@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.
Files changed (247) hide show
  1. package/README.md +17 -0
  2. package/dist/ContentView-CZG-ro_B.js +146 -0
  3. package/dist/ContentView-CZG-ro_B.js.map +1 -0
  4. package/dist/CookiePreferencesView-MhO9FO-4.js +213 -0
  5. package/dist/CookiePreferencesView-MhO9FO-4.js.map +1 -0
  6. package/dist/DefaultLayout-Dbb3uJED.js +394 -0
  7. package/dist/DefaultLayout-Dbb3uJED.js.map +1 -0
  8. package/dist/FullscreenLayout-1SgPHWw-.js +30 -0
  9. package/dist/FullscreenLayout-1SgPHWw-.js.map +1 -0
  10. package/dist/HomeView-DYU-O_Il.js +21 -0
  11. package/dist/HomeView-DYU-O_Il.js.map +1 -0
  12. package/dist/NotFoundView-CeYjJNg0.js +52 -0
  13. package/dist/NotFoundView-CeYjJNg0.js.map +1 -0
  14. package/dist/OverlayShell-pzbqQW25.js +642 -0
  15. package/dist/OverlayShell-pzbqQW25.js.map +1 -0
  16. package/dist/SettingsView-Bndrta44.js +2207 -0
  17. package/dist/SettingsView-Bndrta44.js.map +1 -0
  18. package/dist/ViewRoute-ChSPabOy.js +32 -0
  19. package/dist/ViewRoute-ChSPabOy.js.map +1 -0
  20. package/dist/WindowsLayout-CXGNPKoY.js +633 -0
  21. package/dist/WindowsLayout-CXGNPKoY.js.map +1 -0
  22. package/dist/app.d.ts +3 -0
  23. package/dist/app.d.ts.map +1 -0
  24. package/dist/components/ContentView.d.ts +10 -0
  25. package/dist/components/ContentView.d.ts.map +1 -0
  26. package/dist/components/HomeView.d.ts +2 -0
  27. package/dist/components/HomeView.d.ts.map +1 -0
  28. package/dist/components/LoadingOverlay.d.ts +2 -0
  29. package/dist/components/LoadingOverlay.d.ts.map +1 -0
  30. package/dist/components/NotFoundView.d.ts +2 -0
  31. package/dist/components/NotFoundView.d.ts.map +1 -0
  32. package/dist/components/RouteErrorBoundary.d.ts +2 -0
  33. package/dist/components/RouteErrorBoundary.d.ts.map +1 -0
  34. package/dist/components/ViewRoute.d.ts +7 -0
  35. package/dist/components/ViewRoute.d.ts.map +1 -0
  36. package/dist/components/ui/alert-dialog.d.ts +32 -0
  37. package/dist/components/ui/alert-dialog.d.ts.map +1 -0
  38. package/dist/components/ui/breadcrumb.d.ts +20 -0
  39. package/dist/components/ui/breadcrumb.d.ts.map +1 -0
  40. package/dist/components/ui/button-group.d.ts +7 -0
  41. package/dist/components/ui/button-group.d.ts.map +1 -0
  42. package/dist/components/ui/button.d.ts +12 -0
  43. package/dist/components/ui/button.d.ts.map +1 -0
  44. package/dist/components/ui/dialog.d.ts +24 -0
  45. package/dist/components/ui/dialog.d.ts.map +1 -0
  46. package/dist/components/ui/drawer.d.ts +38 -0
  47. package/dist/components/ui/drawer.d.ts.map +1 -0
  48. package/dist/components/ui/select.d.ts +5 -0
  49. package/dist/components/ui/select.d.ts.map +1 -0
  50. package/dist/components/ui/sidebar.d.ts +46 -0
  51. package/dist/components/ui/sidebar.d.ts.map +1 -0
  52. package/dist/components/ui/sonner.d.ts +6 -0
  53. package/dist/components/ui/sonner.d.ts.map +1 -0
  54. package/dist/components/ui/switch.d.ts +8 -0
  55. package/dist/components/ui/switch.d.ts.map +1 -0
  56. package/dist/constants/urls.d.ts +6 -0
  57. package/dist/constants/urls.d.ts.map +1 -0
  58. package/dist/constants/urls.js +8 -0
  59. package/dist/constants/urls.js.map +1 -0
  60. package/dist/features/alertDialog/DialogContext.d.ts +12 -0
  61. package/dist/features/alertDialog/DialogContext.d.ts.map +1 -0
  62. package/dist/features/config/ConfigProvider.d.ts +15 -0
  63. package/dist/features/config/ConfigProvider.d.ts.map +1 -0
  64. package/dist/features/config/types.d.ts +177 -0
  65. package/dist/features/config/types.d.ts.map +1 -0
  66. package/dist/features/config/useConfig.d.ts +8 -0
  67. package/dist/features/config/useConfig.d.ts.map +1 -0
  68. package/dist/features/cookieConsent/CookieConsentModal.d.ts +6 -0
  69. package/dist/features/cookieConsent/CookieConsentModal.d.ts.map +1 -0
  70. package/dist/features/cookieConsent/CookiePreferencesView.d.ts +2 -0
  71. package/dist/features/cookieConsent/CookiePreferencesView.d.ts.map +1 -0
  72. package/dist/features/cookieConsent/cookieConsent.d.ts +22 -0
  73. package/dist/features/cookieConsent/cookieConsent.d.ts.map +1 -0
  74. package/dist/features/cookieConsent/useCookieConsent.d.ts +15 -0
  75. package/dist/features/cookieConsent/useCookieConsent.d.ts.map +1 -0
  76. package/dist/features/drawer/DrawerContext.d.ts +24 -0
  77. package/dist/features/drawer/DrawerContext.d.ts.map +1 -0
  78. package/dist/features/layouts/AppLayout.d.ts +12 -0
  79. package/dist/features/layouts/AppLayout.d.ts.map +1 -0
  80. package/dist/features/layouts/DefaultLayout.d.ts +10 -0
  81. package/dist/features/layouts/DefaultLayout.d.ts.map +1 -0
  82. package/dist/features/layouts/FullscreenLayout.d.ts +9 -0
  83. package/dist/features/layouts/FullscreenLayout.d.ts.map +1 -0
  84. package/dist/features/layouts/LayoutProviders.d.ts +9 -0
  85. package/dist/features/layouts/LayoutProviders.d.ts.map +1 -0
  86. package/dist/features/layouts/OverlayShell.d.ts +10 -0
  87. package/dist/features/layouts/OverlayShell.d.ts.map +1 -0
  88. package/dist/features/layouts/WindowsLayout.d.ts +24 -0
  89. package/dist/features/layouts/WindowsLayout.d.ts.map +1 -0
  90. package/dist/features/layouts/utils.d.ts +16 -0
  91. package/dist/features/layouts/utils.d.ts.map +1 -0
  92. package/dist/features/modal/ModalContext.d.ts +20 -0
  93. package/dist/features/modal/ModalContext.d.ts.map +1 -0
  94. package/dist/features/sentry/initSentry.d.ts +14 -0
  95. package/dist/features/sentry/initSentry.d.ts.map +1 -0
  96. package/dist/features/settings/SettingsContext.d.ts +10 -0
  97. package/dist/features/settings/SettingsContext.d.ts.map +1 -0
  98. package/dist/features/settings/SettingsIcons.d.ts +22 -0
  99. package/dist/features/settings/SettingsIcons.d.ts.map +1 -0
  100. package/dist/features/settings/SettingsProvider.d.ts +5 -0
  101. package/dist/features/settings/SettingsProvider.d.ts.map +1 -0
  102. package/dist/features/settings/SettingsRoutes.d.ts +7 -0
  103. package/dist/features/settings/SettingsRoutes.d.ts.map +1 -0
  104. package/dist/features/settings/SettingsView.d.ts +2 -0
  105. package/dist/features/settings/SettingsView.d.ts.map +1 -0
  106. package/dist/features/settings/components/Advanced.d.ts +2 -0
  107. package/dist/features/settings/components/Advanced.d.ts.map +1 -0
  108. package/dist/features/settings/components/Appearance.d.ts +2 -0
  109. package/dist/features/settings/components/Appearance.d.ts.map +1 -0
  110. package/dist/features/settings/components/DataPrivacy.d.ts +2 -0
  111. package/dist/features/settings/components/DataPrivacy.d.ts.map +1 -0
  112. package/dist/features/settings/components/Develop.d.ts +2 -0
  113. package/dist/features/settings/components/Develop.d.ts.map +1 -0
  114. package/dist/features/settings/components/LanguageAndRegion.d.ts +2 -0
  115. package/dist/features/settings/components/LanguageAndRegion.d.ts.map +1 -0
  116. package/dist/features/settings/components/ServiceWorker.d.ts +2 -0
  117. package/dist/features/settings/components/ServiceWorker.d.ts.map +1 -0
  118. package/dist/features/settings/components/UpdateApp.d.ts +2 -0
  119. package/dist/features/settings/components/UpdateApp.d.ts.map +1 -0
  120. package/dist/features/settings/components/develop/DialogTestButtons.d.ts +2 -0
  121. package/dist/features/settings/components/develop/DialogTestButtons.d.ts.map +1 -0
  122. package/dist/features/settings/components/develop/DrawerTestButtons.d.ts +2 -0
  123. package/dist/features/settings/components/develop/DrawerTestButtons.d.ts.map +1 -0
  124. package/dist/features/settings/components/develop/ModalTestButtons.d.ts +2 -0
  125. package/dist/features/settings/components/develop/ModalTestButtons.d.ts.map +1 -0
  126. package/dist/features/settings/components/develop/ToastTestButtons.d.ts +2 -0
  127. package/dist/features/settings/components/develop/ToastTestButtons.d.ts.map +1 -0
  128. package/dist/features/settings/hooks/useSettings.d.ts +2 -0
  129. package/dist/features/settings/hooks/useSettings.d.ts.map +1 -0
  130. package/dist/features/sonner/SonnerContext.d.ts +29 -0
  131. package/dist/features/sonner/SonnerContext.d.ts.map +1 -0
  132. package/dist/features/theme/ThemeProvider.d.ts +11 -0
  133. package/dist/features/theme/ThemeProvider.d.ts.map +1 -0
  134. package/dist/features/theme/themes.d.ts +114 -0
  135. package/dist/features/theme/themes.d.ts.map +1 -0
  136. package/dist/features/theme/useTheme.d.ts +10 -0
  137. package/dist/features/theme/useTheme.d.ts.map +1 -0
  138. package/dist/i18n/I18nProvider.d.ts +9 -0
  139. package/dist/i18n/I18nProvider.d.ts.map +1 -0
  140. package/dist/i18n/config.d.ts +23 -0
  141. package/dist/i18n/config.d.ts.map +1 -0
  142. package/dist/i18n/translations/en/common.json.d.ts +19 -0
  143. package/dist/i18n/translations/en/cookieConsent.json.d.ts +53 -0
  144. package/dist/i18n/translations/en/settings.json.d.ts +358 -0
  145. package/dist/i18n/translations/fr/common.json.d.ts +19 -0
  146. package/dist/i18n/translations/fr/cookieConsent.json.d.ts +53 -0
  147. package/dist/i18n/translations/fr/settings.json.d.ts +358 -0
  148. package/dist/index-lmRk5L6z.js +2160 -0
  149. package/dist/index-lmRk5L6z.js.map +1 -0
  150. package/dist/index.d.ts +7 -0
  151. package/dist/index.d.ts.map +1 -0
  152. package/dist/index.js +12 -0
  153. package/dist/index.js.map +1 -0
  154. package/dist/lib/utils.d.ts +3 -0
  155. package/dist/lib/utils.d.ts.map +1 -0
  156. package/dist/lib/z-index.d.ts +29 -0
  157. package/dist/lib/z-index.d.ts.map +1 -0
  158. package/dist/router/router.d.ts +3 -0
  159. package/dist/router/router.d.ts.map +1 -0
  160. package/dist/router/routes.d.ts +4 -0
  161. package/dist/router/routes.d.ts.map +1 -0
  162. package/dist/sidebar-ClIeZ2zb.js +303 -0
  163. package/dist/sidebar-ClIeZ2zb.js.map +1 -0
  164. package/dist/style.css +1 -0
  165. package/dist/switch-8SzUJz7Q.js +44 -0
  166. package/dist/switch-8SzUJz7Q.js.map +1 -0
  167. package/dist/types.js +2 -0
  168. package/dist/types.js.map +1 -0
  169. package/package.json +93 -0
  170. package/postcss.config.js +6 -0
  171. package/src/app.tsx +119 -0
  172. package/src/components/ContentView.tsx +258 -0
  173. package/src/components/HomeView.tsx +19 -0
  174. package/src/components/LoadingOverlay.tsx +12 -0
  175. package/src/components/NotFoundView.tsx +84 -0
  176. package/src/components/RouteErrorBoundary.tsx +95 -0
  177. package/src/components/ViewRoute.tsx +47 -0
  178. package/src/components/ui/alert-dialog.tsx +181 -0
  179. package/src/components/ui/breadcrumb.tsx +155 -0
  180. package/src/components/ui/button-group.tsx +52 -0
  181. package/src/components/ui/button.tsx +51 -0
  182. package/src/components/ui/dialog.tsx +160 -0
  183. package/src/components/ui/drawer.tsx +200 -0
  184. package/src/components/ui/select.tsx +24 -0
  185. package/src/components/ui/sidebar.tsx +406 -0
  186. package/src/components/ui/sonner.tsx +36 -0
  187. package/src/components/ui/switch.tsx +45 -0
  188. package/src/constants/urls.ts +4 -0
  189. package/src/features/alertDialog/DialogContext.tsx +468 -0
  190. package/src/features/config/ConfigProvider.ts +96 -0
  191. package/src/features/config/types.ts +195 -0
  192. package/src/features/config/useConfig.ts +15 -0
  193. package/src/features/cookieConsent/CookieConsentModal.tsx +122 -0
  194. package/src/features/cookieConsent/CookiePreferencesView.tsx +328 -0
  195. package/src/features/cookieConsent/cookieConsent.ts +84 -0
  196. package/src/features/cookieConsent/useCookieConsent.ts +39 -0
  197. package/src/features/drawer/DrawerContext.tsx +116 -0
  198. package/src/features/layouts/AppLayout.tsx +63 -0
  199. package/src/features/layouts/DefaultLayout.tsx +625 -0
  200. package/src/features/layouts/FullscreenLayout.tsx +55 -0
  201. package/src/features/layouts/LayoutProviders.tsx +20 -0
  202. package/src/features/layouts/OverlayShell.tsx +171 -0
  203. package/src/features/layouts/WindowsLayout.tsx +860 -0
  204. package/src/features/layouts/utils.ts +99 -0
  205. package/src/features/modal/ModalContext.tsx +112 -0
  206. package/src/features/sentry/initSentry.ts +72 -0
  207. package/src/features/settings/SettingsContext.tsx +19 -0
  208. package/src/features/settings/SettingsIcons.tsx +452 -0
  209. package/src/features/settings/SettingsProvider.tsx +341 -0
  210. package/src/features/settings/SettingsRoutes.tsx +66 -0
  211. package/src/features/settings/SettingsView.tsx +327 -0
  212. package/src/features/settings/components/Advanced.tsx +128 -0
  213. package/src/features/settings/components/Appearance.tsx +306 -0
  214. package/src/features/settings/components/DataPrivacy.tsx +142 -0
  215. package/src/features/settings/components/Develop.tsx +174 -0
  216. package/src/features/settings/components/LanguageAndRegion.tsx +329 -0
  217. package/src/features/settings/components/ServiceWorker.tsx +363 -0
  218. package/src/features/settings/components/UpdateApp.tsx +206 -0
  219. package/src/features/settings/components/develop/DialogTestButtons.tsx +137 -0
  220. package/src/features/settings/components/develop/DrawerTestButtons.tsx +67 -0
  221. package/src/features/settings/components/develop/ModalTestButtons.tsx +30 -0
  222. package/src/features/settings/components/develop/ToastTestButtons.tsx +179 -0
  223. package/src/features/settings/hooks/useSettings.tsx +10 -0
  224. package/src/features/sonner/SonnerContext.tsx +286 -0
  225. package/src/features/theme/ThemeProvider.tsx +16 -0
  226. package/src/features/theme/themes.ts +561 -0
  227. package/src/features/theme/useTheme.tsx +71 -0
  228. package/src/i18n/I18nProvider.tsx +32 -0
  229. package/src/i18n/config.ts +107 -0
  230. package/src/i18n/translations/en/common.json +16 -0
  231. package/src/i18n/translations/en/cookieConsent.json +50 -0
  232. package/src/i18n/translations/en/settings.json +355 -0
  233. package/src/i18n/translations/fr/common.json +16 -0
  234. package/src/i18n/translations/fr/cookieConsent.json +50 -0
  235. package/src/i18n/translations/fr/settings.json +355 -0
  236. package/src/index.css +412 -0
  237. package/src/index.html +100 -0
  238. package/src/index.ts +31 -0
  239. package/src/lib/utils.ts +6 -0
  240. package/src/lib/z-index.ts +29 -0
  241. package/src/main.tsx +26 -0
  242. package/src/router/router.tsx +8 -0
  243. package/src/router/routes.tsx +115 -0
  244. package/src/service-worker/register.ts +1199 -0
  245. package/src/service-worker/sw-dev.ts +87 -0
  246. package/src/service-worker/sw.ts +105 -0
  247. 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';
@@ -0,0 +1,6 @@
1
+ import { type ClassValue, clsx } from 'clsx';
2
+ import { twMerge } from 'tailwind-merge';
3
+
4
+ export function cn(...inputs: ClassValue[]) {
5
+ return twMerge(clsx(inputs));
6
+ }
@@ -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
+ };