Skip to content

Repository files navigation

ABAP NW 7.02 to ABAP Cloud namespace dependency

ABAP_STANDARD ABAP_CLOUD
checks e2e_nightly
auto_downport generate_result deploy_web

abap2UI5 — samples-controls

Last generated: 2026-07-20 06:21 UTC

Learn how to use every UI5 control in ABAP — the UI5 Demo Kit rebuilt with abap2UI5.

You know the drill from the UI5 Demo Kit: pick a control, open its sample, copy the pattern. This repository brings that experience to ABAP — the official demo kit samples of ten UI5 libraries (sap.m, sap.f, sap.ui.core, sap.ui.layout, sap.ui.table, sap.ui.unified, sap.uxap, sap.tnt, sap.ui.codeeditor, sap.ui.integration), rebuilt 1:1 as ready-to-run abap2UI5 apps. Wondering how to express a control in ABAP? Its sample is already here — or on its way.

Try it in 60 seconds

  1. Install abap2UI5.
  2. Pull this repository with abapGit.
  3. Start z2ui5_cl_smpc_app_overview — every sample in one searchable table: each row links the original UI5 sample and its ABAP rebuild, and one click starts the app right in your system.

No ABAP system at hand? Open the GitHub Pages demo — the framework and every sample run fully client-side in your browser.

The learning path

This repository is step 2 of 3 — the control reference of the abap2UI5 sample family:

Repository What you learn Where to start
1️⃣ samples the abap2UI5 basics — bindings, events, popups, navigation, complete apps run Z2UI5_CL_SMP_APP_000
2️⃣ samples-controls — 📍 you are here how to use every UI5 control — the UI5 Demo Kit rebuilt with abap2UI5 run z2ui5_cl_smpc_app_overview
3️⃣ samples-stack how abap2UI5 plays with your stack — OData, RAP, WebSockets, the Fiori Launchpad and more pick your technology in its package table

Learn by comparing

Every port keeps the structure of its original, so the two read side by side: the UI5 original (JS/XML) in ui5/, the ABAP rebuild in src/, and api.md as the full index — one row per demo kit sample, with links to both. The most effective way to learn a control: open its demo kit sample and its ABAP class next to each other and compare line by line.

How this repository is built — the generation pipeline

This repository is generated and gated by an AI coding agent: from every official demo kit sample of the covered libraries whose control exists since UI5 1.71 and is not deprecated (legacy-free ready), it builds an abap2UI5 app — exposing the functional gaps between what UI5 offers and what abap2UI5 can already express, so they can be closed. Deprecated or newer controls are listed as out of scope. The pipeline:

  1. Read — clone OpenUI5 and scan every demo kit sample of the covered libraries (src/<library>/test/<library path>/demokit/sample/<Name>/, second segment with dots as slashes, e.g. src/sap.tnt/test/sap/tnt/…).
  2. Generate — rebuild each sample 1:1 as an abap2UI5 app (z2ui5_if_app), filed under src/<category>/<library> (src/01/01 = OpenUI5 ≤ 1.71, sap.m — see AGENTS §3); both levels are derived from the port's meta/ sidecar.
  3. Store templates — keep the original UI5 JS/XML templates in ui5/, one folder per sample — only ported samples are archived; each batch copies its samples over from the OpenUI5 checkout.
  4. Report — regenerate the coverage tables and the in-system overview app. In api.md, marks an in-scope sample not yet ported (the backlog) and an out-of-scope one (deprecated / newer than UI5 1.71).

Reviewed, curated samples graduate to the hand-maintained abap2UI5/samples repository.

Generation prompt (UI5 sample → abap2UI5 app)
You are porting one official UI5 demo kit sample to abap2UI5.

Input:  the sample's original files (Component.js, *.view.xml, controller,
        manifest.json) from the OpenUI5 checkout.
Output: one ABAP class z2ui5_cl_smpc_app_<n> implementing z2ui5_if_app, that
        rebuilds the sample's UI and behaviour 1:1.

