Skip to content

feat(plugins/html): add sap.html opt-in plugin for native HTML tags - #13

Open
petermuessig wants to merge 3 commits into
mainfrom
feat/sap-html-plugin
Open

petermuessig wants to merge 3 commits into
mainfrom
feat/sap-html-plugin

Conversation

@petermuessig

@petermuessig petermuessig commented Sep 18, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds a new plugins/html opt-in package that maps lowercase HTML tags in TSX views to the corresponding sap.html.* UI5 control classes (available from OpenUI5 1.154.0), making native HTML feel as first-class as any other control — no per-tag imports required.

  • Opt-in scope — withScope(htmlScope, () => …) enables HTML tags for a subtree; outside the scope, lowercase tags throw a clear error.
  • Tag resolution — first character uppercased, rest as-is: <div> → sap/html/Div, <h1> → sap/html/H1, <blockquote> → sap/html/Blockquote.
  • Text children — sole text child → text property; mixed text + controls → sap.ui.core.html.TextContent wrappers preserving source order; void elements (<br>, <input>, …) reject children.
  • Preload — preloadSapHtml() reads the library metadata's controls list and async-requires every sap/html/* module in one batch, so the sync resolver always finds them.
  • Full UI5 pipeline reused — data binding, dot-handler events, class=, ref=, and auto-prefix-id all work unchanged.

Changes

Area What changed
packages/jsx-runtime/src/plugins/html/index.ts New plugin: tagToModulePath, resolveHtmlControl, normaliseHtmlProps, sapHtmlIntrinsic, htmlScope, preloadSapHtml
packages/jsx-runtime/src/plugins/html/README.md Plugin documentation
packages/jsx-runtime/package.json Added ./plugins/html exports subpath
packages/jsx-runtime/src/runtime/runtime.ts Replaced permissive HTMLAttributes bag in JSX.IntrinsicElements with per-tag types (AnchorAttributes, InputAttributes, ButtonHtmlAttributes, …)
packages/jsx-runtime/scripts/jsx-runtime-aug.d.ts Re-exports for all new tag type interfaces
packages/jsx-runtime/test/qunit/plugins/html.qunit.ts 26 QUnit tests using patched sap.ui.require — no real sap.html required at test time
packages/jsx-runtime/test/qunit/testsuite.qunit.ts Registered plugins/html test suite
packages/jsx-runtime-showcase/ui5.yaml Bumped framework version to 1.154.0-SNAPSHOT, added sap.html library
packages/jsx-runtime-showcase/ui5-workspace.yaml Added local openui5 + sapui5.runtime workspace resolutions
packages/jsx-runtime-showcase/webapp/Component.ts async init() with await preloadSapHtml() before router init
packages/jsx-runtime-showcase/webapp/view/showcases/NativeHtml.tsx Chapter 19 showcase view
packages/jsx-runtime-showcase/webapp/docs/native-html.md Learn page
packages/jsx-runtime-showcase/webapp/docs/samples/native-html.md Explore sample description
packages/jsx-runtime-showcase/webapp/view/ExploreSample.tsx Added native-html registry entry
packages/jsx-runtime-showcase/webapp/controller/Explorer.controller.ts Added nav entries in Learn (Expert Corner) and Explore (Plugins)
packages/jsx-runtime-showcase/webapp/view/LearnDoc.tsx Added sap-icon://html5 icon case
docs/gotchas.md Updated "HTML intrinsic tags" section
.changeset/html-plugin-sap-html.md minor changeset — triggers a 0.2.0 version bump on release

Test plan

  • pnpm --filter @ui5-community/jsx-runtime build — compiles cleanly
  • pnpm --filter @ui5-community/jsx-runtime test — 26/26 plugins/html tests green, all other suites unchanged
  • Showcase with OpenUI5 1.154.0-SNAPSHOT — Native HTML sample renders; bound <input> updates model; MessageToast fires on button/link click

Maps lowercase HTML tags (<div>, <span>, <input>, …) to the
corresponding sap.html.* UI5 control classes introduced in OpenUI5
1.154.0, so native HTML can be written in TSX views without per-tag
imports.

Key design points:

- Opt-in via withScope(htmlScope, () => …); outside the scope,
  lowercase tags throw a clear "no htmlIntrinsic" error.
- Tag resolution: first character uppercased, rest unchanged
  ("div" → sap/html/Div, "h1" → sap/html/H1).
- Text children: sole text → `text` property; mixed text+controls →
  sap.ui.core.html.TextContent wrappers preserving source order;
  void elements reject children.
- preloadSapHtml() uses the library metadata's `controls` list to
  async-require every sap/html/* module in one batch, so the sync
  sap.ui.require resolver always finds them.
- Full UI5 pipeline reused: data binding, events, dot-handlers,
  class=, ref=, and auto-prefix-id all work unchanged.

Also includes:
- Per-tag JSX.IntrinsicElements types (AnchorAttributes,
  InputAttributes, ButtonHtmlAttributes, …) replacing the previous
  permissive HTMLAttributes bag.
- ./plugins/html exports subpath in package.json.
- NativeHtml.tsx showcase view (chapter 19) with live demo.
- Learn + Explore navigation entries and docs pages.
- QUnit tests (26 assertions) using fake sap.html controls via a
  patched sap.ui.require; no real sap.html library required at
  test time.
The ToolPage aside had no scroll context — `sapTntToolPage`'s
`overflow: hidden` clipped the NavigationList's scrollbar track so
items below the fold were unreachable. Adding `overflow-y: auto` on
`.sapTntToolPageAsideContent` surfaces a scrollbar on the nav panel.

Also scroll the active `.sapTntNLISelected` item into view on each
route change (setTimeout-deferred so the binding update lands first),
so deep-linking to a low item like "Plugins / Extend → Native HTML via
sap.html" reveals the selection without manual scrolling.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant