SampleSampletypeA worked example you read or clone. Evidence: it demonstrates, it never provides.See every one →What this type is →by a community orgby a community orgoriginPublished by a community organisation, so it outlives any one maintainer.See every one →Starting point

custom-controls-customer

A template repository for a customer's own UI5 artefacts in abap2UI5: an icon font, CSS, a reuse library or a custom control, served from a BSP of their own under the resourceRoot z2ui5_ccc.

Adding a UI5 reuse library to abap2UI5 used to mean patching the framework's own BSP by hand in four places: the resourceRoots in index.html, the library in manifest.json, the xmlns: in the view and the module in the controller. All four are generated from app/webapp in the abap2UI5 repository and force-overwritten in abap2UI5 frontend on every framework update, so the patch survives until the next upgrade and then the icons are gone with no error message. This repository holds those artefacts instead: files go under app/webapp/, npm run app2bsp turns them into the BSP Z2UI5_CCC with its page directory and ICF nodes under src/01, and abapGit installs the result. Four declaration blocks at the top of app/webapp/cc/Extension.js (resource roots, libraries, icon fonts and stylesheets) replace the four framework patches one for one, and from ABAP z2ui5_cl_ccc=>xmlns( ) and render( ) pull the extension into a view. abap2UI5 reserves the resourceRoot z2ui5_ccc in its manifest.json, so BSP, launchpad and ICF-service mode all resolve the BSP without configuration.

Facts

Last pushLicenceMIT

Where it sits

Lives in
Demonstrates
Custom controls and librariesUI5Custom controls and librariescapabilityExtending the set of controls an app is built from: a control of its own, a wrapper around a third-party widget, or an icon font registered with the framework, packaged so another app can reuse it. Distinct from [Web Components interop](capability:ui5-web-components), which brings in standard custom elements, and from [generators](capability:generators), which scaffold a control project rather than being one.
Add-on to
abap2UI5abap2UI5artifactOne ABAP class implementing z2ui5_if_app is the whole app: the browser loads a generic UI5 shell once, and every interaction after that is an HTTP roundtrip back into ABAP.
Serves
Requires
abap2UI5abap2UI5artifactThe framework in the backend this BSP extends: it reserves the resourceRoot z2ui5_ccc the artefacts are served under, and the ABAP class z2ui5_cl_ccc builds into an abap2UI5 view. On an older framework the check app renders an empty page and the browser console shows a failed request for z2ui5_ccc/cc/Extension.js.abapGitabapGitartifactInstalling the ABAP classes, the BSP application Z2UI5_CCC and the two ICF nodes it is served from into the system.
Optional
abap2UI5 frontendabap2UI5 frontendartifactThe frontend BSP that resolves z2ui5_ccc against this BSP, needed when abap2UI5 runs in BSP or launchpad mode.frontend

Who is behind it

abap2UI5-addonsabap2UI5-addonsOrganisationMaintains this
In the atlas: maintains 21
@abap2UI5-addons
maintaineroblomov-devPersonContributes to this
In the atlas: maintains 4, contributes to 44
@oblomov-dev
1 contributor

What it declares

Every artifact

Type
Sample
Origin
By a community org

As a sample

Form
A template or starter

Connections4

README

quoted from abap2UI5-addons/custom-controls-customer under MIT, read
abap2UI5-addons/custom-controls-customer/README.mdOn GitHub

custom-controls-customer

abap2UI5-addons ABAP abap2UI5 License
check

A template repository for your own frontend artefacts in abap2UI5. A UI5 reuse library, an icon font, corporate CSS, a custom control — served to abap2UI5 from a BSP that belongs to you. Fork it (or copy it into your own git host), put your files under app/webapp/, run npm run app2bsp, and install the result with abapGit. Nothing in abap2UI5 or in its frontend BSP has to change, and no pull request against the framework is needed.

Part of abap2UI5-addons - addons and apps for abap2UI5, installed with abapGit.

Why

Adding a UI5 reuse library to abap2UI5 used to mean patching the framework's own BSP by hand, in four places:

FilePatch
index.htmldata-sap-ui-resourceroots → "com.myorg.reuselib": "/sap/bc/ui5_ui5/sap/zreuseicons/"
manifest.jsonsap.ui5.dependencies.libs → "com.myorg.reuselib": {}
View1.view.xmlxmlns:custom="com.myorg.reuselib"
View1.controller.jssap.ui.define([… "com/myorg/reuselib/library"])

All four are generated from app/webapp in the abap2UI5 repository and force-overwritten in abap2UI5/frontend on every framework update — so the patch survives exactly until the next upgrade, and then the icons are gone with no error message.

This repository is the supported place for those artefacts instead. It is the same mechanism abap2UI5-addons/custom-controls uses for the community controls, with a second reserved namespace so the two never collide.

Installation

Requirements

  • Standard ABAP 7.50 or higher
  • abap2UI5 - a version that reserves the z2ui5_ccc resourceRoot, installed in the backend. On an older framework the check app renders an empty page and the browser console shows a failed request for z2ui5_ccc/cc/Extension.js.
  • abap2UI5/frontend — the frontend BSP, when running in BSP or launchpad mode

