@alepha/ui 0.18.2 → 0.18.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 (231) hide show
  1. package/dist/admin/{AdminApiKeys-BJhIwfD6.js → AdminApiKeys-Dy_k-4Vd.js} +2 -2
  2. package/dist/admin/{AdminApiKeys-BJhIwfD6.js.map → AdminApiKeys-Dy_k-4Vd.js.map} +1 -1
  3. package/dist/admin/{AdminAudits-DzD_4cDt.js → AdminAudits-CKiFMSSU.js} +2 -2
  4. package/dist/admin/{AdminAudits-DzD_4cDt.js.map → AdminAudits-CKiFMSSU.js.map} +1 -1
  5. package/dist/admin/{AdminDashboard-C92tIc6x.js → AdminDashboard-PhC_dZqo.js} +2 -2
  6. package/dist/admin/{AdminDashboard-C92tIc6x.js.map → AdminDashboard-PhC_dZqo.js.map} +1 -1
  7. package/dist/admin/{AdminFiles-DLpfhBkf.js → AdminFiles-DFTjijGp.js} +2 -2
  8. package/dist/admin/{AdminFiles-DLpfhBkf.js.map → AdminFiles-DFTjijGp.js.map} +1 -1
  9. package/dist/admin/{AdminJobDashboard-KIOkeMgE.js → AdminJobDashboard-BL8gGPDp.js} +2 -2
  10. package/dist/admin/{AdminJobDashboard-KIOkeMgE.js.map → AdminJobDashboard-BL8gGPDp.js.map} +1 -1
  11. package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js → AdminJobExecutions-D9E-CS-U.js} +2 -2
  12. package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js.map → AdminJobExecutions-D9E-CS-U.js.map} +1 -1
  13. package/dist/admin/{AdminJobRegistry-PFajqaGK.js → AdminJobRegistry-Ci9ue1zC.js} +2 -2
  14. package/dist/admin/{AdminJobRegistry-PFajqaGK.js.map → AdminJobRegistry-Ci9ue1zC.js.map} +1 -1
  15. package/dist/admin/{AdminLayout-B1DXZHDn.js → AdminLayout-I6TlUMPc.js} +2 -2
  16. package/dist/admin/{AdminLayout-B1DXZHDn.js.map → AdminLayout-I6TlUMPc.js.map} +1 -1
  17. package/dist/admin/AdminNotifications-ZPHCYrv7.js +542 -0
  18. package/dist/admin/AdminNotifications-ZPHCYrv7.js.map +1 -0
  19. package/dist/admin/{AdminParameters-BspPeqp_.js → AdminParameters-CqgvhRsb.js} +120 -105
  20. package/dist/admin/AdminParameters-CqgvhRsb.js.map +1 -0
  21. package/dist/admin/{AdminSessions-BnH5CZQl.js → AdminSessions-Bz5NRuoW.js} +2 -2
  22. package/dist/admin/{AdminSessions-BnH5CZQl.js.map → AdminSessions-Bz5NRuoW.js.map} +1 -1
  23. package/dist/admin/{AdminUserLayout-DUbC6-BI.js → AdminUserLayout-lXT6I0Qq.js} +14 -8
  24. package/dist/admin/AdminUserLayout-lXT6I0Qq.js.map +1 -0
  25. package/dist/admin/{AdminUserProfile-DuTUnjdG.js → AdminUserProfile-vFBLoJ3h.js} +3 -3
  26. package/dist/admin/{AdminUserProfile-DuTUnjdG.js.map → AdminUserProfile-vFBLoJ3h.js.map} +1 -1
  27. package/dist/admin/{AdminUserSessions-DvZdAGpL.js → AdminUserSessions-CT_YDim0.js} +2 -2
  28. package/dist/admin/{AdminUserSessions-DvZdAGpL.js.map → AdminUserSessions-CT_YDim0.js.map} +1 -1
  29. package/dist/admin/{AdminUsers-CR9z0g_5.js → AdminUsers-D1UfGya9.js} +2 -2
  30. package/dist/admin/{AdminUsers-CR9z0g_5.js.map → AdminUsers-D1UfGya9.js.map} +1 -1
  31. package/dist/admin/{AuthLayout-DsUfp9RG.js → AuthLayout-_frhdgOO.js} +2 -2
  32. package/dist/admin/{AuthLayout-DsUfp9RG.js.map → AuthLayout-_frhdgOO.js.map} +1 -1
  33. package/dist/admin/Login-xtNmQtGh.js +275 -0
  34. package/dist/admin/Login-xtNmQtGh.js.map +1 -0
  35. package/dist/admin/{Profile-B2EcIDB9.js → Profile-_AtPUwAP.js} +31 -27
  36. package/dist/admin/Profile-_AtPUwAP.js.map +1 -0
  37. package/dist/admin/{Register-Z3fxRbUF.js → Register-JcCjHUUn.js} +198 -142
  38. package/dist/admin/Register-JcCjHUUn.js.map +1 -0
  39. package/dist/admin/{ResetPassword-_Y1qTTKh.js → ResetPassword-CwGBPLJO.js} +7 -7
  40. package/dist/admin/ResetPassword-CwGBPLJO.js.map +1 -0
  41. package/dist/admin/{VerifyEmail-Bg22bwcC.js → VerifyEmail-hNxWejWf.js} +23 -8
  42. package/dist/admin/VerifyEmail-hNxWejWf.js.map +1 -0
  43. package/dist/admin/{core-BVO_TQxb.js → core-CYaRQ8O-.js} +709 -556
  44. package/dist/admin/core-CYaRQ8O-.js.map +1 -0
  45. package/dist/admin/index.d.ts +83 -44
  46. package/dist/admin/index.d.ts.map +1 -1
  47. package/dist/admin/index.js +58 -39
  48. package/dist/admin/index.js.map +1 -1
  49. package/dist/auth/{AuthLayout-C161NeF6.js → AuthLayout-AvLlcLjS.js} +2 -2
  50. package/dist/auth/{AuthLayout-C161NeF6.js.map → AuthLayout-AvLlcLjS.js.map} +1 -1
  51. package/dist/auth/Login-BA1E8IZl.js +275 -0
  52. package/dist/auth/Login-BA1E8IZl.js.map +1 -0
  53. package/dist/auth/{Profile-BMpXJ0oi.js → Profile-YcWdeuFz.js} +31 -27
  54. package/dist/auth/Profile-YcWdeuFz.js.map +1 -0
  55. package/dist/auth/{Register-2gx8qll-.js → Register-CPhEO5MG.js} +198 -142
  56. package/dist/auth/Register-CPhEO5MG.js.map +1 -0
  57. package/dist/{demo/ResetPassword-CAPj8MO3.js → auth/ResetPassword-DCtGcneA.js} +7 -7
  58. package/dist/auth/ResetPassword-DCtGcneA.js.map +1 -0
  59. package/dist/{demo/VerifyEmail-DFmdCdYs.js → auth/VerifyEmail-DkH7NBfn.js} +23 -8
  60. package/dist/auth/VerifyEmail-DkH7NBfn.js.map +1 -0
  61. package/dist/auth/{core-DyfeVr5c.js → core-D5jIAVF2.js} +386 -294
  62. package/dist/auth/core-D5jIAVF2.js.map +1 -0
  63. package/dist/auth/index.d.ts +93 -48
  64. package/dist/auth/index.d.ts.map +1 -1
  65. package/dist/auth/index.js +28 -24
  66. package/dist/auth/index.js.map +1 -1
  67. package/dist/core/index.d.ts +116 -61
  68. package/dist/core/index.d.ts.map +1 -1
  69. package/dist/core/index.js +873 -701
  70. package/dist/core/index.js.map +1 -1
  71. package/dist/demo/{AuthLayout-DN-ClJQk.js → AuthLayout-Brri4A-L.js} +2 -2
  72. package/dist/demo/{AuthLayout-DN-ClJQk.js.map → AuthLayout-Brri4A-L.js.map} +1 -1
  73. package/dist/demo/DemoButton-wiCxZZ_L.js +182 -0
  74. package/dist/demo/DemoButton-wiCxZZ_L.js.map +1 -0
  75. package/dist/demo/DemoControlSelect-D7ILObVg.js +305 -0
  76. package/dist/demo/DemoControlSelect-D7ILObVg.js.map +1 -0
  77. package/dist/demo/DemoDataTable-DZ5Y8pFX.js +362 -0
  78. package/dist/demo/DemoDataTable-DZ5Y8pFX.js.map +1 -0
  79. package/dist/demo/{DemoDialog-DW8QEvD1.js → DemoDialog-CUWdLHim.js} +2 -2
  80. package/dist/demo/{DemoDialog-DW8QEvD1.js.map → DemoDialog-CUWdLHim.js.map} +1 -1
  81. package/dist/demo/{DemoFlex-CAhLUanT.js → DemoFlex-a8OhMMvq.js} +3 -3
  82. package/dist/demo/{DemoFlex-CAhLUanT.js.map → DemoFlex-a8OhMMvq.js.map} +1 -1
  83. package/dist/demo/{DemoHeading-yIFmNjHB.js → DemoHeading-C13OVDfS.js} +3 -3
  84. package/dist/demo/{DemoHeading-yIFmNjHB.js.map → DemoHeading-C13OVDfS.js.map} +1 -1
  85. package/dist/demo/{DemoHome-BSGuBHus.js → DemoHome-D_De3UiT.js} +2 -2
  86. package/dist/demo/{DemoHome-BSGuBHus.js.map → DemoHome-D_De3UiT.js.map} +1 -1
  87. package/dist/demo/{DemoJsonViewer-DsA2IpgV.js → DemoJsonViewer-B50s9aGM.js} +3 -3
  88. package/dist/demo/{DemoJsonViewer-DsA2IpgV.js.map → DemoJsonViewer-B50s9aGM.js.map} +1 -1
  89. package/dist/demo/{DemoLayout-Cy6xjn6P.js → DemoLayout-CHU8WTwO.js} +14 -5
  90. package/dist/demo/DemoLayout-CHU8WTwO.js.map +1 -0
  91. package/dist/demo/{DemoLogin-vqxgTu4P.js → DemoLogin-BBlrWpml.js} +49 -32
  92. package/dist/demo/DemoLogin-BBlrWpml.js.map +1 -0
  93. package/dist/demo/{DemoRegister-YHPvPg77.js → DemoRegister-BuNE3_-f.js} +49 -50
  94. package/dist/demo/DemoRegister-BuNE3_-f.js.map +1 -0
  95. package/dist/demo/{DemoResetPassword-mOW18Zlm.js → DemoResetPassword-D_IjjjOJ.js} +12 -16
  96. package/dist/demo/DemoResetPassword-D_IjjjOJ.js.map +1 -0
  97. package/dist/demo/{DemoSidebar-od7aLjP_.js → DemoSidebar-Giy2HRBD.js} +3 -3
  98. package/dist/demo/{DemoSidebar-od7aLjP_.js.map → DemoSidebar-Giy2HRBD.js.map} +1 -1
  99. package/dist/demo/{DemoText-DU3JeRS0.js → DemoText-ubcw-vog.js} +3 -3
  100. package/dist/demo/{DemoText-DU3JeRS0.js.map → DemoText-ubcw-vog.js.map} +1 -1
  101. package/dist/demo/{DemoToast-CUJEiPRa.js → DemoToast-9die_dYT.js} +2 -2
  102. package/dist/demo/{DemoToast-CUJEiPRa.js.map → DemoToast-9die_dYT.js.map} +1 -1
  103. package/dist/demo/{DemoTypeForm-C1dNkahD.js → DemoTypeForm-D_d6OVKL.js} +8 -4
  104. package/dist/demo/DemoTypeForm-D_d6OVKL.js.map +1 -0
  105. package/dist/demo/DemoVerifyEmail-B43KlF4F.js +34 -0
  106. package/dist/demo/DemoVerifyEmail-B43KlF4F.js.map +1 -0
  107. package/dist/demo/Login-C12N4oGs.js +275 -0
  108. package/dist/demo/Login-C12N4oGs.js.map +1 -0
  109. package/dist/demo/{Profile-BE_Y3co2.js → Profile-DS5q4vOh.js} +31 -27
  110. package/dist/demo/Profile-DS5q4vOh.js.map +1 -0
  111. package/dist/demo/{Register-fXHmBpr3.js → Register-B4hLBeEv.js} +198 -142
  112. package/dist/demo/Register-B4hLBeEv.js.map +1 -0
  113. package/dist/{auth/ResetPassword-DBxt9hKk.js → demo/ResetPassword-D8g9ha1N.js} +7 -7
  114. package/dist/demo/ResetPassword-D8g9ha1N.js.map +1 -0
  115. package/dist/demo/{Showcase-BtEU0pY9.js → Showcase-D6Fxt4X4.js} +64 -65
  116. package/dist/demo/Showcase-D6Fxt4X4.js.map +1 -0
  117. package/dist/{auth/VerifyEmail-Z80Ubajk.js → demo/VerifyEmail-BjDo0cZA.js} +23 -8
  118. package/dist/demo/VerifyEmail-BjDo0cZA.js.map +1 -0
  119. package/dist/demo/{auth-Djd7SKiw.js → auth-ByVTreDl.js} +8 -8
  120. package/dist/demo/{auth-Djd7SKiw.js.map → auth-ByVTreDl.js.map} +1 -1
  121. package/dist/demo/{core-B7LNjM78.js → core-DFgB3yU4.js} +741 -573
  122. package/dist/demo/core-DFgB3yU4.js.map +1 -0
  123. package/dist/demo/index.d.ts +1 -0
  124. package/dist/demo/index.d.ts.map +1 -1
  125. package/dist/demo/index.js +24 -18
  126. package/dist/demo/index.js.map +1 -1
  127. package/package.json +7 -7
  128. package/src/admin/AdminRouter.tsx +24 -1
  129. package/src/admin/components/notifications/AdminNotifications.tsx +519 -0
  130. package/src/admin/components/parameters/ParameterDetails.tsx +12 -270
  131. package/src/admin/components/parameters/ParameterDetailsConfigForm.tsx +238 -0
  132. package/src/admin/components/parameters/ParameterDetailsLoading.tsx +24 -0
  133. package/src/admin/components/parameters/ParameterHistory.tsx +10 -11
  134. package/src/admin/components/parameters/ParameterTree.tsx +28 -184
  135. package/src/admin/components/parameters/ParameterTreeNode.tsx +151 -0
  136. package/src/admin/components/shared/AdminResourceHeader.tsx +2 -25
  137. package/src/admin/components/shared/AdminResourceHeaderMenuItem.tsx +37 -0
  138. package/src/admin/components/shared/AdminResourceTabs.tsx +2 -26
  139. package/src/admin/components/shared/AdminResourceTabsItem.tsx +36 -0
  140. package/src/auth/components/Login.tsx +188 -121
  141. package/src/auth/components/Profile.tsx +1 -22
  142. package/src/auth/components/ProfileField.tsx +39 -0
  143. package/src/auth/components/Register.tsx +215 -158
  144. package/src/auth/components/ResetPassword.tsx +7 -11
  145. package/src/auth/components/VerifyEmail.tsx +35 -10
  146. package/src/auth/components/buttons/UserButton.tsx +19 -21
  147. package/src/auth/index.ts +1 -0
  148. package/src/core/components/Flex.tsx +10 -0
  149. package/src/core/components/buttons/ActionButton.tsx +104 -78
  150. package/src/core/components/data/DetailDrawer.tsx +102 -96
  151. package/src/core/components/data/DetailList.tsx +2 -1
  152. package/src/core/components/layout/Breadcrumb.tsx +3 -6
  153. package/src/core/components/layout/DashboardShell.tsx +18 -4
  154. package/src/core/components/layout/Sidebar.tsx +16 -241
  155. package/src/core/components/layout/SidebarCollapsedItem.tsx +91 -0
  156. package/src/core/components/layout/SidebarItem.tsx +146 -0
  157. package/src/core/components/layout/index.ts +3 -1
  158. package/src/core/form/components/Control.tsx +31 -29
  159. package/src/core/form/components/ControlArray.tsx +13 -39
  160. package/src/core/form/components/ControlDate.tsx +10 -21
  161. package/src/core/form/components/ControlNumber.tsx +4 -33
  162. package/src/core/form/components/ControlQueryBuilder.tsx +12 -175
  163. package/src/core/form/components/ControlQueryBuilderHelp.tsx +165 -0
  164. package/src/core/form/components/ControlSelect.browser.spec.tsx +343 -0
  165. package/src/core/form/components/ControlSelect.tsx +294 -92
  166. package/src/core/form/components/TypeForm.browser.spec.tsx +3 -3
  167. package/src/core/form/components/TypeForm.tsx +5 -2
  168. package/src/core/form/index.ts +8 -1
  169. package/src/core/form/utils/parseInput.ts +7 -3
  170. package/src/core/index.ts +3 -1
  171. package/src/core/json/components/JsonViewer.tsx +103 -319
  172. package/src/core/json/components/JsonViewerCopyButton.tsx +46 -0
  173. package/src/core/json/components/JsonViewerRowNode.tsx +120 -0
  174. package/src/core/json/components/JsonViewerShared.ts +76 -0
  175. package/src/core/styles.css +12 -2
  176. package/src/core/table/components/ColumnPicker.tsx +3 -3
  177. package/src/core/table/components/DataTable.tsx +89 -29
  178. package/src/core/table/components/DataTableFilters.tsx +6 -11
  179. package/src/core/table/components/DataTablePagination.tsx +9 -3
  180. package/src/core/table/components/DataTableToolbar.tsx +7 -3
  181. package/src/core/table/components/FilterPicker.tsx +3 -3
  182. package/src/core/table/interfaces/types.ts +29 -0
  183. package/src/core/utils/icons.tsx +2 -2
  184. package/src/demo/DemoRouter.ts +8 -1
  185. package/src/demo/components/DemoLayout.tsx +12 -2
  186. package/src/demo/components/auth/DemoLogin.tsx +35 -28
  187. package/src/demo/components/auth/DemoRegister.tsx +35 -49
  188. package/src/demo/components/auth/DemoResetPassword.tsx +5 -9
  189. package/src/demo/components/auth/DemoVerifyEmail.tsx +7 -6
  190. package/src/demo/components/core/DemoButton.tsx +123 -103
  191. package/src/demo/components/core/DemoControlSelect.tsx +325 -0
  192. package/src/demo/components/core/DemoDataTable.tsx +255 -237
  193. package/src/demo/components/core/DemoTypeForm.tsx +7 -2
  194. package/src/demo/components/shared/MacWindow.tsx +5 -11
  195. package/src/demo/components/shared/Showcase.tsx +28 -42
  196. package/dist/admin/AdminParameters-BspPeqp_.js.map +0 -1
  197. package/dist/admin/AdminUserLayout-DUbC6-BI.js.map +0 -1
  198. package/dist/admin/Login-DHbYJKwg.js +0 -219
  199. package/dist/admin/Login-DHbYJKwg.js.map +0 -1
  200. package/dist/admin/Profile-B2EcIDB9.js.map +0 -1
  201. package/dist/admin/Register-Z3fxRbUF.js.map +0 -1
  202. package/dist/admin/ResetPassword-_Y1qTTKh.js.map +0 -1
  203. package/dist/admin/VerifyEmail-Bg22bwcC.js.map +0 -1
  204. package/dist/admin/core-BVO_TQxb.js.map +0 -1
  205. package/dist/auth/Login-C7jIqf00.js +0 -219
  206. package/dist/auth/Login-C7jIqf00.js.map +0 -1
  207. package/dist/auth/Profile-BMpXJ0oi.js.map +0 -1
  208. package/dist/auth/Register-2gx8qll-.js.map +0 -1
  209. package/dist/auth/ResetPassword-DBxt9hKk.js.map +0 -1
  210. package/dist/auth/VerifyEmail-Z80Ubajk.js.map +0 -1
  211. package/dist/auth/core-DyfeVr5c.js.map +0 -1
  212. package/dist/demo/DemoButton-CGUyR9eM.js +0 -178
  213. package/dist/demo/DemoButton-CGUyR9eM.js.map +0 -1
  214. package/dist/demo/DemoDataTable-QFG-xXSx.js +0 -358
  215. package/dist/demo/DemoDataTable-QFG-xXSx.js.map +0 -1
  216. package/dist/demo/DemoLayout-Cy6xjn6P.js.map +0 -1
  217. package/dist/demo/DemoLogin-vqxgTu4P.js.map +0 -1
  218. package/dist/demo/DemoRegister-YHPvPg77.js.map +0 -1
  219. package/dist/demo/DemoResetPassword-mOW18Zlm.js.map +0 -1
  220. package/dist/demo/DemoTypeForm-C1dNkahD.js.map +0 -1
  221. package/dist/demo/DemoVerifyEmail-D9EcXZ38.js +0 -30
  222. package/dist/demo/DemoVerifyEmail-D9EcXZ38.js.map +0 -1
  223. package/dist/demo/Login-CoYf_P_F.js +0 -219
  224. package/dist/demo/Login-CoYf_P_F.js.map +0 -1
  225. package/dist/demo/Profile-BE_Y3co2.js.map +0 -1
  226. package/dist/demo/Register-fXHmBpr3.js.map +0 -1
  227. package/dist/demo/ResetPassword-CAPj8MO3.js.map +0 -1
  228. package/dist/demo/Showcase-BtEU0pY9.js.map +0 -1
  229. package/dist/demo/VerifyEmail-DFmdCdYs.js.map +0 -1
  230. package/dist/demo/core-B7LNjM78.js.map +0 -1
  231. package/src/demo/styles.css +0 -0
