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.
- package/dist/apiInterceptorWorker-CFF3bC6o.mjs +818 -0
- package/dist/{index-B3CWFAxa.mjs → index-DtxDGaqF.mjs} +11942 -3291
- package/dist/index.css +1301 -564
- package/dist/language-server-web-worker.mjs +1 -1
- package/dist/language-server.mjs +1 -1
- package/dist/lint-CYAUfk0_.mjs +168 -0
- package/dist/metadata-utils-CCIMqe69.mjs +466 -0
- package/dist/scripts/package.json +252 -0
- package/dist/scripts/src/components/App/AppLayoutContext.js +0 -1
- package/dist/scripts/src/components/App/AppNative.js +21 -9
- package/dist/scripts/src/components/AppHeader/AppHeader.js +1 -1
- package/dist/scripts/src/components/AutoComplete/AutoComplete.js +5 -2
- package/dist/scripts/src/components/AutoComplete/AutoCompleteNative.js +13 -10
- package/dist/scripts/src/components/Bookmark/BookmarkNative.js +5 -1
- package/dist/scripts/src/components/CodeBlock/CodeBlock.js +31 -0
- package/dist/scripts/src/components/CodeBlock/CodeBlockNative.js +82 -0
- package/dist/scripts/src/components/ComponentProvider.js +5 -0
- package/dist/scripts/src/components/DatePicker/DatePickerNative.js +1 -0
- package/dist/scripts/src/components/Form/FormContext.js +5 -4
- package/dist/scripts/src/components/Form/FormNative.js +41 -43
- package/dist/scripts/src/components/Form/formActions.js +1 -1
- package/dist/scripts/src/components/FormItem/FormItem.js +6 -3
- package/dist/scripts/src/components/FormItem/FormItemNative.js +56 -15
- package/dist/scripts/src/components/FormItem/ItemWithLabel.js +1 -1
- package/dist/scripts/src/components/Heading/Heading.js +13 -0
- package/dist/scripts/src/components/Heading/HeadingNative.js +1 -1
- package/dist/scripts/src/components/HtmlTags/HtmlTags.js +7 -3
- package/dist/scripts/src/components/Icon/DarkToLightIcon.js +10 -0
- package/dist/scripts/src/components/Icon/LightToDark.js +10 -0
- package/dist/scripts/src/components/IconProvider.js +4 -0
- package/dist/scripts/src/components/Image/ImageNative.js +1 -1
- package/dist/scripts/src/components/Items/ItemsNative.js +8 -6
- package/dist/scripts/src/components/Link/Link.js +5 -5
- package/dist/scripts/src/components/List/ListNative.js +1 -1
- package/dist/scripts/src/components/Markdown/Markdown.js +52 -16
- package/dist/scripts/src/components/Markdown/MarkdownNative.js +34 -73
- package/dist/scripts/src/components/Markdown/highlight-code.js +160 -0
- package/dist/scripts/src/components/Markdown/parse-binding-expr.js +60 -0
- package/dist/scripts/src/components/Markdown/utils.js +282 -0
- package/dist/scripts/src/components/ModalDialog/ConfirmationModalContextProvider.js +116 -0
- package/dist/scripts/src/components/ModalDialog/Dialog.js +20 -0
- package/dist/scripts/src/components/NavGroup/NavGroupNative.js +4 -5
- package/dist/scripts/src/components/NestedApp/NestedApp.js +61 -0
- package/dist/scripts/src/components/NestedApp/NestedAppNative.js +125 -0
- package/dist/scripts/src/components/NestedApp/Tooltip.js +46 -0
- package/dist/scripts/src/components/NumberBox/NumberBox.js +4 -1
- package/dist/scripts/src/components/NumberBox/NumberBoxNative.js +2 -2
- package/dist/scripts/src/components/Option/Option.js +3 -2
- package/dist/scripts/src/components/Select/Select.js +5 -3
- package/dist/scripts/src/components/Select/SelectNative.js +53 -40
- package/dist/scripts/src/components/SelectionStore/SelectionStore.js +1 -1
- package/dist/scripts/src/components/Spinner/Spinner.js +0 -1
- package/dist/scripts/src/components/TableOfContents/TableOfContents.js +1 -0
- package/dist/scripts/src/components/Text/Text.js +12 -1
- package/dist/scripts/src/components/Text/TextNative.js +5 -1
- package/dist/scripts/src/components/TextBox/TextBox.js +6 -1
- package/dist/scripts/src/components/TextBox/TextBoxNative.js +2 -2
- package/dist/scripts/src/components/Theme/ThemeNative.js +7 -3
- package/dist/scripts/src/components/ToneChangerButton/ToneChangerButton.js +1 -3
- package/dist/scripts/src/components-core/RestApiProxy.js +10 -7
- package/dist/scripts/src/components-core/TableOfContentsContext.js +1 -1
- package/dist/scripts/src/components-core/appContext/date-functions.js +23 -0
- package/dist/scripts/src/components-core/appContext/math-function.js +27 -0
- package/dist/scripts/src/components-core/appContext/misc-utils.js +13 -0
- package/dist/scripts/src/components-core/interception/ApiInterceptor.js +199 -0
- package/dist/scripts/src/components-core/interception/ApiInterceptorProvider.js +94 -0
- package/dist/scripts/src/components-core/interception/Backend.js +128 -0
- package/dist/scripts/src/components-core/interception/Errors.js +129 -0
- package/dist/scripts/src/components-core/interception/InMemoryDb.js +41 -0
- package/dist/scripts/src/components-core/interception/IndexedDb.js +207 -0
- package/dist/scripts/src/components-core/interception/ReadonlyCollection.js +145 -0
- package/dist/scripts/src/components-core/interception/abstractions.js +2 -0
- package/dist/scripts/src/components-core/interception/apiInterceptorWorker.js +46 -0
- package/dist/scripts/src/components-core/interception/useApiInterceptorContext.js +9 -0
- package/dist/scripts/src/components-core/rendering/AppContent.js +336 -0
- package/dist/scripts/src/components-core/rendering/AppRoot.js +84 -0
- package/dist/scripts/src/components-core/rendering/AppWrapper.js +49 -0
- package/dist/scripts/src/components-core/rendering/ComponentAdapter.js +17 -7
- package/dist/scripts/src/components-core/rendering/Container.js +2 -1
- package/dist/scripts/src/components-core/theming/ThemeProvider.js +2 -7
- package/dist/scripts/src/components-core/theming/themes/root.js +1 -0
- package/dist/scripts/src/components-core/utils/date-utils.js +78 -0
- package/dist/scripts/src/components-core/utils/hooks.js +26 -0
- package/dist/scripts/src/components-core/utils/misc.js +1 -1
- package/dist/scripts/src/components-core/utils/request-params.js +70 -0
- package/dist/scripts/src/logging/LoggerContext.js +22 -0
- package/dist/scripts/src/logging/LoggerInitializer.js +14 -0
- package/dist/scripts/src/logging/LoggerService.js +60 -0
- package/dist/scripts/src/parsers/xmlui-parser/transform.js +7 -0
- package/dist/{server-common-DW5h7Q34.mjs → server-common-9TiLMTJj.mjs} +106 -98
- package/dist/style.css +3314 -2823
- package/dist/{lint-EcgF-9Wr.mjs → transform-DC0Gy6qw.mjs} +1246 -540
- package/dist/xmlui-metadata.mjs +2850 -2665
- package/dist/xmlui-metadata.umd.js +2850 -2665
- package/dist/xmlui-parser.d.ts +49 -4
- package/dist/xmlui-parser.mjs +49 -48
- package/dist/xmlui-standalone.umd.js +34674 -31457
- package/dist/xmlui.d.ts +3 -1
- package/dist/xmlui.mjs +10 -10
- package/package.json +3 -1
- package/dist/apiInterceptorWorker-7aKQ2rBj.mjs +0 -8447
- 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
|
|
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
|
|
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
|
|
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
|
+
}
|