Steps - with abapGit, in this order:

  1. abap2UI5 (and abap2UI5/frontend for BSP or launchpad mode)
  2. fork this repository (or copy it into your own git host) and put your artefacts in - see Usage
  3. your fork (branch main) - it brings the ABAP classes, the BSP application Z2UI5_CCC and the two ICF nodes it is served from

Start - ?app_start=z2ui5_cl_ccc_sample_00 — the check app. If the badge renders, is styled and reacts to a click, the BSP is deployed and the frontend resolves z2ui5_ccc.

Usage

1. Drop the files under app/webapp/
app/webapp/
├── index.html          the BSP start page - a note, this BSP has no UI
├── Util.js             small helpers (url, loadStyle, loadScript, logError)
├── cc/
│   ├── Extension.js    THE FILE YOU EDIT - the four config blocks
│   └── Example.js      a template custom control
└── css/
    └── style.css       your CSS

Two limits come from the BSP page format and are checked by app2bsp, which fails loudly rather than letting SAP reject the import:

  • at most one directory level — cc/Example.js is fine, cc/lib/x.js is not
  • names from letters, digits, _ and . only — no hyphens
2. Declare what has to be registered

Everything that must happen once, before a view can use your artefacts, is declared at the top of app/webapp/cc/Extension.js:

const RESOURCE_ROOTS = {
  "com.myorg.reuselib": "/sap/bc/ui5_ui5/sap/zreuseicons/",
};

const LIBRARIES = ["com.myorg.reuselib"];

const ICON_FONTS = [{
  fontFamily: "MyCustomFontFamily",
  collectionName: "my-icons",
  fontURI: Util.url("fonts"),
  metadata: { Regal: "e910", Stapler: "e917" },
}];

const STYLESHEETS = [Util.url("css/style.css")];

Those four blocks are the replacement for the four framework patches in the table above, one for one.

3. Regenerate and commit
npm run app2bsp        # app/webapp -> src/01 (BSP pages, page directory, ICF nodes)
npx abaplint abaplint.jsonc

CI runs both and fails on a diff, so a stale BSP page can never ship old JavaScript unnoticed.

4. Use it from ABAP
DATA(view) = z2ui5_cl_ui5_view_builder=>factory( ).

DATA(root) = view->ele( n  = `View`
                        ns = `mvc`
    )->a( n = `xmlns`     v = `sap.m`
    )->a( n = `xmlns:mvc` v = `sap.ui.core.mvc` ).

z2ui5_cl_ccc=>xmlns( root ).             " declares xmlns:z2ui5_ccc - once per view

DATA(page) = root->ele( `Page` )->a( n = `title` v = `Warehouse` ).

z2ui5_cl_ccc=>render( page ).            " loads and installs the extension

page->tag( `Button`
    )->a( n = `icon` v = `sap-icon://my-icons/Regal`   " your own icon font
    )->a( n = `text` v = `Rack` ).

client->view_display( view->stringify( ) ).

render( ) is what pulls Extension.js into the page, so it belongs in every view that relies on an icon font, a stylesheet or a registered library — before the controls that use them. Calling it twice is harmless; the installation runs once per page.

How it works

abap2UI5 reserves the resourceRoot z2ui5_ccc in its manifest.json:

"sap.ui5": { "resourceRoots": { "z2ui5_cci": "../z2ui5_cci/", "z2ui5_ccc": "../z2ui5_ccc/" } }

so the module z2ui5_ccc/cc/Example is served from /sap/bc/ui5_ui5/sap/z2ui5_ccc/cc/Example.js — the BSP Z2UI5_CCC that this repository builds. In the standalone HTTP service, where there is no sibling BSP to resolve ../z2ui5_ccc/ against, z2ui5_cl_http_handler hands the absolute path to the frontend instead. All three delivery modes (BSP, launchpad, ICF service) therefore resolve it without configuration.

Registering the path costs nothing when this repository is not installed: the browser requests nothing from z2ui5_ccc until a view actually names the namespace.

your ABAP app  ──►  z2ui5_cl_ccc=>render( page )
                          │  emits <z2ui5_ccc:Extension/> into the view
                          ▼
abap2UI5 frontend  ──►  loads z2ui5_ccc/cc/Extension.js from YOUR BSP
                          │  which registers, at page level:
                          ├─ resource roots of other BSPs
                          ├─ UI5 reuse libraries
                          ├─ icon fonts (IconPool)
                          └─ stylesheets

Keeping an existing reuse-library BSP

You do not have to move an existing library into this BSP. Leave ZREUSEICONS where it is and register it in RESOURCE_ROOTS plus LIBRARIES — one entry each, in a file that no framework update overwrites. The library keeps its own name (com.myorg.reuselib), and views address it under their own prefix:

root->a( n = `xmlns:custom` v = `com.myorg.reuselib` ).

Moving it in here is still the tidier option when you can: one BSP, one transport, one thing to install.