@@ -1,31 +1,17 @@
1
- import {
2
- ActionButton,
3
- type ActionMenuConfig,
4
- type ActionMenuItem,
5
- type ActionProps,
6
- Flex,
7
- OmnibarButton,
8
- renderIcon,
9
- SidebarCollapseButton,
10
- Text,
11
- ui,
12
- } from "@alepha/ui";
13
1
  import type { FlexProps, MantineBreakpoint } from "@mantine/core";
14
- import {
15
- IconChevronDown,
16
- IconChevronRight,
17
- IconSquareRounded,
18
- } from "@tabler/icons-react";
19
- import { useEvents } from "alepha/react";
20
2
  import { useRouter } from "alepha/react/router";
21
- import {
22
- type ComponentType,
23
- Fragment,
24
- type ReactNode,
25
- useCallback,
26
- useMemo,
27
- useState,
28
- } from "react";
3
+ import { type ComponentType, Fragment, type ReactNode, useMemo } from "react";
4
+ import { ui } from "../../constants/ui.ts";
5
+ import { renderIcon } from "../../helpers/renderIcon.tsx";
6
+ import type { ActionProps } from "../buttons/ActionButton.tsx";
7
+ import OmnibarButton from "../buttons/OmnibarButton.tsx";
8
+ import SidebarCollapseButton from "../buttons/ToggleSidebarButton.tsx";
9
+ import Flex from "../Flex.tsx";
10
+ import Text from "../Text.tsx";
11
+ import { SidebarCollapsedItem } from "./SidebarCollapsedItem.tsx";
12
+ import { SidebarItem } from "./SidebarItem.tsx";
13
+
14
+ // ---------------------------------------------------------------------------------------------------------------------
29
15
 
