@ui5/webcomponents-base 2.20.0 → 2.20.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/.tsbuildinfobuild +1 -1
- package/dist/createReactComponent.d.ts +26 -0
- package/dist/createReactComponent.js +51 -0
- package/dist/createReactComponent.js.map +1 -0
- package/dist/custom-elements-internal.json +15 -0
- package/dist/custom-elements.json +15 -0
- package/dist/generated/VersionInfo.js +3 -3
- package/dist/generated/VersionInfo.js.map +1 -1
- package/dist/prod/createReactComponent.js +2 -0
- package/dist/prod/createReactComponent.js.map +7 -0
- package/dist/prod/generated/VersionInfo.js +1 -1
- package/dist/prod/generated/VersionInfo.js.map +1 -1
- package/dist/prod/sap/base/Log.js +15 -29
- package/dist/prod/sap/base/assert.js +1 -1
- package/dist/prod/sap/base/config/MemoryConfigurationProvider.js +1 -1
- package/dist/prod/sap/base/security/URLListValidator.js +9 -5
- package/dist/prod/sap/base/security/encodeCSS.js +1 -1
- package/dist/prod/sap/base/security/encodeXML.js +1 -1
- package/dist/prod/sap/base/security/sanitizeHTML.js +1 -1
- package/dist/prod/sap/base/strings/toHex.js +1 -1
- package/dist/prod/sap/base/util/now.js +7 -13
- package/dist/prod/sap/base/util/uid.js +1 -1
- package/dist/prod/sap/ui/thirdparty/caja-html-sanitizer.js +15 -3
- package/dist/react18/createReactComponent.d.ts +38 -0
- package/dist/react18/createReactComponent.js +112 -0
- package/dist/react18/createReactComponent.js.map +1 -0
- package/dist/sap/base/Log.js +15 -29
- package/dist/sap/base/assert.js +1 -1
- package/dist/sap/base/config/MemoryConfigurationProvider.js +1 -1
- package/dist/sap/base/security/URLListValidator.js +9 -5
- package/dist/sap/base/security/encodeCSS.js +1 -1
- package/dist/sap/base/security/encodeXML.js +1 -1
- package/dist/sap/base/security/sanitizeHTML.js +1 -1
- package/dist/sap/base/strings/toHex.js +1 -1
- package/dist/sap/base/util/now.js +7 -13
- package/dist/sap/base/util/uid.js +1 -1
- package/dist/sap/ui/thirdparty/caja-html-sanitizer.js +15 -3
- package/package.json +12 -4
- package/src/react18/createReactComponent.tsx +140 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React wrapper factory for UI5 Web Components.
|
|
3
|
+
*
|
|
4
|
+
* This lightweight factory creates typed React components that wrap UI5 Web Components.
|
|
5
|
+
* It handles:
|
|
6
|
+
* - Event prop conversion (onXxx → ui5-xxx event listeners)
|
|
7
|
+
* - Ref forwarding
|
|
8
|
+
* - Children handling
|
|
9
|
+
*
|
|
10
|
+
* Note: Supports React >=19.
|
|
11
|
+
*
|
|
12
|
+
* Note: This is for documentation samples only - for production React apps,
|
|
13
|
+
* use the official @ui5/webcomponents-react library.
|
|
14
|
+
*/
|
|
15
|
+
import type UI5Element from "@ui5/webcomponents-base/dist/UI5Element.js";
|
|
16
|
+
/**
|
|
17
|
+
* Creates a React component wrapper for a UI5 Web Component.
|
|
18
|
+
*
|
|
19
|
+
* @param ComponentClass - The UI5 Web Component class (e.g., Button from "@ui5/webcomponents/dist/Button.js")
|
|
20
|
+
* @returns A React component that renders the custom element with proper TypeScript types
|
|
21
|
+
* @since 2.21.0
|
|
22
|
+
* @example
|
|
23
|
+
* import Button from "@ui5/webcomponents/dist/Button.js";
|
|
24
|
+
* const ReactButton = createReactComponent(Button);
|
|
25
|
+
*/
|
|
26
|
+
export default function createReactComponent<T extends typeof UI5Element>(klass: T): (props: InstanceType<T>["_jsxProps"]) => import("react").DOMElement<Record<string, unknown>, Element>;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React wrapper factory for UI5 Web Components.
|
|
3
|
+
*
|
|
4
|
+
* This lightweight factory creates typed React components that wrap UI5 Web Components.
|
|
5
|
+
* It handles:
|
|
6
|
+
* - Event prop conversion (onXxx → ui5-xxx event listeners)
|
|
7
|
+
* - Ref forwarding
|
|
8
|
+
* - Children handling
|
|
9
|
+
*
|
|
10
|
+
* Note: Supports React >=19.
|
|
11
|
+
*
|
|
12
|
+
* Note: This is for documentation samples only - for production React apps,
|
|
13
|
+
* use the official @ui5/webcomponents-react library.
|
|
14
|
+
*/
|
|
15
|
+
import { createElement } from "react";
|
|
16
|
+
/**
|
|
17
|
+
* Creates a React component wrapper for a UI5 Web Component.
|
|
18
|
+
*
|
|
19
|
+
* @param ComponentClass - The UI5 Web Component class (e.g., Button from "@ui5/webcomponents/dist/Button.js")
|
|
20
|
+
* @returns A React component that renders the custom element with proper TypeScript types
|
|
21
|
+
* @since 2.21.0
|
|
22
|
+
* @example
|
|
23
|
+
* import Button from "@ui5/webcomponents/dist/Button.js";
|
|
24
|
+
* const ReactButton = createReactComponent(Button);
|
|
25
|
+
*/
|
|
26
|
+
export default function createReactComponent(klass) {
|
|
27
|
+
const tag = klass.getMetadata().getTag();
|
|
28
|
+
return function Component(props) {
|
|
29
|
+
const patchedProps = {};
|
|
30
|
+
Object.entries(props).forEach(([key, value]) => {
|
|
31
|
+
if (key.startsWith("on") && typeof value === "function") {
|
|
32
|
+
// React 19 wraps DOM events (change, click, input, etc.) in SyntheticEvent,
|
|
33
|
+
// hiding CustomEvent.detail under nativeEvent.detail.
|
|
34
|
+
// Patch all event handlers to restore detail from nativeEvent.
|
|
35
|
+
const originalHandler = value;
|
|
36
|
+
patchedProps[key] = (e) => {
|
|
37
|
+
const nativeDetail = e.nativeEvent?.detail;
|
|
38
|
+
if (nativeDetail !== undefined) {
|
|
39
|
+
e.detail = nativeDetail;
|
|
40
|
+
}
|
|
41
|
+
originalHandler(e);
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
patchedProps[key] = value;
|
|
46
|
+
}
|
|
47
|
+
});
|
|
48
|
+
return createElement(tag, patchedProps);
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=createReactComponent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"createReactComponent.js","sourceRoot":"","sources":["../src/createReactComponent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC;AAGtC;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,UAAU,oBAAoB,CAA8B,KAAQ;IACjF,MAAM,GAAG,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC,MAAM,EAAE,CAAC;IAEzC,OAAO,SAAS,SAAS,CAAC,KAAmC;QAC5D,MAAM,YAAY,GAA4B,EAAE,CAAC;QAEjD,MAAM,CAAC,OAAO,CAAC,KAAgC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,EAAE,KAAK,CAAC,EAAE,EAAE;YACzE,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,OAAO,KAAK,KAAK,UAAU,EAAE,CAAC;gBACzD,4EAA4E;gBAC5E,sDAAsD;gBACtD,+DAA+D;gBAC/D,MAAM,eAAe,GAAG,KAAK,CAAC;gBAC9B,YAAY,CAAC,GAAG,CAAC,GAAG,CAAC,CAAQ,EAAE,EAAE;oBAChC,MAAM,YAAY,GAAI,CAAsD,CAAC,WAAW,EAAE,MAAM,CAAC;oBACjG,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;wBAC/B,CAAoC,CAAC,MAAM,GAAG,YAAY,CAAC;oBAC7D,CAAC;oBACD,eAAe,CAAC,CAAC,CAAC,CAAC;gBACpB,CAAC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACP,YAAY,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;YAC3B,CAAC;QACF,CAAC,CAAC,CAAC;QAEH,OAAO,aAAa,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;IACzC,CAAC,CAAC;AACH,CAAC","sourcesContent":["/**\n * React wrapper factory for UI5 Web Components.\n *\n * This lightweight factory creates typed React components that wrap UI5 Web Components.\n * It handles:\n * - Event prop conversion (onXxx → ui5-xxx event listeners)\n * - Ref forwarding\n * - Children handling\n *\n * Note: Supports React >=19.\n *\n * Note: This is for documentation samples only - for production React apps,\n * use the official @ui5/webcomponents-react library.\n */\n\nimport { createElement } from \"react\";\nimport type UI5Element from \"@ui5/webcomponents-base/dist/UI5Element.js\";\n\n/**\n * Creates a React component wrapper for a UI5 Web Component.\n *\n * @param ComponentClass - The UI5 Web Component class (e.g., Button from \"@ui5/webcomponents/dist/Button.js\")\n * @returns A React component that renders the custom element with proper TypeScript types\n * @since 2.21.0\n * @example\n * import Button from \"@ui5/webcomponents/dist/Button.js\";\n * const ReactButton = createReactComponent(Button);\n */\nexport default function createReactComponent<T extends typeof UI5Element>(klass: T) {\n\tconst tag = klass.getMetadata().getTag();\n\n\treturn function Component(props: InstanceType<T>[\"_jsxProps\"]) {\n\t\tconst patchedProps: Record<string, unknown> = {};\n\n\t\tObject.entries(props as Record<string, unknown>).forEach(([key, value]) => {\n\t\t\tif (key.startsWith(\"on\") && typeof value === \"function\") {\n\t\t\t\t// React 19 wraps DOM events (change, click, input, etc.) in SyntheticEvent,\n\t\t\t\t// hiding CustomEvent.detail under nativeEvent.detail.\n\t\t\t\t// Patch all event handlers to restore detail from nativeEvent.\n\t\t\t\tconst originalHandler = value;\n\t\t\t\tpatchedProps[key] = (e: Event) => {\n\t\t\t\t\tconst nativeDetail = (e as unknown as { nativeEvent?: { detail: unknown } }).nativeEvent?.detail;\n\t\t\t\t\tif (nativeDetail !== undefined) {\n\t\t\t\t\t\t(e as unknown as { detail: unknown }).detail = nativeDetail;\n\t\t\t\t\t}\n\t\t\t\t\toriginalHandler(e);\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tpatchedProps[key] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn createElement(tag, patchedProps);\n\t};\n}\n"]}
|
|
@@ -842,6 +842,21 @@
|
|
|
842
842
|
}
|
|
843
843
|
]
|
|
844
844
|
},
|
|
845
|
+
{
|
|
846
|
+
"kind": "javascript-module",
|
|
847
|
+
"path": "dist/createReactComponent.js",
|
|
848
|
+
"declarations": [],
|
|
849
|
+
"exports": [
|
|
850
|
+
{
|
|
851
|
+
"kind": "js",
|
|
852
|
+
"name": "default",
|
|
853
|
+
"declaration": {
|
|
854
|
+
"name": "createReactComponent",
|
|
855
|
+
"module": "dist/createReactComponent.js"
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
]
|
|
859
|
+
},
|
|
845
860
|
{
|
|
846
861
|
"kind": "javascript-module",
|
|
847
862
|
"path": "dist/decorators.js",
|
|
@@ -827,6 +827,21 @@
|
|
|
827
827
|
}
|
|
828
828
|
]
|
|
829
829
|
},
|
|
830
|
+
{
|
|
831
|
+
"kind": "javascript-module",
|
|
832
|
+
"path": "dist/createReactComponent.js",
|
|
833
|
+
"declarations": [],
|
|
834
|
+
"exports": [
|
|
835
|
+
{
|
|
836
|
+
"kind": "js",
|
|
837
|
+
"name": "default",
|
|
838
|
+
"declaration": {
|
|
839
|
+
"name": "createReactComponent",
|
|
840
|
+
"module": "dist/createReactComponent.js"
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
]
|
|
844
|
+
},
|
|
830
845
|
{
|
|
831
846
|
"kind": "javascript-module",
|
|
832
847
|
"path": "dist/decorators.js",
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
const VersionInfo = {
|
|
2
|
-
version: "2.20.
|
|
2
|
+
version: "2.20.2",
|
|
3
3
|
major: 2,
|
|
4
4
|
minor: 20,
|
|
5
|
-
patch:
|
|
5
|
+
patch: 2,
|
|
6
6
|
suffix: "",
|
|
7
7
|
isNext: false,
|
|
8
|
-
buildTime:
|
|
8
|
+
buildTime: 1774015045,
|
|
9
9
|
};
|
|
10
10
|
export default VersionInfo;
|
|
11
11
|
//# sourceMappingURL=VersionInfo.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VersionInfo.js","sourceRoot":"","sources":["../../src/generated/VersionInfo.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG;IACnB,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,EAAE;IACV,MAAM,EAAE,KAAK;IACb,SAAS,EAAE,UAAU;CACrB,CAAC;AACF,eAAe,WAAW,CAAC","sourcesContent":["const VersionInfo = {\n\tversion: \"2.20.
|
|
1
|
+
{"version":3,"file":"VersionInfo.js","sourceRoot":"","sources":["../../src/generated/VersionInfo.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,GAAG;IACnB,OAAO,EAAE,QAAQ;IACjB,KAAK,EAAE,CAAC;IACR,KAAK,EAAE,EAAE;IACT,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,EAAE;IACV,MAAM,EAAE,KAAK;IACb,SAAS,EAAE,UAAU;CACrB,CAAC;AACF,eAAe,WAAW,CAAC","sourcesContent":["const VersionInfo = {\n\tversion: \"2.20.2\",\n\tmajor: 2,\n\tminor: 20,\n\tpatch: 2,\n\tsuffix: \"\",\n\tisNext: false,\n\tbuildTime: 1774015045,\n};\nexport default VersionInfo;"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";import{createElement as d}from"react";export default function p(i){const s=i.getMetadata().getTag();return function(r){const n={};return Object.entries(r).forEach(([t,e])=>{if(t.startsWith("on")&&typeof e=="function"){const c=e;n[t]=o=>{const a=o.nativeEvent?.detail;a!==void 0&&(o.detail=a),c(o)}}else n[t]=e}),d(s,n)}}
|
|
2
|
+
//# sourceMappingURL=createReactComponent.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/createReactComponent.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * React wrapper factory for UI5 Web Components.\n *\n * This lightweight factory creates typed React components that wrap UI5 Web Components.\n * It handles:\n * - Event prop conversion (onXxx \u2192 ui5-xxx event listeners)\n * - Ref forwarding\n * - Children handling\n *\n * Note: Supports React >=19.\n *\n * Note: This is for documentation samples only - for production React apps,\n * use the official @ui5/webcomponents-react library.\n */\n\nimport { createElement } from \"react\";\nimport type UI5Element from \"@ui5/webcomponents-base/dist/UI5Element.js\";\n\n/**\n * Creates a React component wrapper for a UI5 Web Component.\n *\n * @param ComponentClass - The UI5 Web Component class (e.g., Button from \"@ui5/webcomponents/dist/Button.js\")\n * @returns A React component that renders the custom element with proper TypeScript types\n * @since 2.21.0\n * @example\n * import Button from \"@ui5/webcomponents/dist/Button.js\";\n * const ReactButton = createReactComponent(Button);\n */\nexport default function createReactComponent<T extends typeof UI5Element>(klass: T) {\n\tconst tag = klass.getMetadata().getTag();\n\n\treturn function Component(props: InstanceType<T>[\"_jsxProps\"]) {\n\t\tconst patchedProps: Record<string, unknown> = {};\n\n\t\tObject.entries(props as Record<string, unknown>).forEach(([key, value]) => {\n\t\t\tif (key.startsWith(\"on\") && typeof value === \"function\") {\n\t\t\t\t// React 19 wraps DOM events (change, click, input, etc.) in SyntheticEvent,\n\t\t\t\t// hiding CustomEvent.detail under nativeEvent.detail.\n\t\t\t\t// Patch all event handlers to restore detail from nativeEvent.\n\t\t\t\tconst originalHandler = value;\n\t\t\t\tpatchedProps[key] = (e: Event) => {\n\t\t\t\t\tconst nativeDetail = (e as unknown as { nativeEvent?: { detail: unknown } }).nativeEvent?.detail;\n\t\t\t\t\tif (nativeDetail !== undefined) {\n\t\t\t\t\t\t(e as unknown as { detail: unknown }).detail = nativeDetail;\n\t\t\t\t\t}\n\t\t\t\t\toriginalHandler(e);\n\t\t\t\t};\n\t\t\t} else {\n\t\t\t\tpatchedProps[key] = value;\n\t\t\t}\n\t\t});\n\n\t\treturn createElement(tag, patchedProps);\n\t};\n}\n"],
|
|
5
|
+
"mappings": "aAeA,OAAS,iBAAAA,MAAqB,QAa9B,wBAAwBC,EAAkDC,EAAU,CACnF,MAAMC,EAAMD,EAAM,YAAY,EAAE,OAAO,EAEvC,OAAO,SAAmBE,EAAqC,CAC9D,MAAMC,EAAwC,CAAC,EAE/C,cAAO,QAAQD,CAAgC,EAAE,QAAQ,CAAC,CAACE,EAAKC,CAAK,IAAM,CAC1E,GAAID,EAAI,WAAW,IAAI,GAAK,OAAOC,GAAU,WAAY,CAIxD,MAAMC,EAAkBD,EACxBF,EAAaC,CAAG,EAAKG,GAAa,CACjC,MAAMC,EAAgBD,EAAuD,aAAa,OACtFC,IAAiB,SACnBD,EAAqC,OAASC,GAEhDF,EAAgBC,CAAC,CAClB,CACD,MACCJ,EAAaC,CAAG,EAAIC,CAEtB,CAAC,EAEMP,EAAcG,EAAKE,CAAY,CACvC,CACD",
|
|
6
|
+
"names": ["createElement", "createReactComponent", "klass", "tag", "props", "patchedProps", "key", "value", "originalHandler", "e", "nativeDetail"]
|
|
7
|
+
}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const e={version:"2.20.
|
|
1
|
+
"use strict";const e={version:"2.20.2",major:2,minor:20,patch:2,suffix:"",isNext:!1,buildTime:1774015045};export default e;
|
|
2
2
|
//# sourceMappingURL=VersionInfo.js.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../src/generated/VersionInfo.ts"],
|
|
4
|
-
"sourcesContent": ["const VersionInfo = {\n\tversion: \"2.20.
|
|
4
|
+
"sourcesContent": ["const VersionInfo = {\n\tversion: \"2.20.2\",\n\tmajor: 2,\n\tminor: 20,\n\tpatch: 2,\n\tsuffix: \"\",\n\tisNext: false,\n\tbuildTime: 1774015045,\n};\nexport default VersionInfo;"],
|
|
5
5
|
"mappings": "aAAA,MAAMA,EAAc,CACnB,QAAS,SACT,MAAO,EACP,MAAO,GACP,MAAO,EACP,OAAQ,GACR,OAAQ,GACR,UAAW,UACZ,EACA,eAAeA",
|
|
6
6
|
"names": ["VersionInfo"]
|
|
7
7
|
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
/*!
|
|
2
2
|
* OpenUI5
|
|
3
|
-
* (c) Copyright
|
|
3
|
+
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
|
|
4
4
|
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
|
|
5
5
|
*/
|
|
6
|
-
import BaseConfig from "./config.js";
|
|
7
6
|
import now from "./util/now.js";
|
|
8
7
|
/**
|
|
9
8
|
* A Logging API for JavaScript.
|
|
@@ -202,8 +201,8 @@ function getLogEntryListenerInstance() {
|
|
|
202
201
|
* Name of the component that produced the log entry
|
|
203
202
|
* @param {function} [fnSupportInfo]
|
|
204
203
|
* Callback that returns an additional support object to be logged in support mode.
|
|
205
|
-
* This function is only called if support info mode is turned on
|
|
206
|
-
*
|
|
204
|
+
* This function is only called if support info mode is turned on via
|
|
205
|
+
* the Support Assistant. To avoid negative effects regarding execution times and
|
|
207
206
|
* memory consumption, the returned object should be a simple immutable JSON object with mostly
|
|
208
207
|
* static and stable content.
|
|
209
208
|
* @public
|
|
@@ -225,8 +224,8 @@ Log.fatal = function (sMessage, vDetails, sComponent, fnSupportInfo) {
|
|
|
225
224
|
* Name of the component that produced the log entry
|
|
226
225
|
* @param {function} [fnSupportInfo]
|
|
227
226
|
* Callback that returns an additional support object to be logged in support mode.
|
|
228
|
-
* This function is only called if support info mode is turned on
|
|
229
|
-
*
|
|
227
|
+
* This function is only called if support info mode is turned on via
|
|
228
|
+
* the Support Assistant. To avoid negative effects regarding execution times and
|
|
230
229
|
* memory consumption, the returned object should be a simple immutable JSON object with mostly
|
|
231
230
|
* static and stable content.
|
|
232
231
|
* @public
|
|
@@ -248,8 +247,8 @@ Log.error = function (sMessage, vDetails, sComponent, fnSupportInfo) {
|
|
|
248
247
|
* Name of the component that produced the log entry
|
|
249
248
|
* @param {function} [fnSupportInfo]
|
|
250
249
|
* Callback that returns an additional support object to be logged in support mode.
|
|
251
|
-
* This function is only called if support info mode is turned on
|
|
252
|
-
*
|
|
250
|
+
* This function is only called if support info mode is turned on via
|
|
251
|
+
* the Support Assistant. To avoid negative effects regarding execution times and
|
|
253
252
|
* memory consumption, the returned object should be a simple immutable JSON object with mostly
|
|
254
253
|
* static and stable content.
|
|
255
254
|
* @public
|
|
@@ -271,8 +270,8 @@ Log.warning = function (sMessage, vDetails, sComponent, fnSupportInfo) {
|
|
|
271
270
|
* Name of the component that produced the log entry
|
|
272
271
|
* @param {function} [fnSupportInfo]
|
|
273
272
|
* Callback that returns an additional support object to be logged in support mode.
|
|
274
|
-
* This function is only called if support info mode is turned on
|
|
275
|
-
*
|
|
273
|
+
* This function is only called if support info mode is turned on via
|
|
274
|
+
* the Support Assistant. To avoid negative effects regarding execution times and
|
|
276
275
|
* memory consumption, the returned object should be a simple immutable JSON object with mostly
|
|
277
276
|
* static and stable content.
|
|
278
277
|
* @public
|
|
@@ -294,8 +293,8 @@ Log.info = function (sMessage, vDetails, sComponent, fnSupportInfo) {
|
|
|
294
293
|
* Name of the component that produced the log entry
|
|
295
294
|
* @param {function} [fnSupportInfo]
|
|
296
295
|
* Callback that returns an additional support object to be logged in support mode.
|
|
297
|
-
* This function is only called if support info mode is turned on
|
|
298
|
-
*
|
|
296
|
+
* This function is only called if support info mode is turned on via
|
|
297
|
+
* the Support Assistant. To avoid negative effects regarding execution times and
|
|
299
298
|
* memory consumption, the returned object should be a simple immutable JSON object with mostly
|
|
300
299
|
* static and stable content.
|
|
301
300
|
* @public
|
|
@@ -317,8 +316,8 @@ Log.debug = function (sMessage, vDetails, sComponent, fnSupportInfo) {
|
|
|
317
316
|
* Name of the component that produced the log entry
|
|
318
317
|
* @param {function} [fnSupportInfo]
|
|
319
318
|
* Callback that returns an additional support object to be logged in support mode.
|
|
320
|
-
* This function is only called if support info mode is turned on
|
|
321
|
-
*
|
|
319
|
+
* This function is only called if support info mode is turned on via
|
|
320
|
+
* the Support Assistant. To avoid negative effects regarding execution times and
|
|
322
321
|
* memory consumption, the returned object should be a simple immutable JSON object with mostly
|
|
323
322
|
* static and stable content.
|
|
324
323
|
* @public
|
|
@@ -418,8 +417,8 @@ Log.logSupportInfo = function (bEnabled) {
|
|
|
418
417
|
* @param {string} [sComponent]
|
|
419
418
|
* The log component under which the message should be logged
|
|
420
419
|
* @param {function} [fnSupportInfo] Callback that returns an additional support object to be
|
|
421
|
-
* logged in support mode. This function is only called if support info mode is turned on
|
|
422
|
-
*
|
|
420
|
+
* logged in support mode. This function is only called if support info mode is turned on via
|
|
421
|
+
* the Support Assistant. To avoid negative effects regarding execution times and
|
|
423
422
|
* memory consumption, the returned object should be a simple immutable JSON object with mostly
|
|
424
423
|
* static and stable content.
|
|
425
424
|
* @returns {module:sap/base/Log.Entry}
|
|
@@ -734,17 +733,4 @@ Log.getLogger = function (sComponent, iDefaultLogLevel) {
|
|
|
734
733
|
}
|
|
735
734
|
return new Logger(sComponent);
|
|
736
735
|
};
|
|
737
|
-
|
|
738
|
-
// set LogLevel
|
|
739
|
-
const sLogLevel = BaseConfig.get({
|
|
740
|
-
name: "sapUiLogLevel",
|
|
741
|
-
type: BaseConfig.Type.String,
|
|
742
|
-
defaultValue: undefined,
|
|
743
|
-
external: true
|
|
744
|
-
});
|
|
745
|
-
if (sLogLevel) {
|
|
746
|
-
Log.setLevel(Log.Level[sLogLevel.toUpperCase()] || parseInt(sLogLevel));
|
|
747
|
-
} else if (!globalThis["sap-ui-optimized"]) {
|
|
748
|
-
Log.setLevel(Log.Level.DEBUG);
|
|
749
|
-
}
|
|
750
736
|
export default Log;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
// validation regexes
|
|
2
2
|
/*!
|
|
3
3
|
* OpenUI5
|
|
4
|
-
* (c) Copyright
|
|
4
|
+
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
|
|
5
5
|
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
var rBasicUrl = /^(?:([^:\/?#]+):)?((?:[\/\\]{2,}((
|
|
8
|
+
var rBasicUrl = /^(?:([^:\/?#]+):)?((?:[\/\\]{2,}(?:(?:[^@\/?#]*@)?(\[[^\]]+\]|[^\/?#:]+)(?::([0-9]+))?)?)?([^?#]*))(?:\?([^#]*))?(?:#(.*))?$/;
|
|
9
9
|
var rCheckPath = /^([a-z0-9-._~!$&'()*+,;=:@]|%[0-9a-f]{2})*$/i;
|
|
10
10
|
var rCheckQuery = /^([a-z0-9-._~!$&'()*+,;=:@\/?]|%[0-9a-f]{2})*$/i;
|
|
11
11
|
var rCheckFragment = rCheckQuery;
|
|
@@ -104,7 +104,8 @@ oURLListValidator.clear = function () {
|
|
|
104
104
|
* @param {string} [protocol] The protocol of the URL, can be falsy to allow all protocols for an entry e.g. "", "http", "mailto"
|
|
105
105
|
* @param {string} [host] The host of the URL, can be falsy to allow all hosts. A wildcard asterisk can be set at the beginning, e.g. "examples.com", "*.example.com"
|
|
106
106
|
* @param {string} [port] The port of the URL, can be falsy to allow all ports, e.g. "", "8080"
|
|
107
|
-
* @param {string} [path] the path of the URL,
|
|
107
|
+
* @param {string} [path] the path of the URL, e.g. "/my-news". Can be falsy to allow all paths. A wildcard asterisk can be set at the end to ensure a path starts with the given string, e.g. "/my-example*".
|
|
108
|
+
* When using wildcards, make sure to only provide normalized URLs to the validate function in order to mitigate the risk of path traversal attacks.
|
|
108
109
|
* @public
|
|
109
110
|
*/
|
|
110
111
|
oURLListValidator.add = function (protocol, host, port, path) {
|
|
@@ -139,13 +140,16 @@ oURLListValidator.entries = function () {
|
|
|
139
140
|
* Validates a URL. Check if it's not a script or other security issue.
|
|
140
141
|
*
|
|
141
142
|
* <b>Note</b>:
|
|
142
|
-
* It is strongly recommended to validate only absolute URLs. There's almost no case
|
|
143
|
+
* It is strongly recommended to validate only absolute, normalized URLs. There's almost no case
|
|
143
144
|
* where checking only the path of a URL would allow to ensure its validity.
|
|
144
|
-
* For compatibility reasons, this API cannot automatically resolve URLs relative to
|
|
145
|
+
* For compatibility reasons, this API does not normalize URLs and cannot automatically resolve URLs relative to
|
|
145
146
|
* <code>document.baseURI</code>, but callers should do so. In that case, and when the
|
|
146
147
|
* allow list is not empty, an entry for the origin of <code>document.baseURI</code>
|
|
147
148
|
* must be added to the allow list.
|
|
148
149
|
*
|
|
150
|
+
* Any measures to mitigate path traversal or similar attack vectors must be taken by the caller, e.g. by using the
|
|
151
|
+
* {@link https://developer.mozilla.org/docs/Web/API/URL URL} API to normalize the URL beforehand.
|
|
152
|
+
*
|
|
149
153
|
* <h3>Details</h3>
|
|
150
154
|
* Splits the given URL into components and checks for allowed characters according to RFC 3986:
|
|
151
155
|
*
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* @returns {string} padded hex representation of the given character code
|
|
16
16
|
*/ /*!
|
|
17
17
|
* OpenUI5
|
|
18
|
-
* (c) Copyright
|
|
18
|
+
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
|
|
19
19
|
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
|
|
20
20
|
*/
|
|
21
21
|
/*
|
|
@@ -1,9 +1,6 @@
|
|
|
1
|
-
// @evo-todo window.performance does not exist on node.js, but there is a module performance-now. Maybe use it
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
|
-
* Returns a high resolution timestamp in microseconds
|
|
5
|
-
* The timestamp is based on 01/01/1970 00:00:00 (UNIX epoch) as float with microsecond precision
|
|
6
|
-
* with millisecond precision, if high resolution timestamps are not available.
|
|
2
|
+
* Returns a high resolution timestamp in microseconds.
|
|
3
|
+
* The timestamp is based on 01/01/1970 00:00:00 (UNIX epoch) as float with microsecond precision.
|
|
7
4
|
* The fractional part of the timestamp represents fractions of a millisecond.
|
|
8
5
|
* Converting to a <code>Date</code> is possible by using <code>require(["sap/base/util/now"], function(now){new Date(now());}</code>
|
|
9
6
|
*
|
|
@@ -11,18 +8,15 @@
|
|
|
11
8
|
* @since 1.58
|
|
12
9
|
* @public
|
|
13
10
|
* @alias module:sap/base/util/now
|
|
14
|
-
* @returns {float} timestamp in microseconds
|
|
11
|
+
* @returns {float} timestamp in microseconds
|
|
15
12
|
*/ /*!
|
|
16
13
|
* OpenUI5
|
|
17
|
-
* (c) Copyright
|
|
14
|
+
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
|
|
18
15
|
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
|
|
19
16
|
*/
|
|
20
17
|
/*global performance */
|
|
21
18
|
|
|
22
|
-
var fnNow =
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
return iNavigationStart + performance.now();
|
|
26
|
-
};
|
|
27
|
-
}();
|
|
19
|
+
var fnNow = function now() {
|
|
20
|
+
return performance.timeOrigin + performance.now();
|
|
21
|
+
};
|
|
28
22
|
export default fnNow;
|
|
@@ -118,7 +118,11 @@ var cssSchema = (function () {
|
|
|
118
118
|
'inset' ], [ 'invert' ], [ 'justify' ], [ 'local' ], [ 'medium' ], [
|
|
119
119
|
'mix' ], [ 'none' ], [ 'normal' ], [ 'once' ], [ 'repeat' ], [ 'scroll'
|
|
120
120
|
], [ 'separate' ], [ 'small-caps' ], [ 'spell-out' ], [ 'transparent' ],
|
|
121
|
-
[ 'visible' ]
|
|
121
|
+
[ 'visible' ],
|
|
122
|
+
// ##### BEGIN: MODIFIED BY SAP
|
|
123
|
+
[ 'flex', 'inline-flex', 'grid', 'inline-grid', 'flow-root', 'contents' ], [ 'initial', 'revert', 'revert-layer', 'unset' ]
|
|
124
|
+
// ##### END: MODIFIED BY SAP
|
|
125
|
+
];
|
|
122
126
|
return {
|
|
123
127
|
'-moz-border-radius': {
|
|
124
128
|
'cssExtra': c[ 0 ],
|
|
@@ -440,7 +444,9 @@ var cssSchema = (function () {
|
|
|
440
444
|
},
|
|
441
445
|
'display': {
|
|
442
446
|
'cssPropBits': 32,
|
|
443
|
-
|
|
447
|
+
// ##### BEGIN: MODIFIED BY SAP
|
|
448
|
+
'cssLitGroup': [ L[ 2 ], L[ 47 ], L[ 54 ], L[ 64 ], L[ 65 ] ]
|
|
449
|
+
// ##### END: MODIFIED BY SAP
|
|
444
450
|
},
|
|
445
451
|
'elevation': {
|
|
446
452
|
'cssPropBits': 5,
|
|
@@ -707,6 +713,12 @@ var cssSchema = (function () {
|
|
|
707
713
|
'cssPropBits': 0,
|
|
708
714
|
'cssLitGroup': [ L[ 18 ], L[ 47 ], L[ 54 ] ]
|
|
709
715
|
},
|
|
716
|
+
// ##### BEGIN: MODIFIED BY SAP
|
|
717
|
+
'text-decoration-line': {
|
|
718
|
+
'cssPropBits': 0,
|
|
719
|
+
'cssLitGroup': [ L[ 18 ], L[ 47 ], L[ 54 ] ]
|
|
720
|
+
},
|
|
721
|
+
// ##### END: MODIFIED BY SAP
|
|
710
722
|
'text-indent': {
|
|
711
723
|
'cssPropBits': 5,
|
|
712
724
|
'cssLitGroup': [ L[ 47 ] ]
|
|
@@ -2004,7 +2016,7 @@ if (typeof window !== 'undefined') {
|
|
|
2004
2016
|
}
|
|
2005
2017
|
/*!
|
|
2006
2018
|
* OpenUI5
|
|
2007
|
-
* (c) Copyright
|
|
2019
|
+
* (c) Copyright 2026 SAP SE or an SAP affiliate company.
|
|
2008
2020
|
* Licensed under the Apache License, Version 2.0 - see LICENSE.txt.
|
|
2009
2021
|
*/
|
|
2010
2022
|
// Based on coding from the HTML4 Sanitizer by Google Inc.
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React wrapper factory for UI5 Web Components.
|
|
3
|
+
*
|
|
4
|
+
* This lightweight factory creates typed React components that wrap UI5 Web Components.
|
|
5
|
+
* It handles:
|
|
6
|
+
* - Event prop conversion (onXxx → ui5-xxx event listeners)
|
|
7
|
+
* - Ref forwarding
|
|
8
|
+
* - Children handling
|
|
9
|
+
*
|
|
10
|
+
* Note: The function supports react >= 18.
|
|
11
|
+
* Note: This is for documentation samples only - for production React apps,
|
|
12
|
+
* use the official @ui5/webcomponents-react library.
|
|
13
|
+
*/
|
|
14
|
+
import * as React from "react";
|
|
15
|
+
import type { ReactNode } from "react";
|
|
16
|
+
import type UI5Element from "../UI5Element.js";
|
|
17
|
+
interface UI5ComponentClass<T extends UI5Element = UI5Element> {
|
|
18
|
+
new (): T;
|
|
19
|
+
getMetadata(): {
|
|
20
|
+
getTag(): string;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Creates a React component wrapper for a UI5 Web Component.
|
|
25
|
+
* Uses the component's _jsxProps type for full TypeScript support.
|
|
26
|
+
*
|
|
27
|
+
* @param ComponentClass - The UI5 Web Component class (e.g., Button from "@ui5/webcomponents/dist/Button.js")
|
|
28
|
+
* @returns A React component that renders the custom element with proper TypeScript types
|
|
29
|
+
* @since 2.21.0
|
|
30
|
+
* @example
|
|
31
|
+
* import Button from "@ui5/webcomponents/dist/Button.js";
|
|
32
|
+
* const ReactButton = createReactComponent(Button);
|
|
33
|
+
* // ReactButton props are typed based on Button's _jsxProps
|
|
34
|
+
*/
|
|
35
|
+
declare function createReactComponent<T extends UI5Element>(ComponentClass: UI5ComponentClass<T>): React.ForwardRefExoticComponent<React.PropsWithoutRef<T["_jsxProps"] & {
|
|
36
|
+
children?: ReactNode;
|
|
37
|
+
}> & React.RefAttributes<T>>;
|
|
38
|
+
export default createReactComponent;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* React wrapper factory for UI5 Web Components.
|
|
3
|
+
*
|
|
4
|
+
* This lightweight factory creates typed React components that wrap UI5 Web Components.
|
|
5
|
+
* It handles:
|
|
6
|
+
* - Event prop conversion (onXxx → ui5-xxx event listeners)
|
|
7
|
+
* - Ref forwarding
|
|
8
|
+
* - Children handling
|
|
9
|
+
*
|
|
10
|
+
* Note: The function supports react >= 18.
|
|
11
|
+
* Note: This is for documentation samples only - for production React apps,
|
|
12
|
+
* use the official @ui5/webcomponents-react library.
|
|
13
|
+
*/
|
|
14
|
+
import * as React from "react";
|
|
15
|
+
import { useRef, useEffect, forwardRef, } from "react";
|
|
16
|
+
// Helper to convert event name
|
|
17
|
+
const toEventName = (propName) => {
|
|
18
|
+
return propName
|
|
19
|
+
.slice(2) // Remove "on"
|
|
20
|
+
.replace(/([A-Z])/g, (match, letter, index) => {
|
|
21
|
+
return index === 0 ? letter.toLowerCase() : `-${letter.toLowerCase()}`;
|
|
22
|
+
});
|
|
23
|
+
};
|
|
24
|
+
// Helper to create cleanup function for event listener
|
|
25
|
+
const createEventCleanup = (element, eventName, handler) => {
|
|
26
|
+
element.addEventListener(eventName, handler);
|
|
27
|
+
return () => element.removeEventListener(eventName, handler);
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* Creates a React component wrapper for a UI5 Web Component.
|
|
31
|
+
* Uses the component's _jsxProps type for full TypeScript support.
|
|
32
|
+
*
|
|
33
|
+
* @param ComponentClass - The UI5 Web Component class (e.g., Button from "@ui5/webcomponents/dist/Button.js")
|
|
34
|
+
* @returns A React component that renders the custom element with proper TypeScript types
|
|
35
|
+
* @since 2.21.0
|
|
36
|
+
* @example
|
|
37
|
+
* import Button from "@ui5/webcomponents/dist/Button.js";
|
|
38
|
+
* const ReactButton = createReactComponent(Button);
|
|
39
|
+
* // ReactButton props are typed based on Button's _jsxProps
|
|
40
|
+
*/
|
|
41
|
+
function createReactComponent(ComponentClass) {
|
|
42
|
+
const tagName = ComponentClass.getMetadata().getTag();
|
|
43
|
+
const Component = forwardRef((props, ref) => {
|
|
44
|
+
const { children, ...restProps } = props;
|
|
45
|
+
const elementRef = useRef(null);
|
|
46
|
+
// Forward ref
|
|
47
|
+
useEffect(() => {
|
|
48
|
+
if (ref) {
|
|
49
|
+
if (typeof ref === "function") {
|
|
50
|
+
ref(elementRef.current);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
ref.current = elementRef.current;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
}, [ref]);
|
|
57
|
+
// Handle event props and boolean props imperatively
|
|
58
|
+
useEffect(() => {
|
|
59
|
+
const element = elementRef.current;
|
|
60
|
+
if (!element) {
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
const eventCleanups = [];
|
|
64
|
+
Object.keys(restProps).forEach(propName => {
|
|
65
|
+
const propValue = restProps[propName];
|
|
66
|
+
if (propName.startsWith("on") && typeof propValue === "function") {
|
|
67
|
+
// Convert React event naming (onClick, onSelectionChange) to DOM event naming
|
|
68
|
+
// onClick -> click, onSelectionChange -> selection-change
|
|
69
|
+
const eventName = toEventName(propName);
|
|
70
|
+
const handler = propValue;
|
|
71
|
+
eventCleanups.push(createEventCleanup(element, eventName, handler));
|
|
72
|
+
}
|
|
73
|
+
else if (typeof propValue === "boolean") {
|
|
74
|
+
// React 18 sets false booleans as empty string attributes on custom elements.
|
|
75
|
+
// Set as property directly to avoid this.
|
|
76
|
+
element[propName] = propValue;
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
return () => {
|
|
80
|
+
eventCleanups.forEach(cleanup => cleanup());
|
|
81
|
+
};
|
|
82
|
+
}, [restProps]);
|
|
83
|
+
// Filter out event handlers and booleans from DOM props
|
|
84
|
+
const domProps = {};
|
|
85
|
+
Object.keys(restProps).forEach(propName => {
|
|
86
|
+
const propValue = restProps[propName];
|
|
87
|
+
if (propName.startsWith("on") && typeof propValue === "function") {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (typeof propValue === "boolean") {
|
|
91
|
+
return;
|
|
92
|
+
} // handled in useEffect
|
|
93
|
+
// className → class for React compatibility
|
|
94
|
+
if (propName === "className") {
|
|
95
|
+
// eslint-disable-next-line dot-notation
|
|
96
|
+
domProps["class"] = propValue;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
// Convert camelCase to kebab-case for HTML attributes
|
|
100
|
+
const attrName = propName.replace(/([A-Z])/g, "-$1").toLowerCase();
|
|
101
|
+
domProps[attrName] = propValue;
|
|
102
|
+
});
|
|
103
|
+
return React.createElement(tagName, { ref: elementRef, ...domProps }, children);
|
|
104
|
+
});
|
|
105
|
+
Component.displayName = tagName
|
|
106
|
+
.split("-")
|
|
107
|
+
.map(part => part.charAt(0).toUpperCase() + part.slice(1))
|
|
108
|
+
.join("");
|
|
109
|
+
return Component;
|
|
110
|
+
}
|
|
111
|
+
export default createReactComponent;
|
|
112
|
+
//# sourceMappingURL=createReactComponent.js.map
|