@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,15 +1,15 @@
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, useFormState } from "alepha/react/form";
3
3
  import { $head, AlephaReactHead, BrowserHeadProvider } from "alepha/react/head";
4
- import { AlephaReactI18n, useI18n } from "alepha/react/i18n";
4
+ import { AlephaReactI18n } from "alepha/react/i18n";
5
5
  import { $cookie } from "alepha/server/cookies";
6
- import { ActionIcon, Anchor, Autocomplete, Badge, Button, Card, ColorInput, ColorSchemeScript, Container, Divider, Fieldset, FileInput, Flex, Grid, Image, Input, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Paper, PasswordInput, Popover, SegmentedControl, Select, Slider, Switch, TagsInput, Text, TextInput, Textarea, Tooltip, UnstyledButton, useMantineTheme } from "@mantine/core";
6
+ import { ActionIcon, Anchor, Autocomplete, Badge, Button, Card, ColorInput, ColorSchemeScript, Container, Divider, Fieldset, FileInput, Flex, Grid, Input, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Paper, PasswordInput, Popover, SegmentedControl, Select, Slider, Switch, TagsInput, Text, TextInput, Textarea, Tooltip, UnstyledButton, 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, createElement, forwardRef, isValidElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
10
10
  import { Notifications, notifications } from "@mantine/notifications";
11
11
  import { IconAlertTriangle, IconAt, IconCalendar, IconCheck, IconChevronRight, IconClock, IconColorPicker, IconFile, IconFilter, IconGripVertical, IconHash, IconInfoCircle, IconInfoTriangle, IconKey, IconLetterCase, IconLink, IconList, IconMail, IconPalette, IconPhone, IconPlus, IconSearch, IconSelector, IconToggleLeft, IconTrash, IconX } from "@tabler/icons-react";
12
- import { $page, NestedView, useActive, useRouter, useRouterState } from "alepha/react/router";
12
+ import { $page, NestedView, useActive, useRouter } from "alepha/react/router";
13
13
  import { NavigationProgress, nprogress } from "@mantine/nprogress";
14
14
  import { useAction, useAlepha, useEvents, useInject, useStore } from "alepha/react";
15
15
  import { Spotlight } from "@mantine/spotlight";
@@ -18,9 +18,7 @@ import "@mantine/hooks";
18
18
  import { DateInput, DateTimePicker, TimeInput } from "@mantine/dates";
19
19
  import { parseQueryString } from "alepha/orm";
20
20
  import "alepha/datetime";
21
-
22
- //#region ../../src/core/atoms/alephaSidebarAtom.ts
23
- const alephaSidebarAtom = $atom({
21
+ $atom({
24
22
  name: "alepha.ui.sidebar",
25
23
  schema: t.object({
26
24
  closed: t.boolean(),
@@ -35,7 +33,6 @@ const alephaSidebarAtom = $atom({
35
33
  collapsedWidth: 72
36
34
  }
37
35
  });
38
-
39
36
  //#endregion
40
37
  //#region ../../src/core/atoms/alephaThemeAtom.ts
41
38
  const alephaThemeAtom = $atom({
@@ -43,7 +40,6 @@ const alephaThemeAtom = $atom({
43
40
  schema: t.object({ index: t.integer() }),
44
41
  default: { index: 0 }
45
42
  });
46
-
47
43
  //#endregion
48
44
  //#region ../../src/core/atoms/alephaThemeOverridesAtom.ts
49
45
  const alephaThemeOverridesAtom = $atom({
@@ -57,14 +53,12 @@ const alephaThemeOverridesAtom = $atom({
57
53
  }),
58
54
  default: {}
59
55
  });
60
-
61
56
  //#endregion
62
57
  //#region ../../src/core/atoms/themes/default.ts
63
58
  const defaultTheme = {
64
59
  name: "Default",
65
60
  description: "Default Alepha Theme"
66
61
  };
67
-
68
62
  //#endregion
69
63
  //#region ../../src/core/atoms/themes/editorial.ts
70
64
  /**
@@ -219,7 +213,6 @@ const editorialTheme = {
219
213
  })
220
214
  }
221
215
  };
222
-
223
216
  //#endregion
224
217
  //#region ../../src/core/atoms/themes/midnight.ts
225
218
  const midnightTheme = {
@@ -334,7 +327,6 @@ const midnightTheme = {
334
327
  ]
335
328
  }
336
329
  };
337
-
338
330
  //#endregion
339
331
  //#region ../../src/core/atoms/themes/monochrome.ts
340
332
  /**
@@ -502,7 +494,6 @@ const monochromeTheme = {
502
494
  })
503
495
  }
504
496
  };
505
-
506
497
  //#endregion
507
498
  //#region ../../src/core/atoms/themes/rosePine.ts
508
499
  /**
@@ -674,7 +665,6 @@ const rosePineTheme = {
674
665
  Badge: Badge.extend({ defaultProps: { fw: 500 } })
675
666
  }
676
667
  };
677
-
678
668
  //#endregion
679
669
  //#region ../../src/core/atoms/themes/softBrutalism.ts
680
670
  /**
@@ -861,7 +851,6 @@ const softBrutalismTheme = {
861
851
  })
862
852
  }
863
853
  };
864
-
865
854
  //#endregion
866
855
  //#region ../../src/core/atoms/themes/terminal.ts
867
856
  /**
@@ -1017,7 +1006,6 @@ const terminalTheme = {
1017
1006
  })
1018
1007
  }
1019
1008
  };
1020
-
1021
1009
  //#endregion
1022
1010
  //#region ../../src/core/atoms/alephaThemeListAtom.ts
1023
1011
  const alephaThemeListAtom = $atom({
@@ -1033,7 +1021,6 @@ const alephaThemeListAtom = $atom({
1033
1021
  monochromeTheme
1034
1022
  ]
1035
1023
  });
1036
-
1037
1024
  //#endregion
1038
1025
  //#region ../../src/core/providers/ThemeProvider.ts
1039
1026
  var ThemeProvider = class ThemeProvider {
@@ -1131,7 +1118,6 @@ var ThemeProvider = class ThemeProvider {
1131
1118
  }
1132
1119
  }
1133
1120
  };
1134
-
1135
1121
  //#endregion
1136
1122
  //#region ../../src/core/components/dialogs/AlertDialog.tsx
1137
1123
  const AlertDialog = ({ options, onClose }) => /* @__PURE__ */ jsxs(Fragment, { children: [options?.message && /* @__PURE__ */ jsx(Text, {
@@ -1144,7 +1130,6 @@ const AlertDialog = ({ options, onClose }) => /* @__PURE__ */ jsxs(Fragment, { c
1144
1130
  children: options?.okLabel || "OK"
1145
1131
  })
1146
1132
  })] });
1147
-
1148
1133
  //#endregion
1149
1134
  //#region ../../src/core/components/dialogs/ConfirmDialog.tsx
1150
1135
  const ConfirmDialog = ({ options, onConfirm }) => /* @__PURE__ */ jsxs(Fragment, { children: [options?.message && /* @__PURE__ */ jsx(Text, {
@@ -1162,7 +1147,6 @@ const ConfirmDialog = ({ options, onConfirm }) => /* @__PURE__ */ jsxs(Fragment,
1162
1147
  children: options?.confirmLabel || "Confirm"
1163
1148
  })]
1164
1149
  })] });
1165
-
1166
1150
  //#endregion
1167
1151
  //#region ../../src/core/components/dialogs/PromptDialog.tsx
1168
1152
  const PromptDialog = ({ options, onSubmit }) => {
@@ -1194,6 +1178,7 @@ const PromptDialog = ({ options, onSubmit }) => {
1194
1178
  }),
1195
1179
  /* @__PURE__ */ jsxs(Flex, {
1196
1180
  justify: "flex-end",
1181
+ gap: "xs",
1197
1182
  children: [/* @__PURE__ */ jsx(Button, {
1198
1183
  variant: "subtle",
1199
1184
  onClick: () => onSubmit(null),
@@ -1206,7 +1191,6 @@ const PromptDialog = ({ options, onSubmit }) => {
1206
1191
  })
1207
1192
  ] });
1208
1193
  };
1209
-
1210
1194
  //#endregion
1211
1195
  //#region ../../src/core/services/DialogService.tsx
1212
1196
  var DialogService = class {
@@ -1268,8 +1252,8 @@ var DialogService = class {
1268
1252
  content: /* @__PURE__ */ jsx(ConfirmDialog, {
1269
1253
  options,
1270
1254
  onConfirm: (confirmed) => {
1271
- this.close(modalId);
1272
1255
  done(confirmed);
1256
+ this.close(modalId);
1273
1257
  }
1274
1258
  })
1275
1259
  });
@@ -1295,8 +1279,8 @@ var DialogService = class {
1295
1279
  content: /* @__PURE__ */ jsx(PromptDialog, {
1296
1280
  options,
1297
1281
  onSubmit: (value) => {
1298
- this.close(modalId);
1299
1282
  done(value);
1283
+ this.close(modalId);
1300
1284
  }
1301
1285
  })
1302
1286
  });
@@ -1320,7 +1304,6 @@ var DialogService = class {
1320
1304
  else modals.closeAll();
1321
1305
  }
1322
1306
  };
1323
-
1324
1307
  //#endregion
1325
1308
  //#region ../../src/core/services/ToastService.tsx
1326
1309
  var ToastService = class {
@@ -1379,7 +1362,6 @@ var ToastService = class {
1379
1362
  });
1380
1363
  }
1381
1364
  };
1382
-
1383
1365
  //#endregion
1384
1366
  //#region ../../src/core/UiRouter.ts
1385
1367
  /**
@@ -1394,7 +1376,6 @@ var UiRouter = class {
1394
1376
  component: AlephaMantineProvider
1395
1377
  });
1396
1378
  };
1397
-
1398
1379
  //#endregion
1399
1380
  //#region ../../src/core/hooks/useTheme.ts
1400
1381
  /**
@@ -1429,7 +1410,6 @@ const useTheme = () => {
1429
1410
  }
1430
1411
  ];
1431
1412
  };
1432
-
1433
1413
  //#endregion
1434
1414
  //#region ../../src/core/hooks/useToast.ts
1435
1415
  /**
@@ -1445,7 +1425,6 @@ const useTheme = () => {
1445
1425
  const useToast = () => {
1446
1426
  return useInject(ToastService);
1447
1427
  };
1448
-
1449
1428
  //#endregion
1450
1429
  //#region ../../src/core/components/layout/Omnibar.tsx
1451
1430
  const Omnibar = (props) => {
@@ -1477,7 +1456,6 @@ const Omnibar = (props) => {
1477
1456
  nothingFound
1478
1457
  });
1479
1458
  };
1480
-
1481
1459
  //#endregion
1482
1460
  //#region ../../src/core/components/AlephaMantineProvider.tsx
1483
1461
  const AlephaMantineProvider = (props) => {
@@ -1519,7 +1497,6 @@ const AlephaMantineProvider = (props) => {
1519
1497
  ]
1520
1498
  })] });
1521
1499
  };
1522
-
1523
1500
  //#endregion
1524
1501
  //#region ../../src/core/constants/ui.ts
1525
1502
  const ui = {
@@ -1538,51 +1515,18 @@ const ui = {
1538
1515
  xl: 32
1539
1516
  } }
1540
1517
  };
1541
-
1542
1518
  //#endregion
1543
1519
  //#region ../../src/core/helpers/isComponentType.ts
1544
1520
  function isComponentType(param) {
1545
1521
  if (isValidElement(param)) return false;
1546
1522
  return typeof param === "function" || typeof param === "object" && param !== null && "$$typeof" in param;
1547
1523
  }
1548
-
1549
1524
  //#endregion
1550
1525
  //#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
1526
  const ActionButton = (_props) => {
1584
1527
  const theme = useMantineTheme();
1585
1528
  const props = { ..._props };
1529
+ if (props.variant === "minimal") {}
1586
1530
  const { tooltip, menu, icon, iconSize, ...restProps } = props;
1587
1531
  if (props.intent) {
1588
1532
  if (props.intent === "primary") restProps.color ??= theme.primaryColor;
@@ -1627,6 +1571,7 @@ const ActionButton = (_props) => {
1627
1571
  children: /* @__PURE__ */ jsx(ActionButton, {
1628
1572
  px: "xs",
1629
1573
  ...rest,
1574
+ "aria-label": typeof children === "string" ? children : void 0,
1630
1575
  tooltip,
1631
1576
  menu,
1632
1577
  children: leftSection
@@ -1783,7 +1728,7 @@ const ActionClickButton = ({ preventDefault, ...props }) => {
1783
1728
  * Action for navigation with active state support.
1784
1729
  */
1785
1730
  const ActionNavigationButton = (props) => {
1786
- const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchor, ...buttonProps } = props;
1731
+ const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchorProps: buttonAnchorProps, anchor, ...buttonProps } = props;
1787
1732
  const router = useRouter();
1788
1733
  const { isPending, isActive } = useActive(options ? {
1789
1734
  href: props.href,
@@ -1797,11 +1742,11 @@ const ActionNavigationButton = (props) => {
1797
1742
  };
1798
1743
  const className = buttonProps.className || "";
1799
1744
  if (isActive && options !== false && classNameActive) buttonProps.className = `${className} ${classNameActive}`.trim();
1800
- if (props.anchorProps || anchor) return /* @__PURE__ */ jsx(Anchor, {
1745
+ if (buttonAnchorProps || anchor) return /* @__PURE__ */ jsx(Anchor, {
1801
1746
  component: "a",
1802
1747
  ...anchorProps,
1803
1748
  ...buttonProps,
1804
- ...props.anchorProps,
1749
+ ...buttonAnchorProps,
1805
1750
  onClick: combinedOnClick,
1806
1751
  children: props.children
1807
1752
  });
@@ -1824,11 +1769,42 @@ const ActionHrefButton = (props) => {
1824
1769
  children: props.children
1825
1770
  });
1826
1771
  };
1827
-
1772
+ const ActionMenuItem = (props) => {
1773
+ const { item, index } = props;
1774
+ const router = useRouter();
1775
+ const action = useAction({ handler: async (e) => {
1776
+ await item.onClick?.();
1777
+ } }, [item.onClick]);
1778
+ if (item.type === "divider") return /* @__PURE__ */ jsx(Menu.Divider, {}, index);
1779
+ if (item.type === "label") return /* @__PURE__ */ jsx(Menu.Label, { children: item.label }, index);
1780
+ if (item.children && item.children.length > 0) return /* @__PURE__ */ jsxs(Menu, {
1781
+ trigger: "hover",
1782
+ position: "right-start",
1783
+ offset: 2,
1784
+ children: [/* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Menu.Item, {
1785
+ leftSection: item.icon,
1786
+ rightSection: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }),
1787
+ children: item.label
1788
+ }) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: item.children.map((child, childIndex) => /* @__PURE__ */ jsx(ActionMenuItem, {
1789
+ item: child,
1790
+ index: childIndex
1791
+ }, childIndex)) })]
1792
+ }, index);
1793
+ const menuItemProps = {};
1794
+ if (props.item.onClick) menuItemProps.onClick = action.run;
1795
+ else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
1796
+ return /* @__PURE__ */ jsx(Menu.Item, {
1797
+ leftSection: item.icon ?? (item.active ? /* @__PURE__ */ jsx(IconCheck, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(Flex, { w: ui.sizes.icon.sm })),
1798
+ onClick: item.onClick,
1799
+ color: item.color,
1800
+ ...menuItemProps,
1801
+ children: item.label
1802
+ }, index);
1803
+ };
1828
1804
  //#endregion
1829
1805
  //#region ../../src/core/components/Flex.tsx
1830
1806
  const Flex$1 = forwardRef((props, ref) => {
1831
- const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, ...rest } = props;
1807
+ const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, overflow, form, ...rest } = props;
1832
1808
  if (fill) rest.flex ??= 1;
1833
1809
  if (col) rest.direction ??= "column";
1834
1810
  if (center) {
@@ -1851,13 +1827,23 @@ const Flex$1 = forwardRef((props, ref) => {
1851
1827
  ...rest.style ?? {}
1852
1828
  };
1853
1829
  if (shadowed) rest.className = `${rest.className ?? ""} shadow-${shadowed === true ? "md" : shadowed}`.trim();
1830
+ if (overflow) rest.className = `${rest.className ?? ""} overflow-auto`.trim();
1831
+ if (form) {
1832
+ let formProps = typeof form === "object" ? form : {};
1833
+ if (formProps instanceof FormModel) formProps = formProps.props;
1834
+ return /* @__PURE__ */ jsx(Flex, {
1835
+ ref,
1836
+ component: "form",
1837
+ ...formProps,
1838
+ ...rest
1839
+ });
1840
+ }
1854
1841
  return /* @__PURE__ */ jsx(Flex, {
1855
1842
  ref,
1856
1843
  ...rest
1857
1844
  });
1858
1845
  });
1859
1846
  Flex$1.displayName = "Flex";
1860
-
1861
1847
  //#endregion
1862
1848
  //#region ../../src/core/components/layout/Container.tsx
1863
1849
  const Container$1 = forwardRef((props, ref) => {
@@ -1867,7 +1853,14 @@ const Container$1 = forwardRef((props, ref) => {
1867
1853
  });
1868
1854
  });
1869
1855
  Container$1.displayName = "Container";
1870
-
1856
+ //#endregion
1857
+ //#region ../../src/core/helpers/renderIcon.tsx
1858
+ const renderIcon = (icon, size) => {
1859
+ if (!icon) return null;
1860
+ if (isValidElement(icon)) return icon;
1861
+ if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui.sizes.icon.md });
1862
+ return icon;
1863
+ };
1871
1864
  //#endregion
1872
1865
  //#region ../../src/core/components/Text.tsx
1873
1866
  const INTENT_COLORS = {
@@ -1896,13 +1889,12 @@ const Text$1 = forwardRef((props, ref) => {
1896
1889
  });
1897
1890
  });
1898
1891
  Text$1.displayName = "Text";
1899
-
1900
1892
  //#endregion
1901
1893
  //#region ../../src/core/form/utils/parseInput.ts
1902
1894
  const parseInput = (props, form) => {
1903
1895
  const disabled = false;
1904
1896
  const id = props.input.props.id;
1905
- 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);
1897
+ 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);
1906
1898
  const description = props.description ?? ("description" in props.input.schema && typeof props.input.schema.description === "string" ? props.input.schema.description : void 0);