30
16
  export interface SidebarProps {
31
17
  items?: SidebarNode[];
@@ -49,9 +35,10 @@ export interface SidebarProps {
49
35
  };
50
36
  }
51
37
 
38
+ // ---------------------------------------------------------------------------------------------------------------------
39
+
52
40
  export const Sidebar = (props: SidebarProps) => {
53
41
  const router = useRouter();
54
- const { onItemClick } = props;
55
42
 
56
43
  const divider = (
57
44
  key: string | number,
@@ -160,7 +147,7 @@ export const Sidebar = (props: SidebarProps) => {
160
147
  key={key}
161
148
  item={item}
162
149
  level={0}
163
- onItemClick={onItemClick}
150
+ onItemClick={props.onItemClick}
164
151
  theme={props.theme ?? {}}
165
152
  />
166
153
  );
@@ -171,7 +158,7 @@ export const Sidebar = (props: SidebarProps) => {
171
158
  key={key}
172
159
  item={item}
173
160
  level={0}
174
- onItemClick={onItemClick}
161
+ onItemClick={props.onItemClick}
175
162
  theme={props.theme ?? {}}
176
163
  />
177
164
  );
@@ -248,218 +235,6 @@ export const Sidebar = (props: SidebarProps) => {
248
235
 
249
236
  // ---------------------------------------------------------------------------------------------------------------------
250
237
 
251
- export interface SidebarItemProps {
252
- item: SidebarMenuItem;
253
- level: number;
254
- onItemClick?: (item: SidebarMenuItem) => void;
255
- theme: SidebarTheme;
256
- }
257
-
258
- export const SidebarItem = (props: SidebarItemProps) => {
259
- const { item, level } = props;
260
- const maxLevel = 2; // 0, 1, 2 = 3 levels total
261
-
262
- const router = useRouter();
263
- const isActive = useCallback((item: SidebarMenuItem): boolean => {
264
- if (!item.children) return false;
265
- for (const child of item.children) {
266
- if (child.href) {
267
- if (router.isActive(child.href)) {
268
- return true;
269
- }
270
- }
271
- if (isActive(child)) {
272
- return true;
273
- }
274
- }
275
- return false;
276
- }, []);
277
-
278
- const [isOpen, setIsOpen] = useState<boolean>(isActive(item));
279
-
280
- useEvents(
281
- {
282
- "react:transition:end": () => {
283
- // recalculate open state on transition end to ensure correct state after navigation
284
- if (isActive(item)) {
285
- setIsOpen(true);
286
- }
287
- },
288
- },
289
- [],
290
- );
291
-
292
- if (level > maxLevel) return null;
293
-
294
- const handleItemClick = (e: MouseEvent) => {
295
- if (!props.item.target) {
296
- e.preventDefault();
297
- }
298
- if (item.children && item.children.length > 0) {
299
- setIsOpen(!isOpen);
300
- } else {
301
- props.onItemClick?.(item);
302
- item.onClick?.();
303
- }
304
- };
305
-
306
- return (
307
- <Flex direction={"column"} ps={level === 0 ? 0 : 32} pos={"relative"}>
308
- <ActionButton
309
- w={"100%"}
310
- justify="space-between"
311
- href={props.item.href}
312
- target={props.item.target}
313
- size={
314
- props.item.theme?.size ??
315
- props.theme.button?.size ??
316
- (level === 0 ? "sm" : "xs")
317
- }
318
- bd={0}
319
- fw={"normal"}
320
- variant={"default"}
321
- propsActive={{
322
- variant: "outline",
323
- }}
324
- radius={props.item.theme?.radius ?? props.theme.button?.radius ?? "md"}
325
- onClick={handleItemClick}
326
- leftSection={
327
- <Flex w={"100%"} align="center" gap={"sm"}>
328
- {renderIcon(item.icon, ui.sizes.icon.sm)}
329
- <Flex direction={"column"}>
330
- <Flex>{item.label}</Flex>
331
- </Flex>
332
- </Flex>
333
- }
334
- rightSection={
335
- item.children ? (
336
- <Flex>
337
- {isOpen ? (
338
- <IconChevronDown size={14} />
339
- ) : (
340
- <IconChevronRight size={14} />
341
- )}
342
- </Flex>
343
- ) : (
344
- props.item.rightSection
345
- )
346
- }
347
- {...props.item.actionProps}
348
- />
349
-
350
- {item.children && isOpen && (
351
- <Flex direction={"column"} data-parent-level={level} gap={2} py={2}>
352
- <Flex
353
- style={{
354
- position: "absolute",
355
- width: 1,
356
- background:
357
- "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
358
- top: 48,
359
- left: 20 + 32 * level,
360
- bottom: 16,
361
- }}
362
- />
363
- {item.children
364
- .filter((child) => !child.can || child.can())
365
- .map((child, index) => (
366
- <SidebarItem
367
- key={index}
368
- item={child}
369
- level={level + 1}
370
- onItemClick={props.onItemClick}
371
- theme={props.theme}
372
- />
373
- ))}
374
- </Flex>
375
- )}
376
- </Flex>
377
- );
378
- };
379
-
380
- // ---------------------------------------------------------------------------------------------------------------------
381
-
382
- const SidebarCollapsedItem = (props: SidebarItemProps) => {
383
- const { item, level } = props;
384
- const router = useRouter();
385
-
386
- const handleItemClick = () => {
387
- props.onItemClick?.(item);
388
- item.onClick?.();
389
- };
390
-
391
- const hasChildren = item.children && item.children.length > 0;
392
-
393
- const menu: ActionMenuConfig | undefined = hasChildren
394
- ? {
395
- on: "hover",
396
- position: "right",
397
- menuProps: {
398
- arrowPosition: "center",
399
- arrowSize: 10,
400
- withArrow: true,
401
- },
402
- items: [
403
- {
404
- type: "label",
405
- label: item.label,
406
- },
407
- ...item
408
- .children!.filter((child) => !child.can || child.can())
409
- .map(
410
- (child): ActionMenuItem => ({
411
- label: child.label as string,
412
- icon: renderIcon(child.icon, ui.sizes.icon.sm),
413
- href: child.href,
414
- active: child.href
415
- ? router.isActive(child.href, {
416
- startWith: child.activeStartsWith,
417
- })
418
- : undefined,
419
- }),
420
- ),
421
- ],
422
- }
423
- : undefined;
424
-
425
- return (
426
- <Flex w={"100%"} justify="center" pos={"relative"}>
427
- <ActionButton
428
- size={
429
- props.item.theme?.size ??
430
- props.theme.button?.size ??
431
- (level === 0 ? "sm" : "xs")
432
- }
433
- bd={0}
434
- variant={"default"}
435
- propsActive={{
436
- variant: "outline",
437
- }}
438
- tooltip={
439
- hasChildren
440
- ? undefined
441
- : {
442
- label: item.label,
443
- position: "right",
444
- }
445
- }
446
- onClick={hasChildren ? undefined : handleItemClick}
447
- icon={
448
- renderIcon(item.icon, ui.sizes.icon.sm) ?? (
449
- <IconSquareRounded size={ui.sizes.icon.sm} />
450
- )
451
- }
452
- href={hasChildren ? undefined : (props.item.href as any)}
453
- target={hasChildren ? undefined : props.item.target}
454
- menu={menu}
455
- {...props.item.actionProps}
456
- />
457
- </Flex>
458
- );
459
- };
460
-
461
- // ---------------------------------------------------------------------------------------------------------------------
462
-
463
238
  export type SidebarNode =
464
239
  | SidebarMenuItem
465
240
  | SidebarSpacer
@@ -0,0 +1,91 @@
1
+ import { IconSquareRounded } from "@tabler/icons-react";
2
+ import { useRouter } from "alepha/react/router";
3
+ import { ui } from "../../constants/ui.ts";
4
+ import { renderIcon } from "../../helpers/renderIcon.tsx";
5
+ import type {
6
+ ActionMenuConfig,
7
+ ActionMenuItem,
8
+ } from "../buttons/ActionButton.tsx";
9
+ import ActionButton from "../buttons/ActionButton.tsx";
10
+ import Flex from "../Flex.tsx";
11
+ import type { SidebarItemProps } from "./SidebarItem.tsx";
12
+
13
+ // ---------------------------------------------------------------------------------------------------------------------
14
+
15
+ export const SidebarCollapsedItem = (props: SidebarItemProps) => {
16
+ const router = useRouter();
17
+
18
+ const handleItemClick = () => {
19
+ props.onItemClick?.(props.item);
20
+ props.item.onClick?.();
21
+ };
22
+
23
+ const hasChildren = props.item.children && props.item.children.length > 0;
24
+
25
+ const menu: ActionMenuConfig | undefined = hasChildren
26
+ ? {
27
+ on: "hover",
28
+ position: "right",
29
+ menuProps: {
30
+ arrowPosition: "center",
31
+ arrowSize: 10,
32
+ withArrow: true,
33
+ },
34
+ items: [
35
+ {
36
+ type: "label",
37
+ label: props.item.label,
38
+ },
39
+ ...props.item
40
+ .children!.filter((child) => !child.can || child.can())
41
+ .map(
42
+ (child): ActionMenuItem => ({
43
+ label: child.label as string,
44
+ icon: renderIcon(child.icon, ui.sizes.icon.sm),
45
+ href: child.href,
46
+ active: child.href
47
+ ? router.isActive(child.href, {
48
+ startWith: child.activeStartsWith,
49
+ })
50
+ : undefined,
51
+ }),
52
+ ),
53
+ ],
54
+ }
55
+ : undefined;
56
+
57
+ return (
58
+ <Flex w={"100%"} justify="center" pos={"relative"}>
59
+ <ActionButton
60
+ size={
61
+ props.item.theme?.size ??
62
+ props.theme.button?.size ??
63
+ (props.level === 0 ? "sm" : "xs")
64
+ }
65
+ bd={0}
66
+ variant={"default"}
67
+ propsActive={{
68
+ variant: "outline",
69
+ }}
70
+ tooltip={
71
+ hasChildren
72
+ ? undefined
73
+ : {
74
+ label: props.item.label,
75
+ position: "right",
76
+ }
77
+ }
78
+ onClick={hasChildren ? undefined : handleItemClick}
79
+ icon={
80
+ renderIcon(props.item.icon, ui.sizes.icon.sm) ?? (
81
+ <IconSquareRounded size={ui.sizes.icon.sm} />
82
+ )
83
+ }
84
+ href={hasChildren ? undefined : (props.item.href as any)}
85
+ target={hasChildren ? undefined : props.item.target}
86
+ menu={menu}
87
+ {...props.item.actionProps}
88
+ />
89
+ </Flex>
90
+ );
91
+ };
@@ -0,0 +1,146 @@
1
+ import { IconChevronDown, IconChevronRight } from "@tabler/icons-react";
2
+ import { useEvents } from "alepha/react";
3
+ import { useRouter } from "alepha/react/router";
4
+ import { useCallback, useState } from "react";
5
+ import { ui } from "../../constants/ui.ts";
6
+ import { renderIcon } from "../../helpers/renderIcon.tsx";
7
+ import ActionButton from "../buttons/ActionButton.tsx";
8
+ import Flex from "../Flex.tsx";
9
+ import type { SidebarMenuItem, SidebarTheme } from "./Sidebar.tsx";
10
+
11
+ // ---------------------------------------------------------------------------------------------------------------------
12
+
13
+ export interface SidebarItemProps {
14
+ item: SidebarMenuItem;
15
+ level: number;
16
+ onItemClick?: (item: SidebarMenuItem) => void;
17
+ theme: SidebarTheme;
18
+ }
19
+
20
+ // ---------------------------------------------------------------------------------------------------------------------
21
+
22
+ export const SidebarItem = (props: SidebarItemProps) => {
23
+ const maxLevel = 2; // 0, 1, 2 = 3 levels total
24
+
25
+ const router = useRouter();
26
+ const isActive = useCallback((item: SidebarMenuItem): boolean => {
27
+ if (!item.children) return false;
28
+ for (const child of item.children) {
29
+ if (child.href) {
30
+ if (router.isActive(child.href)) {
31
+ return true;
32
+ }
33
+ }
34
+ if (isActive(child)) {
35
+ return true;
36
+ }
37
+ }
38
+ return false;
39
+ }, []);
40
+
41
+ const [isOpen, setIsOpen] = useState<boolean>(isActive(props.item));
42
+
43
+ useEvents(
44
+ {
45
+ "react:transition:end": () => {
46
+ // recalculate open state on transition end to ensure correct state after navigation
47
+ if (isActive(props.item)) {
48
+ setIsOpen(true);
49
+ }
50
+ },
51
+ },
52
+ [],
53
+ );
54
+
55
+ if (props.level > maxLevel) return null;
56
+
57
+ const handleItemClick = (e: MouseEvent) => {
58
+ if (!props.item.target) {
59
+ e.preventDefault();
60
+ }
61
+ if (props.item.children && props.item.children.length > 0) {
62
+ setIsOpen(!isOpen);
63
+ } else {
64
+ props.onItemClick?.(props.item);
65
+ props.item.onClick?.();
66
+ }
67
+ };
68
+
69
+ return (
70
+ <Flex direction={"column"} ps={props.level === 0 ? 0 : 32} pos={"relative"}>
71
+ <ActionButton
72
+ w={"100%"}
73
+ justify="space-between"
74
+ href={props.item.href}
75
+ target={props.item.target}
76
+ size={
77
+ props.item.theme?.size ??
78
+ props.theme.button?.size ??
79
+ (props.level === 0 ? "sm" : "xs")
80
+ }
81
+ bd={0}
82
+ fw={"normal"}
83
+ variant={"default"}
84
+ propsActive={{
85
+ variant: "outline",
86
+ }}
87
+ radius={props.item.theme?.radius ?? props.theme.button?.radius ?? "md"}
88
+ onClick={handleItemClick}
89
+ leftSection={
90
+ <Flex w={"100%"} align="center" gap={"sm"}>
91
+ {renderIcon(props.item.icon, ui.sizes.icon.sm)}
92
+ <Flex direction={"column"}>
93
+ <Flex>{props.item.label}</Flex>
94
+ </Flex>
95
+ </Flex>
96
+ }
97
+ rightSection={
98
+ props.item.children ? (
99
+ <Flex>
100
+ {isOpen ? (
101
+ <IconChevronDown size={14} />
102
+ ) : (
103
+ <IconChevronRight size={14} />
104
+ )}
105
+ </Flex>
106
+ ) : (
107
+ props.item.rightSection
108
+ )
109
+ }
110
+ {...props.item.actionProps}
111
+ />
112
+
113
+ {props.item.children && isOpen && (
114
+ <Flex
115
+ direction={"column"}
116
+ data-parent-level={props.level}
117
+ gap={2}
118
+ py={2}
119
+ >
120
+ <Flex
121
+ style={{
122
+ position: "absolute",
123
+ width: 1,
124
+ background:
125
+ "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
126
+ top: 48,
127
+ left: 20 + 32 * props.level,
128
+ bottom: 16,
129
+ }}
130
+ />
131
+ {props.item.children
132
+ .filter((child) => !child.can || child.can())
133
+ .map((child, index) => (
134
+ <SidebarItem
135
+ key={index}
136
+ item={child}
137
+ level={props.level + 1}
138
+ onItemClick={props.onItemClick}
139
+ theme={props.theme}
140
+ />
141
+ ))}
142
+ </Flex>
143
+ )}
144
+ </Flex>
145
+ );
146
+ };
@@ -35,7 +35,6 @@ export type {
35
35
  SidebarButtonTheme,
36
36
  SidebarDivider,
37
37
  SidebarElement,
38
- SidebarItemProps,
39
38
  SidebarMenuItem,
40
39
  SidebarNode,
41
40
  SidebarProps,
@@ -45,6 +44,9 @@ export type {
45
44
  SidebarTheme,
46
45
  } from "./Sidebar.tsx";
47
46
  export { Sidebar } from "./Sidebar.tsx";
47
+ export { SidebarCollapsedItem } from "./SidebarCollapsedItem.tsx";
48
+ export type { SidebarItemProps } from "./SidebarItem.tsx";
49
+ export { SidebarItem } from "./SidebarItem.tsx";
48
50
 
49
51
  // ---------------------------------------------------------------------------------------------------------------------
50
52