@alepha/ui 0.15.1 → 0.15.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 (199) hide show
  1. package/dist/admin/AdminAudits-BU-p1g7A.js +3 -0
  2. package/dist/admin/{AdminAudits-DClGEVBj.js → AdminAudits-Oh7iAfQa.js} +5 -5
  3. package/dist/admin/AdminAudits-Oh7iAfQa.js.map +1 -0
  4. package/dist/admin/AdminFiles-Bg9feLFH.js +3 -0
  5. package/dist/admin/{AdminFiles-C76r1_Xz.js → AdminFiles-Cu8GHgQ3.js} +3 -3
  6. package/dist/admin/AdminFiles-Cu8GHgQ3.js.map +1 -0
  7. package/dist/admin/{AdminNotifications-Bsalygm5.js → AdminNotifications-CgYkBuG_.js} +3 -3
  8. package/dist/admin/AdminNotifications-CgYkBuG_.js.map +1 -0
  9. package/dist/admin/AdminNotifications-DmfGPqHe.js +3 -0
  10. package/dist/admin/{AdminParameters-CpmAWwqN.js → AdminParameters-Cl-R0nXt.js} +1 -1
  11. package/dist/admin/{AdminParameters-Bmxtnpv-.js → AdminParameters-hjNG_KXb.js} +4 -4
  12. package/dist/admin/AdminParameters-hjNG_KXb.js.map +1 -0
  13. package/dist/admin/{AdminSessions-DmK3R6pP.js → AdminSessions-Bey9cuy1.js} +4 -4
  14. package/dist/admin/AdminSessions-Bey9cuy1.js.map +1 -0
  15. package/dist/admin/AdminSessions-Cn4_jB04.js +3 -0
  16. package/dist/admin/{AdminUserAudits-BPMP1Qd2.js → AdminUserAudits-C7AN9jx7.js} +4 -4
  17. package/dist/admin/AdminUserAudits-C7AN9jx7.js.map +1 -0
  18. package/dist/admin/{AdminUserAudits-Brcenss9.js → AdminUserAudits-Cp_ERd2g.js} +1 -1
  19. package/dist/admin/{AdminUserCreate-CZjB6NKc.js → AdminUserCreate-BVIm4JdN.js} +5 -5
  20. package/dist/admin/AdminUserCreate-BVIm4JdN.js.map +1 -0
  21. package/dist/admin/{AdminUserCreate-Cx8bkYC2.js → AdminUserCreate-C1aInRDk.js} +1 -1
  22. package/dist/admin/{AdminUserDetails-8TYsqQBy.js → AdminUserDetails-Dcn3OwMC.js} +1 -1
  23. package/dist/admin/{AdminUserDetails-DuqCOBJK.js → AdminUserDetails-yM4x8JE6.js} +5 -5
  24. package/dist/admin/AdminUserDetails-yM4x8JE6.js.map +1 -0
  25. package/dist/admin/{AdminUserLayout-Dgk8s7Cd.js → AdminUserLayout-BnfBC1gD.js} +4 -4
  26. package/dist/admin/AdminUserLayout-BnfBC1gD.js.map +1 -0
  27. package/dist/admin/{AdminUserLayout-Bz2u_zQ4.js → AdminUserLayout-gb-nbggz.js} +1 -1
  28. package/dist/admin/{AdminUserSessions-DCpe8_T6.js → AdminUserSessions-kmkXG-xf.js} +4 -4
  29. package/dist/admin/AdminUserSessions-kmkXG-xf.js.map +1 -0
  30. package/dist/admin/AdminUserSessions-rvA0ztxn.js +3 -0
  31. package/dist/admin/{AdminUserSettings-qxDfowqh.js → AdminUserSettings-DZ9iWhJW.js} +5 -5
  32. package/dist/admin/AdminUserSettings-DZ9iWhJW.js.map +1 -0
  33. package/dist/admin/AdminUserSettings-Dg-wTRzN.js +3 -0
  34. package/dist/admin/{AdminUsers-ZlPsDz0T.js → AdminUsers-D6Y5K8Am.js} +5 -5
  35. package/dist/admin/AdminUsers-D6Y5K8Am.js.map +1 -0
  36. package/dist/admin/AdminUsers-RCaxccEW.js +3 -0
  37. package/dist/admin/index.d.ts +55 -36
  38. package/dist/admin/index.d.ts.map +1 -1
  39. package/dist/admin/index.js +54 -32
  40. package/dist/admin/index.js.map +1 -1
  41. package/dist/auth/{AuthLayout-CWzQ8rCe.js → AuthLayout-Dj5K4SIN.js} +2 -2
  42. package/dist/auth/AuthLayout-Dj5K4SIN.js.map +1 -0
  43. package/dist/auth/{Login-CyvKwy5e.js → Login-BBqTosqZ.js} +6 -6
  44. package/dist/auth/Login-BBqTosqZ.js.map +1 -0
  45. package/dist/auth/Login-CoU63mMR.js +4 -0
  46. package/dist/auth/Profile-Bxj8Nwom.js +150 -0
  47. package/dist/auth/Profile-Bxj8Nwom.js.map +1 -0
  48. package/dist/auth/Register-BV_oa_AK.js +4 -0
  49. package/dist/auth/{Register-C7Zp09Ks.js → Register-Ce675Crg.js} +8 -8
  50. package/dist/auth/Register-Ce675Crg.js.map +1 -0
  51. package/dist/auth/ResetPassword-D5wC8GAA.js +3 -0
  52. package/dist/auth/{ResetPassword-DYJSUC6B.js → ResetPassword-DWdt7c40.js} +5 -5
  53. package/dist/auth/ResetPassword-DWdt7c40.js.map +1 -0
  54. package/dist/auth/{VerifyEmail-CNXFIwWW.js → VerifyEmail-CI4JwByV.js} +4 -4
  55. package/dist/auth/VerifyEmail-CI4JwByV.js.map +1 -0
  56. package/dist/auth/VerifyEmail-DAfqVm5s.js +3 -0
  57. package/dist/auth/index.d.ts +36 -20
  58. package/dist/auth/index.d.ts.map +1 -1
  59. package/dist/auth/index.js +62 -17
  60. package/dist/auth/index.js.map +1 -1
  61. package/dist/core/index.d.ts +216 -71
  62. package/dist/core/index.d.ts.map +1 -1
  63. package/dist/core/index.js +733 -445
  64. package/dist/core/index.js.map +1 -1
  65. package/dist/demo/{DemoDataTable-DYbDYbs5.js → DemoDataTable-CguplbR7.js} +2 -2
  66. package/dist/demo/{DemoDataTable-DYbDYbs5.js.map → DemoDataTable-CguplbR7.js.map} +1 -1
  67. package/dist/demo/DemoJsonViewer-DIssGVlJ.js +4 -0
  68. package/dist/demo/{DemoJsonViewer-D_Hff1Q2.js → DemoJsonViewer-Dgdk3Txb.js} +3 -3
  69. package/dist/demo/{DemoJsonViewer-D_Hff1Q2.js.map → DemoJsonViewer-Dgdk3Txb.js.map} +1 -1
  70. package/dist/demo/{DemoLayout-DjIDm93B.js → DemoLayout-B20TEuhV.js} +2 -2
  71. package/dist/demo/DemoLayout-B20TEuhV.js.map +1 -0
  72. package/dist/demo/DemoLayout-DSRyf4qJ.js +3 -0
  73. package/dist/demo/{DemoLogin-BA_HiIRZ.js → DemoLogin-S-b15cmE.js} +7 -7
  74. package/dist/demo/DemoLogin-S-b15cmE.js.map +1 -0
  75. package/dist/demo/{DemoRegister-B6syaxP9.js → DemoRegister-B29MdAaZ.js} +9 -9
  76. package/dist/demo/DemoRegister-B29MdAaZ.js.map +1 -0
  77. package/dist/demo/{DemoResetPassword-BOcLG4GF.js → DemoResetPassword-CPTy88iK.js} +6 -6
  78. package/dist/demo/DemoResetPassword-CPTy88iK.js.map +1 -0
  79. package/dist/demo/{DemoSidebar-DpZXf7GO.js → DemoSidebar-MVmQKfMt.js} +2 -2
  80. package/dist/demo/{DemoSidebar-DpZXf7GO.js.map → DemoSidebar-MVmQKfMt.js.map} +1 -1
  81. package/dist/demo/{DemoTypeForm-BlLAcQqZ.js → DemoTypeForm-w-qtfRlC.js} +3 -3
  82. package/dist/demo/DemoTypeForm-w-qtfRlC.js.map +1 -0
  83. package/dist/demo/{DemoVerifyEmail-C-J7bXUQ.js → DemoVerifyEmail-C8FFJT5A.js} +5 -5
  84. package/dist/demo/DemoVerifyEmail-C8FFJT5A.js.map +1 -0
  85. package/dist/demo/{Showcase-HchhcsHV.js → Showcase-CQrMWars.js} +2 -2
  86. package/dist/demo/Showcase-CQrMWars.js.map +1 -0
  87. package/dist/demo/index.d.ts +25 -15
  88. package/dist/demo/index.d.ts.map +1 -1
  89. package/dist/demo/index.js +24 -14
  90. package/dist/demo/index.js.map +1 -1
  91. package/package.json +6 -6
  92. package/src/admin/AdminRouter.ts +4 -4
  93. package/src/admin/MainRouter.ts +1 -1
  94. package/src/admin/components/audits/AdminAudits.tsx +4 -4
  95. package/src/admin/components/files/AdminFiles.tsx +2 -2
  96. package/src/admin/components/jobs/AdminJobs.tsx +2 -2
  97. package/src/admin/components/notifications/AdminNotifications.tsx +2 -2
  98. package/src/admin/components/parameters/AdminParameters.tsx +1 -1
  99. package/src/admin/components/parameters/ParameterDetails.tsx +2 -2
  100. package/src/admin/components/parameters/ParameterHistory.tsx +1 -1
  101. package/src/admin/components/parameters/types.ts +9 -3
  102. package/src/admin/components/sessions/AdminSessions.tsx +3 -3
  103. package/src/admin/components/shared/AdminResourceHeader.tsx +1 -1
  104. package/src/admin/components/shared/AdminResourceTabs.tsx +1 -1
  105. package/src/admin/components/users/AdminUserAudits.tsx +3 -3
  106. package/src/admin/components/users/AdminUserCreate.tsx +4 -4
  107. package/src/admin/components/users/AdminUserDetails.tsx +4 -4
  108. package/src/admin/components/users/AdminUserLayout.tsx +3 -3
  109. package/src/admin/components/users/AdminUserSessions.tsx +3 -3
  110. package/src/admin/components/users/AdminUserSettings.tsx +4 -4
  111. package/src/admin/components/users/AdminUsers.tsx +4 -4
  112. package/src/admin/index.ts +27 -2
  113. package/src/auth/AuthI18n.ts +1 -1
  114. package/src/auth/AuthRouter.ts +14 -2
  115. package/src/auth/components/AuthLayout.tsx +1 -1
  116. package/src/auth/components/Login.tsx +5 -5
  117. package/src/auth/components/Profile.tsx +157 -0
  118. package/src/auth/components/Register.tsx +7 -7
  119. package/src/auth/components/ResetPassword.tsx +4 -4
  120. package/src/auth/components/VerifyEmail.tsx +3 -3
  121. package/src/auth/components/buttons/UserButton.tsx +35 -3
  122. package/src/auth/index.ts +25 -4
  123. package/src/core/UiRouter.ts +15 -0
  124. package/src/core/atoms/alephaSidebarAtom.ts +57 -0
  125. package/src/core/atoms/alephaThemeListAtom.ts +3 -1
  126. package/src/core/components/buttons/ActionButton.tsx +10 -10
  127. package/src/core/components/buttons/BurgerButton.tsx +5 -4
  128. package/src/core/components/buttons/LanguageButton.tsx +1 -1
  129. package/src/core/components/buttons/OmnibarButton.tsx +20 -1
  130. package/src/core/components/buttons/ThemeButton.tsx +1 -1
  131. package/src/core/components/buttons/ToggleSidebarButton.tsx +33 -23
  132. package/src/core/components/form/Control.tsx +1 -1
  133. package/src/core/components/form/ControlArray.tsx +2 -2
  134. package/src/core/components/form/ControlDate.tsx +1 -1
  135. package/src/core/components/form/ControlNumber.tsx +2 -2
  136. package/src/core/components/form/ControlObject.tsx +1 -1
  137. package/src/core/components/form/ControlQueryBuilder.tsx +1 -1
  138. package/src/core/components/form/ControlSelect.tsx +1 -1
  139. package/src/core/components/form/TypeForm.tsx +2 -2
  140. package/src/core/components/layout/AdminShell.tsx +236 -30
  141. package/src/core/components/layout/AlephaMantineProvider.tsx +3 -3
  142. package/src/core/components/layout/AppBar.tsx +235 -18
  143. package/src/core/components/layout/Omnibar.tsx +4 -4
  144. package/src/core/components/layout/Sidebar.tsx +43 -82
  145. package/src/core/components/table/DataTable.tsx +2 -2
  146. package/src/core/components/table/DataTableFilters.tsx +1 -1
  147. package/src/core/components/table/types.ts +1 -1
  148. package/src/core/hooks/useDialog.ts +1 -1
  149. package/src/core/hooks/useTheme.ts +1 -1
  150. package/src/core/hooks/useToast.ts +1 -1
  151. package/src/core/index.ts +46 -9
  152. package/src/core/providers/ThemeProvider.ts +1 -1
  153. package/src/core/styles.css +58 -0
  154. package/src/core/utils/parseInput.ts +1 -1
  155. package/src/demo/DemoRouter.ts +1 -1
  156. package/src/demo/components/DemoLayout.tsx +1 -1
  157. package/src/demo/components/core/DemoTypeForm.tsx +1 -1
  158. package/src/demo/components/json/DemoJsonViewer.tsx +1 -1
  159. package/src/demo/components/shared/Showcase.tsx +1 -1
  160. package/src/demo/index.ts +11 -1
  161. package/src/json/index.ts +13 -0
  162. package/dist/admin/AdminAudits-ColpiP4T.js +0 -3
  163. package/dist/admin/AdminAudits-DClGEVBj.js.map +0 -1
  164. package/dist/admin/AdminFiles-C5pqXN5B.js +0 -3
  165. package/dist/admin/AdminFiles-C76r1_Xz.js.map +0 -1
  166. package/dist/admin/AdminNotifications-BXixCBu9.js +0 -3
  167. package/dist/admin/AdminNotifications-Bsalygm5.js.map +0 -1
  168. package/dist/admin/AdminParameters-Bmxtnpv-.js.map +0 -1
  169. package/dist/admin/AdminSessions-CrkRvey3.js +0 -3
  170. package/dist/admin/AdminSessions-DmK3R6pP.js.map +0 -1
  171. package/dist/admin/AdminUserAudits-BPMP1Qd2.js.map +0 -1
  172. package/dist/admin/AdminUserCreate-CZjB6NKc.js.map +0 -1
  173. package/dist/admin/AdminUserDetails-DuqCOBJK.js.map +0 -1
  174. package/dist/admin/AdminUserLayout-Dgk8s7Cd.js.map +0 -1
  175. package/dist/admin/AdminUserSessions-DCpe8_T6.js.map +0 -1
  176. package/dist/admin/AdminUserSessions-beiJqY2D.js +0 -3
  177. package/dist/admin/AdminUserSettings-CxlInVnu.js +0 -3
  178. package/dist/admin/AdminUserSettings-qxDfowqh.js.map +0 -1
  179. package/dist/admin/AdminUsers-Bd0wMP8v.js +0 -3
  180. package/dist/admin/AdminUsers-ZlPsDz0T.js.map +0 -1
  181. package/dist/auth/AuthLayout-CWzQ8rCe.js.map +0 -1
  182. package/dist/auth/Login-CxOPyNFP.js +0 -4
  183. package/dist/auth/Login-CyvKwy5e.js.map +0 -1
  184. package/dist/auth/Register-C7Zp09Ks.js.map +0 -1
  185. package/dist/auth/Register-Cacr7YbA.js +0 -4
  186. package/dist/auth/ResetPassword-CMkx8Ibf.js +0 -3
  187. package/dist/auth/ResetPassword-DYJSUC6B.js.map +0 -1
  188. package/dist/auth/VerifyEmail-CNXFIwWW.js.map +0 -1
  189. package/dist/auth/VerifyEmail-DKyDlz96.js +0 -3
  190. package/dist/demo/DemoJsonViewer-DbWVDdz_.js +0 -4
  191. package/dist/demo/DemoLayout-DjIDm93B.js.map +0 -1
  192. package/dist/demo/DemoLayout-nNMajP_9.js +0 -3
  193. package/dist/demo/DemoLogin-BA_HiIRZ.js.map +0 -1
  194. package/dist/demo/DemoRegister-B6syaxP9.js.map +0 -1
  195. package/dist/demo/DemoResetPassword-BOcLG4GF.js.map +0 -1
  196. package/dist/demo/DemoTypeForm-BlLAcQqZ.js.map +0 -1
  197. package/dist/demo/DemoVerifyEmail-C-J7bXUQ.js.map +0 -1
  198. package/dist/demo/Showcase-HchhcsHV.js.map +0 -1
  199. package/src/core/RootRouter.ts +0 -9
