@shellui/core 0.0.4
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/README.md +17 -0
- package/dist/ContentView-CZG-ro_B.js +146 -0
- package/dist/ContentView-CZG-ro_B.js.map +1 -0
- package/dist/CookiePreferencesView-MhO9FO-4.js +213 -0
- package/dist/CookiePreferencesView-MhO9FO-4.js.map +1 -0
- package/dist/DefaultLayout-Dbb3uJED.js +394 -0
- package/dist/DefaultLayout-Dbb3uJED.js.map +1 -0
- package/dist/FullscreenLayout-1SgPHWw-.js +30 -0
- package/dist/FullscreenLayout-1SgPHWw-.js.map +1 -0
- package/dist/HomeView-DYU-O_Il.js +21 -0
- package/dist/HomeView-DYU-O_Il.js.map +1 -0
- package/dist/NotFoundView-CeYjJNg0.js +52 -0
- package/dist/NotFoundView-CeYjJNg0.js.map +1 -0
- package/dist/OverlayShell-pzbqQW25.js +642 -0
- package/dist/OverlayShell-pzbqQW25.js.map +1 -0
- package/dist/SettingsView-Bndrta44.js +2207 -0
- package/dist/SettingsView-Bndrta44.js.map +1 -0
- package/dist/ViewRoute-ChSPabOy.js +32 -0
- package/dist/ViewRoute-ChSPabOy.js.map +1 -0
- package/dist/WindowsLayout-CXGNPKoY.js +633 -0
- package/dist/WindowsLayout-CXGNPKoY.js.map +1 -0
- package/dist/app.d.ts +3 -0
- package/dist/app.d.ts.map +1 -0
- package/dist/components/ContentView.d.ts +10 -0
- package/dist/components/ContentView.d.ts.map +1 -0
- package/dist/components/HomeView.d.ts +2 -0
- package/dist/components/HomeView.d.ts.map +1 -0
- package/dist/components/LoadingOverlay.d.ts +2 -0
- package/dist/components/LoadingOverlay.d.ts.map +1 -0
- package/dist/components/NotFoundView.d.ts +2 -0
- package/dist/components/NotFoundView.d.ts.map +1 -0
- package/dist/components/RouteErrorBoundary.d.ts +2 -0
- package/dist/components/RouteErrorBoundary.d.ts.map +1 -0
- package/dist/components/ViewRoute.d.ts +7 -0
- package/dist/components/ViewRoute.d.ts.map +1 -0
- package/dist/components/ui/alert-dialog.d.ts +32 -0
- package/dist/components/ui/alert-dialog.d.ts.map +1 -0
- package/dist/components/ui/breadcrumb.d.ts +20 -0
- package/dist/components/ui/breadcrumb.d.ts.map +1 -0
- package/dist/components/ui/button-group.d.ts +7 -0
- package/dist/components/ui/button-group.d.ts.map +1 -0
- package/dist/components/ui/button.d.ts +12 -0
- package/dist/components/ui/button.d.ts.map +1 -0
- package/dist/components/ui/dialog.d.ts +24 -0
- package/dist/components/ui/dialog.d.ts.map +1 -0
- package/dist/components/ui/drawer.d.ts +38 -0
- package/dist/components/ui/drawer.d.ts.map +1 -0
- package/dist/components/ui/select.d.ts +5 -0
- package/dist/components/ui/select.d.ts.map +1 -0
- package/dist/components/ui/sidebar.d.ts +46 -0
- package/dist/components/ui/sidebar.d.ts.map +1 -0
- package/dist/components/ui/sonner.d.ts +6 -0
- package/dist/components/ui/sonner.d.ts.map +1 -0
- package/dist/components/ui/switch.d.ts +8 -0
- package/dist/components/ui/switch.d.ts.map +1 -0
- package/dist/constants/urls.d.ts +6 -0
- package/dist/constants/urls.d.ts.map +1 -0
- package/dist/constants/urls.js +8 -0
- package/dist/constants/urls.js.map +1 -0
- package/dist/features/alertDialog/DialogContext.d.ts +12 -0
- package/dist/features/alertDialog/DialogContext.d.ts.map +1 -0
- package/dist/features/config/ConfigProvider.d.ts +15 -0
- package/dist/features/config/ConfigProvider.d.ts.map +1 -0
- package/dist/features/config/types.d.ts +177 -0
- package/dist/features/config/types.d.ts.map +1 -0
- package/dist/features/config/useConfig.d.ts +8 -0
- package/dist/features/config/useConfig.d.ts.map +1 -0
- package/dist/features/cookieConsent/CookieConsentModal.d.ts +6 -0
- package/dist/features/cookieConsent/CookieConsentModal.d.ts.map +1 -0
- package/dist/features/cookieConsent/CookiePreferencesView.d.ts +2 -0
- package/dist/features/cookieConsent/CookiePreferencesView.d.ts.map +1 -0
- package/dist/features/cookieConsent/cookieConsent.d.ts +22 -0
- package/dist/features/cookieConsent/cookieConsent.d.ts.map +1 -0
- package/dist/features/cookieConsent/useCookieConsent.d.ts +15 -0
- package/dist/features/cookieConsent/useCookieConsent.d.ts.map +1 -0
- package/dist/features/drawer/DrawerContext.d.ts +24 -0
- package/dist/features/drawer/DrawerContext.d.ts.map +1 -0
- package/dist/features/layouts/AppLayout.d.ts +12 -0
- package/dist/features/layouts/AppLayout.d.ts.map +1 -0
- package/dist/features/layouts/DefaultLayout.d.ts +10 -0
- package/dist/features/layouts/DefaultLayout.d.ts.map +1 -0
- package/dist/features/layouts/FullscreenLayout.d.ts +9 -0
- package/dist/features/layouts/FullscreenLayout.d.ts.map +1 -0
- package/dist/features/layouts/LayoutProviders.d.ts +9 -0
- package/dist/features/layouts/LayoutProviders.d.ts.map +1 -0
- package/dist/features/layouts/OverlayShell.d.ts +10 -0
- package/dist/features/layouts/OverlayShell.d.ts.map +1 -0
- package/dist/features/layouts/WindowsLayout.d.ts +24 -0
- package/dist/features/layouts/WindowsLayout.d.ts.map +1 -0
- package/dist/features/layouts/utils.d.ts +16 -0
- package/dist/features/layouts/utils.d.ts.map +1 -0
- package/dist/features/modal/ModalContext.d.ts +20 -0
- package/dist/features/modal/ModalContext.d.ts.map +1 -0
- package/dist/features/sentry/initSentry.d.ts +14 -0
- package/dist/features/sentry/initSentry.d.ts.map +1 -0
- package/dist/features/settings/SettingsContext.d.ts +10 -0
- package/dist/features/settings/SettingsContext.d.ts.map +1 -0
- package/dist/features/settings/SettingsIcons.d.ts +22 -0
- package/dist/features/settings/SettingsIcons.d.ts.map +1 -0
- package/dist/features/settings/SettingsProvider.d.ts +5 -0
- package/dist/features/settings/SettingsProvider.d.ts.map +1 -0
- package/dist/features/settings/SettingsRoutes.d.ts +7 -0
- package/dist/features/settings/SettingsRoutes.d.ts.map +1 -0
- package/dist/features/settings/SettingsView.d.ts +2 -0
- package/dist/features/settings/SettingsView.d.ts.map +1 -0
- package/dist/features/settings/components/Advanced.d.ts +2 -0
- package/dist/features/settings/components/Advanced.d.ts.map +1 -0
- package/dist/features/settings/components/Appearance.d.ts +2 -0
- package/dist/features/settings/components/Appearance.d.ts.map +1 -0
- package/dist/features/settings/components/DataPrivacy.d.ts +2 -0
- package/dist/features/settings/components/DataPrivacy.d.ts.map +1 -0
- package/dist/features/settings/components/Develop.d.ts +2 -0
- package/dist/features/settings/components/Develop.d.ts.map +1 -0
- package/dist/features/settings/components/LanguageAndRegion.d.ts +2 -0
- package/dist/features/settings/components/LanguageAndRegion.d.ts.map +1 -0
- package/dist/features/settings/components/ServiceWorker.d.ts +2 -0
- package/dist/features/settings/components/ServiceWorker.d.ts.map +1 -0
- package/dist/features/settings/components/UpdateApp.d.ts +2 -0
- package/dist/features/settings/components/UpdateApp.d.ts.map +1 -0
- package/dist/features/settings/components/develop/DialogTestButtons.d.ts +2 -0
- package/dist/features/settings/components/develop/DialogTestButtons.d.ts.map +1 -0
- package/dist/features/settings/components/develop/DrawerTestButtons.d.ts +2 -0
- package/dist/features/settings/components/develop/DrawerTestButtons.d.ts.map +1 -0
- package/dist/features/settings/components/develop/ModalTestButtons.d.ts +2 -0
- package/dist/features/settings/components/develop/ModalTestButtons.d.ts.map +1 -0
- package/dist/features/settings/components/develop/ToastTestButtons.d.ts +2 -0
- package/dist/features/settings/components/develop/ToastTestButtons.d.ts.map +1 -0
- package/dist/features/settings/hooks/useSettings.d.ts +2 -0
- package/dist/features/settings/hooks/useSettings.d.ts.map +1 -0
- package/dist/features/sonner/SonnerContext.d.ts +29 -0
- package/dist/features/sonner/SonnerContext.d.ts.map +1 -0
- package/dist/features/theme/ThemeProvider.d.ts +11 -0
- package/dist/features/theme/ThemeProvider.d.ts.map +1 -0
- package/dist/features/theme/themes.d.ts +114 -0
- package/dist/features/theme/themes.d.ts.map +1 -0
- package/dist/features/theme/useTheme.d.ts +10 -0
- package/dist/features/theme/useTheme.d.ts.map +1 -0
- package/dist/i18n/I18nProvider.d.ts +9 -0
- package/dist/i18n/I18nProvider.d.ts.map +1 -0
- package/dist/i18n/config.d.ts +23 -0
- package/dist/i18n/config.d.ts.map +1 -0
- package/dist/i18n/translations/en/common.json.d.ts +19 -0
- package/dist/i18n/translations/en/cookieConsent.json.d.ts +53 -0
- package/dist/i18n/translations/en/settings.json.d.ts +358 -0
- package/dist/i18n/translations/fr/common.json.d.ts +19 -0
- package/dist/i18n/translations/fr/cookieConsent.json.d.ts +53 -0
- package/dist/i18n/translations/fr/settings.json.d.ts +358 -0
- package/dist/index-lmRk5L6z.js +2160 -0
- package/dist/index-lmRk5L6z.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/utils.d.ts +3 -0
- package/dist/lib/utils.d.ts.map +1 -0
- package/dist/lib/z-index.d.ts +29 -0
- package/dist/lib/z-index.d.ts.map +1 -0
- package/dist/router/router.d.ts +3 -0
- package/dist/router/router.d.ts.map +1 -0
- package/dist/router/routes.d.ts +4 -0
- package/dist/router/routes.d.ts.map +1 -0
- package/dist/sidebar-ClIeZ2zb.js +303 -0
- package/dist/sidebar-ClIeZ2zb.js.map +1 -0
- package/dist/style.css +1 -0
- package/dist/switch-8SzUJz7Q.js +44 -0
- package/dist/switch-8SzUJz7Q.js.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +93 -0
- package/postcss.config.js +6 -0
- package/src/app.tsx +119 -0
- package/src/components/ContentView.tsx +258 -0
- package/src/components/HomeView.tsx +19 -0
- package/src/components/LoadingOverlay.tsx +12 -0
- package/src/components/NotFoundView.tsx +84 -0
- package/src/components/RouteErrorBoundary.tsx +95 -0
- package/src/components/ViewRoute.tsx +47 -0
- package/src/components/ui/alert-dialog.tsx +181 -0
- package/src/components/ui/breadcrumb.tsx +155 -0
- package/src/components/ui/button-group.tsx +52 -0
- package/src/components/ui/button.tsx +51 -0
- package/src/components/ui/dialog.tsx +160 -0
- package/src/components/ui/drawer.tsx +200 -0
- package/src/components/ui/select.tsx +24 -0
- package/src/components/ui/sidebar.tsx +406 -0
- package/src/components/ui/sonner.tsx +36 -0
- package/src/components/ui/switch.tsx +45 -0
- package/src/constants/urls.ts +4 -0
- package/src/features/alertDialog/DialogContext.tsx +468 -0
- package/src/features/config/ConfigProvider.ts +96 -0
- package/src/features/config/types.ts +195 -0
- package/src/features/config/useConfig.ts +15 -0
- package/src/features/cookieConsent/CookieConsentModal.tsx +122 -0
- package/src/features/cookieConsent/CookiePreferencesView.tsx +328 -0
- package/src/features/cookieConsent/cookieConsent.ts +84 -0
- package/src/features/cookieConsent/useCookieConsent.ts +39 -0
- package/src/features/drawer/DrawerContext.tsx +116 -0
- package/src/features/layouts/AppLayout.tsx +63 -0
- package/src/features/layouts/DefaultLayout.tsx +625 -0
- package/src/features/layouts/FullscreenLayout.tsx +55 -0
- package/src/features/layouts/LayoutProviders.tsx +20 -0
- package/src/features/layouts/OverlayShell.tsx +171 -0
- package/src/features/layouts/WindowsLayout.tsx +860 -0
- package/src/features/layouts/utils.ts +99 -0
- package/src/features/modal/ModalContext.tsx +112 -0
- package/src/features/sentry/initSentry.ts +72 -0
- package/src/features/settings/SettingsContext.tsx +19 -0
- package/src/features/settings/SettingsIcons.tsx +452 -0
- package/src/features/settings/SettingsProvider.tsx +341 -0
- package/src/features/settings/SettingsRoutes.tsx +66 -0
- package/src/features/settings/SettingsView.tsx +327 -0
- package/src/features/settings/components/Advanced.tsx +128 -0
- package/src/features/settings/components/Appearance.tsx +306 -0
- package/src/features/settings/components/DataPrivacy.tsx +142 -0
- package/src/features/settings/components/Develop.tsx +174 -0
- package/src/features/settings/components/LanguageAndRegion.tsx +329 -0
- package/src/features/settings/components/ServiceWorker.tsx +363 -0
- package/src/features/settings/components/UpdateApp.tsx +206 -0
- package/src/features/settings/components/develop/DialogTestButtons.tsx +137 -0
- package/src/features/settings/components/develop/DrawerTestButtons.tsx +67 -0
- package/src/features/settings/components/develop/ModalTestButtons.tsx +30 -0
- package/src/features/settings/components/develop/ToastTestButtons.tsx +179 -0
- package/src/features/settings/hooks/useSettings.tsx +10 -0
- package/src/features/sonner/SonnerContext.tsx +286 -0
- package/src/features/theme/ThemeProvider.tsx +16 -0
- package/src/features/theme/themes.ts +561 -0
- package/src/features/theme/useTheme.tsx +71 -0
- package/src/i18n/I18nProvider.tsx +32 -0
- package/src/i18n/config.ts +107 -0
- package/src/i18n/translations/en/common.json +16 -0
- package/src/i18n/translations/en/cookieConsent.json +50 -0
- package/src/i18n/translations/en/settings.json +355 -0
- package/src/i18n/translations/fr/common.json +16 -0
- package/src/i18n/translations/fr/cookieConsent.json +50 -0
- package/src/i18n/translations/fr/settings.json +355 -0
- package/src/index.css +412 -0
- package/src/index.html +100 -0
- package/src/index.ts +31 -0
- package/src/lib/utils.ts +6 -0
- package/src/lib/z-index.ts +29 -0
- package/src/main.tsx +26 -0
- package/src/router/router.tsx +8 -0
- package/src/router/routes.tsx +115 -0
- package/src/service-worker/register.ts +1199 -0
- package/src/service-worker/sw-dev.ts +87 -0
- package/src/service-worker/sw.ts +105 -0
- package/tailwind.config.js +60 -0
package/src/index.css
ADDED
|
@@ -0,0 +1,412 @@
|
|
|
1
|
+
@import 'tailwindcss';
|
|
2
|
+
|
|
3
|
+
@custom-variant dark (&:is(.dark *));
|
|
4
|
+
|
|
5
|
+
/*
|
|
6
|
+
* CSS variables defined outside @layer base so they can be overridden
|
|
7
|
+
* by JavaScript setProperty() calls (Tailwind v4 limitation)
|
|
8
|
+
* These are fallback defaults - theme system will override them dynamically
|
|
9
|
+
*
|
|
10
|
+
* IMPORTANT: In Tailwind v4, CSS variables must be defined on :root (not in @layer)
|
|
11
|
+
* for JavaScript overrides to work properly
|
|
12
|
+
*/
|
|
13
|
+
:root {
|
|
14
|
+
--background: 0 0% 100%;
|
|
15
|
+
--foreground: 222.2 84% 4.9%;
|
|
16
|
+
--card: 0 0% 100%;
|
|
17
|
+
--card-foreground: 222.2 84% 4.9%;
|
|
18
|
+
--popover: 0 0% 100%;
|
|
19
|
+
--popover-foreground: 222.2 84% 4.9%;
|
|
20
|
+
--primary: 142 71% 45%;
|
|
21
|
+
--primary-foreground: 0 0% 100%;
|
|
22
|
+
--secondary: 210 40% 96.1%;
|
|
23
|
+
--secondary-foreground: 222.2 47.4% 11.2%;
|
|
24
|
+
--muted: 210 40% 96.1%;
|
|
25
|
+
--muted-foreground: 215.4 16.3% 46.9%;
|
|
26
|
+
--accent: 210 40% 96.1%;
|
|
27
|
+
--accent-foreground: 222.2 47.4% 11.2%;
|
|
28
|
+
--destructive: 0 84.2% 60.2%;
|
|
29
|
+
--destructive-foreground: 210 40% 98%;
|
|
30
|
+
--border: 214.3 31.8% 91.4%;
|
|
31
|
+
--input: 214.3 31.8% 91.4%;
|
|
32
|
+
--ring: 222.2 84% 4.9%;
|
|
33
|
+
--radius: 0.5rem;
|
|
34
|
+
--sidebar-background: 0 0% 98%;
|
|
35
|
+
--sidebar-foreground: 240 5.3% 26.1%;
|
|
36
|
+
--sidebar-primary: 240 5.9% 10%;
|
|
37
|
+
--sidebar-primary-foreground: 0 0% 98%;
|
|
38
|
+
--sidebar-accent: 240 4.8% 95.9%;
|
|
39
|
+
--sidebar-accent-foreground: 240 5.9% 10%;
|
|
40
|
+
--sidebar-border: 220 13% 91%;
|
|
41
|
+
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.dark {
|
|
45
|
+
--background: 222.2 84% 4.9%;
|
|
46
|
+
--foreground: 210 40% 98%;
|
|
47
|
+
--card: 222.2 84% 4.9%;
|
|
48
|
+
--card-foreground: 210 40% 98%;
|
|
49
|
+
--popover: 222.2 84% 4.9%;
|
|
50
|
+
--popover-foreground: 210 40% 98%;
|
|
51
|
+
--primary: 142 71% 55%;
|
|
52
|
+
--primary-foreground: 0 0% 100%;
|
|
53
|
+
--secondary: 217.2 32.6% 17.5%;
|
|
54
|
+
--secondary-foreground: 210 40% 98%;
|
|
55
|
+
--muted: 217.2 32.6% 17.5%;
|
|
56
|
+
--muted-foreground: 215 20.2% 65.1%;
|
|
57
|
+
--accent: 217.2 32.6% 17.5%;
|
|
58
|
+
--accent-foreground: 210 40% 98%;
|
|
59
|
+
--destructive: 0 62.8% 30.6%;
|
|
60
|
+
--destructive-foreground: 210 40% 98%;
|
|
61
|
+
--border: 217.2 32.6% 17.5%;
|
|
62
|
+
--input: 217.2 32.6% 17.5%;
|
|
63
|
+
--ring: 212.7 26.8% 83.9%;
|
|
64
|
+
--sidebar-background: 240 5.9% 10%;
|
|
65
|
+
--sidebar-foreground: 240 4.8% 95.9%;
|
|
66
|
+
--sidebar-primary: 224.3 76.3% 94.9%;
|
|
67
|
+
--sidebar-primary-foreground: 240 5.9% 10%;
|
|
68
|
+
--sidebar-accent: 240 3.7% 15.9%;
|
|
69
|
+
--sidebar-accent-foreground: 240 4.8% 95.9%;
|
|
70
|
+
--sidebar-border: 240 3.7% 15.9%;
|
|
71
|
+
--sidebar-ring: 217.2 91.2% 59.8%;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@layer base {
|
|
75
|
+
* {
|
|
76
|
+
border-color: hsl(var(--border));
|
|
77
|
+
}
|
|
78
|
+
body {
|
|
79
|
+
background-color: hsl(var(--background));
|
|
80
|
+
color: hsl(var(--foreground));
|
|
81
|
+
font-family: var(
|
|
82
|
+
--body-font-family,
|
|
83
|
+
var(
|
|
84
|
+
--font-family,
|
|
85
|
+
system-ui,
|
|
86
|
+
-apple-system,
|
|
87
|
+
BlinkMacSystemFont,
|
|
88
|
+
'Segoe UI',
|
|
89
|
+
Roboto,
|
|
90
|
+
'Helvetica Neue',
|
|
91
|
+
Arial,
|
|
92
|
+
sans-serif
|
|
93
|
+
)
|
|
94
|
+
);
|
|
95
|
+
letter-spacing: var(--letter-spacing, normal);
|
|
96
|
+
text-shadow: var(--text-shadow, none);
|
|
97
|
+
line-height: var(--line-height, 1.5);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/* Apply heading font family if specified, otherwise use body font */
|
|
101
|
+
h1,
|
|
102
|
+
h2,
|
|
103
|
+
h3,
|
|
104
|
+
h4,
|
|
105
|
+
h5,
|
|
106
|
+
h6 {
|
|
107
|
+
font-family: var(
|
|
108
|
+
--heading-font-family,
|
|
109
|
+
var(
|
|
110
|
+
--body-font-family,
|
|
111
|
+
var(
|
|
112
|
+
--font-family,
|
|
113
|
+
system-ui,
|
|
114
|
+
-apple-system,
|
|
115
|
+
BlinkMacSystemFont,
|
|
116
|
+
'Segoe UI',
|
|
117
|
+
Roboto,
|
|
118
|
+
'Helvetica Neue',
|
|
119
|
+
Arial,
|
|
120
|
+
sans-serif
|
|
121
|
+
)
|
|
122
|
+
)
|
|
123
|
+
);
|
|
124
|
+
letter-spacing: var(--letter-spacing, normal);
|
|
125
|
+
text-shadow: var(--text-shadow, none);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/* Add playful styling to buttons for Comic Sans theme */
|
|
129
|
+
button,
|
|
130
|
+
[role='button'] {
|
|
131
|
+
letter-spacing: var(--letter-spacing, normal);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
button:hover,
|
|
135
|
+
[role='button']:hover {
|
|
136
|
+
filter: brightness(0.95);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* Playful input styling */
|
|
140
|
+
input,
|
|
141
|
+
textarea,
|
|
142
|
+
select {
|
|
143
|
+
letter-spacing: var(--letter-spacing, normal);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/* Select field - custom caret with proper spacing */
|
|
147
|
+
select.select-field {
|
|
148
|
+
appearance: none;
|
|
149
|
+
-webkit-appearance: none;
|
|
150
|
+
-moz-appearance: none;
|
|
151
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23999' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
152
|
+
background-repeat: no-repeat;
|
|
153
|
+
background-position: right 0.75rem center;
|
|
154
|
+
background-size: 1rem 1rem;
|
|
155
|
+
padding-right: 2.5rem;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/* Dark mode caret color */
|
|
159
|
+
.dark select.select-field {
|
|
160
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23aaa' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E");
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
:root {
|
|
164
|
+
--sidebar: hsl(0 0% 98%);
|
|
165
|
+
--sidebar-foreground: hsl(240 5.3% 26.1%);
|
|
166
|
+
--sidebar-primary: hsl(240 5.9% 10%);
|
|
167
|
+
--sidebar-primary-foreground: hsl(0 0% 98%);
|
|
168
|
+
--sidebar-accent: hsl(240 4.8% 95.9%);
|
|
169
|
+
--sidebar-accent-foreground: hsl(240 5.9% 10%);
|
|
170
|
+
--sidebar-border: hsl(220 13% 91%);
|
|
171
|
+
--sidebar-ring: hsl(217.2 91.2% 59.8%);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
.dark {
|
|
175
|
+
--sidebar: hsl(240 5.9% 10%);
|
|
176
|
+
--sidebar-foreground: hsl(240 4.8% 95.9%);
|
|
177
|
+
--sidebar-primary: hsl(224.3 76.3% 48%);
|
|
178
|
+
--sidebar-primary-foreground: hsl(0 0% 100%);
|
|
179
|
+
--sidebar-accent: hsl(240 3.7% 15.9%);
|
|
180
|
+
--sidebar-accent-foreground: hsl(240 4.8% 95.9%);
|
|
181
|
+
--sidebar-border: hsl(240 3.7% 15.9%);
|
|
182
|
+
--sidebar-ring: hsl(217.2 91.2% 59.8%);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/*
|
|
186
|
+
* @theme directive for Tailwind v4
|
|
187
|
+
* This registers CSS variables as theme tokens that Tailwind can use
|
|
188
|
+
* The tailwind.config.js file handles nested colors (primary.foreground)
|
|
189
|
+
* but @theme ensures the base CSS variables are available to Tailwind
|
|
190
|
+
*/
|
|
191
|
+
@theme {
|
|
192
|
+
/* Register CSS variables as theme tokens - these reference the dynamic variables */
|
|
193
|
+
/* Tailwind v4 will use these to generate utility classes */
|
|
194
|
+
--color-background: hsl(var(--background));
|
|
195
|
+
--color-foreground: hsl(var(--foreground));
|
|
196
|
+
--color-card: hsl(var(--card));
|
|
197
|
+
--color-card-foreground: hsl(var(--card-foreground));
|
|
198
|
+
--color-popover: hsl(var(--popover));
|
|
199
|
+
--color-popover-foreground: hsl(var(--popover-foreground));
|
|
200
|
+
--color-primary: hsl(var(--primary));
|
|
201
|
+
--color-primary-foreground: hsl(var(--primary-foreground));
|
|
202
|
+
--color-secondary: hsl(var(--secondary));
|
|
203
|
+
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
|
204
|
+
--color-muted: hsl(var(--muted));
|
|
205
|
+
--color-muted-foreground: hsl(var(--muted-foreground));
|
|
206
|
+
--color-accent: hsl(var(--accent));
|
|
207
|
+
--color-accent-foreground: hsl(var(--accent-foreground));
|
|
208
|
+
--color-destructive: hsl(var(--destructive));
|
|
209
|
+
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
|
210
|
+
--color-border: hsl(var(--border));
|
|
211
|
+
--color-input: hsl(var(--input));
|
|
212
|
+
--color-ring: hsl(var(--ring));
|
|
213
|
+
--color-sidebar-background: hsl(var(--sidebar-background));
|
|
214
|
+
--color-sidebar-foreground: hsl(var(--sidebar-foreground));
|
|
215
|
+
--color-sidebar-primary: hsl(var(--sidebar-primary));
|
|
216
|
+
--color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
|
|
217
|
+
--color-sidebar-accent: hsl(var(--sidebar-accent));
|
|
218
|
+
--color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
|
|
219
|
+
--color-sidebar-border: hsl(var(--sidebar-border));
|
|
220
|
+
--color-sidebar-ring: hsl(var(--sidebar-ring));
|
|
221
|
+
|
|
222
|
+
/* Border radius tokens */
|
|
223
|
+
--radius-lg: var(--radius);
|
|
224
|
+
--radius-md: calc(var(--radius) - 2px);
|
|
225
|
+
--radius-sm: calc(var(--radius) - 4px);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
@layer base {
|
|
229
|
+
* {
|
|
230
|
+
outline-color: hsl(var(--ring) / 0.5);
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/* Ensure Sonner toasts use theme variables - override Sonner defaults */
|
|
234
|
+
[data-sonner-toast] {
|
|
235
|
+
background-color: hsl(var(--background)) !important;
|
|
236
|
+
color: hsl(var(--foreground)) !important;
|
|
237
|
+
border-color: hsl(var(--border)) !important;
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
[data-sonner-toast] [data-description] {
|
|
241
|
+
color: hsl(var(--muted-foreground)) !important;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
[data-sonner-toast] [data-button],
|
|
245
|
+
[data-sonner-toast] button[data-button] {
|
|
246
|
+
background-color: hsl(var(--primary)) !important;
|
|
247
|
+
color: hsl(var(--primary-foreground)) !important;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
[data-sonner-toast] [data-button]:hover,
|
|
251
|
+
[data-sonner-toast] button[data-button]:hover {
|
|
252
|
+
background-color: hsl(var(--primary) / 0.9) !important;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
[data-sonner-toast] [data-cancel],
|
|
256
|
+
[data-sonner-toast] button[data-cancel] {
|
|
257
|
+
background-color: hsl(var(--muted)) !important;
|
|
258
|
+
color: hsl(var(--muted-foreground)) !important;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
[data-sonner-toast] [data-cancel]:hover,
|
|
262
|
+
[data-sonner-toast] button[data-cancel]:hover {
|
|
263
|
+
background-color: hsl(var(--muted) / 0.8) !important;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/* Success toast icon uses text color (no separate icon color) */
|
|
267
|
+
[data-sonner-toast][data-type='success'] [data-icon],
|
|
268
|
+
[data-sonner-toast][data-type='success'] [data-icon] svg {
|
|
269
|
+
color: hsl(var(--foreground)) !important;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/* Color error toast icon */
|
|
273
|
+
[data-sonner-toast][data-type='error'] [data-icon],
|
|
274
|
+
[data-sonner-toast][data-type='error'] svg {
|
|
275
|
+
color: hsl(var(--destructive)) !important;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
/* Invert sidebar icons in dark mode - target all icons in sidebar context */
|
|
279
|
+
/* Exclude app icon and logo which have their own rules */
|
|
280
|
+
.dark [data-sidebar='sidebar'] img[src*='/icons/']:not(.sidebar-app-icon):not(.sidebar-logo),
|
|
281
|
+
.dark [data-sidebar='sidebar'] img[src*='icons/']:not(.sidebar-app-icon):not(.sidebar-logo),
|
|
282
|
+
.dark [data-sidebar='sidebar'] img[src$='.svg']:not(.sidebar-app-icon):not(.sidebar-logo) {
|
|
283
|
+
filter: invert(1) brightness(1.2);
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
/* Sidebar trigger button icon should adapt to theme */
|
|
287
|
+
.dark button[aria-label*='sidebar'] img {
|
|
288
|
+
filter: invert(1);
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
/* Sidebar app icon - match text color for visibility */
|
|
292
|
+
/* In light mode: make icon dark to match dark text */
|
|
293
|
+
[data-sidebar='sidebar'] img.sidebar-app-icon {
|
|
294
|
+
filter: brightness(0) saturate(100%);
|
|
295
|
+
opacity: 0.9;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/* In dark mode: invert to make icon light to match light text */
|
|
299
|
+
.dark [data-sidebar='sidebar'] img.sidebar-app-icon {
|
|
300
|
+
filter: brightness(0) invert(1) saturate(100%);
|
|
301
|
+
opacity: 0.9;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
/* Sidebar logo - dark in light mode, white in dark mode */
|
|
305
|
+
/* In light mode: make logo dark */
|
|
306
|
+
[data-sidebar='sidebar'] img.sidebar-logo {
|
|
307
|
+
filter: brightness(0) saturate(100%);
|
|
308
|
+
opacity: 0.9;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/* In dark mode: invert to make logo white */
|
|
312
|
+
.dark [data-sidebar='sidebar'] img.sidebar-logo {
|
|
313
|
+
filter: brightness(0) invert(1) saturate(100%);
|
|
314
|
+
opacity: 0.9;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/* Dialog / modal overlay and content animations */
|
|
319
|
+
[data-dialog-content] {
|
|
320
|
+
left: 50%;
|
|
321
|
+
top: 50%;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
@keyframes dialog-overlay-fade-in {
|
|
325
|
+
from {
|
|
326
|
+
opacity: 0;
|
|
327
|
+
}
|
|
328
|
+
to {
|
|
329
|
+
opacity: 1;
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
@keyframes dialog-overlay-fade-out {
|
|
333
|
+
from {
|
|
334
|
+
opacity: 1;
|
|
335
|
+
}
|
|
336
|
+
to {
|
|
337
|
+
opacity: 0;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
@keyframes dialog-content-in {
|
|
341
|
+
from {
|
|
342
|
+
opacity: 0;
|
|
343
|
+
transform: scale(0.96);
|
|
344
|
+
}
|
|
345
|
+
to {
|
|
346
|
+
opacity: 1;
|
|
347
|
+
transform: scale(1);
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
@keyframes dialog-content-out {
|
|
351
|
+
from {
|
|
352
|
+
opacity: 1;
|
|
353
|
+
transform: scale(1);
|
|
354
|
+
}
|
|
355
|
+
to {
|
|
356
|
+
opacity: 0;
|
|
357
|
+
transform: scale(0.96);
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
[data-dialog-overlay][data-state='open'] {
|
|
362
|
+
animation: dialog-overlay-fade-in 0.1s ease-out;
|
|
363
|
+
}
|
|
364
|
+
[data-dialog-overlay][data-state='closed'] {
|
|
365
|
+
animation: dialog-overlay-fade-out 0.1s ease-in;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
[data-dialog-content][data-state='open'] {
|
|
369
|
+
animation: dialog-content-in 0.1s ease-out 0.05s both;
|
|
370
|
+
}
|
|
371
|
+
[data-dialog-content][data-state='closed'] {
|
|
372
|
+
animation: dialog-content-out 0.1s ease-in both;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
/* Cookie consent dialog (bottom-left) animations */
|
|
376
|
+
@keyframes cookie-dialog-content-in {
|
|
377
|
+
from {
|
|
378
|
+
opacity: 0;
|
|
379
|
+
transform: translateY(20px);
|
|
380
|
+
}
|
|
381
|
+
to {
|
|
382
|
+
opacity: 1;
|
|
383
|
+
transform: translateY(0);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
@keyframes cookie-dialog-content-out {
|
|
387
|
+
from {
|
|
388
|
+
opacity: 1;
|
|
389
|
+
transform: translateY(0);
|
|
390
|
+
}
|
|
391
|
+
to {
|
|
392
|
+
opacity: 0;
|
|
393
|
+
transform: translateY(20px);
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
[data-cookie-consent][data-state='open'] {
|
|
398
|
+
animation: cookie-dialog-content-in 0.15s ease-out 0.05s both;
|
|
399
|
+
}
|
|
400
|
+
[data-cookie-consent][data-state='closed'] {
|
|
401
|
+
animation: cookie-dialog-content-out 0.15s ease-in both;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/* Loading overlay top bar animation – grows from left to right */
|
|
405
|
+
@keyframes loading-bar-slide {
|
|
406
|
+
from {
|
|
407
|
+
width: 0%;
|
|
408
|
+
}
|
|
409
|
+
to {
|
|
410
|
+
width: 100%;
|
|
411
|
+
}
|
|
412
|
+
}
|
package/src/index.html
ADDED
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta
|
|
6
|
+
name="viewport"
|
|
7
|
+
content="width=device-width, initial-scale=1.0"
|
|
8
|
+
/>
|
|
9
|
+
<title></title>
|
|
10
|
+
<link
|
|
11
|
+
rel="icon"
|
|
12
|
+
href="/favicon.svg"
|
|
13
|
+
type="image/svg+xml"
|
|
14
|
+
/>
|
|
15
|
+
<script>
|
|
16
|
+
// Initialize theme immediately to prevent FOUC
|
|
17
|
+
// This sets both the dark class AND CSS variables before React loads
|
|
18
|
+
(function () {
|
|
19
|
+
try {
|
|
20
|
+
const stored = localStorage.getItem('shellui:settings');
|
|
21
|
+
let theme = 'system';
|
|
22
|
+
let themeName = 'default';
|
|
23
|
+
if (stored) {
|
|
24
|
+
const parsed = JSON.parse(stored);
|
|
25
|
+
theme = parsed.appearance?.theme || 'system';
|
|
26
|
+
themeName = parsed.appearance?.themeName || 'default';
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// Determine if dark mode
|
|
30
|
+
let isDark = false;
|
|
31
|
+
if (theme === 'system') {
|
|
32
|
+
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
|
|
33
|
+
isDark = mediaQuery.matches;
|
|
34
|
+
} else {
|
|
35
|
+
isDark = theme === 'dark';
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Apply dark class
|
|
39
|
+
if (isDark) {
|
|
40
|
+
document.documentElement.classList.add('dark');
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Set default theme CSS variables immediately
|
|
44
|
+
// This ensures bg-primary works from the start
|
|
45
|
+
// These HSL values match the default theme in themes.ts
|
|
46
|
+
const root = document.documentElement;
|
|
47
|
+
|
|
48
|
+
if (isDark) {
|
|
49
|
+
// Dark mode default theme colors
|
|
50
|
+
root.style.setProperty('--primary', '142 71% 55%');
|
|
51
|
+
root.style.setProperty('--primary-foreground', '0 0% 100%');
|
|
52
|
+
root.style.setProperty('--background', '222.2 84% 4.9%');
|
|
53
|
+
root.style.setProperty('--foreground', '210 40% 98%');
|
|
54
|
+
} else {
|
|
55
|
+
// Light mode default theme colors
|
|
56
|
+
root.style.setProperty('--primary', '142 71% 45%');
|
|
57
|
+
root.style.setProperty('--primary-foreground', '0 0% 100%');
|
|
58
|
+
root.style.setProperty('--background', '0 0% 100%');
|
|
59
|
+
root.style.setProperty('--foreground', '222.2 84% 4.9%');
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
// Set other essential variables with defaults
|
|
63
|
+
root.style.setProperty('--card', isDark ? '222.2 84% 4.9%' : '0 0% 100%');
|
|
64
|
+
root.style.setProperty('--card-foreground', isDark ? '210 40% 98%' : '222.2 84% 4.9%');
|
|
65
|
+
root.style.setProperty('--secondary', isDark ? '217.2 32.6% 17.5%' : '210 40% 96.1%');
|
|
66
|
+
root.style.setProperty('--muted', isDark ? '217.2 32.6% 17.5%' : '210 40% 96.1%');
|
|
67
|
+
root.style.setProperty('--border', isDark ? '217.2 32.6% 17.5%' : '214.3 31.8% 91.4%');
|
|
68
|
+
root.style.setProperty('--input', isDark ? '217.2 32.6% 17.5%' : '214.3 31.8% 91.4%');
|
|
69
|
+
root.style.setProperty('--ring', isDark ? '212.7 26.8% 83.9%' : '222.2 84% 4.9%');
|
|
70
|
+
root.style.setProperty('--radius', '0.5rem');
|
|
71
|
+
} catch (e) {
|
|
72
|
+
// Ignore errors
|
|
73
|
+
console.error('[Theme Init] Error:', e);
|
|
74
|
+
}
|
|
75
|
+
})();
|
|
76
|
+
</script>
|
|
77
|
+
<style>
|
|
78
|
+
* {
|
|
79
|
+
box-sizing: border-box;
|
|
80
|
+
}
|
|
81
|
+
html,
|
|
82
|
+
body {
|
|
83
|
+
margin: 0;
|
|
84
|
+
padding: 0;
|
|
85
|
+
height: 100%;
|
|
86
|
+
overflow: hidden;
|
|
87
|
+
}
|
|
88
|
+
#root {
|
|
89
|
+
height: 100%;
|
|
90
|
+
}
|
|
91
|
+
</style>
|
|
92
|
+
</head>
|
|
93
|
+
<body>
|
|
94
|
+
<div id="root"></div>
|
|
95
|
+
<script
|
|
96
|
+
type="module"
|
|
97
|
+
src="/main.tsx"
|
|
98
|
+
></script>
|
|
99
|
+
</body>
|
|
100
|
+
</html>
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ShellUI Core - Main entry point
|
|
3
|
+
* Exports the App component, types, and utilities for use in config files and other packages.
|
|
4
|
+
*
|
|
5
|
+
* CSS is imported as a side effect and extracted to dist/style.css during the library build.
|
|
6
|
+
* Consumers must import '@shellui/core/style.css' (or include it in their build) for styles to apply.
|
|
7
|
+
*/
|
|
8
|
+
import './index.css';
|
|
9
|
+
|
|
10
|
+
export { default as App } from './app.js';
|
|
11
|
+
export type {
|
|
12
|
+
ShellUIConfig,
|
|
13
|
+
NavigationItem,
|
|
14
|
+
NavigationGroup,
|
|
15
|
+
LocalizedString,
|
|
16
|
+
ThemeDefinition,
|
|
17
|
+
ThemeColors,
|
|
18
|
+
DrawerPosition,
|
|
19
|
+
LayoutType,
|
|
20
|
+
CookieConsentCategory,
|
|
21
|
+
CookieDefinition,
|
|
22
|
+
CookieConsentConfig,
|
|
23
|
+
} from './features/config/types.js';
|
|
24
|
+
export { useConfig } from './features/config/useConfig.js';
|
|
25
|
+
export { default as urls } from './constants/urls.js';
|
|
26
|
+
export {
|
|
27
|
+
getCookieConsentAccepted,
|
|
28
|
+
getCookieConsentNeedsRenewal,
|
|
29
|
+
getCookieConsentNewHosts,
|
|
30
|
+
} from './features/cookieConsent/cookieConsent.js';
|
|
31
|
+
export { useCookieConsent } from './features/cookieConsent/useCookieConsent.js';
|
package/src/lib/utils.ts
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Central z-index scale for overlay layers.
|
|
3
|
+
* Order (bottom to top): modal/drawer → toast → alert-dialog.
|
|
4
|
+
* Use these constants everywhere so stacking stays consistent.
|
|
5
|
+
*/
|
|
6
|
+
export const Z_INDEX = {
|
|
7
|
+
/** Sidebar trigger (above main content, below modals) */
|
|
8
|
+
SIDEBAR_TRIGGER: 9999,
|
|
9
|
+
/** Modal overlay and content (settings panel, etc.) */
|
|
10
|
+
MODAL_OVERLAY: 10000,
|
|
11
|
+
MODAL_CONTENT: 10001,
|
|
12
|
+
/** Drawer overlay and content (slide-out panels; same level as modal) */
|
|
13
|
+
DRAWER_OVERLAY: 10000,
|
|
14
|
+
DRAWER_CONTENT: 10001,
|
|
15
|
+
/** Toasts (above modals so they stay clickable when modal is open) */
|
|
16
|
+
TOAST: 10100,
|
|
17
|
+
/** Alert dialog overlay and content (confirmations; above toasts) */
|
|
18
|
+
ALERT_DIALOG_OVERLAY: 10200,
|
|
19
|
+
ALERT_DIALOG_CONTENT: 10201,
|
|
20
|
+
/** Cookie consent (above everything to ensure visibility) */
|
|
21
|
+
COOKIE_CONSENT_OVERLAY: 10300,
|
|
22
|
+
COOKIE_CONSENT_CONTENT: 10301,
|
|
23
|
+
/** Windows layout: taskbar (below windows), windows use dynamic z-index above this */
|
|
24
|
+
WINDOWS_TASKBAR: 9000,
|
|
25
|
+
/** Base z-index for windows; each window gets base + order */
|
|
26
|
+
WINDOWS_WINDOW_BASE: 9001,
|
|
27
|
+
} as const;
|
|
28
|
+
|
|
29
|
+
export type ZIndexLayer = keyof typeof Z_INDEX;
|
package/src/main.tsx
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Application entry point - renders the App component to the DOM.
|
|
3
|
+
* This file is used by the CLI (via index.html) to bootstrap the full application.
|
|
4
|
+
* It is NOT part of the library build.
|
|
5
|
+
*/
|
|
6
|
+
import { StrictMode } from 'react';
|
|
7
|
+
import ReactDOM from 'react-dom/client';
|
|
8
|
+
import App from './app';
|
|
9
|
+
|
|
10
|
+
// Store root instance to handle HMR properly
|
|
11
|
+
// Use window to persist across HMR reloads
|
|
12
|
+
const container = document.getElementById('root')!; // eslint-disable-line @typescript-eslint/no-non-null-assertion
|
|
13
|
+
const windowRecord = window as unknown as Record<string, unknown>;
|
|
14
|
+
const root =
|
|
15
|
+
(windowRecord.__shellui_root__ as ReturnType<typeof ReactDOM.createRoot>) ||
|
|
16
|
+
ReactDOM.createRoot(container);
|
|
17
|
+
|
|
18
|
+
if (!windowRecord.__shellui_root__) {
|
|
19
|
+
windowRecord.__shellui_root__ = root;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
root.render(
|
|
23
|
+
<StrictMode>
|
|
24
|
+
<App />
|
|
25
|
+
</StrictMode>,
|
|
26
|
+
);
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { createBrowserRouter } from 'react-router';
|
|
2
|
+
import type { ShellUIConfig } from '../features/config/types';
|
|
3
|
+
import { createRoutes } from './routes';
|
|
4
|
+
|
|
5
|
+
export const createAppRouter = (config: ShellUIConfig) => {
|
|
6
|
+
const routes = createRoutes(config);
|
|
7
|
+
return createBrowserRouter(routes);
|
|
8
|
+
};
|