@alepha/ui 0.18.2 → 0.19.0

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 (257) hide show
  1. package/dist/admin/{AdminApiKeys-BJhIwfD6.js → AdminApiKeys-Bt1PjO6o.js} +3 -4
  2. package/dist/admin/{AdminApiKeys-BJhIwfD6.js.map → AdminApiKeys-Bt1PjO6o.js.map} +1 -1
  3. package/dist/admin/{AdminAudits-DzD_4cDt.js → AdminAudits-C7c1CN4c.js} +3 -4
  4. package/dist/admin/{AdminAudits-DzD_4cDt.js.map → AdminAudits-C7c1CN4c.js.map} +1 -1
  5. package/dist/admin/{AdminDashboard-C92tIc6x.js → AdminDashboard-C3RXpTp6.js} +3 -4
  6. package/dist/admin/{AdminDashboard-C92tIc6x.js.map → AdminDashboard-C3RXpTp6.js.map} +1 -1
  7. package/dist/admin/{AdminFiles-DLpfhBkf.js → AdminFiles-31ivR6Wq.js} +3 -4
  8. package/dist/admin/{AdminFiles-DLpfhBkf.js.map → AdminFiles-31ivR6Wq.js.map} +1 -1
  9. package/dist/admin/{AdminJobDashboard-KIOkeMgE.js → AdminJobDashboard-BABLe7hL.js} +73 -25
  10. package/dist/admin/AdminJobDashboard-BABLe7hL.js.map +1 -0
  11. package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js → AdminJobExecutions-D-G8RIlr.js} +3 -4
  12. package/dist/admin/{AdminJobExecutions-D0Yo_PU0.js.map → AdminJobExecutions-D-G8RIlr.js.map} +1 -1
  13. package/dist/admin/{AdminJobRegistry-PFajqaGK.js → AdminJobRegistry-oIS3K9NX.js} +3 -4
  14. package/dist/admin/{AdminJobRegistry-PFajqaGK.js.map → AdminJobRegistry-oIS3K9NX.js.map} +1 -1
  15. package/dist/admin/{AdminLayout-B1DXZHDn.js → AdminLayout-BmZ9mtXh.js} +8 -25
  16. package/dist/admin/AdminLayout-BmZ9mtXh.js.map +1 -0
  17. package/dist/admin/AdminNotifications-DHdzksww.js +541 -0
  18. package/dist/admin/AdminNotifications-DHdzksww.js.map +1 -0
  19. package/dist/admin/{AdminParameters-BspPeqp_.js → AdminParameters-CyZQSXnN.js} +118 -112
  20. package/dist/admin/AdminParameters-CyZQSXnN.js.map +1 -0
  21. package/dist/admin/{AdminSessions-BnH5CZQl.js → AdminSessions--xwELDSO.js} +3 -4
  22. package/dist/admin/{AdminSessions-BnH5CZQl.js.map → AdminSessions--xwELDSO.js.map} +1 -1
  23. package/dist/admin/{AdminUserLayout-DUbC6-BI.js → AdminUserLayout-DvBTG5gd.js} +82 -115
  24. package/dist/admin/AdminUserLayout-DvBTG5gd.js.map +1 -0
  25. package/dist/admin/{AdminUserProfile-DuTUnjdG.js → AdminUserProfile-CzsPBl6Z.js} +7 -6
  26. package/dist/admin/AdminUserProfile-CzsPBl6Z.js.map +1 -0
  27. package/dist/admin/{AdminUserSessions-DvZdAGpL.js → AdminUserSessions-C-aUnhVN.js} +3 -4
  28. package/dist/admin/{AdminUserSessions-DvZdAGpL.js.map → AdminUserSessions-C-aUnhVN.js.map} +1 -1
  29. package/dist/admin/{AdminUsers-CR9z0g_5.js → AdminUsers-BYwei5sj.js} +4 -4
  30. package/dist/admin/AdminUsers-BYwei5sj.js.map +1 -0
  31. package/dist/admin/{AuthLayout-DsUfp9RG.js → AuthLayout-CkPGLJku.js} +3 -4
  32. package/dist/admin/{AuthLayout-DsUfp9RG.js.map → AuthLayout-CkPGLJku.js.map} +1 -1
  33. package/dist/{demo/IconGoogle-CSQLPYwX.js → admin/IconGoogle-8Nkx6yax.js} +2 -4
  34. package/dist/admin/{IconGoogle-Ch1m3Uzl.js.map → IconGoogle-8Nkx6yax.js.map} +1 -1
  35. package/dist/admin/Login-DSBqNsZc.js +274 -0
  36. package/dist/admin/Login-DSBqNsZc.js.map +1 -0
  37. package/dist/admin/{Profile-B2EcIDB9.js → Profile-CDRjJo0P.js} +31 -29
  38. package/dist/admin/Profile-CDRjJo0P.js.map +1 -0
  39. package/dist/admin/{Register-Z3fxRbUF.js → Register-4QGFOnfh.js} +201 -146
  40. package/dist/admin/Register-4QGFOnfh.js.map +1 -0
  41. package/dist/admin/{ResetPassword-_Y1qTTKh.js → ResetPassword-Gxc9L_mY.js} +9 -10
  42. package/dist/admin/ResetPassword-Gxc9L_mY.js.map +1 -0
  43. package/dist/admin/{VerifyEmail-Bg22bwcC.js → VerifyEmail-D7G5NnaN.js} +25 -11
  44. package/dist/admin/VerifyEmail-D7G5NnaN.js.map +1 -0
  45. package/dist/admin/adminUserAtom-DCi4wf-v.js +11 -0
  46. package/dist/admin/adminUserAtom-DCi4wf-v.js.map +1 -0
  47. package/dist/admin/{core-BVO_TQxb.js → core-D1AbU50V.js} +662 -570
  48. package/dist/admin/core-D1AbU50V.js.map +1 -0
  49. package/dist/admin/index.d.ts +141 -53
  50. package/dist/admin/index.d.ts.map +1 -1
  51. package/dist/admin/index.js +67 -49
  52. package/dist/admin/index.js.map +1 -1
  53. package/dist/admin/rolldown-runtime-CiIaOW0V.js +13 -0
  54. package/dist/{demo/AuthLayout-DN-ClJQk.js → auth/AuthLayout-CfRKcTqP.js} +3 -4
  55. package/dist/auth/{AuthLayout-C161NeF6.js.map → AuthLayout-CfRKcTqP.js.map} +1 -1
  56. package/dist/{admin/IconGoogle-Ch1m3Uzl.js → auth/IconGoogle-8Nkx6yax.js} +2 -4
  57. package/dist/auth/{IconGoogle-Ch1m3Uzl.js.map → IconGoogle-8Nkx6yax.js.map} +1 -1
  58. package/dist/auth/Login-DJyweoPS.js +274 -0
  59. package/dist/auth/Login-DJyweoPS.js.map +1 -0
  60. package/dist/auth/{Profile-BMpXJ0oi.js → Profile-Cy93pNTw.js} +31 -29
  61. package/dist/auth/Profile-Cy93pNTw.js.map +1 -0
  62. package/dist/auth/{Register-2gx8qll-.js → Register-CSqzzitW.js} +201 -146
  63. package/dist/auth/Register-CSqzzitW.js.map +1 -0
  64. package/dist/{demo/ResetPassword-CAPj8MO3.js → auth/ResetPassword-B61QPlQi.js} +9 -10
  65. package/dist/auth/ResetPassword-B61QPlQi.js.map +1 -0
  66. package/dist/{demo/VerifyEmail-DFmdCdYs.js → auth/VerifyEmail-CqBJ11id.js} +25 -11
  67. package/dist/auth/VerifyEmail-CqBJ11id.js.map +1 -0
  68. package/dist/auth/{core-DyfeVr5c.js → core-C6D3pazL.js} +403 -343
  69. package/dist/auth/core-C6D3pazL.js.map +1 -0
  70. package/dist/auth/index.d.ts +93 -54
  71. package/dist/auth/index.d.ts.map +1 -1
  72. package/dist/auth/index.js +30 -31
  73. package/dist/auth/index.js.map +1 -1
  74. package/dist/auth/rolldown-runtime-CiIaOW0V.js +13 -0
  75. package/dist/core/index.d.ts +123 -62
  76. package/dist/core/index.d.ts.map +1 -1
  77. package/dist/core/index.js +878 -776
  78. package/dist/core/index.js.map +1 -1
  79. package/dist/{auth/AuthLayout-C161NeF6.js → demo/AuthLayout-Dq5tSLSc.js} +3 -4
  80. package/dist/demo/{AuthLayout-DN-ClJQk.js.map → AuthLayout-Dq5tSLSc.js.map} +1 -1
  81. package/dist/demo/DemoButton-_Ws2w-J0.js +181 -0
  82. package/dist/demo/DemoButton-_Ws2w-J0.js.map +1 -0
  83. package/dist/demo/DemoControlSelect-ChP4ZOpQ.js +304 -0
  84. package/dist/demo/DemoControlSelect-ChP4ZOpQ.js.map +1 -0
  85. package/dist/demo/DemoDataTable-Hwf_UUni.js +361 -0
  86. package/dist/demo/DemoDataTable-Hwf_UUni.js.map +1 -0
  87. package/dist/demo/{DemoDialog-DW8QEvD1.js → DemoDialog-B01OMVRd.js} +3 -4
  88. package/dist/demo/{DemoDialog-DW8QEvD1.js.map → DemoDialog-B01OMVRd.js.map} +1 -1
  89. package/dist/demo/{DemoFlex-CAhLUanT.js → DemoFlex-870PEl0V.js} +4 -5
  90. package/dist/demo/{DemoFlex-CAhLUanT.js.map → DemoFlex-870PEl0V.js.map} +1 -1
  91. package/dist/demo/{DemoHeading-yIFmNjHB.js → DemoHeading-C1YR27fz.js} +4 -5
  92. package/dist/demo/{DemoHeading-yIFmNjHB.js.map → DemoHeading-C1YR27fz.js.map} +1 -1
  93. package/dist/demo/{DemoHome-BSGuBHus.js → DemoHome-DRbL2eGf.js} +4 -5
  94. package/dist/demo/{DemoHome-BSGuBHus.js.map → DemoHome-DRbL2eGf.js.map} +1 -1
  95. package/dist/demo/{DemoJsonViewer-DsA2IpgV.js → DemoJsonViewer-DoABiqBW.js} +4 -5
  96. package/dist/demo/{DemoJsonViewer-DsA2IpgV.js.map → DemoJsonViewer-DoABiqBW.js.map} +1 -1
  97. package/dist/demo/{DemoLayout-Cy6xjn6P.js → DemoLayout-CN_PDCX2.js} +16 -8
  98. package/dist/demo/DemoLayout-CN_PDCX2.js.map +1 -0
  99. package/dist/demo/{DemoLogin-vqxgTu4P.js → DemoLogin-B5x-ug3Q.js} +51 -35
  100. package/dist/demo/DemoLogin-B5x-ug3Q.js.map +1 -0
  101. package/dist/demo/{DemoRegister-YHPvPg77.js → DemoRegister-Q6sg2xuV.js} +51 -53
  102. package/dist/demo/DemoRegister-Q6sg2xuV.js.map +1 -0
  103. package/dist/demo/{DemoResetPassword-mOW18Zlm.js → DemoResetPassword-DrqZfmEw.js} +14 -19
  104. package/dist/demo/DemoResetPassword-DrqZfmEw.js.map +1 -0
  105. package/dist/demo/{DemoSidebar-od7aLjP_.js → DemoSidebar-CfKS6w1o.js} +4 -5
  106. package/dist/demo/{DemoSidebar-od7aLjP_.js.map → DemoSidebar-CfKS6w1o.js.map} +1 -1
  107. package/dist/demo/{DemoText-DU3JeRS0.js → DemoText-pT6Gi5b5.js} +4 -5
  108. package/dist/demo/{DemoText-DU3JeRS0.js.map → DemoText-pT6Gi5b5.js.map} +1 -1
  109. package/dist/demo/{DemoToast-CUJEiPRa.js → DemoToast-I13NBzQQ.js} +3 -4
  110. package/dist/demo/{DemoToast-CUJEiPRa.js.map → DemoToast-I13NBzQQ.js.map} +1 -1
  111. package/dist/demo/{DemoTypeForm-C1dNkahD.js → DemoTypeForm-BqzcrtvN.js} +9 -6
  112. package/dist/demo/DemoTypeForm-BqzcrtvN.js.map +1 -0
  113. package/dist/demo/DemoVerifyEmail-HwD8xfQw.js +33 -0
  114. package/dist/demo/DemoVerifyEmail-HwD8xfQw.js.map +1 -0
  115. package/dist/{auth/IconGoogle-Ch1m3Uzl.js → demo/IconGoogle-CwQy4G9y.js} +2 -4
  116. package/dist/demo/{IconGoogle-CSQLPYwX.js.map → IconGoogle-CwQy4G9y.js.map} +1 -1
  117. package/dist/demo/Login-CqG1iJbn.js +274 -0
  118. package/dist/demo/Login-CqG1iJbn.js.map +1 -0
  119. package/dist/demo/{Profile-BE_Y3co2.js → Profile-C0ojJCaG.js} +31 -29
  120. package/dist/demo/Profile-C0ojJCaG.js.map +1 -0
  121. package/dist/demo/{Register-fXHmBpr3.js → Register-KKZwr_lL.js} +201 -146
  122. package/dist/demo/Register-KKZwr_lL.js.map +1 -0
  123. package/dist/{auth/ResetPassword-DBxt9hKk.js → demo/ResetPassword-DMrLFEtr.js} +9 -10
  124. package/dist/demo/ResetPassword-DMrLFEtr.js.map +1 -0
  125. package/dist/demo/{Showcase-BtEU0pY9.js → Showcase-D49Wud2v.js} +65 -68
  126. package/dist/demo/Showcase-D49Wud2v.js.map +1 -0
  127. package/dist/{auth/VerifyEmail-Z80Ubajk.js → demo/VerifyEmail-BFCAFz6T.js} +25 -11
  128. package/dist/demo/VerifyEmail-BFCAFz6T.js.map +1 -0
  129. package/dist/demo/{auth-Djd7SKiw.js → auth-D9qTZzCa.js} +18 -35
  130. package/dist/demo/{auth-Djd7SKiw.js.map → auth-D9qTZzCa.js.map} +1 -1
  131. package/dist/demo/{core-B7LNjM78.js → core-DRtQklr3.js} +752 -647
  132. package/dist/demo/core-DRtQklr3.js.map +1 -0
  133. package/dist/demo/index.d.ts +1 -0
  134. package/dist/demo/index.d.ts.map +1 -1
  135. package/dist/demo/index.js +25 -22
  136. package/dist/demo/index.js.map +1 -1
  137. package/dist/demo/rolldown-runtime-CiIaOW0V.js +13 -0
  138. package/package.json +19 -19
  139. package/src/admin/AdminRouter.tsx +42 -2
  140. package/src/admin/atoms/adminUserAtom.ts +7 -0
  141. package/src/admin/components/AdminLayout.tsx +2 -14
  142. package/src/admin/components/jobs/AdminJobDashboard.tsx +51 -20
  143. package/src/admin/components/notifications/AdminNotifications.tsx +519 -0
  144. package/src/admin/components/parameters/ParameterDetails.tsx +12 -270
  145. package/src/admin/components/parameters/ParameterDetailsConfigForm.tsx +238 -0
  146. package/src/admin/components/parameters/ParameterDetailsLoading.tsx +24 -0
  147. package/src/admin/components/parameters/ParameterHistory.tsx +10 -11
  148. package/src/admin/components/parameters/ParameterTree.tsx +28 -184
  149. package/src/admin/components/parameters/ParameterTreeNode.tsx +151 -0
  150. package/src/admin/components/shared/AdminResourceHeader.tsx +2 -25
  151. package/src/admin/components/shared/AdminResourceHeaderMenuItem.tsx +37 -0
  152. package/src/admin/components/shared/AdminResourceTabs.tsx +2 -26
  153. package/src/admin/components/shared/AdminResourceTabsItem.tsx +36 -0
  154. package/src/admin/components/users/AdminUserLayout.tsx +84 -127
  155. package/src/admin/components/users/AdminUserProfile.tsx +5 -2
  156. package/src/admin/components/users/AdminUsers.tsx +1 -1
  157. package/src/auth/components/Login.tsx +188 -121
  158. package/src/auth/components/Profile.tsx +1 -22
  159. package/src/auth/components/ProfileField.tsx +39 -0
  160. package/src/auth/components/Register.tsx +215 -158
  161. package/src/auth/components/ResetPassword.tsx +7 -11
  162. package/src/auth/components/VerifyEmail.tsx +35 -10
  163. package/src/auth/components/buttons/UserButton.tsx +19 -21
  164. package/src/auth/index.ts +1 -0
  165. package/src/core/components/Flex.tsx +34 -0
  166. package/src/core/components/buttons/ActionButton.tsx +105 -78
  167. package/src/core/components/data/DetailDrawer.tsx +102 -96
  168. package/src/core/components/data/DetailList.tsx +2 -1
  169. package/src/core/components/dialogs/PromptDialog.tsx +1 -1
  170. package/src/core/components/layout/Breadcrumb.tsx +4 -7
  171. package/src/core/components/layout/DashboardShell.tsx +18 -4
  172. package/src/core/components/layout/Sidebar.tsx +16 -241
  173. package/src/core/components/layout/SidebarCollapsedItem.tsx +91 -0
  174. package/src/core/components/layout/SidebarItem.tsx +146 -0
  175. package/src/core/components/layout/index.ts +3 -1
  176. package/src/core/form/components/Control.tsx +31 -29
  177. package/src/core/form/components/ControlArray.tsx +13 -39
  178. package/src/core/form/components/ControlDate.tsx +10 -21
  179. package/src/core/form/components/ControlNumber.tsx +4 -33
  180. package/src/core/form/components/ControlQueryBuilder.tsx +12 -175
  181. package/src/core/form/components/ControlQueryBuilderHelp.tsx +165 -0
  182. package/src/core/form/components/ControlSelect.browser.spec.tsx +343 -0
  183. package/src/core/form/components/ControlSelect.tsx +294 -92
  184. package/src/core/form/components/TypeForm.browser.spec.tsx +3 -3
  185. package/src/core/form/components/TypeForm.tsx +5 -2
  186. package/src/core/form/index.ts +8 -1
  187. package/src/core/form/utils/parseInput.ts +7 -3
  188. package/src/core/index.ts +3 -1
  189. package/src/core/json/components/JsonViewer.tsx +103 -319
  190. package/src/core/json/components/JsonViewerCopyButton.tsx +46 -0
  191. package/src/core/json/components/JsonViewerRowNode.tsx +120 -0
  192. package/src/core/json/components/JsonViewerShared.ts +76 -0
  193. package/src/core/services/DialogService.tsx +2 -2
  194. package/src/core/styles.css +13 -2
  195. package/src/core/table/components/ColumnPicker.tsx +3 -3
  196. package/src/core/table/components/DataTable.tsx +88 -29
  197. package/src/core/table/components/DataTableFilters.tsx +6 -11
  198. package/src/core/table/components/DataTablePagination.tsx +9 -3
  199. package/src/core/table/components/DataTableToolbar.tsx +7 -3
  200. package/src/core/table/components/FilterPicker.tsx +3 -3
  201. package/src/core/table/interfaces/types.ts +29 -0
  202. package/src/core/utils/icons.tsx +2 -2
  203. package/src/demo/DemoRouter.ts +8 -1
  204. package/src/demo/components/DemoLayout.tsx +12 -2
  205. package/src/demo/components/auth/DemoLogin.tsx +35 -28
  206. package/src/demo/components/auth/DemoRegister.tsx +35 -49
  207. package/src/demo/components/auth/DemoResetPassword.tsx +5 -9
  208. package/src/demo/components/auth/DemoVerifyEmail.tsx +7 -6
  209. package/src/demo/components/core/DemoButton.tsx +123 -103
  210. package/src/demo/components/core/DemoControlSelect.tsx +325 -0
  211. package/src/demo/components/core/DemoDataTable.tsx +255 -237
  212. package/src/demo/components/core/DemoTypeForm.tsx +7 -2
  213. package/src/demo/components/shared/MacWindow.tsx +5 -11
  214. package/src/demo/components/shared/Showcase.tsx +28 -42
  215. package/dist/admin/AdminJobDashboard-KIOkeMgE.js.map +0 -1
  216. package/dist/admin/AdminLayout-B1DXZHDn.js.map +0 -1
  217. package/dist/admin/AdminParameters-BspPeqp_.js.map +0 -1
  218. package/dist/admin/AdminUserLayout-DUbC6-BI.js.map +0 -1
  219. package/dist/admin/AdminUserProfile-DuTUnjdG.js.map +0 -1
  220. package/dist/admin/AdminUsers-CR9z0g_5.js.map +0 -1
  221. package/dist/admin/Login-DHbYJKwg.js +0 -219
  222. package/dist/admin/Login-DHbYJKwg.js.map +0 -1
  223. package/dist/admin/Profile-B2EcIDB9.js.map +0 -1
  224. package/dist/admin/Register-Z3fxRbUF.js.map +0 -1
  225. package/dist/admin/ResetPassword-_Y1qTTKh.js.map +0 -1
  226. package/dist/admin/VerifyEmail-Bg22bwcC.js.map +0 -1
  227. package/dist/admin/core-BVO_TQxb.js.map +0 -1
  228. package/dist/admin/rolldown-runtime-CjeV3_4I.js +0 -18
  229. package/dist/auth/Login-C7jIqf00.js +0 -219
  230. package/dist/auth/Login-C7jIqf00.js.map +0 -1
  231. package/dist/auth/Profile-BMpXJ0oi.js.map +0 -1
  232. package/dist/auth/Register-2gx8qll-.js.map +0 -1
  233. package/dist/auth/ResetPassword-DBxt9hKk.js.map +0 -1
  234. package/dist/auth/VerifyEmail-Z80Ubajk.js.map +0 -1
  235. package/dist/auth/core-DyfeVr5c.js.map +0 -1
  236. package/dist/auth/rolldown-runtime-CjeV3_4I.js +0 -18
  237. package/dist/demo/DemoButton-CGUyR9eM.js +0 -178
  238. package/dist/demo/DemoButton-CGUyR9eM.js.map +0 -1
  239. package/dist/demo/DemoDataTable-QFG-xXSx.js +0 -358
  240. package/dist/demo/DemoDataTable-QFG-xXSx.js.map +0 -1
  241. package/dist/demo/DemoLayout-Cy6xjn6P.js.map +0 -1
  242. package/dist/demo/DemoLogin-vqxgTu4P.js.map +0 -1
  243. package/dist/demo/DemoRegister-YHPvPg77.js.map +0 -1
  244. package/dist/demo/DemoResetPassword-mOW18Zlm.js.map +0 -1
  245. package/dist/demo/DemoTypeForm-C1dNkahD.js.map +0 -1
  246. package/dist/demo/DemoVerifyEmail-D9EcXZ38.js +0 -30
  247. package/dist/demo/DemoVerifyEmail-D9EcXZ38.js.map +0 -1
  248. package/dist/demo/Login-CoYf_P_F.js +0 -219
  249. package/dist/demo/Login-CoYf_P_F.js.map +0 -1
  250. package/dist/demo/Profile-BE_Y3co2.js.map +0 -1
  251. package/dist/demo/Register-fXHmBpr3.js.map +0 -1
  252. package/dist/demo/ResetPassword-CAPj8MO3.js.map +0 -1
  253. package/dist/demo/Showcase-BtEU0pY9.js.map +0 -1
  254. package/dist/demo/VerifyEmail-DFmdCdYs.js.map +0 -1
  255. package/dist/demo/core-B7LNjM78.js.map +0 -1
  256. package/dist/demo/rolldown-runtime-CjeV3_4I.js +0 -18
  257. package/src/demo/styles.css +0 -0
