@hitachivantara/app-shell-ui 2.3.2 → 2.3.3

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 (62) hide show
  1. package/dist/components/AppShell/AppShell.js +16 -5
  2. package/dist/components/AppShell/AppShellContainer.js +75 -66
  3. package/dist/components/AppShell/AppShellRouter.js +98 -109
  4. package/dist/components/AppShellI18nProvider/AppShellI18nProvider.js +19 -25
  5. package/dist/components/AppShellProvider/AppShellProvider.js +84 -91
  6. package/dist/components/AppShellViewProvider/AppShellViewProvider.js +10 -7
  7. package/dist/components/ConfigIcon.js +13 -15
  8. package/dist/components/CustomHooksInitializer/CustomHooksInitializer.js +7 -7
  9. package/dist/components/GlobalStyles.js +11 -9
  10. package/dist/components/IconUiKit/IconUiKit.js +10 -8
  11. package/dist/components/InitErrorFallback/InitErrorFallback.js +31 -23
  12. package/dist/components/SnackbarProvider/SnackbarProvider.js +17 -20
  13. package/dist/components/layout/AppShellLayout.js +50 -65
  14. package/dist/components/layout/BrandLogo/BrandLogo.js +25 -35
  15. package/dist/components/layout/BrandLogo/logos.js +38 -55
  16. package/dist/components/layout/Header/Header.js +55 -74
  17. package/dist/components/layout/HeaderActions/AppSwitcherToggle/AppSwitcherToggle.js +66 -74
  18. package/dist/components/layout/HeaderActions/AppSwitcherToggle/styles.js +12 -12
  19. package/dist/components/layout/HeaderActions/ColorModeSwitcher.js +23 -26
  20. package/dist/components/layout/HeaderActions/DynamicAction.js +22 -21
  21. package/dist/components/layout/HeaderActions/HeaderActions.js +15 -22
  22. package/dist/components/layout/HeaderActions/HelpButton/HelpButton.js +22 -31
  23. package/dist/components/layout/HeaderActions/InternalAction/InternalAction.js +25 -36
  24. package/dist/components/layout/VerticalNavigation/NavigationCollapse.js +29 -34
  25. package/dist/components/layout/VerticalNavigation/NavigationHeader.js +18 -20
  26. package/dist/components/layout/VerticalNavigation/VerticalNavigation.js +96 -130
  27. package/dist/hooks/useClearLocationState.js +10 -12
  28. package/dist/hooks/useConditionsEvaluator.js +67 -81
  29. package/dist/hooks/useCustomEventListener.js +16 -28
  30. package/dist/hooks/useFilteredModel.js +30 -27
  31. package/dist/hooks/useLocalStorage.js +26 -26
  32. package/dist/hooks/useModelFromConfig.js +43 -39
  33. package/dist/hooks/useNavigationMenuItems.js +27 -30
  34. package/dist/hooks/useNotificationsEventListener.js +35 -42
  35. package/dist/hooks/useResizeObserver.js +13 -13
  36. package/dist/hooks/useThemeEventListener.js +17 -18
  37. package/dist/i18n/constants.js +5 -6
  38. package/dist/i18n/index.js +26 -20
  39. package/dist/i18n/useI18nInit.js +72 -66
  40. package/dist/index.js +4 -3
  41. package/dist/pages/ErrorPage/ErrorPage.js +33 -32
  42. package/dist/pages/ErrorPage/Footer.js +46 -55
  43. package/dist/pages/GenericError/CatServer.js +585 -569
  44. package/dist/pages/GenericError/GenericError.js +25 -26
  45. package/dist/pages/LoadingPage/LoadingPage.js +9 -17
  46. package/dist/pages/LoadingPage/index.js +4 -3
  47. package/dist/pages/NotFound/DogeSpace.js +505 -540
  48. package/dist/pages/NotFound/NotFound.js +17 -20
  49. package/dist/pages/NotFound/index.js +2 -4
  50. package/dist/pages/RootRoute.js +32 -19
  51. package/dist/providers/BannerProvider.js +98 -123
  52. package/dist/providers/LayoutProvider.js +26 -32
  53. package/dist/providers/NavigationProvider.js +96 -107
  54. package/dist/utils/CombinedProviders.js +12 -18
  55. package/dist/utils/documentUtil.js +12 -12
  56. package/dist/utils/filterModel.js +134 -170
  57. package/dist/utils/lazyImport.js +31 -36
  58. package/dist/utils/navigationUtil.js +68 -53
  59. package/dist/utils/processConfig.js +119 -153
  60. package/package.json +8 -8
  61. package/dist/components/IconUiKit/index.js +0 -6
  62. package/dist/pages/LoadingPage/styles.js +0 -30
