PackagePackagetypeA library you install and call yourself.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 →

abap2UI5 frontend-webcomponent

An alternative abap2UI5 frontend: one ES module registering <abap2ui5-app>, which renders the views an unchanged abap2UI5 app class sends with UI5 Web Components and no UI5 core.

abap2UI5 apps are reached through the project's UI5 single-page app, which loads the UI5 core. This frontend speaks the same JSON protocol and renders the same views out of UI5 Web Components instead, so the app class stays as it is and the bundle is 1265 kB raw, 263 kB gzip, with the 62 components its mappers create and nothing else. It ships as one custom element: dist/index.html is the standalone start page with ?app_start=<CLASS>, and the same element goes into a React, Vue, Angular or plain-HTML page, where it renders into its own shadow root, keeps its own backend session and reports what happens as DOM events. It implements the core protocol in full (app start, events with their model delta, the sap-contextid session, the five view slots, the app stack and the URL hash) and the protocol's portable view profile v1 for rendering, 65 of 65 controls mapped, 42 full and 23 basic. Embedded, the element never reads or writes location: it emits an abap2ui5-route event per hash the app would write and takes one back through navigate(hash), so the host keeps its own routing.

Facts

Last pushLicenceMIT

Where it sits

Lives in
Provides
UI written in ABAPABAPUI written in ABAPcapabilityProducing a web user interface from ABAP code, with the application’s backend language also defining what the user sees and how it behaves.Web Components interopUI5Web Components interopcapabilityUsing standards-based custom elements inside an app, and the question of which control set an app should be built from at all, two concerns that are often answered as 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 whose app classes it renders: the element is pointed at an abap2UI5 HTTP service with endpoint, and the views, events and model it works on are that framework's protocol.@ui5/webcomponents@ui5/webcomponentsartifactThe control set the renderer creates elements from: one mapper per control, with the 62 components it uses imported into the bundle and the UI5 core never loaded.

Who is behind it

abap2UI5abap2UI5OrganisationMaintains this
In the atlas: maintains 18
@abap2UI5
maintaineroblomov-devPersonContributes to this
In the atlas: maintains 4, contributes to 44
@oblomov-dev
1 contributor

Before choosing this

Conditions

PracticalFunctional boundary

Not for views built from controls outside the portable profile: sap.ui.table, sap.f, sap.uxap, sap.ui.comp and z2ui5.cc custom controls render as a visible unsupported-control box and are listed in the diagnostics, and CONTROL_BY_ID and BINDING_CALL stay unsupported. Nine frontend actions the profile allows, DOWNLOAD_B64_FILE and SYSTEM_LOGOUT among them, are skipped and reported rather than run, and formatters other than the profile's Formatter.Date* render a placeholder.

What it declares

Every artifact

Type
Package
Origin
By a community org

As a package

Where it runs
does not say
Distributed through
does not say

Connections5

abap2UI5 frontend-webcomponent connectionsabap2UI5frontend-webcomponentPROVIDES→ provides2provides stated Renders in the browser what an abap2UI5 app class sends, over the same JSON protocol as the project's UI5 single-page app, and covers the protocol's portable view profile v1 with 65 of 65 controls mapped. abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponent abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponentUI written in ABAPprovides stated Maps each profile control to UI5 Web Components (`sap.m.Button` to `ui5-button`, `sap.m.Table` to `ui5-table`) and ships the result as the custom element `<abap2ui5-app>`, which runs in any web app without the UI5 core being loaded. abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponent abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponentWeb Components interopNEEDS→ connects to1connects to stated Every interaction is a roundtrip to the abap2UI5 HTTP service the `endpoint` attribute names: the app start, each event with the delta of the edited paths, the `sap-contextid` session and, where a token layer asks for one, the CSRF token. abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponent abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponentabap2UI5→ needs2needs stated The control set the renderer creates elements from: one mapper per control, with the 62 components it uses imported into the bundle and the UI5 core never loaded. abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponent abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponent@ui5/webcomponentsneeds stated The framework whose app classes it renders: the element is pointed at an abap2UI5 HTTP service with `endpoint`, and the views, events and model it works on are that framework's protocol. abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponent abap2UI5/frontend-webcomponent — README: https://github.com/abap2ui5/frontend-webcomponentabap2UI5

README