@@ -1,9 +1,9 @@
1
- import { $atom, $context, $inject, $module, Alepha, AlephaError, TypeBoxError, t } from "alepha";
2
- import { AlephaReactForm, FormValidationError, useForm, useFormState } from "alepha/react/form";
1
+ import { $atom, $inject, $module, Alepha, AlephaError, TypeBoxError, t } from "alepha";
2
+ import { AlephaReactForm, FormModel, FormValidationError, useFieldValue, useForm, useFormState } from "alepha/react/form";
3
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, CopyButton, Divider, Drawer, Fieldset, FileInput, Flex, Grid, Image, Input, Kbd, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, Paper, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, SimpleGrid, Slider, Switch, Table, Tabs, TagsInput, Text, TextInput, Textarea, Tooltip, UnstyledButton, useMantineColorScheme, useMantineTheme } from "@mantine/core";
6
+ import { ActionIcon, Anchor, AppShell, Autocomplete, Badge, Burger, Button, Card, Checkbox, ColorInput, ColorSchemeScript, ColorSwatch, Container, CopyButton, Divider, Drawer, Fieldset, FileInput, Flex, Grid, Image, Input, Kbd, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, Paper, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, SimpleGrid, Slider, Switch, Table, TagsInput, Text, TextInput, Textarea, Tooltip, UnstyledButton, useMantineColorScheme, useMantineTheme } from "@mantine/core";
7
7
  import { ModalsProvider, modals } from "@mantine/modals";
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";
@@ -18,7 +18,6 @@ import { useOs } from "@mantine/hooks";
18
18
  import { DateInput, DateTimePicker, TimeInput } from "@mantine/dates";
19
19
  import { parseQueryString } from "alepha/orm";
20
20
  import { DateTimeProvider } from "alepha/datetime";
21
-
22
21
  //#region ../../src/core/atoms/alephaSidebarAtom.ts
23
22
  const alephaSidebarAtom = $atom({
24
23
  name: "alepha.ui.sidebar",
@@ -35,7 +34,6 @@ const alephaSidebarAtom = $atom({
35
34
  collapsedWidth: 72
36
35
  }
37
36
  });
38
-
39
37
  //#endregion
40
38
  //#region ../../src/core/atoms/alephaThemeAtom.ts
41
39
  const alephaThemeAtom = $atom({
@@ -43,7 +41,6 @@ const alephaThemeAtom = $atom({
43
41
  schema: t.object({ index: t.integer() }),
44
42
  default: { index: 0 }
45
43
  });
46
-
47
44
  //#endregion
48
45
  //#region ../../src/core/atoms/alephaThemeOverridesAtom.ts
49
46
  const alephaThemeOverridesAtom = $atom({
@@ -57,14 +54,12 @@ const alephaThemeOverridesAtom = $atom({
57
54
  }),
58
55
  default: {}
59
56
  });
60
-
61
57
  //#endregion
62
58
  //#region ../../src/core/atoms/themes/default.ts
63
59
  const defaultTheme = {
64
60
  name: "Default",
65
61
  description: "Default Alepha Theme"
66
62
  };
67
-
68
63
  //#endregion
69
64
  //#region ../../src/core/atoms/themes/editorial.ts
70
65
  /**
@@ -219,7 +214,6 @@ const editorialTheme = {
219
214
  })
220
215
  }
221
216
  };
222
-
223
217
  //#endregion
224
218
  //#region ../../src/core/atoms/themes/midnight.ts
225
219
  const midnightTheme = {
@@ -334,7 +328,6 @@ const midnightTheme = {
334
328
  ]
335
329
  }
336
330
  };
337
-
338
331
  //#endregion
339
332
  //#region ../../src/core/atoms/themes/monochrome.ts
340
333
  /**
@@ -502,7 +495,6 @@ const monochromeTheme = {
502
495
  })
503
496
  }
504
497
  };
505
-
506
498
  //#endregion
507
499
  //#region ../../src/core/atoms/themes/rosePine.ts
508
500
  /**
@@ -674,7 +666,6 @@ const rosePineTheme = {
674
666
  Badge: Badge.extend({ defaultProps: { fw: 500 } })
675
667
  }
676
668
  };
677
-
678
669
  //#endregion
679
670
  //#region ../../src/core/atoms/themes/softBrutalism.ts
680
671
  /**
@@ -861,7 +852,6 @@ const softBrutalismTheme = {
861
852
  })
862
853
  }
863
854
  };
864
-
865
855
  //#endregion
866
856
  //#region ../../src/core/atoms/themes/terminal.ts
867
857
  /**
@@ -1017,7 +1007,6 @@ const terminalTheme = {
1017
1007
  })
1018
1008
  }
1019
1009
  };
1020
-
1021
1010
  //#endregion
1022
1011
  //#region ../../src/core/atoms/alephaThemeListAtom.ts
1023
1012
  const alephaThemeListAtom = $atom({
@@ -1033,7 +1022,6 @@ const alephaThemeListAtom = $atom({
1033
1022
  monochromeTheme
1034
1023
  ]
1035
1024
  });
1036
-
1037
1025
  //#endregion
1038
1026
  //#region ../../src/core/providers/ThemeProvider.ts
1039
1027
  var ThemeProvider = class ThemeProvider {
@@ -1131,7 +1119,6 @@ var ThemeProvider = class ThemeProvider {
1131
1119
  }
1132
1120
  }
1133
1121
  };
1134
-
1135
1122
  //#endregion
1136
1123
  //#region ../../src/core/components/dialogs/AlertDialog.tsx
1137
1124
  const AlertDialog = ({ options, onClose }) => /* @__PURE__ */ jsxs(Fragment, { children: [options?.message && /* @__PURE__ */ jsx(Text, {
@@ -1144,7 +1131,6 @@ const AlertDialog = ({ options, onClose }) => /* @__PURE__ */ jsxs(Fragment, { c
1144
1131
  children: options?.okLabel || "OK"
1145
1132
  })
1146
1133
  })] });
1147
-
1148
1134
  //#endregion
1149
1135
  //#region ../../src/core/components/dialogs/ConfirmDialog.tsx
1150
1136
  const ConfirmDialog = ({ options, onConfirm }) => /* @__PURE__ */ jsxs(Fragment, { children: [options?.message && /* @__PURE__ */ jsx(Text, {
@@ -1162,7 +1148,6 @@ const ConfirmDialog = ({ options, onConfirm }) => /* @__PURE__ */ jsxs(Fragment,
1162
1148
  children: options?.confirmLabel || "Confirm"
1163
1149
  })]
1164
1150
  })] });
1165
-
1166
1151
  //#endregion
1167
1152
  //#region ../../src/core/components/dialogs/PromptDialog.tsx
1168
1153
  const PromptDialog = ({ options, onSubmit }) => {
@@ -1194,6 +1179,7 @@ const PromptDialog = ({ options, onSubmit }) => {
1194
1179
  }),
1195
1180
  /* @__PURE__ */ jsxs(Flex, {
1196
1181
  justify: "flex-end",
1182
+ gap: "xs",
1197
1183
  children: [/* @__PURE__ */ jsx(Button, {
1198
1184
  variant: "subtle",
1199
1185
  onClick: () => onSubmit(null),
@@ -1206,7 +1192,6 @@ const PromptDialog = ({ options, onSubmit }) => {
1206
1192
  })
1207
1193
  ] });
1208
1194
  };
1209
-
1210
1195
  //#endregion
1211
1196
  //#region ../../src/core/services/DialogService.tsx
1212
1197
  var DialogService = class {
@@ -1268,8 +1253,8 @@ var DialogService = class {
1268
1253
  content: /* @__PURE__ */ jsx(ConfirmDialog, {
1269
1254
  options,
1270
1255
  onConfirm: (confirmed) => {
1271
- this.close(modalId);
1272
1256
  done(confirmed);
1257
+ this.close(modalId);
1273
1258
  }
1274
1259
  })
1275
1260
  });
@@ -1295,8 +1280,8 @@ var DialogService = class {
1295
1280
  content: /* @__PURE__ */ jsx(PromptDialog, {
1296
1281
  options,
1297
1282
  onSubmit: (value) => {
1298
- this.close(modalId);
1299
1283
  done(value);
1284
+ this.close(modalId);
1300
1285
  }
1301
1286
  })
1302
1287
  });