@@ -1,9 +1,20 @@
1
- import { jsx } from "react/jsx-runtime";
2
1
  import { HvAppShellContainer } from "./AppShellContainer.js";
3
2
  import { HvAppShellRouter } from "./AppShellRouter.js";
3
+ import { jsx } from "react/jsx-runtime";
4
+ //#region src/components/AppShell/AppShell.tsx
5
+ /**
6
+ * The main App Shell UI component that:
7
+ * - Loads the configuration via `config` or `configUrl`
8
+ * - Instantiates Global Providers (i18n, theming, error boundary, etc)
9
+ * - Renders the App Shell Header & Vertical Navigation Layout
10
+ * - Instantiates the App Shell Router for the given configuration
11
+ */
4
12
  function HvAppShell({ config, configUrl }) {
5
- return /* @__PURE__ */ jsx(HvAppShellContainer, { config, configUrl, children: /* @__PURE__ */ jsx(HvAppShellRouter, {}) });
13
+ return /* @__PURE__ */ jsx(HvAppShellContainer, {
14
+ config,
15
+ configUrl,
16
+ children: /* @__PURE__ */ jsx(HvAppShellRouter, {})
17
+ });
6
18
  }
7
- export {
8
- HvAppShell as default
9
- };
19
+ //#endregion
20
+ export { HvAppShell as default };
@@ -1,77 +1,86 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Suspense } from "react";
3
- import { ErrorBoundary } from "react-error-boundary";
4
- import { HelmetProvider } from "react-helmet-async";
5
- import { I18nextProvider } from "react-i18next";
6
- import { HvProvider, HvLoading } from "@hitachivantara/uikit-react-core";
1
+ import useI18nInit from "../../i18n/useI18nInit.js";
7
2
  import { createI18NextInstance } from "../../i18n/index.js";
3
+ import GenericError from "../../pages/GenericError/GenericError.js";
8
4
  import { LayoutProvider } from "../../providers/LayoutProvider.js";
9
5
  import { HvAppShellI18nProvider } from "../AppShellI18nProvider/AppShellI18nProvider.js";
10
6
  import { HvAppShellProvider } from "../AppShellProvider/AppShellProvider.js";
11
7
  import { GlobalStyles } from "../GlobalStyles.js";
12
8
  import InitErrorFallback from "../InitErrorFallback/InitErrorFallback.js";
13
- import useI18nInit from "../../i18n/useI18nInit.js";
14
9
  import SnackbarProvider from "../SnackbarProvider/SnackbarProvider.js";
15
- import GenericError from "../../pages/GenericError/GenericError.js";
16
- const i18n = createI18NextInstance();
17
- const configRequests = /* @__PURE__ */ new Map();
10
+ import { Suspense } from "react";
11
+ import { ErrorBoundary } from "react-error-boundary";
12
+ import { HelmetProvider } from "react-helmet-async";
13
+ import { I18nextProvider } from "react-i18next";
14
+ import { HvLoading, HvProvider } from "@hitachivantara/uikit-react-core";
15
+ import { jsx, jsxs } from "react/jsx-runtime";
16
+ //#region src/components/AppShell/AppShellContainer.tsx
17
+ var i18n = createI18NextInstance();
18
+ var configRequests = /* @__PURE__ */ new Map();
18
19
  function useConfig(configProp, configUrl) {
19
- if (configProp) return configProp;
20
- if (!configUrl) return void 0;
21
- let cached = configRequests.get(configUrl);
22
- if (!cached) {
23
- const req = {
24
- status: "pending",
25
- promise: fetch(new URL(configUrl, document.baseURI)).then((r) => r.json()).then((data) => {
26
- req.status = "fulfilled";
27
- req.result = data;
28
- }).catch((err) => {
29
- req.status = "rejected";
30
- req.error = err;
31
- })
32
- };
33
- configRequests.set(configUrl, req);
34
- cached = req;
35
- }
36
- if (cached.status === "fulfilled") return cached.result;
37
- if (cached.status === "rejected") throw cached.error;
38
- throw cached.promise;
20
+ if (configProp) return configProp;
21
+ if (!configUrl) return void 0;
22
+ let cached = configRequests.get(configUrl);
23
+ if (!cached) {
24
+ const req = {
25
+ status: "pending",
26
+ promise: fetch(new URL(configUrl, document.baseURI)).then((r) => r.json()).then((data) => {
27
+ req.status = "fulfilled";
28
+ req.result = data;
29
+ }).catch((err) => {
30
+ req.status = "rejected";
31
+ req.error = err;
32
+ })
33
+ };
34
+ configRequests.set(configUrl, req);
35
+ cached = req;
36
+ }
37
+ if (cached.status === "fulfilled") return cached.result;
38
+ if (cached.status === "rejected") throw cached.error;
39
+ throw cached.promise;
39
40
  }
