@wavemaker-ai/react-runtime 1.0.0-rc.322 → 1.0.0-rc.324
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/actions/login-action.js +1 -1
- package/components/advanced/carousel/index.d.ts +1 -0
- package/components/advanced/carousel/template.d.ts +1 -0
- package/components/advanced/login/index.d.ts +1 -0
- package/components/advanced/marquee/index.d.ts +1 -0
- package/components/basic/anchor/index.d.ts +1 -0
- package/components/basic/anchor/index.js +16 -14
- package/components/basic/audio/index.d.ts +1 -0
- package/components/basic/html/index.d.ts +1 -0
- package/components/basic/icon/index.d.ts +1 -0
- package/components/basic/icon/index.js +13 -16
- package/components/basic/iframe/index.d.ts +1 -0
- package/components/basic/label/index.d.ts +1 -0
- package/components/basic/label/index.js +5 -3
- package/components/basic/label/props.d.ts +1 -1
- package/components/basic/picture/index.d.ts +1 -0
- package/components/basic/picture/index.js +3 -2
- package/components/basic/progress-bar/index.d.ts +1 -0
- package/components/basic/progress-circle/index.d.ts +1 -0
- package/components/basic/richtexteditor/index.d.ts +2 -0
- package/components/basic/search/index.d.ts +6 -0
- package/components/basic/search/index.js +69 -9
- package/components/basic/search/props.d.ts +4 -0
- package/components/basic/spinner/index.d.ts +2 -0
- package/components/basic/spinner/index.js +11 -9
- package/components/basic/spinner/props.d.ts +5 -0
- package/components/basic/tile/index.d.ts +1 -0
- package/components/basic/tree/index.d.ts +1 -0
- package/components/basic/video/index.d.ts +1 -0
- package/components/chart/index.d.ts +2 -0
- package/components/chart/props.d.ts +1 -0
- package/components/chart/src/chart.js +12 -1
- package/components/chart/src/types.d.ts +2 -0
- package/components/common/WmAppIcon/index.d.ts +15 -0
- package/components/common/WmAppIcon/index.js +130 -0
- package/components/common/WmAppIcon/props.d.ts +17 -0
- package/components/common/WmAppIcon/props.js +0 -0
- package/components/common/index.d.ts +3 -1
- package/components/common/index.js +10 -2
- package/components/common/wm-skeleton.d.ts +7 -0
- package/components/common/wm-skeleton.js +11 -1
- package/components/container/accordion/accordion-pane/index.d.ts +2 -0
- package/components/container/accordion/accordion-pane/index.js +10 -1
- package/components/container/accordion/accordion-pane/props.d.ts +1 -0
- package/components/container/accordion/index.d.ts +1 -0
- package/components/container/accordion/index.js +2 -2
- package/components/container/index.d.ts +1 -0
- package/components/container/layout-grid/grid-column/index.d.ts +1 -0
- package/components/container/layout-grid/grid-row/index.d.ts +1 -0
- package/components/container/layout-grid/index.d.ts +1 -0
- package/components/container/linear-layout/index.d.ts +1 -0
- package/components/container/linear-layout/linear-layout-item/index.d.ts +1 -0
- package/components/container/panel/components/panel-header/index.js +16 -16
- package/components/container/panel/index.d.ts +1 -0
- package/components/container/repeat-template/index.d.ts +1 -0
- package/components/container/tabs/index.d.ts +1 -0
- package/components/container/tabs/index.js +18 -18
- package/components/container/tabs/props.d.ts +1 -0
- package/components/container/tabs/tab-pane/index.d.ts +2 -0
- package/components/container/tabs/tab-pane/index.js +2 -0
- package/components/container/tabs/tab-pane/props.d.ts +1 -0
- package/components/container/wizard/components/StepComponents.js +14 -6
- package/components/container/wizard/index.d.ts +2 -0
- package/components/container/wizard/index.js +2 -2
- package/components/container/wizard/props.d.ts +4 -0
- package/components/container/wizard/wizard-step/index.d.ts +1 -0
- package/components/container/wizard/wizard-step/index.js +6 -0
- package/components/data/card/card-actions/index.d.ts +1 -0
- package/components/data/card/card-content/index.d.ts +1 -0
- package/components/data/card/card-footer/index.d.ts +1 -0
- package/components/data/card/index.d.ts +1 -0
- package/components/data/card/index.js +13 -6
- package/components/data/form/dynamic-fields/index.js +1 -0
- package/components/data/form/form-action/index.d.ts +2 -0
- package/components/data/form/form-action/index.js +6 -4
- package/components/data/form/form-field/index.js +5 -4
- package/components/data/form/form-header/index.d.ts +1 -1
- package/components/data/form/form-header/index.js +10 -1
- package/components/data/form/index.js +5 -3
- package/components/data/form/props.d.ts +1 -0
- package/components/data/list/components/ListHeader.js +19 -3
- package/components/data/list/components/ListItemWithTemplate.js +5 -1
- package/components/data/list/components/ListItems.d.ts +1 -1
- package/components/data/list/components/ListItems.js +5 -1
- package/components/data/list/components/LoadMoreButton.js +14 -2
- package/components/data/list/components/StandardListItems.js +1 -1
- package/components/data/list/components/props.d.ts +11 -5
- package/components/data/list/hooks/props.d.ts +2 -2
- package/components/data/list/hooks/useListEventHandlers.js +3 -2
- package/components/data/list/index.d.ts +5 -1
- package/components/data/list/index.js +17 -4
- package/components/data/list/props.d.ts +14 -2
- package/components/data/list/utils/list-helpers.d.ts +5 -1
- package/components/data/list/utils/list-helpers.js +10 -0
- package/components/data/pagination/components/PageSizeSelector.js +49 -155
- package/components/data/pagination/hooks/usePagination.js +24 -1
- package/components/data/table/components/RowCells.js +1 -1
- package/components/data/table/components/TableDataRow.js +16 -3
- package/components/data/table/components/TableHeader.js +1 -1
- package/components/data/table/components/TablePanelHeading.js +14 -2
- package/components/data/table/hooks/useResponsiveColumns.d.ts +1 -0
- package/components/data/table/hooks/useTableColumns.js +2 -2
- package/components/data/table/hooks/useTableData.js +30 -1
- package/components/data/table/index.d.ts +4 -0
- package/components/data/table/index.js +47 -30
- package/components/data/table/live-table/index.d.ts +1 -0
- package/components/data/table/props.d.ts +11 -2
- package/components/data/table/table-action/index.d.ts +1 -0
- package/components/data/table/table-column/index.d.ts +1 -0
- package/components/data/table/table-row/index.d.ts +1 -0
- package/components/data/table/table-row-action/index.d.ts +1 -0
- package/components/data/table/utils/buildSelectionColumns.d.ts +1 -1
- package/components/data/table/utils/buildSelectionColumns.js +97 -71
- package/components/data/table/utils/columnBuilder.d.ts +13 -0
- package/components/data/table/utils/columnBuilder.js +27 -18
- package/components/data/table/utils/columnWidthDistribution.d.ts +1 -1
- package/components/data/table/utils/columnWidthDistribution.js +4 -1
- package/components/data/table/utils/constants.d.ts +1 -1
- package/components/data/table/utils/constants.js +1 -1
- package/components/dialogs/alert-dialog/index.d.ts +2 -0
- package/components/dialogs/confirm-dialog/index.d.ts +2 -0
- package/components/dialogs/dialog/index.d.ts +2 -0
- package/components/dialogs/dialog-actions/index.d.ts +1 -0
- package/components/dialogs/dialog-body/index.d.ts +1 -0
- package/components/dialogs/dialog-content/index.d.ts +1 -0
- package/components/dialogs/dialog-header/index.d.ts +1 -0
- package/components/dialogs/dialog-header/index.js +11 -12
- package/components/dialogs/iframe-dialog/index.d.ts +2 -0
- package/components/dialogs/login-dialog/index.d.ts +4 -0
- package/components/dialogs/login-dialog/index.js +2 -1
- package/components/dialogs/login-dialog/props.d.ts +1 -0
- package/components/dialogs/page-dialog/index.d.ts +4 -0
- package/components/dialogs/page-dialog/index.js +2 -1
- package/components/dialogs/page-dialog/props.d.ts +1 -0
- package/components/form/button/index.d.ts +1 -0
- package/components/form/button/index.js +29 -33
- package/components/form/button-group/index.d.ts +1 -0
- package/components/input/calendar/index.d.ts +2 -0
- package/components/input/chips/index.d.ts +2 -0
- package/components/input/chips/index.js +9 -3
- package/components/input/chips/utils.d.ts +5 -0
- package/components/input/chips/utils.js +29 -0
- package/components/input/color-picker/index.d.ts +2 -0
- package/components/input/composite/index.d.ts +1 -0
- package/components/input/composite/index.js +1 -0
- package/components/input/currency/index.d.ts +2 -0
- package/components/input/default/checkbox/index.d.ts +6 -0
- package/components/input/default/checkbox/index.js +48 -18
- package/components/input/default/checkbox/props.d.ts +8 -0
- package/components/input/default/checkboxset/index.d.ts +2 -0
- package/components/input/default/radioset/index.d.ts +2 -0
- package/components/input/default/switch/index.d.ts +6 -0
- package/components/input/default/switch/index.js +36 -9
- package/components/input/default/switch/prop.d.ts +2 -0
- package/components/input/epoch/date/index.d.ts +1 -0
- package/components/input/epoch/datetime/index.d.ts +1 -0
- package/components/input/epoch/time/index.d.ts +1 -0
- package/components/input/fileupload/components/ListItems.d.ts +5 -1
- package/components/input/fileupload/components/ListItems.js +27 -5
- package/components/input/fileupload/components/MultiUpload.js +12 -1
- package/components/input/fileupload/components/SingleUpload.js +12 -1
- package/components/input/fileupload/index.d.ts +3 -0
- package/components/input/fileupload/index.js +11 -0
- package/components/input/fileupload/props.d.ts +10 -0
- package/components/input/number/index.d.ts +2 -0
- package/components/input/rating/index.d.ts +6 -0
- package/components/input/rating/index.js +10 -5
- package/components/input/rating/props.d.ts +8 -0
- package/components/input/select/index.d.ts +2 -0
- package/components/input/slider/index.d.ts +6 -0
- package/components/input/slider/index.js +19 -2
- package/components/input/slider/props.d.ts +2 -0
- package/components/input/text/index.d.ts +7 -1
- package/components/input/text/index.js +25 -6
- package/components/input/text/props.d.ts +8 -0
- package/components/input/textarea/index.d.ts +2 -0
- package/components/input/textarea/index.js +9 -4
- package/components/input/textarea/util.d.ts +1 -0
- package/components/input/textarea/util.js +17 -0
- package/components/input/upload/index.d.ts +2 -0
- package/components/navbar/index.d.ts +7 -0
- package/components/navbar/index.js +21 -7
- package/components/navbar/nav/index.d.ts +1 -0
- package/components/navbar/nav-item/index.d.ts +1 -0
- package/components/navigation/breadcrumb/index.d.ts +1 -0
- package/components/navigation/menu/index.d.ts +3 -1
- package/components/navigation/menu/index.js +22 -4
- package/components/navigation/menu/props.d.ts +1 -0
- package/components/navigation/popover/index.d.ts +1 -0
- package/components/navigation/popover/index.js +8 -2
- package/components/page/partial/index.d.ts +1 -0
- package/core/appstore.d.ts +10 -0
- package/core/appstore.js +9 -1
- package/core/constants/events.d.ts +3 -0
- package/core/constants/events.js +13 -1
- package/core/proxy-service.js +1 -1
- package/core/util/index.d.ts +2 -0
- package/core/util/index.js +29 -0
- package/higherOrder/BasePage.js +81 -26
- package/higherOrder/props.d.ts +1 -0
- package/higherOrder/useActivePageReactivity.d.ts +21 -0
- package/higherOrder/useActivePageReactivity.js +57 -0
- package/higherOrder/withBaseWrapper.js +2 -0
- package/higherOrder/withRenderLogger.d.ts +15 -0
- package/higherOrder/withRenderLogger.js +53 -0
- package/hooks/useAuth.js +7 -1
- package/package-lock.json +219 -198
- package/package.json +4 -3
- package/runtime-dynamic/factories/dynamic-component.js +18 -5
- package/runtime-dynamic/factories/utils.js +7 -1
- package/runtime-dynamic/services/compile-render.js +2 -1
- package/store/slices/i18nSlice.d.ts +2 -0
- package/store/slices/i18nSlice.js +3 -1
- package/types/index.d.ts +6 -0
- package/utils/attr.js +4 -1
- package/utils/svg-icon.d.ts +27 -0
- package/utils/svg-icon.js +75 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wavemaker-ai/react-runtime",
|
|
3
|
-
"version": "1.0.0-rc.
|
|
3
|
+
"version": "1.0.0-rc.324",
|
|
4
4
|
"description": "React runtime package for Wavemaker",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -21,6 +21,7 @@
|
|
|
21
21
|
"build:lib": "node scripts/build.js post-build",
|
|
22
22
|
"sync-docs": "node scripts/sync-docs.js",
|
|
23
23
|
"build:local": "npm run build:lib -- --production=false",
|
|
24
|
+
"build:watch": "node scripts/build.js watch",
|
|
24
25
|
"format": "prettier --write .",
|
|
25
26
|
"start": "next start",
|
|
26
27
|
"lint": "next lint",
|
|
@@ -57,8 +58,8 @@
|
|
|
57
58
|
"@mui/x-date-pickers": "8.5.3",
|
|
58
59
|
"@reduxjs/toolkit": "2.9.1",
|
|
59
60
|
"@tanstack/react-table": "8.21.3",
|
|
60
|
-
"@wavemaker-ai/react-codegen": "1.0.0-rc.
|
|
61
|
-
"@wavemaker-ai/variables": "1.0.0-rc.
|
|
61
|
+
"@wavemaker-ai/react-codegen": "1.0.0-rc.324",
|
|
62
|
+
"@wavemaker-ai/variables": "1.0.0-rc.324",
|
|
62
63
|
"@wavemaker/nvd3": "1.8.16",
|
|
63
64
|
"axios": "1.15.1",
|
|
64
65
|
"d3": "7.8.5",
|
|
@@ -18,11 +18,25 @@ var __spreadValues = (a, b) => {
|
|
|
18
18
|
};
|
|
19
19
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
20
|
import { jsx } from "react/jsx-runtime";
|
|
21
|
-
import React, { useEffect, useRef } from "react";
|
|
21
|
+
import React, { useEffect, useReducer, useRef } from "react";
|
|
22
22
|
import { useAppState } from "../../context/WidgetProvider";
|
|
23
23
|
import { useAppContext } from "../../context/AppContext";
|
|
24
24
|
import { renderTranspiledMarkup } from "../services/markup-transpiler";
|
|
25
25
|
import { scopeComponentStyles, removeComponentStyles } from "../services/css-scoping";
|
|
26
|
+
function useCrossScopeDataRefresh(appContext, componentType) {
|
|
27
|
+
const [, forceRender] = useReducer((count) => count + 1, 0);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
if (componentType === "page") return;
|
|
30
|
+
const subscribe = appContext == null ? void 0 : appContext.subscribe;
|
|
31
|
+
if (typeof subscribe !== "function") return;
|
|
32
|
+
const unsubscribePage = subscribe("page-variables-data-loaded", forceRender);
|
|
33
|
+
const unsubscribeApp = subscribe("app-variables-data-loaded", forceRender);
|
|
34
|
+
return () => {
|
|
35
|
+
unsubscribePage == null ? void 0 : unsubscribePage();
|
|
36
|
+
unsubscribeApp == null ? void 0 : unsubscribeApp();
|
|
37
|
+
};
|
|
38
|
+
}, [appContext, componentType]);
|
|
39
|
+
}
|
|
26
40
|
function usePageEvents(appState, componentType) {
|
|
27
41
|
const appStateRef = useRef(appState);
|
|
28
42
|
appStateRef.current = appState;
|
|
@@ -55,12 +69,11 @@ function createDynamicComponent({
|
|
|
55
69
|
styles
|
|
56
70
|
}) {
|
|
57
71
|
const InnerComponent = () => {
|
|
58
|
-
var _a;
|
|
59
72
|
const appState = useAppState();
|
|
60
73
|
usePageEvents(appState, componentType);
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
const notification =
|
|
74
|
+
const appContext = useAppContext();
|
|
75
|
+
useCrossScopeDataRefresh(appContext, componentType);
|
|
76
|
+
const notification = appContext == null ? void 0 : appContext.notification;
|
|
64
77
|
useEffect(() => {
|
|
65
78
|
if (styles) {
|
|
66
79
|
scopeComponentStyles(componentName, componentType, styles);
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
var __defProp = Object.defineProperty;
|
|
2
|
+
var __defProps = Object.defineProperties;
|
|
3
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
2
4
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
3
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
4
6
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
@@ -14,6 +16,7 @@ var __spreadValues = (a, b) => {
|
|
|
14
16
|
}
|
|
15
17
|
return a;
|
|
16
18
|
};
|
|
19
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
17
20
|
import { buildAddPageScript } from "../services/script-executor";
|
|
18
21
|
import { transpileAndBuildGetVariables } from "../services/variable-transpiler";
|
|
19
22
|
import { transpileFragment } from "../services/markup-transpiler";
|
|
@@ -21,6 +24,7 @@ import { yieldToMain } from "../utils";
|
|
|
21
24
|
import { buildStartupInfo } from "./startup-info";
|
|
22
25
|
import { createDynamicComponent } from "./dynamic-component";
|
|
23
26
|
async function buildDynamicComponent(fragment, config) {
|
|
27
|
+
var _a;
|
|
24
28
|
const { markup, script, styles, variables } = fragment;
|
|
25
29
|
const { componentName, componentType, scriptScope, hoc, componentInfo, transpileOptions } = config;
|
|
26
30
|
const addPageScript = buildAddPageScript(script, scriptScope, componentName);
|
|
@@ -40,7 +44,9 @@ async function buildDynamicComponent(fragment, config) {
|
|
|
40
44
|
});
|
|
41
45
|
InnerComponent.displayName = config.displayName || `Dynamic${componentType.charAt(0).toUpperCase() + componentType.slice(1)}(${componentName})`;
|
|
42
46
|
const startupInfo = buildStartupInfo(variables);
|
|
43
|
-
const info = componentInfo(startupInfo)
|
|
47
|
+
const info = __spreadProps(__spreadValues({}, componentInfo(startupInfo)), {
|
|
48
|
+
activePageDeps: (_a = transpiled == null ? void 0 : transpiled.activePageDeps) != null ? _a : []
|
|
49
|
+
});
|
|
44
50
|
return hoc(InnerComponent, addPageScript, getVariables, info);
|
|
45
51
|
}
|
|
46
52
|
export {
|
|
@@ -13,7 +13,8 @@ const UTIL_SCOPE = {
|
|
|
13
13
|
};
|
|
14
14
|
const lazyPartialCache = /* @__PURE__ */ new Map();
|
|
15
15
|
function markupErrorNode(className, message) {
|
|
16
|
-
|
|
16
|
+
console.error(`[markup-transpiler] ${className}: ${message}`);
|
|
17
|
+
return null;
|
|
17
18
|
}
|
|
18
19
|
function extractMarkupComponents(markup) {
|
|
19
20
|
const cached = componentNameCache.get(markup);
|
|
@@ -70,6 +70,7 @@ const RTL_LANGUAGE_CODES = [
|
|
|
70
70
|
];
|
|
71
71
|
const initialState = {
|
|
72
72
|
selectedLocale: "",
|
|
73
|
+
localeRevision: 0,
|
|
73
74
|
defaultSupportedLocale: "en",
|
|
74
75
|
appLocale: {},
|
|
75
76
|
dateFormat: "MMM d, y",
|
|
@@ -126,7 +127,7 @@ const loadLocaleBundle = createAsyncThunk(
|
|
|
126
127
|
i18nService.selectedLocale = locale;
|
|
127
128
|
}
|
|
128
129
|
updateLocaleDirection(locale);
|
|
129
|
-
appstore.set("i18nService", __spreadProps(__spreadValues({}, response.data), { selectedLocale: locale }));
|
|
130
|
+
appstore.set("i18nService", __spreadProps(__spreadValues(__spreadValues({}, i18nService), response.data), { selectedLocale: locale }));
|
|
130
131
|
return { data: response.data, locale };
|
|
131
132
|
} catch (error) {
|
|
132
133
|
console.warn(`Error loading locale resource: ${error}`);
|
|
@@ -188,6 +189,7 @@ const i18nSlice = createSlice({
|
|
|
188
189
|
state.dateTimeFormat = `${state.dateFormat} ${state.timeFormat}`;
|
|
189
190
|
state.prefabMessages = action.payload.data.prefabMessages || {};
|
|
190
191
|
state.selectedLocale = action.payload.locale || state.selectedLocale;
|
|
192
|
+
state.localeRevision += 1;
|
|
191
193
|
}).addCase(loadLocaleBundle.rejected, (state, action) => {
|
|
192
194
|
state.error = action.payload;
|
|
193
195
|
});
|
package/types/index.d.ts
CHANGED
|
@@ -60,5 +60,11 @@ export type ComponentInfo = {
|
|
|
60
60
|
startUpVariables: string[];
|
|
61
61
|
startUpActions: string[];
|
|
62
62
|
autoUpdateVariables: string[];
|
|
63
|
+
/**
|
|
64
|
+
* Dependency paths this component reads cross-context from the active page, e.g.
|
|
65
|
+
* `Variables.PageDataInvoke1.dataSet.content` or `Widgets.button1.caption`. Declared at codegen
|
|
66
|
+
* time; the runtime value-gates re-renders to exactly these when the active page changes.
|
|
67
|
+
*/
|
|
68
|
+
activePageDeps?: string[];
|
|
63
69
|
isPartOfPrefab: boolean;
|
|
64
70
|
};
|
package/utils/attr.js
CHANGED
|
@@ -215,10 +215,13 @@ const removeInvalidAttributes = (attributes, explicitRemoveAttributes) => {
|
|
|
215
215
|
const filteredAttributes = {};
|
|
216
216
|
Object.keys(attributes).forEach((key) => {
|
|
217
217
|
var _a;
|
|
218
|
+
const value = attributes[key];
|
|
218
219
|
if ((explicitRemoveAttributes == null ? void 0 : explicitRemoveAttributes.includes(key)) || INTERNAL_ATTRIBUTES.has(key) || !isSafeAttributeName(key)) {
|
|
220
|
+
if (key === "ref") {
|
|
221
|
+
filteredAttributes[key] = value;
|
|
222
|
+
}
|
|
219
223
|
return;
|
|
220
224
|
}
|
|
221
|
-
const value = attributes[key];
|
|
222
225
|
if (Array.isArray(value) || typeof value === "object" && value !== null) {
|
|
223
226
|
return;
|
|
224
227
|
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Check if the url is an SVG icon url (path ends with .svg, ignoring query/hash). */
|
|
2
|
+
export declare function isSvgIconUrl(url: string | null | undefined): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Resolve a raw icon URL the same way image sources are resolved in React runtime
|
|
5
|
+
* (prefab resource prefixing for relative `resources/` paths).
|
|
6
|
+
*/
|
|
7
|
+
export declare function resolveIconUrl(rawUrl: string | null | undefined, prefabName?: string): string | null;
|
|
8
|
+
/**
|
|
9
|
+
* Make fetched SVG behave like a font icon:
|
|
10
|
+
* - replace non-"none" fill/stroke attributes with currentColor
|
|
11
|
+
* - replace non-"none" inline fill:/stroke: style values with currentColor
|
|
12
|
+
* - on the root <svg>, set width/height to 1em and default fill to currentColor
|
|
13
|
+
*/
|
|
14
|
+
export declare function normalizeSvg(svg: string): string;
|
|
15
|
+
export declare function sanitizeSvgMarkup(svg: string): string;
|
|
16
|
+
/**
|
|
17
|
+
* Returns cached normalized SVG markup synchronously
|
|
18
|
+
* Use before async fetch so remounts render the icon on the first paint.
|
|
19
|
+
*/
|
|
20
|
+
export declare function getCachedSvgIcon(resolvedUrl: string): string | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Fetch and normalize SVG markup for the given resolved URL.
|
|
23
|
+
* Results are cached module-wide; concurrent requests for the same URL share one fetch.
|
|
24
|
+
*/
|
|
25
|
+
export declare function fetchSvgIcon(resolvedUrl: string): Promise<string>;
|
|
26
|
+
/** @internal Test helper */
|
|
27
|
+
export declare function clearSvgIconCache(): void;
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import DOMPurify from "dompurify";
|
|
2
|
+
import { prefixPrefabResourceUrl } from "./resource-url";
|
|
3
|
+
function isSvgIconUrl(url) {
|
|
4
|
+
if (!url) {
|
|
5
|
+
return false;
|
|
6
|
+
}
|
|
7
|
+
const path = url.split(/[?#]/)[0];
|
|
8
|
+
return /\.svg$/i.test(path);
|
|
9
|
+
}
|
|
10
|
+
function resolveIconUrl(rawUrl, prefabName) {
|
|
11
|
+
if (!rawUrl) {
|
|
12
|
+
return null;
|
|
13
|
+
}
|
|
14
|
+
const resolved = prefixPrefabResourceUrl(rawUrl, prefabName);
|
|
15
|
+
return resolved || null;
|
|
16
|
+
}
|
|
17
|
+
function normalizeSvg(svg) {
|
|
18
|
+
if (!svg) return "";
|
|
19
|
+
let out = svg;
|
|
20
|
+
out = out.replace(/fill\s*=\s*"(?!\s*none\s*")[^"]*"/gi, 'fill="currentColor"').replace(/fill\s*=\s*'(?!\s*none\s*')[^']*'/gi, "fill='currentColor'").replace(/stroke\s*=\s*"(?!\s*none\s*")[^"]*"/gi, 'stroke="currentColor"').replace(/stroke\s*=\s*'(?!\s*none\s*')[^']*'/gi, "stroke='currentColor'").replace(/(fill|stroke)\s*:\s*(?!\s*none\b)[^;"']+/gi, "$1: currentColor");
|
|
21
|
+
out = out.replace(/<svg\b([^>]*)>/i, (_match, attrs) => {
|
|
22
|
+
let updated = attrs;
|
|
23
|
+
updated = updated.replace(/\swidth\s*=\s*("[^"]*"|'[^']*')/gi, "").replace(/\s+$/, "") + ' width="1em"';
|
|
24
|
+
updated = updated.replace(/\sheight\s*=\s*("[^"]*"|'[^']*')/gi, "").replace(/\s+$/, "") + ' height="1em"';
|
|
25
|
+
updated += ' fill="currentColor"';
|
|
26
|
+
return `<svg${updated}>`;
|
|
27
|
+
});
|
|
28
|
+
return out;
|
|
29
|
+
}
|
|
30
|
+
function sanitizeSvgMarkup(svg) {
|
|
31
|
+
return DOMPurify.sanitize(svg, { USE_PROFILES: { svg: true, svgFilters: true } });
|
|
32
|
+
}
|
|
33
|
+
const svgCache = /* @__PURE__ */ new Map();
|
|
34
|
+
const inFlightRequests = /* @__PURE__ */ new Map();
|
|
35
|
+
function getCachedSvgIcon(resolvedUrl) {
|
|
36
|
+
return svgCache.get(resolvedUrl);
|
|
37
|
+
}
|
|
38
|
+
async function fetchSvgIcon(resolvedUrl) {
|
|
39
|
+
const cached = svgCache.get(resolvedUrl);
|
|
40
|
+
if (cached !== void 0) {
|
|
41
|
+
return cached;
|
|
42
|
+
}
|
|
43
|
+
let request = inFlightRequests.get(resolvedUrl);
|
|
44
|
+
if (!request) {
|
|
45
|
+
request = fetch(resolvedUrl).then((response) => {
|
|
46
|
+
if (!response.ok) {
|
|
47
|
+
throw new Error(`Failed to fetch SVG: ${response.status}`);
|
|
48
|
+
}
|
|
49
|
+
return response.text();
|
|
50
|
+
}).then((raw) => {
|
|
51
|
+
const normalized = sanitizeSvgMarkup(normalizeSvg(raw));
|
|
52
|
+
svgCache.set(resolvedUrl, normalized);
|
|
53
|
+
inFlightRequests.delete(resolvedUrl);
|
|
54
|
+
return normalized;
|
|
55
|
+
}).catch((error) => {
|
|
56
|
+
inFlightRequests.delete(resolvedUrl);
|
|
57
|
+
throw error;
|
|
58
|
+
});
|
|
59
|
+
inFlightRequests.set(resolvedUrl, request);
|
|
60
|
+
}
|
|
61
|
+
return request;
|
|
62
|
+
}
|
|
63
|
+
function clearSvgIconCache() {
|
|
64
|
+
svgCache.clear();
|
|
65
|
+
inFlightRequests.clear();
|
|
66
|
+
}
|
|
67
|
+
export {
|
|
68
|
+
clearSvgIconCache,
|
|
69
|
+
fetchSvgIcon,
|
|
70
|
+
getCachedSvgIcon,
|
|
71
|
+
isSvgIconUrl,
|
|
72
|
+
normalizeSvg,
|
|
73
|
+
resolveIconUrl,
|
|
74
|
+
sanitizeSvgMarkup
|
|
75
|
+
};
|