@@ -1320,7 +1305,6 @@ var DialogService = class {
1320
1305
  else modals.closeAll();
1321
1306
  }
1322
1307
  };
1323
-
1324
1308
  //#endregion
1325
1309
  //#region ../../src/core/services/ToastService.tsx
1326
1310
  var ToastService = class {
@@ -1379,7 +1363,6 @@ var ToastService = class {
1379
1363
  });
1380
1364
  }
1381
1365
  };
1382
-
1383
1366
  //#endregion
1384
1367
  //#region ../../src/core/UiRouter.ts
1385
1368
  /**
@@ -1394,7 +1377,6 @@ var UiRouter = class {
1394
1377
  component: AlephaMantineProvider
1395
1378
  });
1396
1379
  };
1397
-
1398
1380
  //#endregion
1399
1381
  //#region ../../src/core/hooks/useTheme.ts
1400
1382
  /**
@@ -1429,7 +1411,6 @@ const useTheme = () => {
1429
1411
  }
1430
1412
  ];
1431
1413
  };
1432
-
1433
1414
  //#endregion
1434
1415
  //#region ../../src/core/hooks/useToast.ts
1435
1416
  /**
@@ -1445,7 +1426,6 @@ const useTheme = () => {
1445
1426
  const useToast = () => {
1446
1427
  return useInject(ToastService);
1447
1428
  };
1448
-
1449
1429
  //#endregion
1450
1430
  //#region ../../src/core/components/layout/Omnibar.tsx
1451
1431
  const Omnibar = (props) => {
@@ -1477,7 +1457,6 @@ const Omnibar = (props) => {
1477
1457
  nothingFound
1478
1458
  });
1479
1459
  };
1480
-
1481
1460
  //#endregion
1482
1461
  //#region ../../src/core/components/AlephaMantineProvider.tsx
1483
1462
  const AlephaMantineProvider = (props) => {
@@ -1519,7 +1498,6 @@ const AlephaMantineProvider = (props) => {
1519
1498
  ]
1520
1499
  })] });
1521
1500
  };
1522
-
1523
1501
  //#endregion
1524
1502
  //#region ../../src/core/constants/ui.ts
1525
1503
  const ui = {
@@ -1538,51 +1516,18 @@ const ui = {
1538
1516
  xl: 32
1539
1517
  } }
1540
1518
  };
1541
-
1542
1519
  //#endregion
1543
1520
  //#region ../../src/core/helpers/isComponentType.ts
1544
1521
  function isComponentType(param) {
1545
1522
  if (isValidElement(param)) return false;
1546
1523
  return typeof param === "function" || typeof param === "object" && param !== null && "$$typeof" in param;
1547
1524
  }
1548
-
1549
1525
  //#endregion
1550
1526
  //#region ../../src/core/components/buttons/ActionButton.tsx
1551
- const ActionMenuItem = (props) => {
1552
- const { item, index } = props;
1553
- const router = useRouter();
1554
- const action = useAction({ handler: async (e) => {
1555
- await item.onClick?.();
1556
- } }, [item.onClick]);
1557
- if (item.type === "divider") return /* @__PURE__ */ jsx(Menu.Divider, {}, index);
1558
- if (item.type === "label") return /* @__PURE__ */ jsx(Menu.Label, { children: item.label }, index);
1559
- if (item.children && item.children.length > 0) return /* @__PURE__ */ jsxs(Menu, {
1560
- trigger: "hover",
1561
- position: "right-start",
1562
- offset: 2,
1563
- children: [/* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Menu.Item, {
1564
- leftSection: item.icon,
1565
- rightSection: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }),
1566
- children: item.label
1567
- }) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: item.children.map((child, childIndex) => /* @__PURE__ */ jsx(ActionMenuItem, {
1568
- item: child,
1569
- index: childIndex
1570
- }, childIndex)) })]
1571
- }, index);
1572
- const menuItemProps = {};
1573
- if (props.item.onClick) menuItemProps.onClick = action.run;
1574
- else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
1575
- return /* @__PURE__ */ jsx(Menu.Item, {
1576
- leftSection: item.icon ?? (item.active ? /* @__PURE__ */ jsx(IconCheck, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(Flex, { w: ui.sizes.icon.sm })),
1577
- onClick: item.onClick,
1578
- color: item.color,
1579
- ...menuItemProps,
1580
- children: item.label
1581
- }, index);
1582
- };
1583
1527
  const ActionButton = (_props) => {
1584
1528
  const theme = useMantineTheme();
1585
1529
  const props = { ..._props };
1530
+ if (props.variant === "minimal") {}
1586
1531
  const { tooltip, menu, icon, iconSize, ...restProps } = props;
1587
1532
  if (props.intent) {
1588
1533
  if (props.intent === "primary") restProps.color ??= theme.primaryColor;
@@ -1627,6 +1572,7 @@ const ActionButton = (_props) => {
1627
1572
  children: /* @__PURE__ */ jsx(ActionButton, {
1628
1573
  px: "xs",
1629
1574
  ...rest,
1575
+ "aria-label": typeof children === "string" ? children : void 0,
1630
1576
  tooltip,
1631
1577
  menu,
1632
1578
  children: leftSection
@@ -1783,7 +1729,7 @@ const ActionClickButton = ({ preventDefault, ...props }) => {
1783
1729
  * Action for navigation with active state support.
1784
1730
  */
1785
1731
  const ActionNavigationButton = (props) => {
1786
- const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchor, ...buttonProps } = props;
1732
+ const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchorProps: buttonAnchorProps, anchor, ...buttonProps } = props;
1787
1733
  const router = useRouter();
1788
1734
  const { isPending, isActive } = useActive(options ? {
1789
1735
  href: props.href,
@@ -1797,11 +1743,11 @@ const ActionNavigationButton = (props) => {
1797
1743
  };
1798
1744
  const className = buttonProps.className || "";
1799
1745
  if (isActive && options !== false && classNameActive) buttonProps.className = `${className} ${classNameActive}`.trim();
1800
- if (props.anchorProps || anchor) return /* @__PURE__ */ jsx(Anchor, {
1746
+ if (buttonAnchorProps || anchor) return /* @__PURE__ */ jsx(Anchor, {
1801
1747
  component: "a",
1802
1748
  ...anchorProps,
1803
1749
  ...buttonProps,
1804
- ...props.anchorProps,
1750
+ ...buttonAnchorProps,
1805
1751
  onClick: combinedOnClick,
1806
1752
  children: props.children
1807
1753
  });
@@ -1824,7 +1770,38 @@ const ActionHrefButton = (props) => {
1824
1770
  children: props.children
1825
1771
  });
1826
1772
  };
1827
-
1773
+ const ActionMenuItem = (props) => {
1774
+ const { item, index } = props;
1775
+ const router = useRouter();
1776
+ const action = useAction({ handler: async (e) => {
1777
+ await item.onClick?.();
1778
+ } }, [item.onClick]);
1779
+ if (item.type === "divider") return /* @__PURE__ */ jsx(Menu.Divider, {}, index);
1780
+ if (item.type === "label") return /* @__PURE__ */ jsx(Menu.Label, { children: item.label }, index);
1781
+ if (item.children && item.children.length > 0) return /* @__PURE__ */ jsxs(Menu, {
1782
+ trigger: "hover",
1783
+ position: "right-start",
1784
+ offset: 2,
1785
+ children: [/* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Menu.Item, {
1786
+ leftSection: item.icon,
1787
+ rightSection: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }),
1788
+ children: item.label
1789
+ }) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: item.children.map((child, childIndex) => /* @__PURE__ */ jsx(ActionMenuItem, {
1790
+ item: child,
1791
+ index: childIndex
1792
+ }, childIndex)) })]
1793
+ }, index);
1794
+ const menuItemProps = {};
1795
+ if (props.item.onClick) menuItemProps.onClick = action.run;
1796
+ else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
1797
+ return /* @__PURE__ */ jsx(Menu.Item, {
1798
+ leftSection: item.icon ?? (item.active ? /* @__PURE__ */ jsx(IconCheck, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(Flex, { w: ui.sizes.icon.sm })),
1799
+ onClick: item.onClick,
1800
+ color: item.color,
1801
+ ...menuItemProps,
1802
+ children: item.label
1803
+ }, index);
1804
+ };
1828
1805
  //#endregion
1829
1806
  //#region ../../src/core/components/buttons/BurgerButton.tsx
1830
1807
  const BurgerButton = (props) => {
@@ -1840,7 +1817,6 @@ const BurgerButton = (props) => {
1840
1817
  ...props
1841
1818
  });
1842
1819
  };
1843
-
1844
1820
  //#endregion
1845
1821
  //#region ../../src/core/components/buttons/ClipboardButton.tsx
1846
1822
  const ClipboardButton = (props) => {
@@ -1861,7 +1837,6 @@ const ClipboardButton = (props) => {
1861
1837
  })
1862
1838
  });
1863
1839
  };
1864
-
1865
1840
  //#endregion
1866
1841
  //#region ../../src/core/components/buttons/DarkModeButton.tsx
1867
1842
  /**
@@ -1893,7 +1868,6 @@ const DarkModeButton = (props) => {
1893
1868
  ...props
1894
1869
  });
1895
1870
  };
1896
-
1897
1871
  //#endregion
1898
1872
  //#region ../../src/core/components/buttons/LanguageButton.tsx
1899
1873
  const LanguageButton = (props) => {
@@ -1909,7 +1883,6 @@ const LanguageButton = (props) => {
1909
1883
  ...props
1910
1884
  });
1911
1885
  };
1912
-
1913
1886
  //#endregion
1914
1887
  //#region ../../src/core/components/buttons/OmnibarButton.tsx
1915
1888
  const OmnibarButton = (props) => {
@@ -1954,7 +1927,6 @@ const OmnibarButton = (props) => {
1954
1927
  })
1955
1928
  });
1956
1929
  };
1957
-
1958
1930
  //#endregion
1959
1931
  //#region ../../src/core/hooks/useDialog.ts
1960
1932
  /**
@@ -1971,7 +1943,6 @@ const OmnibarButton = (props) => {
1971
1943
  const useDialog = () => {
1972
1944
  return useInject(DialogService);
1973
1945
  };
1974
-
1975
1946
  //#endregion
1976
1947
  //#region ../../src/core/components/buttons/ThemeExpertModal.tsx
1977
1948
  const MANTINE_COLORS = [
@@ -2180,7 +2151,6 @@ const ThemeExpertModal = () => {
2180
2151
  ]
2181
2152
  });
2182
2153
  };
2183
-
2184
2154
  //#endregion
2185
2155
  //#region ../../src/core/components/buttons/ThemeButton.tsx
2186
2156
  const ThemeButton = (props) => {
@@ -2209,7 +2179,6 @@ const ThemeButton = (props) => {
2209
2179
  ...actionProps
2210
2180
  });
2211
2181
  };
2212
-
2213
2182
  //#endregion
2214
2183
  //#region ../../src/core/components/buttons/ToggleSidebarButton.tsx
2215
2184
  const ToggleSidebarButton = (props) => {
@@ -2231,10 +2200,10 @@ const ToggleSidebarButton = (props) => {
2231
2200
  ...props
2232
2201
  });
2233
2202
  };
2234
-
2235
2203
  //#endregion
2236
2204
  //#region ../../src/core/components/data/DetailList.tsx
2237
- const DetailList = ({ items, columns = 1 }) => {
2205
+ const DetailList = (props) => {
2206
+ const { items, columns = 1 } = props;
2238
2207
  return /* @__PURE__ */ jsx(Grid, {
2239
2208
  gutter: "xs",
2240
2209
  children: items.filter((item) => !item.hidden).map((item) => /* @__PURE__ */ jsx(Grid.Col, {
@@ -2273,7 +2242,6 @@ const DetailList = ({ items, columns = 1 }) => {
2273
2242
  }, item.label))
2274
2243
  });
2275
2244
  };
2276
-
2277
2245
  //#endregion
2278
2246
  //#region ../../src/core/components/data/StatCards.tsx
2279
2247
  const StatCards = ({ items }) => /* @__PURE__ */ jsx(Flex, {
@@ -2309,11 +2277,10 @@ const StatCards = ({ items }) => /* @__PURE__ */ jsx(Flex, {
2309
2277
  }, item.label);
2310
2278
  })
2311
2279
  });
2312
-
2313
2280
  //#endregion
2314
2281
  //#region ../../src/core/components/Flex.tsx
2315
2282
  const Flex$1 = forwardRef((props, ref) => {
2316
- const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, ...rest } = props;
2283
+ const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, overflow, form, ...rest } = props;
2317
2284
  if (fill) rest.flex ??= 1;
2318
2285
  if (col) rest.direction ??= "column";
2319
2286
  if (center) {
@@ -2336,13 +2303,23 @@ const Flex$1 = forwardRef((props, ref) => {
2336
2303
  ...rest.style ?? {}
2337
2304
  };
2338
2305
  if (shadowed) rest.className = `${rest.className ?? ""} shadow-${shadowed === true ? "md" : shadowed}`.trim();
2306
+ if (overflow) rest.className = `${rest.className ?? ""} overflow-auto`.trim();
2307
+ if (form) {
2308
+ let formProps = typeof form === "object" ? form : {};
2309
+ if (formProps instanceof FormModel) formProps = formProps.props;
2310
+ return /* @__PURE__ */ jsx(Flex, {
2311
+ ref,
2312
+ component: "form",
2313
+ ...formProps,
2314
+ ...rest
2315
+ });
2316
+ }
2339
2317
  return /* @__PURE__ */ jsx(Flex, {
2340
2318
  ref,
2341
2319
  ...rest
2342
2320
  });
2343
2321
  });
2344
2322
  Flex$1.displayName = "Flex";
2345
-
2346
2323
  //#endregion
2347
2324
  //#region ../../src/core/components/layout/AppBar.tsx
2348
2325
  const AppBar = (props) => {
@@ -2457,7 +2434,6 @@ const AppBar = (props) => {
2457
2434
  });
2458
2435
  return content;
2459
2436
  };
2460
-
2461
2437
  //#endregion
2462
2438
  //#region ../../src/core/components/layout/Breadcrumb.tsx
2463
2439
  /**
@@ -2467,7 +2443,8 @@ const AppBar = (props) => {
2467
2443
  * Pages should define a `label` in their `$page()` options for best results.
2468
2444
  * Falls back to the page name converted to Title Case.
2469
2445
  */