1907
1899
  const error = form.error && form.error instanceof TypeBoxError ? form.error.value.message : void 0;
1908
1900
  const icon = !props.icon ? getDefaultIcon({
@@ -1910,17 +1902,20 @@ const parseInput = (props, form) => {
1910
1902
  format: props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0,
1911
1903
  name: props.input.props.name,
1912
1904
  isEnum: props.input.schema && "enum" in props.input.schema && Boolean(props.input.schema.enum),
1913
- isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array"
1914
- }) : isValidElement(props.icon) ? props.icon : createElement(props.icon, { size: ui.sizes.icon.md });
1905
+ isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array",
1906
+ size: props.size
1907
+ }) : isValidElement(props.icon) ? props.icon : createElement(props.icon, { size: ui.sizes.icon.sm });
1915
1908
  const format = props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0;
1916
1909
  const required = props.input.required;
1917
1910
  const schema = props.input.schema;
1911
+ const testId = props.input.props?.["data-testid"];
1918
1912
  const inputProps = {
1919
1913
  label,
1920
1914
  description,
1921
1915
  error,
1922
1916
  required,
1923
- disabled
1917
+ disabled,
1918
+ ...testId ? { "data-testid": testId } : {}
1924
1919
  };
1925
1920
  if ("minLength" in schema && typeof schema.minLength === "number") inputProps.minLength = schema.minLength;