@@ -1,24 +1,50 @@
1
- import { AlephaReactForm, FormValidationError, useForm, useFormState } from "@alepha/react/form";
2
- import { $head, AlephaReactHead } from "@alepha/react/head";
3
- import { AlephaReactI18n, useI18n } from "@alepha/react/i18n";
4
- import { $atom, $inject, $module, Alepha, AlephaError, TypeBoxError, t } from "alepha";
1
+ import { $atom, $context, $inject, $module, Alepha, AlephaError, TypeBoxError, t } from "alepha";
2
+ import { AlephaReactForm, FormValidationError, useForm, useFormState } from "alepha/react/form";
3
+ import { $head, AlephaReactHead } from "alepha/react/head";
4
+ import { AlephaReactI18n, useI18n } from "alepha/react/i18n";
5
5
  import { $cookie } from "alepha/server/cookies";
6
- import { $page, NestedView, useActive, useRouter } from "@alepha/react/router";
7
- import { useAction, useEvents, useInject, useStore } from "@alepha/react";
8
- import { ActionIcon, Anchor, AppShell, Autocomplete, Badge, Box, Burger, Button, Card, Checkbox, Collapse, ColorInput, ColorSchemeScript, CopyButton, Divider, Fieldset, FileInput, Flex, Flex as Flex$1, Grid, Group, Input, Kbd, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, Slider, Stack, Switch, Table, TagsInput, Text, Text as Text$1, TextInput, Textarea, ThemeIcon, Tooltip, UnstyledButton, useComputedColorScheme, useMantineColorScheme, useMantineTheme } from "@mantine/core";
6
+ import { ActionIcon, Anchor, AppShell, Autocomplete, Badge, Box, Burger, Button, Card, Checkbox, Collapse, ColorInput, ColorSchemeScript, Container, CopyButton, Divider, Fieldset, FileInput, Flex, Flex as Flex$1, Grid, Group, Image, Input, Kbd, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, Slider, Stack, Switch, Table, TagsInput, Text, Text as Text$1, TextInput, Textarea, ThemeIcon, Tooltip, UnstyledButton, useComputedColorScheme, useMantineColorScheme, useMantineTheme } from "@mantine/core";
9
7
  import { ModalsProvider, modals } from "@mantine/modals";