Rules:
- Build the view with the generic builder z2ui5_cl_ai_xml, translating the
  sample's XML 1:1 (open = descend into a container, leaf = childless
  control/stay, shut = ascend). Attributes are added with
  a( n = `key` v = `value` ) chained right after the control's open/leaf;
  a targets that control, and v is any string expression (literal, a
  client->_bind/_event result, a |...| string template). factory( )
  returns an empty root: open the mvc:View and declare its xmlns namespaces
  yourself. Blank line between controls whose verb differs (open<->leaf,
  before shut); none between same-verb controls, none right after a shut,
  none between a control and its attrs; the whole view ends in a single ).
  An aggregation carries the same namespace as its XML tag (its parent
  control's): <m:content> under a Page is open( n = `content` ns = `m` ),
  a default-namespace <columns> inside an sap.ui.table.Table is open( `columns` ).
  Braces { } inside a |...| template are ALWAYS escaped \{ \} - an unescaped {
  is read as a binding by the XMLView parser and crashes view creation.
  Booleans: literal v = `true`/`false`, or v = z2ui5_cl_ai_xml=>as_bool( flag )
  when fed from an ABAP boolean variable.
- BEFORE declaring any sample feature inexpressible, check CAPABILITIES.md -
  the map of what abap2UI5 can express, each entry backed by a proving port.
  Never improvise around a feature it marks expressible.
- Structure z2ui5_if_app~main as a dispatcher:
    me->client = client.
    IF client->check_on_init( ).
      model_init( ).
      view_display( ).
    ELSEIF client->check_on_event( ).
      on_event( ).
    ENDIF.
  Add model_init / on_event only when the app actually has data / events.
  z2ui5_if_app~main is always the FIRST method in the implementation; the
  remaining methods follow in the order they are called from main, EXCEPT
  model_init which always goes LAST (after every other method, and declared
  last in the DEFINITION too) - its large mock-data VALUE #( ) block must not
  interrupt the reading flow of the dispatcher/view/event methods.
- Always the simplest possible notation: omit parameters that equal the
  default - get_event_arg( ) not get_event_arg( 1 ) (index only for 2+).
- Move the sample's JSON model data into ABAP (VALUE #( ... )) and bind it
  with client->_bind (two-way; the former _bind_edit is obsolete - always use
  _bind). Absent JSON properties must not serialize as empty strings: `""`
  crashes enum-typed properties and overrides property defaults where the
  original's undefined picked the default - fill the UI5 default explicitly
  or split the aggregation into per-shape templates.
- abap2UI5 serves ONE default model - there are no named models. A named-model
  binding ({ui>/rowMode}, {img>/x}) is folded into the default model: drop the
  prefix and bind the field directly (client->_bind( rowmode )); structural-diff
  matches on the last path segment. A typed/complex binding is kept as a raw
  binding-info string, braces escaped: |\{ path: 'Q', type:
  'sap.ui.model.type.Integer' \}| (same for Date/Currency parts and sorter) -
  it passes through to XMLView.create unmangled. See the port-a-sample guide (.claude/skills/port-a-sample/SKILL.md)
  "Idiom cheat-sheet".
- Frontend actions: a control method LISTED in CONTROL_METHODS
  (FrontendAction.js) carries explicit arg kinds and silently drops every
  argument beyond them - verify the kinds before a parametrized call. An
  UNLISTED public method also runs unless it matches the deny regex
  (destroy/bind/attach/setModel/...); a denylisted or argument-dropping
  need is a declared deviation plus a pr/ request, never a LIVE_TEST hope.
  popover_display imports xml + by_id (the XML parameter is `xml`, not
  `val`).
- Map controller event handlers to check_on_event( ) branches. To pass a value
  into an event, use the `$`-prefixed form in t_arg (a model column as
  `${COL}`, the event object as `$event.oSource.sId` / `${$source>/text}`) and
  read it back with get_event_arg( ) - a bare `{COL}` (the attribute
  property-binding form) is NOT resolved there. Transport real event/source
  values this way instead of faking a static placeholder.
- The sample's CONTROL must exist since UI5 1.71 and not be deprecated
  (out-of-scope samples are never ported). Members newer than 1.71 are KEPT
  1:1 when the original uses them - declare each in the sidecar as a
  POST_171 deviation naming the member (the property gate checks this).
- Must pass abaplint for ABAP_STANDARD, ABAP_CLOUD and ABAP_702 (downport).
- The class carries NO ABAP Doc header. Write the port's sidecar
  meta/z2ui5_cl_smpc_app_<n>.json instead (sample, entity, file, batch, audit,
  status, deviations) - see AGENTS.md section 5 and the port-a-sample guide; validate with
  node scripts/validate-meta.mjs.
- Any runtime asset URLs the sample uses (test-resources / resources images)
  also point at the OpenUI5 host (sdk.openui5.org), never SAPUI5.
- Leave the abapGit <DESCRIPT> as the scaffolder's `<library> - <sample name>`
  default (e.g. `sap.f - GridListBoxContainerGrouping`); only improve the
  trailing text to a human phrase when you know one. Don't agonize over
  entity-vs-library (see AGENTS.md section 5 and the port-a-sample guide).
- Follow all ABAP conventions in AGENTS.md.

Ports are filed by the sample's UI5 library — src/01 (sap.m), src/02 (sap.ui.*), src/03 (sap.uxap), src/04 (sap.f), src/05 (sap.tnt) — one flat ABAP package per library; see AGENTS §3 for the folder table. The generation/review batch a port came from is recorded in its meta/<class>.json, not in the tree. The browser demo is built from web/ into docs/; see web/README.md.

Repo map

File What it is
AGENTS.md The complete generation rulebook (conventions, skeleton, gates)
CAPABILITIES.md What abap2UI5 can express — each entry backed by a proving port or a source-verified trace
TRAINING.md The improvement loop: batches, quality ladder, reference repositories
STATUS.md Generated point-in-time state + the open findings backlog
STATUS-history.md The chronological journal (batches, probes, audits)
api.md One row per demo kit sample: ported, backlog or out of scope
meta/ One sidecar per port — status, checked, typed deviations
pr/ Forwardable improvement requests for the abap2UI5 framework, distilled from porting gaps
ai-mcp MCP server for AI coding agents — capability queries, view validation, deploy, headless run + screenshot on this repo's infrastructure (separate repository)
abap2UI5-linter The view gates as standalone CLI, library and GitHub Action — extracted from this repo and now used BY it (scripts/view-gates.mjs)

Compatibility

Every app is ABAP Cloud ready and downportable to 7.02. In detail, every app:

  • uses only controls available since UI5 1.71 (16 Jan 2020), none of them deprecated (legacy-free ready). Individual members newer than 1.71 are kept where the original sample uses them — declared per port (POST_171), so those apps need a correspondingly recent UI5;
  • runs on SAPUI5 and OpenUI5, including the legacy-free runtime;
  • runs on ABAP Cloud and ABAP Standard, and downports to 7.02.

CI enforces this on every change:

Build What it does
ABAP_STANDARD abaplint ./abaplint.jsonc (syntax v750)
ABAP_CLOUD abaplint .github/abaplint/abap_cloud.jsonc (syntax Cloud)
ABAP_702 npm run downportabaplint .github/abaplint/abap_702.jsonc
checks pattern-lint (distilled lessons), structural-diff --strict (port vs original view incl. binding values, undeclared deviations fail), view-gates (abap2UI5-linter: UI5 metadata, builder structure, headless XMLView.create per port), data-fidelity (seeded values vs the archived mocks), validate-meta + overview/coverage sync

Every port also carries a machine-readable sidecar meta/<class>.json (sample, status, declared deviations) — the source of truth the overview app, the coverage and the structural diff read from.

Coverage

Coverage per UI5 library — the share of official demo kit samples that already have an abap2UI5 port.

Overall 411 / 628 in-scope demo kit samples ported (65.4 %). In scope: samples whose control exists since UI5 1.71 and is not deprecated (legacy-free ready). Out of scope: 113 of 741 samples — 21 on deprecated controls, 52 on controls newer than 1.71, 37 that are not app views (UI5 test infrastructure, Component routing, view-templating demos — see ui5/scope-nonapp.json), 3 demo apps without an owning control. Plus 5 ported samples outside that scope — maintainer-decided exceptions (ui5/scope-exceptions.json, listed in STATUS.md); they are not counted as coverage of the in-scope backlog. Control metadata from OpenUI5 1.152.0.

Module Samples In scope Ported Coverage
sap.tnt 17 17 17 100.0 % ██████████
sap.ui.codeeditor 2 2 2 100.0 % ██████████
sap.ui.core 63 20 20 100.0 % ██████████
sap.ui.integration 4 4 4 100.0 % ██████████
sap.ui.layout 61 61 61 100.0 % ██████████
sap.ui.table 21 21 21 100.0 % ██████████
sap.ui.unified 21 21 21 100.0 % ██████████
sap.uxap 45 45 31 68.9 % ███████░░░
sap.m 461 403 217 53.8 % █████░░░░░
sap.f 46 34 17 50.0 % █████░░░░░
Total 741 628 411 65.4 % ███████░░░

For the full control-level view — one row per sample (Module · Control · Since · Deprecated · Sample · ABAP), every link pointing at OpenUI5 — see api.md, or the in-system overview app z2ui5_cl_smpc_app_overview, where the Sample column links the OpenUI5 source (its ↗ opens the live sample) and the abap2UI5 column links the generated class (its ↗ starts the app in the system).

The coverage summary and api.md are generated by the generate_result workflow (scripts/generate-coverage.mjs), and the overview app by scripts/generate-overview.mjs, both from the latest OpenUI5 demo kit samples — do not edit them by hand.

Dependencies

Issues

For bug reports or feature requests, please open an issue in the abap2UI5 repository.

About

Learn how to use every UI5 control in ABAP — the UI5 Demo Kit rebuilt with abap2UI5

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Contributors

Languages