1926
1921
  if ("maxLength" in schema && typeof schema.maxLength === "number") inputProps.maxLength = schema.maxLength;
@@ -1934,7 +1929,6 @@ const parseInput = (props, form) => {
1934
1929
  inputProps
1935
1930
  };
1936
1931
  };
1937
-
1938
1932
  //#endregion
1939
1933
  //#region ../../src/core/form/components/ControlArray.tsx
1940
1934
  /**
@@ -1945,8 +1939,8 @@ const useArrayItems = (input) => {
1945
1939
  const alepha = useAlepha();
1946
1940
  const keyCounter = useRef(0);
1947
1941
  const [items, setItemsState] = useState(() => {
1948
- const defaultValue = input?.props?.defaultValue;
1949
- if (Array.isArray(defaultValue)) return defaultValue.map((value) => ({
1942
+ const initial = input?.initialValue;
1943
+ if (Array.isArray(initial)) return initial.map((value) => ({
1950
1944
  key: keyCounter.current++,
1951
1945
  value
1952
1946
  }));
@@ -1972,22 +1966,9 @@ const useArrayItems = (input) => {
1972
1966
  if (!input?.form) return;
1973
1967
  const formId = input.form.id;
1974
1968
  const fieldPath = input.path;
1975
- const listeners = [alepha.events.on("form:reset", (event) => {
1976
- if (event.id === formId) {
1977
- const defaultValue = input.props?.defaultValue;
1978
- keyCounter.current = 0;
1979
- if (Array.isArray(defaultValue)) setItemsState(defaultValue.map((value) => ({
1980
- key: keyCounter.current++,
1981
- value
1982
- })));
1983
- else setItemsState([]);
1984
- }
1985
- }), alepha.events.on("form:change", (event) => {
1969
+ return alepha.events.on("form:change", (event) => {
1986
1970
  if (event.id === formId && event.path === fieldPath) syncFromFormValue(event.value);
1987
- })];
1988
- return () => {
1989
- for (const unsub of listeners) unsub();
1990
- };
1971
+ });
1991
1972
  }, [
1992
1973
  alepha,
1993
1974
  input,
@@ -2012,10 +1993,10 @@ const createArrayItemInput = (parentInput, itemSchema, index, _itemKey, value, o
2012
1993
  path: `${parentInput.path}/${index}`,
2013
1994
  required: false,
2014
1995
  form: parentInput.form,
1996
+ initialValue: value,
2015
1997
  props: {
2016
1998
  id: `${parentInput.props.id}-${index}`,
2017
- name: `${parentInput.props.name}[${index}]`,
2018
- defaultValue: value
1999
+ name: `${parentInput.props.name}[${index}]`
2019
2000
  },
2020
2001
  set: onValueChange
2021
2002
  };
@@ -2030,10 +2011,10 @@ const createArrayItemFieldInput = (parentInput, itemSchema, fieldName, index, _i
2030
2011
  path: `${parentInput.path}/${index}/${fieldName}`,
2031
2012
  required: itemSchema.required?.includes(fieldName) ?? false,
2032
2013
  form: parentInput.form,
2014
+ initialValue: itemValue?.[fieldName],
2033
2015
  props: {
2034
2016
  id: `${parentInput.props.id}-${index}-${fieldName}`,
2035
- name: `${parentInput.props.name}[${index}].${fieldName}`,
2036
- defaultValue: itemValue?.[fieldName]
2017
+ name: `${parentInput.props.name}[${index}].${fieldName}`
2037
2018
  },
2038
2019
  set: (value) => onFieldChange(fieldName, value)
2039
2020
  };
@@ -2237,7 +2218,6 @@ const ControlArray = (props) => {
2237
2218
  })
2238
2219
  });
2239
2220
  };
2240
-
2241
2221
  //#endregion
2242
2222
  //#region ../../src/core/form/components/ControlDate.tsx
2243
2223
  /**
@@ -2251,7 +2231,9 @@ const ControlArray = (props) => {
2251
2231
  * Automatically detects date formats from schema and renders appropriate picker.
2252
2232
  */