8
+ import { IconAlertTriangle, IconArrowDown, IconArrowLeft, IconArrowUp, IconArrowsSort, IconAt, IconCalendar, IconCheck, IconChevronDown, IconChevronRight, IconClock, IconColorPicker, IconColumns, IconCopy, IconFile, IconFilter, IconGripVertical, IconHash, IconInfoCircle, IconInfoTriangle, IconKey, IconLanguage, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightCollapse, IconLetterCase, IconLink, IconList, IconMail, IconMoon, IconPalette, IconPhone, IconPlus, IconRefresh, IconSearch, IconSelector, IconSquareRounded, IconSun, IconToggleLeft, IconTrash, IconX } from "@tabler/icons-react";
9
+ import { Children, createElement, isValidElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
10
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
10
11
  import { Notifications, notifications } from "@mantine/notifications";
12
+ import { $page, Link, NestedView, useActive, useRouter } from "alepha/react/router";
11
13
  import { NavigationProgress, nprogress } from "@mantine/nprogress";
12
- import { IconAlertTriangle, IconArrowDown, IconArrowUp, IconArrowsSort, IconAt, IconCalendar, IconCheck, IconChevronDown, IconChevronRight, IconClock, IconColorPicker, IconColumns, IconCopy, IconFile, IconFilter, IconGripVertical, IconHash, IconInfoCircle, IconInfoTriangle, IconKey, IconLanguage, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightCollapse, IconLetterCase, IconLink, IconList, IconMail, IconMoon, IconPalette, IconPhone, IconPlus, IconRefresh, IconSearch, IconSelector, IconSquareRounded, IconSun, IconToggleLeft, IconTrash, IconX } from "@tabler/icons-react";
13
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
+ import { ClientOnly, useAction, useEvents, useInject, useStore } from "alepha/react";
14
15
  import { Spotlight, spotlight } from "@mantine/spotlight";
15
- import { Children, createElement, isValidElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
16
16
  import { ui as ui$1 } from "@alepha/ui";
17
+ import { useDebouncedCallback, useOs } from "@mantine/hooks";
17
18
  import { DateInput, DateTimePicker, TimeInput } from "@mantine/dates";
18
19
  import { parseQueryString } from "alepha/orm";
19
- import { useDebouncedCallback } from "@mantine/hooks";
20
20
  import { DateTimeProvider } from "alepha/datetime";
21
21
 
22
+ //#region ../../src/core/atoms/alephaSidebarAtom.ts
23
+ const alephaSidebarAtom = $atom({
24
+ name: "alepha.ui.sidebar",
25
+ schema: t.object({
26
+ opened: t.boolean(),
27
+ collapsed: t.boolean(),
28
+ width: t.number(),
29
+ defaultWidth: t.number(),
30
+ collapsedWidth: t.number(),
31
+ maxWidth: t.number(),
32
+ collapseThreshold: t.number(),
33
+ hoverDelay: t.number()
34
+ }),
35
+ default: {
36
+ opened: false,
37
+ collapsed: false,
38
+ width: 300,
39
+ defaultWidth: 300,
40
+ collapsedWidth: 78,
41
+ maxWidth: 500,
42
+ collapseThreshold: 240,
43
+ hoverDelay: 300
44
+ }
45
+ });
46
+
47
+ //#endregion
22
48
  //#region ../../src/core/atoms/alephaThemeAtom.ts
23
49
  const alephaThemeAtom = $atom({
24
50
  name: "alepha.ui.theme",
@@ -193,222 +219,6 @@ var ThemeProvider = class {
193
219
  }
194
220
  };
195
221
 
196
- //#endregion
197
- //#region ../../src/core/hooks/useTheme.ts
198
- /**
199
- * Hook to get and set the current theme.
200
- *
201
- * Returns a tuple with the current theme and a function to set the theme.
202
- *
203
- * ```tsx
204
- * const [theme, setTheme] = useTheme();
205
- * ```
206
- */
207
- const useTheme = () => {
208
- useStore(alephaThemeAtom);
209
- const themeProvider = useInject(ThemeProvider);
210
- const theme = themeProvider.getTheme();
211
- const setTheme = (theme) => {
212
- themeProvider.setTheme(theme.index);
213
- };
214
- return [theme, setTheme];
215
- };
216
-
217
- //#endregion
218
- //#region ../../src/core/services/ToastService.tsx
219
- var ToastService = class {
220
- raw = notifications;
221
- options = { default: {
222
- radius: "md",
223
- withBorder: true,
224
- withCloseButton: true,
225
- autoClose: 5e3,
226
- position: "top-center"
227
- } };
228
- show(options) {
229
- notifications.show({
230
- ...this.options.default,
231
- ...options
232
- });
233
- }
234
- info(options) {
235
- if (typeof options === "string") options = { message: options };
236
- this.show({
237
- color: "blue",
238
- icon: /* @__PURE__ */ jsx(IconInfoCircle, { size: 20 }),
239
- title: "Info",
240
- message: "Information notification",
241
- ...options
242
- });
243
- }
244
- success(options) {
245
- if (typeof options === "string") options = { message: options };
246
- this.show({
247
- color: "green",
248
- icon: /* @__PURE__ */ jsx(IconCheck, { size: 16 }),
249
- title: "Success",
250
- message: "Operation completed successfully",
251
- ...options
252
- });
253
- }
254
- warning(options) {
255
- if (typeof options === "string") options = { message: options };
256
- this.show({
257
- color: "yellow",
258
- icon: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 20 }),
259
- title: "Warning",
260
- message: "Please review this warning",
261
- ...options
262
- });
263
- }
264
- danger(options) {
265
- if (typeof options === "string") options = { message: options };
266
- this.show({
267
- color: "red",
268
- icon: /* @__PURE__ */ jsx(IconX, { size: 20 }),
269
- title: "Error",
270
- message: "An error occurred",
271
- ...options
272
- });
273
- }
274
- };
275
-
276
- //#endregion
277
- //#region ../../src/core/hooks/useToast.ts
278
- /**
279
- * Use this hook to access the Toast Service for showing notifications.
280
- *
281
- * @example
282
- * ```tsx
283
- * const toast = useToast();
284
- * toast.success({ message: "Operation completed successfully!" });
285
- * toast.error({ title: "Error", message: "Something went wrong" });
286
- * ```
287
- */
288
- const useToast = () => {
289
- return useInject(ToastService);
290
- };
291
-
292
- //#endregion
293
- //#region ../../src/core/constants/ui.ts
294
- const ui = {
295
- colors: {
296
- transparent: "transparent",
297
- background: "var(--alepha-background)",
298
- surface: "var(--alepha-surface)",
299
- elevated: "var(--alepha-elevated)",
300
- border: "var(--alepha-border)"
301
- },
302
- sizes: { icon: {
303
- xs: 12,
304
- sm: 16,
305
- md: 20,
306
- lg: 24,
307
- xl: 32
308
- } }
309
- };
310
-
311
- //#endregion
312
- //#region ../../src/core/helpers/isComponentType.ts
313
- function isComponentType(param) {
314
- if (isValidElement(param)) return false;
315
- return typeof param === "function" || typeof param === "object" && param !== null && "$$typeof" in param;
316
- }
317
-
318
- //#endregion
319
- //#region ../../src/core/helpers/renderIcon.tsx
320
- const renderIcon = (icon) => {
321
- if (!icon) return null;
322
- if (isValidElement(icon)) return icon;
323
- if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: ui$1.sizes.icon.md });
324
- return icon;
325
- };
326
-
327
- //#endregion
328
- //#region ../../src/core/components/layout/Omnibar.tsx
329
- const Omnibar = (props) => {
330
- const shortcut = props.shortcut ?? "mod+K";
331
- const searchPlaceholder = props.searchPlaceholder ?? "Search...";
332
- const nothingFound = props.nothingFound ?? "Nothing found...";
333
- const router = useRouter();
334
- const [user] = useStore("alepha.server.request.user");
335
- return /* @__PURE__ */ jsx(Spotlight, {
336
- actions: useMemo(() => router.concretePages.filter((page) => {
337
- if (page.can && !page.can()) return false;
338
- return true;
339
- }).map((page) => ({
340
- id: page.name,
341
- label: page.label ?? page.name,
342
- description: page.description,
343
- onClick: () => {
344
- if (page.staticName) return router.go(page.staticName, { params: page.params });
345
- return router.go(page.name);
346
- },
347
- leftSection: renderIcon(page.icon)
348
- })), [user]),
349
- shortcut,
350
- limit: 10,
351
- searchProps: {
352
- leftSection: /* @__PURE__ */ jsx(IconSearch, { size: ui.sizes.icon.md }),
353
- placeholder: searchPlaceholder
354
- },
355
- nothingFound
356
- });
357
- };
358
- var Omnibar_default = Omnibar;
359
-
360
- //#endregion
361
- //#region ../../src/core/components/layout/AlephaMantineProvider.tsx
362
- const AlephaMantineProvider = (props) => {
363
- const toast = useToast();
364
- const [theme] = useTheme();
365
- useEvents({
366
- "react:transition:begin": () => {
367
- nprogress.start();
368
- },
369
- "react:transition:end": () => {
370
- nprogress.complete();
371
- },
372
- "react:action:error": ({ error }) => {
373
- if (error instanceof FormValidationError || error instanceof TypeBoxError) return;
374
- toast.danger({
375
- title: error.name || "Error",
376
- message: error.message ?? "An error occurred while processing your action."
377
- });
378
- }
379
- }, []);
380
- const defaultColorScheme = props.mantine?.defaultColorScheme ?? theme.defaultColorScheme;
381
- return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ColorSchemeScript, {
382
- defaultColorScheme,
383
- ...props.colorSchemeScript
384
- }), /* @__PURE__ */ jsxs(MantineProvider, {
385
- ...props.mantine,
386
- defaultColorScheme,
387
- theme: {
388
- ...theme,
389
- ...props.mantine?.theme
390
- },
391
- children: [
392
- /* @__PURE__ */ jsx(Notifications, { ...props.notifications }),
393
- /* @__PURE__ */ jsx(NavigationProgress, { ...props.navigationProgress }),
394
- /* @__PURE__ */ jsxs(ModalsProvider, {
395
- ...props.modals,
396
- children: [props.omnibar !== false && /* @__PURE__ */ jsx(Omnibar_default, { ...props.omnibar }), props.children ?? /* @__PURE__ */ jsx(NestedView, {})]
397
- })
398
- ]
399
- })] });
400
- };
401
- var AlephaMantineProvider_default = AlephaMantineProvider;
402
-
403
- //#endregion
404
- //#region ../../src/core/RootRouter.ts
405
- var RootRouter = class {
406
- root = $page({
407
- path: "/",
408
- component: AlephaMantineProvider_default
409
- });
410
- };
411
-
412
222
  //#endregion
