@alepha/ui 0.18.1 → 0.18.2

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 (187) hide show
  1. package/dist/admin/{AdminApiKeys-C-6_Q-lH.js → AdminApiKeys-BJhIwfD6.js} +17 -38
  2. package/dist/admin/AdminApiKeys-BJhIwfD6.js.map +1 -0
  3. package/dist/admin/{AdminAudits-Bgbf04hO.js → AdminAudits-DzD_4cDt.js} +23 -19
  4. package/dist/admin/AdminAudits-DzD_4cDt.js.map +1 -0
  5. package/dist/admin/AdminDashboard-C92tIc6x.js +67 -0
  6. package/dist/admin/AdminDashboard-C92tIc6x.js.map +1 -0
  7. package/dist/admin/{AdminFiles-B9a7G3cY.js → AdminFiles-DLpfhBkf.js} +3 -7
  8. package/dist/admin/AdminFiles-DLpfhBkf.js.map +1 -0
  9. package/dist/admin/{AdminJobDashboard-DaTwf5OY.js → AdminJobDashboard-KIOkeMgE.js} +2 -2
  10. package/dist/admin/{AdminJobDashboard-DaTwf5OY.js.map → AdminJobDashboard-KIOkeMgE.js.map} +1 -1
  11. package/dist/admin/{AdminJobExecutions-B9cek5dl.js → AdminJobExecutions-D0Yo_PU0.js} +24 -36
  12. package/dist/admin/AdminJobExecutions-D0Yo_PU0.js.map +1 -0
  13. package/dist/admin/{AdminJobRegistry-DFgV3oqx.js → AdminJobRegistry-PFajqaGK.js} +10 -18
  14. package/dist/admin/AdminJobRegistry-PFajqaGK.js.map +1 -0
  15. package/dist/admin/AdminLayout-B1DXZHDn.js +61 -0
  16. package/dist/admin/AdminLayout-B1DXZHDn.js.map +1 -0
  17. package/dist/admin/{AdminParameters-DHw9ATgl.js → AdminParameters-BspPeqp_.js} +2 -2
  18. package/dist/admin/{AdminParameters-DHw9ATgl.js.map → AdminParameters-BspPeqp_.js.map} +1 -1
  19. package/dist/admin/{AdminSessions-BhGJPI3z.js → AdminSessions-BnH5CZQl.js} +48 -53
  20. package/dist/admin/AdminSessions-BnH5CZQl.js.map +1 -0
  21. package/dist/admin/{AdminUserLayout-BdC4Te8m.js → AdminUserLayout-DUbC6-BI.js} +2 -2
  22. package/dist/admin/{AdminUserLayout-BdC4Te8m.js.map → AdminUserLayout-DUbC6-BI.js.map} +1 -1
  23. package/dist/admin/{AdminUserProfile-DAt23fqY.js → AdminUserProfile-DuTUnjdG.js} +3 -3
  24. package/dist/admin/{AdminUserProfile-DAt23fqY.js.map → AdminUserProfile-DuTUnjdG.js.map} +1 -1
  25. package/dist/admin/{AdminUserSessions-1uzcx02z.js → AdminUserSessions-DvZdAGpL.js} +33 -35
  26. package/dist/admin/AdminUserSessions-DvZdAGpL.js.map +1 -0
  27. package/dist/admin/AdminUsers-CR9z0g_5.js +206 -0
  28. package/dist/admin/AdminUsers-CR9z0g_5.js.map +1 -0
  29. package/dist/admin/{AuthLayout-DFJvCvzw.js → AuthLayout-DsUfp9RG.js} +2 -2
  30. package/dist/admin/{AuthLayout-DFJvCvzw.js.map → AuthLayout-DsUfp9RG.js.map} +1 -1
  31. package/dist/admin/{IconGoogle-CSQLPYwX.js → IconGoogle-Ch1m3Uzl.js} +1 -1
  32. package/dist/admin/{IconGoogle-CSQLPYwX.js.map → IconGoogle-Ch1m3Uzl.js.map} +1 -1
  33. package/dist/admin/{Login-BGheURrg.js → Login-DHbYJKwg.js} +3 -3
  34. package/dist/{auth/Login-Denw_UGy.js.map → admin/Login-DHbYJKwg.js.map} +1 -1
  35. package/dist/{auth/Profile-BMX_Ar_s.js → admin/Profile-B2EcIDB9.js} +2 -2
  36. package/dist/{auth/Profile-BMX_Ar_s.js.map → admin/Profile-B2EcIDB9.js.map} +1 -1
  37. package/dist/admin/{Register-Cs10l8vX.js → Register-Z3fxRbUF.js} +3 -3
  38. package/dist/{demo/Register-a70LPgs2.js.map → admin/Register-Z3fxRbUF.js.map} +1 -1
  39. package/dist/admin/{ResetPassword-BwDdfkGH.js → ResetPassword-_Y1qTTKh.js} +2 -2
  40. package/dist/admin/{ResetPassword-BwDdfkGH.js.map → ResetPassword-_Y1qTTKh.js.map} +1 -1
  41. package/dist/admin/{VerifyEmail-DfXHAiQl.js → VerifyEmail-Bg22bwcC.js} +2 -2
  42. package/dist/admin/{VerifyEmail-DfXHAiQl.js.map → VerifyEmail-Bg22bwcC.js.map} +1 -1
  43. package/dist/admin/{core-2xoLiT0o.js → core-BVO_TQxb.js} +1474 -233
  44. package/dist/admin/core-BVO_TQxb.js.map +1 -0
  45. package/dist/admin/index.d.ts +29 -4
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +448 -69
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/auth/{AuthLayout-CAE1pX9s.js → AuthLayout-C161NeF6.js} +2 -2
  50. package/dist/auth/{AuthLayout-CAE1pX9s.js.map → AuthLayout-C161NeF6.js.map} +1 -1
  51. package/dist/auth/{Login-Denw_UGy.js → Login-C7jIqf00.js} +2 -2
  52. package/dist/{admin/Login-BGheURrg.js.map → auth/Login-C7jIqf00.js.map} +1 -1
  53. package/dist/{admin/Profile-B-c9pCPf.js → auth/Profile-BMpXJ0oi.js} +2 -2
  54. package/dist/{demo/Profile-CWqti7FB.js.map → auth/Profile-BMpXJ0oi.js.map} +1 -1
  55. package/dist/auth/{Register-6hi_cpfF.js → Register-2gx8qll-.js} +2 -2
  56. package/dist/auth/{Register-6hi_cpfF.js.map → Register-2gx8qll-.js.map} +1 -1
  57. package/dist/{demo/ResetPassword-DWN0lzr5.js → auth/ResetPassword-DBxt9hKk.js} +2 -2
  58. package/dist/auth/{ResetPassword-CqfTk1FI.js.map → ResetPassword-DBxt9hKk.js.map} +1 -1
  59. package/dist/{demo/VerifyEmail-DZWL72K4.js → auth/VerifyEmail-Z80Ubajk.js} +2 -2
  60. package/dist/auth/{VerifyEmail-nWiSTMjF.js.map → VerifyEmail-Z80Ubajk.js.map} +1 -1
  61. package/dist/auth/{core-niW0sFLv.js → core-DyfeVr5c.js} +1002 -38
  62. package/dist/auth/core-DyfeVr5c.js.map +1 -0
  63. package/dist/auth/index.d.ts +12 -1
  64. package/dist/auth/index.d.ts.map +1 -1
  65. package/dist/auth/index.js +12 -13
  66. package/dist/auth/index.js.map +1 -1
  67. package/dist/core/index.d.ts +95 -14
  68. package/dist/core/index.d.ts.map +1 -1
  69. package/dist/core/index.js +1473 -232
  70. package/dist/core/index.js.map +1 -1
  71. package/dist/demo/{AuthLayout-jLa0aKsI.js → AuthLayout-DN-ClJQk.js} +2 -2
  72. package/dist/demo/{AuthLayout-jLa0aKsI.js.map → AuthLayout-DN-ClJQk.js.map} +1 -1
  73. package/dist/demo/{DemoButton-BmaWZVwf.js → DemoButton-CGUyR9eM.js} +3 -3
  74. package/dist/demo/{DemoButton-BmaWZVwf.js.map → DemoButton-CGUyR9eM.js.map} +1 -1
  75. package/dist/demo/{DemoDataTable-Z9xyV221.js → DemoDataTable-QFG-xXSx.js} +15 -19
  76. package/dist/demo/DemoDataTable-QFG-xXSx.js.map +1 -0
  77. package/dist/demo/{DemoDialog-4ItHLf9t.js → DemoDialog-DW8QEvD1.js} +2 -2
  78. package/dist/demo/{DemoDialog-4ItHLf9t.js.map → DemoDialog-DW8QEvD1.js.map} +1 -1
  79. package/dist/demo/{DemoFlex-EtVq8QfX.js → DemoFlex-CAhLUanT.js} +3 -3
  80. package/dist/demo/{DemoFlex-EtVq8QfX.js.map → DemoFlex-CAhLUanT.js.map} +1 -1
  81. package/dist/demo/{DemoHeading-BS-vGfkI.js → DemoHeading-yIFmNjHB.js} +3 -3
  82. package/dist/demo/{DemoHeading-BS-vGfkI.js.map → DemoHeading-yIFmNjHB.js.map} +1 -1
  83. package/dist/demo/{DemoHome-Clbn8AmS.js → DemoHome-BSGuBHus.js} +2 -2
  84. package/dist/demo/{DemoHome-Clbn8AmS.js.map → DemoHome-BSGuBHus.js.map} +1 -1
  85. package/dist/demo/{DemoJsonViewer-DkIX_ky2.js → DemoJsonViewer-DsA2IpgV.js} +3 -3
  86. package/dist/demo/{DemoJsonViewer-DkIX_ky2.js.map → DemoJsonViewer-DsA2IpgV.js.map} +1 -1
  87. package/dist/demo/{DemoLayout-C56xb5EE.js → DemoLayout-Cy6xjn6P.js} +2 -2
  88. package/dist/demo/{DemoLayout-C56xb5EE.js.map → DemoLayout-Cy6xjn6P.js.map} +1 -1
  89. package/dist/demo/{DemoLogin-BZwpicOS.js → DemoLogin-vqxgTu4P.js} +8 -8
  90. package/dist/demo/{DemoLogin-BZwpicOS.js.map → DemoLogin-vqxgTu4P.js.map} +1 -1
  91. package/dist/demo/{DemoRegister-C7_qc4MJ.js → DemoRegister-YHPvPg77.js} +8 -8
  92. package/dist/demo/{DemoRegister-C7_qc4MJ.js.map → DemoRegister-YHPvPg77.js.map} +1 -1
  93. package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js → DemoResetPassword-mOW18Zlm.js} +8 -8
  94. package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js.map → DemoResetPassword-mOW18Zlm.js.map} +1 -1
  95. package/dist/demo/{DemoSidebar-CcBo4ltC.js → DemoSidebar-od7aLjP_.js} +3 -3
  96. package/dist/demo/{DemoSidebar-CcBo4ltC.js.map → DemoSidebar-od7aLjP_.js.map} +1 -1
  97. package/dist/demo/{DemoText-CzXuUn3g.js → DemoText-DU3JeRS0.js} +3 -3
  98. package/dist/demo/{DemoText-CzXuUn3g.js.map → DemoText-DU3JeRS0.js.map} +1 -1
  99. package/dist/demo/{DemoToast-BgHDhWrX.js → DemoToast-CUJEiPRa.js} +2 -2
  100. package/dist/demo/{DemoToast-BgHDhWrX.js.map → DemoToast-CUJEiPRa.js.map} +1 -1
  101. package/dist/demo/{DemoTypeForm-DDzWoMSV.js → DemoTypeForm-C1dNkahD.js} +3 -3
  102. package/dist/demo/{DemoTypeForm-DDzWoMSV.js.map → DemoTypeForm-C1dNkahD.js.map} +1 -1
  103. package/dist/demo/{DemoVerifyEmail-C_Irdnov.js → DemoVerifyEmail-D9EcXZ38.js} +8 -8
  104. package/dist/demo/{DemoVerifyEmail-C_Irdnov.js.map → DemoVerifyEmail-D9EcXZ38.js.map} +1 -1
  105. package/dist/demo/{Login-hSOU3jZc.js → Login-CoYf_P_F.js} +2 -2
  106. package/dist/demo/{Login-hSOU3jZc.js.map → Login-CoYf_P_F.js.map} +1 -1
  107. package/dist/demo/{Profile-CWqti7FB.js → Profile-BE_Y3co2.js} +2 -2
  108. package/dist/{admin/Profile-B-c9pCPf.js.map → demo/Profile-BE_Y3co2.js.map} +1 -1
  109. package/dist/demo/{Register-a70LPgs2.js → Register-fXHmBpr3.js} +2 -2
  110. package/dist/{admin/Register-Cs10l8vX.js.map → demo/Register-fXHmBpr3.js.map} +1 -1
  111. package/dist/{auth/ResetPassword-CqfTk1FI.js → demo/ResetPassword-CAPj8MO3.js} +2 -2
  112. package/dist/demo/{ResetPassword-DWN0lzr5.js.map → ResetPassword-CAPj8MO3.js.map} +1 -1
  113. package/dist/demo/{Showcase-Dq3MISpd.js → Showcase-BtEU0pY9.js} +2 -2
  114. package/dist/demo/{Showcase-Dq3MISpd.js.map → Showcase-BtEU0pY9.js.map} +1 -1
  115. package/dist/{auth/VerifyEmail-nWiSTMjF.js → demo/VerifyEmail-DFmdCdYs.js} +2 -2
  116. package/dist/demo/{VerifyEmail-DZWL72K4.js.map → VerifyEmail-DFmdCdYs.js.map} +1 -1
  117. package/dist/demo/{auth-d6n3xbug.js → auth-Djd7SKiw.js} +8 -8
  118. package/dist/demo/{auth-d6n3xbug.js.map → auth-Djd7SKiw.js.map} +1 -1
  119. package/dist/demo/{core-RCUw1Q-a.js → core-B7LNjM78.js} +1484 -226
  120. package/dist/demo/core-B7LNjM78.js.map +1 -0
  121. package/dist/demo/index.js +17 -17
  122. package/package.json +3 -3
  123. package/src/admin/{AdminRouter.ts → AdminRouter.tsx} +128 -19
  124. package/src/admin/components/AdminDashboard.tsx +52 -0
  125. package/src/admin/components/AdminLayout.tsx +32 -40
  126. package/src/admin/components/audits/AdminAudits.tsx +22 -16
  127. package/src/admin/components/files/AdminFiles.tsx +1 -6
  128. package/src/admin/components/jobs/AdminJobExecutions.tsx +33 -39
  129. package/src/admin/components/jobs/AdminJobRegistry.tsx +9 -18
  130. package/src/admin/components/keys/AdminApiKeys.tsx +23 -41
  131. package/src/admin/components/sessions/AdminSessions.tsx +71 -71
  132. package/src/admin/components/users/AdminUserSessions.tsx +33 -31
  133. package/src/admin/components/users/AdminUsers.tsx +184 -72
  134. package/src/admin/index.ts +2 -2
  135. package/src/admin/primitives/$uiAdmin.ts +1 -1
  136. package/src/auth/components/buttons/UserButton.tsx +1 -3
  137. package/src/core/atoms/alephaSidebarAtom.ts +1 -1
  138. package/src/core/atoms/alephaThemeListAtom.ts +14 -1
  139. package/src/core/atoms/alephaThemeOverridesAtom.ts +17 -0
  140. package/src/core/atoms/themes/editorial.ts +184 -0
  141. package/src/core/atoms/themes/monochrome.ts +197 -0
  142. package/src/core/atoms/themes/rosePine.ts +208 -0
  143. package/src/core/atoms/themes/softBrutalism.ts +221 -0
  144. package/src/core/atoms/themes/terminal.ts +186 -0
  145. package/src/core/components/Flex.tsx +91 -1
  146. package/src/core/components/Text.tsx +1 -1
  147. package/src/core/components/buttons/ActionButton.tsx +15 -19
  148. package/src/core/components/buttons/DarkModeButton.tsx +3 -3
  149. package/src/core/components/buttons/LanguageButton.tsx +1 -1
  150. package/src/core/components/buttons/OmnibarButton.tsx +1 -2
  151. package/src/core/components/buttons/ThemeButton.tsx +40 -11
  152. package/src/core/components/buttons/ThemeExpertModal.tsx +184 -0
  153. package/src/core/components/buttons/ToggleSidebarButton.tsx +1 -2
  154. package/src/core/components/layout/AppBar.tsx +10 -0
  155. package/src/core/components/layout/DashboardShell.tsx +10 -7
  156. package/src/core/components/layout/Sidebar.tsx +60 -52
  157. package/src/core/constants/ui.ts +5 -5
  158. package/src/core/hooks/useTheme.ts +26 -3
  159. package/src/core/index.ts +6 -1
  160. package/src/core/interfaces/AlephaTheme.ts +2 -0
  161. package/src/core/providers/ThemeProvider.ts +108 -8
  162. package/src/core/services/DialogService.tsx +24 -3
  163. package/src/core/styles.css +26 -23
  164. package/src/core/table/components/DataTable.tsx +167 -137
  165. package/src/core/table/components/DataTableFilters.tsx +1 -6
  166. package/src/core/table/components/DataTablePagination.tsx +51 -28
  167. package/src/core/table/components/DataTableToolbar.tsx +9 -4
  168. package/src/core/table/index.ts +1 -0
  169. package/src/core/table/interfaces/types.ts +13 -9
  170. package/src/demo/components/core/DemoDataTable.tsx +15 -19
  171. package/dist/admin/AdminApiKeys-C-6_Q-lH.js.map +0 -1
  172. package/dist/admin/AdminAudits-Bgbf04hO.js.map +0 -1
  173. package/dist/admin/AdminFiles-B9a7G3cY.js.map +0 -1
  174. package/dist/admin/AdminJobExecutions-B9cek5dl.js.map +0 -1
  175. package/dist/admin/AdminJobRegistry-DFgV3oqx.js.map +0 -1
  176. package/dist/admin/AdminLayout-DHsvWxVB.js +0 -70
  177. package/dist/admin/AdminLayout-DHsvWxVB.js.map +0 -1
  178. package/dist/admin/AdminSessions-BhGJPI3z.js.map +0 -1
  179. package/dist/admin/AdminUserSessions-1uzcx02z.js.map +0 -1
  180. package/dist/admin/AdminUsers-C85c3eiQ.js +0 -121
  181. package/dist/admin/AdminUsers-C85c3eiQ.js.map +0 -1
  182. package/dist/admin/auth-Dr0Cf8I7.js +0 -319
  183. package/dist/admin/auth-Dr0Cf8I7.js.map +0 -1
  184. package/dist/admin/core-2xoLiT0o.js.map +0 -1
  185. package/dist/auth/core-niW0sFLv.js.map +0 -1
  186. package/dist/demo/DemoDataTable-Z9xyV221.js.map +0 -1
  187. package/dist/demo/core-RCUw1Q-a.js.map +0 -1