2253
2233
  const ControlDate = (props) => {
2254
- const { inputProps, id, icon, format } = parseInput(props, useFormState(props.input));
2234
+ const form = useFormState(props.input);
2235
+ const [value, setValue] = useFieldValue(props.input);
2236
+ const { inputProps, id, icon, format } = parseInput(props, form);
2255
2237
  if (!props.input?.props) return null;
2256
2238
  if (props.datetime || format === "date-time") {
2257
2239
  const dateTimePickerProps = typeof props.datetime === "object" ? props.datetime : {};
@@ -2259,10 +2241,8 @@ const ControlDate = (props) => {
2259
2241
  ...inputProps,
2260
2242
  id,
2261
2243
  leftSection: icon,
2262
- defaultValue: props.input.props.defaultValue ? new Date(props.input.props.defaultValue) : void 0,
2263
- onChange: (value) => {
2264
- props.input.set(value ? new Date(value).toISOString() : void 0);
2265
- },
2244
+ value: value ? new Date(value) : null,
2245
+ onChange: (val) => setValue(val ? new Date(val).toISOString() : void 0),
2266
2246
  ...dateTimePickerProps
2267
2247
  });
2268
2248
  }
@@ -2272,10 +2252,8 @@ const ControlDate = (props) => {
2272
2252
  ...inputProps,
2273
2253
  id,
2274
2254
  leftSection: icon,
2275
- defaultValue: props.input.props.defaultValue ? new Date(props.input.props.defaultValue) : void 0,
2276
- onChange: (value) => {
2277
- props.input.set(value ? new Date(value).toISOString().slice(0, 10) : void 0);
2278
- },
2255
+ value: value ? new Date(value) : null,
2256
+ onChange: (val) => setValue(val ? new Date(val).toISOString().slice(0, 10) : void 0),
2279
2257
  ...dateInputProps
2280
2258
  });
2281
2259
  }
@@ -2285,30 +2263,23 @@ const ControlDate = (props) => {
2285
2263
  ...inputProps,
2286
2264
  id,
2287
2265
  leftSection: icon,
2288
- defaultValue: props.input.props.defaultValue,
2289
- onChange: (event) => {
2290
- props.input.set(event.currentTarget.value);
2291
- },
2266
+ value: value ?? "",
2267
+ onChange: (event) => setValue(event.currentTarget.value),
2292
2268
  ...timeInputProps
2293
2269
  });
2294
2270
  }
2295
2271
  return null;
2296
2272
  };
2297
-
2298
2273
  //#endregion
2299
2274
  //#region ../../src/core/form/components/ControlNumber.tsx
2300
2275
  /**
2301
2276
  *
2302
2277
  */
2303
2278
  const ControlNumber = (props) => {
2304
- const { inputProps, id, icon } = parseInput(props, useFormState(props.input));
2305
- const ref = useRef(null);
2306
- const [value, setValue] = useState(props.input.props.defaultValue);
2307
- useEvents({ "form:reset": (event) => {
2308
- if (event.id === props.input?.form.id && ref.current) setValue(props.input.props.defaultValue);
2309
- } }, [props.input]);
2279
+ const form = useFormState(props.input);
2280
+ const [value, setValue] = useFieldValue(props.input);
2281
+ const { inputProps, id, icon } = parseInput(props, form);
2310
2282
  if (!props.input?.props) return null;
2311
- const { type, ...inputPropsWithoutType } = props.input.props;
2312
2283
  if (props.sliderProps) {
2313
2284
  const min = props.sliderProps.min ?? inputProps.minimum ?? 0;
2314
2285
  const max = props.sliderProps.max ?? inputProps.maximum ?? 100;
@@ -2321,38 +2292,28 @@ const ControlNumber = (props) => {
2321
2292
  },
2322
2293
  children: /* @__PURE__ */ jsx(Slider, {
2323
2294
  ...inputProps,
2324
- ref,
2325
2295
  id,
2326
- ...inputPropsWithoutType,
2327
2296
  ...props.sliderProps,
2328
- value,
2297
+ value: value ?? 0,
2329
2298
  min,
2330
2299
  max,
2331
2300
  label: () => value,
2332
- onChange: (val) => {
2333
- setValue(val);
2334
- props.input.set(val);
2335
- }
2301
+ onChange: (val) => setValue(val)
2336
2302
  })
2337
2303
  })
2338
2304
  });
2339
2305
  }
2340
2306
  return /* @__PURE__ */ jsx(NumberInput, {
2341
2307
  ...inputProps,
2342
- ref,
2343
2308
  id,
2344
2309
  leftSection: icon,
2345
- ...inputPropsWithoutType,
2346
2310
  ...props.numberInputProps,
2347
2311
  value: value ?? "",
2348
2312
  onChange: (val) => {
2349
- const newValue = val !== null ? Number(val) : void 0;
2350
- setValue(newValue);
2351
- props.input.set(newValue);
2313
+ setValue(val !== null ? Number(val) : void 0);
2352
2314
  }
2353
2315
  });
2354
2316
  };
2355
-
2356
2317
  //#endregion
2357
2318
  //#region ../../src/core/form/components/ControlObject.tsx