413
223
  //#region ../../src/core/components/data/ErrorViewer.tsx
414
224
  const getSizeConfig = (size = "sm") => {
@@ -625,135 +435,357 @@ const PromptDialog = ({ options, onSubmit }) => {
625
435
  })
626
436
  ] });
627
437
  };
628
- var PromptDialog_default = PromptDialog;
438
+ var PromptDialog_default = PromptDialog;
439
+
440
+ //#endregion
441
+ //#region ../../src/core/constants/ui.ts
442
+ const ui = {
443
+ colors: {
444
+ transparent: "transparent",
445
+ background: "var(--alepha-background)",
446
+ surface: "var(--alepha-surface)",
447
+ elevated: "var(--alepha-elevated)",
448
+ border: "var(--alepha-border)"
449
+ },
450
+ sizes: { icon: {
451
+ xs: 12,
452
+ sm: 16,
453
+ md: 20,
454
+ lg: 24,
455
+ xl: 32
456
+ } }
457
+ };
458
+
459
+ //#endregion
460
+ //#region ../../src/core/services/DialogService.tsx
461
+ var DialogService = class {
462
+ options = { default: {
463
+ centered: true,
464
+ withCloseButton: true,
465
+ size: "md",
466
+ overlayProps: {
467
+ backgroundOpacity: .55,
468
+ blur: 3
469
+ },
470
+ transitionProps: {
471
+ transition: "pop",
472
+ duration: 200
473
+ }
474
+ } };
475
+ /**
476
+ * Show an alert dialog with a message
477
+ */
478
+ alert(options) {
479
+ return new Promise((resolve) => {
480
+ const modalId = this.open({
481
+ ...options,
482
+ title: options?.title || "Alert",
483
+ content: /* @__PURE__ */ jsx(AlertDialog_default, {
484
+ options,
485
+ onClose: () => {
486
+ this.close(modalId);
487
+ resolve();
488
+ }
489
+ })
490
+ });
491
+ });
492
+ }
493
+ /**
494
+ * Show a confirmation dialog that returns a promise
495
+ */
496
+ confirm(options) {
497
+ return new Promise((resolve) => {
498
+ const modalId = this.open({
499
+ ...options,
500
+ title: options?.title || "Confirm",
501
+ closeOnClickOutside: false,
502
+ closeOnEscape: false,
503
+ content: /* @__PURE__ */ jsx(ConfirmDialog_default, {
504
+ options,
505
+ onConfirm: (confirmed) => {
506
+ this.close(modalId);
507
+ resolve(confirmed);
508
+ }
509
+ })
510
+ });
511
+ });
512
+ }
513
+ /**
514
+ * Show a prompt dialog to get user input
515
+ */
516
+ prompt(options) {
517
+ return new Promise((resolve) => {
518
+ const modalId = this.open({
519
+ ...options,
520
+ title: options?.title || "Input",
521
+ closeOnClickOutside: false,
522
+ closeOnEscape: false,
523
+ content: /* @__PURE__ */ jsx(PromptDialog_default, {
524
+ options,
525
+ onSubmit: (value) => {
526
+ this.close(modalId);
527
+ resolve(value);
528
+ }
529
+ })
530
+ });
531
+ });
532
+ }
533
+ /**
534
+ * Open a custom dialog with provided content
535
+ */
536
+ open(options) {
537
+ return modals.open({
538
+ ...this.options.default,
539
+ ...options,
540
+ children: options?.content || options?.message
541
+ });
542
+ }
543
+ /**
544
+ * Close the currently open dialog or a specific dialog by ID
545
+ */
546
+ close(modalId) {
547
+ if (modalId) modals.close(modalId);
548
+ else modals.closeAll();
549
+ }
550
+ /**
551
+ * Show an error viewer dialog
552
+ */
553
+ error(error, options) {
554
+ this.open({
555
+ size: "lg",
556
+ title: options?.title || "Error",
557
+ ...options,
558
+ content: /* @__PURE__ */ jsx(Flex$1, {
559
+ bdrs: "md",
560
+ w: "100%",
561
+ flex: 1,
562
+ p: "sm",
563
+ bg: ui.colors.surface,
564
+ children: /* @__PURE__ */ jsx(ErrorViewer_default, {
565
+ size: "xs",
566
+ error,
567
+ showStack: options?.showStack ?? true
568
+ })
569
+ })
570
+ });
571
+ }
572
+ /**
573
+ * Show a form dialog for structured input
574
+ */
575
+ form(options) {
576
+ return Promise.resolve(null);
577
+ }
578
+ /**
579
+ * Show a loading/progress dialog with optional progress percentage
580
+ */
581
+ loading(options) {}
582
+ /**
583
+ * Show an image viewer/gallery dialog
584
+ */
585
+ image(src, options) {}
586
+ };
587
+
588
+ //#endregion
589
+ //#region ../../src/core/services/ToastService.tsx
590
+ var ToastService = class {
591
+ raw = notifications;
592
+ options = { default: {
593
+ radius: "md",
594
+ withBorder: true,
595
+ withCloseButton: true,
596
+ autoClose: 5e3,
597
+ position: "top-center"
598
+ } };
599
+ show(options) {
600
+ notifications.show({
601
+ ...this.options.default,
602
+ ...options
603
+ });
604
+ }
605
+ info(options) {
606
+ if (typeof options === "string") options = { message: options };
607
+ this.show({
608
+ color: "blue",
609
+ icon: /* @__PURE__ */ jsx(IconInfoCircle, { size: 20 }),
610
+ title: "Info",
611
+ message: "Information notification",
612
+ ...options
613
+ });
614
+ }
615
+ success(options) {
616
+ if (typeof options === "string") options = { message: options };
617
+ this.show({
618
+ color: "green",
619
+ icon: /* @__PURE__ */ jsx(IconCheck, { size: 16 }),
620
+ title: "Success",
621
+ message: "Operation completed successfully",
622
+ ...options
623
+ });
624
+ }
625
+ warning(options) {
626
+ if (typeof options === "string") options = { message: options };
627
+ this.show({
628
+ color: "yellow",
629
+ icon: /* @__PURE__ */ jsx(IconAlertTriangle, { size: 20 }),
630
+ title: "Warning",
631
+ message: "Please review this warning",
632
+ ...options
633
+ });
634
+ }
635
+ danger(options) {
636
+ if (typeof options === "string") options = { message: options };
637
+ this.show({
638
+ color: "red",
639
+ icon: /* @__PURE__ */ jsx(IconX, { size: 20 }),
640
+ title: "Error",
641
+ message: "An error occurred",
642
+ ...options
643
+ });
644
+ }
645
+ };
646
+
647
+ //#endregion
648
+ //#region ../../src/core/hooks/useTheme.ts
649
+ /**
650
+ * Hook to get and set the current theme.
651
+ *
652
+ * Returns a tuple with the current theme and a function to set the theme.
653
+ *
654
+ * ```tsx
655
+ * const [theme, setTheme] = useTheme();
656
+ * ```
657
+ */
658
+ const useTheme = () => {
659
+ useStore(alephaThemeAtom);
660
+ const themeProvider = useInject(ThemeProvider);
661
+ const theme = themeProvider.getTheme();
662
+ const setTheme = (theme) => {
663
+ themeProvider.setTheme(theme.index);
664
+ };
665
+ return [theme, setTheme];
666
+ };
667
+
668
+ //#endregion
669
+ //#region ../../src/core/hooks/useToast.ts
670
+ /**
671
+ * Use this hook to access the Toast Service for showing notifications.
672
+ *
673
+ * @example
674
+ * ```tsx
675
+ * const toast = useToast();
676
+ * toast.success({ message: "Operation completed successfully!" });
677
+ * toast.error({ title: "Error", message: "Something went wrong" });
678
+ * ```
679
+ */
680
+ const useToast = () => {
681
+ return useInject(ToastService);
682
+ };
683
+
684
+ //#endregion
685
+ //#region ../../src/core/helpers/isComponentType.ts
686
+ function isComponentType(param) {
687
+ if (isValidElement(param)) return false;
688
+ return typeof param === "function" || typeof param === "object" && param !== null && "$$typeof" in param;
689
+ }
690
+
691
+ //#endregion
692
+ //#region ../../src/core/helpers/renderIcon.tsx
693
+ const renderIcon = (icon) => {
694
+ if (!icon) return null;
695
+ if (isValidElement(icon)) return icon;
696
+ if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: ui$1.sizes.icon.md });
697
+ return icon;
698
+ };
699
+
700
+ //#endregion
701
+ //#region ../../src/core/components/layout/Omnibar.tsx
702
+ const Omnibar = (props) => {
703
+ const shortcut = props.shortcut ?? "mod+K";
704
+ const searchPlaceholder = props.searchPlaceholder ?? "Search...";
705
+ const nothingFound = props.nothingFound ?? "Nothing found...";
706
+ const router = useRouter();
707
+ const [user] = useStore("alepha.server.request.user");
708
+ return /* @__PURE__ */ jsx(Spotlight, {
709
+ actions: useMemo(() => router.concretePages.filter((page) => {
710
+ if (page.can && !page.can()) return false;
711
+ return true;
712
+ }).map((page) => ({
713
+ id: page.name,
714
+ label: page.label ?? page.name,
715
+ description: page.description,
716
+ onClick: () => {
717
+ if (page.staticName) return router.push(page.staticName, { params: page.params });
718
+ return router.push(page.name);
719
+ },
720
+ leftSection: renderIcon(page.icon)
721
+ })), [user]),
722
+ shortcut,
723
+ limit: 10,
724
+ searchProps: {
725
+ leftSection: /* @__PURE__ */ jsx(IconSearch, { size: ui.sizes.icon.md }),
726
+ placeholder: searchPlaceholder
727
+ },
728
+ nothingFound
729
+ });
730
+ };
731
+ var Omnibar_default = Omnibar;
732
+
733
+ //#endregion
734
+ //#region ../../src/core/components/layout/AlephaMantineProvider.tsx
735
+ const AlephaMantineProvider = (props) => {
736
+ const toast = useToast();
737
+ const [theme] = useTheme();
738
+ useEvents({
739
+ "react:transition:begin": () => {
740
+ nprogress.start();
741
+ },
742
+ "react:transition:end": () => {
743
+ nprogress.complete();
744
+ },
745
+ "react:action:error": ({ error }) => {
746
+ if (error instanceof FormValidationError || error instanceof TypeBoxError) return;
747
+ toast.danger({
748
+ title: error.name || "Error",
749
+ message: error.message ?? "An error occurred while processing your action."
750
+ });
751
+ }
752
+ }, []);
753
+ const defaultColorScheme = props.mantine?.defaultColorScheme ?? theme.defaultColorScheme;
754
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(ColorSchemeScript, {
755
+ defaultColorScheme,
756
+ ...props.colorSchemeScript
757
+ }), /* @__PURE__ */ jsxs(MantineProvider, {
758
+ ...props.mantine,
759
+ defaultColorScheme,
760
+ theme: {
761
+ ...theme,
762
+ ...props.mantine?.theme
763
+ },
764
+ children: [
765
+ /* @__PURE__ */ jsx(Notifications, { ...props.notifications }),
766
+ /* @__PURE__ */ jsx(NavigationProgress, { ...props.navigationProgress }),
767
+ /* @__PURE__ */ jsxs(ModalsProvider, {
768
+ ...props.modals,
769
+ children: [props.omnibar !== false && /* @__PURE__ */ jsx(Omnibar_default, { ...props.omnibar }), props.children ?? /* @__PURE__ */ jsx(NestedView, {})]
770
+ })
771
+ ]
772
+ })] });
773
+ };
774
+ var AlephaMantineProvider_default = AlephaMantineProvider;
629
775
 