@@ -1,14 +1,14 @@
1
1
  import { $atom, $context, $inject, $module, Alepha, AlephaError, TypeBoxError, t } from "alepha";
2
2
  import { AlephaReactForm, FormValidationError, useForm, useFormState } from "alepha/react/form";
3
- import { $head, AlephaReactHead } from "alepha/react/head";
3
+ import { $head, AlephaReactHead, BrowserHeadProvider } from "alepha/react/head";
4
4
  import { AlephaReactI18n, useI18n } from "alepha/react/i18n";
5
5
  import { $cookie } from "alepha/server/cookies";
6
+ import { ActionIcon, Anchor, AppShell, Autocomplete, Badge, Burger, Button, Card, Checkbox, ColorInput, ColorSchemeScript, ColorSwatch, Container as Container$1, CopyButton, Divider, Drawer, Fieldset, FileInput, Flex as Flex$1, Grid, Image, Input, Kbd, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, Paper, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, SimpleGrid, Slider, Switch, Table, Tabs, TagsInput, Text as Text$1, TextInput, Textarea, Tooltip, Tree, UnstyledButton, getTreeExpandedState, useMantineColorScheme, useMantineTheme, useTree } from "@mantine/core";
6
7
  import { ModalsProvider, modals } from "@mantine/modals";