2358
2319
  /**
@@ -2429,94 +2390,10 @@ const ControlObject = (props) => {
2429
2390
  })
2430
2391
  });
2431
2392
  };
2432
-
2433
2393
  //#endregion
2434
- //#region ../../src/core/form/components/ControlQueryBuilder.tsx
2435
- /**
2436
- * Query builder with text input and help popover.
2437
- * Generates query strings for parseQueryString syntax.
2438
- */
2439
- const ControlQueryBuilder = ({ schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps }) => {
2440
- const [helpOpened, setHelpOpened] = useState(false);
2441
- const [textValue, setTextValue] = useState(value);
2442
- const inputRef = useRef(null);
2443
- const fields = schema ? extractSchemaFields(schema) : [];
2444
- const [error, setError] = useState(null);
2445
- const isValid = (value) => {
2446
- try {
2447
- parseQueryString(value.trim());
2448
- } catch (e) {
2449
- setError(e.message);
2450
- return false;
2451
- }
2452
- setError(null);
2453
- return true;
2454
- };
2455
- const handleTextChange = (newValue) => {
2456
- setTextValue(newValue);
2457
- if (isValid(newValue)) onChange?.(newValue);
2458
- };
2459
- const handleClear = () => {
2460
- setTextValue("");
2461
- onChange?.("");
2462
- isValid("");
2463
- };
2464
- const handleInsert = (text) => {
2465
- const newValue = textValue ? `${textValue}${text} ` : `${text} `;
2466
- setTextValue(newValue);
2467
- if (isValid(newValue)) onChange?.(newValue);
2468
- setTimeout(() => {
2469
- inputRef.current?.focus();
2470
- const length = inputRef.current?.value.length || 0;
2471
- inputRef.current?.setSelectionRange(length, length);
2472
- }, 0);
2473
- };
2474
- useEvents({ "form:change": (event) => {
2475
- if (event.id === inputRef.current?.form?.id) {
2476
- if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
2477
- }
2478
- } }, []);
2479
- return /* @__PURE__ */ jsxs(Popover, {
2480
- width: 800,
2481
- position: "bottom-start",
2482
- shadow: "md",
2483
- opened: helpOpened,
2484
- onChange: setHelpOpened,
2485
- closeOnClickOutside: true,
2486
- closeOnEscape: true,
2487
- transitionProps: {
2488
- transition: "fade-up",
2489
- duration: 200,
2490
- timingFunction: "ease"
2491
- },
2492
- children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
2493
- ref: inputRef,
2494
- placeholder,
2495
- value: textValue,
2496
- onChange: (e) => handleTextChange(e.currentTarget.value),
2497
- onFocus: () => setHelpOpened(true),
2498
- leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
2499
- rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
2500
- size: "sm",
2501
- variant: "subtle",
2502
- color: "gray",
2503
- onClick: handleClear,
2504
- children: /* @__PURE__ */ jsx(IconX, { size: 14 })
2505
- }),
2506
- ...textInputProps
2507
- }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
2508
- bg: "transparent",
2509
- p: "xs",
2510
- bd: `1px solid ${ui.colors.border}`,
2511
- style: { backdropFilter: "blur(20px)" },
2512
- children: /* @__PURE__ */ jsx(QueryHelp, {
2513
- fields,
2514
- onInsert: handleInsert
2515
- })
2516
- })]
2517
- });
2518
- };
2519
- function QueryHelp({ fields, onInsert }) {
2394
+ //#region ../../src/core/form/components/ControlQueryBuilderHelp.tsx
2395
+ const ControlQueryBuilderHelp = (props) => {
2396
+ const { fields, onInsert } = props;
2520
2397
  return /* @__PURE__ */ jsxs(Flex, {
2521
2398
  gap: "md",
2522
2399
  align: "flex-start",
@@ -2679,112 +2556,312 @@ function QueryHelp({ fields, onInsert }) {
2679
2556
  })
2680
2557
  ]
2681
2558
  });
2682
- }
2683
-
2559
+ };
2560
+ //#endregion
2561
+ //#region ../../src/core/form/components/ControlQueryBuilder.tsx
2562
+ /**
2563
+ * Query builder with text input and help popover.
2564
+ * Generates query strings for parseQueryString syntax.
2565
+ */
2566
+ const ControlQueryBuilder = (props) => {
2567
+ const { schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps } = props;
2568
+ const [helpOpened, setHelpOpened] = useState(false);
2569
+ const [textValue, setTextValue] = useState(value);
2570
+ const inputRef = useRef(null);
2571
+ const fields = schema ? extractSchemaFields(schema) : [];
2572
+ const [error, setError] = useState(null);
2573
+ const isValid = (value) => {
2574
+ try {
2575
+ parseQueryString(value.trim());
2576
+ } catch (e) {
2577
+ setError(e.message);
2578
+ return false;
2579
+ }
2580
+ setError(null);
2581
+ return true;
2582
+ };
2583
+ const handleTextChange = (newValue) => {
2584
+ setTextValue(newValue);
2585
+ if (isValid(newValue)) onChange?.(newValue);
2586
+ };
2587
+ const handleClear = () => {
2588
+ setTextValue("");
2589
+ onChange?.("");
2590
+ isValid("");
2591
+ };
2592
+ const handleInsert = (text) => {
2593
+ const newValue = textValue ? `${textValue}${text} ` : `${text} `;
2594
+ setTextValue(newValue);
2595
+ if (isValid(newValue)) onChange?.(newValue);
2596
+ setTimeout(() => {
2597
+ inputRef.current?.focus();
2598
+ const length = inputRef.current?.value.length || 0;
2599
+ inputRef.current?.setSelectionRange(length, length);
2600
+ }, 0);
2601
+ };
2602
+ useEvents({ "form:change": (event) => {
2603
+ if (event.id === inputRef.current?.form?.id) {
2604
+ if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
2605
+ }
2606
+ } }, []);
2607
+ return /* @__PURE__ */ jsxs(Popover, {
2608
+ width: 800,
2609
+ position: "bottom-start",
2610
+ shadow: "md",
2611
+ opened: helpOpened,
2612
+ onChange: setHelpOpened,
2613
+ closeOnClickOutside: true,
2614
+ closeOnEscape: true,
2615
+ transitionProps: {
2616
+ transition: "fade-up",
2617
+ duration: 200,
2618
+ timingFunction: "ease"
2619
+ },
2620
+ children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
2621
+ ref: inputRef,
2622
+ placeholder,
2623
+ value: textValue,
2624
+ onChange: (e) => handleTextChange(e.currentTarget.value),
2625
+ onFocus: () => setHelpOpened(true),
2626
+ leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
2627
+ rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
2628
+ size: "sm",
2629
+ variant: "subtle",
2630
+ color: "gray",
2631
+ onClick: handleClear,
2632
+ children: /* @__PURE__ */ jsx(IconX, { size: 14 })
2633
+ }),
2634
+ ...textInputProps
2635
+ }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
2636
+ bg: "transparent",
2637
+ p: "xs",
2638
+ bd: `1px solid ${ui.colors.border}`,
2639
+ style: { backdropFilter: "blur(20px)" },
2640
+ children: /* @__PURE__ */ jsx(ControlQueryBuilderHelp, {
2641
+ fields,
2642
+ onInsert: handleInsert
2643
+ })
2644
+ })]
2645
+ });
2646
+ };
2684
2647
  //#endregion
2685
2648
  //#region ../../src/core/form/components/ControlSelect.tsx
2686
2649
  /**
2687
- * ControlSelect component for handling Select, MultiSelect, and TagsInput.
2650
+ * ControlSelect component for handling Select, MultiSelect, Autocomplete, and TagsInput.
2688
2651
  *
2689
2652
  * Features:
2690
2653
  * - Basic Select with enum support
2691
2654
  * - MultiSelect for array of enums
2692
- * - TagsInput for array of strings (no enum)
2693
- * - Future: Lazy loading
2694
- * - Future: Searchable/filterable options
2695
- * - Future: Custom option rendering
2655
+ * - Autocomplete for creatable single values
2656
+ * - TagsInput for creatable array values
2657
+ * - Async lazy loading with auto short/long mode detection
2658
+ * - Short mode: client-side filtering with cached data
2659
+ * - Long mode: debounced server search
2696
2660
  *
2697
2661
  * Automatically detects enum values and array types from schema.
2698
2662
  */