630
776
  //#endregion
631
- //#region ../../src/core/services/DialogService.tsx
632
- var DialogService = class {
633
- options = { default: {
634
- centered: true,
635
- withCloseButton: true,
636
- size: "md",
637
- overlayProps: {
638
- backgroundOpacity: .55,
639
- blur: 3
640
- },
641
- transitionProps: {
642
- transition: "pop",
643
- duration: 200
644
- }
645
- } };
646
- /**
647
- * Show an alert dialog with a message
648
- */
649
- alert(options) {
650
- return new Promise((resolve) => {
651
- const modalId = this.open({
652
- ...options,
653
- title: options?.title || "Alert",
654
- content: /* @__PURE__ */ jsx(AlertDialog_default, {
655
- options,
656
- onClose: () => {
657
- this.close(modalId);
658
- resolve();
659
- }
660
- })
661
- });
662
- });
663
- }
664
- /**
665
- * Show a confirmation dialog that returns a promise
666
- */
667
- confirm(options) {
668
- return new Promise((resolve) => {
669
- const modalId = this.open({
670
- ...options,
671
- title: options?.title || "Confirm",
672
- closeOnClickOutside: false,
673
- closeOnEscape: false,
674
- content: /* @__PURE__ */ jsx(ConfirmDialog_default, {
675
- options,
676
- onConfirm: (confirmed) => {
677
- this.close(modalId);
678
- resolve(confirmed);
679
- }
680
- })
681
- });
682
- });
683
- }
684
- /**
685
- * Show a prompt dialog to get user input
686
- */
687
- prompt(options) {
688
- return new Promise((resolve) => {
689
- const modalId = this.open({
690
- ...options,
691
- title: options?.title || "Input",
692
- closeOnClickOutside: false,
693
- closeOnEscape: false,
694
- content: /* @__PURE__ */ jsx(PromptDialog_default, {
695
- options,
696
- onSubmit: (value) => {
697
- this.close(modalId);
698
- resolve(value);
699
- }
700
- })
701
- });
702
- });
703
- }
704
- /**
705
- * Open a custom dialog with provided content
706
- */
707
- open(options) {
708
- return modals.open({
709
- ...this.options.default,
710
- ...options,
711
- children: options?.content || options?.message
712
- });
713
- }
714
- /**
715
- * Close the currently open dialog or a specific dialog by ID
716
- */
717
- close(modalId) {
718
- if (modalId) modals.close(modalId);
719
- else modals.closeAll();
720
- }
721
- /**
722
- * Show an error viewer dialog
723
- */
724
- error(error, options) {
725
- this.open({
726
- size: "lg",
727
- title: options?.title || "Error",
728
- ...options,
729
- content: /* @__PURE__ */ jsx(Flex$1, {
730
- bdrs: "md",
731
- w: "100%",
732
- flex: 1,
733
- p: "sm",
734
- bg: ui.colors.surface,
735
- children: /* @__PURE__ */ jsx(ErrorViewer_default, {
736
- size: "xs",
737
- error,
738
- showStack: options?.showStack ?? true
739
- })
740
- })
741
- });
742
- }
743
- /**
744
- * Show a form dialog for structured input
745
- */
746
- form(options) {
747
- return Promise.resolve(null);
748
- }
749
- /**
750
- * Show a loading/progress dialog with optional progress percentage
751
- */
752
- loading(options) {}
753
- /**
754
- * Show an image viewer/gallery dialog
755
- */
756
- image(src, options) {}
777
+ //#region ../../src/core/UiRouter.ts
778
+ /**
779
+ * UI Router defining the root page with AlephaMantineProvider.
780
+ *
781
+ * - Use UiRouter when you need Alepha's Mantine-based UI components and theming.
782
+ * - Prefer to use $ui() for convenience. (Custom Factory of UiRouter)
783
+ */
784
+ var UiRouter = class {
785
+ root = $page({
786
+ path: "/",
787
+ component: AlephaMantineProvider_default
788
+ });
757
789
  };
758
790
 
759
791
  //#endregion
@@ -1050,10 +1082,13 @@ const ActionHrefButton = (props) => {
1050
1082
  //#endregion
1051
1083
  //#region ../../src/core/components/buttons/BurgerButton.tsx
1052
1084
  const BurgerButton = (props) => {
1053
- const [opened, setOpened] = useStore("alepha.ui.sidebar.opened");
1085
+ const [sidebar, setSidebar] = useStore(alephaSidebarAtom);
1054
1086
  return /* @__PURE__ */ jsx(Burger, {
1055
- opened,
1056
- onClick: () => setOpened(!opened),
1087
+ opened: sidebar.opened,
1088
+ onClick: () => setSidebar({
1089
+ ...sidebar,
1090
+ opened: !sidebar.opened
1091
+ }),
1057
1092
  hiddenFrom: "sm",
1058
1093
  size: "sm",
1059
1094
  ...props
@@ -1152,14 +1187,27 @@ var LanguageButton_default = LanguageButton;
1152
1187
  //#endregion
1153
1188
  //#region ../../src/core/components/buttons/OmnibarButton.tsx
1154
1189
  const OmnibarButton = (props) => {
1190
+ const os = useOs();
1191
+ const shortcut = os === "macos" || os === "ios" ? "⌘" : "Ctrl";
1192
+ if (props.collapsed) return /* @__PURE__ */ jsx(ActionButton_default, {
1193
+ variant: "subtle",
1194
+ onClick: spotlight.open,
1195
+ radius: "md",
1196
+ icon: /* @__PURE__ */ jsx(IconSearch, { size: 16 }),
1197
+ tooltip: {
1198
+ label: "Search",
1199
+ position: "right"
1200
+ },
1201
+ ...props.actionProps
1202
+ });
1155
1203
  return /* @__PURE__ */ jsx(ActionButton_default, {
1156
1204
  variant: "default",
1157
1205
  onClick: spotlight.open,
1158
1206
  justify: "space-between",
1159
- rightSection: /* @__PURE__ */ jsx(Kbd, {
1207
+ rightSection: /* @__PURE__ */ jsxs(Kbd, {
1160
1208
  visibleFrom: "sm",
1161
1209
  size: "sm",
1162
- children: "⌘+K"
1210
+ children: [/* @__PURE__ */ jsx(ClientOnly, { children: shortcut }), "+K"]
1163
1211
  }),
1164
1212
  radius: "md",
1165
1213
  ...props.actionProps,
@@ -1201,6 +1249,32 @@ const ThemeButton = (props) => {
1201
1249
  };
1202
1250
  var ThemeButton_default = ThemeButton;
1203
1251
 
1252
+ //#endregion
1253
+ //#region ../../src/core/components/buttons/ToggleSidebarButton.tsx
1254
+ const ToggleSidebarButton = (props) => {
1255
+ const [sidebar, setSidebar] = useStore(alephaSidebarAtom);
1256
+ return /* @__PURE__ */ jsx(ActionButton_default, {
1257
+ icon: sidebar.collapsed ? /* @__PURE__ */ jsx(IconLayoutSidebarRightCollapse, {}) : /* @__PURE__ */ jsx(IconLayoutSidebarLeftCollapse, {}),
1258
+ visibleFrom: "sm",
1259
+ variant: "subtle",
1260
+ size: "md",
1261
+ onClick: () => {
1262
+ const expanding = sidebar.collapsed;
1263
+ setSidebar({
1264
+ ...sidebar,
1265
+ collapsed: !sidebar.collapsed,
1266
+ width: expanding ? sidebar.defaultWidth : sidebar.width
1267
+ });
1268
+ },
1269
+ tooltip: {
1270
+ position: "right",
1271
+ label: sidebar.collapsed ? "Show sidebar" : "Hide sidebar"
1272
+ },
1273
+ ...props
1274
+ });
1275
+ };
1276
+ var ToggleSidebarButton_default = ToggleSidebarButton;
1277
+
1204
1278
  //#endregion
1205
1279
  //#region ../../src/core/utils/icons.tsx
1206
1280
  /**
@@ -2449,7 +2523,7 @@ var Control_default = Control;
2449
2523
  * @example
2450
2524
  * ```tsx
2451
2525
  * import { t } from "alepha";
2452
- * import { useForm } from "@alepha/react/form";
2526
+ * import { useForm } from "alepha/react/form";
2453
2527
  * import { TypeForm } from "@alepha/ui";
2454
2528
  *
2455
2529
  * const form = useForm({
@@ -2566,7 +2640,9 @@ var TypeForm_default = TypeForm;
2566
2640
  //#region ../../src/core/components/layout/AppBar.tsx
2567
2641
  const AppBar = (props) => {
2568
2642
  const { items = [] } = props;
2643
+ const router = useRouter();
2569
2644
  const renderItem = (item, index) => {
2645
+ if (item.can && !item.can()) return null;
2570
2646
  if ("type" in item) {
2571
2647
  if (item.type === "burger") return /* @__PURE__ */ jsx(BurgerButton_default, {}, index);
2572
2648
  if (item.type === "dark") return /* @__PURE__ */ jsx(DarkModeButton_default, { ...item.props }, index);
@@ -2574,17 +2650,70 @@ const AppBar = (props) => {
2574
2650
  if (item.type === "lang") return /* @__PURE__ */ jsx(LanguageButton_default, { ...item.props }, index);
2575
2651
  if (item.type === "spacer") return /* @__PURE__ */ jsx(Flex$1, { w: 16 }, index);
2576
2652
  if (item.type === "divider") return /* @__PURE__ */ jsx(Divider, { orientation: "vertical" }, index);
2653
+ if (item.type === "logo") return renderLogo(item, index);
2654
+ if (item.type === "back") return renderBack(item, index);
2577
2655
  }
2578
2656
  if ("element" in item) return item.element;
2579
2657
  return null;
2580
2658
  };
2659
+ const renderLogo = (item, index) => {
2660
+ const { src, text, icon, href, height = 32, width, fontWeight = 700, fontSize = "lg" } = item.props ?? {};
2661
+ const logoContent = src ? /* @__PURE__ */ jsx(Image, {
2662
+ src,
2663
+ h: height,
2664
+ w: width,
2665
+ fit: "contain"
2666
+ }) : icon ? typeof icon === "function" ? /* @__PURE__ */ jsx(icon, {}) : icon : text ? /* @__PURE__ */ jsx(Text$1, {
2667
+ fw: fontWeight,
2668
+ size: fontSize,
2669
+ children: text
2670
+ }) : null;
2671
+ if (href) return /* @__PURE__ */ jsx(Anchor, {
2672
+ component: Link,
2673
+ href,
2674
+ underline: "never",
2675
+ c: "inherit",
2676
+ children: logoContent
2677
+ }, index);
2678
+ return /* @__PURE__ */ jsx(Flex$1, { children: logoContent }, index);
2679
+ };
2680
+ const renderBack = (item, index) => {
2681
+ const { label = "Back", iconOnly = true, href, icon } = item.props ?? {};
2682
+ const renderIcon = () => {
2683
+ if (!icon) return /* @__PURE__ */ jsx(IconArrowLeft, { size: 18 });
2684
+ if (typeof icon === "function") return /* @__PURE__ */ jsx(icon, { size: 18 });
2685
+ return icon;
2686
+ };
2687
+ const iconElement = renderIcon();
2688
+ const handleClick = () => {
2689
+ if (href) router.push(href);
2690
+ else router.back();
2691
+ };
2692
+ if (iconOnly) return /* @__PURE__ */ jsx(ActionButton_default, {
2693
+ icon: iconElement,
2694
+ variant: "subtle",
2695
+ color: "gray",
2696
+ onClick: handleClick,
2697
+ tooltip: {
2698
+ label,
2699
+ position: "bottom"
2700
+ }
2701
+ }, index);
2702
+ return /* @__PURE__ */ jsx(ActionButton_default, {
2703
+ leftSection: iconElement,
2704
+ variant: "subtle",
2705
+ color: "gray",
2706
+ onClick: handleClick,
2707
+ children: label
2708
+ }, index);
2709
+ };
2581
2710
  const leftItems = items.filter((item) => item.position === "left");
2582
2711
  const centerItems = items.filter((item) => item.position === "center");
2583
2712
  const rightItems = items.filter((item) => item.position === "right");
2584
- return /* @__PURE__ */ jsxs(Flex$1, {
2713
+ const content = /* @__PURE__ */ jsxs(Flex$1, {
2585
2714
  h: "100%",
2586
2715
  align: "center",
2587
- px: "md",
2716
+ px: props.container ? 0 : "md",
2588
2717
  justify: "space-between",
2589
2718
  ...props.flexProps,
2590
2719
  children: [
@@ -2613,47 +2742,44 @@ const AppBar = (props) => {
2613
2742
  })
2614
2743
  ]
2615
2744
  });
2745
+ if (props.container) return /* @__PURE__ */ jsx(Container, {
2746
+ h: "100%",
2747
+ ...typeof props.container === "boolean" ? {} : props.container,
2748
+ children: content
2749
+ });
2750
+ return content;
2616
2751
  };
2617
2752
  var AppBar_default = AppBar;
2618
2753
 
2619
- //#endregion
2620
- //#region ../../src/core/components/buttons/ToggleSidebarButton.tsx
2621
- const ToggleSidebarButton = () => {
2622
- const [collapsed, setCollapsed] = useStore("alepha.ui.sidebar.collapsed");
2623
- return /* @__PURE__ */ jsx(Flex$1, { children: /* @__PURE__ */ jsx(ActionButton_default, {
2624
- icon: collapsed ? /* @__PURE__ */ jsx(IconLayoutSidebarRightCollapse, {}) : /* @__PURE__ */ jsx(IconLayoutSidebarLeftCollapse, {}),
2625
- variant: "subtle",
2626
- size: "md",
2627
- onClick: () => setCollapsed(!collapsed),
2628
- tooltip: {
2629
- position: "right",
2630
- label: collapsed ? "Show sidebar" : "Hide sidebar"
2631
- }
2632
- }) });
2633
- };
2634
- var ToggleSidebarButton_default = ToggleSidebarButton;
2635
-
2636
2754
  //#endregion
2637
2755
  //#region ../../src/core/components/layout/Sidebar.tsx
2638
2756
  const Sidebar = (props) => {
2639
2757
  const router = useRouter();
2640
2758
  const { onItemClick } = props;
2759
+ const divider = (key) => {
2760
+ return /* @__PURE__ */ jsx(Flex$1, {
2761
+ h: 1,
2762
+ bg: "var(--alepha-border)",
2763
+ my: "xs",
2764
+ mx: props.collapsed ? 0 : "sm"
2765
+ }, key);
2766
+ };
2641
2767
  const renderNode = (item, key) => {
2642
2768
  if ("type" in item) {
2643
- if (item.type === "spacer") return /* @__PURE__ */ jsx(Flex$1, { h: 16 }, key);
2644
- if (item.type === "divider") return /* @__PURE__ */ jsx(Flex$1, {
2645
- h: 1,
2646
- bg: "var(--alepha-border)",
2647
- my: "md",
2648
- mx: "sm"
2769
+ if (item.type === "spacer") {
2770
+ if (props.collapsed) return null;
2771
+ return /* @__PURE__ */ jsx(Flex$1, { h: 16 }, key);
2772
+ }
2773
+ if (item.type === "divider") return divider(key);
2774
+ if (item.type === "search") return /* @__PURE__ */ jsx(Flex$1, {
2775
+ mb: "xs",
2776
+ children: /* @__PURE__ */ jsx(OmnibarButton_default, { collapsed: props.collapsed })
2649
2777
  }, key);
2650
- if (item.type === "search") return /* @__PURE__ */ jsx(OmnibarButton_default, { collapsed: props.collapsed }, key);
2651
2778
  if (item.type === "toggle") return /* @__PURE__ */ jsx(ToggleSidebarButton_default, {}, key);
2652
2779
  if (item.type === "section") {
2653
- if (props.collapsed) return;
2780
+ if (props.collapsed) return divider(key);
2654
2781
  return /* @__PURE__ */ jsxs(Flex$1, {
2655
2782
  mt: "md",
2656
- mb: "xs",
2657
2783
  align: "center",
2658
2784
  gap: "xs",
2659
2785
  children: [renderIcon(item.icon), /* @__PURE__ */ jsx(Text$1, {
@@ -2662,7 +2788,7 @@ const Sidebar = (props) => {
2662
2788
  tt: "uppercase",
2663
2789
  fw: "bold",
2664
2790
  children: item.label
2665
- }, key)]
2791
+ })]
2666
2792
  }, key);
2667
2793
  }
2668
2794
  }
@@ -2698,13 +2824,13 @@ const Sidebar = (props) => {
2698
2824
  return [];
2699
2825
  };
2700
2826
  const padding = "md";
2701
- const gap = props.items ? props.gap : "xs";
2702
- const menu = useMemo(() => getSidebarNodes(), []);
2827
+ const gap = props.items ? props.gap ?? 2 : "xs";
2828
+ const menu = useMemo(() => getSidebarNodes(), [props.items, props.autoPopulateMenu]);
2703
2829
  return /* @__PURE__ */ jsxs(Flex$1, {
2704
2830
  flex: 1,
2705
2831
  py: padding,
2706
2832
  direction: "column",
2707
- className: "overflow-auto",
2833
+ className: "alepha-sidebar-scroll",
2708
2834
  ...props.flexProps,
2709
2835
  children: [
2710
2836
  /* @__PURE__ */ jsx(Flex$1, {
@@ -2718,7 +2844,7 @@ const Sidebar = (props) => {
2718
2844
  px: padding,
2719
2845
  direction: "column",
2720
2846
  flex: 1,
2721
- className: "overflow-auto",
2847
+ className: "alepha-sidebar-scroll",
2722
2848
  children: menu.filter((it) => !it.position).map((item, index) => renderNode(item, index))
2723
2849
  }),
2724
2850
  /* @__PURE__ */ jsx(Flex$1, {
@@ -2767,6 +2893,7 @@ const SidebarItem = (props) => {
2767
2893
  href: props.item.href,
2768
2894
  target: props.item.target,
2769
2895
  size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
2896
+ tooltip: item.description,
2770
2897
  c: "var(--mantine-color-text)",
2771
2898
  color: "gray",
2772
2899
  variant: "subtle",
@@ -2777,13 +2904,9 @@ const SidebarItem = (props) => {
2777
2904
  w: "100%",
2778
2905
  align: "center",
2779
2906
  gap: "sm",
2780
- children: [renderIcon(item.icon), /* @__PURE__ */ jsxs(Flex$1, {
2907
+ children: [renderIcon(item.icon), /* @__PURE__ */ jsx(Flex$1, {
2781
2908
  direction: "column",
2782
- children: [/* @__PURE__ */ jsx(Flex$1, { children: item.label }), item.description && /* @__PURE__ */ jsx(Text$1, {
2783
- size: "xs",
2784
- c: "dimmed",
2785
- children: item.description
2786
- })]
2909
+ children: /* @__PURE__ */ jsx(Flex$1, { children: item.label })
2787
2910
  })]
2788
2911
  }),
2789
2912
  rightSection: item.children ? /* @__PURE__ */ jsx(Flex$1, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
@@ -2809,31 +2932,15 @@ const SidebarItem = (props) => {
2809
2932
  };
2810
2933
  const SidebarCollapsedItem = (props) => {
2811
2934
  const { item, level } = props;
2812
- const router = useRouter();
2813
- const isActive = useCallback((item) => {
2814
- if (!item.children) return false;
2815
- for (const child of item.children) {
2816
- if (child.href) {
2817
- if (router.isActive(child.href)) return true;
2818
- }
2819
- if (isActive(child)) return true;
2820
- }
2821
- return false;
2822
- }, []);
2823
- const [isOpen, setIsOpen] = useState(isActive(item));
2824
- const handleItemClick = (e) => {
2825
- if (!props.item.target) e.preventDefault();
2826
- if (item.children && item.children.length > 0) setIsOpen(!isOpen);
2827
- else {
2828
- props.onItemClick?.(item);
2829
- item.onClick?.();
2830
- }
2935
+ const handleItemClick = () => {
2936
+ props.onItemClick?.(item);
2937
+ item.onClick?.();
2831
2938
  };
2832
2939
  return /* @__PURE__ */ jsx(ActionButton_default, {
2833
2940
  size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
2834
2941
  variant: "subtle",
2835
2942
  variantActive: "default",
2836
- tooltip: item.children ? void 0 : {
2943
+ tooltip: {
2837
2944
  label: item.label,
2838
2945
  position: "right"
2839
2946
  },
@@ -2842,16 +2949,6 @@ const SidebarCollapsedItem = (props) => {
2842
2949
  icon: renderIcon(item.icon) ?? /* @__PURE__ */ jsx(IconSquareRounded, {}),
2843
2950
  href: props.item.href,
2844
2951
  target: props.item.target,
2845
- menu: item.children ? {
2846
- position: "right",
2847
- on: "hover",
2848
- items: item.children.filter((child) => !child.can || child.can()).map((child) => ({
2849
- label: child.label,
2850
- href: child.href,
2851
- icon: renderIcon(child.icon),
2852
- children: child.children?.filter((c) => !c.can || c.can())
2853
- }))
2854
- } : void 0,
2855
2952
  ...props.item.actionProps
2856
2953
  });
2857
2954
  };
@@ -2860,8 +2957,129 @@ const SidebarCollapsedItem = (props) => {
2860
2957
  //#region ../../src/core/components/layout/AdminShell.tsx
2861
2958
  const AdminShell = (props) => {
2862
2959
  const router = useRouter();
2863
- const [opened, setOpened] = useStore("alepha.ui.sidebar.opened");
2864
- const [collapsed] = useStore("alepha.ui.sidebar.collapsed", props.sidebarProps?.collapsed);
2960
+ const [sidebar, setSidebar] = useStore(alephaSidebarAtom);
2961
+ const { opened, collapsed } = sidebar;
2962
+ useEffect(() => {
2963
+ if (props.sidebarProps?.collapsed !== void 0) setSidebar({
2964
+ ...sidebar,
2965
+ collapsed: props.sidebarProps.collapsed
2966
+ });
2967
+ }, []);
2968
+ const [isResizing, setIsResizing] = useState(false);
2969
+ const [isHovering, setIsHovering] = useState(false);
2970
+ const [collapseEffect, setCollapseEffect] = useState({
2971
+ offset: 0,
2972
+ opacity: 1
2973
+ });
2974
+ const resizeRef = useRef(null);
2975
+ const { collapsedWidth, collapseThreshold, maxWidth, hoverDelay, defaultWidth } = sidebar;
2976
+ const handleResizeStart = useCallback((e) => {
2977
+ if (!props.sidebarResizable) return;
2978
+ e.preventDefault();
2979
+ if (collapsed) {
2980
+ setSidebar({
2981
+ ...sidebar,
2982
+ collapsed: false,
2983
+ width: defaultWidth
2984
+ });
2985
+ setIsResizing(true);
2986
+ resizeRef.current = {
2987
+ startX: e.clientX,
2988
+ startWidth: defaultWidth
2989
+ };
2990
+ } else {
2991
+ setIsResizing(true);
2992
+ resizeRef.current = {
2993
+ startX: e.clientX,
2994
+ startWidth: sidebar.width
2995
+ };
2996
+ }
2997
+ }, [
2998
+ props.sidebarResizable,
2999
+ collapsed,
3000
+ sidebar,
3001
+ setSidebar,
3002
+ defaultWidth
3003
+ ]);
3004
+ useEffect(() => {
3005
+ if (!isResizing) return;
3006
+ const handleMouseMove = (e) => {
3007
+ if (!resizeRef.current) return;
3008
+ const delta = e.clientX - resizeRef.current.startX;
3009
+ const rawWidth = resizeRef.current.startWidth + delta;
3010
+ const newWidth = Math.min(Math.max(rawWidth, collapsedWidth), maxWidth);
3011
+ if (rawWidth < collapseThreshold) {
3012
+ const progress = Math.max(0, (collapseThreshold - rawWidth) / collapseThreshold);
3013
+ setCollapseEffect({
3014
+ offset: -progress * collapsedWidth,
3015
+ opacity: 1 - progress * .7
3016
+ });
3017
+ setSidebar({
3018
+ ...sidebar,
3019
+ width: collapseThreshold,
3020
+ collapsed: false
3021
+ });
3022
+ } else {
3023
+ setCollapseEffect({
3024
+ offset: 0,
3025
+ opacity: 1
3026
+ });
3027
+ setSidebar({
3028
+ ...sidebar,
3029
+ width: newWidth,
3030
+ collapsed: false
3031
+ });
3032
+ }
3033
+ };
3034
+ const handleMouseUp = () => {
3035
+ if (collapseEffect.offset < 0) setSidebar({
3036
+ ...sidebar,
3037
+ collapsed: true
3038
+ });
3039
+ setCollapseEffect({
3040
+ offset: 0,
3041
+ opacity: 1
3042
+ });
3043
+ setIsResizing(false);
3044
+ resizeRef.current = null;
3045
+ };
3046
+ document.addEventListener("mousemove", handleMouseMove);
3047
+ document.addEventListener("mouseup", handleMouseUp);
3048
+ return () => {
3049
+ document.removeEventListener("mousemove", handleMouseMove);
3050
+ document.removeEventListener("mouseup", handleMouseUp);
3051
+ };
3052
+ }, [
3053
+ isResizing,
3054
+ sidebar,
3055
+ setSidebar,
3056
+ collapsedWidth,
3057
+ maxWidth,
3058
+ collapseThreshold,
3059
+ collapseEffect.offset
3060
+ ]);
3061
+ const hoverTimeoutRef = useRef(null);
3062
+ const handleNavbarMouseEnter = useCallback(() => {
3063
+ if (collapsed) hoverTimeoutRef.current = setTimeout(() => {
3064
+ setIsHovering(true);
3065
+ }, hoverDelay);
3066
+ }, [collapsed, hoverDelay]);
3067
+ const handleNavbarMouseLeave = useCallback(() => {
3068
+ if (hoverTimeoutRef.current) {
3069
+ clearTimeout(hoverTimeoutRef.current);
3070
+ hoverTimeoutRef.current = null;
3071
+ }
3072
+ setIsHovering(false);
3073
+ }, []);
3074
+ useEffect(() => {
3075
+ if (collapsed) {
3076
+ setIsHovering(false);
3077
+ if (hoverTimeoutRef.current) {
3078
+ clearTimeout(hoverTimeoutRef.current);
3079
+ hoverTimeoutRef.current = null;
3080
+ }
3081
+ }
3082
+ }, [collapsed]);
2865
3083
  const shouldShowSidebar = () => {
2866
3084
  if (props.noSidebarWhen?.paths) {
2867
3085
  for (const path of props.noSidebarWhen.paths) if (router.isActive(path, { startWith: true })) return false;
@@ -2874,25 +3092,35 @@ const AdminShell = (props) => {
2874
3092
  setShowSidebar(shouldShowSidebar());
2875
3093
  },
2876
3094
  "react:transition:begin": () => {
2877
- setOpened(false);
3095
+ setSidebar({
3096
+ ...sidebar,
3097
+ opened: false
3098
+ });
2878
3099
  }
2879
- }, []);
3100
+ }, [sidebar]);
2880
3101
  const defaultAppBarItems = [{
2881
3102
  position: "left",
2882
3103
  type: "burger"
2883
3104
  }];
3105
+ const appBarProps = { ...props.appBarProps };
3106
+ appBarProps.container ??= props.container;
2884
3107
  const hasSidebar = showSidebar && props.sidebarProps !== void 0;
2885
3108
  const hasAppBar = hasSidebar || props.appBarProps || props.header;
2886
3109
  const headerHeight = hasAppBar ? 60 : 0;
2887
3110
  const footerHeight = props.footer ? 24 : 0;
2888
- const sidebarWidth = hasSidebar ? collapsed ? 78 : 300 : 0;
3111
+ const expandedWidth = Math.max(sidebar.width, collapsedWidth);
3112
+ const isExpandedByHover = collapsed && isHovering;
3113
+ const effectiveCollapsed = collapsed && !isHovering;
3114
+ const hoverWidth = Math.max(defaultWidth, collapsedWidth);
3115
+ const sidebarWidth = hasSidebar ? effectiveCollapsed || isExpandedByHover ? collapsedWidth : expandedWidth : 0;
3116
+ const canResize = props.sidebarResizable && !collapsed;
2889
3117
  return /* @__PURE__ */ jsxs(AppShell, {
2890
3118
  w: "100%",
2891
3119
  flex: 1,
2892
3120
  padding: "md",
2893
3121
  header: hasAppBar ? { height: 60 } : void 0,
2894
3122
  navbar: hasSidebar ? {
2895
- width: collapsed ? { base: 78 } : { base: 300 },
3123
+ width: effectiveCollapsed || isExpandedByHover ? { base: collapsedWidth } : { base: expandedWidth },
2896
3124
  breakpoint: "sm",
2897
3125
  collapsed: { mobile: !opened }
2898
3126
  } : void 0,
@@ -2904,16 +3132,41 @@ const AdminShell = (props) => {
2904
3132
  ...props.appShellHeaderProps,
2905
3133
  children: props.header ?? /* @__PURE__ */ jsx(AppBar_default, {
2906
3134
  items: defaultAppBarItems,
2907
- ...props.appBarProps
3135
+ ...appBarProps
2908
3136
  })
2909
3137
  }),
2910
- hasSidebar && /* @__PURE__ */ jsx(AppShell.Navbar, {
3138
+ hasSidebar && /* @__PURE__ */ jsxs(AppShell.Navbar, {
2911
3139
  bg: ui.colors.surface,
3140
+ className: "alepha-sidebar-navbar",
3141
+ "data-resizing": isResizing,
3142
+ "data-hover-expanded": isExpandedByHover,
3143
+ onMouseEnter: handleNavbarMouseEnter,
3144
+ onMouseLeave: handleNavbarMouseLeave,
3145
+ style: {
3146
+ transform: collapseEffect.offset ? `translateX(${collapseEffect.offset}px)` : void 0,
3147
+ opacity: collapseEffect.opacity,
3148
+ ...isExpandedByHover && {
3149
+ width: hoverWidth,
3150
+ zIndex: 200,
3151
+ boxShadow: "var(--mantine-shadow-xl)"
3152
+ }
3153
+ },
2912
3154
  ...props.appShellNavbarProps,
2913
- children: /* @__PURE__ */ jsx(Sidebar, {
2914
- collapsed,
2915
- ...props.sidebarProps ?? {}
2916
- })
3155
+ children: [/* @__PURE__ */ jsx(Sidebar, {
3156
+ ...props.sidebarProps ?? {},
3157
+ collapsed: effectiveCollapsed
3158
+ }), (canResize || isExpandedByHover) && /* @__PURE__ */ jsx(Flex$1, {
3159
+ pos: "absolute",
3160
+ right: -6,
3161
+ top: 0,
3162
+ bottom: 0,
3163
+ w: 12,
3164
+ style: {
3165
+ cursor: "col-resize",
3166
+ userSelect: "none"
3167
+ },
3168
+ onMouseDown: handleResizeStart
3169
+ })]
2917
3170
  }),
2918
3171
  /* @__PURE__ */ jsx(AppShell.Main, {
2919
3172
  pl: sidebarWidth,
@@ -2923,8 +3176,17 @@ const AdminShell = (props) => {
2923
3176
  display: "flex",
2924
3177
  flex: 1,
2925
3178
  style: { flexDirection: "column" },
3179
+ className: "alepha-sidebar-main",
3180
+ "data-resizing": isResizing,
2926
3181
  ...props.appShellMainProps,
2927
- children: props.children ?? /* @__PURE__ */ jsx(NestedView, {})
3182
+ children: props.container ? /* @__PURE__ */ jsx(Container, {
3183
+ w: "100%",
3184
+ flex: 1,
3185
+ display: "flex",
3186
+ style: { flexDirection: "column" },
3187
+ ...typeof props.container === "boolean" ? {} : props.container,
3188
+ children: props.children ?? /* @__PURE__ */ jsx(NestedView, {})
3189
+ }) : props.children ?? /* @__PURE__ */ jsx(NestedView, {})
2928
3190
  }),
2929
3191
  props.footer && /* @__PURE__ */ jsx(AppShell.Footer, {
2930
3192
  bg: ui.colors.surface,
@@ -3618,7 +3880,25 @@ const useDialog = () => {
3618
3880
  //#endregion
3619
3881
  //#region ../../src/core/index.ts
3620
3882
  /**
3621
- * Mantine
3883
+ * | type | quality | stability |
3884
+ * |------|---------|-----------|
3885
+ * | frontend | rare | experimental |
3886
+ *
3887
+ * Core UI components based on Mantine UI v8.
3888
+ *
3889
+ * **Features:**
3890
+ * - Mantine integration with theme support
3891
+ * - ActionButton, BurgerButton, ClipboardButton, DarkModeButton, LanguageButton, ThemeButton
3892
+ * - AlertDialog, ConfirmDialog, PromptDialog
3893
+ * - Form controls: Control, ControlArray, ControlDate, ControlNumber, ControlObject, ControlSelect, ControlQueryBuilder
3894
+ * - TypeForm for automatic form generation from TypeBox schemas
3895
+ * - AdminShell layout component
3896
+ * - AppBar with configurable elements
3897
+ * - Sidebar navigation with sections and menu items
3898
+ * - Omnibar for command palette / search
3899
+ * - DataTable with filtering, sorting, pagination
3900
+ * - Toast notifications
3901
+ * - Theme system with dark mode
3622
3902
  *
3623
3903
  * @module alepha.ui
3624
3904
  */
@@ -3628,7 +3908,7 @@ const AlephaUI = $module({
3628
3908
  DialogService,
3629
3909
  ToastService,
3630
3910
  ThemeProvider,
3631
- RootRouter
3911
+ UiRouter
3632
3912
  ],
3633
3913
  register: (alepha) => {
3634
3914
  alepha.with(AlephaReactI18n);
@@ -3639,7 +3919,15 @@ const AlephaUI = $module({
3639
3919
  alepha.with(ToastService);
3640
3920
  }
3641
3921
  });
3922
+ /**
3923
+ * Convenience function to configure and inject the UiRouter.
3924
+ */
3925
+ const $ui = (options = {}) => {
3926
+ const { alepha } = $context();
3927
+ if (options.themes) alepha.store.set(alephaThemeListAtom, options.themes);
3928
+ return alepha.inject(UiRouter);
3929
+ };
3642
3930
 
3643
3931
  //#endregion
3644
- export { ActionButton_default as ActionButton, AdminShell_default as AdminShell, AlephaMantineProvider_default as AlephaMantineProvider, AlephaUI, AlertDialog_default as AlertDialog, AppBar_default as AppBar, BurgerButton_default as BurgerButton, ClipboardButton_default as ClipboardButton, ConfirmDialog_default as ConfirmDialog, Control_default as Control, ControlArray_default as ControlArray, ControlDate_default as ControlDate, ControlNumber_default as ControlNumber, ControlObject_default as ControlObject, ControlQueryBuilder_default as ControlQueryBuilder, ControlSelect_default as ControlSelect, DarkModeButton_default as DarkModeButton, DataTable_default as DataTable, DialogService, Flex, LanguageButton_default as LanguageButton, OPERATOR_INFO, Omnibar_default as Omnibar, OmnibarButton_default as OmnibarButton, PromptDialog_default as PromptDialog, RootRouter, Sidebar, Text, ThemeButton_default as ThemeButton, ThemeProvider, ToastService, TypeForm_default as TypeForm, alephaThemeAtom, alephaThemeListAtom, capitalize, defaultTheme, extractSchemaFields, getDefaultIcon, getOperatorsForField, midnightTheme, prettyName, ui, useDialog, useToast };
3932
+ export { $ui, ActionButton_default as ActionButton, AdminShell_default as AdminShell, AlephaMantineProvider_default as AlephaMantineProvider, AlephaUI, AlertDialog_default as AlertDialog, AppBar_default as AppBar, BurgerButton_default as BurgerButton, ClipboardButton_default as ClipboardButton, ConfirmDialog_default as ConfirmDialog, Control_default as Control, ControlArray_default as ControlArray, ControlDate_default as ControlDate, ControlNumber_default as ControlNumber, ControlObject_default as ControlObject, ControlQueryBuilder_default as ControlQueryBuilder, ControlSelect_default as ControlSelect, DarkModeButton_default as DarkModeButton, DataTable_default as DataTable, DialogService, Flex, LanguageButton_default as LanguageButton, OPERATOR_INFO, Omnibar_default as Omnibar, OmnibarButton_default as OmnibarButton, PromptDialog_default as PromptDialog, Sidebar, Text, ThemeButton_default as ThemeButton, ThemeProvider, ToastService, ToggleSidebarButton_default as ToggleSidebarButton, TypeForm_default as TypeForm, UiRouter, alephaSidebarAtom, alephaThemeAtom, alephaThemeListAtom, capitalize, defaultTheme, extractSchemaFields, getDefaultIcon, getOperatorsForField, midnightTheme, prettyName, ui, useDialog, useToast };
3645
3933
  //# sourceMappingURL=index.js.map