40
- function AppShellContainerInner({
41
- config: configProp,
42
- configUrl,
43
- children
44
- }) {
45
- const config = useConfig(
46
- configProp,
47
- configUrl
48
- );
49
- useI18nInit(i18n, config, configUrl);
50
- return /* @__PURE__ */ jsx(I18nextProvider, { i18n, children: /* @__PURE__ */ jsx(HvAppShellI18nProvider, { children: /* @__PURE__ */ jsx(
51
- ErrorBoundary,
52
- {
53
- fallback: /* @__PURE__ */ jsx(GenericError, { includeFooter: false }),
54
- children: /* @__PURE__ */ jsx(HvAppShellProvider, { config, children: /* @__PURE__ */ jsx(LayoutProvider, { children: /* @__PURE__ */ jsx(SnackbarProvider, { children }) }) })
55
- },
56
- "general"
57
- ) }) });
41
+ /**
42
+ * Inner component that resolves config, initializes i18n synchronously,
43
+ * then renders the provider tree.
44
+ *
45
+ * Because it may throw a Promise (via `useConfig`), it MUST be wrapped in
46
+ * a `<Suspense>` boundary by the parent `HvAppShellContainer`.
47
+ */
48
+ function AppShellContainerInner({ config: configProp, configUrl, children }) {
49
+ const config = useConfig(configProp, configUrl);
50
+ useI18nInit(i18n, config, configUrl);
51
+ return /* @__PURE__ */ jsx(I18nextProvider, {
52
+ i18n,
53
+ children: /* @__PURE__ */ jsx(HvAppShellI18nProvider, { children: /* @__PURE__ */ jsx(ErrorBoundary, {
54
+ fallback: /* @__PURE__ */ jsx(GenericError, { includeFooter: false }),
55
+ children: /* @__PURE__ */ jsx(HvAppShellProvider, {
56
+ config,
57
+ children: /* @__PURE__ */ jsx(LayoutProvider, { children: /* @__PURE__ */ jsx(SnackbarProvider, { children }) })
58
+ })
59
+ }, "general") })
60
+ });
58
61
  }
59
- function HvAppShellContainer({
60
- config,
61
- configUrl,
62
- children
63
- }) {
64
- return /* @__PURE__ */ jsx(HelmetProvider, { children: /* @__PURE__ */ jsxs(HvProvider, { children: [
65
- /* @__PURE__ */ jsx(GlobalStyles, {}),
66
- /* @__PURE__ */ jsx(ErrorBoundary, { fallback: /* @__PURE__ */ jsx(InitErrorFallback, {}), children: /* @__PURE__ */ jsx(
67
- Suspense,
68
- {
69
- fallback: /* @__PURE__ */ jsx(HvLoading, { style: { height: "100vh", width: "100%" } }),
70
- children: /* @__PURE__ */ jsx(AppShellContainerInner, { config, configUrl, children })
71
- }
72
- ) })
73
- ] }) });
62
+ /**
63
+ * Top-level App Shell container.
64
+ *
65
+ * Wraps everything in global providers (Helmet, theme, styles) and a
66
+ * `<Suspense>` boundary that shows a loading indicator while the config
67
+ * is being fetched and i18next is being initialized.
68
+ */
69
+ function HvAppShellContainer({ config, configUrl, children }) {
70
+ return /* @__PURE__ */ jsx(HelmetProvider, { children: /* @__PURE__ */ jsxs(HvProvider, { children: [/* @__PURE__ */ jsx(GlobalStyles, {}), /* @__PURE__ */ jsx(ErrorBoundary, {
71
+ fallback: /* @__PURE__ */ jsx(InitErrorFallback, {}),
72
+ children: /* @__PURE__ */ jsx(Suspense, {
73
+ fallback: /* @__PURE__ */ jsx(HvLoading, { style: {
74
+ height: "100vh",
75
+ width: "100%"
76
+ } }),
77
+ children: /* @__PURE__ */ jsx(AppShellContainerInner, {
78
+ config,
79
+ configUrl,
80
+ children
81
+ })
82
+ })
83
+ })] }) });
74
84
  }
75
- export {
76
- HvAppShellContainer
77
- };
85
+ //#endregion
86
+ export { HvAppShellContainer };
@@ -1,118 +1,107 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import { useRef, useState, useMemo, useEffect, lazy, Fragment } from "react";
3
- import { ErrorBoundary } from "react-error-boundary";
4
- import { matchRoutes, RouterProvider, createBrowserRouter, Outlet } from "react-router-dom";
5
- import { useHvAppShellModel } from "@hitachivantara/app-shell-shared";
6
- import { HvContainer } from "@hitachivantara/uikit-react-core";
7
- import LoadingPage from "../../pages/LoadingPage/LoadingPage.js";
8
- import { RootRoute } from "../../pages/RootRoute.js";
9
1
  import { getAppIdFromBundle } from "../../utils/navigationUtil.js";
10
2
  import GenericError from "../../pages/GenericError/GenericError.js";
3
+ import LoadingPage_default from "../../pages/LoadingPage/index.js";
4
+ import { RootRoute } from "../../pages/RootRoute.js";
11
5
  import AppShellViewProvider from "../AppShellViewProvider/AppShellViewProvider.js";
12
- const NotFound = lazy(() => import("../../pages/NotFound/index.js"));
6
+ import { Fragment, lazy, useEffect, useMemo, useRef, useState } from "react";
7
+ import { ErrorBoundary } from "react-error-boundary";
8
+ import { HvContainer } from "@hitachivantara/uikit-react-core";
9
+ import { useHvAppShellModel } from "@hitachivantara/app-shell-shared";
10
+ import { Outlet, RouterProvider, createBrowserRouter, matchRoutes } from "react-router-dom";
11
+ import { jsx } from "react/jsx-runtime";
12
+ //#region src/components/AppShell/AppShellRouter.tsx
13
+ var NotFound = lazy(() => import("../../pages/NotFound/index.js"));
13
14
  function renderNestedRoutes(views) {
14
- if (!views) {
15
- return void 0;
16
- }
17
- return views.map((view) => {
18
- const { bundle, route } = view;
19
- const appId = getAppIdFromBundle(bundle);
20
- const RouteComponent = lazy(() => import(
21
- /* @vite-ignore */
22
- bundle
23
- ));
24
- const path = route.replace(/^\//, "");
25
- return {
26
- path,
27
- // "Component" used instead of "element" due to lazy loading
28
- Component: () => /* @__PURE__ */ jsx(AppShellViewProvider, { id: appId, children: /* @__PURE__ */ jsx(ErrorBoundary, { fallback: /* @__PURE__ */ jsx(GenericError, {}), children: /* @__PURE__ */ jsx(RouteComponent, { ...view.config, children: view.views ? /* @__PURE__ */ jsx(Outlet, {}) : null }) }, view.key) }),
29
- children: renderNestedRoutes(view.views)
30
- };
31
- });
15
+ if (!views) return;
16
+ return views.map((view) => {
17
+ const { bundle, route } = view;
18
+ const appId = getAppIdFromBundle(bundle);
19
+ const RouteComponent = lazy(() => import(
20
+ /* @vite-ignore */
21
+ bundle
22
+ ));
23
+ return {
24
+ path: route.replace(/^\//, ""),
25
+ Component: () => /* @__PURE__ */ jsx(AppShellViewProvider, {
26
+ id: appId,
27
+ children: /* @__PURE__ */ jsx(ErrorBoundary, {
28
+ fallback: /* @__PURE__ */ jsx(GenericError, {}),
29
+ children: /* @__PURE__ */ jsx(RouteComponent, {
30
+ ...view.config,
31
+ children: view.views ? /* @__PURE__ */ jsx(Outlet, {}) : null
32
+ })
33
+ }, view.key)
34
+ }),
35
+ children: renderNestedRoutes(view.views)
36
+ };
37
+ });
32
38
  }
33
39
  function renderRoutes(mainPanel) {
34
- if (mainPanel?.views == null) {
35
- return [];
36
- }
37
- const { views, maxWidth = "xl", ...mainContainerProps } = mainPanel;
38
- return views.map((view) => {
39
- const {
40
- bundle,
41
- route,
42
- config,
43
- views: nestedViews,
44
- maxWidth: viewMaxWidth,
45
- key,
46
- conditions,
47
- disableContainer,
48
- ...viewContainerProps
49
- } = view;
50
- const appId = getAppIdFromBundle(bundle);
51
- const RouteComponent = lazy(() => import(
52
- /* @vite-ignore */
53
- bundle
54
- ));
55
- const showContainer = !(disableContainer ?? mainPanel.disableContainer);
56
- const containerProps = showContainer && {
57
- maxWidth: viewMaxWidth ?? maxWidth,
58
- ...mainContainerProps,
59
- ...viewContainerProps
60
- };
61
- const ContainerComponent = showContainer ? HvContainer : Fragment;
62
- return {
63
- path: route,
64
- // "Component" used instead of "element" due to lazy loading
65
- Component: () => /* @__PURE__ */ jsx(ErrorBoundary, { fallback: /* @__PURE__ */ jsx(GenericError, {}), children: /* @__PURE__ */ jsx(ContainerComponent, { ...containerProps, children: /* @__PURE__ */ jsx(AppShellViewProvider, { id: appId, children: /* @__PURE__ */ jsx(RouteComponent, { ...config, children: nestedViews ? /* @__PURE__ */ jsx(Outlet, {}) : null }) }) }) }, view.key),
66
- children: renderNestedRoutes(nestedViews)
67
- };
68
- });
40
+ if (mainPanel?.views == null) return [];
41
+ const { views, maxWidth = "xl", ...mainContainerProps } = mainPanel;
42
+ return views.map((view) => {
43
+ const { bundle, route, config, views: nestedViews, maxWidth: viewMaxWidth, key, conditions, disableContainer, ...viewContainerProps } = view;
44
+ const appId = getAppIdFromBundle(bundle);
45
+ const RouteComponent = lazy(() => import(
46
+ /* @vite-ignore */
47
+ bundle
48
+ ));
49
+ const showContainer = !(disableContainer ?? mainPanel.disableContainer);
50
+ const containerProps = showContainer && {
51
+ maxWidth: viewMaxWidth ?? maxWidth,
52
+ ...mainContainerProps,
53
+ ...viewContainerProps
54
+ };
55
+ const ContainerComponent = showContainer ? HvContainer : Fragment;
56
+ return {
57
+ path: route,
58
+ Component: () => /* @__PURE__ */ jsx(ErrorBoundary, {
59
+ fallback: /* @__PURE__ */ jsx(GenericError, {}),
60
+ children: /* @__PURE__ */ jsx(ContainerComponent, {
61
+ ...containerProps,
62
+ children: /* @__PURE__ */ jsx(AppShellViewProvider, {
63
+ id: appId,
64
+ children: /* @__PURE__ */ jsx(RouteComponent, {
65
+ ...config,
66
+ children: nestedViews ? /* @__PURE__ */ jsx(Outlet, {}) : null
67
+ })
68
+ })
69
+ })
70
+ }, view.key),
71
+ children: renderNestedRoutes(nestedViews)
72
+ };
73
+ });
69
74
  }
70
75
  function HvAppShellRouter() {
71
- const { baseUrl, mainPanel } = useHvAppShellModel();
72
- const prevRoutesRef = useRef([]);
73
- const [routerKey, setRouterKey] = useState("router-initial");
74
- const childRoutes = useMemo(
75
- () => [
76
- ...renderRoutes(mainPanel),
77
- // catch-all for 404 route
78
- { path: "*", element: /* @__PURE__ */ jsx(NotFound, {}) }
79
- ],
80
- [mainPanel]
81
- );
82
- useEffect(() => {
83
- if (prevRoutesRef.current.length === 0) {
84
- prevRoutesRef.current = childRoutes;
85
- return;
86
- }
87
- const currentPath = globalThis.location.pathname;
88
- const prevMatch = matchRoutes(prevRoutesRef.current, currentPath);
89
- const newMatch = matchRoutes(childRoutes, currentPath);
90
- const prevWas404 = !prevMatch || prevMatch.at(-1)?.route.path === "*";
91
- const newIs404 = !newMatch || newMatch.at(-1)?.route.path === "*";
92
- if (prevWas404 && !newIs404 || !prevWas404 && newIs404) {
93
- setRouterKey(`router-${newIs404 ? "404" : "valid"}`);
94
- }
95
- prevRoutesRef.current = childRoutes;
96
- }, [baseUrl, childRoutes]);
97
- return /* @__PURE__ */ jsx(
98
- RouterProvider,
99
- {
100
- fallbackElement: /* @__PURE__ */ jsx(LoadingPage, {}),
101
- future: { v7_startTransition: false },
102
- router: createBrowserRouter(
103
- [
104
- {
105
- element: /* @__PURE__ */ jsx(RootRoute, {}),
106
- errorElement: /* @__PURE__ */ jsx(GenericError, {}),
107
- children: childRoutes
108
- }
109
- ],
110
- { basename: baseUrl ?? "/" }
111
- )
112
- },
113
- routerKey
114
- );
76
+ const { baseUrl, mainPanel } = useHvAppShellModel();
77
+ const prevRoutesRef = useRef([]);
78
+ const [routerKey, setRouterKey] = useState("router-initial");
79
+ const childRoutes = useMemo(() => [...renderRoutes(mainPanel), {
80
+ path: "*",
81
+ element: /* @__PURE__ */ jsx(NotFound, {})
82
+ }], [mainPanel]);
83
+ useEffect(() => {
84
+ if (prevRoutesRef.current.length === 0) {
85
+ prevRoutesRef.current = childRoutes;
86
+ return;
87
+ }
88
+ const currentPath = globalThis.location.pathname;
89
+ const prevMatch = matchRoutes(prevRoutesRef.current, currentPath);
90
+ const newMatch = matchRoutes(childRoutes, currentPath);
91
+ const prevWas404 = !prevMatch || prevMatch.at(-1)?.route.path === "*";
92
+ const newIs404 = !newMatch || newMatch.at(-1)?.route.path === "*";
93
+ if (prevWas404 && !newIs404 || !prevWas404 && newIs404) setRouterKey(`router-${newIs404 ? "404" : "valid"}`);
94
+ prevRoutesRef.current = childRoutes;
95
+ }, [baseUrl, childRoutes]);
96
+ return /* @__PURE__ */ jsx(RouterProvider, {
97
+ fallbackElement: /* @__PURE__ */ jsx(LoadingPage_default, {}),
98
+ future: { v7_startTransition: false },
99
+ router: createBrowserRouter([{
100
+ element: /* @__PURE__ */ jsx(RootRoute, {}),
101
+ errorElement: /* @__PURE__ */ jsx(GenericError, {}),
102
+ children: childRoutes
103
+ }], { basename: baseUrl ?? "/" })
104
+ }, routerKey);
115
105
  }
116
- export {
117
- HvAppShellRouter
118
- };
106
+ //#endregion
107
+ export { HvAppShellRouter };
@@ -1,29 +1,23 @@
1
- import { jsx } from "react/jsx-runtime";
2
1
  import { useContext, useMemo } from "react";
3
2
  import { I18nContext, useTranslation } from "react-i18next";
4
3
  import { HvAppShellI18nContext } from "@hitachivantara/app-shell-shared";
5
- function HvAppShellI18nProvider({
6
- children
7
- }) {
8
- const { i18n } = useContext(I18nContext);
9
- useTranslation();
10
- const language = i18n.language;
11
- const appShellI18n = useMemo(
12
- () => ({
13
- language,
14
- changeLanguage: async (newLng) => {
15
- if (i18n) {
16
- await i18n.changeLanguage(newLng);
17
- } else {
18
- console.warn("I18N not initialized");
19
- }
20
- return void 0;
21
- }
22
- }),
23
- [i18n, language]
24
- );
25
- return /* @__PURE__ */ jsx(HvAppShellI18nContext.Provider, { value: appShellI18n, children });
4
+ import { jsx } from "react/jsx-runtime";
5
+ //#region src/components/AppShellI18nProvider/AppShellI18nProvider.tsx
6
+ function HvAppShellI18nProvider({ children }) {
7
+ const { i18n } = useContext(I18nContext);
8
+ useTranslation();
9
+ const language = i18n.language;
10
+ const appShellI18n = useMemo(() => ({
11
+ language,
12
+ changeLanguage: async (newLng) => {
13
+ if (i18n) await i18n.changeLanguage(newLng);
14
+ else console.warn("I18N not initialized");
15
+ }
16
+ }), [i18n, language]);
17
+ return /* @__PURE__ */ jsx(HvAppShellI18nContext.Provider, {
18
+ value: appShellI18n,
19
+ children
20
+ });
26
21
  }
27
- export {
28
- HvAppShellI18nProvider
29
- };
22
+ //#endregion
23
+ export { HvAppShellI18nProvider };
@@ -1,96 +1,89 @@
1
- import { jsx } from "react/jsx-runtime";
2
- import { useContext, useMemo, useState, useEffect } from "react";
3
- import { I18nContext } from "react-i18next";
4
- import { HvAppShellRuntimeContext, HvAppShellContext, HvAppShellModelContext, HvAppShellCombinedProvidersContext } from "@hitachivantara/app-shell-shared";
5
- import { themes, HvProvider } from "@hitachivantara/uikit-react-core";
6
- import { useFilteredModel } from "../../hooks/useFilteredModel.js";
7
1
  import useLocalStorage from "../../hooks/useLocalStorage.js";
2
+ import { useFilteredModel } from "../../hooks/useFilteredModel.js";
8
3
  import { useModelFromConfig } from "../../hooks/useModelFromConfig.js";
9
4
  import CombinedProviders from "../../utils/CombinedProviders.js";
10
- const AppShellProviderInner = ({
11
- config,
12
- model,
13
- children
14
- }) => {
15
- const { value: storedColorModeValue } = useLocalStorage("COLOR_MODE");
16
- const { isPending: isModelPending, model: filteredModel } = useFilteredModel(model);
17
- const [theme, setTheme] = useState();
18
- useEffect(() => {
19
- const theme2 = filteredModel?.theming?.theme;
20
- if (!theme2) return;
21
- if (themes[theme2]) {
22
- setTheme(themes[theme2]);
23
- return;
24
- }
25
- import(
26
- /* @vite-ignore */
27
- theme2
28
- ).then((module) => {
29
- setTheme(module.default);
30
- }).catch((e) => {
31
- console.error(`Import of theme bundle ${theme2} failed! ${e}`);
32
- });
33
- }, [filteredModel?.theming?.theme]);
34
- const providers = useMemo(() => {
35
- if (!filteredModel?.providers) {
36
- return;
37
- }
38
- const providersComponents = [];
39
- for (const { bundle, key, config: config2 } of filteredModel.providers) {
40
- const component = model.preloadedBundles.get(
41
- bundle
42
- );
43
- providersComponents.push({
44
- key,
45
- component,
46
- config: config2
47
- });
48
- }
49
- return providersComponents;
50
- }, [filteredModel?.providers, model.preloadedBundles]);
51
- const providersContext = useMemo(
52
- () => ({
53
- providers
54
- }),
55
- [providers]
56
- );
57
- const appShellConfigContextValue = useMemo(() => config, [config]);
58
- const appShellModelContextValue = useMemo(
59
- () => filteredModel,
60
- [filteredModel]
61
- );
62
- if (isModelPending || !filteredModel || filteredModel.theming?.theme && !theme) {
63
- return null;
64
- }
65
- return /* @__PURE__ */ jsx(HvAppShellContext.Provider, { value: appShellConfigContextValue, children: /* @__PURE__ */ jsx(HvAppShellModelContext.Provider, { value: appShellModelContextValue, children: /* @__PURE__ */ jsx(
66
- HvProvider,
67
- {
68
- theme,
69
- colorMode: storedColorModeValue ?? filteredModel.theming?.colorMode,
70
- children: /* @__PURE__ */ jsx(HvAppShellCombinedProvidersContext.Provider, { value: providersContext, children })
71
- }
72
- ) }) });
5
+ import { useContext, useEffect, useMemo, useState } from "react";
6
+ import { I18nContext } from "react-i18next";
7
+ import { HvProvider, themes } from "@hitachivantara/uikit-react-core";
8
+ import { HvAppShellCombinedProvidersContext, HvAppShellContext, HvAppShellModelContext, HvAppShellRuntimeContext } from "@hitachivantara/app-shell-shared";
9
+ import { jsx } from "react/jsx-runtime";
10
+ //#region src/components/AppShellProvider/AppShellProvider.tsx
11
+ var AppShellProviderInner = ({ config: configProp, model, children }) => {
12
+ const { value: storedColorModeValue } = useLocalStorage("COLOR_MODE");
13
+ const { isPending: isModelPending, model: filteredModel } = useFilteredModel(model);
14
+ const [theme, setTheme] = useState();
15
+ useEffect(() => {
16
+ const newTheme = filteredModel?.theming?.theme;
17
+ if (!newTheme) return;
18
+ if (themes[newTheme]) {
19
+ setTheme(themes[newTheme]);
20
+ return;
21
+ }
22
+ import(
23
+ /* @vite-ignore */
24
+ newTheme
25
+ ).then((module) => {
26
+ setTheme(module.default);
27
+ }).catch((e) => {
28
+ console.error(`Import of theme bundle ${newTheme} failed! ${e}`);
29
+ });
30
+ }, [filteredModel?.theming?.theme]);
31
+ const providers = useMemo(() => {
32
+ if (!filteredModel?.providers) return;
33
+ const providersComponents = [];
34
+ for (const { bundle, key, config } of filteredModel.providers) {
35
+ const component = model.preloadedBundles.get(bundle);
36
+ providersComponents.push({
37
+ key,
38
+ component,
39
+ config
40
+ });
41
+ }
42
+ return providersComponents;
43
+ }, [filteredModel?.providers, model.preloadedBundles]);
44
+ const providersContext = useMemo(() => ({ providers }), [providers]);
45
+ const appShellConfigContextValue = useMemo(() => configProp, [configProp]);
46
+ const appShellModelContextValue = useMemo(() => filteredModel, [filteredModel]);
47
+ if (isModelPending || !filteredModel || filteredModel.theming?.theme && !theme) return null;
48
+ return /* @__PURE__ */ jsx(HvAppShellContext.Provider, {
49
+ value: appShellConfigContextValue,
50
+ children: /* @__PURE__ */ jsx(HvAppShellModelContext.Provider, {
51
+ value: appShellModelContextValue,
52
+ children: /* @__PURE__ */ jsx(HvProvider, {
53
+ theme,
54
+ colorMode: storedColorModeValue ?? filteredModel.theming?.colorMode,
55
+ children: /* @__PURE__ */ jsx(HvAppShellCombinedProvidersContext.Provider, {
56
+ value: providersContext,
57
+ children
58
+ })
59
+ })
60
+ })
61
+ });
73
62
  };
74
- function HvAppShellProvider({
75
- children,
76
- config: configProp
77
- }) {
78
- const { i18n } = useContext(I18nContext);
79
- const runtimeContext = useMemo(() => ({ i18n }), [i18n]);
80
- const { model, isPending: areBundlesLoading } = useModelFromConfig(configProp);
81
- const systemProviders = useMemo(() => {
82
- if (!model?.systemProviders) return void 0;
83
- return model.systemProviders.map(({ key, bundle, config }) => ({
84
- key,
85
- component: model.preloadedBundles.get(bundle),
86
- config
87
- }));
88
- }, [model?.systemProviders, model?.preloadedBundles]);
89
- if (!configProp || !model || areBundlesLoading) {
90
- return null;
91
- }
92
- return /* @__PURE__ */ jsx(HvAppShellRuntimeContext.Provider, { value: runtimeContext, children: /* @__PURE__ */ jsx(CombinedProviders, { providers: systemProviders, children: /* @__PURE__ */ jsx(AppShellProviderInner, { config: configProp, model, children }) }) });
63
+ function HvAppShellProvider({ children, config: configProp }) {
64
+ const { i18n } = useContext(I18nContext);
65
+ const runtimeContext = useMemo(() => ({ i18n }), [i18n]);
66
+ const { model, isPending: areBundlesLoading } = useModelFromConfig(configProp);
67
+ const systemProviders = useMemo(() => {
68
+ if (!model?.systemProviders) return void 0;
69
+ return model.systemProviders.map(({ key, bundle, config }) => ({
70
+ key,
71
+ component: model.preloadedBundles.get(bundle),
72
+ config
73
+ }));
74
+ }, [model?.systemProviders, model?.preloadedBundles]);
75
+ if (!configProp || !model || areBundlesLoading) return null;
76
+ return /* @__PURE__ */ jsx(HvAppShellRuntimeContext.Provider, {
77
+ value: runtimeContext,
78
+ children: /* @__PURE__ */ jsx(CombinedProviders, {
79
+ providers: systemProviders,
80
+ children: /* @__PURE__ */ jsx(AppShellProviderInner, {
81
+ config: configProp,
82
+ model,
83
+ children
84
+ })
85
+ })
86
+ });
93
87
  }
94
- export {
95
- HvAppShellProvider
96
- };
88
+ //#endregion
89
+ export { HvAppShellProvider };