2470
- const Breadcrumb = ({ home = "Home", separator, size = "sm", ...groupProps }) => {
2446
+ const Breadcrumbs = (props) => {
2447
+ const { home = "Home", separator, size = "sm", ...groupProps } = props;
2471
2448
  const state = useRouterState();
2472
2449
  const router = useRouter();
2473
2450
  const crumbs = [];
@@ -2511,7 +2488,6 @@ const Breadcrumb = ({ home = "Home", separator, size = "sm", ...groupProps }) =>
2511
2488
  }, crumb.href))
2512
2489
  });
2513
2490
  };
2514
-
2515
2491
  //#endregion
2516
2492
  //#region ../../src/core/components/layout/Container.tsx
2517
2493
  const Container$1 = forwardRef((props, ref) => {
@@ -2521,12 +2497,171 @@ const Container$1 = forwardRef((props, ref) => {
2521
2497
  });
2522
2498
  });
2523
2499
  Container$1.displayName = "Container";
2524
-
2500
+ //#endregion
2501
+ //#region ../../src/core/helpers/renderIcon.tsx
2502
+ const renderIcon = (icon, size) => {
2503
+ if (!icon) return null;
2504
+ if (isValidElement(icon)) return icon;
2505
+ if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui.sizes.icon.md });
2506
+ return icon;
2507
+ };
2508
+ //#endregion
2509
+ //#region ../../src/core/components/Text.tsx
2510
+ const INTENT_COLORS = {
2511
+ primary: "blue",
2512
+ info: "cyan",
2513
+ success: "green",
2514
+ warning: "yellow",
2515
+ danger: "red"
2516
+ };
2517
+ const Text$1 = forwardRef((props, ref) => {
2518
+ const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
2519
+ if (intent) rest.c ??= INTENT_COLORS[intent];
2520
+ if (bold) rest.fw ??= 700;
2521
+ if (light) rest.fw ??= 300;
2522
+ if (italic) rest.fs ??= "italic";
2523
+ if (muted) rest.c ??= "dimmed";
2524
+ if (small) rest.size ??= "xs";
2525
+ if (uppercase) rest.tt ??= "uppercase";
2526
+ if (capitalize) rest.tt ??= "capitalize";
2527
+ if (center) rest.ta ??= "center";
2528
+ if (monospace) rest.ff ??= "monospace";
2529
+ if (title) rest.size ??= "xl";
2530
+ return /* @__PURE__ */ jsx(Text, {
2531
+ ref,
2532
+ ...rest
2533
+ });
2534
+ });
2535
+ Text$1.displayName = "Text";
2536
+ //#endregion
2537
+ //#region ../../src/core/components/layout/SidebarCollapsedItem.tsx
2538
+ const SidebarCollapsedItem = (props) => {
2539
+ const router = useRouter();
2540
+ const handleItemClick = () => {
2541
+ props.onItemClick?.(props.item);
2542
+ props.item.onClick?.();
2543
+ };
2544
+ const hasChildren = props.item.children && props.item.children.length > 0;
2545
+ const menu = hasChildren ? {
2546
+ on: "hover",
2547
+ position: "right",
2548
+ menuProps: {
2549
+ arrowPosition: "center",
2550
+ arrowSize: 10,
2551
+ withArrow: true
2552
+ },
2553
+ items: [{
2554
+ type: "label",
2555
+ label: props.item.label
2556
+ }, ...props.item.children.filter((child) => !child.can || child.can()).map((child) => ({
2557
+ label: child.label,
2558
+ icon: renderIcon(child.icon, ui.sizes.icon.sm),
2559
+ href: child.href,
2560
+ active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
2561
+ }))]
2562
+ } : void 0;
2563
+ return /* @__PURE__ */ jsx(Flex$1, {
2564
+ w: "100%",
2565
+ justify: "center",
2566
+ pos: "relative",
2567
+ children: /* @__PURE__ */ jsx(ActionButton, {
2568
+ size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
2569
+ bd: 0,
2570
+ variant: "default",
2571
+ propsActive: { variant: "outline" },
2572
+ tooltip: hasChildren ? void 0 : {
2573
+ label: props.item.label,
2574
+ position: "right"
2575
+ },
2576
+ onClick: hasChildren ? void 0 : handleItemClick,
2577
+ icon: renderIcon(props.item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
2578
+ href: hasChildren ? void 0 : props.item.href,
2579
+ target: hasChildren ? void 0 : props.item.target,
2580
+ menu,
2581
+ ...props.item.actionProps
2582
+ })
2583
+ });
2584
+ };
2585
+ //#endregion
2586
+ //#region ../../src/core/components/layout/SidebarItem.tsx
2587
+ const SidebarItem = (props) => {
2588
+ const maxLevel = 2;
2589
+ const router = useRouter();
2590
+ const isActive = useCallback((item) => {
2591
+ if (!item.children) return false;
2592
+ for (const child of item.children) {
2593
+ if (child.href) {
2594
+ if (router.isActive(child.href)) return true;
2595
+ }
2596
+ if (isActive(child)) return true;
2597
+ }
2598
+ return false;
2599
+ }, []);
2600
+ const [isOpen, setIsOpen] = useState(isActive(props.item));
2601
+ useEvents({ "react:transition:end": () => {
2602
+ if (isActive(props.item)) setIsOpen(true);
2603
+ } }, []);
2604
+ if (props.level > maxLevel) return null;
2605
+ const handleItemClick = (e) => {
2606
+ if (!props.item.target) e.preventDefault();
2607
+ if (props.item.children && props.item.children.length > 0) setIsOpen(!isOpen);
2608
+ else {
2609
+ props.onItemClick?.(props.item);
2610
+ props.item.onClick?.();
2611
+ }
2612
+ };
2613
+ return /* @__PURE__ */ jsxs(Flex$1, {
2614
+ direction: "column",
2615
+ ps: props.level === 0 ? 0 : 32,
2616
+ pos: "relative",
2617
+ children: [/* @__PURE__ */ jsx(ActionButton, {
2618
+ w: "100%",
2619
+ justify: "space-between",
2620
+ href: props.item.href,
2621
+ target: props.item.target,
2622
+ size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
2623
+ bd: 0,
2624
+ fw: "normal",
2625
+ variant: "default",
2626
+ propsActive: { variant: "outline" },
2627
+ radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
2628
+ onClick: handleItemClick,
2629
+ leftSection: /* @__PURE__ */ jsxs(Flex$1, {
2630
+ w: "100%",
2631
+ align: "center",
2632
+ gap: "sm",
2633
+ children: [renderIcon(props.item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex$1, {
2634
+ direction: "column",
2635
+ children: /* @__PURE__ */ jsx(Flex$1, { children: props.item.label })
2636
+ })]
2637
+ }),
2638
+ rightSection: props.item.children ? /* @__PURE__ */ jsx(Flex$1, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
2639
+ ...props.item.actionProps
2640
+ }), props.item.children && isOpen && /* @__PURE__ */ jsxs(Flex$1, {
2641
+ direction: "column",
2642
+ "data-parent-level": props.level,
2643
+ gap: 2,
2644
+ py: 2,
2645
+ children: [/* @__PURE__ */ jsx(Flex$1, { style: {
2646
+ position: "absolute",
2647
+ width: 1,
2648
+ background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
2649
+ top: 48,
2650
+ left: 20 + 32 * props.level,
2651
+ bottom: 16
2652
+ } }), props.item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
2653
+ item: child,
2654
+ level: props.level + 1,
2655
+ onItemClick: props.onItemClick,
2656
+ theme: props.theme
2657
+ }, index))]
2658
+ })]
2659
+ });
2660
+ };
2525
2661
  //#endregion
2526
2662
  //#region ../../src/core/components/layout/Sidebar.tsx
2527
2663
  const Sidebar = (props) => {
2528
2664
  const router = useRouter();
2529
- const { onItemClick } = props;
2530
2665
  const divider = (key, fill, collapsed) => {
2531
2666
  return /* @__PURE__ */ jsx(Flex$1, {
2532
2667
  h: 1,
@@ -2577,13 +2712,13 @@ const Sidebar = (props) => {
2577
2712
  if (collapsed) return /* @__PURE__ */ jsx(SidebarCollapsedItem, {
2578
2713
  item,
2579
2714
  level: 0,
2580
- onItemClick,
2715
+ onItemClick: props.onItemClick,
2581
2716
  theme: props.theme ?? {}
2582
2717
  }, key);
2583
2718
  return /* @__PURE__ */ jsx(SidebarItem, {
2584
2719
  item,
2585
2720
  level: 0,
2586
- onItemClick,
2721
+ onItemClick: props.onItemClick,
2587
2722
  theme: props.theme ?? {}
2588
2723
  }, key);
2589
2724
  };
@@ -2646,133 +2781,9 @@ const Sidebar = (props) => {
2646
2781
  })] });
2647
2782
  return renderSidebar(false);
2648
2783
  };
