xmlui 0.9.21 → 0.9.25

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.
Files changed (102) hide show
  1. package/dist/apiInterceptorWorker-CFF3bC6o.mjs +818 -0
  2. package/dist/{index-B3CWFAxa.mjs → index-DtxDGaqF.mjs} +11942 -3291
  3. package/dist/index.css +1301 -564
  4. package/dist/language-server-web-worker.mjs +1 -1
  5. package/dist/language-server.mjs +1 -1
  6. package/dist/lint-CYAUfk0_.mjs +168 -0
  7. package/dist/metadata-utils-CCIMqe69.mjs +466 -0
  8. package/dist/scripts/package.json +252 -0
  9. package/dist/scripts/src/components/App/AppLayoutContext.js +0 -1
  10. package/dist/scripts/src/components/App/AppNative.js +21 -9
  11. package/dist/scripts/src/components/AppHeader/AppHeader.js +1 -1
  12. package/dist/scripts/src/components/AutoComplete/AutoComplete.js +5 -2
  13. package/dist/scripts/src/components/AutoComplete/AutoCompleteNative.js +13 -10
  14. package/dist/scripts/src/components/Bookmark/BookmarkNative.js +5 -1
  15. package/dist/scripts/src/components/CodeBlock/CodeBlock.js +31 -0
  16. package/dist/scripts/src/components/CodeBlock/CodeBlockNative.js +82 -0
  17. package/dist/scripts/src/components/ComponentProvider.js +5 -0
  18. package/dist/scripts/src/components/DatePicker/DatePickerNative.js +1 -0
  19. package/dist/scripts/src/components/Form/FormContext.js +5 -4
  20. package/dist/scripts/src/components/Form/FormNative.js +41 -43
  21. package/dist/scripts/src/components/Form/formActions.js +1 -1
  22. package/dist/scripts/src/components/FormItem/FormItem.js +6 -3
  23. package/dist/scripts/src/components/FormItem/FormItemNative.js +56 -15
  24. package/dist/scripts/src/components/FormItem/ItemWithLabel.js +1 -1
  25. package/dist/scripts/src/components/Heading/Heading.js +13 -0
  26. package/dist/scripts/src/components/Heading/HeadingNative.js +1 -1
  27. package/dist/scripts/src/components/HtmlTags/HtmlTags.js +7 -3
  28. package/dist/scripts/src/components/Icon/DarkToLightIcon.js +10 -0
  29. package/dist/scripts/src/components/Icon/LightToDark.js +10 -0
  30. package/dist/scripts/src/components/IconProvider.js +4 -0
  31. package/dist/scripts/src/components/Image/ImageNative.js +1 -1
  32. package/dist/scripts/src/components/Items/ItemsNative.js +8 -6
  33. package/dist/scripts/src/components/Link/Link.js +5 -5
  34. package/dist/scripts/src/components/List/ListNative.js +1 -1
  35. package/dist/scripts/src/components/Markdown/Markdown.js +52 -16
  36. package/dist/scripts/src/components/Markdown/MarkdownNative.js +34 -73
  37. package/dist/scripts/src/components/Markdown/highlight-code.js +160 -0
  38. package/dist/scripts/src/components/Markdown/parse-binding-expr.js +60 -0
  39. package/dist/scripts/src/components/Markdown/utils.js +282 -0
  40. package/dist/scripts/src/components/ModalDialog/ConfirmationModalContextProvider.js +116 -0
  41. package/dist/scripts/src/components/ModalDialog/Dialog.js +20 -0
  42. package/dist/scripts/src/components/NavGroup/NavGroupNative.js +4 -5
  43. package/dist/scripts/src/components/NestedApp/NestedApp.js +61 -0
  44. package/dist/scripts/src/components/NestedApp/NestedAppNative.js +125 -0
  45. package/dist/scripts/src/components/NestedApp/Tooltip.js +46 -0
  46. package/dist/scripts/src/components/NumberBox/NumberBox.js +4 -1
  47. package/dist/scripts/src/components/NumberBox/NumberBoxNative.js +2 -2
  48. package/dist/scripts/src/components/Option/Option.js +3 -2
  49. package/dist/scripts/src/components/Select/Select.js +5 -3
  50. package/dist/scripts/src/components/Select/SelectNative.js +53 -40
  51. package/dist/scripts/src/components/SelectionStore/SelectionStore.js +1 -1
  52. package/dist/scripts/src/components/Spinner/Spinner.js +0 -1
  53. package/dist/scripts/src/components/TableOfContents/TableOfContents.js +1 -0
  54. package/dist/scripts/src/components/Text/Text.js +12 -1
  55. package/dist/scripts/src/components/Text/TextNative.js +5 -1
  56. package/dist/scripts/src/components/TextBox/TextBox.js +6 -1
  57. package/dist/scripts/src/components/TextBox/TextBoxNative.js +2 -2
  58. package/dist/scripts/src/components/Theme/ThemeNative.js +7 -3
  59. package/dist/scripts/src/components/ToneChangerButton/ToneChangerButton.js +1 -3
  60. package/dist/scripts/src/components-core/RestApiProxy.js +10 -7
  61. package/dist/scripts/src/components-core/TableOfContentsContext.js +1 -1
  62. package/dist/scripts/src/components-core/appContext/date-functions.js +23 -0
  63. package/dist/scripts/src/components-core/appContext/math-function.js +27 -0
  64. package/dist/scripts/src/components-core/appContext/misc-utils.js +13 -0
  65. package/dist/scripts/src/components-core/interception/ApiInterceptor.js +199 -0
  66. package/dist/scripts/src/components-core/interception/ApiInterceptorProvider.js +94 -0
  67. package/dist/scripts/src/components-core/interception/Backend.js +128 -0
  68. package/dist/scripts/src/components-core/interception/Errors.js +129 -0
  69. package/dist/scripts/src/components-core/interception/InMemoryDb.js +41 -0
  70. package/dist/scripts/src/components-core/interception/IndexedDb.js +207 -0
  71. package/dist/scripts/src/components-core/interception/ReadonlyCollection.js +145 -0
  72. package/dist/scripts/src/components-core/interception/abstractions.js +2 -0
  73. package/dist/scripts/src/components-core/interception/apiInterceptorWorker.js +46 -0
  74. package/dist/scripts/src/components-core/interception/useApiInterceptorContext.js +9 -0
  75. package/dist/scripts/src/components-core/rendering/AppContent.js +336 -0
  76. package/dist/scripts/src/components-core/rendering/AppRoot.js +84 -0
  77. package/dist/scripts/src/components-core/rendering/AppWrapper.js +49 -0
  78. package/dist/scripts/src/components-core/rendering/ComponentAdapter.js +17 -7
  79. package/dist/scripts/src/components-core/rendering/Container.js +2 -1
  80. package/dist/scripts/src/components-core/theming/ThemeProvider.js +2 -7
  81. package/dist/scripts/src/components-core/theming/themes/root.js +1 -0
  82. package/dist/scripts/src/components-core/utils/date-utils.js +78 -0
  83. package/dist/scripts/src/components-core/utils/hooks.js +26 -0
  84. package/dist/scripts/src/components-core/utils/misc.js +1 -1
  85. package/dist/scripts/src/components-core/utils/request-params.js +70 -0
  86. package/dist/scripts/src/logging/LoggerContext.js +22 -0
  87. package/dist/scripts/src/logging/LoggerInitializer.js +14 -0
  88. package/dist/scripts/src/logging/LoggerService.js +60 -0
  89. package/dist/scripts/src/parsers/xmlui-parser/transform.js +7 -0
  90. package/dist/{server-common-DW5h7Q34.mjs → server-common-9TiLMTJj.mjs} +106 -98
  91. package/dist/style.css +3314 -2823
  92. package/dist/{lint-EcgF-9Wr.mjs → transform-DC0Gy6qw.mjs} +1246 -540
  93. package/dist/xmlui-metadata.mjs +2850 -2665
  94. package/dist/xmlui-metadata.umd.js +2850 -2665
  95. package/dist/xmlui-parser.d.ts +49 -4
  96. package/dist/xmlui-parser.mjs +49 -48
  97. package/dist/xmlui-standalone.umd.js +34674 -31457
  98. package/dist/xmlui.d.ts +3 -1
  99. package/dist/xmlui.mjs +10 -10
  100. package/package.json +3 -1
  101. package/dist/apiInterceptorWorker-7aKQ2rBj.mjs +0 -8447
  102. package/dist/parser-CBXS8ft2.mjs +0 -1196