2699
2663
  const ControlSelect = (props) => {
2700
- const { inputProps, id, icon } = parseInput(props, useFormState(props.input));
2664
+ const form = useFormState(props.input);
2665
+ const [value, setValue] = useFieldValue(props.input);
2666
+ const { inputProps, id, icon } = parseInput(props, form);
2701
2667
  const isArray = props.input.schema && "type" in props.input.schema && props.input.schema.type === "array";
2702
- let itemsEnum;
2703
- if (isArray && "items" in props.input.schema && props.input.schema.items) {
2704
- const items = props.input.schema.items;
2705
- if ("enum" in items && Array.isArray(items.enum)) itemsEnum = items.enum;
2706
- }
2668
+ const isNumeric = props.input.schema && "type" in props.input.schema && (props.input.schema.type === "integer" || props.input.schema.type === "number");
2669
+ const isBoolean = props.input.schema && "type" in props.input.schema && props.input.schema.type === "boolean";
2707
2670
  const enumValues = props.input.schema && "enum" in props.input.schema && Array.isArray(props.input.schema.enum) ? props.input.schema.enum : [];
2708
- const [data, setData] = useState([]);
2671
+ const { data: asyncData, loading, mode, search } = useAsyncLoader(props.loader, props.loaderThreshold ?? 100, props.loaderDebounce ?? 300, props.input.initialValue);
2672
+ const [staticData, setStaticData] = useState([]);
2673
+ const enumKey = JSON.stringify(enumValues);
2709
2674
  useEffect(() => {
2710
- if (!props.input?.props) return;
2711
- if (props.loader) props.loader().then(setData);
2712
- else setData(enumValues);
2713
- }, [props.input, props.loader]);
2675
+ if (!props.input?.props || props.loader) return;
2676
+ if (isBoolean && enumValues.length === 0) setStaticData([{
2677
+ value: "true",
2678
+ label: "True"
2679
+ }, {
2680
+ value: "false",
2681
+ label: "False"
2682
+ }]);
2683
+ else setStaticData(enumValues);
2684
+ }, [
2685
+ props.input,
2686
+ props.loader,
2687
+ enumKey,
2688
+ isBoolean
2689
+ ]);
2690
+ const data = props.loader ? asyncData : staticData;
2714
2691
  if (!props.input?.props) return null;
2715
- if (props.segmented) {
2716
- const segmentedControlProps = typeof props.segmented === "object" ? props.segmented : {};
2692
+ /**
2693
+ * Coerce value for numeric schemas Select values are always strings.
2694
+ */
2695
+ const coerceValue = (val) => {
2696
+ if (val == null) return val;
2697
+ if (isNumeric) return Number(val);
2698
+ if (isBoolean) return val === "true";
2699
+ return val;
2700
+ };
2701
+ if (props.segmentedProps) {
2702
+ const segmentedControlProps = typeof props.segmentedProps === "object" ? props.segmentedProps : {};
2703
+ const segmentedData = segmentedControlProps.data ?? data.slice(0, 10);
2717
2704
  return /* @__PURE__ */ jsx(Input.Wrapper, {
2718
2705
  ...inputProps,
2719
- children: /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(SegmentedControl, {
2720
- disabled: inputProps.disabled,
2721
- defaultValue: String(props.input.props.defaultValue),
2722
- ...segmentedControlProps,
2723
- onChange: (value) => {
2724
- props.input.set(value);
2725
- },
2726
- data: data.slice(0, 10)
2727
- }) })
2706
+ children: /* @__PURE__ */ jsx(Flex, {
2707
+ my: "calc(var(--mantine-spacing-xs) / 2)",
2708
+ children: /* @__PURE__ */ jsx(SegmentedControl, {
2709
+ disabled: inputProps.disabled,
2710
+ value: value != null ? String(value) : "",
2711
+ ...segmentedControlProps,
2712
+ onChange: (val) => {
2713
+ setValue(coerceValue(val));
2714
+ },
2715
+ data: segmentedData
2716
+ })
2717
+ })
2728
2718
  });
2729
2719
  }