2649
- const SidebarItem = (props) => {
2650
- const { item, level } = props;
2651
- const maxLevel = 2;
2652
- const router = useRouter();
2653
- const isActive = useCallback((item) => {
2654
- if (!item.children) return false;
2655
- for (const child of item.children) {
2656
- if (child.href) {
2657
- if (router.isActive(child.href)) return true;
2658
- }
2659
- if (isActive(child)) return true;
2660
- }
2661
- return false;
2662
- }, []);
2663
- const [isOpen, setIsOpen] = useState(isActive(item));
2664
- useEvents({ "react:transition:end": () => {
2665
- if (isActive(item)) setIsOpen(true);
2666
- } }, []);
2667
- if (level > maxLevel) return null;
2668
- const handleItemClick = (e) => {
2669
- if (!props.item.target) e.preventDefault();
2670
- if (item.children && item.children.length > 0) setIsOpen(!isOpen);
2671
- else {
2672
- props.onItemClick?.(item);
2673
- item.onClick?.();
2674
- }
2675
- };
2676
- return /* @__PURE__ */ jsxs(Flex$1, {
2677
- direction: "column",
2678
- ps: level === 0 ? 0 : 32,
2679
- pos: "relative",
2680
- children: [/* @__PURE__ */ jsx(ActionButton, {
2681
- w: "100%",
2682
- justify: "space-between",
2683
- href: props.item.href,
2684
- target: props.item.target,
2685
- size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
2686
- bd: 0,
2687
- fw: "normal",
2688
- variant: "default",
2689
- propsActive: { variant: "outline" },
2690
- radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
2691
- onClick: handleItemClick,
2692
- leftSection: /* @__PURE__ */ jsxs(Flex$1, {
2693
- w: "100%",
2694
- align: "center",
2695
- gap: "sm",
2696
- children: [renderIcon(item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex$1, {
2697
- direction: "column",
2698
- children: /* @__PURE__ */ jsx(Flex$1, { children: item.label })
2699
- })]
2700
- }),
2701
- rightSection: item.children ? /* @__PURE__ */ jsx(Flex$1, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
2702
- ...props.item.actionProps
2703
- }), item.children && isOpen && /* @__PURE__ */ jsxs(Flex$1, {
2704
- direction: "column",
2705
- "data-parent-level": level,
2706
- gap: 2,
2707
- py: 2,
2708
- children: [/* @__PURE__ */ jsx(Flex$1, { style: {
2709
- position: "absolute",
2710
- width: 1,
2711
- background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
2712
- top: 48,
2713
- left: 20 + 32 * level,
2714
- bottom: 16
2715
- } }), item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
2716
- item: child,
2717
- level: level + 1,
2718
- onItemClick: props.onItemClick,
2719
- theme: props.theme
2720
- }, index))]
2721
- })]
2722
- });
2723
- };
2724
- const SidebarCollapsedItem = (props) => {
2725
- const { item, level } = props;
2726
- const router = useRouter();
2727
- const handleItemClick = () => {
2728
- props.onItemClick?.(item);
2729
- item.onClick?.();
2730
- };
2731
- const hasChildren = item.children && item.children.length > 0;
2732
- const menu = hasChildren ? {
2733
- on: "hover",
2734
- position: "right",
2735
- menuProps: {
2736
- arrowPosition: "center",
2737
- arrowSize: 10,
2738
- withArrow: true
2739
- },
2740
- items: [{
2741
- type: "label",
2742
- label: item.label
2743
- }, ...item.children.filter((child) => !child.can || child.can()).map((child) => ({
2744
- label: child.label,
2745
- icon: renderIcon(child.icon, ui.sizes.icon.sm),
2746
- href: child.href,
2747
- active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
2748
- }))]
2749
- } : void 0;
2750
- return /* @__PURE__ */ jsx(Flex$1, {
2751
- w: "100%",
2752
- justify: "center",
2753
- pos: "relative",
2754
- children: /* @__PURE__ */ jsx(ActionButton, {
2755
- size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
2756
- bd: 0,
2757
- variant: "default",
2758
- propsActive: { variant: "outline" },
2759
- tooltip: hasChildren ? void 0 : {
2760
- label: item.label,
2761
- position: "right"
2762
- },
2763
- onClick: hasChildren ? void 0 : handleItemClick,
2764
- icon: renderIcon(item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
2765
- href: hasChildren ? void 0 : props.item.href,
2766
- target: hasChildren ? void 0 : props.item.target,
2767
- menu,
2768
- ...props.item.actionProps
2769
- })
2770
- });
2771
- };
2772
-
2773
- //#endregion
2774
- //#region ../../src/core/components/layout/DashboardShell.tsx
2775
- const DashboardShell = (props) => {
2784
+ //#endregion
2785
+ //#region ../../src/core/components/layout/DashboardShell.tsx
2786
+ const DashboardShell = (props) => {
2776
2787
  const router = useRouter();
2777
2788
  const [sidebar, setSidebar] = useStore(alephaSidebarAtom);
2778
2789
  const collapsed = props.sidebarProps?.collapsed !== void 0 ? props.sidebarProps.collapsed : sidebar.collapsed;
@@ -2809,6 +2820,8 @@ const DashboardShell = (props) => {
2809
2820
  const fHeight = props.footerHeight ?? 24;
2810
2821
  const headerHeight = hasAppBar ? hHeight : 0;
2811
2822
  const footerHeight = footerElement ? fHeight : 0;
2823
+ const navbarWidth = collapsed ? collapsedWidth : expandedWidth;
2824
+ const mainContent = props.children ?? /* @__PURE__ */ jsx(NestedView, {});
2812
2825
  return /* @__PURE__ */ jsxs(AppShell, {
2813
2826
  layout: "alt",
2814
2827
  w: "100%",
@@ -2816,7 +2829,7 @@ const DashboardShell = (props) => {
2816
2829
  flex: 1,
2817
2830
  header: hasAppBar ? { height: hHeight } : void 0,
2818
2831
  navbar: hasSidebar ? {
2819
- width: { base: collapsed ? collapsedWidth : expandedWidth },
2832
+ width: { base: navbarWidth },
2820
2833
  breakpoint: "md",
2821
2834
  collapsed: { mobile: sidebar.closed }
2822
2835
  } : void 0,
@@ -2853,8 +2866,12 @@ const DashboardShell = (props) => {
2853
2866
  display: "flex",
2854
2867
  bg: "var(--alepha-ground)",
2855
2868
  pos: "relative",
2869
+ h: props.fill ? "100%" : "inherit",
2856
2870
  ...props.appShellMainProps,
2857
- children: props.children ?? /* @__PURE__ */ jsx(NestedView, {})
2871
+ children: props.container ? /* @__PURE__ */ jsx(Container$1, {
2872
+ ...typeof props.container === "boolean" ? {} : props.container,
2873
+ children: mainContent
2874
+ }) : mainContent
2858
2875
  }),
2859
2876
  footerElement && /* @__PURE__ */ jsx(AppShell.Footer, {
2860
2877
  ...props.appShellFooterProps,
@@ -2863,42 +2880,12 @@ const DashboardShell = (props) => {
2863
2880
  ]
2864
2881
  });
2865
2882
  };
2866
-
2867
- //#endregion
2868
- //#region ../../src/core/components/Text.tsx
2869
- const INTENT_COLORS = {
2870
- primary: "blue",
2871
- info: "cyan",
2872
- success: "green",
2873
- warning: "yellow",
2874
- danger: "red"
2875
- };
2876
- const Text$1 = forwardRef((props, ref) => {
2877
- const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
2878
- if (intent) rest.c ??= INTENT_COLORS[intent];
2879
- if (bold) rest.fw ??= 700;
2880
- if (light) rest.fw ??= 300;
2881
- if (italic) rest.fs ??= "italic";
2882
- if (muted) rest.c ??= "dimmed";
2883
- if (small) rest.size ??= "xs";
2884
- if (uppercase) rest.tt ??= "uppercase";
2885
- if (capitalize) rest.tt ??= "capitalize";
2886
- if (center) rest.ta ??= "center";
2887
- if (monospace) rest.ff ??= "monospace";
2888
- if (title) rest.size ??= "xl";
2889
- return /* @__PURE__ */ jsx(Text, {
2890
- ref,
2891
- ...rest
2892
- });
2893
- });
2894
- Text$1.displayName = "Text";
2895
-
2896
2883
  //#endregion
2897
2884
  //#region ../../src/core/form/utils/parseInput.ts
2898
2885
  const parseInput = (props, form) => {
2899
2886
  const disabled = false;
2900
2887
  const id = props.input.props.id;
2901
- const label = props.title ?? ("title" in props.input.schema && typeof props.input.schema.title === "string" ? props.input.schema.title : void 0) ?? prettyName(props.input.path);
2888
+ const label = props.label ?? ("title" in props.input.schema && typeof props.input.schema.title === "string" ? props.input.schema.title : void 0) ?? prettyName(props.input.path);
2902
2889
  const description = props.description ?? ("description" in props.input.schema && typeof props.input.schema.description === "string" ? props.input.schema.description : void 0);
2903
2890
  const error = form.error && form.error instanceof TypeBoxError ? form.error.value.message : void 0;
2904
2891
  const icon = !props.icon ? getDefaultIcon({
@@ -2906,17 +2893,20 @@ const parseInput = (props, form) => {
2906
2893
  format: props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0,
2907
2894
  name: props.input.props.name,
2908
2895
  isEnum: props.input.schema && "enum" in props.input.schema && Boolean(props.input.schema.enum),
2909
- isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array"
2910
- }) : isValidElement(props.icon) ? props.icon : createElement(props.icon, { size: ui.sizes.icon.md });
2896
+ isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array",
2897
+ size: props.size
2898
+ }) : isValidElement(props.icon) ? props.icon : createElement(props.icon, { size: ui.sizes.icon.sm });
2911
2899
  const format = props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0;
2912
2900
  const required = props.input.required;
2913
2901
  const schema = props.input.schema;
2902
+ const testId = props.input.props?.["data-testid"];
2914
2903
  const inputProps = {
2915
2904
  label,
2916
2905
  description,
2917
2906
  error,
2918
2907
  required,
2919
- disabled
2908
+ disabled,
2909
+ ...testId ? { "data-testid": testId } : {}
2920
2910
  };
2921
2911
  if ("minLength" in schema && typeof schema.minLength === "number") inputProps.minLength = schema.minLength;
2922
2912
  if ("maxLength" in schema && typeof schema.maxLength === "number") inputProps.maxLength = schema.maxLength;
@@ -2930,7 +2920,6 @@ const parseInput = (props, form) => {
2930
2920
  inputProps
2931
2921
  };
2932
2922
  };
2933
-
2934
2923
  //#endregion
2935
2924
  //#region ../../src/core/form/components/ControlArray.tsx
2936
2925
  /**
@@ -2941,8 +2930,8 @@ const useArrayItems = (input) => {
2941
2930
  const alepha = useAlepha();
2942
2931
  const keyCounter = useRef(0);
2943
2932
  const [items, setItemsState] = useState(() => {
2944
- const defaultValue = input?.props?.defaultValue;
2945
- if (Array.isArray(defaultValue)) return defaultValue.map((value) => ({
2933
+ const initial = input?.initialValue;
2934
+ if (Array.isArray(initial)) return initial.map((value) => ({
2946
2935
  key: keyCounter.current++,
2947
2936
  value
2948
2937
  }));
@@ -2968,22 +2957,9 @@ const useArrayItems = (input) => {
2968
2957
  if (!input?.form) return;
2969
2958
  const formId = input.form.id;
2970
2959
  const fieldPath = input.path;
2971
- const listeners = [alepha.events.on("form:reset", (event) => {
2972
- if (event.id === formId) {
2973
- const defaultValue = input.props?.defaultValue;
2974
- keyCounter.current = 0;
2975
- if (Array.isArray(defaultValue)) setItemsState(defaultValue.map((value) => ({
2976
- key: keyCounter.current++,
2977
- value
2978
- })));
2979
- else setItemsState([]);
2980
- }
2981
- }), alepha.events.on("form:change", (event) => {
2960
+ return alepha.events.on("form:change", (event) => {
2982
2961
  if (event.id === formId && event.path === fieldPath) syncFromFormValue(event.value);
2983
- })];
2984
- return () => {
2985
- for (const unsub of listeners) unsub();
2986
- };
2962
+ });
2987
2963
  }, [
2988
2964
  alepha,
2989
2965
  input,
@@ -3008,10 +2984,10 @@ const createArrayItemInput = (parentInput, itemSchema, index, _itemKey, value, o
3008
2984
  path: `${parentInput.path}/${index}`,
3009
2985
  required: false,
3010
2986
  form: parentInput.form,
2987
+ initialValue: value,
3011
2988
  props: {
3012
2989
  id: `${parentInput.props.id}-${index}`,
3013
- name: `${parentInput.props.name}[${index}]`,
3014
- defaultValue: value
2990
+ name: `${parentInput.props.name}[${index}]`
3015
2991
  },
3016
2992
  set: onValueChange
3017
2993
  };
@@ -3026,10 +3002,10 @@ const createArrayItemFieldInput = (parentInput, itemSchema, fieldName, index, _i
3026
3002
  path: `${parentInput.path}/${index}/${fieldName}`,
3027
3003
  required: itemSchema.required?.includes(fieldName) ?? false,
3028
3004
  form: parentInput.form,
3005
+ initialValue: itemValue?.[fieldName],
3029
3006
  props: {
3030
3007
  id: `${parentInput.props.id}-${index}-${fieldName}`,
3031
- name: `${parentInput.props.name}[${index}].${fieldName}`,
3032
- defaultValue: itemValue?.[fieldName]
3008
+ name: `${parentInput.props.name}[${index}].${fieldName}`
3033
3009
  },
3034
3010
  set: (value) => onFieldChange(fieldName, value)
3035
3011
  };
@@ -3233,7 +3209,6 @@ const ControlArray = (props) => {
3233
3209
  })
3234
3210
  });
3235
3211
  };
3236
-
3237
3212
  //#endregion
3238
3213
  //#region ../../src/core/form/components/ControlDate.tsx
3239
3214
  /**
@@ -3247,7 +3222,9 @@ const ControlArray = (props) => {
3247
3222
  * Automatically detects date formats from schema and renders appropriate picker.
3248
3223
  */
3249
3224
  const ControlDate = (props) => {
3250
- const { inputProps, id, icon, format } = parseInput(props, useFormState(props.input));
3225
+ const form = useFormState(props.input);
3226
+ const [value, setValue] = useFieldValue(props.input);
3227
+ const { inputProps, id, icon, format } = parseInput(props, form);
3251
3228
  if (!props.input?.props) return null;
3252
3229
  if (props.datetime || format === "date-time") {
3253
3230
  const dateTimePickerProps = typeof props.datetime === "object" ? props.datetime : {};
@@ -3255,10 +3232,8 @@ const ControlDate = (props) => {
3255
3232
  ...inputProps,
3256
3233
  id,
3257
3234
  leftSection: icon,
3258
- defaultValue: props.input.props.defaultValue ? new Date(props.input.props.defaultValue) : void 0,
3259
- onChange: (value) => {
3260
- props.input.set(value ? new Date(value).toISOString() : void 0);
3261
- },
3235
+ value: value ? new Date(value) : null,
3236
+ onChange: (val) => setValue(val ? new Date(val).toISOString() : void 0),
3262
3237
  ...dateTimePickerProps
3263
3238
  });
3264
3239
  }
@@ -3268,10 +3243,8 @@ const ControlDate = (props) => {
3268
3243
  ...inputProps,
3269
3244
  id,
3270
3245
  leftSection: icon,
3271
- defaultValue: props.input.props.defaultValue ? new Date(props.input.props.defaultValue) : void 0,
3272
- onChange: (value) => {
3273
- props.input.set(value ? new Date(value).toISOString().slice(0, 10) : void 0);
3274
- },
3246
+ value: value ? new Date(value) : null,
3247
+ onChange: (val) => setValue(val ? new Date(val).toISOString().slice(0, 10) : void 0),
3275
3248
  ...dateInputProps
3276
3249
  });
3277
3250
  }
@@ -3281,30 +3254,23 @@ const ControlDate = (props) => {
3281
3254
  ...inputProps,
3282
3255
  id,
3283
3256
  leftSection: icon,
3284
- defaultValue: props.input.props.defaultValue,
3285
- onChange: (event) => {
3286
- props.input.set(event.currentTarget.value);
3287
- },
3257
+ value: value ?? "",
3258
+ onChange: (event) => setValue(event.currentTarget.value),
3288
3259
  ...timeInputProps
3289
3260
  });
3290
3261
  }
3291
3262
  return null;
3292
3263
  };
3293
-
3294
3264
  //#endregion
3295
3265
  //#region ../../src/core/form/components/ControlNumber.tsx
3296
3266
  /**
3297
3267
  *
3298
3268
  */
3299
3269
  const ControlNumber = (props) => {
3300
- const { inputProps, id, icon } = parseInput(props, useFormState(props.input));
3301
- const ref = useRef(null);
3302
- const [value, setValue] = useState(props.input.props.defaultValue);
3303
- useEvents({ "form:reset": (event) => {
3304
- if (event.id === props.input?.form.id && ref.current) setValue(props.input.props.defaultValue);
3305
- } }, [props.input]);
3270
+ const form = useFormState(props.input);
3271
+ const [value, setValue] = useFieldValue(props.input);
3272
+ const { inputProps, id, icon } = parseInput(props, form);
3306
3273
  if (!props.input?.props) return null;
3307
- const { type, ...inputPropsWithoutType } = props.input.props;
3308
3274
  if (props.sliderProps) {
3309
3275
  const min = props.sliderProps.min ?? inputProps.minimum ?? 0;
3310
3276
  const max = props.sliderProps.max ?? inputProps.maximum ?? 100;
@@ -3317,38 +3283,28 @@ const ControlNumber = (props) => {
3317
3283
  },
3318
3284
  children: /* @__PURE__ */ jsx(Slider, {
3319
3285
  ...inputProps,
3320
- ref,
3321
3286
  id,
3322
- ...inputPropsWithoutType,
3323
3287
  ...props.sliderProps,
3324
- value,
3288
+ value: value ?? 0,
3325
3289
  min,
3326
3290
  max,
3327
3291
  label: () => value,
3328
- onChange: (val) => {
3329
- setValue(val);
3330
- props.input.set(val);
3331
- }
3292
+ onChange: (val) => setValue(val)
3332
3293
  })
3333
3294
  })
3334
3295
  });
3335
3296
  }
3336
3297
  return /* @__PURE__ */ jsx(NumberInput, {
3337
3298
  ...inputProps,
3338
- ref,
3339
3299
  id,
3340
3300
  leftSection: icon,
3341
- ...inputPropsWithoutType,
3342
3301
  ...props.numberInputProps,
3343
3302
  value: value ?? "",
3344
3303
  onChange: (val) => {
3345
- const newValue = val !== null ? Number(val) : void 0;
3346
- setValue(newValue);
3347
- props.input.set(newValue);
3304
+ setValue(val !== null ? Number(val) : void 0);
3348
3305
  }
3349
3306
  });
3350
3307
  };
3351
-
3352
3308
  //#endregion
3353
3309
  //#region ../../src/core/form/components/ControlObject.tsx
3354
3310
  /**
@@ -3425,94 +3381,10 @@ const ControlObject = (props) => {
3425
3381
  })
3426
3382
  });
3427
3383
  };
3428
-
3429
3384
  //#endregion
3430
- //#region ../../src/core/form/components/ControlQueryBuilder.tsx
3431
- /**
3432
- * Query builder with text input and help popover.
3433
- * Generates query strings for parseQueryString syntax.
3434
- */
3435
- const ControlQueryBuilder = ({ schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps }) => {
3436
- const [helpOpened, setHelpOpened] = useState(false);
3437
- const [textValue, setTextValue] = useState(value);
3438
- const inputRef = useRef(null);
3439
- const fields = schema ? extractSchemaFields(schema) : [];
3440
- const [error, setError] = useState(null);
3441
- const isValid = (value) => {
3442
- try {
3443
- parseQueryString(value.trim());
3444
- } catch (e) {
3445
- setError(e.message);
3446
- return false;
3447
- }
3448
- setError(null);
3449
- return true;
3450
- };
3451
- const handleTextChange = (newValue) => {
3452
- setTextValue(newValue);
3453
- if (isValid(newValue)) onChange?.(newValue);
3454
- };
3455
- const handleClear = () => {
3456
- setTextValue("");
3457
- onChange?.("");
3458
- isValid("");
3459
- };
3460
- const handleInsert = (text) => {
3461
- const newValue = textValue ? `${textValue}${text} ` : `${text} `;
3462
- setTextValue(newValue);
3463
- if (isValid(newValue)) onChange?.(newValue);
3464
- setTimeout(() => {
3465
- inputRef.current?.focus();
3466
- const length = inputRef.current?.value.length || 0;
3467
- inputRef.current?.setSelectionRange(length, length);
3468
- }, 0);
3469
- };
3470
- useEvents({ "form:change": (event) => {
3471
- if (event.id === inputRef.current?.form?.id) {
3472
- if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
3473
- }
3474
- } }, []);
3475
- return /* @__PURE__ */ jsxs(Popover, {
3476
- width: 800,
3477
- position: "bottom-start",
3478
- shadow: "md",
3479
- opened: helpOpened,
3480
- onChange: setHelpOpened,
3481
- closeOnClickOutside: true,
3482
- closeOnEscape: true,
3483
- transitionProps: {
3484
- transition: "fade-up",
3485
- duration: 200,
3486
- timingFunction: "ease"
3487
- },
3488
- children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
3489
- ref: inputRef,
3490
- placeholder,
3491
- value: textValue,
3492
- onChange: (e) => handleTextChange(e.currentTarget.value),
3493
- onFocus: () => setHelpOpened(true),
3494
- leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
3495
- rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
3496
- size: "sm",
3497
- variant: "subtle",
3498
- color: "gray",
3499
- onClick: handleClear,
3500
- children: /* @__PURE__ */ jsx(IconX, { size: 14 })
3501
- }),
3502
- ...textInputProps
3503
- }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
3504
- bg: "transparent",
3505
- p: "xs",
3506
- bd: `1px solid ${ui.colors.border}`,
3507
- style: { backdropFilter: "blur(20px)" },
3508
- children: /* @__PURE__ */ jsx(QueryHelp, {
3509
- fields,
3510
- onInsert: handleInsert
3511
- })
3512
- })]
3513
- });
3514
- };
3515
- function QueryHelp({ fields, onInsert }) {
3385
+ //#region ../../src/core/form/components/ControlQueryBuilderHelp.tsx
3386
+ const ControlQueryBuilderHelp = (props) => {
3387
+ const { fields, onInsert } = props;
3516
3388
  return /* @__PURE__ */ jsxs(Flex, {
3517
3389
  gap: "md",
3518
3390
  align: "flex-start",
@@ -3675,112 +3547,312 @@ function QueryHelp({ fields, onInsert }) {
3675
3547
  })
3676
3548
  ]
3677
3549
  });