@@ -0,0 +1,336 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AppContent = AppContent;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_1 = require("react");
9
+ const lodash_es_1 = require("lodash-es");
10
+ const react_hot_toast_1 = __importDefault(require("react-hot-toast"));
11
+ const package_json_1 = require("../../../package.json");
12
+ const ComponentRegistryContext_1 = require("../../components/ComponentRegistryContext");
13
+ const ConfirmationModalContextProvider_1 = require("../../components/ModalDialog/ConfirmationModalContextProvider");
14
+ const ThemeContext_1 = require("../theming/ThemeContext");
15
+ const hooks_1 = require("../utils/hooks");
16
+ const themeVars_1 = require("../theming/themeVars");
17
+ const useApiInterceptorContext_1 = require("../interception/useApiInterceptorContext");
18
+ const constants_1 = require("../constants");
19
+ const AppStateContext_1 = require("../../components/App/AppStateContext");
20
+ const misc_1 = require("../utils/misc");
21
+ const DebugViewProvider_1 = require("../DebugViewProvider");
22
+ const misc_utils_1 = require("../appContext/misc-utils");
23
+ const date_functions_1 = require("../appContext/date-functions");
24
+ const math_function_1 = require("../appContext/math-function");
25
+ const AppContext_1 = require("../AppContext");
26
+ const renderChild_1 = require("./renderChild");
27
+ const AppRoot_1 = require("./AppRoot");
28
+ const react_2 = require("@remix-run/react");
29
+ const ThemingDefs_1 = require("../../abstractions/ThemingDefs");
30
+ /**
31
+ * This component wraps the entire app into a container with these particular
32
+ * responsibilities:
33
+ * - Managing the application state
34
+ * - Helping the app with viewport-related functionality (e.g., information
35
+ * of viewport size, supporting responsive apps)
36
+ * - Providing xmlui-defined methods and properties for apps, such as
37
+ * `activeThemeId`, `navigate`, `toast`, and many others.
38
+ */
39
+ function AppContent({ rootContainer, routerBaseName, globalProps, standalone, trackContainerHeight, decorateComponentsWithTestId, debugEnabled, children, }) {
40
+ const [loggedInUser, setLoggedInUser] = (0, react_1.useState)(null);
41
+ const debugView = (0, DebugViewProvider_1.useDebugView)();
42
+ const componentRegistry = (0, ComponentRegistryContext_1.useComponentRegistry)();
43
+ const navigate = (0, react_2.useNavigate)();
44
+ const { confirm } = (0, ConfirmationModalContextProvider_1.useConfirm)();
45
+ // --- Prepare theme-related variables. We will use them to manage the selected theme
46
+ // --- and also pass them to the app context.
47
+ const { activeThemeId, activeThemeTone, setActiveThemeId, setActiveThemeTone, availableThemeIds, root, toggleThemeTone, } = (0, ThemeContext_1.useThemes)();
48
+ // --- Handle special key combinations to change the theme and tone
49
+ (0, hooks_1.useDocumentKeydown)((event) => {
50
+ // --- Alt + Ctrl + Shift + T changes the current theme
51
+ if (event.code === "KeyT" && event.altKey && event.ctrlKey && event.shiftKey) {
52
+ setActiveThemeId(availableThemeIds[(availableThemeIds.indexOf(activeThemeId) + 1) % availableThemeIds.length]);
53
+ }
54
+ // --- Alt + Ctrl + Shift + O changes the current theme tone
55
+ if (event.code === "KeyO" && event.altKey && event.ctrlKey && event.shiftKey) {
56
+ setActiveThemeTone(ThemingDefs_1.ThemeToneKeys[(ThemingDefs_1.ThemeToneKeys.indexOf(activeThemeTone) + 1) % ThemingDefs_1.ThemeToneKeys.length]);
57
+ }
58
+ // --- Alt + Ctrl + Shift + S toggles the current state view
59
+ if (event.code === "KeyS" && event.altKey && event.ctrlKey && event.shiftKey) {
60
+ debugView.setDisplayStateView(!debugView.displayStateView);
61
+ }
62
+ });
63
+ // --- We use the state variables to store the current media query values
64
+ const [maxWidthPhone, setMaxWidthPhone] = (0, react_1.useState)("0");
65
+ const [maxWidthPhoneLower, setMaxWidthPhoneLower] = (0, react_1.useState)("0");
66
+ const [maxWidthLandscapePhone, setMaxWidthLandscapePhone] = (0, react_1.useState)("0");
67
+ const [maxWidthLandscapePhoneLower, setMaxWidthLandscapePhoneLower] = (0, react_1.useState)("0");
68
+ const [maxWidthTablet, setMaxWidthTablet] = (0, react_1.useState)("0");
69
+ const [maxWidthTabletLower, setMaxWidthTabletLower] = (0, react_1.useState)("0");
70
+ const [maxWidthDesktop, setMaxWidthDesktop] = (0, react_1.useState)("0");
71
+ const [maxWidthDesktopLower, setMaxWidthDesktopLower] = (0, react_1.useState)("0");
72
+ const [maxWidthLargeDesktop, setMaxWidthLargeDesktop] = (0, react_1.useState)("0");
73
+ const [maxWidthLargeDesktopLower, setMaxWidthLargeDesktopLower] = (0, react_1.useState)("0");
74
+ // --- We create a lower dimension value for the media query using a range
75
+ const createLowerDimensionValue = (dimension) => {
76
+ const match = dimension.match(/^(\d+)px$/);
77
+ return match ? `${parseInt(match[1]) - 0.02}px` : "0";
78
+ };
79
+ // --- Whenever the size of the viewport changes, we update the values
80
+ // --- related to viewport size
81
+ const observer = (0, react_1.useRef)();
82
+ (0, hooks_1.useIsomorphicLayoutEffect)(() => {
83
+ if (trackContainerHeight) {
84
+ if (root && root !== document.body) {
85
+ // --- We are already observing old element
86
+ if (observer === null || observer === void 0 ? void 0 : observer.current) {
87
+ observer.current.unobserve(root);
88
+ }
89
+ if (trackContainerHeight === "auto") {
90
+ root.style.setProperty("--containerHeight", 'auto');
91
+ }
92
+ else {
93
+ observer.current = new ResizeObserver((entries) => {
94
+ root.style.setProperty("--containerHeight", entries[0].contentRect.height + "px");
95
+ });
96
+ }
97
+ if (observer.current) {
98
+ observer.current.observe(root);
99
+ }
100
+ }
101
+ }
102
+ return () => {
103
+ if (observer === null || observer === void 0 ? void 0 : observer.current) {
104
+ observer.current.unobserve(root);
105
+ }
106
+ };
107
+ }, [root, observer, trackContainerHeight]);
108
+ // --- Whenever the application root DOM object or the active theme changes, we sync
109
+ // --- with the theme variable values (because we can't use css var in media queries)
110
+ (0, hooks_1.useIsomorphicLayoutEffect)(() => {
111
+ const mwPhone = getComputedStyle(root).getPropertyValue((0, themeVars_1.getVarKey)("maxWidth-phone"));
112
+ setMaxWidthPhone(mwPhone);
113
+ setMaxWidthPhoneLower(createLowerDimensionValue(mwPhone));
114
+ const mwLandscapePhone = getComputedStyle(root).getPropertyValue((0, themeVars_1.getVarKey)("maxWidth-landscape-phone"));
115
+ setMaxWidthLandscapePhone(mwLandscapePhone);
116
+ setMaxWidthLandscapePhoneLower(createLowerDimensionValue(mwLandscapePhone));
117
+ const mwTablet = getComputedStyle(root).getPropertyValue((0, themeVars_1.getVarKey)("maxWidth-tablet"));
118
+ setMaxWidthTablet(mwTablet);
119
+ setMaxWidthTabletLower(createLowerDimensionValue(mwTablet));
120
+ const mwDesktop = getComputedStyle(root).getPropertyValue((0, themeVars_1.getVarKey)("maxWidth-desktop"));
121
+ setMaxWidthDesktop(mwDesktop);
122
+ setMaxWidthDesktopLower(createLowerDimensionValue(mwDesktop));
123
+ const mwLargeDesktop = getComputedStyle(root).getPropertyValue((0, themeVars_1.getVarKey)("maxWidth-large-desktop"));
124
+ setMaxWidthLargeDesktop(mwLargeDesktop);
125
+ setMaxWidthLargeDesktopLower(createLowerDimensionValue(mwLargeDesktop));
126
+ }, [activeThemeId, root]);
127
+ // --- Set viewport size information
128
+ const isViewportPhone = (0, hooks_1.useMediaQuery)(`(max-width: ${maxWidthPhoneLower})`);
129
+ const isViewportLandscapePhone = (0, hooks_1.useMediaQuery)(`(min-width: ${maxWidthPhone}) and (max-width: ${maxWidthLandscapePhoneLower})`);
130
+ const isViewportTablet = (0, hooks_1.useMediaQuery)(`(min-width: ${maxWidthLandscapePhone}) and (max-width: ${maxWidthTabletLower})`);
131
+ const isViewportDesktop = (0, hooks_1.useMediaQuery)(`(min-width: ${maxWidthTablet}) and (max-width: ${maxWidthDesktopLower})`);
132
+ const isViewportLargeDesktop = (0, hooks_1.useMediaQuery)(`(min-width: ${maxWidthDesktop}) and (max-width: ${maxWidthLargeDesktopLower})`);
133
+ let vpSize = "xs";
134
+ let vpSizeIndex = 0;
135
+ const isViewportXlDesktop = (0, hooks_1.useMediaQuery)(`(min-width: ${maxWidthLargeDesktop})`);
136
+ if (isViewportXlDesktop) {
137
+ vpSize = "xxl";
138
+ vpSizeIndex = 5;
139
+ }
140
+ else if (isViewportLargeDesktop) {
141
+ vpSize = "xl";
142
+ vpSizeIndex = 4;
143
+ }
144
+ else if (isViewportDesktop) {
145
+ vpSize = "lg";
146
+ vpSizeIndex = 3;
147
+ }
148
+ else if (isViewportTablet) {
149
+ vpSize = "md";
150
+ vpSizeIndex = 2;
151
+ }
152
+ else if (isViewportLandscapePhone) {
153
+ vpSize = "sm";
154
+ vpSizeIndex = 1;
155
+ }
156
+ // --- Collect information about the current environment
157
+ const isInIFrame = (0, hooks_1.useIsInIFrame)();
158
+ const isWindowFocused = (0, hooks_1.useIsWindowFocused)();
159
+ const apiInterceptorContext = (0, useApiInterceptorContext_1.useApiInterceptorContext)();
160
+ const location = (0, react_2.useLocation)();
161
+ const lastHash = (0, react_1.useRef)("");
162
+ const [scrollForceRefresh, setScrollForceRefresh] = (0, react_1.useState)(0);
163
+ // --- Listen to location change using useEffect with location as dependency
164
+ // https://jasonwatmore.com/react-router-v6-listen-to-location-route-change-without-history-listen
165
+ // https://dev.to/mindactuate/scroll-to-anchor-element-with-react-router-v6-38op
166
+ (0, react_1.useEffect)(() => {
167
+ var _a;
168
+ let hash = "";
169
+ if (location.hash) {
170
+ hash = location.hash.slice(1); // safe hash for further use after navigation
171
+ }
172
+ if (lastHash.current !== hash) {
173
+ lastHash.current = hash;
174
+ if (!((_a = location.state) === null || _a === void 0 ? void 0 : _a.preventHashScroll)) {
175
+ requestAnimationFrame(() => {
176
+ var _a;
177
+ (_a = document
178
+ .getElementById(lastHash.current)) === null || _a === void 0 ? void 0 : _a.scrollIntoView({ behavior: "instant", block: "start" });
179
+ });
180
+ }
181
+ }
182
+ }, [location, scrollForceRefresh]);
183
+ const forceRefreshAnchorScroll = (0, react_1.useCallback)(() => {
184
+ lastHash.current = "";
185
+ setScrollForceRefresh((prev) => prev + 1);
186
+ }, []);
187
+ // --- We collect all the actions defined in the app and pass them to the app context
188
+ const Actions = (0, react_1.useMemo)(() => {
189
+ const ret = {
190
+ _SUPPORT_IMPLICIT_CONTEXT: true,
191
+ };
192
+ for (const [key, value] of componentRegistry.actionFunctions) {
193
+ ret[key] = value;
194
+ }
195
+ return ret;
196
+ }, [componentRegistry.actionFunctions]);
197
+ // --- We collect information about app embedding and pass it to the app context
198
+ const embed = (0, react_1.useMemo)(() => {
199
+ return {
200
+ isInIFrame: isInIFrame,
201
+ };
202
+ }, [isInIFrame]);
203
+ // --- We collect information about the current environment and pass it to the app context
204
+ const environment = (0, react_1.useMemo)(() => {
205
+ return {
206
+ isWindowFocused,
207
+ };
208
+ }, [isWindowFocused]);
209
+ // --- We collect information about the current media size and pass it to the app context
210
+ const mediaSize = (0, react_1.useMemo)(() => {
211
+ return {
212
+ phone: isViewportPhone,
213
+ landscapePhone: isViewportLandscapePhone,
214
+ tablet: isViewportTablet,
215
+ desktop: isViewportDesktop,
216
+ largeDesktop: isViewportLargeDesktop,
217
+ xlDesktop: isViewportXlDesktop,
218
+ smallScreen: isViewportPhone || isViewportLandscapePhone || isViewportTablet,
219
+ largeScreen: !(isViewportPhone || isViewportLandscapePhone || isViewportTablet),
220
+ size: vpSize,
221
+ sizeIndex: vpSizeIndex,
222
+ };
223
+ }, [
224
+ isViewportPhone,
225
+ isViewportLandscapePhone,
226
+ isViewportTablet,
227
+ isViewportDesktop,
228
+ isViewportLargeDesktop,
229
+ isViewportXlDesktop,
230
+ vpSize,
231
+ vpSizeIndex,
232
+ ]);
233
+ // --- We extract the global properties from the app configuration and pass them to the app context
234
+ const appGlobals = (0, react_1.useMemo)(() => {
235
+ return globalProps ? Object.assign({}, globalProps) : constants_1.EMPTY_OBJECT;
236
+ }, [globalProps]);
237
+ // --- We assemble the app context object form the collected information
238
+ const appContextValue = (0, react_1.useMemo)(() => {
239
+ const ret = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({
240
+ // --- Engine-related
241
+ version: package_json_1.version,
242
+ // --- Actions namespace
243
+ Actions,
244
+ // --- App-specific
245
+ appGlobals,
246
+ debugEnabled,
247
+ decorateComponentsWithTestId,
248
+ environment,
249
+ mediaSize,
250
+ queryClient: AppRoot_1.queryClient,
251
+ standalone }, date_functions_1.dateFunctions), math_function_1.mathFunctions), {
252
+ // --- File Utilities
253
+ formatFileSizeInBytes: misc_1.formatFileSizeInBytes,
254
+ getFileExtension: misc_1.getFileExtension,
255
+ // --- Navigation-related
256
+ navigate,
257
+ routerBaseName,
258
+ // --- Notifications and dialogs
259
+ confirm,
260
+ signError,
261
+ toast: react_hot_toast_1.default,
262
+ // --- Theme-related
263
+ activeThemeId,
264
+ activeThemeTone,
265
+ availableThemeIds, setTheme: setActiveThemeId, setThemeTone: setActiveThemeTone, toggleThemeTone,
266
+ // --- User-related
267
+ loggedInUser,
268
+ setLoggedInUser,
269
+ delay: misc_1.delay,
270
+ embed,
271
+ apiInterceptorContext, getPropertyByPath: lodash_es_1.get }), misc_utils_1.miscellaneousUtils), { forceRefreshAnchorScroll });
272
+ return ret;
273
+ }, [
274
+ Actions,
275
+ appGlobals,
276
+ debugEnabled,
277
+ decorateComponentsWithTestId,
278
+ environment,
279
+ mediaSize,
280
+ standalone,
281
+ navigate,
282
+ routerBaseName,
283
+ confirm,
284
+ activeThemeId,
285
+ activeThemeTone,
286
+ availableThemeIds,
287
+ setActiveThemeId,
288
+ setActiveThemeTone,
289
+ toggleThemeTone,
290
+ loggedInUser,
291
+ embed,
292
+ apiInterceptorContext,
293
+ forceRefreshAnchorScroll,
294
+ ]);
295
+ // --- We prepare the helper infrastructure for the `AppState` component, which manages
296
+ // --- app-wide state using buckets (state sections).
297
+ const [appState, setAppState] = (0, react_1.useState)(constants_1.EMPTY_OBJECT);
298
+ const registerAppState = (0, react_1.useCallback)((bucket, initialValue) => {
299
+ setAppState((prev) => {
300
+ return Object.assign(Object.assign({}, prev), { [bucket]: initialValue });
301
+ });
302
+ }, []);
303
+ const update = (0, react_1.useCallback)((bucket, patch) => {
304
+ setAppState((prev) => {
305
+ return Object.assign(Object.assign({}, prev), { [bucket]: Object.assign(Object.assign({}, (prev[bucket] || {})), patch) });
306
+ });
307
+ }, []);
308
+ const appStateContextValue = (0, react_1.useMemo)(() => {
309
+ return {
310
+ registerAppState,
311
+ appState,
312
+ update,
313
+ };
314
+ }, [appState, registerAppState, update]);
315
+ const memoedVarsRef = (0, react_1.useRef)(new Map());
316
+ const renderedRoot = (0, renderChild_1.renderChild)({
317
+ node: rootContainer,
318
+ state: constants_1.EMPTY_OBJECT,
319
+ dispatch: constants_1.noop,
320
+ appContext: undefined,
321
+ lookupAction: constants_1.noop,
322
+ lookupSyncCallback: constants_1.noop,
323
+ registerComponentApi: constants_1.noop,
324
+ renderChild: constants_1.noop,
325
+ statePartChanged: constants_1.noop,
326
+ cleanup: constants_1.noop,
327
+ memoedVarsRef,
328
+ });
329
+ return ((0, jsx_runtime_1.jsx)(AppContext_1.AppContext.Provider, { value: appContextValue, children: (0, jsx_runtime_1.jsx)(AppStateContext_1.AppStateContext.Provider, { value: appStateContextValue, children: (!!children && (0, react_1.isValidElement)(renderedRoot))
330
+ ? (0, react_1.cloneElement)(renderedRoot, null, children)
331
+ : renderedRoot }) }));
332
+ }
333
+ // --- We pass this funtion to the global app context
334
+ function signError(error) {
335
+ react_hot_toast_1.default.error(typeof error === "string" ? error : error.message || "Something went wrong");
336
+ }
@@ -0,0 +1,84 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.queryClient = void 0;
4
+ exports.AppRoot = AppRoot;
5
+ const jsx_runtime_1 = require("react/jsx-runtime");
6
+ const react_1 = require("react");
7
+ const react_query_1 = require("@tanstack/react-query");
8
+ const immer_1 = require("immer");
9
+ const reportEngineError_1 = require("../reportEngineError");
10
+ const ComponentProvider_1 = require("../../components/ComponentProvider");
11
+ const DebugViewProvider_1 = require("../DebugViewProvider");
12
+ const AppWrapper_1 = require("./AppWrapper");
13
+ // --- We want to enable the produce method of `immer` on Map objects
14
+ (0, immer_1.enableMapSet)();
15
+ // --- We use this object in the app context to represent the `QlientQuery`
16
+ // --- of the react-query package.
17
+ exports.queryClient = new react_query_1.QueryClient({
18
+ defaultOptions: {
19
+ queries: {
20
+ refetchOnWindowFocus: false,
21
+ },
22
+ },
23
+ });
24
+ /**
25
+ * This component is responsible for running a pre-compiled xmlui app. It
26
+ * receives the internal representation of the app markup and code (coming
27
+ * from either code-behind files or inlined markup expressions) and executes
28
+ * the app accordingly.
29
+ */
30
+ function AppRoot({ apiInterceptor, contributes, node, decorateComponentsWithTestId, debugEnabled, defaultTheme, defaultTone, resources, globalProps, standalone, trackContainerHeight, routerBaseName, previewMode, resourceMap, sources, extensionManager, children, projectCompilation, }) {
31
+ // --- Make sure, the root node is wrapped in a `Theme` component. Also,
32
+ // --- the root node must be wrapped in a `Container` component managing
33
+ // --- the app's top-level state.
34
+ const rootNode = (0, react_1.useMemo)(() => {
35
+ const themedRoot = {
36
+ type: "Theme",
37
+ props: {
38
+ root: true,
39
+ },
40
+ children: [node],
41
+ };
42
+ return {
43
+ type: "Container",
44
+ uid: "root",
45
+ children: [themedRoot],
46
+ uses: [],
47
+ };
48
+ }, [node]);
49
+ if (projectCompilation) {
50
+ const entryDeps = projectCompilation.entrypoint.dependencies;
51
+ const transDeps = getTransitiveDependencies(entryDeps, projectCompilation.components);
52
+ // console.log("projectCompilation: ", projectCompilation);
53
+ // console.log("transitive dependencies of entrypoint: ", transDeps);
54
+ }
55
+ // --- Start with an error-free state
56
+ (0, reportEngineError_1.resetErrors)();
57
+ // --- Render the app providing a component registry (in which the engine finds a
58
+ // --- component definition by its name). Ensure the app has a context for debugging.
59
+ return ((0, jsx_runtime_1.jsx)(ComponentProvider_1.ComponentProvider, { contributes: contributes, extensionManager: extensionManager, children: (0, jsx_runtime_1.jsx)(DebugViewProvider_1.DebugViewProvider, { debugConfig: globalProps === null || globalProps === void 0 ? void 0 : globalProps.debug, children: (0, jsx_runtime_1.jsx)(AppWrapper_1.AppWrapper, { projectCompilation: projectCompilation, resourceMap: resourceMap, apiInterceptor: apiInterceptor, node: rootNode, contributes: contributes, resources: resources, routerBaseName: routerBaseName, decorateComponentsWithTestId: decorateComponentsWithTestId, debugEnabled: debugEnabled, defaultTheme: defaultTheme, defaultTone: defaultTone, globalProps: globalProps, standalone: standalone, trackContainerHeight: trackContainerHeight, previewMode: previewMode, sources: sources, children: children }) }) }));
60
+ }
61
+ /**
62
+ *
63
+ * @param directCompDepNames The direct dependencies (those are component names)
64
+ * of the component for which the transitive dependencies will be returned
65
+ * @param components the compilation info of all the components of the project */
66
+ function getTransitiveDependencies(directCompDepNames, components) {
67
+ const allDepsByCompName = components.reduce(function addDepsByNameToCollection(collection, { definition: { name }, dependencies }) {
68
+ return collection.set(name, dependencies);
69
+ }, new Map());
70
+ const transitiveDeps = new Set();
71
+ populateTransitiveDeps(directCompDepNames);
72
+ return transitiveDeps;
73
+ function populateTransitiveDeps(directCompDepNames) {
74
+ if (!directCompDepNames)
75
+ return;
76
+ for (const directDep of directCompDepNames) {
77
+ if (!transitiveDeps.has(directDep)) {
78
+ transitiveDeps.add(directDep);
79
+ const depsOfDirectDep = allDepsByCompName.get(directDep);
80
+ populateTransitiveDeps(depsOfDirectDep);
81
+ }
82
+ }
83
+ }
84
+ }
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.AppWrapper = void 0;
7
+ const jsx_runtime_1 = require("react/jsx-runtime");
8
+ const react_router_dom_1 = require("react-router-dom");
9
+ const react_query_1 = require("@tanstack/react-query");
10
+ const react_helmet_async_1 = require("react-helmet-async");
11
+ const ConfirmationModalContextProvider_1 = require("../../components/ModalDialog/ConfirmationModalContextProvider");
12
+ const constants_1 = require("../constants");
13
+ const IconProvider_1 = require("../../components/IconProvider");
14
+ const ThemeProvider_1 = __importDefault(require("../theming/ThemeProvider"));
15
+ const InspectorContext_1 = require("../InspectorContext");
16
+ const AppRoot_1 = require("./AppRoot");
17
+ const AppContent_1 = require("./AppContent");
18
+ const ErrorBoundary_1 = require("./ErrorBoundary");
19
+ const LoggerContext_1 = require("../../logging/LoggerContext");
20
+ const LoggerInitializer_1 = require("../../logging/LoggerInitializer");
21
+ /**
22
+ * This component wraps the application into other layers of (nested) components
23
+ * that provide app functionality and services requiring unique interaction with
24
+ * the browser or the React environment.
25
+ */
26
+ const AppWrapper = ({ node, previewMode = false, routerBaseName: baseName = "", contributes = constants_1.EMPTY_OBJECT, globalProps, standalone, trackContainerHeight, decorateComponentsWithTestId, debugEnabled, defaultTheme, defaultTone, resources, resourceMap, sources, children, projectCompilation, }) => {
27
+ var _a;
28
+ if (previewMode) {
29
+ // --- Prevent leaking the meta items to the parent document,
30
+ // --- if it lives in an iframe (e.g. docs)
31
+ react_helmet_async_1.HelmetProvider.canUseDOM = false;
32
+ }
33
+ // --- Set a few default properties
34
+ const siteName = (globalProps === null || globalProps === void 0 ? void 0 : globalProps.name) || "XMLUI app";
35
+ const useHashBasedRouting = (_a = globalProps === null || globalProps === void 0 ? void 0 : globalProps.useHashBasedRouting) !== null && _a !== void 0 ? _a : true;
36
+ // --- The children of the AppWrapper component are the components that
37
+ // --- provide the app functionality and services. These components are
38
+ // --- wrapped in other components that provide the necessary environment
39
+ // --- for the app to run.
40
+ const dynamicChildren = ((0, jsx_runtime_1.jsxs)(react_helmet_async_1.HelmetProvider, { children: [(0, jsx_runtime_1.jsx)(react_helmet_async_1.Helmet, { defaultTitle: siteName, titleTemplate: `%s | ${siteName}` }), (0, jsx_runtime_1.jsxs)(LoggerContext_1.LoggerProvider, { children: [(0, jsx_runtime_1.jsx)(LoggerInitializer_1.LoggerInitializer, {}), (0, jsx_runtime_1.jsx)(IconProvider_1.IconProvider, { children: (0, jsx_runtime_1.jsx)(ThemeProvider_1.default, { resourceMap: resourceMap, themes: contributes.themes, defaultTheme: defaultTheme, defaultTone: defaultTone, resources: resources, children: (0, jsx_runtime_1.jsx)(InspectorContext_1.InspectorProvider, { sources: sources, projectCompilation: projectCompilation, mockApi: globalProps === null || globalProps === void 0 ? void 0 : globalProps.demoMockApi, children: (0, jsx_runtime_1.jsx)(ConfirmationModalContextProvider_1.ConfirmationModalContextProvider, { children: (0, jsx_runtime_1.jsx)(AppContent_1.AppContent, { rootContainer: node, routerBaseName: baseName, globalProps: globalProps, standalone: standalone, decorateComponentsWithTestId: decorateComponentsWithTestId, debugEnabled: debugEnabled, trackContainerHeight: trackContainerHeight, children: children }) }) }) }) })] })] }));
41
+ // --- Select the router type for the app
42
+ const Router = previewMode ? react_router_dom_1.MemoryRouter : useHashBasedRouting ? react_router_dom_1.HashRouter : react_router_dom_1.BrowserRouter;
43
+ return (
44
+ // <React.StrictMode>
45
+ (0, jsx_runtime_1.jsx)(ErrorBoundary_1.ErrorBoundary, { node: node, location: "root-outer", children: (0, jsx_runtime_1.jsxs)(react_query_1.QueryClientProvider, { client: AppRoot_1.queryClient, children: [(typeof window === "undefined" || process.env.VITE_REMIX) && dynamicChildren, !(typeof window === "undefined" || process.env.VITE_REMIX) && ((0, jsx_runtime_1.jsx)(Router, { basename: Router === react_router_dom_1.HashRouter ? undefined : baseName, children: dynamicChildren }))] }) })
46
+ // </React.StrictMode>
47
+ );
48
+ };
49
+ exports.AppWrapper = AppWrapper;
@@ -132,14 +132,13 @@ const ComponentAdapter = (0, react_1.forwardRef)(function ComponentAdapter(_a, r
132
132
  const apiBoundProps = (0, react_1.useMemo)(() => getApiBoundItems(safeNode.props, "DataSource", "DataSourceRef"), [safeNode.props]);
133
133
  const apiBoundEvents = (0, react_1.useMemo)(() => getApiBoundItems(safeNode.events, "APICall", "FileDownload", "FileUpload"), [safeNode.events]);
134
134
  const isApiBound = apiBoundProps.length > 0 || apiBoundEvents.length > 0;
135
- // --- API-bound components provide helpful behavior out of the box, such as transforming API-bound
136
- // --- events and properties. This extra functionality is implemented in `ApiBoundComponent`.
137
- if (isApiBound) {
138
- return ((0, jsx_runtime_1.jsx)(ApiBoundComponent_1.ApiBoundComponent, { uid: uid, renderChild: memoedRenderChild, node: safeNode, apiBoundEvents: apiBoundEvents, apiBoundProps: apiBoundProps, layoutContextRef: layoutContextRef, parentRendererContext: parentRenderContext }, safeNode.uid));
139
- }
140
135
  // --- Obtain the component renderer and descriptor from the component registry
141
136
  const componentRegistry = (0, ComponentRegistryContext_1.useComponentRegistry)();
142
137
  const { renderer, descriptor, isCompoundComponent } = componentRegistry.lookupComponentRenderer(safeNode.type) || {};
138
+ // if (safeNode.type.startsWith("Component")) {
139
+ // console.log("renderer", renderer, safeNode.type);
140
+ // console.log("registry", componentRegistry.getRegisteredComponentKeys().length);
141
+ // }
143
142
  // --- Obtain a function that can lookup an event handler, which is bound to a
144
143
  // --- particular event of this component instance
145
144
  const memoedLookupEventHandler = (0, react_1.useCallback)((eventName, actionOptions) => {
@@ -228,6 +227,11 @@ const ComponentAdapter = (0, react_1.forwardRef)(function ComponentAdapter(_a, r
228
227
  const resolvedUid = (0, extractParam_1.extractParam)(state, testId, appContext, true);
229
228
  renderedNode = ((0, jsx_runtime_1.jsx)(ComponentDecorator_1.default, { attr: { "data-testid": resolvedUid, "data-inspectId": inspectId }, allowOnlyRefdChild: isCompoundComponent || safeNode.type === "ModalDialog", onTargetMounted: safeNode.type === "ModalDialog" ? refreshInspection : undefined, ref: ref, children: (0, react_1.cloneElement)(renderedNode, Object.assign({}, (0, mergeProps_1.mergeProps)(Object.assign(Object.assign({}, renderedNode.props), mouseEventHandlers), rest))) }));
230
229
  }
230
+ // --- API-bound components provide helpful behavior out of the box, such as transforming API-bound
231
+ // --- events and properties. This extra functionality is implemented in `ApiBoundComponent`.
232
+ if (isApiBound) {
233
+ return ((0, jsx_runtime_1.jsx)(ApiBoundComponent_1.ApiBoundComponent, { uid: uid, renderChild: memoedRenderChild, node: safeNode, apiBoundEvents: apiBoundEvents, apiBoundProps: apiBoundProps, layoutContextRef: layoutContextRef, parentRendererContext: parentRenderContext }, safeNode.uid));
234
+ }
231
235
  // --- The current layout context may suggest to wrap the rendered node.
232
236
  if ((_b = layoutContextRef.current) === null || _b === void 0 ? void 0 : _b.wrapChild) {
233
237
  renderedNode = layoutContextRef.current.wrapChild(rendererContext, renderedNode, descriptor);
@@ -251,10 +255,16 @@ const ComponentAdapter = (0, react_1.forwardRef)(function ComponentAdapter(_a, r
251
255
  return (0, react_1.cloneElement)(renderedNode, Object.assign({
252
256
  // ref: ref ? composeRefs(ref, (renderedNode as any).ref) : (renderedNode as any).ref,
253
257
  // ...mergeProps({ ...renderedNode.props, ...mouseEventHandlers }, rest),
254
- ref: renderedNode.type === react_1.default.Fragment ? undefined : (ref ? (0, react_compose_refs_1.composeRefs)(ref, renderedNode.ref) : renderedNode.ref) }, (0, mergeProps_1.mergeProps)(Object.assign(Object.assign({}, renderedNode.props), (renderedNode.type !== react_1.default.Fragment ? mouseEventHandlers : {})), rest)), ...(childrenArray));
258
+ ref: renderedNode.type === react_1.default.Fragment
259
+ ? undefined
260
+ : ref
261
+ ? (0, react_compose_refs_1.composeRefs)(ref, renderedNode.ref)
262
+ : renderedNode.ref }, (0, mergeProps_1.mergeProps)(Object.assign(Object.assign({}, renderedNode.props), (renderedNode.type !== react_1.default.Fragment ? mouseEventHandlers : {})), rest)), ...childrenArray);
255
263
  }
256
264
  // --- If the rendering resulted in multiple React nodes, wrap them in a fragment.
257
- return (react_1.default.isValidElement(renderedNode) && !!children) ? (0, react_1.cloneElement)(renderedNode, null, children) : renderedNode;
265
+ return react_1.default.isValidElement(renderedNode) && !!children
266
+ ? (0, react_1.cloneElement)(renderedNode, null, children)
267
+ : renderedNode;
258
268
  });
259
269
  /**
260
270
  * This function renders the content of a slot. If the slot is named, it looks for a template
@@ -329,7 +329,8 @@ exports.Container = (0, react_1.memo)((0, react_1.forwardRef)(function Container
329
329
  // --- We have an unknown event handler
330
330
  throw new Error("Invalid event handler");
331
331
  }
332
- if (options === null || options === void 0 ? void 0 : options.ephemeral) {
332
+ //if we have a context or ephemeral event handler, we don't cache it (otherwise we would have stale reference for the context)
333
+ if ((options === null || options === void 0 ? void 0 : options.ephemeral) || (options === null || options === void 0 ? void 0 : options.context)) {
333
334
  return handler;
334
335
  }
335
336
  if (!((_a = fnsRef.current[uid]) === null || _a === void 0 ? void 0 : _a[fnCacheKey])) {
@@ -201,7 +201,7 @@ exports.builtInThemes = [
201
201
  solid_1.SolidThemeDefinition,
202
202
  ];
203
203
  // theme-overriding properties change.
204
- function ThemeProvider({ children, themes: custThemes = constants_1.EMPTY_ARRAY, defaultTheme = "xmlui", defaultTone = "light", resources = constants_1.EMPTY_OBJECT, resourceMap = constants_1.EMPTY_OBJECT, }) {
204
+ function ThemeProvider({ children, themes: custThemes = constants_1.EMPTY_ARRAY, defaultTheme = "xmlui", defaultTone = "light", resources = constants_1.EMPTY_OBJECT, resourceMap = constants_1.EMPTY_OBJECT, localThemes = constants_1.EMPTY_OBJECT, }) {
205
205
  const [activeThemeTone, setActiveThemeTone] = (0, react_1.useState)(() => {
206
206
  if (!defaultTone) {
207
207
  return ThemingDefs_1.ThemeToneKeys[0];
@@ -271,6 +271,7 @@ function ThemeProvider({ children, themes: custThemes = constants_1.EMPTY_ARRAY,
271
271
  resources,
272
272
  root,
273
273
  themes,
274
+ localThemes,
274
275
  ]);
275
276
  const currentThemeContextValue = (0, react_1.useMemo)(() => {
276
277
  const themeVal = {
@@ -326,12 +327,6 @@ function resolveThemeVarsWithCssVars(theme) {
326
327
  }
327
328
  return ret;
328
329
  }
329
- // for (let i = 1; i < (result?.length || 0); i++) {
330
- // const varName = result?.[i];
331
- // if(varName){
332
- // return input.replace(regex, `var(${getVarKey(varName)})`);
333
- // }
334
- // }
335
330
  return input;
336
331
  }
337
332
  }
@@ -155,6 +155,7 @@ exports.RootThemeDefinition = {
155
155
  "fontFamily": "$fontFamily-sans-serif",
156
156
  // --- Various font sizes (relative to the current context)
157
157
  "fontSize-gigantic": "3rem",
158
+ "fontSize-larger": "2.15rem",
158
159
  "fontSize-large": "1.5rem",
159
160
  "fontSize-medium": "1.25rem",
160
161
  "fontSize-normal": "1rem",
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isoDateString = isoDateString;
4
+ exports.formatDate = formatDate;
5
+ exports.formatDateTime = formatDateTime;
6
+ exports.formatTime = formatTime;
7
+ exports.formatTimeWithoutSeconds = formatTimeWithoutSeconds;
8
+ exports.formatDateWithoutYear = formatDateWithoutYear;
9
+ exports.getDate = getDate;
10
+ exports.getDateUntilNow = getDateUntilNow;
11
+ exports.smartFormatDateTime = smartFormatDateTime;
12
+ exports.smartFormatDate = smartFormatDate;
13
+ exports.isDateToday = isDateToday;
14
+ exports.isDateYesterday = isDateYesterday;
15
+ exports.isDateTomorrow = isDateTomorrow;
16
+ const date_fns_1 = require("date-fns");
17
+ const misc_1 = require("../utils/misc");
18
+ function isoDateString(date) {
19
+ return (!date ? new Date() : new Date(date)).toJSON();
20
+ }
21
+ function formatDate(date) {
22
+ return new Date(date).toLocaleDateString();
23
+ }
24
+ function formatDateTime(date) {
25
+ return new Date(date).toLocaleString();
26
+ }
27
+ function formatTime(date) {
28
+ return new Date(date).toLocaleTimeString();
29
+ }
30
+ function formatTimeWithoutSeconds(date) {
31
+ return (0, date_fns_1.format)(new Date(date), "H:m");
32
+ }
33
+ function formatDateWithoutYear(date) {
34
+ return new Date(date).toLocaleDateString([], {
35
+ month: "numeric",
36
+ day: "2-digit"
37
+ });
38
+ }
39
+ function getDate(date) {
40
+ return date ? new Date(date) : new Date();
41
+ }
42
+ function getDateUntilNow(date, nowLabel, time) {
43
+ return date ? (0, misc_1.humanReadableDateTimeTillNow)(date, nowLabel, time) : "-";
44
+ }
45
+ function smartFormatDateTime(date) {
46
+ if (!date) {
47
+ return "-";
48
+ }
49
+ if ((0, date_fns_1.isToday)(new Date(date))) {
50
+ return new Date(date).toLocaleTimeString();
51
+ }
52
+ if ((0, date_fns_1.isThisWeek)(new Date(date))) {
53
+ return `${(0, date_fns_1.formatRelative)(new Date(date), new Date())}`;
54
+ }
55
+ return new Date(date).toLocaleString();
56
+ }
57
+ function smartFormatDate(date) {
58
+ if (!date) {
59
+ return "-";
60
+ }
61
+ //TODO we could use formatRelative when they implement this: https://github.com/date-fns/date-fns/issues/1218
62
+ if ((0, date_fns_1.isToday)(new Date(date))) {
63
+ return "Today";
64
+ }
65
+ if ((0, date_fns_1.isYesterday)(new Date(date))) {
66
+ return "Yesterday";
67
+ }
68
+ return new Date(date).toLocaleDateString();
69
+ }
70
+ function isDateToday(date) {
71
+ return (0, date_fns_1.isToday)(new Date(date));
72
+ }
73
+ function isDateYesterday(date) {
74
+ return (0, date_fns_1.isYesterday)(new Date(date));
75
+ }
76
+ function isDateTomorrow(date) {
77
+ return (0, date_fns_1.isTomorrow)(new Date(date));
78
+ }