Binary artefacts

BSP pages are text. A .woff2, .ttf or .png cannot be committed under app/webapp — app2bsp would mangle it, so it rejects the name instead. Two ways work:

  • base64 data URI in CSS — for a single icon font this is the simplest path, because a data URI is text and rides along in css/style.css:

    @font-face {
      font-family: "MyCustomFontFamily";
      src: url("data:font/woff2;base64,d09GMgABAAAAA...") format("woff2");
    }

    Note that the UI5 IconPool needs the font file itself at fontURI, so for sap-icon:// icons use the MIME route below; a data URI covers the CSS-class usage (<span class="my-icons">).

  • MIME objects — upload the font into the BSP with /UI5/UI5_REPOSITORY_LOAD (report /UI5/UI5_REPOSITORY_LOAD in SE38) or keep it as a W3MI object serialized by abapGit, then point fontURI at the URL it is served from. This is the right choice for anything large or for a font the IconPool has to read.

Naming

ABAP objects here follow the scheme z2ui5_<type>_<token>_<object> the abap2UI5 repositories share, with the token ccc — custom control customers — reserved for this one, the way smp belongs to abap2UI5/samples and cci to the community add-on abap2UI5-addons/custom-controls. So every class starts with Z2UI5_CL_CCC (Z2UI5_CX_CCC for exceptions, Z2UI5_IF_CCC for interfaces) and is at most 25 characters long — object_naming in abaplint.jsonc enforces both, and the comment there explains where the 25 comes from.

The frontend side carries the same token: the BSP is Z2UI5_CCC and the resourceRoot it is served under is z2ui5_ccc — the ABAP name of the BSP, lowercased. A resourceRoot resolves to the BSP's URL (/sap/bc/ui5_ui5/sap/z2ui5_ccc/), so the two are necessarily the same string, and keeping the ABAP token in it means there is one name to remember for the whole repository instead of two. It is reserved in the abap2UI5 manifest.json, which is what makes this BSP findable without patching anything downstream.

The community controls follow the same rule, so abap2UI5-addons/custom-controls ships the BSP Z2UI5_CCI under the root z2ui5_cci for its z2ui5_cl_cci* classes. The two roots therefore differ in the last letter only: _cci is the community one, _ccc this one. They are distinct strings and cannot collide, but a typo in a view's xmlns: resolves against the wrong BSP and shows up only as a failed module request in the browser console — so when a control does not render, check that letter first.

Renaming

Z2UI5_CCC and the Z2UI5_CL_CCC* classes are the defaults. To use your own namespace, change BSP and PREFIX in tools/app2bsp.mjs, the resourceRoots key the frontend registers, the class names, and the object_naming patterns in abaplint.jsonc — all together.

Be aware that z2ui5_ccc is the namespace abap2UI5 registers out of the box. Renaming it means registering the new one yourself, which puts you back in the business of patching framework files — so rename the ABAP objects if your system demands it, but keep the resourceRoot.

What is in the box

ArtefactPurpose
app/webapp/cc/Extension.jsthe bootstrap element — resource roots, libraries, icon fonts, stylesheets
app/webapp/cc/Example.jsa template custom control (property, event, renderer)
app/webapp/Util.jsurl, loadStyle, loadScript, logError, isDestroyed
src/z2ui5_cl_ccc.clas.abapABAP side — xmlns( ), render( ), example( ), leaf( )
src/00/z2ui5_cl_ccc_sample_00.clas.abapinstallation check app
tools/app2bsp.mjsapp/webapp → the abapGit BSP artefacts under src/01

Development

CI (.github/workflows/check.yml) runs on every push to main and every pull request: abaplint against abaplint.jsonc, a check that the BSP under src/01 matches app/webapp (npm run app2bsp must leave no diff), and a syntax check of every JavaScript file under app/webapp. Run the same before you push:

npm run app2bsp
npx abaplint abaplint.jsonc
  • abap2UI5-addons/custom-controls — the same mechanism under the reserved namespace z2ui5_cci, for controls shared with the community. If what you are building is generally useful, contribute it there instead.

Contributing

Issues and pull requests are welcome.

License

MIT - see LICENSE.

MIT, read

Details

Sources3
GitHub APIdiscovered herechecked
github.com/abap2UI5-addons/custom-controls-customertree, pushes, contributors, CIchecked
README.mdquoted, and what the entry declareschecked

Sources are graph entities: the same page may back several entries, and an unreachable source flags every row that rests on it.

Compatibility and provenance
discovered viaGitHub API
first seen in the atlas
ecosystem and domainabap, ui-and-frontend-bridge
Flavors1
Standard ABAP
“- Standard ABAP 7.50 or higher” — abap2UI5-addons/custom-controls-customer — READMEchecked
Contributors1

From the repository’s contributor list, .

History in the atlas1
  1. First seen.
For your agent
Ref
artifact:abap2ui5-addons-custom-controls-customer
JSON
/artifacts/abap2ui5-addons-custom-controls-customer.json
MCP
Connecting an agent