3678
- }
3679
-
3550
+ };
3551
+ //#endregion
3552
+ //#region ../../src/core/form/components/ControlQueryBuilder.tsx
3553
+ /**
3554
+ * Query builder with text input and help popover.
3555
+ * Generates query strings for parseQueryString syntax.
3556
+ */
3557
+ const ControlQueryBuilder = (props) => {
3558
+ const { schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps } = props;
3559
+ const [helpOpened, setHelpOpened] = useState(false);
3560
+ const [textValue, setTextValue] = useState(value);
3561
+ const inputRef = useRef(null);
3562
+ const fields = schema ? extractSchemaFields(schema) : [];
3563
+ const [error, setError] = useState(null);
3564
+ const isValid = (value) => {
3565
+ try {
3566
+ parseQueryString(value.trim());
3567
+ } catch (e) {
3568
+ setError(e.message);
3569
+ return false;
3570
+ }
3571
+ setError(null);
3572
+ return true;
3573
+ };
3574
+ const handleTextChange = (newValue) => {
3575
+ setTextValue(newValue);
3576
+ if (isValid(newValue)) onChange?.(newValue);
3577
+ };
3578
+ const handleClear = () => {
3579
+ setTextValue("");
3580
+ onChange?.("");
3581
+ isValid("");
3582
+ };
3583
+ const handleInsert = (text) => {
3584
+ const newValue = textValue ? `${textValue}${text} ` : `${text} `;
3585
+ setTextValue(newValue);
3586
+ if (isValid(newValue)) onChange?.(newValue);
3587
+ setTimeout(() => {
3588
+ inputRef.current?.focus();
3589
+ const length = inputRef.current?.value.length || 0;
3590
+ inputRef.current?.setSelectionRange(length, length);
3591
+ }, 0);
3592
+ };
3593
+ useEvents({ "form:change": (event) => {
3594
+ if (event.id === inputRef.current?.form?.id) {
3595
+ if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
3596
+ }
3597
+ } }, []);
3598
+ return /* @__PURE__ */ jsxs(Popover, {
3599
+ width: 800,
3600
+ position: "bottom-start",
3601
+ shadow: "md",
3602
+ opened: helpOpened,
3603
+ onChange: setHelpOpened,
3604
+ closeOnClickOutside: true,
3605
+ closeOnEscape: true,
3606
+ transitionProps: {
3607
+ transition: "fade-up",
3608
+ duration: 200,
3609
+ timingFunction: "ease"
3610
+ },
3611
+ children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
3612
+ ref: inputRef,
3613
+ placeholder,
3614
+ value: textValue,
3615
+ onChange: (e) => handleTextChange(e.currentTarget.value),
3616
+ onFocus: () => setHelpOpened(true),
3617
+ leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
3618
+ rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
3619
+ size: "sm",
3620
+ variant: "subtle",
3621
+ color: "gray",
3622
+ onClick: handleClear,
3623
+ children: /* @__PURE__ */ jsx(IconX, { size: 14 })
3624
+ }),
3625
+ ...textInputProps
3626
+ }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
3627
+ bg: "transparent",
3628
+ p: "xs",
3629
+ bd: `1px solid ${ui.colors.border}`,
3630
+ style: { backdropFilter: "blur(20px)" },
3631
+ children: /* @__PURE__ */ jsx(ControlQueryBuilderHelp, {
3632
+ fields,
3633
+ onInsert: handleInsert
3634
+ })
3635
+ })]
3636
+ });
3637
+ };
3680
3638
  //#endregion
3681
3639
  //#region ../../src/core/form/components/ControlSelect.tsx
3682
3640
  /**
3683
- * ControlSelect component for handling Select, MultiSelect, and TagsInput.
3641
+ * ControlSelect component for handling Select, MultiSelect, Autocomplete, and TagsInput.
3684
3642
  *
3685
3643
  * Features:
3686
3644
  * - Basic Select with enum support
3687
3645
  * - MultiSelect for array of enums
3688
- * - TagsInput for array of strings (no enum)
3689
- * - Future: Lazy loading
3690
- * - Future: Searchable/filterable options
3691
- * - Future: Custom option rendering
3646
+ * - Autocomplete for creatable single values
3647
+ * - TagsInput for creatable array values
3648
+ * - Async lazy loading with auto short/long mode detection
3649
+ * - Short mode: client-side filtering with cached data
3650
+ * - Long mode: debounced server search
3692
3651
  *
3693
3652
  * Automatically detects enum values and array types from schema.
3694
3653
  */
3695
3654
  const ControlSelect = (props) => {
3696
- const { inputProps, id, icon } = parseInput(props, useFormState(props.input));
3655
+ const form = useFormState(props.input);
3656
+ const [value, setValue] = useFieldValue(props.input);
3657
+ const { inputProps, id, icon } = parseInput(props, form);
3697
3658
  const isArray = props.input.schema && "type" in props.input.schema && props.input.schema.type === "array";
3698
- let itemsEnum;
3699
- if (isArray && "items" in props.input.schema && props.input.schema.items) {
3700
- const items = props.input.schema.items;
3701
- if ("enum" in items && Array.isArray(items.enum)) itemsEnum = items.enum;
3702
- }
3659
+ const isNumeric = props.input.schema && "type" in props.input.schema && (props.input.schema.type === "integer" || props.input.schema.type === "number");
3660
+ const isBoolean = props.input.schema && "type" in props.input.schema && props.input.schema.type === "boolean";
3703
3661
  const enumValues = props.input.schema && "enum" in props.input.schema && Array.isArray(props.input.schema.enum) ? props.input.schema.enum : [];
3704
- const [data, setData] = useState([]);
3662
+ const { data: asyncData, loading, mode, search } = useAsyncLoader(props.loader, props.loaderThreshold ?? 100, props.loaderDebounce ?? 300, props.input.initialValue);
3663
+ const [staticData, setStaticData] = useState([]);
3664
+ const enumKey = JSON.stringify(enumValues);
3705
3665
  useEffect(() => {
3706
- if (!props.input?.props) return;
3707
- if (props.loader) props.loader().then(setData);
3708
- else setData(enumValues);
3709
- }, [props.input, props.loader]);
3666
+ if (!props.input?.props || props.loader) return;
3667
+ if (isBoolean && enumValues.length === 0) setStaticData([{
3668
+ value: "true",
3669
+ label: "True"
3670
+ }, {
3671
+ value: "false",
3672
+ label: "False"
3673
+ }]);
3674
+ else setStaticData(enumValues);
3675
+ }, [
3676
+ props.input,
3677
+ props.loader,
3678
+ enumKey,
3679
+ isBoolean
3680
+ ]);
3681
+ const data = props.loader ? asyncData : staticData;
3710
3682
  if (!props.input?.props) return null;
3711
- if (props.segmented) {
3712
- const segmentedControlProps = typeof props.segmented === "object" ? props.segmented : {};
3683
+ /**
3684
+ * Coerce value for numeric schemas Select values are always strings.
3685
+ */
3686
+ const coerceValue = (val) => {
3687
+ if (val == null) return val;
3688
+ if (isNumeric) return Number(val);
3689
+ if (isBoolean) return val === "true";
3690
+ return val;
3691
+ };
3692
+ if (props.segmentedProps) {
3693
+ const segmentedControlProps = typeof props.segmentedProps === "object" ? props.segmentedProps : {};
3694
+ const segmentedData = segmentedControlProps.data ?? data.slice(0, 10);
3713
3695
  return /* @__PURE__ */ jsx(Input.Wrapper, {
3714
3696
  ...inputProps,
3715
- children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(SegmentedControl, {
3716
- disabled: inputProps.disabled,
3717
- defaultValue: String(props.input.props.defaultValue),
3718
- ...segmentedControlProps,
3719
- onChange: (value) => {
3720
- props.input.set(value);
3721
- },
3722
- data: data.slice(0, 10)
3723
- }) })
3697
+ children: /* @__PURE__ */ jsx(Flex, {
3698
+ my: "calc(var(--mantine-spacing-xs) / 2)",
3699
+ children: /* @__PURE__ */ jsx(SegmentedControl, {
3700
+ disabled: inputProps.disabled,
3701
+ value: value != null ? String(value) : "",
3702
+ ...segmentedControlProps,
3703
+ onChange: (val) => {
3704
+ setValue(coerceValue(val));
3705
+ },
3706
+ data: segmentedData
3707
+ })
3708
+ })
3724
3709
  });
3725
3710
  }