quoted from abap2UI5/frontend-webcomponent under MIT, read
abap2UI5/frontend-webcomponent/README.mdOn GitHub

abap2UI5 frontend - UI5 Web Components

An alternative frontend for abap2UI5: it speaks the same JSON protocol as the official UI5 SPA and renders the views an unchanged abap2UI5 app class sends - with UI5 Web Components (@ui5/webcomponents, @ui5/webcomponents-fiori 2.27), without the UI5 core. One ES module, one custom element:

<script type="module" src="abap2ui5-wc.js"></script>
<abap2ui5-app endpoint="/sap/bc/z2ui5" app="Z2UI5_CL_MY_APP"></abap2ui5-app>
  • standalone - dist/index.html is the equivalent of the UI5 SPA's start page: ?app_start=<CLASS>;
  • embedded - in any web app (React, Vue, Angular, plain HTML): the element renders into its own shadow root, keeps its own backend session and reports what happens as DOM events.

The editable-table sample of abap2UI5/samples, unchanged, in the web-components frontend

What it implements

The abap2UI5 protocol is layered:

LayerHere
Core protocol (transport, request/response, sessions, navigation, errors)all of it: app start, events with T_EVENT_ARG, the model delta of the edited paths (__delta rows), the draft id, the sap-contextid session, the CSRF token handshake, the five view slots (MAIN, NEST, NEST2, POPUP, POPOVER), the app stack (nav_app_call / nav_app_leave / the back button), the URL hash (ROUTER action: KEEP/FRESH routes, browser Back/Forward restores, the app-state hash, app-owned hashes with their listener event, HASH_BACK; see The URL hash), PROTOCOL check, the error body of a failed roundtrip shown verbatim as text
Portable view profile v1 (61 controls + 4 tolerated elements, profile/portable-v1.json)65 of 65 mapped - table below
full UI5 view profileno - a control outside the portable profile renders as a visible unsupported control box (its children are still rendered) and is listed in the diagnostics
semantic profile (agent snapshot)no - that is the MCP server's agent client

Frontend actions (T_CUSTOM / .eF wires): MESSAGE_TOAST, MESSAGE_BOX (types, details, custom actions, onClose event), CONTROL_GLOBAL (message toast/box incl. client-composed {0} texts, VIEW_SLOTS destroy = popup/popover close, BUSY_INDICATOR, THEMING, INVISIBLE_MESSAGE announce), SET_TITLE, START_TIMER, SET_FOCUS, CLIPBOARD_COPY, OPEN_NEW_TAB / LOCATION_RELOAD (same origin only), URLHELPER REDIRECT (http(s) only), HASH_BACK (with its fallback route), and the navigation family under its client-API names (SET_PUSH_STATE, HASH_REPLACE, HASH_ATTACH_CHANGED, SET_NAV_ROUTING, SET_APP_STATE_ACTIVE - a backend folds them into the ROUTER system action; as an .eF wire they reach the router as the same options). CONTROL_BY_ID and BINDING_CALL are excluded from the portable profile and stay unsupported. Everything else is skipped, logged and listed in the diagnostics - never thrown.

Bindings: absolute and relative paths, list bindings with one template (sorter, length, startIndex), element binding (binding="{/X}"), two-way binding of every value-like property (the edit goes into the model and the next event's delta, exactly as the UI5 frontend sends it), typed bindings for display (sap.ui.model.type / odata.type Integer, Float, Decimal, Date, Time, DateTime, Currency with formatOptions such as decimals, pattern, source.pattern) and back (numbers stay numbers, read with the symbols of the locale they are shown in: 1.234,56 in a German browser), expression bindings in the profile's grammar (${...}, operators, ? :, .length, Math.max/min/abs/round/floor/ceil, toUpperCase/toLowerCase/ trim/indexOf/includes/startsWith/endsWith) evaluated by a small parser - no eval -, composite text and parts, the device> model, and the profile's frontend formatters Formatter.DateCreateObject, Formatter.DateAbapDateToDateObject and Formatter.DateAbapDateTimeToDateObject (ABAP DATS/TIMS or ISO strings to dates, e.g. for DatePicker.dateValue, minDate, maxDate; same names and behaviour as the UI5 frontend's model/formatter.js). Any other formatter renders a visible [formatter name] placeholder and is reported. Tables and lists grow: growing / growingThreshold / growingTriggerText / growingScrollToLoad render the first rows and a "More" trigger.

Embedding