2730
- if (props.autocomplete) {
2731
- const autocompleteProps = typeof props.autocomplete === "object" ? props.autocomplete : {};
2732
- return /* @__PURE__ */ jsx(Autocomplete, {
2720
+ const sharedProps = {
2721
+ size: props.size,
2722
+ id,
2723
+ leftSection: loading ? /* @__PURE__ */ jsx(Loader, {
2724
+ color: "gray",
2725
+ size: 10
2726
+ }) : icon,
2727
+ data
2728
+ };
2729
+ const selectableProps = {
2730
+ ...sharedProps,
2731
+ searchable: true,
2732
+ rightSection: /* @__PURE__ */ jsx("span", {})
2733
+ };
2734
+ const longModeProps = mode === "long" ? {
2735
+ filter: ({ options }) => options,
2736
+ onSearchChange: search.run
2737
+ } : {};
2738
+ if (props.creatable && (isArray || props.tagsInputProps)) {
2739
+ const tagsInputExtraProps = props.tagsInputProps ?? {};
2740
+ return /* @__PURE__ */ jsx(TagsInput, {
2733
2741
  ...inputProps,
2734
- size: props.size,
2735
- id,
2736
- leftSection: icon,
2737
- data,
2738
- ...props.input.props,
2739
- ...autocompleteProps
2742
+ ...sharedProps,
2743
+ ...longModeProps,
2744
+ value: Array.isArray(value) ? value : [],
2745
+ onChange: (val) => {
2746
+ setValue(val);
2747
+ },
2748
+ ...tagsInputExtraProps
2740
2749
  });
2741
2750
  }
2742
- if (isArray && !itemsEnum || props.tags) {
2743
- const tagsInputProps = typeof props.tags === "object" ? props.tags : {};
2744
- return /* @__PURE__ */ jsx(TagsInput, {
2751
+ if (props.creatable) {
2752
+ const autocompleteExtraProps = props.autocompleteProps ?? {};
2753
+ return /* @__PURE__ */ jsx(Autocomplete, {
2745
2754
  ...inputProps,
2746
- size: props.size,
2747
- id,
2748
- leftSection: icon,
2749
- defaultValue: Array.isArray(props.input.props.defaultValue) ? props.input.props.defaultValue : [],
2750
- onChange: (value) => {
2751
- props.input.set(value);
2755
+ ...sharedProps,
2756
+ ...longModeProps,
2757
+ value: value != null ? String(value) : "",
2758
+ onChange: (val) => {
2759
+ setValue(coerceValue(val));
2752
2760
  },
2753
- ...tagsInputProps
2761
+ ...autocompleteExtraProps
2754
2762
  });
2755
2763
  }
2756
- if (isArray && itemsEnum || props.multi) {
2757
- const data = itemsEnum?.map((value) => ({
2758
- value,
2759
- label: value
2760
- })) || [];
2761
- const multiSelectProps = typeof props.multi === "object" ? props.multi : {};
2764
+ if (isArray || props.multiSelectProps) {
2765
+ const multiSelectExtraProps = typeof props.multiSelectProps === "object" ? props.multiSelectProps : {};
2762
2766
  return /* @__PURE__ */ jsx(MultiSelect, {
2763
2767
  ...inputProps,
2764
- size: props.size,
2765
- id,
2766
- leftSection: icon,
2767
- data,
2768
- defaultValue: Array.isArray(props.input.props.defaultValue) ? props.input.props.defaultValue : [],
2769
- onChange: (value) => {
2770
- props.input.set(value);
2768
+ ...selectableProps,
2769
+ ...longModeProps,
2770
+ value: Array.isArray(value) ? value : [],
2771
+ onChange: (val) => {
2772
+ setValue(val);
2771
2773
  },
2772
- ...multiSelectProps
2774
+ ...multiSelectExtraProps
2773
2775
  });
2774
2776
  }
2775
- const selectProps = typeof props.select === "object" ? props.select : {};
2777
+ const selectExtraProps = typeof props.selectProps === "object" ? props.selectProps : {};
2778
+ if (mode === "static") return /* @__PURE__ */ jsx(Select, {
2779
+ ...inputProps,
2780
+ ...selectableProps,
2781
+ value: value != null ? String(value) : null,
2782
+ onChange: (val) => {
2783
+ setValue(coerceValue(val));
2784
+ },
2785
+ ...selectExtraProps
2786
+ });
2776
2787
  return /* @__PURE__ */ jsx(Select, {
2777
2788
  ...inputProps,
2778
- size: props.size,
2779
- id,
2780
- leftSection: icon,
2781
- rightSection: null,
2782
- data,
2783
- ...props.input.props,
2784
- ...selectProps
2789
+ ...selectableProps,
2790
+ ...longModeProps,
2791
+ value: value != null ? String(value) : null,
2792
+ onChange: (val) => {
2793
+ setValue(coerceValue(val));
2794
+ },
2795
+ ...selectExtraProps
2785
2796
  });
2786
2797
  };
2787
-
2798
+ /**
2799
+ * Hook for async select data loading with auto short/long mode detection.
2800
+ */
2801
+ const useAsyncLoader = (loader, threshold, debounceMs, defaultValue) => {
2802
+ const [data, setData] = useState([]);
2803
+ const [loading, setLoading] = useState(false);
2804
+ const [mode, setMode] = useState("static");
2805
+ const cache = useRef(/* @__PURE__ */ new Map());
2806
+ useAction({
2807
+ name: "select:loader:init",
2808
+ runOnInit: true,
2809
+ handler: async () => {
2810
+ if (!loader) {
2811
+ setMode("static");
2812
+ return;
2813
+ }
2814
+ setLoading(true);
2815
+ try {
2816
+ const result = await loader("");
2817
+ const isShort = result.length <= threshold;
2818
+ setMode(isShort ? "short" : "long");
2819
+ cache.current.set("", result);
2820
+ setData(result);
2821
+ if (!isShort && defaultValue != null && String(defaultValue) !== "") {
2822
+ const resolved = await loader("", [String(defaultValue)]);
2823
+ if (resolved.length > 0) setData((prev) => {
2824
+ const existing = new Set(prev.map((d) => typeof d === "string" ? d : d.value));
2825
+ const newItems = resolved.filter((r) => {
2826
+ const val = typeof r === "string" ? r : r.value;
2827
+ return !existing.has(val);
2828
+ });
2829
+ return [...prev, ...newItems];
2830
+ });
2831
+ }
2832
+ } finally {
2833
+ setLoading(false);
2834
+ }
2835
+ }
2836
+ }, [loader, threshold]);
2837
+ return {
2838
+ data,
2839
+ loading,
2840
+ mode,
2841
+ search: useAction({
2842
+ debounce: debounceMs,
2843
+ handler: async (text) => {
2844
+ if (!loader || mode !== "long") return;
2845
+ if (cache.current.has(text)) {
2846
+ setData(cache.current.get(text));
2847
+ return;
2848
+ }
2849
+ setLoading(true);
2850
+ try {
2851
+ const result = await loader(text);
2852
+ cache.current.set(text, result);
2853
+ setData(result);
2854
+ } finally {
2855
+ setLoading(false);
2856
+ }
2857
+ }
2858
+ }, [
2859
+ loader,
2860
+ mode,
2861
+ debounceMs
2862
+ ])
2863
+ };
2864
+ };
2788
2865
  //#endregion
2789
2866
  //#region ../../src/core/form/components/Control.tsx
2790
2867
  /**
@@ -2813,6 +2890,7 @@ const ControlSelect = (props) => {
2813
2890
  */
2814
2891
  const Control = (_props) => {
2815
2892
  const form = useFormState(_props.input, ["error"]);
2893
+ const [value, setValue] = useFieldValue(_props.input);
2816
2894
  if (!_props.input?.props) return null;
2817
2895
  const { inputProps, id, icon, format, schema } = parseInput(_props, form);
2818
2896
  const props = {
@@ -2820,12 +2898,11 @@ const Control = (_props) => {
2820
2898
  ...schema.$control
2821
2899
  };
2822
2900
  if (props.query) return /* @__PURE__ */ jsx(ControlQueryBuilder, {
2823
- ...props.input.props,
2824
2901
  ...inputProps,
2825
2902
  schema: props.query,
2826
- value: props.input.props.value,
2827
- onChange: (value) => {
2828
- props.input.set(value);
2903
+ value,
2904
+ onChange: (val) => {
2905
+ setValue(val);
2829
2906
  }
2830
2907
  });
2831
2908
  if (props.custom) {
@@ -2836,9 +2913,9 @@ const Control = (_props) => {
2836
2913
  flex: 1,
2837
2914
  mt: "calc(var(--mantine-spacing-xs) / 2)",
2838
2915
  children: /* @__PURE__ */ jsx(Custom, {
2839
- defaultValue: props.input.props.defaultValue,
2840
- onChange: (value) => {
2841
- props.input.set(value);
2916
+ value,
2917
+ onChange: (val) => {
2918
+ setValue(val);
2842
2919
  }
2843
2920
  })
2844
2921
  })
@@ -2849,7 +2926,7 @@ const Control = (_props) => {
2849
2926
  const controlObjectProps = typeof props.object === "object" ? props.object : {};
2850
2927
  return /* @__PURE__ */ jsx(ControlObject, {
2851
2928
  input: props.input,
2852
- title: props.title,
2929
+ label: props.label,
2853
2930
  description: props.description,
2854
2931
  ...controlObjectProps
2855
2932
  });
@@ -2860,18 +2937,18 @@ const Control = (_props) => {
2860
2937
  const controlArrayProps = typeof props.array === "object" ? props.array : {};
2861
2938
  return /* @__PURE__ */ jsx(ControlArray, {
2862
2939
  input: props.input,
2863
- title: props.title,
2940
+ label: props.label,
2864
2941
  description: props.description,
2865
2942
  ...controlArrayProps
2866
2943
  });
2867
2944
  }
2868
- if (props.number || props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
2945
+ if (props.number || !props.select && props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
2869
2946
  const controlNumberProps = typeof props.number === "object" ? props.number : {};
2870
2947
  if (props.slider) controlNumberProps.sliderProps ??= {};
2871
2948
  return /* @__PURE__ */ jsx(ControlNumber, {
2872
2949
  size: props.size,
2873
2950
  input: props.input,
2874
- title: props.title,
2951
+ label: props.label,
2875
2952
  description: props.description,
2876
2953
  icon,
2877
2954
  ...controlNumberProps
@@ -2884,9 +2961,7 @@ const Control = (_props) => {
2884
2961
  size: props.size,
2885
2962
  id,
2886
2963
  leftSection: icon,
2887
- onChange: (file) => {
2888
- props.input.set(file);
2889
- },
2964
+ onChange: (file) => setValue(file),
2890
2965
  ...fileInputProps
2891
2966
  });
2892
2967
  }
@@ -2897,17 +2972,18 @@ const Control = (_props) => {
2897
2972
  size: props.size,
2898
2973
  id,
2899
2974
  leftSection: icon,
2900
- ...props.input.props,
2975
+ value: value ?? "",
2976
+ onChange: (val) => setValue(val),
2901
2977
  ...colorInputProps
2902
2978
  });
2903
2979
  }
2904
2980
  if (props.input.schema && "enum" in props.input.schema && props.input.schema.enum || isArray && !isArrayOfObjects || props.select) {
2905
2981
  const opts = typeof props.select === "object" ? props.select : {};
2906
- if (props.segmented) opts.segmented ??= {};
2982
+ if (props.segmented) opts.segmentedProps ??= {};
2907
2983
  return /* @__PURE__ */ jsx(ControlSelect, {
2908
2984
  size: props.size,
2909
2985
  input: props.input,
2910
- title: props.title,
2986
+ label: props.label,
2911
2987
  description: props.description,
2912
2988
  icon,
2913
2989
  ...opts
@@ -2921,16 +2997,16 @@ const Control = (_props) => {
2921
2997
  size: props.size,
2922
2998
  id,
2923
2999
  color: "blue",
2924
- defaultChecked: props.input.props.defaultValue,
3000
+ checked: Boolean(value),
2925
3001
  onChange: (event) => {
2926
- props.input.set(event.currentTarget.checked);
3002
+ setValue(event.currentTarget.checked);
2927
3003
  },
2928
3004
  ...switchProps
2929
3005
  });
2930
3006
  }
2931
3007
  const opts = {
2932
3008
  input: props.input,
2933
- select: { data: [{
3009
+ selectProps: { data: [{
2934
3010
  value: "true",
2935
3011
  label: "Yes"
2936
3012
  }, {
@@ -2940,7 +3016,7 @@ const Control = (_props) => {
2940
3016
  };
2941
3017
  return /* @__PURE__ */ jsx(ControlSelect, {
2942
3018
  size: props.size,
2943
- title: props.title,
3019
+ label: props.label,
2944
3020
  description: props.description,
2945
3021
  icon,
2946
3022
  ...opts
@@ -2953,7 +3029,8 @@ const Control = (_props) => {
2953
3029
  size: props.size,
2954
3030
  id,
2955
3031
  leftSection: icon,
2956
- ...props.input.props,
3032
+ value: value ?? "",
3033
+ onChange: (ev) => setValue(ev.target.value),
2957
3034
  ...passwordInputProps
2958
3035
  });
2959
3036
  }
@@ -2964,14 +3041,15 @@ const Control = (_props) => {
2964
3041
  size: props.size,
2965
3042
  id,
2966
3043
  leftSection: icon,
2967
- ...props.input.props,
3044
+ value: value ?? "",
3045
+ onChange: (ev) => setValue(ev.target.value),
2968
3046
  ...textAreaProps
2969
3047
  });
2970
3048
  }
2971
3049
  if (props.date || props.datetime || props.time || format === "date" || format === "date-time" || format === "time") return /* @__PURE__ */ jsx(ControlDate, {
2972
3050
  size: props.size,
2973
3051
  input: props.input,
2974
- title: props.title,
3052
+ label: props.label,
2975
3053
  description: props.description,
2976
3054
  icon,
2977
3055
  date: props.date,
@@ -2986,7 +3064,7 @@ const Control = (_props) => {
2986
3064
  case "uri": return "url";
2987
3065
  case "tel":
2988
3066
  case "phone": return "tel";
2989
- default: return;
3067
+ default: return props.input.props.type ?? "text";
2990
3068
  }
2991
3069
  };
2992
3070
  return /* @__PURE__ */ jsx(TextInput, {
@@ -2995,26 +3073,11 @@ const Control = (_props) => {
2995
3073
  id,
2996
3074
  leftSection: icon,
2997
3075
  type: getInputType(),
2998
- ...props.input.props,
2999
- ...textInputProps,
3000
- inputWrapperOrder: [
3001
- "label",
3002
- "input",
3003
- "description",
3004
- "error"
3005
- ]
3076
+ value: value ?? "",
3077
+ onChange: (ev) => setValue(ev.target.value),
3078
+ ...textInputProps
3006
3079
  });
3007
3080
  };
3008
-
3009
- //#endregion
3010
- //#region ../../src/core/helpers/renderIcon.tsx
3011
- const renderIcon = (icon, size) => {
3012
- if (!icon) return null;
3013
- if (isValidElement(icon)) return icon;
3014
- if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui.sizes.icon.md });
3015
- return icon;
3016
- };
3017
-
3018
3081
  //#endregion
3019
3082
  //#region ../../src/core/utils/extractSchemaFields.ts
3020
3083
  /**
@@ -3103,15 +3166,14 @@ const OPERATOR_INFO = {
3103
3166
  example: "status=[active,pending]"
3104
3167
  }
3105
3168
  };
3106
-
3107
3169
  //#endregion
3108
3170
  //#region ../../src/core/utils/icons.tsx
3109
3171
  /**
3110
3172
  * Get the default icon for an input based on its type, format, or name.
3111
3173
  */
3112
3174
  const getDefaultIcon = (params) => {
3113
- const { type, format, name, isEnum, isArray, size = "sm" } = params;
3114
- const iconSize = ui.sizes.icon[size];
3175
+ const { type, format, name, isEnum, isArray, size = "xs" } = params;
3176
+ const iconSize = ui.sizes.icon[size] - 4;
3115
3177
  if (format) switch (format) {
3116
3178
  case "email": return /* @__PURE__ */ jsx(IconMail, { size: iconSize });
3117
3179
  case "url":
@@ -3145,7 +3207,6 @@ const getDefaultIcon = (params) => {
3145
3207
  }
3146
3208
  return /* @__PURE__ */ jsx(IconAt, { size: iconSize });
3147
3209
  };
3148
-
3149
3210
  //#endregion
3150
3211
  //#region ../../src/core/utils/string.ts
3151
3212
  /**
@@ -3183,7 +3244,6 @@ const prettyName = (name) => {
3183
3244
  const segments = name.split("/").filter((s) => s && !/^\d+$/.test(s));
3184
3245
  return toTitleCase(segments[segments.length - 1] || name.replaceAll("/", ""));
3185
3246
  };
3186
-
3187
3247
  //#endregion
3188
3248
  //#region ../../src/core/index.ts
3189
3249
  /**
@@ -3222,7 +3282,7 @@ const AlephaUI = $module({
3222
3282
  alepha.with(ToastService);
3223
3283
  }
3224
3284
  });
3225
-
3226
3285
  //#endregion
3227
3286
  export { ui as a, ActionButton as i, capitalize as n, AlephaMantineProvider as o, Control as r, AlephaUI as t };
3228
- //# sourceMappingURL=core-DyfeVr5c.js.map
3287
+
3288
+ //# sourceMappingURL=core-C6D3pazL.js.map