3726
- if (props.autocomplete) {
3727
- const autocompleteProps = typeof props.autocomplete === "object" ? props.autocomplete : {};
3728
- return /* @__PURE__ */ jsx(Autocomplete, {
3711
+ const sharedProps = {
3712
+ size: props.size,
3713
+ id,
3714
+ leftSection: loading ? /* @__PURE__ */ jsx(Loader, {
3715
+ color: "gray",
3716
+ size: 10
3717
+ }) : icon,
3718
+ data
3719
+ };
3720
+ const selectableProps = {
3721
+ ...sharedProps,
3722
+ searchable: true,
3723
+ rightSection: /* @__PURE__ */ jsx("span", {})
3724
+ };
3725
+ const longModeProps = mode === "long" ? {
3726
+ filter: ({ options }) => options,
3727
+ onSearchChange: search.run
3728
+ } : {};
3729
+ if (props.creatable && (isArray || props.tagsInputProps)) {
3730
+ const tagsInputExtraProps = props.tagsInputProps ?? {};
3731
+ return /* @__PURE__ */ jsx(TagsInput, {
3729
3732
  ...inputProps,
3730
- size: props.size,
3731
- id,
3732
- leftSection: icon,
3733
- data,
3734
- ...props.input.props,
3735
- ...autocompleteProps
3733
+ ...sharedProps,
3734
+ ...longModeProps,
3735
+ value: Array.isArray(value) ? value : [],
3736
+ onChange: (val) => {
3737
+ setValue(val);
3738
+ },
3739
+ ...tagsInputExtraProps
3736
3740
  });
3737
3741
  }
3738
- if (isArray && !itemsEnum || props.tags) {
3739
- const tagsInputProps = typeof props.tags === "object" ? props.tags : {};
3740
- return /* @__PURE__ */ jsx(TagsInput, {
3742
+ if (props.creatable) {
3743
+ const autocompleteExtraProps = props.autocompleteProps ?? {};
3744
+ return /* @__PURE__ */ jsx(Autocomplete, {
3741
3745
  ...inputProps,
3742
- size: props.size,
3743
- id,
3744
- leftSection: icon,
3745
- defaultValue: Array.isArray(props.input.props.defaultValue) ? props.input.props.defaultValue : [],
3746
- onChange: (value) => {
3747
- props.input.set(value);
3746
+ ...sharedProps,
3747
+ ...longModeProps,
3748
+ value: value != null ? String(value) : "",
3749
+ onChange: (val) => {
3750
+ setValue(coerceValue(val));
3748
3751
  },
3749
- ...tagsInputProps
3752
+ ...autocompleteExtraProps
3750
3753
  });
3751
3754
  }
3752
- if (isArray && itemsEnum || props.multi) {
3753
- const data = itemsEnum?.map((value) => ({
3754
- value,
3755
- label: value
3756
- })) || [];
3757
- const multiSelectProps = typeof props.multi === "object" ? props.multi : {};
3755
+ if (isArray || props.multiSelectProps) {
3756
+ const multiSelectExtraProps = typeof props.multiSelectProps === "object" ? props.multiSelectProps : {};
3758
3757
  return /* @__PURE__ */ jsx(MultiSelect, {
3759
3758
  ...inputProps,
3760
- size: props.size,
3761
- id,
3762
- leftSection: icon,
3763
- data,
3764
- defaultValue: Array.isArray(props.input.props.defaultValue) ? props.input.props.defaultValue : [],
3765
- onChange: (value) => {
3766
- props.input.set(value);
3759
+ ...selectableProps,
3760
+ ...longModeProps,
3761
+ value: Array.isArray(value) ? value : [],
3762
+ onChange: (val) => {
3763
+ setValue(val);
3767
3764
  },
3768
- ...multiSelectProps
3765
+ ...multiSelectExtraProps
3769
3766
  });
3770
3767
  }
3771
- const selectProps = typeof props.select === "object" ? props.select : {};
3768
+ const selectExtraProps = typeof props.selectProps === "object" ? props.selectProps : {};
3769
+ if (mode === "static") return /* @__PURE__ */ jsx(Select, {
3770
+ ...inputProps,
3771
+ ...selectableProps,
3772
+ value: value != null ? String(value) : null,
3773
+ onChange: (val) => {
3774
+ setValue(coerceValue(val));
3775
+ },
3776
+ ...selectExtraProps
3777
+ });
3772
3778
  return /* @__PURE__ */ jsx(Select, {
3773
3779
  ...inputProps,
3774
- size: props.size,
3775
- id,
3776
- leftSection: icon,
3777
- rightSection: null,
3778
- data,
3779
- ...props.input.props,
3780
- ...selectProps
3780
+ ...selectableProps,
3781
+ ...longModeProps,
3782
+ value: value != null ? String(value) : null,
3783
+ onChange: (val) => {
3784
+ setValue(coerceValue(val));
3785
+ },
3786
+ ...selectExtraProps
3781
3787
  });
3782
3788
  };
3783
-
3789
+ /**
3790
+ * Hook for async select data loading with auto short/long mode detection.
3791
+ */
3792
+ const useAsyncLoader = (loader, threshold, debounceMs, defaultValue) => {
3793
+ const [data, setData] = useState([]);
3794
+ const [loading, setLoading] = useState(false);
3795
+ const [mode, setMode] = useState("static");
3796
+ const cache = useRef(/* @__PURE__ */ new Map());
3797
+ useAction({
3798
+ name: "select:loader:init",
3799
+ runOnInit: true,
3800
+ handler: async () => {
3801
+ if (!loader) {
3802
+ setMode("static");
3803
+ return;
3804
+ }
3805
+ setLoading(true);
3806
+ try {
3807
+ const result = await loader("");
3808
+ const isShort = result.length <= threshold;
3809
+ setMode(isShort ? "short" : "long");
3810
+ cache.current.set("", result);
3811
+ setData(result);
3812
+ if (!isShort && defaultValue != null && String(defaultValue) !== "") {
3813
+ const resolved = await loader("", [String(defaultValue)]);
3814
+ if (resolved.length > 0) setData((prev) => {
3815
+ const existing = new Set(prev.map((d) => typeof d === "string" ? d : d.value));
3816
+ const newItems = resolved.filter((r) => {
3817
+ const val = typeof r === "string" ? r : r.value;
3818
+ return !existing.has(val);
3819
+ });
3820
+ return [...prev, ...newItems];
3821
+ });
3822
+ }
3823
+ } finally {
3824
+ setLoading(false);
3825
+ }
3826
+ }
3827
+ }, [loader, threshold]);
3828
+ return {
3829
+ data,
3830
+ loading,
3831
+ mode,
3832
+ search: useAction({
3833
+ debounce: debounceMs,
3834
+ handler: async (text) => {
3835
+ if (!loader || mode !== "long") return;
3836
+ if (cache.current.has(text)) {
3837
+ setData(cache.current.get(text));
3838
+ return;
3839
+ }
3840
+ setLoading(true);
3841
+ try {
3842
+ const result = await loader(text);
3843
+ cache.current.set(text, result);
3844
+ setData(result);
3845
+ } finally {
3846
+ setLoading(false);
3847
+ }
3848
+ }
3849
+ }, [
3850
+ loader,
3851
+ mode,
3852
+ debounceMs
3853
+ ])
3854
+ };
3855
+ };
3784
3856
  //#endregion
3785
3857
  //#region ../../src/core/form/components/Control.tsx
3786
3858
  /**
@@ -3809,6 +3881,7 @@ const ControlSelect = (props) => {
3809
3881
  */
3810
3882
  const Control = (_props) => {
3811
3883
  const form = useFormState(_props.input, ["error"]);
3884
+ const [value, setValue] = useFieldValue(_props.input);
3812
3885
  if (!_props.input?.props) return null;
3813
3886
  const { inputProps, id, icon, format, schema } = parseInput(_props, form);
3814
3887
  const props = {
@@ -3816,12 +3889,11 @@ const Control = (_props) => {
3816
3889
  ...schema.$control
3817
3890
  };
3818
3891
  if (props.query) return /* @__PURE__ */ jsx(ControlQueryBuilder, {
3819
- ...props.input.props,
3820
3892
  ...inputProps,
3821
3893
  schema: props.query,
3822
- value: props.input.props.value,
3823
- onChange: (value) => {
3824
- props.input.set(value);
3894
+ value,
3895
+ onChange: (val) => {
3896
+ setValue(val);
3825
3897
  }
3826
3898
  });
3827
3899
  if (props.custom) {
@@ -3832,9 +3904,9 @@ const Control = (_props) => {
3832
3904
  flex: 1,
3833
3905
  mt: "calc(var(--mantine-spacing-xs) / 2)",
3834
3906
  children: /* @__PURE__ */ jsx(Custom, {
3835
- defaultValue: props.input.props.defaultValue,
3836
- onChange: (value) => {
3837
- props.input.set(value);
3907
+ value,
3908
+ onChange: (val) => {
3909
+ setValue(val);
3838
3910
  }
3839
3911
  })
3840
3912
  })
@@ -3845,7 +3917,7 @@ const Control = (_props) => {
3845
3917
  const controlObjectProps = typeof props.object === "object" ? props.object : {};
3846
3918
  return /* @__PURE__ */ jsx(ControlObject, {
3847
3919
  input: props.input,
3848
- title: props.title,
3920
+ label: props.label,
3849
3921
  description: props.description,
3850
3922
  ...controlObjectProps
3851
3923
  });
@@ -3856,18 +3928,18 @@ const Control = (_props) => {
3856
3928
  const controlArrayProps = typeof props.array === "object" ? props.array : {};
3857
3929
  return /* @__PURE__ */ jsx(ControlArray, {
3858
3930
  input: props.input,
3859
- title: props.title,
3931
+ label: props.label,
3860
3932
  description: props.description,
3861
3933
  ...controlArrayProps
3862
3934
  });
3863
3935
  }
3864
- if (props.number || props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
3936
+ if (props.number || !props.select && props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
3865
3937
  const controlNumberProps = typeof props.number === "object" ? props.number : {};
3866
3938
  if (props.slider) controlNumberProps.sliderProps ??= {};
3867
3939
  return /* @__PURE__ */ jsx(ControlNumber, {
3868
3940
  size: props.size,
3869
3941
  input: props.input,
3870
- title: props.title,
3942
+ label: props.label,
3871
3943
  description: props.description,
3872
3944
  icon,
3873
3945
  ...controlNumberProps
@@ -3880,9 +3952,7 @@ const Control = (_props) => {
3880
3952
  size: props.size,
3881
3953
  id,
3882
3954
  leftSection: icon,
3883
- onChange: (file) => {
3884
- props.input.set(file);
3885
- },
3955
+ onChange: (file) => setValue(file),
3886
3956
  ...fileInputProps
3887
3957
  });
3888
3958
  }
@@ -3893,17 +3963,18 @@ const Control = (_props) => {
3893
3963
  size: props.size,
3894
3964
  id,
3895
3965
  leftSection: icon,
3896
- ...props.input.props,
3966
+ value: value ?? "",
3967
+ onChange: (val) => setValue(val),
3897
3968
  ...colorInputProps
3898
3969
  });
3899
3970
  }
3900
3971
  if (props.input.schema && "enum" in props.input.schema && props.input.schema.enum || isArray && !isArrayOfObjects || props.select) {
3901
3972
  const opts = typeof props.select === "object" ? props.select : {};
3902
- if (props.segmented) opts.segmented ??= {};
3973
+ if (props.segmented) opts.segmentedProps ??= {};
3903
3974
  return /* @__PURE__ */ jsx(ControlSelect, {
3904
3975
  size: props.size,
3905
3976
  input: props.input,
3906
- title: props.title,
3977
+ label: props.label,
3907
3978
  description: props.description,
3908
3979
  icon,
3909
3980
  ...opts
@@ -3917,16 +3988,16 @@ const Control = (_props) => {
3917
3988
  size: props.size,
3918
3989
  id,
3919
3990
  color: "blue",
3920
- defaultChecked: props.input.props.defaultValue,
3991
+ checked: Boolean(value),
3921
3992
  onChange: (event) => {
3922
- props.input.set(event.currentTarget.checked);
3993
+ setValue(event.currentTarget.checked);
3923
3994
  },
3924
3995
  ...switchProps
3925
3996
  });
3926
3997
  }
3927
3998
  const opts = {
3928
3999
  input: props.input,
3929
- select: { data: [{
4000
+ selectProps: { data: [{
3930
4001
  value: "true",
3931
4002
  label: "Yes"
3932
4003
  }, {
@@ -3936,7 +4007,7 @@ const Control = (_props) => {
3936
4007
  };
3937
4008
  return /* @__PURE__ */ jsx(ControlSelect, {
3938
4009
  size: props.size,
3939
- title: props.title,
4010
+ label: props.label,
3940
4011
  description: props.description,
3941
4012
  icon,
3942
4013
  ...opts
@@ -3949,7 +4020,8 @@ const Control = (_props) => {
3949
4020
  size: props.size,
3950
4021
  id,
3951
4022
  leftSection: icon,
3952
- ...props.input.props,
4023
+ value: value ?? "",
4024
+ onChange: (ev) => setValue(ev.target.value),
3953
4025
  ...passwordInputProps
3954
4026
  });
3955
4027
  }
@@ -3960,14 +4032,15 @@ const Control = (_props) => {
3960
4032
  size: props.size,
3961
4033
  id,
3962
4034
  leftSection: icon,
3963
- ...props.input.props,
4035
+ value: value ?? "",
4036
+ onChange: (ev) => setValue(ev.target.value),
3964
4037
  ...textAreaProps
3965
4038
  });
3966
4039
  }
3967
4040
  if (props.date || props.datetime || props.time || format === "date" || format === "date-time" || format === "time") return /* @__PURE__ */ jsx(ControlDate, {
3968
4041
  size: props.size,
3969
4042
  input: props.input,
3970
- title: props.title,
4043
+ label: props.label,
3971
4044
  description: props.description,
3972
4045
  icon,
3973
4046
  date: props.date,
@@ -3982,7 +4055,7 @@ const Control = (_props) => {
3982
4055
  case "uri": return "url";
3983
4056
  case "tel":
3984
4057
  case "phone": return "tel";
3985
- default: return;
4058
+ default: return props.input.props.type ?? "text";
3986
4059
  }
3987
4060
  };
3988
4061
  return /* @__PURE__ */ jsx(TextInput, {
@@ -3991,17 +4064,11 @@ const Control = (_props) => {
3991
4064
  id,
3992
4065
  leftSection: icon,
3993
4066
  type: getInputType(),
3994
- ...props.input.props,
3995
- ...textInputProps,
3996
- inputWrapperOrder: [
3997
- "label",
3998
- "input",
3999
- "description",
4000
- "error"
4001
- ]
4067
+ value: value ?? "",
4068
+ onChange: (ev) => setValue(ev.target.value),
4069
+ ...textInputProps
4002
4070
  });
4003
4071
  };
4004
-
4005
4072
  //#endregion
4006
4073
  //#region ../../src/core/form/components/TypeForm.tsx
4007
4074
  /**
@@ -4047,6 +4114,7 @@ const Control = (_props) => {
4047
4114
  */
4048
4115
  const TypeForm = (props) => {
4049
4116
  const { form, columns = 3, children, controlProps, fieldControlProps, skipFormElement = false, skipSubmitButton = false, submitButtonProps, fill = true, size } = props;
4117
+ const { dirty } = useFormState(form, ["dirty"]);
4050
4118
  const schema = props.schema || form.options.schema;
4051
4119
  if (!schema?.properties) return null;
4052
4120
  const supportedFields = Object.keys(schema.properties);
@@ -4109,10 +4177,12 @@ const TypeForm = (props) => {
4109
4177
  children: [/* @__PURE__ */ jsx(ActionButton, {
4110
4178
  variant: "subtle",
4111
4179
  type: "reset",
4180
+ disabled: !dirty,
4112
4181
  children: "Reset"
4113
4182
  }), /* @__PURE__ */ jsx(ActionButton, {
4114
4183
  intent: "primary",
4115
4184
  form,
4185
+ disabled: !dirty,
4116
4186
  ...submitButtonProps,
4117
4187
  children: submitButtonProps?.children ?? "Submit"
4118
4188
  })]
@@ -4130,23 +4200,10 @@ const TypeForm = (props) => {
4130
4200
  children: content
4131
4201
  });
4132
4202
  };
4133
-
4134
- //#endregion
4135
- //#region ../../src/core/helpers/renderIcon.tsx
4136
- const renderIcon = (icon, size) => {
4137
- if (!icon) return null;
4138
- if (isValidElement(icon)) return icon;
4139
- if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui.sizes.icon.md });
4140
- return icon;
4141
- };
4142
-
4143
- //#endregion
4144
- //#region ../../src/core/table/interfaces/types.ts
4145
- const DEFAULT_MAX_VISIBLE_COLUMNS = 8;
4146
-
4147
4203
  //#endregion
4148
4204
  //#region ../../src/core/table/components/DataTableFilters.tsx
4149
- const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) => {
4205
+ const DataTableFilters = (props) => {
4206
+ const { schema, form, typeFormProps, filterVisibility } = props;
4150
4207
  const visibleSchema = useMemo(() => {
4151
4208
  const visibleKeys = Object.keys(schema.properties).filter((key) => filterVisibility[key] !== false);
4152
4209
  if (visibleKeys.length === 0) return null;
@@ -4157,14 +4214,14 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
4157
4214
  return t.object(visibleProps);
4158
4215
  }, [schema, filterVisibility]);
4159
4216
  if (!visibleSchema) return null;
4160
- return /* @__PURE__ */ jsx(Flex, {
4161
- w: "100%",
4217
+ return /* @__PURE__ */ jsx(Flex$1, {
4218
+ surface: true,
4219
+ flex: 1,
4220
+ mt: -4,
4162
4221
  p: "xs",
4163
4222
  m: "xs",
4164
4223
  bdrs: "md",
4165
- bg: ui.colors.surface,
4166
4224
  children: /* @__PURE__ */ jsx(TypeForm, {
4167
- size: "xs",
4168
4225
  ...typeFormProps,
4169
4226
  skipSubmitButton: true,
4170
4227
  fill: true,
@@ -4175,17 +4232,17 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
4175
4232
  sm: 2,
4176
4233
  md: 3,
4177
4234
  lg: 4,
4178
- xl: 6
4235
+ xl: 5
4179
4236
  }
4180
4237
  })
4181
4238
  });
4182
4239
  };
4183
-
4184
4240
  //#endregion
4185
4241
  //#region ../../src/core/table/components/DataTablePagination.tsx
4186
- const DataTablePagination = ({ page, size, totalPages, totalElements, offset, numberOfElements, onPageChange, onSizeChange }) => {
4242
+ const DataTablePagination = ({ page, size, totalPages, totalElements, isFirst, isLast, offset, numberOfElements, onPageChange, onSizeChange }) => {
4187
4243
  const from = numberOfElements > 0 ? offset + 1 : 0;
4188
4244
  const to = offset + numberOfElements;
4245
+ const hasTotal = totalPages != null;
4189
4246
  return /* @__PURE__ */ jsxs(Flex$1, {
4190
4247
  align: "center",
4191
4248
  justify: "space-between",
@@ -4233,15 +4290,15 @@ const DataTablePagination = ({ page, size, totalPages, totalElements, offset, nu
4233
4290
  ]
4234
4291
  }) }), /* @__PURE__ */ jsx(Flex$1, { children: /* @__PURE__ */ jsx(Pagination, {
4235
4292
  size: "sm",
4236
- withEdges: true,
4237
- total: totalPages,
4293
+ withEdges: hasTotal,
4294
+ withPages: hasTotal,
4295
+ total: hasTotal ? totalPages : isLast !== false ? page : page + 1,
4238
4296
  value: page,
4239
4297
  onChange: onPageChange
4240
4298
  }) })]
4241
4299
  })]
4242
4300
  });
4243
4301
  };
4244
-
4245
4302
  //#endregion
4246
4303
  //#region ../../src/core/table/components/ColumnPicker.tsx
4247
4304
  const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
@@ -4257,7 +4314,7 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
4257
4314
  let count = 0;
4258
4315
  onVisibilityChange(columnEntries.reduce((acc, [key, col]) => {
4259
4316
  if (col.defaultHidden) acc[key] = false;
4260
- else if (count < DEFAULT_MAX_VISIBLE_COLUMNS) {
4317
+ else if (count < 8) {
4261
4318
  acc[key] = true;
4262
4319
  count++;
4263
4320
  } else acc[key] = false;
@@ -4285,7 +4342,7 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
4285
4342
  timingFunction: "ease"
4286
4343
  },
4287
4344
  children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
4288
- variant: "subtle",
4345
+ variant: "minimal",
4289
4346
  icon: IconColumns,
4290
4347
  onClick: () => setOpened((o) => !o)
4291
4348
  }) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
@@ -4315,12 +4372,12 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
4315
4372
  gap: 4,
4316
4373
  children: [/* @__PURE__ */ jsx(ActionButton, {
4317
4374
  size: "compact-xs",
4318
- variant: "subtle",
4375
+ variant: "minimal",
4319
4376
  onClick: handleShowAll,
4320
4377
  children: "All"
4321
4378
  }), /* @__PURE__ */ jsx(ActionButton, {
4322
4379
  size: "compact-xs",
4323
- variant: "subtle",
4380
+ variant: "minimal",
4324
4381
  onClick: handleDefault,
4325
4382
  children: "Default"
4326
4383
  })]
@@ -4342,7 +4399,6 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
4342
4399
  })]
4343
4400
  });
4344
4401
  };
4345
-
4346
4402
  //#endregion
4347
4403
  //#region ../../src/core/table/components/FilterPicker.tsx
4348
4404
  const getFieldLabel = (schema, key) => {
@@ -4386,7 +4442,7 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
4386
4442
  timingFunction: "ease"
4387
4443
  },
4388
4444
  children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
4389
- variant: "subtle",
4445
+ variant: "minimal",
4390
4446
  icon: IconFilter,
4391
4447
  onClick: () => setOpened((o) => !o)
4392
4448
  }) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
@@ -4416,12 +4472,12 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
4416
4472
  gap: 4,
4417
4473
  children: [/* @__PURE__ */ jsx(ActionButton, {
4418
4474
  size: "compact-xs",
4419
- variant: "subtle",
4475
+ variant: "minimal",
4420
4476
  onClick: handleShowAll,
4421
4477
  children: "All"
4422
4478
  }), /* @__PURE__ */ jsx(ActionButton, {
4423
4479
  size: "compact-xs",
4424
- variant: "subtle",
4480
+ variant: "minimal",
4425
4481
  onClick: handleHideAll,
4426
4482
  children: "None"
4427
4483
  })]
@@ -4443,7 +4499,6 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
4443
4499
  })]
4444
4500
  });
4445
4501
  };