The bundle registers <abap2ui5-app>; give the element a height.

<!-- plain HTML -->
<script type="module" src="/assets/abap2ui5-wc.js"></script>
<abap2ui5-app endpoint="/sap/bc/z2ui5" app="Z2UI5_CL_MY_APP" style="height: 600px"></abap2ui5-app>
<script>
  document.querySelector('abap2ui5-app')
    .addEventListener('abap2ui5-message', (e) => console.log(e.detail));
</script>
// React 19 (custom elements are first-class; React 18: addEventListener in a ref effect)
import '@abap2ui5/frontend-webcomponent';
export const Abap2UI5 = ({ app }) => (
  <abap2ui5-app endpoint="/sap/bc/z2ui5" app={app} style={{ display: 'block', height: 600 }} />
);
<!-- Vue 3 - compilerOptions.isCustomElement: (t) => t === 'abap2ui5-app' -->
<script setup>import '@abap2ui5/frontend-webcomponent';</script>
<template>
  <abap2ui5-app endpoint="/sap/bc/z2ui5" :app="app" style="display:block;height:600px"
                @abap2ui5-message="onMessage" />
</template>

Angular: add CUSTOM_ELEMENTS_SCHEMA to the component and import the module once. examples/plain.html runs two apps side by side (the demo server serves it at /examples/plain.html), examples/react.jsx and examples/vue.vue are the snippets above in full.

Attribute
endpointthe abap2UI5 HTTP service (/sap/bc/z2ui5, or an absolute URL)
appthe app class; changing it restarts the element with that app
paramsextra start parameters, a=1&b=2 (they travel in SEARCH)
themea UI5 Web Components theme: sap_horizon (default), sap_horizon_dark, sap_horizon_hcb, sap_fiori_3, ...
credentialsfetch credentials: same-origin (default), include (a backend on another origin, cookie auth), omit
csrfauto (default: fetch a token when a token layer answers 403 X-CSRF-Token: Required, re-send once), fetch (before the first POST), none, or a token
diagnosticsoff hides the diagnostics panel (the console and the events still report)
document-titleSET_TITLE also sets document.title (always on in the standalone page)
standalonethe element owns the page: the URL hash is the app's (routes, app state, Back/Forward) and travels with every request
routingthe URL hash: hash (read and write the page's hash - the default with standalone), events (never touch the host's URL, emit abap2ui5-route - the default embedded), off
languagethe language of the frontend's own texts (message box buttons and titles, "No data", the error dialog - English and German built in, defineTexts() adds one) and of the web components; default: the page's lang, else the browser's. The standalone page takes ?sap-language=

endpoint, app, params, credentials, csrf, routing, standalone and language restart the element when changed; theme, diagnostics and document-title apply at once.

Properties: headers (extra request headers - Authorization, sap-client; a new object assigned later is used from the next request on), transport (your own { roundtrip(body), endSession() } - set before the element connects), session, diagnostics; methods restart(), navigate(hash). Events (bubbling, composed): abap2ui5-response, abap2ui5-request, abap2ui5-message, abap2ui5-title, abap2ui5-error (detail.retry says whether the error dialog offers Retry), abap2ui5-diagnostic, abap2ui5-route. TypeScript hosts get the element, its event map and the exports typed from types/index.d.ts.

The URL hash