7
- import { ActionIcon, Anchor, AppShell, Autocomplete, Badge, Burger, Button, Card, Checkbox, ColorInput, ColorSchemeScript, Container as Container$1, CopyButton, Divider, Drawer, Fieldset, FileInput, Flex as Flex$1, Grid, Image, Input, Kbd, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, Paper, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, Slider, Switch, Table, Tabs, TagsInput, Text as Text$1, TextInput, Textarea, ThemeIcon, Tooltip, Tree, UnstyledButton, getTreeExpandedState, useMantineColorScheme, useMantineTheme, useTree } from "@mantine/core";
8
8
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
9
9
  import { Children, Fragment as Fragment$1, createElement, forwardRef, isValidElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
10
10
  import { Notifications, notifications } from "@mantine/notifications";
11
- import { IconAlertTriangle, IconArrowDown, IconArrowLeft, IconArrowUp, IconArrowsSort, IconAt, IconCalendar, IconCheck, IconChevronDown, IconChevronRight, IconClipboard, IconClock, IconColorPicker, IconColumns, IconCopy, IconDownload, 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";
11
+ import { IconAlertTriangle, IconArrowDown, IconArrowLeft, IconArrowUp, IconArrowsSort, IconAt, IconCalendar, IconCheck, IconChevronDown, IconChevronRight, IconClipboard, IconClock, IconColorPicker, IconColumns, IconCopy, IconDotsVertical, IconDownload, 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";
12
12
  import { $page, Link, NestedView, useActive, useRouter, useRouterState } from "alepha/react/router";
13
13
  import { NavigationProgress, nprogress } from "@mantine/nprogress";
14
14
  import { ClientOnly, useAction, useAlepha, useEvents, useInject, useStore } from "alepha/react";
@@ -32,7 +32,7 @@ const alephaSidebarAtom = $atom({
32
32
  closed: true,
33
33
  collapsed: false,
34
34
  expandedWidth: 300,
35
- collapsedWidth: 78
35
+ collapsedWidth: 72
36
36
  }
37
37
  });
38
38
 
@@ -44,6 +44,20 @@ const alephaThemeAtom = $atom({
44
44
  default: { index: 0 }
45
45
  });
46
46
 
47
+ //#endregion
48
+ //#region ../../src/core/atoms/alephaThemeOverridesAtom.ts
49
+ const alephaThemeOverridesAtom = $atom({
50
+ name: "alepha.ui.themeOverrides",
51
+ schema: t.object({
52
+ primaryColor: t.optional(t.text()),
53
+ radius: t.optional(t.text()),
54
+ fontFamily: t.optional(t.text()),
55
+ fontSize: t.optional(t.text()),
56
+ scale: t.optional(t.text())
57
+ }),
58
+ default: {}
59
+ });
60
+
47
61
  //#endregion
48
62
  //#region ../../src/core/atoms/themes/default.ts
49
63
  const defaultTheme = {
@@ -51,6 +65,161 @@ const defaultTheme = {
51
65
  description: "Default Alepha Theme"
52
66
  };
53
67
 
68
+ //#endregion
69
+ //#region ../../src/core/atoms/themes/editorial.ts
70
+ /**
71
+ * Editorial theme.
72
+ *
73
+ * Serif typography, high contrast black and white, thin borders, generous whitespace.
74
+ * Newspaper/magazine aesthetic — elegant restraint.
75
+ */
76
+ const editorialTheme = {
77
+ name: "Editorial",
78
+ description: "Serif typography with newspaper elegance",
79
+ defaultColorScheme: "light",
80
+ head: { link: [
81
+ {
82
+ rel: "preconnect",
83
+ href: "https://fonts.googleapis.com"
84
+ },
85
+ {
86
+ rel: "preconnect",
87
+ href: "https://fonts.gstatic.com",
88
+ crossorigin: ""
89
+ },
90
+ {
91
+ rel: "stylesheet",
92
+ href: "https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700;800&family=Source+Serif+4:ital,wght@0,300;0,400;0,600;1,300;1,400&display=swap"
93
+ }
94
+ ] },
95
+ primaryColor: "ink",
96
+ primaryShade: {
97
+ light: 7,
98
+ dark: 3
99
+ },
100
+ autoContrast: true,
101
+ fontFamily: "\"Source Serif 4\", \"Georgia\", \"Times New Roman\", serif",
102
+ fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
103
+ headings: {
104
+ fontFamily: "\"Playfair Display\", \"Georgia\", \"Times New Roman\", serif",
105
+ fontWeight: "700",
106
+ textWrap: "wrap",
107
+ sizes: {
108
+ h1: {
109
+ fontSize: "2.5rem",
110
+ lineHeight: "1.15"
111
+ },
112
+ h2: {
113
+ fontSize: "1.75rem",
114
+ lineHeight: "1.2"
115
+ },
116
+ h3: {
117
+ fontSize: "1.375rem",
118
+ lineHeight: "1.3"
119
+ },
120
+ h4: {
121
+ fontSize: "1.125rem",
122
+ lineHeight: "1.4"
123
+ },
124
+ h5: {
125
+ fontSize: "1rem",
126
+ lineHeight: "1.5"
127
+ },
128
+ h6: {
129
+ fontSize: "0.875rem",
130
+ lineHeight: "1.5"
131
+ }
132
+ }
133
+ },
134
+ defaultRadius: "sm",
135
+ radius: {
136
+ xs: "2px",
137
+ sm: "3px",
138
+ md: "4px",
139
+ lg: "6px",
140
+ xl: "8px"
141
+ },
142
+ shadows: {
143
+ xs: "0 1px 2px rgba(0, 0, 0, 0.06)",
144
+ sm: "0 1px 3px rgba(0, 0, 0, 0.08)",
145
+ md: "0 2px 6px rgba(0, 0, 0, 0.08)",
146
+ lg: "0 4px 12px rgba(0, 0, 0, 0.1)",
147
+ xl: "0 8px 24px rgba(0, 0, 0, 0.1)"
148
+ },
149
+ colors: {
150
+ ink: [
151
+ "#f5f3f0",
152
+ "#e8e4de",
153
+ "#d4cec5",
154
+ "#b5ad9f",
155
+ "#8c8272",
156
+ "#6b6050",
157
+ "#4a4035",
158
+ "#332b22",
159
+ "#1f1812",
160
+ "#0d0a07"
161
+ ],
162
+ burgundy: [
163
+ "#faf0f0",
164
+ "#f0d4d4",
165
+ "#e0adad",
166
+ "#cc8585",
167
+ "#b35e5e",
168
+ "#944545",
169
+ "#763636",
170
+ "#5a2828",
171
+ "#3d1b1b",
172
+ "#220f0f"
173
+ ],
174
+ gray: [
175
+ "#faf9f7",
176
+ "#f0eee9",
177
+ "#e0dcd5",
178
+ "#c8c2b8",
179
+ "#a8a194",
180
+ "#8a8273",
181
+ "#6b6456",
182
+ "#504a3f",
183
+ "#36322b",
184
+ "#1e1b17"
185
+ ],
186
+ dark: [
187
+ "#d5d2cd",
188
+ "#aba59c",
189
+ "#817a6e",
190
+ "#5e584e",
191
+ "#46413a",
192
+ "#36322c",
193
+ "#2a2721",
194
+ "#201d19",
195
+ "#171411",
196
+ "#0d0b09"
197
+ ]
198
+ },
199
+ components: {
200
+ Button: Button.extend({
201
+ defaultProps: { fw: 600 },
202
+ styles: { root: { letterSpacing: "0.02em" } }
203
+ }),
204
+ ActionIcon: ActionIcon.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
205
+ Paper: Paper.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
206
+ Card: Card.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
207
+ TextInput: TextInput.extend({ styles: { input: { border: "1px solid var(--mantine-color-default-border)" } } }),
208
+ Badge: Badge.extend({
209
+ defaultProps: {
210
+ fw: 600,
211
+ variant: "outline"
212
+ },
213
+ styles: { root: {
214
+ fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
215
+ letterSpacing: "0.04em",
216
+ textTransform: "uppercase",
217
+ fontSize: "0.65rem"
218
+ } }
219
+ })
220
+ }
221
+ };
222
+
54
223
  //#endregion
55
224
  //#region ../../src/core/atoms/themes/midnight.ts
56
225
  const midnightTheme = {
@@ -166,41 +335,793 @@ const midnightTheme = {
166
335
  }
167
336
  };
168
337
 
338
+ //#endregion
339
+ //#region ../../src/core/atoms/themes/monochrome.ts
340
+ /**
341
+ * Monochrome theme.
342
+ *
343
+ * Pure black and white. No color. Bold typography does all the heavy lifting.
344
+ * A design-school statement piece — minimalist color, maximalist type.
345
+ */
346
+ const monochromeTheme = {
347
+ name: "Monochrome",
348
+ description: "Pure black and white — zero color, maximum typography",
349
+ primaryColor: "mono",
350
+ primaryShade: {
351
+ light: 8,
352
+ dark: 1
353
+ },
354
+ autoContrast: true,
355
+ fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
356
+ fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
357
+ headings: {
358
+ fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
359
+ fontWeight: "800",
360
+ textWrap: "wrap",
361
+ sizes: {
362
+ h1: {
363
+ fontSize: "2.25rem",
364
+ lineHeight: "1.15"
365
+ },
366
+ h2: {
367
+ fontSize: "1.625rem",
368
+ lineHeight: "1.25"
369
+ },
370
+ h3: {
371
+ fontSize: "1.25rem",
372
+ lineHeight: "1.35"
373
+ },
374
+ h4: {
375
+ fontSize: "1.0625rem",
376
+ lineHeight: "1.45"
377
+ },
378
+ h5: {
379
+ fontSize: "0.9375rem",
380
+ lineHeight: "1.5"
381
+ },
382
+ h6: {
383
+ fontSize: "0.8125rem",
384
+ lineHeight: "1.5"
385
+ }
386
+ }
387
+ },
388
+ defaultRadius: "0",
389
+ radius: {
390
+ xs: "0",
391
+ sm: "0",
392
+ md: "0",
393
+ lg: "0",
394
+ xl: "2px"
395
+ },
396
+ shadows: {
397
+ xs: "0 1px 2px rgba(0, 0, 0, 0.08)",
398
+ sm: "0 1px 4px rgba(0, 0, 0, 0.1)",
399
+ md: "0 2px 8px rgba(0, 0, 0, 0.12)",
400
+ lg: "0 4px 16px rgba(0, 0, 0, 0.14)",
401
+ xl: "0 8px 32px rgba(0, 0, 0, 0.16)"
402
+ },
403
+ colors: {
404
+ mono: [
405
+ "#f5f5f5",
406
+ "#e0e0e0",
407
+ "#c0c0c0",
408
+ "#a0a0a0",
409
+ "#808080",
410
+ "#606060",
411
+ "#404040",
412
+ "#282828",
413
+ "#141414",
414
+ "#000000"
415
+ ],
416
+ gray: [
417
+ "#f5f5f5",
418
+ "#e5e5e5",
419
+ "#cccccc",
420
+ "#b0b0b0",
421
+ "#909090",
422
+ "#707070",
423
+ "#555555",
424
+ "#3a3a3a",
425
+ "#252525",
426
+ "#121212"
427
+ ],
428
+ blue: [
429
+ "#f5f5f5",
430
+ "#e0e0e0",
431
+ "#c0c0c0",
432
+ "#a0a0a0",
433
+ "#808080",
434
+ "#606060",
435
+ "#404040",
436
+ "#282828",
437
+ "#141414",
438
+ "#000000"
439
+ ],
440
+ green: [
441
+ "#f5f5f5",
442
+ "#e0e0e0",
443
+ "#c0c0c0",
444
+ "#a0a0a0",
445
+ "#808080",
446
+ "#606060",
447
+ "#404040",
448
+ "#282828",
449
+ "#141414",
450
+ "#000000"
451
+ ],
452
+ red: [
453
+ "#f5f5f5",
454
+ "#e0e0e0",
455
+ "#c0c0c0",
456
+ "#a0a0a0",
457
+ "#808080",
458
+ "#606060",
459
+ "#404040",
460
+ "#282828",
461
+ "#141414",
462
+ "#000000"
463
+ ],
464
+ dark: [
465
+ "#d0d0d0",
466
+ "#a0a0a0",
467
+ "#707070",
468
+ "#505050",
469
+ "#383838",
470
+ "#282828",
471
+ "#1c1c1c",
472
+ "#141414",
473
+ "#0a0a0a",
474
+ "#000000"
475
+ ]
476
+ },
477
+ components: {
478
+ Button: Button.extend({
479
+ defaultProps: { fw: 700 },
480
+ styles: { root: {
481
+ border: "2px solid currentColor",
482
+ letterSpacing: "0.03em",
483
+ textTransform: "uppercase",
484
+ fontSize: "0.8125rem"
485
+ } }
486
+ }),
487
+ ActionIcon: ActionIcon.extend({ styles: { root: { border: "2px solid currentColor" } } }),
488
+ Paper: Paper.extend({ styles: { root: { border: "2px solid var(--mantine-color-default-border)" } } }),
489
+ Card: Card.extend({ styles: { root: { border: "2px solid var(--mantine-color-default-border)" } } }),
490
+ TextInput: TextInput.extend({ styles: { input: { border: "2px solid var(--mantine-color-default-border)" } } }),
491
+ Badge: Badge.extend({
492
+ defaultProps: {
493
+ fw: 700,
494
+ variant: "outline"
495
+ },
496
+ styles: { root: {
497
+ textTransform: "uppercase",
498
+ letterSpacing: "0.06em",
499
+ fontSize: "0.65rem",
500
+ border: "2px solid currentColor"
501
+ } }
502
+ })
503
+ }
504
+ };
505
+
506
+ //#endregion
507
+ //#region ../../src/core/atoms/themes/rosePine.ts
508
+ /**
509
+ * Rosé Pine theme.
510
+ *
511
+ * Muted pinks, golds, and subtle greens on warm dark backgrounds.
512
+ * Cozy, low-contrast, easy on the eyes.
513
+ * Based on the Rosé Pine color philosophy.
514
+ */
515
+ const rosePineTheme = {
516
+ name: "Rosé Pine",
517
+ description: "Muted pinks and golds on warm dark backgrounds",
518
+ defaultColorScheme: "dark",
519
+ primaryColor: "rose",
520
+ primaryShade: {
521
+ light: 5,
522
+ dark: 4
523
+ },
524
+ autoContrast: true,
525
+ fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
526
+ fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
527
+ headings: {
528
+ fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
529
+ fontWeight: "600",
530
+ textWrap: "wrap",
531
+ sizes: {
532
+ h1: {
533
+ fontSize: "2rem",
534
+ lineHeight: "1.25"
535
+ },
536
+ h2: {
537
+ fontSize: "1.5rem",
538
+ lineHeight: "1.3"
539
+ },
540
+ h3: {
541
+ fontSize: "1.25rem",
542
+ lineHeight: "1.4"
543
+ },
544
+ h4: {
545
+ fontSize: "1rem",
546
+ lineHeight: "1.5"
547
+ },
548
+ h5: {
549
+ fontSize: "0.875rem",
550
+ lineHeight: "1.5"
551
+ },
552
+ h6: {
553
+ fontSize: "0.75rem",
554
+ lineHeight: "1.5"
555
+ }
556
+ }
557
+ },
558
+ defaultRadius: "md",
559
+ radius: {
560
+ xs: "4px",
561
+ sm: "6px",
562
+ md: "8px",
563
+ lg: "12px",
564
+ xl: "16px"
565
+ },
566
+ shadows: {
567
+ xs: "0 1px 3px rgba(0, 0, 0, 0.2)",
568
+ sm: "0 2px 6px rgba(0, 0, 0, 0.2)",
569
+ md: "0 4px 12px rgba(0, 0, 0, 0.25)",
570
+ lg: "0 8px 24px rgba(0, 0, 0, 0.3)",
571
+ xl: "0 12px 36px rgba(0, 0, 0, 0.35)"
572
+ },
573
+ colors: {
574
+ rose: [
575
+ "#faf0f4",
576
+ "#f2d8e3",
577
+ "#eabdd0",
578
+ "#e0a0bb",
579
+ "#d4849f",
580
+ "#c4748f",
581
+ "#b06282",
582
+ "#9a5275",
583
+ "#7a3f5e",
584
+ "#5c2e47"
585
+ ],
586
+ gold: [
587
+ "#fdf8ec",
588
+ "#f8ecc8",
589
+ "#f2dda0",
590
+ "#eacb72",
591
+ "#e0b94d",
592
+ "#c9a33e",
593
+ "#a98830",
594
+ "#866b24",
595
+ "#634f1a",
596
+ "#403310"
597
+ ],
598
+ pine: [
599
+ "#ecf5f0",
600
+ "#d0e6da",
601
+ "#add4be",
602
+ "#86c0a0",
603
+ "#62ac84",
604
+ "#4e9670",
605
+ "#3e7a5a",
606
+ "#2f5e44",
607
+ "#20412f",
608
+ "#12251b"
609
+ ],
610
+ foam: [
611
+ "#edf6f7",
612
+ "#d2e9eb",
613
+ "#b0d9dd",
614
+ "#8bc6cc",
615
+ "#6ab3bb",
616
+ "#569da5",
617
+ "#438088",
618
+ "#33636a",
619
+ "#23454a",
620
+ "#14292c"
621
+ ],
622
+ red: [
623
+ "#f9eef0",
624
+ "#efd3d8",
625
+ "#e3b2bb",
626
+ "#d68e9b",
627
+ "#c86c7c",
628
+ "#b25566",
629
+ "#944454",
630
+ "#733442",
631
+ "#52252f",
632
+ "#33161d"
633
+ ],
634
+ gray: [
635
+ "#f4f0f2",
636
+ "#e4dde1",
637
+ "#cec5cb",
638
+ "#b5aab2",
639
+ "#9a8e96",
640
+ "#7e737a",
641
+ "#635a60",
642
+ "#4a4248",
643
+ "#332d31",
644
+ "#1e1a1c"
645
+ ],
646
+ dark: [
647
+ "#e0d8e0",
648
+ "#b0a6b2",
649
+ "#817786",
650
+ "#615768",
651
+ "#4a3f54",
652
+ "#3a3044",
653
+ "#2a2436",
654
+ "#211e2e",
655
+ "#1a1724",
656
+ "#110f1a"
657
+ ]
658
+ },
659
+ components: {
660
+ Button: Button.extend({
661
+ defaultProps: { fw: 500 },
662
+ styles: { root: { transition: "background-color 0.15s ease, opacity 0.15s ease" } }
663
+ }),
664
+ ActionIcon: ActionIcon.extend({ styles: { root: { transition: "background-color 0.15s ease, opacity 0.15s ease" } } }),
665
+ Paper: Paper.extend({
666
+ defaultProps: { shadow: "sm" },
667
+ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } }
668
+ }),
669
+ Card: Card.extend({
670
+ defaultProps: { shadow: "sm" },
671
+ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } }
672
+ }),
673
+ TextInput: TextInput.extend({ styles: { input: { border: "1px solid var(--mantine-color-default-border)" } } }),
674
+ Badge: Badge.extend({ defaultProps: { fw: 500 } })
675
+ }
676
+ };
677
+
678
+ //#endregion
679
+ //#region ../../src/core/atoms/themes/softBrutalism.ts
680
+ /**
681
+ * Soft Brutalism theme.
682
+ *
683
+ * Pastel pop palette with solid offset shadows, rounded corners, and bold borders.
684
+ * A friendlier take on neubrutalism — playful but production-ready.
685
+ */
686
+ const softBrutalismTheme = {
687
+ name: "Soft Brutalism",
688
+ description: "Pastel pop with bold borders and offset shadows",
689
+ head: { link: [
690
+ {
691
+ rel: "preconnect",
692
+ href: "https://fonts.googleapis.com"
693
+ },
694
+ {
695
+ rel: "preconnect",
696
+ href: "https://fonts.gstatic.com",
697
+ crossorigin: ""
698
+ },
699
+ {
700
+ rel: "stylesheet",
701
+ href: "https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
702
+ }
703
+ ] },
704
+ primaryColor: "lavender",
705
+ primaryShade: {
706
+ light: 5,
707
+ dark: 7
708
+ },
709
+ autoContrast: true,
710
+ cursorType: "pointer",
711
+ fontFamily: "Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
712
+ fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
713
+ headings: {
714
+ fontFamily: "Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
715
+ fontWeight: "700",
716
+ textWrap: "wrap",
717
+ sizes: {
718
+ h1: {
719
+ fontSize: "2rem",
720
+ lineHeight: "1.25"
721
+ },
722
+ h2: {
723
+ fontSize: "1.5rem",
724
+ lineHeight: "1.3"
725
+ },
726
+ h3: {
727
+ fontSize: "1.25rem",
728
+ lineHeight: "1.4"
729
+ },
730
+ h4: {
731
+ fontSize: "1rem",
732
+ lineHeight: "1.5"
733
+ },
734
+ h5: {
735
+ fontSize: "0.875rem",
736
+ lineHeight: "1.5"
737
+ },
738
+ h6: {
739
+ fontSize: "0.75rem",
740
+ lineHeight: "1.5"
741
+ }
742
+ }
743
+ },
744
+ defaultRadius: "md",
745
+ radius: {
746
+ xs: "6px",
747
+ sm: "8px",
748
+ md: "12px",
749
+ lg: "16px",
750
+ xl: "24px"
751
+ },
752
+ shadows: {
753
+ xs: "2px 2px 0 0 rgba(100, 80, 140, 0.15)",
754
+ sm: "3px 3px 0 0 rgba(100, 80, 140, 0.2)",
755
+ md: "4px 4px 0 0 rgba(100, 80, 140, 0.2)",
756
+ lg: "6px 6px 0 0 rgba(100, 80, 140, 0.25)",
757
+ xl: "8px 8px 0 0 rgba(100, 80, 140, 0.3)"
758
+ },
759
+ colors: {
760
+ lavender: [
761
+ "#f3f0fa",
762
+ "#e4dcf4",
763
+ "#d1c4e9",
764
+ "#b4a7d6",
765
+ "#9a8bc4",
766
+ "#7f6cb0",
767
+ "#6a549e",
768
+ "#543f87",
769
+ "#3d2d6b",
770
+ "#2a1d52"
771
+ ],
772
+ peach: [
773
+ "#fef3ec",
774
+ "#fce4d0",
775
+ "#f9d0ae",
776
+ "#f4b886",
777
+ "#f4a261",
778
+ "#e68a42",
779
+ "#c67234",
780
+ "#a35a28",
781
+ "#6b3a1a",
782
+ "#4a2710"
783
+ ],
784
+ mint: [
785
+ "#ecfaf0",
786
+ "#d4f2dc",
787
+ "#b3e8c2",
788
+ "#8edba4",
789
+ "#81c995",
790
+ "#5ab874",
791
+ "#42a05c",
792
+ "#2e8548",
793
+ "#1a5c2e",
794
+ "#0f3f1e"
795
+ ],
796
+ coral: [
797
+ "#fef0ef",
798
+ "#fcd9d7",
799
+ "#f8b8b4",
800
+ "#f29490",
801
+ "#e97171",
802
+ "#d65454",
803
+ "#b83e3e",
804
+ "#962d2d",
805
+ "#6b1f1f",
806
+ "#4a1414"
807
+ ],
808
+ gray: [
809
+ "#faf8f6",
810
+ "#f0ece8",
811
+ "#ddd7d0",
812
+ "#c4bbb2",
813
+ "#a89e95",
814
+ "#8c8279",
815
+ "#6e655d",
816
+ "#524b44",
817
+ "#3a342f",
818
+ "#24211e"
819
+ ],
820
+ dark: [
821
+ "#d4d0dc",
822
+ "#a9a2b5",
823
+ "#7e7690",
824
+ "#5c546e",
825
+ "#443c56",
826
+ "#342d45",
827
+ "#2a2339",
828
+ "#1e1a2e",
829
+ "#161224",
830
+ "#0f0c1a"
831
+ ]
832
+ },
833
+ components: {
834
+ Button: Button.extend({
835
+ defaultProps: { fw: 600 },
836
+ styles: { root: {
837
+ border: "2px solid currentColor",
838
+ boxShadow: "3px 3px 0 0 rgba(100, 80, 140, 0.2)",
839
+ transition: "box-shadow 0.15s ease, transform 0.15s ease"
840
+ } }
841
+ }),
842
+ ActionIcon: ActionIcon.extend({ styles: { root: {
843
+ border: "2px solid currentColor",
844
+ boxShadow: "2px 2px 0 0 rgba(100, 80, 140, 0.15)"
845
+ } } }),
846
+ Paper: Paper.extend({
847
+ defaultProps: { shadow: "sm" },
848
+ styles: { root: { border: "2px solid var(--mantine-color-default-border)" } }
849
+ }),
850
+ Card: Card.extend({
851
+ defaultProps: { shadow: "sm" },
852
+ styles: { root: { border: "2px solid var(--mantine-color-default-border)" } }
853
+ }),
854
+ TextInput: TextInput.extend({ styles: { input: {
855
+ border: "2px solid var(--mantine-color-default-border)",
856
+ transition: "box-shadow 0.15s ease, border-color 0.15s ease"
857
+ } } }),
858
+ Badge: Badge.extend({
859
+ defaultProps: { fw: 600 },
860
+ styles: { root: { border: "2px solid currentColor" } }
861
+ })
862
+ }
863
+ };
864
+
865
+ //#endregion
866
+ //#region ../../src/core/atoms/themes/terminal.ts
867
+ /**
868
+ * Terminal theme.
869
+ *
870
+ * Monospace everything, green-on-black, zero radius.
871
+ * CRT/hacker aesthetic for developer tools and dashboards.
872
+ */
873
+ const terminalTheme = {
874
+ name: "Terminal",
875
+ description: "Green phosphor on black — monospace hacker aesthetic",
876
+ defaultColorScheme: "dark",
877
+ primaryColor: "terminal",
878
+ primaryShade: {
879
+ light: 5,
880
+ dark: 4
881
+ },
882
+ autoContrast: true,
883
+ fontFamily: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
884
+ fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
885
+ headings: {
886
+ fontFamily: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
887
+ fontWeight: "700",
888
+ textWrap: "wrap",
889
+ sizes: {
890
+ h1: {
891
+ fontSize: "1.75rem",
892
+ lineHeight: "1.3"
893
+ },
894
+ h2: {
895
+ fontSize: "1.375rem",
896
+ lineHeight: "1.35"
897
+ },
898
+ h3: {
899
+ fontSize: "1.125rem",
900
+ lineHeight: "1.4"
901
+ },
902
+ h4: {
903
+ fontSize: "1rem",
904
+ lineHeight: "1.5"
905
+ },
906
+ h5: {
907
+ fontSize: "0.875rem",
908
+ lineHeight: "1.5"
909
+ },
910
+ h6: {
911
+ fontSize: "0.75rem",
912
+ lineHeight: "1.5"
913
+ }
914
+ }
915
+ },
916
+ defaultRadius: "0",
917
+ radius: {
918
+ xs: "0",
919
+ sm: "0",
920
+ md: "0",
921
+ lg: "2px",
922
+ xl: "4px"
923
+ },
924
+ shadows: {
925
+ xs: "none",
926
+ sm: "none",
927
+ md: "0 0 8px rgba(0, 255, 65, 0.08)",
928
+ lg: "0 0 16px rgba(0, 255, 65, 0.1)",
929
+ xl: "0 0 24px rgba(0, 255, 65, 0.12)"
930
+ },
931
+ colors: {
932
+ terminal: [
933
+ "#e6fff0",
934
+ "#b3ffd1",
935
+ "#80ffb3",
936
+ "#4dff94",
937
+ "#00ff41",
938
+ "#00d636",
939
+ "#00ad2b",
940
+ "#008521",
941
+ "#005c17",
942
+ "#00330d"
943
+ ],
944
+ amber: [
945
+ "#fff8e6",
946
+ "#ffecb3",
947
+ "#ffe080",
948
+ "#ffd54d",
949
+ "#ffca28",
950
+ "#d4a520",
951
+ "#aa8418",
952
+ "#806310",
953
+ "#554208",
954
+ "#2b2104"
955
+ ],
956
+ red: [
957
+ "#ffe6e6",
958
+ "#ffb3b3",
959
+ "#ff8080",
960
+ "#ff4d4d",
961
+ "#ff1a1a",
962
+ "#d41515",
963
+ "#aa1010",
964
+ "#800c0c",
965
+ "#550808",
966
+ "#2b0404"
967
+ ],
968
+ gray: [
969
+ "#e8eaed",
970
+ "#c8cdd3",
971
+ "#a4aab3",
972
+ "#808892",
973
+ "#5f6872",
974
+ "#474f58",
975
+ "#363c44",
976
+ "#282d33",
977
+ "#1c2026",
978
+ "#12151a"
979
+ ],
980
+ dark: [
981
+ "#c9cdd2",
982
+ "#8b9198",
983
+ "#5c636b",
984
+ "#3d444c",
985
+ "#2b3138",
986
+ "#1e242b",
987
+ "#151a20",
988
+ "#0e1216",
989
+ "#080c0f",
990
+ "#020303"
991
+ ]
992
+ },
993
+ components: {
994
+ Button: Button.extend({
995
+ defaultProps: { fw: 600 },
996
+ styles: { root: {
997
+ border: "1px solid currentColor",
998
+ textTransform: "uppercase",
999
+ letterSpacing: "0.05em",
1000
+ fontSize: "0.8125rem"
1001
+ } }
1002
+ }),
1003
+ ActionIcon: ActionIcon.extend({ styles: { root: { border: "1px solid currentColor" } } }),
1004
+ Paper: Paper.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
1005
+ Card: Card.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
1006
+ TextInput: TextInput.extend({ styles: { input: {
1007
+ border: "1px solid var(--mantine-color-default-border)",
1008
+ fontFamily: "inherit"
1009
+ } } }),
1010
+ Badge: Badge.extend({
1011
+ defaultProps: { fw: 600 },
1012
+ styles: { root: {
1013
+ border: "1px solid currentColor",
1014
+ textTransform: "uppercase",
1015
+ letterSpacing: "0.05em"
1016
+ } }
1017
+ })
1018
+ }
1019
+ };
1020
+
169
1021
  //#endregion