4446
-
4447
4502
  //#endregion
4448
4503
  //#region ../../src/core/table/components/DataTableToolbar.tsx
4449
4504
  const escapeCsvField = (value) => {
@@ -4515,7 +4570,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
4515
4570
  onVisibilityChange: onColumnVisibilityChange
4516
4571
  }),
4517
4572
  withExport && /* @__PURE__ */ jsx(ActionButton, {
4518
- variant: "subtle",
4573
+ variant: "minimal",
4519
4574
  icon: IconDownload,
4520
4575
  menu: { items: [{
4521
4576
  label: "Export as CSV",
@@ -4538,7 +4593,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
4538
4593
  children: [selectedItems.length, " selected"]
4539
4594
  }),
4540
4595
  /* @__PURE__ */ jsx(ActionButton, {
4541
- variant: "subtle",
4596
+ variant: "minimal",
4542
4597
  size: "compact-sm",
4543
4598
  icon: IconX,
4544
4599
  onClick: onClearSelection,
@@ -4562,7 +4617,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
4562
4617
  ...props,
4563
4618
  children: props.label
4564
4619
  }, index) : props), /* @__PURE__ */ jsx(ActionButton, {
4565
- variant: "subtle",
4620
+ variant: "minimal",
4566
4621
  icon: IconRefresh,
4567
4622
  onClick: onRefresh
4568
4623
  })]
@@ -4570,7 +4625,6 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
4570
4625
  ]
4571
4626
  });
4572
4627
  };
4573
-
4574
4628
  //#endregion
4575
4629
  //#region ../../src/core/table/components/useTableSelection.ts
4576
4630
  const useTableSelection = (items, getItemKey, enabled) => {
@@ -4633,7 +4687,6 @@ const useTableSelection = (items, getItemKey, enabled) => {
4633
4687
  isSelected: useCallback((item) => selectedKeys.has(getItemKey(item)), [selectedKeys, getItemKey])
4634
4688
  };
4635
4689
  };
4636
-
4637
4690
  //#endregion
4638
4691
  //#region ../../src/core/table/components/DataTable.tsx
4639
4692
  /**
@@ -4671,18 +4724,22 @@ const FIT_STYLE = {
4671
4724
  };
4672
4725
  const DataTable = (props) => {
4673
4726
  const [items, setItems] = useState(typeof props.items === "function" ? { content: [] } : props.items);
4674
- const defaultSize = props.infinityScroll ? 100 : props.defaultSize || 10;
4727
+ const itemsRef = useRef(items);
4728
+ const [loaded, setLoaded] = useState(typeof props.items !== "function" || !props.submitOnInit);
4729
+ const defaultSize = props.defaultSize || (props.infinityScroll ? 100 : 10);
4675
4730
  const [page, setPage] = useState(1);
4676
4731
  const [size, setSize] = useState(String(defaultSize));
4677
4732
  const [currentPage, setCurrentPage] = useState(0);
4678
4733
  const alepha = useInject(Alepha);
4734
+ itemsRef.current = items;
4679
4735
  const sentinelRef = useRef(null);
4736
+ const debounceRef = useRef(null);
4680
4737
  const [columnVisibility, setColumnVisibility] = useState(() => {
4681
4738
  const entries = Object.entries(props.columns);
4682
4739
  let visibleCount = 0;
4683
4740
  return entries.reduce((acc, [key, col]) => {
4684
4741
  if (col.defaultHidden) acc[key] = false;
4685
- else if (visibleCount < DEFAULT_MAX_VISIBLE_COLUMNS) {
4742
+ else if (visibleCount < 8) {
4686
4743
  acc[key] = true;
4687
4744
  visibleCount++;
4688
4745
  } else acc[key] = false;
@@ -4749,13 +4806,14 @@ const DataTable = (props) => {
4749
4806
  }),
4750
4807
  handler: async (values) => {
4751
4808
  if (typeof props.items === "function") {
4752
- const response = await props.items(values, { items: items.content });
4809
+ const response = await props.items(values, { items: itemsRef.current.content });
4753
4810
  if (props.infinityScroll && values.page > 0) setItems((prev) => ({
4754
4811
  ...response,
4755
4812
  content: [...prev.content, ...response.content]
4756
4813
  }));
4757
4814
  else setItems(response);
4758
4815
  setCurrentPage(values.page);
4816
+ if (!loaded) setLoaded(true);
4759
4817
  }
4760
4818
  },
4761
4819
  onReset: async () => {
@@ -4775,9 +4833,23 @@ const DataTable = (props) => {
4775
4833
  return;
4776
4834
  }
4777
4835
  props.onFilterChange?.(key, value, form);
4836
+ if (props.skipSubmitOnChange) return;
4837
+ form.input.page.set(0);
4838
+ const delay = props.debounce ?? 300;
4839
+ if (delay > 0) {
4840
+ if (debounceRef.current) clearTimeout(debounceRef.current);
4841
+ debounceRef.current = setTimeout(() => {
4842
+ form.submit();
4843
+ }, delay);
4844
+ } else await form.submit();
4778
4845
  }
4779
- }, [items]);
4846
+ }, []);
4780
4847
  const dt = useInject(DateTimeProvider);
4848
+ useEffect(() => {
4849
+ return () => {
4850
+ if (debounceRef.current) clearTimeout(debounceRef.current);
4851
+ };
4852
+ }, []);
4781
4853
  useEffect(() => {
4782
4854
  if (props.submitOnInit) form.submit();
4783
4855
  if (props.submitEvery) {
@@ -4842,9 +4914,9 @@ const DataTable = (props) => {
4842
4914
  }), col.sortable && /* @__PURE__ */ jsxs(Flex$1, {
4843
4915
  c: "dimmed",
4844
4916
  children: [
4845
- sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.sm }),
4846
- sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.sm }),
4847
- sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.sm })
4917
+ sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.xs }),
4918
+ sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.xs }),
4919
+ sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.xs })
4848
4920
  ]
4849
4921
  })]
4850
4922
  })
@@ -4904,9 +4976,15 @@ const DataTable = (props) => {
4904
4976
  form,
4905
4977
  alepha
4906
4978
  };
4979
+ const content = col.value?.(item, ctx);
4907
4980
  return /* @__PURE__ */ jsx(Table.Td, {
4908
4981
  style: col.fit ? FIT_STYLE : void 0,
4909
- children: col.value?.(item, ctx)
4982
+ children: col.action ? /* @__PURE__ */ jsx(ActionButton, {
4983
+ td: "inherit",
4984
+ unstyled: true,
4985
+ ...col.action(item),
4986
+ children: content
4987
+ }) : content
4910
4988
  }, key);
4911
4989
  }),
4912
4990
  props.rowActions && (() => {
@@ -4923,7 +5001,7 @@ const DataTable = (props) => {
4923
5001
  style: FIT_STYLE,
4924
5002
  onClick: (e) => e.stopPropagation(),
4925
5003
  children: /* @__PURE__ */ jsx(ActionButton, {
4926
- variant: "subtle",
5004
+ variant: "minimal",
4927
5005
  size: "xs",
4928
5006
  icon: IconDotsVertical,
4929
5007
  menu: { items: actions.map((action) => {
@@ -4931,7 +5009,10 @@ const DataTable = (props) => {
4931
5009
  return {
4932
5010
  label: action.label ?? (typeof action.tooltip === "string" ? action.tooltip : void 0),
4933
5011
  icon: Icon && isComponentType(Icon) ? /* @__PURE__ */ jsx(Icon, { size: 14 }) : Icon,
4934
- onClick: action.onClick,
5012
+ onClick: action.onClick ? async () => {
5013
+ await action.onClick();
5014
+ if (!action.skipRefresh) await form.submit();
5015
+ } : void 0,
4935
5016
  color: action.color
4936
5017
  };
4937
5018
  }) }
@@ -4993,15 +5074,21 @@ const DataTable = (props) => {
4993
5074
  bordered: true,
4994
5075
  elevated: true,
4995
5076
  shadowed: "xs",
5077
+ flex: 1,
5078
+ style: { minHeight: 0 },
4996
5079
  children: [
4997
5080
  /* @__PURE__ */ jsx(Flex$1, {
4998
5081
  className: "overflow-auto",
5082
+ flex: 1,
5083
+ style: { minHeight: 0 },
5084
+ col: true,
4999
5085
  children: /* @__PURE__ */ jsxs(Table, {
5000
5086
  "aria-label": "Data table",
5001
5087
  withRowBorders: true,
5002
5088
  highlightOnHover: true,
5003
5089
  ...props.tableProps,
5004
5090
  children: [/* @__PURE__ */ jsx(Table.Thead, {
5091
+ bdrs: "md",
5005
5092
  style: {
5006
5093
  position: "sticky",
5007
5094
  top: 0,
@@ -5013,30 +5100,39 @@ const DataTable = (props) => {
5013
5100
  head,
5014
5101
  props.rowActions && /* @__PURE__ */ jsx(Table.Th, { style: FIT_STYLE })
5015
5102
  ] })
5016
- }), /* @__PURE__ */ jsxs(Table.Tbody, {
5017
- style: {
5018
- opacity: form.submitting ? .5 : 1,
5019
- transition: "opacity 150ms ease"
5020
- },
5021
- children: [rows, items.content.length === 0 && /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
5022
- colSpan: totalColumns || 1,
5023
- py: "xl",
5024
- style: { textAlign: "center" },
5103
+ }), /* @__PURE__ */ jsx(Table.Tbody, { children: !loaded || form.submitting ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
5104
+ colSpan: totalColumns || 1,
5105
+ py: "sm",
5106
+ children: /* @__PURE__ */ jsx(Flex$1, {
5107
+ justify: "center",
5108
+ p: "md",
5109
+ children: /* @__PURE__ */ jsx(Loader, {
5110
+ size: "sm",
5111
+ type: "dots"
5112
+ })
5113
+ })
5114
+ }) }) : rows.length === 0 ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
5115
+ colSpan: totalColumns || 1,
5116
+ py: "xl",
5117
+ children: /* @__PURE__ */ jsx(Flex$1, {
5118
+ justify: "center",
5025
5119
  children: /* @__PURE__ */ jsx(Text$1, {
5026
5120
  c: "dimmed",
5027
5121
  size: "sm",
5028
- children: form.submitting ? "Loading…" : "No results"
5122
+ children: props.emptyLabel ?? "No results"
5029
5123
  })
5030
- }) })]
5031
- })]
5124
+ })
5125
+ }) }) : rows })]
5032
5126
  })
5033
5127
  }),
5034
5128
  props.infinityScroll && /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
5035
5129
  !props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
5036
5130
  page,
5037
5131
  size,
5038
- totalPages: items.page?.totalPages ?? 1,
5132
+ totalPages: items.page?.totalPages,
5039
5133
  totalElements: items.page?.totalElements,
5134
+ isFirst: items.page?.isFirst,
5135
+ isLast: items.page?.isLast,
5040
5136
  offset: items.page?.offset ?? 0,
5041
5137
  numberOfElements: items.content.length,
5042
5138
  onPageChange: (value) => {
@@ -5058,7 +5154,6 @@ const DataTable = (props) => {
5058
5154
  })]
5059
5155
  });
5060
5156
  };
5061
-
5062
5157
  //#endregion
5063
5158
  //#region ../../src/core/utils/extractSchemaFields.ts
5064
5159
  /**
@@ -5147,15 +5242,14 @@ const OPERATOR_INFO = {
5147
5242
  example: "status=[active,pending]"
5148
5243
  }
5149
5244
  };
5150
-
5151
5245
  //#endregion
5152
5246
  //#region ../../src/core/utils/icons.tsx
5153
5247
  /**
5154
5248
  * Get the default icon for an input based on its type, format, or name.
5155
5249
  */
5156
5250
  const getDefaultIcon = (params) => {
5157
- const { type, format, name, isEnum, isArray, size = "sm" } = params;
5158
- const iconSize = ui.sizes.icon[size];
5251
+ const { type, format, name, isEnum, isArray, size = "xs" } = params;
5252
+ const iconSize = ui.sizes.icon[size] - 4;
5159
5253
  if (format) switch (format) {
5160
5254
  case "email": return /* @__PURE__ */ jsx(IconMail, { size: iconSize });
5161
5255
  case "url":
@@ -5189,7 +5283,6 @@ const getDefaultIcon = (params) => {
5189
5283
  }
5190
5284
  return /* @__PURE__ */ jsx(IconAt, { size: iconSize });
5191
5285
  };
5192
-
5193
5286
  //#endregion
5194
5287
  //#region ../../src/core/utils/string.ts
5195
5288
  /**
@@ -5227,7 +5320,6 @@ const prettyName = (name) => {
5227
5320
  const segments = name.split("/").filter((s) => s && !/^\d+$/.test(s));
5228
5321
  return toTitleCase(segments[segments.length - 1] || name.replaceAll("/", ""));
5229
5322
  };
5230
-
5231
5323
  //#endregion
5232
5324
  //#region ../../src/core/index.ts
5233
5325
  /**
@@ -5266,7 +5358,7 @@ const AlephaUI = $module({
5266
5358
  alepha.with(ToastService);
5267
5359
  }
5268
5360
  });
5269
-
5270
5361
  //#endregion
5271
- export { ActionButton as _, Control as a, useToast as b, Breadcrumb as c, DetailList as d, ToggleSidebarButton as f, ClipboardButton as g, LanguageButton as h, TypeForm as i, Flex$1 as l, useDialog as m, capitalize as n, Text$1 as o, ThemeButton as p, DataTable as r, DashboardShell as s, AlephaUI as t, StatCards as u, ui as v, alephaSidebarAtom as x, AlephaMantineProvider as y };
5272
- //# sourceMappingURL=core-BVO_TQxb.js.map
5362
+ export { ActionButton as _, Control as a, useToast as b, Breadcrumbs as c, DetailList as d, ToggleSidebarButton as f, ClipboardButton as g, LanguageButton as h, TypeForm as i, Flex$1 as l, useDialog as m, capitalize as n, DashboardShell as o, ThemeButton as p, DataTable as r, Text$1 as s, AlephaUI as t, StatCards as u, ui as v, alephaSidebarAtom as x, AlephaMantineProvider as y };
5363
+
5364
+ //# sourceMappingURL=core-D1AbU50V.js.map