abap2UI5 apps can keep their state in the URL hash (spec/navigation.md): hash routing (#/app/<CLASS>/<DRAFT> in mode KEEP, #/app/<CLASS> in FRESH; a nav_app_call pushes a history entry, the browser Back button restores the caller's draft), the app-state hash (#/z2ui5-xapp-state=<DRAFT>: reload and bookmarks restore the state), and app-owned hashes (hash_set / hash_replace with a listener event raised on Back/Forward, HASH_BACK with a fallback route). The backend sends what the URL has to reflect as the ROUTER system action; this frontend applies it once per response, as the UI5 frontend's router does.

  • Standalone (dist/index.html, or routing="hash"): the page's hash is the app's. It is written with the History API, a browser Back/Forward or a manual edit sends the app-start-shaped restore request (no ID, the new HASH), and every request carries the hash as S_FRONT.HASH. Inside the SAP Fiori launchpad the shell part before &/ is kept.
  • Embedded (the default without standalone): the hash is the host's. The element never reads or writes location, sends no HASH, and tells the host instead - an abap2ui5-route event per hash the app would write, { action: 'push' | 'replace', hash, app, id }, and { action: 'back' } for HASH_BACK. A host that routes itself can record those hashes and, on its own Back button or a deep link, hand one back with element.navigate(hash): a route then restores that draft, an app-owned hash raises the app's listener event - and that one request carries the hash. routing="off" ignores the ROUTER action altogether.

The protocol client, the renderer and the control registry are exported too (Session, createFetchTransport, Renderer, defineControl, ...), and defineControl('z2ui5.cc.MyControl', mapper) adds a mapper of your own.

Run the demo

The demo backend is abap2UI5 itself, transpiled to Node - @abap2ui5/node-runtime 1.146.0 - with 16 real sample apps of abap2UI5/samples transpiled on top, exactly as the package's README describes for your own apps.

npm ci
npm run demo:build   # open-abap-core at the runtime's commit, transpile demo/abap, abap2ui5-own-apps
npm run build        # dist/abap2ui5-wc.js, dist/index.html
npm run demo:serve   # http://127.0.0.1:4300/?app_start=Z2UI5_CL_SMP_APP_494

The same server answers the official UI5 SPA at http://127.0.0.1:4300/sap/bc/z2ui5/?app_start=Z2UI5_CL_SMP_APP_494 - one backend, two frontends.

Demo appStatus
Z2UI5_CL_SMP_APP_493Hello World - Shell, Page, MessageStrip, Titleruns fully
Z2UI5_CL_SMP_APP_494Data binding - two-way binding, delta, MessageBoxruns fully
Z2UI5_CL_SMP_APP_381MessageToast via the global object - Select, CheckBox, toast options, onClose event, client-composed toastruns fully (toast position options are not applied)
Z2UI5_CL_SMP_APP_382MessageBox types, details, custom actionsruns fully
Z2UI5_CL_SMP_APP_011Table - edit mode, cell inputs, MultiSelect, delete and add rowsruns fully
Z2UI5_CL_SMP_APP_019Table selection modes - SegmentedButton, selection read in ABAPruns fully
Z2UI5_CL_SMP_APP_048List - StandardListItem, ${ROW} args on detailPress, selectionChangeruns fully
Z2UI5_CL_SMP_APP_012 (+020)Popups - dialog over the page, popup closed on the client, popup app via nav_app_callruns fully
Z2UI5_CL_SMP_APP_026Popover at its opener, input and footerruns fully
Z2UI5_CL_SMP_APP_024 (+025)Navigation - call another app, return data, back buttonruns fully
Z2UI5_CL_SMP_APP_445Device model - device> bindings, expressions, IconTabBar, popupruns fully
Z2UI5_CL_SMP_APP_125Set the tab title (SET_TITLE)runs fully
Z2UI5_CL_SMP_APP_027Expression binding, types, composite partspartial: the RegExp(...) expression is outside the profile - reported, the button stays disabled
Z2UI5_CL_SMP_APP_453ObjectStatus, ObjectNumber in a tableruns fully
Z2UI5_CL_SMP_APP_480 (+469)Hash routing (KEEP) - #/app/<CLASS>/<DRAFT>, nav_app_call pushes, browser Back/Forward restore the draftsruns fully
Z2UI5_CL_SMP_APP_498App state in the URL - #/z2ui5-xapp-state=<DRAFT>, a reload restores the stateruns fully (the share link is the backend's)

Data binding A popup A popover Device model and tabs MessageToast form ObjectStatus and ObjectNumber

All screenshots: docs/screenshots/.

Tests

npm run lint
npm test            # node:test - bindings, expressions, types, the protocol client
                    # (delta, slots, errors, busy queue), transport (contextid, CSRF),
                    # the URL hash router, frontend actions (both shapes of the
                    # profile's action list), formatters, the renderer on happy-dom over the recorded
                    # views of every demo app, the vendored-file hashes, profile coverage
npm run e2e         # Playwright - every demo app in the web-components frontend,
                    # DOM + backend state, and the same interaction in the UI5 SPA
                    # with the request bodies / models compared; embedding; errors
npm run screenshots # docs/screenshots/

The e2e cross-check drives the official UI5 SPA through the UI5 control API (setValue + fireChange, firePress, ...) and compares what both frontends sent (EVENT, T_EVENT_ARG, MODEL) and what the backend answered. UI5 itself comes from sdk.openui5.org; OPENUI5_DIR=<node_modules/@openui5> serves it from local packages instead (offline sandboxes), CROSS_CHECK=0 skips the UI5 half. Chromium: CHROMIUM_BIN, else /opt/pw-browsers/chromium when present, else Playwright's own.

Architecture

src/core/       the protocol client - no DOM
  session.js      start / fire / closeSlot, response adoption (vendored applyResponse),
                  delta (vendored buildDelta), app stack, APP-change popup teardown, busy queue,
                  route restore, the error body verbatim
  transport.js    fetch POST { value }, sap-contextid, CSRF handshake, terminate HEAD
  router.js       the URL hash: ROUTER sync, routes, app-state hash, app-owned hashes,
                  HASH_BACK - on the page's hash or as abap2ui5-route events (embedded)
  actions.js      T_CUSTOM / eF frontend actions
src/bindings/   model.js (long-lived models, edited paths, device>), binding.js (property and
                list bindings), expression.js (profile grammar), types.js (typed display),
                formatters.js (the profile's Formatter.Date*), objectsyntax.js
src/render/     renderer.js (XML -> elements, scopes, two-way, wires), wires.js (event args),
                registry.js + controls/*.js (one mapper per UI5 control), webcomponents.js (imports)
src/ui/         app.js (slots, popups, toast/box, busy, errors, diagnostics), styles.js
src/element.js  <abap2ui5-app>
src/vendor/agent/  viewxml.mjs, snapshot.mjs, appclient.mjs of abap2UI5/mcp-server, unchanged

The XML parser, the wire parser, the response bookkeeping and the delta builder are the MCP server's agent client modules, vendored unchanged at a recorded commit (scripts/vendor-agent.mjs, src/vendor/agent/source.json, hash test) - the same code that already speaks the protocol for agents; the bundler drops what the browser does not call.

Bundle (npm run build): dist/abap2ui5-wc.js 1265 kB raw / 263 kB gzip loaded up front (the 62 web components used, nothing else); on demand, in dist/chunks/: the SAP icon collection (248 kB gzip, on the first icon), popover internals, the CLDR data of the user's locale, extra themes.

Control coverage

Portable profile v1: 65 of 65 controls mapped (42 full, 23 basic).

UI5 control (profile v1)rendered asstatusbasic: what is left out
sap.m.Pageui5-page + ui5-bar header/footerfull
sap.m.ShellHTML/CSSfull
sap.m.VBoxHTML/CSSfullCSS flexbox: direction, alignItems, justifyContent, wrap, fitContainer; FlexItemData grow/shrink/base
sap.ui.layout.form.SimpleFormCSS grid + ui5-titlebasiclabel/field grid with group titles; layout, columns and breakpoints are not modelled
sap.m.HBoxHTML/CSSfullCSS flexbox: direction, alignItems, justifyContent, wrap, fitContainer; FlexItemData grow/shrink/base
sap.m.Panelui5-panelfull
sap.ui.layout.GridHTML/CSSbasicdefaultSpan and GridData span (XL/L/M/S); no indent
sap.m.FlexBoxHTML/CSSfullCSS flexbox: direction, alignItems, justifyContent, wrap, fitContainer; FlexItemData grow/shrink/base
sap.m.ScrollContainerHTML/CSSfull
sap.m.IconTabFilterui5-tabfull
sap.m.IconTabBarui5-tabcontainer + ui5-tabbasictabs with text, icon, count, iconColor and content; selectedKey, select; no expand/collapse event, no drag & drop
sap.ui.layout.VerticalLayoutHTML/CSSbasica column of its content; width/spacing not modelled
sap.ui.core.Titleui5-titlebasicicon not shown
sap.ui.layout.HorizontalLayoutHTML/CSSbasican inline row of its content; allowWrapping always on
sap.m.OverflowToolbarui5-toolbar (+ ui5-toolbar-button, -item, -spacer, -separator)full
sap.m.ToolbarSpacerui5-toolbar-spacerfull
sap.m.Toolbarui5-toolbar (+ ui5-toolbar-button, -item, -spacer, -separator)full
sap.m.Barui5-barfull
sap.m.OverflowToolbarButtonui5-buttonbasicicon button with the text as tooltip (the overflow text is the toolbar's)
sap.m.Textui5-textfull
sap.m.Labelui5-labelfull
sap.m.Titleui5-titlefull
sap.m.ObjectStatusstyled <span> + ui5-iconbasicicon, title, text, state, inverted, active; no stateAnnouncementText
sap.m.Linkui5-linkfull
sap.m.ObjectIdentifierHTML (+ ui5-link when titleActive)basictitle, text, titleActive/titlePress
sap.ui.core.HTMLHTML/CSSbasiccontent sanitized: no script, no style element, no event handlers
sap.ui.core.Iconui5-iconfull
sap.m.ObjectNumberHTML/CSSbasicnumber, unit, state, emphasized
sap.tnt.InfoLabelui5-tag + ui5-iconfull
sap.m.ProgressIndicatorui5-progress-indicatorfull
sap.m.ImageHTML <img>full
sap.m.Inputui5-input + ui5-iconfull
sap.m.TextAreaui5-textareafull
sap.ui.core.Itemui5-option + ui5-cb-item + ui5-mcb-itemfull
sap.m.CheckBoxui5-checkboxfull
sap.m.Switchui5-switchfull
sap.m.SegmentedButtonui5-segmented-buttonfull
sap.m.SegmentedButtonItemui5-segmented-button-itemfull
sap.m.Selectui5-selectfull
sap.m.DatePickerui5-date-pickerbasicvalue (two-way), valueFormat, displayFormat, minDate/maxDate; dateValue one-way (from a frontend formatter)
sap.m.SearchFieldui5-input + ui5-iconfull
sap.m.ComboBoxui5-comboboxfull
sap.m.MultiInputui5-multi-inputbasictokens are shown; a token delete fires tokenUpdate but is not written back into the bound token table (UI5 needs z2ui5.cc.MultiInputExt for that too)
sap.m.Tokenui5-tokenbasictext, key, selected
sap.m.MultiComboBoxui5-multi-comboboxfull
sap.m.StepInputui5-step-inputfull
sap.ui.core.ListItemui5-option + ui5-cb-item + ui5-mcb-itemfull
sap.m.DateTimePickerui5-datetime-pickerbasicvalue (two-way), valueFormat, displayFormat, minDate/maxDate; dateValue one-way (from a frontend formatter)
sap.m.Buttonui5-button (ui5-toolbar-button in a toolbar)full
sap.m.ToggleButtonui5-toggle-buttonfull
sap.m.Columnui5-table-header-cellbasicheader, width, hAlign, minScreenWidth; no demandPopin/footer
sap.m.ColumnListItemui5-table-row + ui5-table-cellbasiccells, type (interactive rows), selected, press; highlight not shown
sap.m.Tableui5-table (+ header row/cells, ui5-table-selection-multi/-single)basiccolumns, items (bound or static), header toolbar, noDataText, MultiSelect/SingleSelect via the selected binding, itemPress, selectionChange, growing (threshold, trigger text, scroll to load); no Delete mode, no grouping
sap.m.Listui5-listbasicitems (bound or static), headerText, mode, itemPress, selectionChange, delete, growing (threshold, trigger text, scroll to load); no grouping
sap.m.StandardListItemui5-libasictitle, description, icon, info, infoState, highlight, type, selected; no counter/avatar
sap.m.CustomListItemui5-li-customfull
sap.m.Treeui5-treebasicnested array binding (sorter, length, startIndex at the top level), headerText, mode, headerToolbar, toggleOpenState/itemPress/selectionChange
sap.m.StandardTreeItemui5-tree-itemfull
sap.m.Dialogui5-dialog + ui5-bar footerbasictitle, icon, state, content size, buttons/begin/endButton/footer, custom header, afterClose; type Message not distinguished
sap.m.Popoverui5-popoverbasictitle, placement, modal, content size, footer, afterClose
sap.m.MessageStripui5-message-stripfull
sap.ui.core.CustomData (tolerated)none (no UI)fulltolerated, no UI
sap.m.FlexItemData (tolerated)none (no UI)fullapplied to the parent control as CSS flex
sap.ui.layout.GridData (tolerated)none (no UI)fullapplied to the parent control as grid span
sap.m.OverflowToolbarLayoutData (tolerated)none (no UI)fulltolerated, no UI

Beyond v1 (31):

UI5 controlrendered asstatusbasic: what is left out
sap.m.ActionListItemui5-lifull
sap.m.AppHTML/CSSfull
sap.m.Avatarui5-avatarbasic
sap.m.BusyIndicatorui5-busy-indicatorfull
sap.m.DateRangeSelectionui5-daterange-pickerbasicvalue only (no dateValue/secondDateValue)
sap.m.DisplayListItemui5-lifull
sap.m.FormattedTextHTML/CSSbasicsanitized HTML; no controls aggregation
sap.m.GenericTagui5-tagbasic
sap.m.GroupHeaderListItemui5-libasic
sap.m.IconTabSeparatorui5-tab-separatorfull
sap.m.MaskInputui5-inputbasica plain input: the mask is shown as placeholder, not enforced
sap.m.NavContainerHTML/CSSbasicshows the initial (or first) page; to() by CONTROL_BY_ID is not supported
sap.m.ObjectAttributeui5-linkbasic
sap.m.ObjectHeaderui5-titlebasictitle, number, attributes and statuses; no intro, icon, markers
sap.m.ObjectListItemui5-libasictitle, intro, number, icon; attributes and statuses are not shown
sap.m.RadioButtonui5-radio-buttonfull
sap.m.RadioButtonGroupHTML/CSSfull
sap.m.RatingIndicatorui5-rating-indicatorfull
sap.m.ResponsivePopoverui5-popoverbasicas Popover (no phone-fullscreen variant)
sap.m.Sliderui5-sliderfull
sap.m.SuggestionItemHTML/CSSbasic
sap.m.TimePickerui5-time-pickerbasic
sap.m.ToolbarSeparatorui5-toolbar-separatorfull
sap.ui.core.FragmentDefinitionHTML/CSSfull
sap.ui.core.InvisibleTextnone (no UI)full
sap.ui.core.SeparatorItemui5-optionbasic
sap.ui.core.mvc.ViewHTML/CSSfull
sap.ui.core.mvc.XMLViewHTML/CSSfull
sap.ui.layout.form.FormCSS grid + ui5-titlebasic
sap.ui.layout.form.FormContainerui5-titlebasic
sap.ui.layout.form.FormElementui5-labelbasic

"basic" = the members listed are rendered; any other property of the control is accepted, ignored and logged (property: in the console), as the profile requires.

Limits

  • Not rendered: controls outside the portable profile (sap.ui.table, sap.f, sap.uxap, sap.ui.comp, z2ui5.cc custom controls, ...) - visible box + diagnostics; formatter functions other than the profile's Formatter.Date*; named models other than device>; XML templating (template:repeat); CONTROL_BY_ID calls and BINDING_CALL (excluded from the portable profile); prevent_default_expr; expressions outside the profile grammar (RegExp, odata.*).
  • Frontend actions the profile allows but this frontend does not run yet (skipped and reported): DOWNLOAD_B64_FILE, SCROLL_TO, SCROLL_INTO_VIEW, SET_FAVICON, SYSTEM_LOGOUT, STORE_DATA, KEYBOARD_SHORTCUT, PLAY_AUDIO, SET_SIZE_LIMIT (the last one MAY be a no-op).
  • Deviations from the UI5 rendering: SimpleForm is a two-column CSS grid (Label opens a row, Title opens a group) rather than ui5-form; MessageToast position options are ignored; DatePicker.dateValue is one-way (a formatter binding, as in UI5 - the edit travels through value); growing renders on the client (all rows are in the model, as with UI5's JSON model).
  • NEST/NEST2 (profile v1.1) are rendered into the MAIN control the display names, appended to its content.
  • Backend concurrency: the e2e tests run with one worker - the transpiled framework in @abap2ui5/node-runtime keeps request state in static attributes, and two roundtrips interleaving in one Node process were seen to read each other's app data.

Development

  • npm run vendor -- /path/to/mcp-server [--ref <sha>] re-vendors the agent modules; npm run vendor:check verifies them.
  • node scripts/vendor-profile.mjs /path/to/protocol [--ref <rev>] re-copies profile/portable-v1.json (default origin/main) and records the commit in profile/source.json.
  • node scripts/vendor-samples.mjs /path/to/samples re-copies the demo apps listed in demo/apps.json; node scripts/record-fixtures.mjs re-records the views the renderer unit tests render.
  • node scripts/generate-coverage.mjs regenerates the table above (npm test fails when it is stale).

See AGENTS.md for the repository rules and CHANGELOG.md for the history.

License

MIT

MIT, read

History

Latest

v0.1.0

Other 6

Notes

First version.

  • Core protocol client (src/core/): app start with location and S_DEVICE, events with T_EVENT_ARG and the model delta of the edited paths (__delta rows for table cells), the draft id, the five view slots (response bookkeeping by the vendored applyResponse), POPUP/POPOVER torn down on an APP change, the app stack followed through S_FRONT.APP, the PROTOCOL check, error texts of failed roundtrips with Restart, one roundtrip at a time with the queue-last and no-busy wire flags; fetch transport with sap-contextid, the CSRF token handshake, credentials and extra headers.
  • Renderer (src/render/): view XML to UI5 Web Components through a control registry - all 65 controls of portable profile v1 plus 31 more; unknown controls as a visible box with their children still rendered, and a diagnostics panel / console / abap2ui5-diagnostic event.
  • Bindings: paths, list bindings with templates, element binding, two-way binding of value-like properties, typed display formatting, expression bindings in the profile grammar (own parser, no eval), composite parts, the device> model; formatters as visible placeholders.
  • Frontend actions: message toast and box (incl. client-composed texts, custom actions, onClose), popup/popover close, SET_TITLE, START_TIMER, SET_FOCUS, clipboard, URL actions with the UI5 frontend's URL rules, theming, busy indicator.
  • Packaging: dist/abap2ui5-wc.js (registers <abap2ui5-app>), dist/index.html (standalone start, ?app_start=), on-demand chunks for icons, CLDR data and themes; embedding examples.
  • Demo and tests: 14 sample apps of abap2UI5/samples on @abap2ui5/node-runtime 1.146.0; Playwright tests of every app with a cross-check of the request bodies and models against the official UI5 SPA served by the same backend; unit tests on node:test and happy-dom; screenshots in docs/screenshots/; CI.

Others providing20

UI written in ABAP
  1. abap2UI5-localabap2UI5 folded into the local classes of one HTTP handlerfrom ABAP
  2. abap2UI5UI5 apps written as one ABAP class, rendered by a generic shellfrom ABAP
  3. abap-cloud-guiReport-style programming model for abap2UI5 on ABAP Cloudfrom ABAP
  4. custom-controlsThirteen custom UI5 controls for abap2UI5 appsfrom ABAP
  5. http-connectorForwards abap2UI5 roundtrips to another system over HTTPfrom ABAP
  6. layout-managementTable and form layouts with saved variants for abap2UI5from ABAP
  7. abap2UI5 for ExcelOffice add-in running an abap2UI5 app in Excel's task panefrom ABAP
  8. abap2UI5-addons/popupsReady-made dialogs for abap2UI5 appsfrom ABAP
  9. rap-extFloorplans rendered from CDS UI annotations as abap2UI5 appsfrom ABAP
  10. selection-screenSelect-options with saved variants for abap2UI5 appsfrom ABAP
  11. abap2UI5 frontendabap2UI5 frontend as ABAP artefacts installed with abapGitfrom ABAP
  12. abap2UI5 Layout EditorDrag-and-drop UI5 view editor that writes an abap2UI5 app classfrom ABAP
  13. abap2UI5 protocolVersioned specification of the abap2UI5 roundtrip protocolfrom ABAP
  14. ZFPM_TOOLSEdits, copies and transports a whole FPM hierarchy at oncefrom ABAP
  15. ZWD_CALENDAR_VHWeb Dynpro ABAP calendar value help for date fieldsfrom ABAP
  16. abap_mustacheMustache template engine for ABAPfrom ABAP
Web Components interop
  1. @openui5/sap.ui.coreFramework core: module loader, MVC runtime, binding, routing, themingfrom UI5
  2. ui5-webcomponents-bundleCustom UI5 Web Components bundle loaded with one script tagfrom UI5
  3. @ui5/tooling-webcDeprecated UI5 Tooling extensions for UI5 Web Components wrappersfrom UI5
  4. @ui5/webcomponentsSAP's UI elements as standard custom elementsfrom UI5

Details

Sources3
GitHub APIdiscovered herechecked
github.com/abap2UI5/frontend-webcomponenttree, 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
UI5 / Web Components
“Frontend with UI5 Web Components – no UI5 core, one embeddable custom element” — abap2UI5/frontend-webcomponent — READMEchecked
Contributors1

From the repository’s contributor list, .

History in the atlas1
  1. First seen.
For your agent
Ref
artifact:abap2ui5-frontend-webcomponent
JSON
/artifacts/abap2ui5-frontend-webcomponent.json
MCP
Connecting an agent