170
1022
  //#region ../../src/core/atoms/alephaThemeListAtom.ts
171
1023
  const alephaThemeListAtom = $atom({
172
1024
  name: "alepha.ui.themeList",
173
1025
  schema: t.array(t.json()),
174
- default: [defaultTheme, midnightTheme]
1026
+ default: [
1027
+ defaultTheme,
1028
+ midnightTheme,
1029
+ softBrutalismTheme,
1030
+ terminalTheme,
1031
+ editorialTheme,
1032
+ rosePineTheme,
1033
+ monochromeTheme
1034
+ ]
175
1035
  });
176
1036
 
177
1037
  //#endregion
178
1038
  //#region ../../src/core/providers/ThemeProvider.ts
179
- var ThemeProvider = class {
1039
+ var ThemeProvider = class ThemeProvider {
180
1040
  alepha = $inject(Alepha);
181
1041
  cookie = $cookie({
182
1042
  name: "theme",
183
1043
  schema: alephaThemeAtom.schema,
184
1044
  ttl: [1, "year"]
185
1045
  });
1046
+ overridesCookie = $cookie({
1047
+ name: "themeOverrides",
1048
+ schema: alephaThemeOverridesAtom.schema,
1049
+ ttl: [1, "year"]
1050
+ });
186
1051
  head = $head(() => {
187
1052
  const theme = this.getTheme();
188
1053
  if (!theme || !theme.name) return {};
189
- return { htmlAttributes: { "data-theme": theme.name } };
1054
+ return {
1055
+ htmlAttributes: { "data-theme": this.slugify(theme.name) },
1056
+ ...theme.head
1057
+ };
190
1058
  });
191
1059
  setTheme(index) {
192
- const newTheme = this.alepha.store.get(alephaThemeListAtom)[index];
193
- if (!newTheme) throw new AlephaError(`Theme with index ${index} not found`);
1060
+ if (!this.alepha.store.get(alephaThemeListAtom)[index]) throw new AlephaError(`Theme with index ${index} not found`);
194
1061
  this.cookie.set({ index });
195
1062
  this.alepha.store.set(alephaThemeAtom, { index });
196
- if (typeof document === "undefined") return;
197
- document.documentElement.removeAttribute("data-theme");
198
- if (newTheme.name) document.documentElement.setAttribute("data-theme", newTheme.name);
1063
+ if (!this.alepha.isBrowser()) return;
1064
+ this.alepha.inject(BrowserHeadProvider).refreshGlobalHead();
199
1065
  }
1066
+ slugify(name) {
1067
+ return name.toLowerCase().replace(/\s+/g, "-");
1068
+ }
1069
+ static FONT_SIZE_MULTIPLIERS = {
1070
+ xs: .85,
1071
+ sm: .925,
1072
+ md: 1,
1073
+ lg: 1.1,
1074
+ xl: 1.25
1075
+ };
1076
+ static SCALE_VALUES = {
1077
+ xs: .85,
1078
+ sm: .925,
1079
+ md: 1,
1080
+ lg: 1.1,
1081
+ xl: 1.25
1082
+ };
1083
+ static DEFAULT_FONT_SIZES = {
1084
+ xs: "0.75rem",
1085
+ sm: "0.875rem",
1086
+ md: "1rem",
1087
+ lg: "1.125rem",
1088
+ xl: "1.25rem"
1089
+ };
200
1090
  getTheme() {
201
1091
  const index = this.getThemeIndex();
202
1092
  const list = this.alepha.store.get(alephaThemeListAtom);
203
- return list[index] || list[0] || defaultTheme;
1093
+ const base = list[index] || list[0] || defaultTheme;
1094
+ const overrides = this.getThemeOverrides();
1095
+ if (!overrides.primaryColor && !overrides.radius && !overrides.fontFamily && !overrides.fontSize && !overrides.scale) return base;
1096
+ const merged = {
1097
+ ...base,
1098
+ ...overrides.primaryColor && { primaryColor: overrides.primaryColor },
1099
+ ...overrides.radius && { defaultRadius: overrides.radius },
1100
+ ...overrides.fontFamily && { fontFamily: overrides.fontFamily },
1101
+ ...overrides.scale && overrides.scale !== "md" && { scale: ThemeProvider.SCALE_VALUES[overrides.scale] ?? 1 }
1102
+ };
1103
+ if (overrides.fontSize && overrides.fontSize !== "md") {
1104
+ const multiplier = ThemeProvider.FONT_SIZE_MULTIPLIERS[overrides.fontSize] ?? 1;
1105
+ const baseSizes = base.fontSizes ?? ThemeProvider.DEFAULT_FONT_SIZES;
1106
+ merged.fontSizes = Object.fromEntries(Object.entries(baseSizes).map(([key, val]) => [key, `${(Number.parseFloat(String(val)) * multiplier).toFixed(4)}rem`]));
1107
+ }
1108
+ return merged;
1109
+ }
1110
+ setThemeOverrides(overrides) {
1111
+ this.overridesCookie.set(overrides);
1112
+ this.alepha.store.set(alephaThemeOverridesAtom, overrides);
1113
+ if (!this.alepha.isBrowser()) return;
1114
+ this.alepha.inject(BrowserHeadProvider).refreshGlobalHead();
1115
+ }
1116
+ getThemeOverrides() {
1117
+ try {
1118
+ return this.overridesCookie.get() ?? this.alepha.store.get(alephaThemeOverridesAtom) ?? {};
1119
+ } catch {
1120
+ return this.alepha.store.get(alephaThemeOverridesAtom) ?? {};
1121
+ }
1122
+ }
1123
+ resetThemeOverrides() {
1124
+ this.setThemeOverrides({});
204
1125
  }
205
1126
  getThemeIndex() {
206
1127
  try {
@@ -307,14 +1228,21 @@ var DialogService = class {
307
1228
  */
308
1229
  alert(options) {
309
1230
  return new Promise((resolve) => {
1231
+ let resolved = false;
1232
+ const done = () => {
1233
+ if (resolved) return;
1234
+ resolved = true;
1235
+ resolve();
1236
+ };
310
1237
  const modalId = this.open({
311
1238
  ...options,
312
1239
  title: options?.title || "Alert",
1240
+ onClose: done,
313
1241
  content: /* @__PURE__ */ jsx(AlertDialog, {
314
1242
  options,
315
1243
  onClose: () => {
316
1244
  this.close(modalId);
317
- resolve();
1245
+ done();
318
1246
  }
319
1247
  })
320
1248
  });
@@ -325,16 +1253,23 @@ var DialogService = class {
325
1253
  */
326
1254
  confirm(options) {
327
1255
  return new Promise((resolve) => {
1256
+ let resolved = false;
1257
+ const done = (confirmed) => {
1258
+ if (resolved) return;
1259
+ resolved = true;
1260
+ resolve(confirmed);
1261
+ };
328
1262
  const modalId = this.open({
329
1263
  ...options,
330
1264
  title: options?.title || "Confirm",
331
1265
  closeOnClickOutside: false,
332
1266
  closeOnEscape: false,
1267
+ onClose: () => done(false),
333
1268
  content: /* @__PURE__ */ jsx(ConfirmDialog, {
334
1269
  options,
335
1270
  onConfirm: (confirmed) => {
336
1271
  this.close(modalId);
337
- resolve(confirmed);
1272
+ done(confirmed);
338
1273
  }
339
1274
  })
340
1275
  });
@@ -345,16 +1280,23 @@ var DialogService = class {
345
1280
  */
346
1281
  prompt(options) {
347
1282
  return new Promise((resolve) => {
1283
+ let resolved = false;
1284
+ const done = (value) => {
1285
+ if (resolved) return;
1286
+ resolved = true;
1287
+ resolve(value);
1288
+ };
348
1289
  const modalId = this.open({
349
1290
  ...options,
350
1291
  title: options?.title || "Input",
351
1292
  closeOnClickOutside: false,
352
1293
  closeOnEscape: false,
1294
+ onClose: () => done(null),
353
1295
  content: /* @__PURE__ */ jsx(PromptDialog, {
354
1296
  options,
355
1297
  onSubmit: (value) => {
356
1298
  this.close(modalId);
357
- resolve(value);
1299
+ done(value);
358
1300
  }
359
1301
  })
360
1302
  });
@@ -458,20 +1400,34 @@ var UiRouter = class {
458
1400
  /**
459
1401
  * Hook to get and set the current theme.
460
1402
  *
461
- * Returns a tuple with the current theme and a function to set the theme.
1403
+ * Returns a tuple with the current theme, a function to set the theme,
1404
+ * and expert mode controls for fine-grained customization.
462
1405
  *
463
1406
  * ```tsx
464
- * const [theme, setTheme] = useTheme();
1407
+ * const [theme, setTheme, expert] = useTheme();
465
1408
  * ```
466
1409
  */
467
1410
  const useTheme = () => {
468
1411
  useStore(alephaThemeAtom);
1412
+ useStore(alephaThemeOverridesAtom);
469
1413
  const themeProvider = useInject(ThemeProvider);
470
1414
  const theme = themeProvider.getTheme();
471
1415
  const setTheme = (theme) => {
472
1416
  themeProvider.setTheme(theme.index);
473
1417
  };
474
- return [theme, setTheme];
1418
+ return [
1419
+ theme,
1420
+ setTheme,
1421
+ {
1422
+ overrides: themeProvider.getThemeOverrides(),
1423
+ setOverrides: (overrides) => {
1424
+ themeProvider.setThemeOverrides(overrides);
1425
+ },
1426
+ resetOverrides: () => {
1427
+ themeProvider.resetThemeOverrides();
1428
+ }
1429
+ }
1430
+ ];
475
1431
  };
476
1432
 
477
1433
  //#endregion
@@ -569,16 +1525,16 @@ const AlephaMantineProvider = (props) => {
569
1525
  const ui = {
570
1526
  colors: {
571
1527
  transparent: "transparent",
572
- background: "var(--alepha-background)",
1528
+ background: "var(--alepha-ground)",
573
1529
  surface: "var(--alepha-surface)",
574
1530
  elevated: "var(--alepha-elevated)",
575
1531
  border: "var(--alepha-border)"
576
1532
  },
577
1533
  sizes: { icon: {
578
- xs: 14,
579
- sm: 16,
580
- md: 20,
581
- lg: 24,
1534
+ xs: 16,
1535
+ sm: 20,
1536
+ md: 24,
1537
+ lg: 28,
582
1538
  xl: 32
583
1539
  } }
584
1540
  };
@@ -617,14 +1573,9 @@ const ActionMenuItem = (props) => {
617
1573
  if (props.item.onClick) menuItemProps.onClick = action.run;
618
1574
  else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
619
1575
  return /* @__PURE__ */ jsx(Menu.Item, {
620
- leftSection: item.icon,
1576
+ leftSection: item.icon ?? (item.active ? /* @__PURE__ */ jsx(IconCheck, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(Flex$1, { w: ui.sizes.icon.sm })),
621
1577
  onClick: item.onClick,
622
1578
  color: item.color,
623
- rightSection: item.active ? /* @__PURE__ */ jsx(ThemeIcon, {
624
- size: "xs",
625
- variant: "transparent",
626
- children: /* @__PURE__ */ jsx(IconCheck, {})
627
- }) : void 0,
628
1579
  ...menuItemProps,
629
1580
  children: item.label
630
1581
  }, index);
@@ -632,11 +1583,9 @@ const ActionMenuItem = (props) => {
632
1583
  const ActionButton = (_props) => {
633
1584
  const theme = useMantineTheme();
634
1585
  const props = { ..._props };
635
- const { tooltip, menu, icon, ...restProps } = props;
636
- if (props.variant === "subtle" || props.variant === "outline") restProps.color ??= "gray";
1586
+ const { tooltip, menu, icon, iconSize, ...restProps } = props;
637
1587
  if (props.intent) {
638
- if (props.intent === "none") restProps.color ??= "gray";
639
- else if (props.intent === "primary") restProps.color ??= theme.primaryColor;
1588
+ if (props.intent === "primary") restProps.color ??= theme.primaryColor;
640
1589
  else if (props.intent === "success") {
641
1590
  restProps.c ??= "white";
642
1591
  restProps.color ??= "green";
@@ -651,10 +1600,11 @@ const ActionButton = (_props) => {
651
1600
  }
652
1601
  if (props.icon) {
653
1602
  const sizes = ui.sizes.icon;
654
- const icon = isComponentType(props.icon) ? /* @__PURE__ */ jsx(props.icon, { size: sizes[props.size || "md"] }) : /* @__PURE__ */ jsx("span", { children: props.icon });
1603
+ const iconSize = props.iconSize ?? sizes[props.size || "sm"];
1604
+ const icon = isComponentType(props.icon) ? /* @__PURE__ */ jsx(props.icon, { size: iconSize }) : /* @__PURE__ */ jsx("span", { children: props.icon });
655
1605
  if (!props.children) {
656
1606
  restProps.children = Children.only(icon);
657
- restProps.px ??= "xs";
1607
+ restProps.p ??= 8;
658
1608
  } else restProps.leftSection = icon;
659
1609
  }
660
1610
  if (props.leftSection && !props.children) restProps.px ??= "xs";
@@ -926,11 +1876,11 @@ const DarkModeButton = (props) => {
926
1876
  const toggleColorScheme = () => {
927
1877
  setColorScheme((document.documentElement.getAttribute("data-mantine-color-scheme") ?? "light") === "dark" ? "light" : "dark");
928
1878
  };
929
- const size = props.size ?? "md";
930
- const iconSize = ui.sizes.icon[size] ?? ui.sizes.icon.md;
1879
+ const size = props.size ?? "sm";
1880
+ const iconSize = ui.sizes.icon[size] ?? ui.sizes.icon.sm;
931
1881
  return /* @__PURE__ */ jsx(ActionButton, {
932
1882
  onClick: toggleColorScheme,
933
- variant: props.variant ?? "subtle",
1883
+ variant: props.variant ?? "default",
934
1884
  size,
935
1885
  "aria-label": "Toggle color scheme",
936
1886
  icon: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(IconSun, {
@@ -949,7 +1899,7 @@ const DarkModeButton = (props) => {
949
1899
  const LanguageButton = (props) => {
950
1900
  const i18n = useI18n();
951
1901
  return /* @__PURE__ */ jsx(ActionButton, {
952
- variant: "subtle",
1902
+ variant: "default",
953
1903
  icon: IconLanguage,
954
1904
  menu: { items: i18n.languages.map((lang) => ({
955
1905
  label: i18n.tr(lang),
@@ -968,8 +1918,7 @@ const OmnibarButton = (props) => {
968
1918
  if (props.collapsed) return /* @__PURE__ */ jsx(ActionButton, {
969
1919
  variant: "subtle",
970
1920
  onClick: spotlight.open,
971
- radius: "md",
972
- icon: /* @__PURE__ */ jsx(IconSearch, { size: 16 }),
1921
+ icon: IconSearch,
973
1922
  tooltip: {
974
1923
  label: "Search",
975
1924
  position: "right"
@@ -1006,20 +1955,258 @@ const OmnibarButton = (props) => {
1006
1955
  });
1007
1956
  };
1008
1957
 
1958
+ //#endregion
1959
+ //#region ../../src/core/hooks/useDialog.ts
1960
+ /**
1961
+ * Use this hook to access the Dialog Service for showing various dialog types.
1962
+ *
1963
+ * @example
1964
+ * ```tsx
1965
+ * const dialog = useDialog();
1966
+ * await dialog.alert({ title: "Alert", message: "This is an alert message" });
1967
+ * const confirmed = await dialog.confirm({ title: "Confirm", message: "Are you sure?" });
1968
+ * const input = await dialog.prompt({ title: "Input", message: "Enter your name:" });
1969
+ * ```
1970
+ */
1971
+ const useDialog = () => {
1972
+ return useInject(DialogService);
1973
+ };
1974
+
1975
+ //#endregion
1976
+ //#region ../../src/core/components/buttons/ThemeExpertModal.tsx
1977
+ const MANTINE_COLORS = [
1978
+ "red",
1979
+ "pink",
1980
+ "grape",
1981
+ "violet",
1982
+ "indigo",
1983
+ "blue",
1984
+ "cyan",
1985
+ "teal",
1986
+ "green",
1987
+ "lime",
1988
+ "yellow",
1989
+ "orange"
1990
+ ];
1991
+ const RADIUS_OPTIONS = [
1992
+ {
1993
+ label: "xs",
1994
+ value: "xs"
1995
+ },
1996
+ {
1997
+ label: "sm",
1998
+ value: "sm"
1999
+ },
2000
+ {
2001
+ label: "md",
2002
+ value: "md"
2003
+ },
2004
+ {
2005
+ label: "lg",
2006
+ value: "lg"
2007
+ },
2008
+ {
2009
+ label: "xl",
2010
+ value: "xl"
2011
+ }
2012
+ ];
2013
+ const SIZE_OPTIONS = [
2014
+ {
2015
+ label: "xs",
2016
+ value: "xs"
2017
+ },
2018
+ {
2019
+ label: "sm",
2020
+ value: "sm"
2021
+ },
2022
+ {
2023
+ label: "md",
2024
+ value: "md"
2025
+ },
2026
+ {
2027
+ label: "lg",
2028
+ value: "lg"
2029
+ },
2030
+ {
2031
+ label: "xl",
2032
+ value: "xl"
2033
+ }
2034
+ ];
2035
+ const FONT_OPTIONS = [
2036
+ {
2037
+ label: "System",
2038
+ value: ""
2039
+ },
2040
+ {
2041
+ label: "Inter",
2042
+ value: "Inter, sans-serif"
2043
+ },
2044
+ {
2045
+ label: "Mono",
2046
+ value: "ui-monospace, SFMono-Regular, Menlo, monospace"
2047
+ },
2048
+ {
2049
+ label: "Serif",
2050
+ value: "Georgia, 'Times New Roman', serif"
2051
+ }
2052
+ ];
2053
+ const ThemeExpertModal = () => {
2054
+ const [, , expert] = useTheme();
2055
+ const dialog = useDialog();
2056
+ const mantineTheme = useMantineTheme();
2057
+ const { overrides, setOverrides } = expert;
2058
+ const currentColor = overrides.primaryColor || mantineTheme.primaryColor;
2059
+ const currentRadius = overrides.radius || mantineTheme.defaultRadius || "md";
2060
+ const currentFont = overrides.fontFamily || "";
2061
+ const currentFontSize = overrides.fontSize || "md";
2062
+ const currentScale = overrides.scale || "md";
2063
+ const updateOverrides = (patch) => {
2064
+ setOverrides({
2065
+ ...overrides,
2066
+ ...patch
2067
+ });
2068
+ };
2069
+ return /* @__PURE__ */ jsxs(Flex$1, {
2070
+ direction: "column",
2071
+ gap: "lg",
2072
+ children: [
2073
+ /* @__PURE__ */ jsxs(Flex$1, {
2074
+ direction: "column",
2075
+ gap: "xs",
2076
+ children: [/* @__PURE__ */ jsx(Text$1, {
2077
+ fw: 500,
2078
+ size: "sm",
2079
+ children: "Primary Color"
2080
+ }), /* @__PURE__ */ jsx(SimpleGrid, {
2081
+ cols: 6,
2082
+ spacing: "xs",
2083
+ children: MANTINE_COLORS.map((color) => /* @__PURE__ */ jsx(Flex$1, {
2084
+ justify: "center",
2085
+ children: /* @__PURE__ */ jsx(ColorSwatch, {
2086
+ color: mantineTheme.colors[color]?.[6] ?? color,
2087
+ onClick: () => updateOverrides({ primaryColor: color }),
2088
+ style: { cursor: "pointer" },
2089
+ size: 32,
2090
+ children: currentColor === color && /* @__PURE__ */ jsx(IconCheck, {
2091
+ size: 14,
2092
+ color: "white"
2093
+ })
2094
+ })
2095
+ }, color))
2096
+ })]
2097
+ }),
2098
+ /* @__PURE__ */ jsxs(Flex$1, {
2099
+ direction: "column",
2100
+ gap: "xs",
2101
+ children: [/* @__PURE__ */ jsx(Text$1, {
2102
+ fw: 500,
2103
+ size: "sm",
2104
+ children: "Border Radius"
2105
+ }), /* @__PURE__ */ jsx(Flex$1, {
2106
+ gap: "xs",
2107
+ children: RADIUS_OPTIONS.map((opt) => /* @__PURE__ */ jsx(ActionButton, {
2108
+ variant: String(currentRadius) === opt.value ? "filled" : "default",
2109
+ size: "xs",
2110
+ flex: 1,
2111
+ onClick: () => updateOverrides({ radius: opt.value }),
2112
+ children: opt.label
2113
+ }, opt.value))
2114
+ })]
2115
+ }),
2116
+ /* @__PURE__ */ jsxs(Flex$1, {
2117
+ direction: "column",
2118
+ gap: "xs",
2119
+ children: [/* @__PURE__ */ jsx(Text$1, {
2120
+ fw: 500,
2121
+ size: "sm",
2122
+ children: "Font Family"
2123
+ }), /* @__PURE__ */ jsx(Select, {
2124
+ data: FONT_OPTIONS,
2125
+ value: currentFont,
2126
+ onChange: (value) => updateOverrides({ fontFamily: value ?? "" }),
2127
+ allowDeselect: false
2128
+ })]
2129
+ }),
2130
+ /* @__PURE__ */ jsxs(Flex$1, {
2131
+ direction: "column",
2132
+ gap: "xs",
2133
+ children: [/* @__PURE__ */ jsx(Text$1, {
2134
+ fw: 500,
2135
+ size: "sm",
2136
+ children: "Font Size"
2137
+ }), /* @__PURE__ */ jsx(Flex$1, {
2138
+ gap: "xs",
2139
+ children: SIZE_OPTIONS.map((opt) => /* @__PURE__ */ jsx(ActionButton, {
2140
+ variant: currentFontSize === opt.value ? "filled" : "default",
2141
+ size: "xs",
2142
+ flex: 1,
2143
+ onClick: () => updateOverrides({ fontSize: opt.value }),
2144
+ children: opt.label
2145
+ }, opt.value))
2146
+ })]
2147
+ }),
2148
+ /* @__PURE__ */ jsxs(Flex$1, {
2149
+ direction: "column",
2150
+ gap: "xs",
2151
+ children: [/* @__PURE__ */ jsx(Text$1, {
2152
+ fw: 500,
2153
+ size: "sm",
2154
+ children: "Scale"
2155
+ }), /* @__PURE__ */ jsx(Flex$1, {
2156
+ gap: "xs",
2157
+ children: SIZE_OPTIONS.map((opt) => /* @__PURE__ */ jsx(ActionButton, {
2158
+ variant: currentScale === opt.value ? "filled" : "default",
2159
+ size: "xs",
2160
+ flex: 1,
2161
+ onClick: () => updateOverrides({ scale: opt.value }),
2162
+ children: opt.label
2163
+ }, opt.value))
2164
+ })]
2165
+ }),
2166
+ /* @__PURE__ */ jsxs(Flex$1, {
2167
+ justify: "space-between",
2168
+ children: [/* @__PURE__ */ jsx(ActionButton, {
2169
+ variant: "subtle",
2170
+ color: "red",
2171
+ onClick: () => expert.resetOverrides(),
2172
+ children: "Reset"
2173
+ }), /* @__PURE__ */ jsx(ActionButton, {
2174
+ variant: "default",
2175
+ px: "xl",
2176
+ onClick: () => dialog.close(),
2177
+ children: "OK"
2178
+ })]
2179
+ })
2180
+ ]
2181
+ });
2182
+ };
2183
+
1009
2184
  //#endregion
1010
2185
  //#region ../../src/core/components/buttons/ThemeButton.tsx
1011
2186
  const ThemeButton = (props) => {
2187
+ const { expert, ...actionProps } = props;
1012
2188
  const [theme, setTheme] = useTheme();
1013
2189
  const themeList = useStore(alephaThemeListAtom)[0];
2190
+ const dialog = useDialog();
2191
+ const items = themeList.map((it, index) => ({
2192
+ label: it.name,
2193
+ onClick: () => setTheme({ index }),
2194
+ active: theme.name === it.name
2195
+ }));
2196
+ if (expert) items.push({ type: "divider" }, {
2197
+ label: "Customize...",
2198
+ onClick: () => {
2199
+ dialog.open({
2200
+ title: "Customize Theme",
2201
+ content: /* @__PURE__ */ jsx(ThemeExpertModal, {})
2202
+ });
2203
+ }
2204
+ });
1014
2205
  return /* @__PURE__ */ jsx(ActionButton, {
1015
- variant: "subtle",
2206
+ variant: "default",
1016
2207
  icon: IconPalette,
1017
- menu: { items: themeList.map((it, index) => ({
1018
- label: it.name,
1019
- onClick: () => setTheme({ index }),
1020
- active: theme.name === it.name
1021
- })) },
1022
- ...props
2208
+ menu: { items },
2209
+ ...actionProps
1023
2210
  });
1024
2211
  };
1025
2212
 
@@ -1030,8 +2217,7 @@ const ToggleSidebarButton = (props) => {
1030
2217
  return /* @__PURE__ */ jsx(ActionButton, {
1031
2218
  icon: sidebar.collapsed ? IconLayoutSidebarRightCollapse : IconLayoutSidebarLeftCollapse,
1032
2219
  visibleFrom: "md",
1033
- variant: "subtle",
1034
- size: "md",
2220
+ variant: "default",
1035
2221
  onClick: () => {
1036
2222
  setSidebar({
1037
2223
  ...sidebar,
@@ -1219,7 +2405,7 @@ const StatCards = ({ items }) => /* @__PURE__ */ jsx(Flex$1, {
1219
2405
  //#endregion
1220
2406
  //#region ../../src/core/components/Flex.tsx
1221
2407
  const Flex = forwardRef((props, ref) => {
1222
- const { fill, center, centerX, centerY, col, ...rest } = props;
2408
+ const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, ...rest } = props;
1223
2409
  if (fill) rest.flex ??= 1;
1224
2410
  if (col) rest.direction ??= "column";
1225
2411
  if (center) {
@@ -1228,6 +2414,20 @@ const Flex = forwardRef((props, ref) => {
1228
2414
  }
1229
2415
  if (centerX) rest.justify ??= "center";
1230
2416
  if (centerY) rest.align ??= "center";
2417
+ if (ground) rest.bg = "var(--alepha-ground)";
2418
+ else if (surface) rest.bg = "var(--alepha-surface)";
2419
+ else if (elevated) rest.bg = "var(--alepha-elevated)";
2420
+ if (rounded) rest.bdrs = rounded === true ? "md" : rounded;
2421
+ if (bordered) rest.bd = "1px solid var(--alepha-border)";
2422
+ if (borderedTop) rest.style = {
2423
+ borderTop: "1px solid var(--alepha-border)",
2424
+ ...rest.style ?? {}
2425
+ };
2426
+ if (borderedBottom) rest.style = {
2427
+ borderBottom: "1px solid var(--alepha-border)",
2428
+ ...rest.style ?? {}
2429
+ };
2430
+ if (shadowed) rest.className = `${rest.className ?? ""} shadow-${shadowed === true ? "md" : shadowed}`.trim();
1231
2431
  return /* @__PURE__ */ jsx(Flex$1, {
1232
2432
  ref,
1233
2433
  ...rest
@@ -1251,6 +2451,7 @@ const AppBar = (props) => {
1251
2451
  if ("type" in item) {
1252
2452
  if (item.type === "burger") return /* @__PURE__ */ jsx(BurgerButton, {}, index);
1253
2453
  if (item.type === "dark") return /* @__PURE__ */ jsx(DarkModeButton, { ...item.props }, index);
2454
+ if (item.type === "theme") return /* @__PURE__ */ jsx(ThemeButton, { ...item.props }, index);
1254
2455
  if (item.type === "search") return /* @__PURE__ */ jsx(OmnibarButton, { ...item.props }, index);
1255
2456
  if (item.type === "lang") return /* @__PURE__ */ jsx(LanguageButton, { ...item.props }, index);
1256
2457
  if (item.type === "spacer") return /* @__PURE__ */ jsx(Flex, { w: 16 }, index);
@@ -1441,6 +2642,9 @@ const Sidebar = (props) => {
1441
2642
  if (item.type === "divider") return divider(key, item.fill, collapsed);
1442
2643
  if (item.type === "search") return /* @__PURE__ */ jsx(Flex, {
1443
2644
  mb: "xs",
2645
+ w: "100%",
2646
+ justify: "center",
2647
+ pos: "relative",
1444
2648
  children: /* @__PURE__ */ jsx(OmnibarButton, { collapsed })
1445
2649
  }, key);
1446
2650
  if (item.type === "toggle") return /* @__PURE__ */ jsx(ToggleSidebarButton, {}, key);
@@ -1448,7 +2652,7 @@ const Sidebar = (props) => {
1448
2652
  if (item.children && item.children.length > 0) {
1449
2653
  if (!item.children.some((child) => !("can" in child) || !child.can || child.can())) return null;
1450
2654
  }
1451
- if (collapsed) return /* @__PURE__ */ jsxs(Fragment$1, { children: [divider(`${key}-d`, void 0, collapsed), item.children?.map((child, index) => renderNode(child, `s${key}-${index}`, collapsed))] }, key);
2655
+ if (collapsed) return /* @__PURE__ */ jsx(Fragment$1, { children: item.children?.map((child, index) => renderNode(child, `s${key}-${index}`, collapsed)) }, key);
1452
2656
  return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Flex, {
1453
2657
  mt: "md",
1454
2658
  align: "center",
@@ -1498,7 +2702,7 @@ const Sidebar = (props) => {
1498
2702
  return [];
1499
2703
  };
1500
2704
  const padding = "md";
1501
- const gap = props.items ? props.gap ?? 4 : "xs";
2705
+ const gap = props.items ? props.gap ?? 8 : "xs";
1502
2706
  const menu = useMemo(() => getSidebarNodes(), [props.items, props.autoPopulateMenu]);
1503
2707
  const renderSidebar = (collapsed) => /* @__PURE__ */ jsxs(Flex, {
1504
2708
  flex: 1,
@@ -1580,10 +2784,7 @@ const SidebarItem = (props) => {
1580
2784
  bd: 0,
1581
2785
  fw: "normal",
1582
2786
  variant: "default",
1583
- propsActive: {
1584
- variant: "outline",
1585
- fw: "bold"
1586
- },
2787
+ propsActive: { variant: "outline" },
1587
2788
  radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
1588
2789
  onClick: handleItemClick,
1589
2790
  leftSection: /* @__PURE__ */ jsxs(Flex, {
@@ -1600,6 +2801,8 @@ const SidebarItem = (props) => {
1600
2801
  }), item.children && isOpen && /* @__PURE__ */ jsxs(Flex, {
1601
2802
  direction: "column",
1602
2803
  "data-parent-level": level,
2804
+ gap: 2,
2805
+ py: 2,
1603
2806
  children: [/* @__PURE__ */ jsx(Flex, { style: {
1604
2807
  position: "absolute",
1605
2808
  width: 1,
@@ -1627,28 +2830,41 @@ const SidebarCollapsedItem = (props) => {
1627
2830
  const menu = hasChildren ? {
1628
2831
  on: "hover",
1629
2832
  position: "right",
1630
- items: item.children.filter((child) => !child.can || child.can()).map((child) => ({
2833
+ menuProps: {
2834
+ arrowPosition: "center",
2835
+ arrowSize: 10,
2836
+ withArrow: true
2837
+ },
2838
+ items: [{
2839
+ type: "label",
2840
+ label: item.label
2841
+ }, ...item.children.filter((child) => !child.can || child.can()).map((child) => ({
1631
2842
  label: child.label,
1632
2843
  icon: renderIcon(child.icon, ui.sizes.icon.sm),
1633
2844
  href: child.href,
1634
2845
  active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
1635
- }))
2846
+ }))]
1636
2847
  } : void 0;
1637
- return /* @__PURE__ */ jsx(ActionButton, {
1638
- size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
1639
- variant: "subtle",
1640
- variantActive: "default",
1641
- tooltip: hasChildren ? void 0 : {
1642
- label: item.label,
1643
- position: "right"
1644
- },
1645
- radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
1646
- onClick: hasChildren ? void 0 : handleItemClick,
1647
- icon: renderIcon(item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
1648
- href: hasChildren ? void 0 : props.item.href,
1649
- target: hasChildren ? void 0 : props.item.target,
1650
- menu,
1651
- ...props.item.actionProps
2848
+ return /* @__PURE__ */ jsx(Flex, {
2849
+ w: "100%",
2850
+ justify: "center",
2851
+ pos: "relative",
2852
+ children: /* @__PURE__ */ jsx(ActionButton, {
2853
+ size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
2854
+ bd: 0,
2855
+ variant: "default",
2856
+ propsActive: { variant: "outline" },
2857
+ tooltip: hasChildren ? void 0 : {
2858
+ label: item.label,
2859
+ position: "right"
2860
+ },
2861
+ onClick: hasChildren ? void 0 : handleItemClick,
2862
+ icon: renderIcon(item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
2863
+ href: hasChildren ? void 0 : props.item.href,
2864
+ target: hasChildren ? void 0 : props.item.target,
2865
+ menu,
2866
+ ...props.item.actionProps
2867
+ })
1652
2868
  });
1653
2869
  };
1654
2870
 
@@ -1694,6 +2910,7 @@ const DashboardShell = (props) => {
1694
2910
  return /* @__PURE__ */ jsxs(AppShell, {
1695
2911
  layout: "alt",
1696
2912
  w: "100%",
2913
+ h: "100vh",
1697
2914
  flex: 1,
1698
2915
  header: hasAppBar ? { height: hHeight } : void 0,
1699
2916
  navbar: hasSidebar ? {
@@ -1712,13 +2929,12 @@ const DashboardShell = (props) => {
1712
2929
  })
1713
2930
  }),
1714
2931
  hasSidebar && /* @__PURE__ */ jsxs(AppShell.Navbar, {
1715
- className: "alepha-sidebar-navbar",
1716
2932
  ...props.appShellNavbarProps,
1717
2933
  children: [
1718
2934
  props.navbarHeader ? /* @__PURE__ */ jsx(Flex, {
1719
2935
  style: { borderBottom: "1px solid var(--mantine-color-default-border)" },
1720
2936
  h: headerHeight,
1721
- children: props.navbarHeader
2937
+ children: props.navbarHeader({ collapsed })
1722
2938
  }) : null,
1723
2939
  /* @__PURE__ */ jsx(Sidebar, {
1724
2940
  ...props.sidebarProps ?? {},
@@ -1732,6 +2948,8 @@ const DashboardShell = (props) => {
1732
2948
  ]
1733
2949
  }),
1734
2950
  /* @__PURE__ */ jsx(AppShell.Main, {
2951
+ display: "flex",
2952
+ bg: "var(--alepha-ground)",
1735
2953
  pos: "relative",
1736
2954
  ...props.appShellMainProps,
1737
2955
  children: props.children ?? /* @__PURE__ */ jsx(NestedView, {})
@@ -1760,7 +2978,7 @@ const Text = forwardRef((props, ref) => {
1760
2978
  if (light) rest.fw ??= 300;
1761
2979
  if (italic) rest.fs ??= "italic";
1762
2980
  if (muted) rest.c ??= "dimmed";
1763
- if (small) rest.size ??= "sm";
2981
+ if (small) rest.size ??= "xs";
1764
2982
  if (uppercase) rest.tt ??= "uppercase";
1765
2983
  if (capitalize) rest.tt ??= "capitalize";
1766
2984
  if (center) rest.ta ??= "center";
@@ -3039,23 +4257,6 @@ const renderIcon = (icon, size) => {
3039
4257
  return icon;
3040
4258
  };
3041
4259
 
3042
- //#endregion
3043
- //#region ../../src/core/hooks/useDialog.ts
3044
- /**
3045
- * Use this hook to access the Dialog Service for showing various dialog types.
3046
- *
3047
- * @example
3048
- * ```tsx
3049
- * const dialog = useDialog();
3050
- * await dialog.alert({ title: "Alert", message: "This is an alert message" });
3051
- * const confirmed = await dialog.confirm({ title: "Confirm", message: "Are you sure?" });
3052
- * const input = await dialog.prompt({ title: "Input", message: "Enter your name:" });
3053
- * ```
3054
- */
3055
- const useDialog = () => {
3056
- return useInject(DialogService);
3057
- };
3058
-
3059
4260
  //#endregion
3060
4261
  //#region ../../src/core/json/components/JsonViewer.tsx
3061
4262
  const SIZE_CONFIG = {
@@ -3408,8 +4609,9 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
3408
4609
  return /* @__PURE__ */ jsx(Flex$1, {
3409
4610
  w: "100%",
3410
4611
  p: "xs",
4612
+ m: "xs",
4613
+ bdrs: "md",
3411
4614
  bg: ui.colors.surface,
3412
- style: { borderBottom: "1px solid var(--alepha-border)" },
3413
4615
  children: /* @__PURE__ */ jsx(TypeForm, {
3414
4616
  size: "xs",
3415
4617
  ...typeFormProps,
@@ -3430,48 +4632,62 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
3430
4632
 
3431
4633
  //#endregion
3432
4634
  //#region ../../src/core/table/components/DataTablePagination.tsx
3433
- const DataTablePagination = ({ page, size, totalPages, onPageChange, onSizeChange }) => {
3434
- return /* @__PURE__ */ jsxs(Flex$1, {
4635
+ const DataTablePagination = ({ page, size, totalPages, totalElements, offset, numberOfElements, onPageChange, onSizeChange }) => {
4636
+ const from = numberOfElements > 0 ? offset + 1 : 0;
4637
+ const to = offset + numberOfElements;
4638
+ return /* @__PURE__ */ jsxs(Flex, {
3435
4639
  align: "center",
3436
- justify: "end",
4640
+ justify: "space-between",
3437
4641
  gap: "md",
3438
- p: "xs",
4642
+ px: "xs",
4643
+ py: 4,
3439
4644
  style: { borderTop: "1px solid var(--alepha-border)" },
3440
- children: [/* @__PURE__ */ jsx(Flex$1, { children: /* @__PURE__ */ jsx(Select, {
3441
- w: 96,
3442
- variant: "default",
3443
- value: size,
3444
- onChange: (value) => {
3445
- if (value) onSizeChange(Number(value));
3446
- },
3447
- data: [
3448
- {
3449
- value: "5",
3450
- label: "5"
3451
- },
3452
- {
3453
- value: "10",
3454
- label: "10"
3455
- },
3456
- {
3457
- value: "25",
3458
- label: "25"
3459
- },
3460
- {
3461
- value: "50",
3462
- label: "50"
4645
+ children: [/* @__PURE__ */ jsx(Flex, {
4646
+ align: "center",
4647
+ children: /* @__PURE__ */ jsx(Text, {
4648
+ size: "xs",
4649
+ c: "dimmed",
4650
+ children: totalElements != null ? `Showing ${from} - ${to} of ${totalElements}` : `Showing ${from} - ${to}`
4651
+ })
4652
+ }), /* @__PURE__ */ jsxs(Flex, {
4653
+ align: "center",
4654
+ gap: "md",
4655
+ children: [/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(Select, {
4656
+ color: "gray",
4657
+ c: "gray",
4658
+ size: "xs",
4659
+ w: 96,
4660
+ variant: "default",
4661
+ value: size,
4662
+ onChange: (value) => {
4663
+ if (value) onSizeChange(Number(value));
3463
4664
  },
3464
- {
3465
- value: "100",
3466
- label: "100"
3467
- }
3468
- ]
3469
- }) }), /* @__PURE__ */ jsx(Flex$1, { children: /* @__PURE__ */ jsx(Pagination, {
3470
- withEdges: true,
3471
- total: totalPages,
3472
- value: page,
3473
- onChange: onPageChange
3474
- }) })]
4665
+ data: [
4666
+ {
4667
+ value: "10",
4668
+ label: "10"
4669
+ },
4670
+ {
4671
+ value: "25",
4672
+ label: "25"
4673
+ },
4674
+ {
4675
+ value: "50",
4676
+ label: "50"
4677
+ },
4678
+ {
4679
+ value: "100",
4680
+ label: "100"
4681
+ }
4682
+ ]
4683
+ }) }), /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(Pagination, {
4684
+ size: "sm",
4685
+ withEdges: true,
4686
+ total: totalPages,
4687
+ value: page,
4688
+ onChange: onPageChange
4689
+ }) })]
4690
+ })]
3475
4691
  });
3476
4692
  };
3477
4693
 
@@ -3693,7 +4909,7 @@ const extractText = (node) => {
3693
4909
  const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility, onColumnVisibilityChange, onFilterVisibilityChange, actions, onRefresh, items, withExport, selectedItems = [], checkboxActions, onClearSelection }) => {
3694
4910
  const hasSelection = selectedItems.length > 0;
3695
4911
  const exportableColumns = useCallback(() => {
3696
- return Object.entries(columns).filter(([key, col]) => !col.actions && columnVisibility[key] !== false);
4912
+ return Object.entries(columns).filter(([key]) => columnVisibility[key] !== false);
3697
4913
  }, [columns, columnVisibility]);
3698
4914
  const buildRows = useCallback(() => {
3699
4915
  const cols = exportableColumns();
@@ -3730,11 +4946,10 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
3730
4946
  };
3731
4947
  await action.onClick(ctx);
3732
4948
  };
3733
- return /* @__PURE__ */ jsxs(Flex$1, {
4949
+ return /* @__PURE__ */ jsxs(Flex, {
3734
4950
  p: "xs",
3735
- style: { borderBottom: "1px solid var(--alepha-border)" },
3736
4951
  children: [
3737
- /* @__PURE__ */ jsxs(Flex$1, {
4952
+ /* @__PURE__ */ jsxs(Flex, {
3738
4953
  gap: 4,
3739
4954
  align: "center",
3740
4955
  children: [
@@ -3789,8 +5004,8 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
3789
5004
  ] })
3790
5005
  ]
3791
5006
  }),
3792
- /* @__PURE__ */ jsx(Flex$1, { flex: 1 }),
3793
- /* @__PURE__ */ jsxs(Flex$1, {
5007
+ /* @__PURE__ */ jsx(Flex, { flex: 1 }),
5008
+ /* @__PURE__ */ jsxs(Flex, {
3794
5009
  gap: "xs",
3795
5010
  children: [actions?.map((props, index) => !isValidElement(props) ? /* @__PURE__ */ jsx(ActionButton, {
3796
5011
  ...props,
@@ -4042,7 +5257,7 @@ const DataTable = (props) => {
4042
5257
  currentPage,
4043
5258
  form
4044
5259
  ]);
4045
- const totalColumns = visibleColumns.length + (panelConfig ? 1 : 0) + (props.withCheckbox ? 1 : 0);
5260
+ const totalColumns = visibleColumns.length + (panelConfig ? 1 : 0) + (props.withCheckbox ? 1 : 0) + (props.rowActions ? 1 : 0);
4046
5261
  const checkboxHeader = props.withCheckbox ? /* @__PURE__ */ jsx(Table.Th, {
4047
5262
  style: { width: 40 },
4048
5263
  children: /* @__PURE__ */ jsx(Checkbox, {
@@ -4065,13 +5280,15 @@ const DataTable = (props) => {
4065
5280
  userSelect: "none"
4066
5281
  } : {}
4067
5282
  },
4068
- children: /* @__PURE__ */ jsxs(Flex$1, {
5283
+ children: /* @__PURE__ */ jsxs(Flex, {
4069
5284
  align: "center",
4070
5285
  gap: 4,
4071
- children: [/* @__PURE__ */ jsx(Text$1, {
5286
+ children: [/* @__PURE__ */ jsx(Text, {
5287
+ bold: true,
5288
+ muted: true,
4072
5289
  size: "xs",
4073
5290
  children: col.label
4074
- }), col.sortable && /* @__PURE__ */ jsxs(Flex$1, {
5291
+ }), col.sortable && /* @__PURE__ */ jsxs(Flex, {
4075
5292
  c: "dimmed",
4076
5293
  children: [
4077
5294
  sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.sm }),
@@ -4113,7 +5330,7 @@ const DataTable = (props) => {
4113
5330
  toggleExpand(itemKey);
4114
5331
  },
4115
5332
  style: { display: "inline-flex" },
4116
- children: /* @__PURE__ */ jsx(Flex$1, {
5333
+ children: /* @__PURE__ */ jsx(Flex, {
4117
5334
  c: "dimmed",
4118
5335
  align: "center",
4119
5336
  justify: "center",
@@ -4136,32 +5353,40 @@ const DataTable = (props) => {
4136
5353
  form,
4137
5354
  alepha
4138
5355
  };
4139
- if (col.actions) {
4140
- const rowActions = col.actions(item, ctx).filter((a) => a.visible !== false);
4141
- return /* @__PURE__ */ jsx(Table.Td, {
4142
- py: 2,
4143
- px: 4,
4144
- style: col.fit ? FIT_STYLE : void 0,
4145
- onClick: (e) => e.stopPropagation(),
4146
- children: /* @__PURE__ */ jsx(Flex$1, {
4147
- gap: 4,
4148
- children: rowActions.map(({ visible: _, ...actionProps }, i) => /* @__PURE__ */ jsx(ActionButton, {
4149
- variant: "subtle",
4150
- size: "xs",
4151
- preventDefault: true,
4152
- h: 20,
4153
- ...actionProps
4154
- }, i))
4155
- })
4156
- }, key);
4157
- }
4158
5356
  return /* @__PURE__ */ jsx(Table.Td, {
4159
- py: 2,
4160
- px: 4,
4161
5357
  style: col.fit ? FIT_STYLE : void 0,
4162
5358
  children: col.value?.(item, ctx)
4163
5359
  }, key);
4164
- })
5360
+ }),
5361
+ props.rowActions && (() => {
5362
+ const ctx = {
5363
+ index,
5364
+ form,
5365
+ alepha
5366
+ };
5367
+ const actions = props.rowActions(item, ctx).filter((a) => a.visible !== false);
5368
+ if (actions.length === 0) return /* @__PURE__ */ jsx(Table.Td, { style: FIT_STYLE });
5369
+ return /* @__PURE__ */ jsx(Table.Td, {
5370
+ py: 2,
5371
+ px: 4,
5372
+ style: FIT_STYLE,
5373
+ onClick: (e) => e.stopPropagation(),
5374
+ children: /* @__PURE__ */ jsx(ActionButton, {
5375
+ variant: "subtle",
5376
+ size: "xs",
5377
+ icon: IconDotsVertical,
5378
+ menu: { items: actions.map((action) => {
5379
+ const Icon = action.icon;
5380
+ return {
5381
+ label: action.label ?? (typeof action.tooltip === "string" ? action.tooltip : void 0),
5382
+ icon: Icon && isComponentType(Icon) ? /* @__PURE__ */ jsx(Icon, { size: 14 }) : Icon,
5383
+ onClick: action.onClick,
5384
+ color: action.color
5385
+ };
5386
+ }) }
5387
+ })
5388
+ });
5389
+ })()
4165
5390
  ]
4166
5391
  }, itemKey)];
4167
5392
  if (panelConfig && showPanel && isExpanded) elements.push(/* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
@@ -4179,13 +5404,19 @@ const DataTable = (props) => {
4179
5404
  "sort"
4180
5405
  ]);
4181
5406
  }, [props.filters, form.options.schema]);
4182
- return /* @__PURE__ */ jsxs(Flex$1, {
5407
+ return /* @__PURE__ */ jsxs(Flex, {
5408
+ gap: "xs",
4183
5409
  flex: 1,
4184
5410
  p: 0,
4185
- bdrs: "sm",
4186
5411
  direction: "column",
4187
- children: [
4188
- /* @__PURE__ */ jsx(DataTableToolbar, {
5412
+ style: { overflow: "hidden" },
5413
+ children: [/* @__PURE__ */ jsxs(Flex, {
5414
+ rounded: true,
5415
+ bordered: true,
5416
+ elevated: true,
5417
+ shadowed: "xs",
5418
+ col: true,
5419
+ children: [/* @__PURE__ */ jsx(DataTableToolbar, {
4189
5420
  columns: props.columns,
4190
5421
  filters: props.filters,
4191
5422
  columnVisibility,
@@ -4199,71 +5430,81 @@ const DataTable = (props) => {
4199
5430
  selectedItems: selection.selectedItems,
4200
5431
  checkboxActions: props.checkboxActions,
4201
5432
  onClearSelection: selection.clear
4202
- }),
4203
- filterSchema && props.filters && /* @__PURE__ */ jsx(DataTableFilters, {
5433
+ }), filterSchema && props.filters && /* @__PURE__ */ jsx(DataTableFilters, {
4204
5434
  schema: filterSchema,
4205
5435
  form,
4206
5436
  typeFormProps: props.typeFormProps,
4207
5437
  filterVisibility
4208
- }),
4209
- /* @__PURE__ */ jsx(Flex$1, {
4210
- className: "overflow-auto",
4211
- children: /* @__PURE__ */ jsxs(Table, {
4212
- "aria-label": "Data table",
4213
- withColumnBorders: true,
4214
- withRowBorders: true,
4215
- ...props.tableProps,
4216
- children: [/* @__PURE__ */ jsx(Table.Thead, {
4217
- style: {
4218
- position: "sticky",
4219
- top: 0,
4220
- zIndex: 1,
4221
- backgroundColor: "var(--mantine-color-body)"
4222
- },
4223
- children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
4224
- panelConfig && /* @__PURE__ */ jsx(Table.Th, { style: { width: 36 } }),
4225
- checkboxHeader,
4226
- head
4227
- ] })
4228
- }), /* @__PURE__ */ jsxs(Table.Tbody, {
4229
- style: {
4230
- opacity: form.submitting ? .5 : 1,
4231
- transition: "opacity 150ms ease"
4232
- },
4233
- children: [rows, items.content.length === 0 && /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
4234
- colSpan: totalColumns || 1,
4235
- py: "xl",
4236
- style: { textAlign: "center" },
4237
- children: /* @__PURE__ */ jsx(Text$1, {
4238
- c: "dimmed",
4239
- size: "sm",
4240
- children: form.submitting ? "Loading…" : "No results"
4241
- })
4242
- }) })]
4243
- })]
5438
+ })]
5439
+ }), /* @__PURE__ */ jsxs(Flex, {
5440
+ col: true,
5441
+ rounded: true,
5442
+ bordered: true,
5443
+ elevated: true,
5444
+ shadowed: "xs",
5445
+ children: [
5446
+ /* @__PURE__ */ jsx(Flex, {
5447
+ className: "overflow-auto",
5448
+ children: /* @__PURE__ */ jsxs(Table, {
5449
+ "aria-label": "Data table",
5450
+ withRowBorders: true,
5451
+ highlightOnHover: true,
5452
+ ...props.tableProps,
5453
+ children: [/* @__PURE__ */ jsx(Table.Thead, {
5454
+ style: {
5455
+ position: "sticky",
5456
+ top: 0,
5457
+ zIndex: 1
5458
+ },
5459
+ children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
5460
+ panelConfig && /* @__PURE__ */ jsx(Table.Th, { style: { width: 36 } }),
5461
+ checkboxHeader,
5462
+ head,
5463
+ props.rowActions && /* @__PURE__ */ jsx(Table.Th, { style: FIT_STYLE })
5464
+ ] })
5465
+ }), /* @__PURE__ */ jsxs(Table.Tbody, {
5466
+ style: {
5467
+ opacity: form.submitting ? .5 : 1,
5468
+ transition: "opacity 150ms ease"
5469
+ },
5470
+ children: [rows, items.content.length === 0 && /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
5471
+ colSpan: totalColumns || 1,
5472
+ py: "xl",
5473
+ style: { textAlign: "center" },
5474
+ children: /* @__PURE__ */ jsx(Text, {
5475
+ c: "dimmed",
5476
+ size: "sm",
5477
+ children: form.submitting ? "Loading…" : "No results"
5478
+ })
5479
+ }) })]
5480
+ })]
5481
+ })
5482
+ }),
5483
+ props.infinityScroll && /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
5484
+ !props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
5485
+ page,
5486
+ size,
5487
+ totalPages: items.page?.totalPages ?? 1,
5488
+ totalElements: items.page?.totalElements,
5489
+ offset: items.page?.offset ?? 0,
5490
+ numberOfElements: items.content.length,
5491
+ onPageChange: (value) => {
5492
+ form.input.page.set(value - 1);
5493
+ },
5494
+ onSizeChange: (value) => {
5495
+ form.input.size.set(value);
5496
+ }
5497
+ }),
5498
+ drawerConfig && /* @__PURE__ */ jsx(Drawer, {
5499
+ opened: drawerItem !== null,
5500
+ onClose: () => setDrawerItem(null),
5501
+ position: "right",
5502
+ size: "xl",
5503
+ ...drawerConfig.props,
5504
+ children: drawerItem && drawerConfig.render(drawerItem)
4244
5505
  })
4245
- }),
4246
- props.infinityScroll && /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
4247
- !props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
4248
- page,
4249
- size,
4250
- totalPages: items.page?.totalPages ?? 1,
4251
- onPageChange: (value) => {
4252
- form.input.page.set(value - 1);
4253
- },
4254
- onSizeChange: (value) => {
4255
- form.input.size.set(value);
4256
- }
4257
- }),
4258
- drawerConfig && /* @__PURE__ */ jsx(Drawer, {
4259
- opened: drawerItem !== null,
4260
- onClose: () => setDrawerItem(null),
4261
- position: "right",
4262
- size: "xl",
4263
- ...drawerConfig.props,
4264
- children: drawerItem && drawerConfig.render(drawerItem)
4265
- })
4266
- ]
5506
+ ]
5507
+ })]
4267
5508
  });
4268
5509
  };
4269
5510
 
@@ -4505,5 +5746,5 @@ const AlephaUI = $module({
4505
5746
  });
4506
5747
 
4507
5748
  //#endregion
4508
- export { $ui, ActionButton, DashboardShell as AdminShell, DashboardShell, AlephaMantineProvider, AlephaUI, AlertDialog, AppBar, Breadcrumb as Breadcrumbs, BurgerButton, ClipboardButton, ConfirmDialog, Container, Control, ControlArray, ControlDate, ControlNumber, ControlObject, ControlQueryBuilder, ControlSelect, DarkModeButton, DataTable, DetailDrawer, DetailList, DialogService, Flex, Heading, JsonViewer, LanguageButton, OPERATOR_INFO, Omnibar, OmnibarButton, PromptDialog, Sidebar, ToggleSidebarButton as SidebarCollapseButton, StatCards, Text, ThemeButton, ThemeProvider, ToastService, TypeForm, UiRouter, alephaSidebarAtom, alephaThemeAtom, alephaThemeListAtom, capitalize, defaultTheme, dialogForm, dialogJson, extractSchemaFields, getDefaultIcon, getOperatorsForField, isComponentType, midnightTheme, prettyName, renderIcon, toTitleCase, ui, useDialog, useTheme, useToast };
5749
+ export { $ui, ActionButton, DashboardShell as AdminShell, DashboardShell, AlephaMantineProvider, AlephaUI, AlertDialog, AppBar, Breadcrumb as Breadcrumbs, BurgerButton, ClipboardButton, ConfirmDialog, Container, Control, ControlArray, ControlDate, ControlNumber, ControlObject, ControlQueryBuilder, ControlSelect, DarkModeButton, DataTable, DetailDrawer, DetailList, DialogService, Flex, Heading, JsonViewer, LanguageButton, OPERATOR_INFO, Omnibar, OmnibarButton, PromptDialog, Sidebar, ToggleSidebarButton as SidebarCollapseButton, StatCards, Text, ThemeButton, ThemeProvider, ToastService, TypeForm, UiRouter, alephaSidebarAtom, alephaThemeAtom, alephaThemeListAtom, alephaThemeOverridesAtom, capitalize, defaultTheme, dialogForm, dialogJson, extractSchemaFields, getDefaultIcon, getOperatorsForField, isComponentType, midnightTheme, prettyName, renderIcon, toTitleCase, ui, useDialog, useTheme, useToast };
4509
5750
  //# sourceMappingURL=index.js.map