@alepha/ui 0.18.1 → 0.18.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/admin/{AdminApiKeys-C-6_Q-lH.js → AdminApiKeys-Dy_k-4Vd.js} +17 -38
- package/dist/admin/AdminApiKeys-Dy_k-4Vd.js.map +1 -0
- package/dist/admin/{AdminAudits-Bgbf04hO.js → AdminAudits-CKiFMSSU.js} +23 -19
- package/dist/admin/AdminAudits-CKiFMSSU.js.map +1 -0
- package/dist/admin/AdminDashboard-PhC_dZqo.js +67 -0
- package/dist/admin/AdminDashboard-PhC_dZqo.js.map +1 -0
- package/dist/admin/{AdminFiles-B9a7G3cY.js → AdminFiles-DFTjijGp.js} +3 -7
- package/dist/admin/AdminFiles-DFTjijGp.js.map +1 -0
- package/dist/admin/{AdminJobDashboard-DaTwf5OY.js → AdminJobDashboard-BL8gGPDp.js} +2 -2
- package/dist/admin/{AdminJobDashboard-DaTwf5OY.js.map → AdminJobDashboard-BL8gGPDp.js.map} +1 -1
- package/dist/admin/{AdminJobExecutions-B9cek5dl.js → AdminJobExecutions-D9E-CS-U.js} +24 -36
- package/dist/admin/AdminJobExecutions-D9E-CS-U.js.map +1 -0
- package/dist/admin/{AdminJobRegistry-DFgV3oqx.js → AdminJobRegistry-Ci9ue1zC.js} +10 -18
- package/dist/admin/AdminJobRegistry-Ci9ue1zC.js.map +1 -0
- package/dist/admin/AdminLayout-I6TlUMPc.js +61 -0
- package/dist/admin/AdminLayout-I6TlUMPc.js.map +1 -0
- package/dist/admin/AdminNotifications-ZPHCYrv7.js +542 -0
- package/dist/admin/AdminNotifications-ZPHCYrv7.js.map +1 -0
- package/dist/admin/{AdminParameters-DHw9ATgl.js → AdminParameters-CqgvhRsb.js} +120 -105
- package/dist/admin/AdminParameters-CqgvhRsb.js.map +1 -0
- package/dist/admin/{AdminSessions-BhGJPI3z.js → AdminSessions-Bz5NRuoW.js} +48 -53
- package/dist/admin/AdminSessions-Bz5NRuoW.js.map +1 -0
- package/dist/admin/{AdminUserLayout-BdC4Te8m.js → AdminUserLayout-lXT6I0Qq.js} +14 -8
- package/dist/admin/AdminUserLayout-lXT6I0Qq.js.map +1 -0
- package/dist/admin/{AdminUserProfile-DAt23fqY.js → AdminUserProfile-vFBLoJ3h.js} +3 -3
- package/dist/admin/{AdminUserProfile-DAt23fqY.js.map → AdminUserProfile-vFBLoJ3h.js.map} +1 -1
- package/dist/admin/{AdminUserSessions-1uzcx02z.js → AdminUserSessions-CT_YDim0.js} +33 -35
- package/dist/admin/AdminUserSessions-CT_YDim0.js.map +1 -0
- package/dist/admin/AdminUsers-D1UfGya9.js +206 -0
- package/dist/admin/AdminUsers-D1UfGya9.js.map +1 -0
- package/dist/admin/{AuthLayout-DFJvCvzw.js → AuthLayout-_frhdgOO.js} +2 -2
- package/dist/admin/{AuthLayout-DFJvCvzw.js.map → AuthLayout-_frhdgOO.js.map} +1 -1
- package/dist/admin/{IconGoogle-CSQLPYwX.js → IconGoogle-Ch1m3Uzl.js} +1 -1
- package/dist/admin/{IconGoogle-CSQLPYwX.js.map → IconGoogle-Ch1m3Uzl.js.map} +1 -1
- package/dist/admin/Login-xtNmQtGh.js +275 -0
- package/dist/admin/Login-xtNmQtGh.js.map +1 -0
- package/dist/{auth/Profile-BMX_Ar_s.js → admin/Profile-_AtPUwAP.js} +31 -27
- package/dist/admin/Profile-_AtPUwAP.js.map +1 -0
- package/dist/admin/{Register-Cs10l8vX.js → Register-JcCjHUUn.js} +199 -143
- package/dist/admin/Register-JcCjHUUn.js.map +1 -0
- package/dist/admin/{ResetPassword-BwDdfkGH.js → ResetPassword-CwGBPLJO.js} +7 -7
- package/dist/admin/ResetPassword-CwGBPLJO.js.map +1 -0
- package/dist/admin/{VerifyEmail-DfXHAiQl.js → VerifyEmail-hNxWejWf.js} +23 -8
- package/dist/admin/VerifyEmail-hNxWejWf.js.map +1 -0
- package/dist/admin/{core-2xoLiT0o.js → core-CYaRQ8O-.js} +2082 -688
- package/dist/admin/core-CYaRQ8O-.js.map +1 -0
- package/dist/admin/index.d.ts +112 -48
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +467 -69
- package/dist/admin/index.js.map +1 -1
- package/dist/auth/{AuthLayout-CAE1pX9s.js → AuthLayout-AvLlcLjS.js} +2 -2
- package/dist/auth/{AuthLayout-CAE1pX9s.js.map → AuthLayout-AvLlcLjS.js.map} +1 -1
- package/dist/auth/Login-BA1E8IZl.js +275 -0
- package/dist/auth/Login-BA1E8IZl.js.map +1 -0
- package/dist/{admin/Profile-B-c9pCPf.js → auth/Profile-YcWdeuFz.js} +31 -27
- package/dist/auth/Profile-YcWdeuFz.js.map +1 -0
- package/dist/auth/{Register-6hi_cpfF.js → Register-CPhEO5MG.js} +198 -142
- package/dist/auth/Register-CPhEO5MG.js.map +1 -0
- package/dist/{demo/ResetPassword-DWN0lzr5.js → auth/ResetPassword-DCtGcneA.js} +7 -7
- package/dist/auth/ResetPassword-DCtGcneA.js.map +1 -0
- package/dist/{demo/VerifyEmail-DZWL72K4.js → auth/VerifyEmail-DkH7NBfn.js} +23 -8
- package/dist/auth/VerifyEmail-DkH7NBfn.js.map +1 -0
- package/dist/auth/{core-niW0sFLv.js → core-D5jIAVF2.js} +1385 -329
- package/dist/auth/core-D5jIAVF2.js.map +1 -0
- package/dist/auth/index.d.ts +105 -49
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +29 -26
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +210 -74
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +2247 -834
- package/dist/core/index.js.map +1 -1
- package/dist/demo/{AuthLayout-jLa0aKsI.js → AuthLayout-Brri4A-L.js} +2 -2
- package/dist/demo/{AuthLayout-jLa0aKsI.js.map → AuthLayout-Brri4A-L.js.map} +1 -1
- package/dist/demo/DemoButton-wiCxZZ_L.js +182 -0
- package/dist/demo/DemoButton-wiCxZZ_L.js.map +1 -0
- package/dist/demo/DemoControlSelect-D7ILObVg.js +305 -0
- package/dist/demo/DemoControlSelect-D7ILObVg.js.map +1 -0
- package/dist/demo/DemoDataTable-DZ5Y8pFX.js +362 -0
- package/dist/demo/DemoDataTable-DZ5Y8pFX.js.map +1 -0
- package/dist/demo/{DemoDialog-4ItHLf9t.js → DemoDialog-CUWdLHim.js} +2 -2
- package/dist/demo/{DemoDialog-4ItHLf9t.js.map → DemoDialog-CUWdLHim.js.map} +1 -1
- package/dist/demo/{DemoFlex-EtVq8QfX.js → DemoFlex-a8OhMMvq.js} +3 -3
- package/dist/demo/{DemoFlex-EtVq8QfX.js.map → DemoFlex-a8OhMMvq.js.map} +1 -1
- package/dist/demo/{DemoHeading-BS-vGfkI.js → DemoHeading-C13OVDfS.js} +3 -3
- package/dist/demo/{DemoHeading-BS-vGfkI.js.map → DemoHeading-C13OVDfS.js.map} +1 -1
- package/dist/demo/{DemoHome-Clbn8AmS.js → DemoHome-D_De3UiT.js} +2 -2
- package/dist/demo/{DemoHome-Clbn8AmS.js.map → DemoHome-D_De3UiT.js.map} +1 -1
- package/dist/demo/{DemoJsonViewer-DkIX_ky2.js → DemoJsonViewer-B50s9aGM.js} +3 -3
- package/dist/demo/{DemoJsonViewer-DkIX_ky2.js.map → DemoJsonViewer-B50s9aGM.js.map} +1 -1
- package/dist/demo/{DemoLayout-C56xb5EE.js → DemoLayout-CHU8WTwO.js} +14 -5
- package/dist/demo/DemoLayout-CHU8WTwO.js.map +1 -0
- package/dist/demo/{DemoLogin-BZwpicOS.js → DemoLogin-BBlrWpml.js} +49 -32
- package/dist/demo/DemoLogin-BBlrWpml.js.map +1 -0
- package/dist/demo/{DemoRegister-C7_qc4MJ.js → DemoRegister-BuNE3_-f.js} +49 -50
- package/dist/demo/DemoRegister-BuNE3_-f.js.map +1 -0
- package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js → DemoResetPassword-D_IjjjOJ.js} +12 -16
- package/dist/demo/DemoResetPassword-D_IjjjOJ.js.map +1 -0
- package/dist/demo/{DemoSidebar-CcBo4ltC.js → DemoSidebar-Giy2HRBD.js} +3 -3
- package/dist/demo/{DemoSidebar-CcBo4ltC.js.map → DemoSidebar-Giy2HRBD.js.map} +1 -1
- package/dist/demo/{DemoText-CzXuUn3g.js → DemoText-ubcw-vog.js} +3 -3
- package/dist/demo/{DemoText-CzXuUn3g.js.map → DemoText-ubcw-vog.js.map} +1 -1
- package/dist/demo/{DemoToast-BgHDhWrX.js → DemoToast-9die_dYT.js} +2 -2
- package/dist/demo/{DemoToast-BgHDhWrX.js.map → DemoToast-9die_dYT.js.map} +1 -1
- package/dist/demo/{DemoTypeForm-DDzWoMSV.js → DemoTypeForm-D_d6OVKL.js} +8 -4
- package/dist/demo/DemoTypeForm-D_d6OVKL.js.map +1 -0
- package/dist/demo/DemoVerifyEmail-B43KlF4F.js +34 -0
- package/dist/demo/DemoVerifyEmail-B43KlF4F.js.map +1 -0
- package/dist/demo/Login-C12N4oGs.js +275 -0
- package/dist/demo/Login-C12N4oGs.js.map +1 -0
- package/dist/demo/{Profile-CWqti7FB.js → Profile-DS5q4vOh.js} +31 -27
- package/dist/demo/Profile-DS5q4vOh.js.map +1 -0
- package/dist/demo/{Register-a70LPgs2.js → Register-B4hLBeEv.js} +198 -142
- package/dist/demo/Register-B4hLBeEv.js.map +1 -0
- package/dist/{auth/ResetPassword-CqfTk1FI.js → demo/ResetPassword-D8g9ha1N.js} +7 -7
- package/dist/demo/ResetPassword-D8g9ha1N.js.map +1 -0
- package/dist/demo/{Showcase-Dq3MISpd.js → Showcase-D6Fxt4X4.js} +64 -65
- package/dist/demo/Showcase-D6Fxt4X4.js.map +1 -0
- package/dist/{auth/VerifyEmail-nWiSTMjF.js → demo/VerifyEmail-BjDo0cZA.js} +23 -8
- package/dist/demo/VerifyEmail-BjDo0cZA.js.map +1 -0
- package/dist/demo/{auth-d6n3xbug.js → auth-ByVTreDl.js} +8 -8
- package/dist/demo/{auth-d6n3xbug.js.map → auth-ByVTreDl.js.map} +1 -1
- package/dist/demo/{core-RCUw1Q-a.js → core-DFgB3yU4.js} +2182 -756
- package/dist/demo/core-DFgB3yU4.js.map +1 -0
- package/dist/demo/index.d.ts +1 -0
- package/dist/demo/index.d.ts.map +1 -1
- package/dist/demo/index.js +24 -18
- package/dist/demo/index.js.map +1 -1
- package/package.json +7 -7
- package/src/admin/{AdminRouter.ts → AdminRouter.tsx} +150 -18
- package/src/admin/components/AdminDashboard.tsx +52 -0
- package/src/admin/components/AdminLayout.tsx +32 -40
- package/src/admin/components/audits/AdminAudits.tsx +22 -16
- package/src/admin/components/files/AdminFiles.tsx +1 -6
- package/src/admin/components/jobs/AdminJobExecutions.tsx +33 -39
- package/src/admin/components/jobs/AdminJobRegistry.tsx +9 -18
- package/src/admin/components/keys/AdminApiKeys.tsx +23 -41
- package/src/admin/components/notifications/AdminNotifications.tsx +519 -0
- package/src/admin/components/parameters/ParameterDetails.tsx +12 -270
- package/src/admin/components/parameters/ParameterDetailsConfigForm.tsx +238 -0
- package/src/admin/components/parameters/ParameterDetailsLoading.tsx +24 -0
- package/src/admin/components/parameters/ParameterHistory.tsx +10 -11
- package/src/admin/components/parameters/ParameterTree.tsx +28 -184
- package/src/admin/components/parameters/ParameterTreeNode.tsx +151 -0
- package/src/admin/components/sessions/AdminSessions.tsx +71 -71
- package/src/admin/components/shared/AdminResourceHeader.tsx +2 -25
- package/src/admin/components/shared/AdminResourceHeaderMenuItem.tsx +37 -0
- package/src/admin/components/shared/AdminResourceTabs.tsx +2 -26
- package/src/admin/components/shared/AdminResourceTabsItem.tsx +36 -0
- package/src/admin/components/users/AdminUserSessions.tsx +33 -31
- package/src/admin/components/users/AdminUsers.tsx +184 -72
- package/src/admin/index.ts +2 -2
- package/src/admin/primitives/$uiAdmin.ts +1 -1
- package/src/auth/components/Login.tsx +188 -121
- package/src/auth/components/Profile.tsx +1 -22
- package/src/auth/components/ProfileField.tsx +39 -0
- package/src/auth/components/Register.tsx +215 -158
- package/src/auth/components/ResetPassword.tsx +7 -11
- package/src/auth/components/VerifyEmail.tsx +35 -10
- package/src/auth/components/buttons/UserButton.tsx +20 -24
- package/src/auth/index.ts +1 -0
- package/src/core/atoms/alephaSidebarAtom.ts +1 -1
- package/src/core/atoms/alephaThemeListAtom.ts +14 -1
- package/src/core/atoms/alephaThemeOverridesAtom.ts +17 -0
- package/src/core/atoms/themes/editorial.ts +184 -0
- package/src/core/atoms/themes/monochrome.ts +197 -0
- package/src/core/atoms/themes/rosePine.ts +208 -0
- package/src/core/atoms/themes/softBrutalism.ts +221 -0
- package/src/core/atoms/themes/terminal.ts +186 -0
- package/src/core/components/Flex.tsx +101 -1
- package/src/core/components/Text.tsx +1 -1
- package/src/core/components/buttons/ActionButton.tsx +109 -87
- package/src/core/components/buttons/DarkModeButton.tsx +3 -3
- package/src/core/components/buttons/LanguageButton.tsx +1 -1
- package/src/core/components/buttons/OmnibarButton.tsx +1 -2
- package/src/core/components/buttons/ThemeButton.tsx +40 -11
- package/src/core/components/buttons/ThemeExpertModal.tsx +184 -0
- package/src/core/components/buttons/ToggleSidebarButton.tsx +1 -2
- package/src/core/components/data/DetailDrawer.tsx +102 -96
- package/src/core/components/data/DetailList.tsx +2 -1
- package/src/core/components/layout/AppBar.tsx +10 -0
- package/src/core/components/layout/Breadcrumb.tsx +3 -6
- package/src/core/components/layout/DashboardShell.tsx +28 -11
- package/src/core/components/layout/Sidebar.tsx +18 -235
- package/src/core/components/layout/SidebarCollapsedItem.tsx +91 -0
- package/src/core/components/layout/SidebarItem.tsx +146 -0
- package/src/core/components/layout/index.ts +3 -1
- package/src/core/constants/ui.ts +5 -5
- package/src/core/form/components/Control.tsx +31 -29
- package/src/core/form/components/ControlArray.tsx +13 -39
- package/src/core/form/components/ControlDate.tsx +10 -21
- package/src/core/form/components/ControlNumber.tsx +4 -33
- package/src/core/form/components/ControlQueryBuilder.tsx +12 -175
- package/src/core/form/components/ControlQueryBuilderHelp.tsx +165 -0
- package/src/core/form/components/ControlSelect.browser.spec.tsx +343 -0
- package/src/core/form/components/ControlSelect.tsx +294 -92
- package/src/core/form/components/TypeForm.browser.spec.tsx +3 -3
- package/src/core/form/components/TypeForm.tsx +5 -2
- package/src/core/form/index.ts +8 -1
- package/src/core/form/utils/parseInput.ts +7 -3
- package/src/core/hooks/useTheme.ts +26 -3
- package/src/core/index.ts +9 -2
- package/src/core/interfaces/AlephaTheme.ts +2 -0
- package/src/core/json/components/JsonViewer.tsx +103 -319
- package/src/core/json/components/JsonViewerCopyButton.tsx +46 -0
- package/src/core/json/components/JsonViewerRowNode.tsx +120 -0
- package/src/core/json/components/JsonViewerShared.ts +76 -0
- package/src/core/providers/ThemeProvider.ts +108 -8
- package/src/core/services/DialogService.tsx +24 -3
- package/src/core/styles.css +33 -20
- package/src/core/table/components/ColumnPicker.tsx +3 -3
- package/src/core/table/components/DataTable.tsx +233 -143
- package/src/core/table/components/DataTableFilters.tsx +6 -16
- package/src/core/table/components/DataTablePagination.tsx +58 -29
- package/src/core/table/components/DataTableToolbar.tsx +16 -7
- package/src/core/table/components/FilterPicker.tsx +3 -3
- package/src/core/table/index.ts +1 -0
- package/src/core/table/interfaces/types.ts +42 -9
- package/src/core/utils/icons.tsx +2 -2
- package/src/demo/DemoRouter.ts +8 -1
- package/src/demo/components/DemoLayout.tsx +12 -2
- package/src/demo/components/auth/DemoLogin.tsx +35 -28
- package/src/demo/components/auth/DemoRegister.tsx +35 -49
- package/src/demo/components/auth/DemoResetPassword.tsx +5 -9
- package/src/demo/components/auth/DemoVerifyEmail.tsx +7 -6
- package/src/demo/components/core/DemoButton.tsx +123 -103
- package/src/demo/components/core/DemoControlSelect.tsx +325 -0
- package/src/demo/components/core/DemoDataTable.tsx +255 -241
- package/src/demo/components/core/DemoTypeForm.tsx +7 -2
- package/src/demo/components/shared/MacWindow.tsx +5 -11
- package/src/demo/components/shared/Showcase.tsx +28 -42
- package/dist/admin/AdminApiKeys-C-6_Q-lH.js.map +0 -1
- package/dist/admin/AdminAudits-Bgbf04hO.js.map +0 -1
- package/dist/admin/AdminFiles-B9a7G3cY.js.map +0 -1
- package/dist/admin/AdminJobExecutions-B9cek5dl.js.map +0 -1
- package/dist/admin/AdminJobRegistry-DFgV3oqx.js.map +0 -1
- package/dist/admin/AdminLayout-DHsvWxVB.js +0 -70
- package/dist/admin/AdminLayout-DHsvWxVB.js.map +0 -1
- package/dist/admin/AdminParameters-DHw9ATgl.js.map +0 -1
- package/dist/admin/AdminSessions-BhGJPI3z.js.map +0 -1
- package/dist/admin/AdminUserLayout-BdC4Te8m.js.map +0 -1
- package/dist/admin/AdminUserSessions-1uzcx02z.js.map +0 -1
- package/dist/admin/AdminUsers-C85c3eiQ.js +0 -121
- package/dist/admin/AdminUsers-C85c3eiQ.js.map +0 -1
- package/dist/admin/Login-BGheURrg.js +0 -219
- package/dist/admin/Login-BGheURrg.js.map +0 -1
- package/dist/admin/Profile-B-c9pCPf.js.map +0 -1
- package/dist/admin/Register-Cs10l8vX.js.map +0 -1
- package/dist/admin/ResetPassword-BwDdfkGH.js.map +0 -1
- package/dist/admin/VerifyEmail-DfXHAiQl.js.map +0 -1
- package/dist/admin/auth-Dr0Cf8I7.js +0 -319
- package/dist/admin/auth-Dr0Cf8I7.js.map +0 -1
- package/dist/admin/core-2xoLiT0o.js.map +0 -1
- package/dist/auth/Login-Denw_UGy.js +0 -219
- package/dist/auth/Login-Denw_UGy.js.map +0 -1
- package/dist/auth/Profile-BMX_Ar_s.js.map +0 -1
- package/dist/auth/Register-6hi_cpfF.js.map +0 -1
- package/dist/auth/ResetPassword-CqfTk1FI.js.map +0 -1
- package/dist/auth/VerifyEmail-nWiSTMjF.js.map +0 -1
- package/dist/auth/core-niW0sFLv.js.map +0 -1
- package/dist/demo/DemoButton-BmaWZVwf.js +0 -178
- package/dist/demo/DemoButton-BmaWZVwf.js.map +0 -1
- package/dist/demo/DemoDataTable-Z9xyV221.js +0 -362
- package/dist/demo/DemoDataTable-Z9xyV221.js.map +0 -1
- package/dist/demo/DemoLayout-C56xb5EE.js.map +0 -1
- package/dist/demo/DemoLogin-BZwpicOS.js.map +0 -1
- package/dist/demo/DemoRegister-C7_qc4MJ.js.map +0 -1
- package/dist/demo/DemoResetPassword-BI1Ct4Dw.js.map +0 -1
- package/dist/demo/DemoTypeForm-DDzWoMSV.js.map +0 -1
- package/dist/demo/DemoVerifyEmail-C_Irdnov.js +0 -30
- package/dist/demo/DemoVerifyEmail-C_Irdnov.js.map +0 -1
- package/dist/demo/Login-hSOU3jZc.js +0 -219
- package/dist/demo/Login-hSOU3jZc.js.map +0 -1
- package/dist/demo/Profile-CWqti7FB.js.map +0 -1
- package/dist/demo/Register-a70LPgs2.js.map +0 -1
- package/dist/demo/ResetPassword-DWN0lzr5.js.map +0 -1
- package/dist/demo/Showcase-Dq3MISpd.js.map +0 -1
- package/dist/demo/VerifyEmail-DZWL72K4.js.map +0 -1
- package/dist/demo/core-RCUw1Q-a.js.map +0 -1
- package/src/demo/styles.css +0 -0
package/dist/core/index.js
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { $atom, $context, $inject, $module, Alepha, AlephaError, TypeBoxError, t } from "alepha";
|
|
2
|
-
import { AlephaReactForm, FormValidationError, useForm, useFormState } from "alepha/react/form";
|
|
3
|
-
import { $head, AlephaReactHead } from "alepha/react/head";
|
|
2
|
+
import { AlephaReactForm, FormValidationError, useFieldValue, useForm, useFormState } from "alepha/react/form";
|
|
3
|
+
import { $head, AlephaReactHead, BrowserHeadProvider } from "alepha/react/head";
|
|
4
4
|
import { AlephaReactI18n, useI18n } from "alepha/react/i18n";
|
|
5
5
|
import { $cookie } from "alepha/server/cookies";
|
|
6
|
+
import { ActionIcon, Anchor, AppShell, Autocomplete, Badge, Burger, Button, Card, Checkbox, ColorInput, ColorSchemeScript, ColorSwatch, Container as Container$1, CopyButton, Divider, Drawer, Fieldset, FileInput, Flex as Flex$1, Grid, Image, Input, Kbd, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, Paper, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, SimpleGrid, Slider, Switch, Table, Tabs, TagsInput, Text as Text$1, TextInput, Textarea, Tooltip, Tree, UnstyledButton, getTreeExpandedState, useMantineColorScheme, useMantineTheme, useTree } from "@mantine/core";
|
|
6
7
|
import { ModalsProvider, modals } from "@mantine/modals";
|
|
7
|
-
import { ActionIcon, Anchor, AppShell, Autocomplete, Badge, Burger, Button, Card, Checkbox, ColorInput, ColorSchemeScript, Container as Container$1, CopyButton, Divider, Drawer, Fieldset, FileInput, Flex as Flex$1, Grid, Image, Input, Kbd, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, Paper, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, Slider, Switch, Table, Tabs, TagsInput, Text as Text$1, TextInput, Textarea, ThemeIcon, Tooltip, Tree, UnstyledButton, getTreeExpandedState, useMantineColorScheme, useMantineTheme, useTree } from "@mantine/core";
|
|
8
8
|
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { Children, Fragment as Fragment$1, createElement, forwardRef, isValidElement, useCallback, useEffect, useMemo, useRef, useState } from "react";
|
|
10
10
|
import { Notifications, notifications } from "@mantine/notifications";
|
|
11
|
-
import { IconAlertTriangle, IconArrowDown, IconArrowLeft, IconArrowUp, IconArrowsSort, IconAt, IconCalendar, IconCheck, IconChevronDown, IconChevronRight, IconClipboard, IconClock, IconColorPicker, IconColumns, IconCopy, IconDownload, IconFile, IconFilter, IconGripVertical, IconHash, IconInfoCircle, IconInfoTriangle, IconKey, IconLanguage, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightCollapse, IconLetterCase, IconLink, IconList, IconMail, IconMoon, IconPalette, IconPhone, IconPlus, IconRefresh, IconSearch, IconSelector, IconSquareRounded, IconSun, IconToggleLeft, IconTrash, IconX } from "@tabler/icons-react";
|
|
11
|
+
import { IconAlertTriangle, IconArrowDown, IconArrowLeft, IconArrowUp, IconArrowsSort, IconAt, IconCalendar, IconCheck, IconChevronDown, IconChevronRight, IconClipboard, IconClock, IconColorPicker, IconColumns, IconCopy, IconDotsVertical, IconDownload, IconFile, IconFilter, IconGripVertical, IconHash, IconInfoCircle, IconInfoTriangle, IconKey, IconLanguage, IconLayoutSidebarLeftCollapse, IconLayoutSidebarRightCollapse, IconLetterCase, IconLink, IconList, IconMail, IconMoon, IconPalette, IconPhone, IconPlus, IconRefresh, IconSearch, IconSelector, IconSquareRounded, IconSun, IconToggleLeft, IconTrash, IconX } from "@tabler/icons-react";
|
|
12
12
|
import { $page, Link, NestedView, useActive, useRouter, useRouterState } from "alepha/react/router";
|
|
13
13
|
import { NavigationProgress, nprogress } from "@mantine/nprogress";
|
|
14
14
|
import { ClientOnly, useAction, useAlepha, useEvents, useInject, useStore } from "alepha/react";
|
|
@@ -32,7 +32,7 @@ const alephaSidebarAtom = $atom({
|
|
|
32
32
|
closed: true,
|
|
33
33
|
collapsed: false,
|
|
34
34
|
expandedWidth: 300,
|
|
35
|
-
collapsedWidth:
|
|
35
|
+
collapsedWidth: 72
|
|
36
36
|
}
|
|
37
37
|
});
|
|
38
38
|
|
|
@@ -44,6 +44,20 @@ const alephaThemeAtom = $atom({
|
|
|
44
44
|
default: { index: 0 }
|
|
45
45
|
});
|
|
46
46
|
|
|
47
|
+
//#endregion
|
|
48
|
+
//#region ../../src/core/atoms/alephaThemeOverridesAtom.ts
|
|
49
|
+
const alephaThemeOverridesAtom = $atom({
|
|
50
|
+
name: "alepha.ui.themeOverrides",
|
|
51
|
+
schema: t.object({
|
|
52
|
+
primaryColor: t.optional(t.text()),
|
|
53
|
+
radius: t.optional(t.text()),
|
|
54
|
+
fontFamily: t.optional(t.text()),
|
|
55
|
+
fontSize: t.optional(t.text()),
|
|
56
|
+
scale: t.optional(t.text())
|
|
57
|
+
}),
|
|
58
|
+
default: {}
|
|
59
|
+
});
|
|
60
|
+
|
|
47
61
|
//#endregion
|
|
48
62
|
//#region ../../src/core/atoms/themes/default.ts
|
|
49
63
|
const defaultTheme = {
|
|
@@ -51,6 +65,161 @@ const defaultTheme = {
|
|
|
51
65
|
description: "Default Alepha Theme"
|
|
52
66
|
};
|
|
53
67
|
|
|
68
|
+
//#endregion
|
|
69
|
+
//#region ../../src/core/atoms/themes/editorial.ts
|
|
70
|
+
/**
|
|
71
|
+
* Editorial theme.
|
|
72
|
+
*
|
|
73
|
+
* Serif typography, high contrast black and white, thin borders, generous whitespace.
|
|
74
|
+
* Newspaper/magazine aesthetic — elegant restraint.
|
|
75
|
+
*/
|
|
76
|
+
const editorialTheme = {
|
|
77
|
+
name: "Editorial",
|
|
78
|
+
description: "Serif typography with newspaper elegance",
|
|
79
|
+
defaultColorScheme: "light",
|
|
80
|
+
head: { link: [
|
|
81
|
+
{
|
|
82
|
+
rel: "preconnect",
|
|
83
|
+
href: "https://fonts.googleapis.com"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
rel: "preconnect",
|
|
87
|
+
href: "https://fonts.gstatic.com",
|
|
88
|
+
crossorigin: ""
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
rel: "stylesheet",
|
|
92
|
+
href: "https://fonts.googleapis.com/css2?family=Playfair+Display:wght@400;600;700;800&family=Source+Serif+4:ital,wght@0,300;0,400;0,600;1,300;1,400&display=swap"
|
|
93
|
+
}
|
|
94
|
+
] },
|
|
95
|
+
primaryColor: "ink",
|
|
96
|
+
primaryShade: {
|
|
97
|
+
light: 7,
|
|
98
|
+
dark: 3
|
|
99
|
+
},
|
|
100
|
+
autoContrast: true,
|
|
101
|
+
fontFamily: "\"Source Serif 4\", \"Georgia\", \"Times New Roman\", serif",
|
|
102
|
+
fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
|
|
103
|
+
headings: {
|
|
104
|
+
fontFamily: "\"Playfair Display\", \"Georgia\", \"Times New Roman\", serif",
|
|
105
|
+
fontWeight: "700",
|
|
106
|
+
textWrap: "wrap",
|
|
107
|
+
sizes: {
|
|
108
|
+
h1: {
|
|
109
|
+
fontSize: "2.5rem",
|
|
110
|
+
lineHeight: "1.15"
|
|
111
|
+
},
|
|
112
|
+
h2: {
|
|
113
|
+
fontSize: "1.75rem",
|
|
114
|
+
lineHeight: "1.2"
|
|
115
|
+
},
|
|
116
|
+
h3: {
|
|
117
|
+
fontSize: "1.375rem",
|
|
118
|
+
lineHeight: "1.3"
|
|
119
|
+
},
|
|
120
|
+
h4: {
|
|
121
|
+
fontSize: "1.125rem",
|
|
122
|
+
lineHeight: "1.4"
|
|
123
|
+
},
|
|
124
|
+
h5: {
|
|
125
|
+
fontSize: "1rem",
|
|
126
|
+
lineHeight: "1.5"
|
|
127
|
+
},
|
|
128
|
+
h6: {
|
|
129
|
+
fontSize: "0.875rem",
|
|
130
|
+
lineHeight: "1.5"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
defaultRadius: "sm",
|
|
135
|
+
radius: {
|
|
136
|
+
xs: "2px",
|
|
137
|
+
sm: "3px",
|
|
138
|
+
md: "4px",
|
|
139
|
+
lg: "6px",
|
|
140
|
+
xl: "8px"
|
|
141
|
+
},
|
|
142
|
+
shadows: {
|
|
143
|
+
xs: "0 1px 2px rgba(0, 0, 0, 0.06)",
|
|
144
|
+
sm: "0 1px 3px rgba(0, 0, 0, 0.08)",
|
|
145
|
+
md: "0 2px 6px rgba(0, 0, 0, 0.08)",
|
|
146
|
+
lg: "0 4px 12px rgba(0, 0, 0, 0.1)",
|
|
147
|
+
xl: "0 8px 24px rgba(0, 0, 0, 0.1)"
|
|
148
|
+
},
|
|
149
|
+
colors: {
|
|
150
|
+
ink: [
|
|
151
|
+
"#f5f3f0",
|
|
152
|
+
"#e8e4de",
|
|
153
|
+
"#d4cec5",
|
|
154
|
+
"#b5ad9f",
|
|
155
|
+
"#8c8272",
|
|
156
|
+
"#6b6050",
|
|
157
|
+
"#4a4035",
|
|
158
|
+
"#332b22",
|
|
159
|
+
"#1f1812",
|
|
160
|
+
"#0d0a07"
|
|
161
|
+
],
|
|
162
|
+
burgundy: [
|
|
163
|
+
"#faf0f0",
|
|
164
|
+
"#f0d4d4",
|
|
165
|
+
"#e0adad",
|
|
166
|
+
"#cc8585",
|
|
167
|
+
"#b35e5e",
|
|
168
|
+
"#944545",
|
|
169
|
+
"#763636",
|
|
170
|
+
"#5a2828",
|
|
171
|
+
"#3d1b1b",
|
|
172
|
+
"#220f0f"
|
|
173
|
+
],
|
|
174
|
+
gray: [
|
|
175
|
+
"#faf9f7",
|
|
176
|
+
"#f0eee9",
|
|
177
|
+
"#e0dcd5",
|
|
178
|
+
"#c8c2b8",
|
|
179
|
+
"#a8a194",
|
|
180
|
+
"#8a8273",
|
|
181
|
+
"#6b6456",
|
|
182
|
+
"#504a3f",
|
|
183
|
+
"#36322b",
|
|
184
|
+
"#1e1b17"
|
|
185
|
+
],
|
|
186
|
+
dark: [
|
|
187
|
+
"#d5d2cd",
|
|
188
|
+
"#aba59c",
|
|
189
|
+
"#817a6e",
|
|
190
|
+
"#5e584e",
|
|
191
|
+
"#46413a",
|
|
192
|
+
"#36322c",
|
|
193
|
+
"#2a2721",
|
|
194
|
+
"#201d19",
|
|
195
|
+
"#171411",
|
|
196
|
+
"#0d0b09"
|
|
197
|
+
]
|
|
198
|
+
},
|
|
199
|
+
components: {
|
|
200
|
+
Button: Button.extend({
|
|
201
|
+
defaultProps: { fw: 600 },
|
|
202
|
+
styles: { root: { letterSpacing: "0.02em" } }
|
|
203
|
+
}),
|
|
204
|
+
ActionIcon: ActionIcon.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
|
|
205
|
+
Paper: Paper.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
|
|
206
|
+
Card: Card.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
|
|
207
|
+
TextInput: TextInput.extend({ styles: { input: { border: "1px solid var(--mantine-color-default-border)" } } }),
|
|
208
|
+
Badge: Badge.extend({
|
|
209
|
+
defaultProps: {
|
|
210
|
+
fw: 600,
|
|
211
|
+
variant: "outline"
|
|
212
|
+
},
|
|
213
|
+
styles: { root: {
|
|
214
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", sans-serif",
|
|
215
|
+
letterSpacing: "0.04em",
|
|
216
|
+
textTransform: "uppercase",
|
|
217
|
+
fontSize: "0.65rem"
|
|
218
|
+
} }
|
|
219
|
+
})
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
54
223
|
//#endregion
|
|
55
224
|
//#region ../../src/core/atoms/themes/midnight.ts
|
|
56
225
|
const midnightTheme = {
|
|
@@ -166,41 +335,793 @@ const midnightTheme = {
|
|
|
166
335
|
}
|
|
167
336
|
};
|
|
168
337
|
|
|
338
|
+
//#endregion
|
|
339
|
+
//#region ../../src/core/atoms/themes/monochrome.ts
|
|
340
|
+
/**
|
|
341
|
+
* Monochrome theme.
|
|
342
|
+
*
|
|
343
|
+
* Pure black and white. No color. Bold typography does all the heavy lifting.
|
|
344
|
+
* A design-school statement piece — minimalist color, maximalist type.
|
|
345
|
+
*/
|
|
346
|
+
const monochromeTheme = {
|
|
347
|
+
name: "Monochrome",
|
|
348
|
+
description: "Pure black and white — zero color, maximum typography",
|
|
349
|
+
primaryColor: "mono",
|
|
350
|
+
primaryShade: {
|
|
351
|
+
light: 8,
|
|
352
|
+
dark: 1
|
|
353
|
+
},
|
|
354
|
+
autoContrast: true,
|
|
355
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
|
|
356
|
+
fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
|
|
357
|
+
headings: {
|
|
358
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
|
|
359
|
+
fontWeight: "800",
|
|
360
|
+
textWrap: "wrap",
|
|
361
|
+
sizes: {
|
|
362
|
+
h1: {
|
|
363
|
+
fontSize: "2.25rem",
|
|
364
|
+
lineHeight: "1.15"
|
|
365
|
+
},
|
|
366
|
+
h2: {
|
|
367
|
+
fontSize: "1.625rem",
|
|
368
|
+
lineHeight: "1.25"
|
|
369
|
+
},
|
|
370
|
+
h3: {
|
|
371
|
+
fontSize: "1.25rem",
|
|
372
|
+
lineHeight: "1.35"
|
|
373
|
+
},
|
|
374
|
+
h4: {
|
|
375
|
+
fontSize: "1.0625rem",
|
|
376
|
+
lineHeight: "1.45"
|
|
377
|
+
},
|
|
378
|
+
h5: {
|
|
379
|
+
fontSize: "0.9375rem",
|
|
380
|
+
lineHeight: "1.5"
|
|
381
|
+
},
|
|
382
|
+
h6: {
|
|
383
|
+
fontSize: "0.8125rem",
|
|
384
|
+
lineHeight: "1.5"
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
},
|
|
388
|
+
defaultRadius: "0",
|
|
389
|
+
radius: {
|
|
390
|
+
xs: "0",
|
|
391
|
+
sm: "0",
|
|
392
|
+
md: "0",
|
|
393
|
+
lg: "0",
|
|
394
|
+
xl: "2px"
|
|
395
|
+
},
|
|
396
|
+
shadows: {
|
|
397
|
+
xs: "0 1px 2px rgba(0, 0, 0, 0.08)",
|
|
398
|
+
sm: "0 1px 4px rgba(0, 0, 0, 0.1)",
|
|
399
|
+
md: "0 2px 8px rgba(0, 0, 0, 0.12)",
|
|
400
|
+
lg: "0 4px 16px rgba(0, 0, 0, 0.14)",
|
|
401
|
+
xl: "0 8px 32px rgba(0, 0, 0, 0.16)"
|
|
402
|
+
},
|
|
403
|
+
colors: {
|
|
404
|
+
mono: [
|
|
405
|
+
"#f5f5f5",
|
|
406
|
+
"#e0e0e0",
|
|
407
|
+
"#c0c0c0",
|
|
408
|
+
"#a0a0a0",
|
|
409
|
+
"#808080",
|
|
410
|
+
"#606060",
|
|
411
|
+
"#404040",
|
|
412
|
+
"#282828",
|
|
413
|
+
"#141414",
|
|
414
|
+
"#000000"
|
|
415
|
+
],
|
|
416
|
+
gray: [
|
|
417
|
+
"#f5f5f5",
|
|
418
|
+
"#e5e5e5",
|
|
419
|
+
"#cccccc",
|
|
420
|
+
"#b0b0b0",
|
|
421
|
+
"#909090",
|
|
422
|
+
"#707070",
|
|
423
|
+
"#555555",
|
|
424
|
+
"#3a3a3a",
|
|
425
|
+
"#252525",
|
|
426
|
+
"#121212"
|
|
427
|
+
],
|
|
428
|
+
blue: [
|
|
429
|
+
"#f5f5f5",
|
|
430
|
+
"#e0e0e0",
|
|
431
|
+
"#c0c0c0",
|
|
432
|
+
"#a0a0a0",
|
|
433
|
+
"#808080",
|
|
434
|
+
"#606060",
|
|
435
|
+
"#404040",
|
|
436
|
+
"#282828",
|
|
437
|
+
"#141414",
|
|
438
|
+
"#000000"
|
|
439
|
+
],
|
|
440
|
+
green: [
|
|
441
|
+
"#f5f5f5",
|
|
442
|
+
"#e0e0e0",
|
|
443
|
+
"#c0c0c0",
|
|
444
|
+
"#a0a0a0",
|
|
445
|
+
"#808080",
|
|
446
|
+
"#606060",
|
|
447
|
+
"#404040",
|
|
448
|
+
"#282828",
|
|
449
|
+
"#141414",
|
|
450
|
+
"#000000"
|
|
451
|
+
],
|
|
452
|
+
red: [
|
|
453
|
+
"#f5f5f5",
|
|
454
|
+
"#e0e0e0",
|
|
455
|
+
"#c0c0c0",
|
|
456
|
+
"#a0a0a0",
|
|
457
|
+
"#808080",
|
|
458
|
+
"#606060",
|
|
459
|
+
"#404040",
|
|
460
|
+
"#282828",
|
|
461
|
+
"#141414",
|
|
462
|
+
"#000000"
|
|
463
|
+
],
|
|
464
|
+
dark: [
|
|
465
|
+
"#d0d0d0",
|
|
466
|
+
"#a0a0a0",
|
|
467
|
+
"#707070",
|
|
468
|
+
"#505050",
|
|
469
|
+
"#383838",
|
|
470
|
+
"#282828",
|
|
471
|
+
"#1c1c1c",
|
|
472
|
+
"#141414",
|
|
473
|
+
"#0a0a0a",
|
|
474
|
+
"#000000"
|
|
475
|
+
]
|
|
476
|
+
},
|
|
477
|
+
components: {
|
|
478
|
+
Button: Button.extend({
|
|
479
|
+
defaultProps: { fw: 700 },
|
|
480
|
+
styles: { root: {
|
|
481
|
+
border: "2px solid currentColor",
|
|
482
|
+
letterSpacing: "0.03em",
|
|
483
|
+
textTransform: "uppercase",
|
|
484
|
+
fontSize: "0.8125rem"
|
|
485
|
+
} }
|
|
486
|
+
}),
|
|
487
|
+
ActionIcon: ActionIcon.extend({ styles: { root: { border: "2px solid currentColor" } } }),
|
|
488
|
+
Paper: Paper.extend({ styles: { root: { border: "2px solid var(--mantine-color-default-border)" } } }),
|
|
489
|
+
Card: Card.extend({ styles: { root: { border: "2px solid var(--mantine-color-default-border)" } } }),
|
|
490
|
+
TextInput: TextInput.extend({ styles: { input: { border: "2px solid var(--mantine-color-default-border)" } } }),
|
|
491
|
+
Badge: Badge.extend({
|
|
492
|
+
defaultProps: {
|
|
493
|
+
fw: 700,
|
|
494
|
+
variant: "outline"
|
|
495
|
+
},
|
|
496
|
+
styles: { root: {
|
|
497
|
+
textTransform: "uppercase",
|
|
498
|
+
letterSpacing: "0.06em",
|
|
499
|
+
fontSize: "0.65rem",
|
|
500
|
+
border: "2px solid currentColor"
|
|
501
|
+
} }
|
|
502
|
+
})
|
|
503
|
+
}
|
|
504
|
+
};
|
|
505
|
+
|
|
506
|
+
//#endregion
|
|
507
|
+
//#region ../../src/core/atoms/themes/rosePine.ts
|
|
508
|
+
/**
|
|
509
|
+
* Rosé Pine theme.
|
|
510
|
+
*
|
|
511
|
+
* Muted pinks, golds, and subtle greens on warm dark backgrounds.
|
|
512
|
+
* Cozy, low-contrast, easy on the eyes.
|
|
513
|
+
* Based on the Rosé Pine color philosophy.
|
|
514
|
+
*/
|
|
515
|
+
const rosePineTheme = {
|
|
516
|
+
name: "Rosé Pine",
|
|
517
|
+
description: "Muted pinks and golds on warm dark backgrounds",
|
|
518
|
+
defaultColorScheme: "dark",
|
|
519
|
+
primaryColor: "rose",
|
|
520
|
+
primaryShade: {
|
|
521
|
+
light: 5,
|
|
522
|
+
dark: 4
|
|
523
|
+
},
|
|
524
|
+
autoContrast: true,
|
|
525
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
|
|
526
|
+
fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
|
|
527
|
+
headings: {
|
|
528
|
+
fontFamily: "-apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
|
|
529
|
+
fontWeight: "600",
|
|
530
|
+
textWrap: "wrap",
|
|
531
|
+
sizes: {
|
|
532
|
+
h1: {
|
|
533
|
+
fontSize: "2rem",
|
|
534
|
+
lineHeight: "1.25"
|
|
535
|
+
},
|
|
536
|
+
h2: {
|
|
537
|
+
fontSize: "1.5rem",
|
|
538
|
+
lineHeight: "1.3"
|
|
539
|
+
},
|
|
540
|
+
h3: {
|
|
541
|
+
fontSize: "1.25rem",
|
|
542
|
+
lineHeight: "1.4"
|
|
543
|
+
},
|
|
544
|
+
h4: {
|
|
545
|
+
fontSize: "1rem",
|
|
546
|
+
lineHeight: "1.5"
|
|
547
|
+
},
|
|
548
|
+
h5: {
|
|
549
|
+
fontSize: "0.875rem",
|
|
550
|
+
lineHeight: "1.5"
|
|
551
|
+
},
|
|
552
|
+
h6: {
|
|
553
|
+
fontSize: "0.75rem",
|
|
554
|
+
lineHeight: "1.5"
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
},
|
|
558
|
+
defaultRadius: "md",
|
|
559
|
+
radius: {
|
|
560
|
+
xs: "4px",
|
|
561
|
+
sm: "6px",
|
|
562
|
+
md: "8px",
|
|
563
|
+
lg: "12px",
|
|
564
|
+
xl: "16px"
|
|
565
|
+
},
|
|
566
|
+
shadows: {
|
|
567
|
+
xs: "0 1px 3px rgba(0, 0, 0, 0.2)",
|
|
568
|
+
sm: "0 2px 6px rgba(0, 0, 0, 0.2)",
|
|
569
|
+
md: "0 4px 12px rgba(0, 0, 0, 0.25)",
|
|
570
|
+
lg: "0 8px 24px rgba(0, 0, 0, 0.3)",
|
|
571
|
+
xl: "0 12px 36px rgba(0, 0, 0, 0.35)"
|
|
572
|
+
},
|
|
573
|
+
colors: {
|
|
574
|
+
rose: [
|
|
575
|
+
"#faf0f4",
|
|
576
|
+
"#f2d8e3",
|
|
577
|
+
"#eabdd0",
|
|
578
|
+
"#e0a0bb",
|
|
579
|
+
"#d4849f",
|
|
580
|
+
"#c4748f",
|
|
581
|
+
"#b06282",
|
|
582
|
+
"#9a5275",
|
|
583
|
+
"#7a3f5e",
|
|
584
|
+
"#5c2e47"
|
|
585
|
+
],
|
|
586
|
+
gold: [
|
|
587
|
+
"#fdf8ec",
|
|
588
|
+
"#f8ecc8",
|
|
589
|
+
"#f2dda0",
|
|
590
|
+
"#eacb72",
|
|
591
|
+
"#e0b94d",
|
|
592
|
+
"#c9a33e",
|
|
593
|
+
"#a98830",
|
|
594
|
+
"#866b24",
|
|
595
|
+
"#634f1a",
|
|
596
|
+
"#403310"
|
|
597
|
+
],
|
|
598
|
+
pine: [
|
|
599
|
+
"#ecf5f0",
|
|
600
|
+
"#d0e6da",
|
|
601
|
+
"#add4be",
|
|
602
|
+
"#86c0a0",
|
|
603
|
+
"#62ac84",
|
|
604
|
+
"#4e9670",
|
|
605
|
+
"#3e7a5a",
|
|
606
|
+
"#2f5e44",
|
|
607
|
+
"#20412f",
|
|
608
|
+
"#12251b"
|
|
609
|
+
],
|
|
610
|
+
foam: [
|
|
611
|
+
"#edf6f7",
|
|
612
|
+
"#d2e9eb",
|
|
613
|
+
"#b0d9dd",
|
|
614
|
+
"#8bc6cc",
|
|
615
|
+
"#6ab3bb",
|
|
616
|
+
"#569da5",
|
|
617
|
+
"#438088",
|
|
618
|
+
"#33636a",
|
|
619
|
+
"#23454a",
|
|
620
|
+
"#14292c"
|
|
621
|
+
],
|
|
622
|
+
red: [
|
|
623
|
+
"#f9eef0",
|
|
624
|
+
"#efd3d8",
|
|
625
|
+
"#e3b2bb",
|
|
626
|
+
"#d68e9b",
|
|
627
|
+
"#c86c7c",
|
|
628
|
+
"#b25566",
|
|
629
|
+
"#944454",
|
|
630
|
+
"#733442",
|
|
631
|
+
"#52252f",
|
|
632
|
+
"#33161d"
|
|
633
|
+
],
|
|
634
|
+
gray: [
|
|
635
|
+
"#f4f0f2",
|
|
636
|
+
"#e4dde1",
|
|
637
|
+
"#cec5cb",
|
|
638
|
+
"#b5aab2",
|
|
639
|
+
"#9a8e96",
|
|
640
|
+
"#7e737a",
|
|
641
|
+
"#635a60",
|
|
642
|
+
"#4a4248",
|
|
643
|
+
"#332d31",
|
|
644
|
+
"#1e1a1c"
|
|
645
|
+
],
|
|
646
|
+
dark: [
|
|
647
|
+
"#e0d8e0",
|
|
648
|
+
"#b0a6b2",
|
|
649
|
+
"#817786",
|
|
650
|
+
"#615768",
|
|
651
|
+
"#4a3f54",
|
|
652
|
+
"#3a3044",
|
|
653
|
+
"#2a2436",
|
|
654
|
+
"#211e2e",
|
|
655
|
+
"#1a1724",
|
|
656
|
+
"#110f1a"
|
|
657
|
+
]
|
|
658
|
+
},
|
|
659
|
+
components: {
|
|
660
|
+
Button: Button.extend({
|
|
661
|
+
defaultProps: { fw: 500 },
|
|
662
|
+
styles: { root: { transition: "background-color 0.15s ease, opacity 0.15s ease" } }
|
|
663
|
+
}),
|
|
664
|
+
ActionIcon: ActionIcon.extend({ styles: { root: { transition: "background-color 0.15s ease, opacity 0.15s ease" } } }),
|
|
665
|
+
Paper: Paper.extend({
|
|
666
|
+
defaultProps: { shadow: "sm" },
|
|
667
|
+
styles: { root: { border: "1px solid var(--mantine-color-default-border)" } }
|
|
668
|
+
}),
|
|
669
|
+
Card: Card.extend({
|
|
670
|
+
defaultProps: { shadow: "sm" },
|
|
671
|
+
styles: { root: { border: "1px solid var(--mantine-color-default-border)" } }
|
|
672
|
+
}),
|
|
673
|
+
TextInput: TextInput.extend({ styles: { input: { border: "1px solid var(--mantine-color-default-border)" } } }),
|
|
674
|
+
Badge: Badge.extend({ defaultProps: { fw: 500 } })
|
|
675
|
+
}
|
|
676
|
+
};
|
|
677
|
+
|
|
678
|
+
//#endregion
|
|
679
|
+
//#region ../../src/core/atoms/themes/softBrutalism.ts
|
|
680
|
+
/**
|
|
681
|
+
* Soft Brutalism theme.
|
|
682
|
+
*
|
|
683
|
+
* Pastel pop palette with solid offset shadows, rounded corners, and bold borders.
|
|
684
|
+
* A friendlier take on neubrutalism — playful but production-ready.
|
|
685
|
+
*/
|
|
686
|
+
const softBrutalismTheme = {
|
|
687
|
+
name: "Soft Brutalism",
|
|
688
|
+
description: "Pastel pop with bold borders and offset shadows",
|
|
689
|
+
head: { link: [
|
|
690
|
+
{
|
|
691
|
+
rel: "preconnect",
|
|
692
|
+
href: "https://fonts.googleapis.com"
|
|
693
|
+
},
|
|
694
|
+
{
|
|
695
|
+
rel: "preconnect",
|
|
696
|
+
href: "https://fonts.gstatic.com",
|
|
697
|
+
crossorigin: ""
|
|
698
|
+
},
|
|
699
|
+
{
|
|
700
|
+
rel: "stylesheet",
|
|
701
|
+
href: "https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap"
|
|
702
|
+
}
|
|
703
|
+
] },
|
|
704
|
+
primaryColor: "lavender",
|
|
705
|
+
primaryShade: {
|
|
706
|
+
light: 5,
|
|
707
|
+
dark: 7
|
|
708
|
+
},
|
|
709
|
+
autoContrast: true,
|
|
710
|
+
cursorType: "pointer",
|
|
711
|
+
fontFamily: "Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
|
|
712
|
+
fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
|
|
713
|
+
headings: {
|
|
714
|
+
fontFamily: "Inter, -apple-system, BlinkMacSystemFont, \"Segoe UI\", \"Noto Sans\", Helvetica, Arial, sans-serif",
|
|
715
|
+
fontWeight: "700",
|
|
716
|
+
textWrap: "wrap",
|
|
717
|
+
sizes: {
|
|
718
|
+
h1: {
|
|
719
|
+
fontSize: "2rem",
|
|
720
|
+
lineHeight: "1.25"
|
|
721
|
+
},
|
|
722
|
+
h2: {
|
|
723
|
+
fontSize: "1.5rem",
|
|
724
|
+
lineHeight: "1.3"
|
|
725
|
+
},
|
|
726
|
+
h3: {
|
|
727
|
+
fontSize: "1.25rem",
|
|
728
|
+
lineHeight: "1.4"
|
|
729
|
+
},
|
|
730
|
+
h4: {
|
|
731
|
+
fontSize: "1rem",
|
|
732
|
+
lineHeight: "1.5"
|
|
733
|
+
},
|
|
734
|
+
h5: {
|
|
735
|
+
fontSize: "0.875rem",
|
|
736
|
+
lineHeight: "1.5"
|
|
737
|
+
},
|
|
738
|
+
h6: {
|
|
739
|
+
fontSize: "0.75rem",
|
|
740
|
+
lineHeight: "1.5"
|
|
741
|
+
}
|
|
742
|
+
}
|
|
743
|
+
},
|
|
744
|
+
defaultRadius: "md",
|
|
745
|
+
radius: {
|
|
746
|
+
xs: "6px",
|
|
747
|
+
sm: "8px",
|
|
748
|
+
md: "12px",
|
|
749
|
+
lg: "16px",
|
|
750
|
+
xl: "24px"
|
|
751
|
+
},
|
|
752
|
+
shadows: {
|
|
753
|
+
xs: "2px 2px 0 0 rgba(100, 80, 140, 0.15)",
|
|
754
|
+
sm: "3px 3px 0 0 rgba(100, 80, 140, 0.2)",
|
|
755
|
+
md: "4px 4px 0 0 rgba(100, 80, 140, 0.2)",
|
|
756
|
+
lg: "6px 6px 0 0 rgba(100, 80, 140, 0.25)",
|
|
757
|
+
xl: "8px 8px 0 0 rgba(100, 80, 140, 0.3)"
|
|
758
|
+
},
|
|
759
|
+
colors: {
|
|
760
|
+
lavender: [
|
|
761
|
+
"#f3f0fa",
|
|
762
|
+
"#e4dcf4",
|
|
763
|
+
"#d1c4e9",
|
|
764
|
+
"#b4a7d6",
|
|
765
|
+
"#9a8bc4",
|
|
766
|
+
"#7f6cb0",
|
|
767
|
+
"#6a549e",
|
|
768
|
+
"#543f87",
|
|
769
|
+
"#3d2d6b",
|
|
770
|
+
"#2a1d52"
|
|
771
|
+
],
|
|
772
|
+
peach: [
|
|
773
|
+
"#fef3ec",
|
|
774
|
+
"#fce4d0",
|
|
775
|
+
"#f9d0ae",
|
|
776
|
+
"#f4b886",
|
|
777
|
+
"#f4a261",
|
|
778
|
+
"#e68a42",
|
|
779
|
+
"#c67234",
|
|
780
|
+
"#a35a28",
|
|
781
|
+
"#6b3a1a",
|
|
782
|
+
"#4a2710"
|
|
783
|
+
],
|
|
784
|
+
mint: [
|
|
785
|
+
"#ecfaf0",
|
|
786
|
+
"#d4f2dc",
|
|
787
|
+
"#b3e8c2",
|
|
788
|
+
"#8edba4",
|
|
789
|
+
"#81c995",
|
|
790
|
+
"#5ab874",
|
|
791
|
+
"#42a05c",
|
|
792
|
+
"#2e8548",
|
|
793
|
+
"#1a5c2e",
|
|
794
|
+
"#0f3f1e"
|
|
795
|
+
],
|
|
796
|
+
coral: [
|
|
797
|
+
"#fef0ef",
|
|
798
|
+
"#fcd9d7",
|
|
799
|
+
"#f8b8b4",
|
|
800
|
+
"#f29490",
|
|
801
|
+
"#e97171",
|
|
802
|
+
"#d65454",
|
|
803
|
+
"#b83e3e",
|
|
804
|
+
"#962d2d",
|
|
805
|
+
"#6b1f1f",
|
|
806
|
+
"#4a1414"
|
|
807
|
+
],
|
|
808
|
+
gray: [
|
|
809
|
+
"#faf8f6",
|
|
810
|
+
"#f0ece8",
|
|
811
|
+
"#ddd7d0",
|
|
812
|
+
"#c4bbb2",
|
|
813
|
+
"#a89e95",
|
|
814
|
+
"#8c8279",
|
|
815
|
+
"#6e655d",
|
|
816
|
+
"#524b44",
|
|
817
|
+
"#3a342f",
|
|
818
|
+
"#24211e"
|
|
819
|
+
],
|
|
820
|
+
dark: [
|
|
821
|
+
"#d4d0dc",
|
|
822
|
+
"#a9a2b5",
|
|
823
|
+
"#7e7690",
|
|
824
|
+
"#5c546e",
|
|
825
|
+
"#443c56",
|
|
826
|
+
"#342d45",
|
|
827
|
+
"#2a2339",
|
|
828
|
+
"#1e1a2e",
|
|
829
|
+
"#161224",
|
|
830
|
+
"#0f0c1a"
|
|
831
|
+
]
|
|
832
|
+
},
|
|
833
|
+
components: {
|
|
834
|
+
Button: Button.extend({
|
|
835
|
+
defaultProps: { fw: 600 },
|
|
836
|
+
styles: { root: {
|
|
837
|
+
border: "2px solid currentColor",
|
|
838
|
+
boxShadow: "3px 3px 0 0 rgba(100, 80, 140, 0.2)",
|
|
839
|
+
transition: "box-shadow 0.15s ease, transform 0.15s ease"
|
|
840
|
+
} }
|
|
841
|
+
}),
|
|
842
|
+
ActionIcon: ActionIcon.extend({ styles: { root: {
|
|
843
|
+
border: "2px solid currentColor",
|
|
844
|
+
boxShadow: "2px 2px 0 0 rgba(100, 80, 140, 0.15)"
|
|
845
|
+
} } }),
|
|
846
|
+
Paper: Paper.extend({
|
|
847
|
+
defaultProps: { shadow: "sm" },
|
|
848
|
+
styles: { root: { border: "2px solid var(--mantine-color-default-border)" } }
|
|
849
|
+
}),
|
|
850
|
+
Card: Card.extend({
|
|
851
|
+
defaultProps: { shadow: "sm" },
|
|
852
|
+
styles: { root: { border: "2px solid var(--mantine-color-default-border)" } }
|
|
853
|
+
}),
|
|
854
|
+
TextInput: TextInput.extend({ styles: { input: {
|
|
855
|
+
border: "2px solid var(--mantine-color-default-border)",
|
|
856
|
+
transition: "box-shadow 0.15s ease, border-color 0.15s ease"
|
|
857
|
+
} } }),
|
|
858
|
+
Badge: Badge.extend({
|
|
859
|
+
defaultProps: { fw: 600 },
|
|
860
|
+
styles: { root: { border: "2px solid currentColor" } }
|
|
861
|
+
})
|
|
862
|
+
}
|
|
863
|
+
};
|
|
864
|
+
|
|
865
|
+
//#endregion
|
|
866
|
+
//#region ../../src/core/atoms/themes/terminal.ts
|
|
867
|
+
/**
|
|
868
|
+
* Terminal theme.
|
|
869
|
+
*
|
|
870
|
+
* Monospace everything, green-on-black, zero radius.
|
|
871
|
+
* CRT/hacker aesthetic for developer tools and dashboards.
|
|
872
|
+
*/
|
|
873
|
+
const terminalTheme = {
|
|
874
|
+
name: "Terminal",
|
|
875
|
+
description: "Green phosphor on black — monospace hacker aesthetic",
|
|
876
|
+
defaultColorScheme: "dark",
|
|
877
|
+
primaryColor: "terminal",
|
|
878
|
+
primaryShade: {
|
|
879
|
+
light: 5,
|
|
880
|
+
dark: 4
|
|
881
|
+
},
|
|
882
|
+
autoContrast: true,
|
|
883
|
+
fontFamily: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
|
|
884
|
+
fontFamilyMonospace: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
|
|
885
|
+
headings: {
|
|
886
|
+
fontFamily: "ui-monospace, SFMono-Regular, \"SF Mono\", Menlo, Consolas, \"Liberation Mono\", monospace",
|
|
887
|
+
fontWeight: "700",
|
|
888
|
+
textWrap: "wrap",
|
|
889
|
+
sizes: {
|
|
890
|
+
h1: {
|
|
891
|
+
fontSize: "1.75rem",
|
|
892
|
+
lineHeight: "1.3"
|
|
893
|
+
},
|
|
894
|
+
h2: {
|
|
895
|
+
fontSize: "1.375rem",
|
|
896
|
+
lineHeight: "1.35"
|
|
897
|
+
},
|
|
898
|
+
h3: {
|
|
899
|
+
fontSize: "1.125rem",
|
|
900
|
+
lineHeight: "1.4"
|
|
901
|
+
},
|
|
902
|
+
h4: {
|
|
903
|
+
fontSize: "1rem",
|
|
904
|
+
lineHeight: "1.5"
|
|
905
|
+
},
|
|
906
|
+
h5: {
|
|
907
|
+
fontSize: "0.875rem",
|
|
908
|
+
lineHeight: "1.5"
|
|
909
|
+
},
|
|
910
|
+
h6: {
|
|
911
|
+
fontSize: "0.75rem",
|
|
912
|
+
lineHeight: "1.5"
|
|
913
|
+
}
|
|
914
|
+
}
|
|
915
|
+
},
|
|
916
|
+
defaultRadius: "0",
|
|
917
|
+
radius: {
|
|
918
|
+
xs: "0",
|
|
919
|
+
sm: "0",
|
|
920
|
+
md: "0",
|
|
921
|
+
lg: "2px",
|
|
922
|
+
xl: "4px"
|
|
923
|
+
},
|
|
924
|
+
shadows: {
|
|
925
|
+
xs: "none",
|
|
926
|
+
sm: "none",
|
|
927
|
+
md: "0 0 8px rgba(0, 255, 65, 0.08)",
|
|
928
|
+
lg: "0 0 16px rgba(0, 255, 65, 0.1)",
|
|
929
|
+
xl: "0 0 24px rgba(0, 255, 65, 0.12)"
|
|
930
|
+
},
|
|
931
|
+
colors: {
|
|
932
|
+
terminal: [
|
|
933
|
+
"#e6fff0",
|
|
934
|
+
"#b3ffd1",
|
|
935
|
+
"#80ffb3",
|
|
936
|
+
"#4dff94",
|
|
937
|
+
"#00ff41",
|
|
938
|
+
"#00d636",
|
|
939
|
+
"#00ad2b",
|
|
940
|
+
"#008521",
|
|
941
|
+
"#005c17",
|
|
942
|
+
"#00330d"
|
|
943
|
+
],
|
|
944
|
+
amber: [
|
|
945
|
+
"#fff8e6",
|
|
946
|
+
"#ffecb3",
|
|
947
|
+
"#ffe080",
|
|
948
|
+
"#ffd54d",
|
|
949
|
+
"#ffca28",
|
|
950
|
+
"#d4a520",
|
|
951
|
+
"#aa8418",
|
|
952
|
+
"#806310",
|
|
953
|
+
"#554208",
|
|
954
|
+
"#2b2104"
|
|
955
|
+
],
|
|
956
|
+
red: [
|
|
957
|
+
"#ffe6e6",
|
|
958
|
+
"#ffb3b3",
|
|
959
|
+
"#ff8080",
|
|
960
|
+
"#ff4d4d",
|
|
961
|
+
"#ff1a1a",
|
|
962
|
+
"#d41515",
|
|
963
|
+
"#aa1010",
|
|
964
|
+
"#800c0c",
|
|
965
|
+
"#550808",
|
|
966
|
+
"#2b0404"
|
|
967
|
+
],
|
|
968
|
+
gray: [
|
|
969
|
+
"#e8eaed",
|
|
970
|
+
"#c8cdd3",
|
|
971
|
+
"#a4aab3",
|
|
972
|
+
"#808892",
|
|
973
|
+
"#5f6872",
|
|
974
|
+
"#474f58",
|
|
975
|
+
"#363c44",
|
|
976
|
+
"#282d33",
|
|
977
|
+
"#1c2026",
|
|
978
|
+
"#12151a"
|
|
979
|
+
],
|
|
980
|
+
dark: [
|
|
981
|
+
"#c9cdd2",
|
|
982
|
+
"#8b9198",
|
|
983
|
+
"#5c636b",
|
|
984
|
+
"#3d444c",
|
|
985
|
+
"#2b3138",
|
|
986
|
+
"#1e242b",
|
|
987
|
+
"#151a20",
|
|
988
|
+
"#0e1216",
|
|
989
|
+
"#080c0f",
|
|
990
|
+
"#020303"
|
|
991
|
+
]
|
|
992
|
+
},
|
|
993
|
+
components: {
|
|
994
|
+
Button: Button.extend({
|
|
995
|
+
defaultProps: { fw: 600 },
|
|
996
|
+
styles: { root: {
|
|
997
|
+
border: "1px solid currentColor",
|
|
998
|
+
textTransform: "uppercase",
|
|
999
|
+
letterSpacing: "0.05em",
|
|
1000
|
+
fontSize: "0.8125rem"
|
|
1001
|
+
} }
|
|
1002
|
+
}),
|
|
1003
|
+
ActionIcon: ActionIcon.extend({ styles: { root: { border: "1px solid currentColor" } } }),
|
|
1004
|
+
Paper: Paper.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
|
|
1005
|
+
Card: Card.extend({ styles: { root: { border: "1px solid var(--mantine-color-default-border)" } } }),
|
|
1006
|
+
TextInput: TextInput.extend({ styles: { input: {
|
|
1007
|
+
border: "1px solid var(--mantine-color-default-border)",
|
|
1008
|
+
fontFamily: "inherit"
|
|
1009
|
+
} } }),
|
|
1010
|
+
Badge: Badge.extend({
|
|
1011
|
+
defaultProps: { fw: 600 },
|
|
1012
|
+
styles: { root: {
|
|
1013
|
+
border: "1px solid currentColor",
|
|
1014
|
+
textTransform: "uppercase",
|
|
1015
|
+
letterSpacing: "0.05em"
|
|
1016
|
+
} }
|
|
1017
|
+
})
|
|
1018
|
+
}
|
|
1019
|
+
};
|
|
1020
|
+
|
|
169
1021
|
//#endregion
|
|
170
1022
|
//#region ../../src/core/atoms/alephaThemeListAtom.ts
|
|
171
1023
|
const alephaThemeListAtom = $atom({
|
|
172
1024
|
name: "alepha.ui.themeList",
|
|
173
1025
|
schema: t.array(t.json()),
|
|
174
|
-
default: [
|
|
1026
|
+
default: [
|
|
1027
|
+
defaultTheme,
|
|
1028
|
+
midnightTheme,
|
|
1029
|
+
softBrutalismTheme,
|
|
1030
|
+
terminalTheme,
|
|
1031
|
+
editorialTheme,
|
|
1032
|
+
rosePineTheme,
|
|
1033
|
+
monochromeTheme
|
|
1034
|
+
]
|
|
175
1035
|
});
|
|
176
1036
|
|
|
177
1037
|
//#endregion
|
|
178
1038
|
//#region ../../src/core/providers/ThemeProvider.ts
|
|
179
|
-
var ThemeProvider = class {
|
|
1039
|
+
var ThemeProvider = class ThemeProvider {
|
|
180
1040
|
alepha = $inject(Alepha);
|
|
181
1041
|
cookie = $cookie({
|
|
182
1042
|
name: "theme",
|
|
183
1043
|
schema: alephaThemeAtom.schema,
|
|
184
1044
|
ttl: [1, "year"]
|
|
185
1045
|
});
|
|
1046
|
+
overridesCookie = $cookie({
|
|
1047
|
+
name: "themeOverrides",
|
|
1048
|
+
schema: alephaThemeOverridesAtom.schema,
|
|
1049
|
+
ttl: [1, "year"]
|
|
1050
|
+
});
|
|
186
1051
|
head = $head(() => {
|
|
187
1052
|
const theme = this.getTheme();
|
|
188
1053
|
if (!theme || !theme.name) return {};
|
|
189
|
-
return {
|
|
1054
|
+
return {
|
|
1055
|
+
htmlAttributes: { "data-theme": this.slugify(theme.name) },
|
|
1056
|
+
...theme.head
|
|
1057
|
+
};
|
|
190
1058
|
});
|
|
191
1059
|
setTheme(index) {
|
|
192
|
-
|
|
193
|
-
if (!newTheme) throw new AlephaError(`Theme with index ${index} not found`);
|
|
1060
|
+
if (!this.alepha.store.get(alephaThemeListAtom)[index]) throw new AlephaError(`Theme with index ${index} not found`);
|
|
194
1061
|
this.cookie.set({ index });
|
|
195
1062
|
this.alepha.store.set(alephaThemeAtom, { index });
|
|
196
|
-
if (
|
|
197
|
-
|
|
198
|
-
|
|
1063
|
+
if (!this.alepha.isBrowser()) return;
|
|
1064
|
+
this.alepha.inject(BrowserHeadProvider).refreshGlobalHead();
|
|
1065
|
+
}
|
|
1066
|
+
slugify(name) {
|
|
1067
|
+
return name.toLowerCase().replace(/\s+/g, "-");
|
|
199
1068
|
}
|
|
1069
|
+
static FONT_SIZE_MULTIPLIERS = {
|
|
1070
|
+
xs: .85,
|
|
1071
|
+
sm: .925,
|
|
1072
|
+
md: 1,
|
|
1073
|
+
lg: 1.1,
|
|
1074
|
+
xl: 1.25
|
|
1075
|
+
};
|
|
1076
|
+
static SCALE_VALUES = {
|
|
1077
|
+
xs: .85,
|
|
1078
|
+
sm: .925,
|
|
1079
|
+
md: 1,
|
|
1080
|
+
lg: 1.1,
|
|
1081
|
+
xl: 1.25
|
|
1082
|
+
};
|
|
1083
|
+
static DEFAULT_FONT_SIZES = {
|
|
1084
|
+
xs: "0.75rem",
|
|
1085
|
+
sm: "0.875rem",
|
|
1086
|
+
md: "1rem",
|
|
1087
|
+
lg: "1.125rem",
|
|
1088
|
+
xl: "1.25rem"
|
|
1089
|
+
};
|
|
200
1090
|
getTheme() {
|
|
201
1091
|
const index = this.getThemeIndex();
|
|
202
1092
|
const list = this.alepha.store.get(alephaThemeListAtom);
|
|
203
|
-
|
|
1093
|
+
const base = list[index] || list[0] || defaultTheme;
|
|
1094
|
+
const overrides = this.getThemeOverrides();
|
|
1095
|
+
if (!overrides.primaryColor && !overrides.radius && !overrides.fontFamily && !overrides.fontSize && !overrides.scale) return base;
|
|
1096
|
+
const merged = {
|
|
1097
|
+
...base,
|
|
1098
|
+
...overrides.primaryColor && { primaryColor: overrides.primaryColor },
|
|
1099
|
+
...overrides.radius && { defaultRadius: overrides.radius },
|
|
1100
|
+
...overrides.fontFamily && { fontFamily: overrides.fontFamily },
|
|
1101
|
+
...overrides.scale && overrides.scale !== "md" && { scale: ThemeProvider.SCALE_VALUES[overrides.scale] ?? 1 }
|
|
1102
|
+
};
|
|
1103
|
+
if (overrides.fontSize && overrides.fontSize !== "md") {
|
|
1104
|
+
const multiplier = ThemeProvider.FONT_SIZE_MULTIPLIERS[overrides.fontSize] ?? 1;
|
|
1105
|
+
const baseSizes = base.fontSizes ?? ThemeProvider.DEFAULT_FONT_SIZES;
|
|
1106
|
+
merged.fontSizes = Object.fromEntries(Object.entries(baseSizes).map(([key, val]) => [key, `${(Number.parseFloat(String(val)) * multiplier).toFixed(4)}rem`]));
|
|
1107
|
+
}
|
|
1108
|
+
return merged;
|
|
1109
|
+
}
|
|
1110
|
+
setThemeOverrides(overrides) {
|
|
1111
|
+
this.overridesCookie.set(overrides);
|
|
1112
|
+
this.alepha.store.set(alephaThemeOverridesAtom, overrides);
|
|
1113
|
+
if (!this.alepha.isBrowser()) return;
|
|
1114
|
+
this.alepha.inject(BrowserHeadProvider).refreshGlobalHead();
|
|
1115
|
+
}
|
|
1116
|
+
getThemeOverrides() {
|
|
1117
|
+
try {
|
|
1118
|
+
return this.overridesCookie.get() ?? this.alepha.store.get(alephaThemeOverridesAtom) ?? {};
|
|
1119
|
+
} catch {
|
|
1120
|
+
return this.alepha.store.get(alephaThemeOverridesAtom) ?? {};
|
|
1121
|
+
}
|
|
1122
|
+
}
|
|
1123
|
+
resetThemeOverrides() {
|
|
1124
|
+
this.setThemeOverrides({});
|
|
204
1125
|
}
|
|
205
1126
|
getThemeIndex() {
|
|
206
1127
|
try {
|
|
@@ -307,14 +1228,21 @@ var DialogService = class {
|
|
|
307
1228
|
*/
|
|
308
1229
|
alert(options) {
|
|
309
1230
|
return new Promise((resolve) => {
|
|
1231
|
+
let resolved = false;
|
|
1232
|
+
const done = () => {
|
|
1233
|
+
if (resolved) return;
|
|
1234
|
+
resolved = true;
|
|
1235
|
+
resolve();
|
|
1236
|
+
};
|
|
310
1237
|
const modalId = this.open({
|
|
311
1238
|
...options,
|
|
312
1239
|
title: options?.title || "Alert",
|
|
1240
|
+
onClose: done,
|
|
313
1241
|
content: /* @__PURE__ */ jsx(AlertDialog, {
|
|
314
1242
|
options,
|
|
315
1243
|
onClose: () => {
|
|
316
1244
|
this.close(modalId);
|
|
317
|
-
|
|
1245
|
+
done();
|
|
318
1246
|
}
|
|
319
1247
|
})
|
|
320
1248
|
});
|
|
@@ -325,16 +1253,23 @@ var DialogService = class {
|
|
|
325
1253
|
*/
|
|
326
1254
|
confirm(options) {
|
|
327
1255
|
return new Promise((resolve) => {
|
|
1256
|
+
let resolved = false;
|
|
1257
|
+
const done = (confirmed) => {
|
|
1258
|
+
if (resolved) return;
|
|
1259
|
+
resolved = true;
|
|
1260
|
+
resolve(confirmed);
|
|
1261
|
+
};
|
|
328
1262
|
const modalId = this.open({
|
|
329
1263
|
...options,
|
|
330
1264
|
title: options?.title || "Confirm",
|
|
331
1265
|
closeOnClickOutside: false,
|
|
332
1266
|
closeOnEscape: false,
|
|
1267
|
+
onClose: () => done(false),
|
|
333
1268
|
content: /* @__PURE__ */ jsx(ConfirmDialog, {
|
|
334
1269
|
options,
|
|
335
1270
|
onConfirm: (confirmed) => {
|
|
336
1271
|
this.close(modalId);
|
|
337
|
-
|
|
1272
|
+
done(confirmed);
|
|
338
1273
|
}
|
|
339
1274
|
})
|
|
340
1275
|
});
|
|
@@ -345,16 +1280,23 @@ var DialogService = class {
|
|
|
345
1280
|
*/
|
|
346
1281
|
prompt(options) {
|
|
347
1282
|
return new Promise((resolve) => {
|
|
1283
|
+
let resolved = false;
|
|
1284
|
+
const done = (value) => {
|
|
1285
|
+
if (resolved) return;
|
|
1286
|
+
resolved = true;
|
|
1287
|
+
resolve(value);
|
|
1288
|
+
};
|
|
348
1289
|
const modalId = this.open({
|
|
349
1290
|
...options,
|
|
350
1291
|
title: options?.title || "Input",
|
|
351
1292
|
closeOnClickOutside: false,
|
|
352
1293
|
closeOnEscape: false,
|
|
1294
|
+
onClose: () => done(null),
|
|
353
1295
|
content: /* @__PURE__ */ jsx(PromptDialog, {
|
|
354
1296
|
options,
|
|
355
1297
|
onSubmit: (value) => {
|
|
356
1298
|
this.close(modalId);
|
|
357
|
-
|
|
1299
|
+
done(value);
|
|
358
1300
|
}
|
|
359
1301
|
})
|
|
360
1302
|
});
|
|
@@ -458,20 +1400,34 @@ var UiRouter = class {
|
|
|
458
1400
|
/**
|
|
459
1401
|
* Hook to get and set the current theme.
|
|
460
1402
|
*
|
|
461
|
-
* Returns a tuple with the current theme
|
|
1403
|
+
* Returns a tuple with the current theme, a function to set the theme,
|
|
1404
|
+
* and expert mode controls for fine-grained customization.
|
|
462
1405
|
*
|
|
463
1406
|
* ```tsx
|
|
464
|
-
* const [theme, setTheme] = useTheme();
|
|
1407
|
+
* const [theme, setTheme, expert] = useTheme();
|
|
465
1408
|
* ```
|
|
466
1409
|
*/
|
|
467
1410
|
const useTheme = () => {
|
|
468
1411
|
useStore(alephaThemeAtom);
|
|
1412
|
+
useStore(alephaThemeOverridesAtom);
|
|
469
1413
|
const themeProvider = useInject(ThemeProvider);
|
|
470
1414
|
const theme = themeProvider.getTheme();
|
|
471
1415
|
const setTheme = (theme) => {
|
|
472
1416
|
themeProvider.setTheme(theme.index);
|
|
473
1417
|
};
|
|
474
|
-
return [
|
|
1418
|
+
return [
|
|
1419
|
+
theme,
|
|
1420
|
+
setTheme,
|
|
1421
|
+
{
|
|
1422
|
+
overrides: themeProvider.getThemeOverrides(),
|
|
1423
|
+
setOverrides: (overrides) => {
|
|
1424
|
+
themeProvider.setThemeOverrides(overrides);
|
|
1425
|
+
},
|
|
1426
|
+
resetOverrides: () => {
|
|
1427
|
+
themeProvider.resetThemeOverrides();
|
|
1428
|
+
}
|
|
1429
|
+
}
|
|
1430
|
+
];
|
|
475
1431
|
};
|
|
476
1432
|
|
|
477
1433
|
//#endregion
|
|
@@ -569,16 +1525,16 @@ const AlephaMantineProvider = (props) => {
|
|
|
569
1525
|
const ui = {
|
|
570
1526
|
colors: {
|
|
571
1527
|
transparent: "transparent",
|
|
572
|
-
background: "var(--alepha-
|
|
1528
|
+
background: "var(--alepha-ground)",
|
|
573
1529
|
surface: "var(--alepha-surface)",
|
|
574
1530
|
elevated: "var(--alepha-elevated)",
|
|
575
1531
|
border: "var(--alepha-border)"
|
|
576
1532
|
},
|
|
577
1533
|
sizes: { icon: {
|
|
578
|
-
xs:
|
|
579
|
-
sm:
|
|
580
|
-
md:
|
|
581
|
-
lg:
|
|
1534
|
+
xs: 16,
|
|
1535
|
+
sm: 20,
|
|
1536
|
+
md: 24,
|
|
1537
|
+
lg: 28,
|
|
582
1538
|
xl: 32
|
|
583
1539
|
} }
|
|
584
1540
|
};
|
|
@@ -592,51 +1548,13 @@ function isComponentType(param) {
|
|
|
592
1548
|
|
|
593
1549
|
//#endregion
|
|
594
1550
|
//#region ../../src/core/components/buttons/ActionButton.tsx
|
|
595
|
-
const ActionMenuItem = (props) => {
|
|
596
|
-
const { item, index } = props;
|
|
597
|
-
const router = useRouter();
|
|
598
|
-
const action = useAction({ handler: async (e) => {
|
|
599
|
-
await item.onClick?.();
|
|
600
|
-
} }, [item.onClick]);
|
|
601
|
-
if (item.type === "divider") return /* @__PURE__ */ jsx(Menu.Divider, {}, index);
|
|
602
|
-
if (item.type === "label") return /* @__PURE__ */ jsx(Menu.Label, { children: item.label }, index);
|
|
603
|
-
if (item.children && item.children.length > 0) return /* @__PURE__ */ jsxs(Menu, {
|
|
604
|
-
trigger: "hover",
|
|
605
|
-
position: "right-start",
|
|
606
|
-
offset: 2,
|
|
607
|
-
children: [/* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Menu.Item, {
|
|
608
|
-
leftSection: item.icon,
|
|
609
|
-
rightSection: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }),
|
|
610
|
-
children: item.label
|
|
611
|
-
}) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: item.children.map((child, childIndex) => /* @__PURE__ */ jsx(ActionMenuItem, {
|
|
612
|
-
item: child,
|
|
613
|
-
index: childIndex
|
|
614
|
-
}, childIndex)) })]
|
|
615
|
-
}, index);
|
|
616
|
-
const menuItemProps = {};
|
|
617
|
-
if (props.item.onClick) menuItemProps.onClick = action.run;
|
|
618
|
-
else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
|
|
619
|
-
return /* @__PURE__ */ jsx(Menu.Item, {
|
|
620
|
-
leftSection: item.icon,
|
|
621
|
-
onClick: item.onClick,
|
|
622
|
-
color: item.color,
|
|
623
|
-
rightSection: item.active ? /* @__PURE__ */ jsx(ThemeIcon, {
|
|
624
|
-
size: "xs",
|
|
625
|
-
variant: "transparent",
|
|
626
|
-
children: /* @__PURE__ */ jsx(IconCheck, {})
|
|
627
|
-
}) : void 0,
|
|
628
|
-
...menuItemProps,
|
|
629
|
-
children: item.label
|
|
630
|
-
}, index);
|
|
631
|
-
};
|
|
632
1551
|
const ActionButton = (_props) => {
|
|
633
1552
|
const theme = useMantineTheme();
|
|
634
1553
|
const props = { ..._props };
|
|
635
|
-
|
|
636
|
-
|
|
1554
|
+
if (props.variant === "minimal") {}
|
|
1555
|
+
const { tooltip, menu, icon, iconSize, ...restProps } = props;
|
|
637
1556
|
if (props.intent) {
|
|
638
|
-
if (props.intent === "
|
|
639
|
-
else if (props.intent === "primary") restProps.color ??= theme.primaryColor;
|
|
1557
|
+
if (props.intent === "primary") restProps.color ??= theme.primaryColor;
|
|
640
1558
|
else if (props.intent === "success") {
|
|
641
1559
|
restProps.c ??= "white";
|
|
642
1560
|
restProps.color ??= "green";
|
|
@@ -651,10 +1569,11 @@ const ActionButton = (_props) => {
|
|
|
651
1569
|
}
|
|
652
1570
|
if (props.icon) {
|
|
653
1571
|
const sizes = ui.sizes.icon;
|
|
654
|
-
const
|
|
1572
|
+
const iconSize = props.iconSize ?? sizes[props.size || "sm"];
|
|
1573
|
+
const icon = isComponentType(props.icon) ? /* @__PURE__ */ jsx(props.icon, { size: iconSize }) : /* @__PURE__ */ jsx("span", { children: props.icon });
|
|
655
1574
|
if (!props.children) {
|
|
656
1575
|
restProps.children = Children.only(icon);
|
|
657
|
-
restProps.
|
|
1576
|
+
restProps.p ??= 8;
|
|
658
1577
|
} else restProps.leftSection = icon;
|
|
659
1578
|
}
|
|
660
1579
|
if (props.leftSection && !props.children) restProps.px ??= "xs";
|
|
@@ -677,6 +1596,7 @@ const ActionButton = (_props) => {
|
|
|
677
1596
|
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
678
1597
|
px: "xs",
|
|
679
1598
|
...rest,
|
|
1599
|
+
"aria-label": typeof children === "string" ? children : void 0,
|
|
680
1600
|
tooltip,
|
|
681
1601
|
menu,
|
|
682
1602
|
children: leftSection
|
|
@@ -833,7 +1753,7 @@ const ActionClickButton = ({ preventDefault, ...props }) => {
|
|
|
833
1753
|
* Action for navigation with active state support.
|
|
834
1754
|
*/
|
|
835
1755
|
const ActionNavigationButton = (props) => {
|
|
836
|
-
const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchor, ...buttonProps } = props;
|
|
1756
|
+
const { active: options, classNameActive, variantActive, propsActive, routerGoOptions, onClick: propsOnClick, anchorProps: buttonAnchorProps, anchor, ...buttonProps } = props;
|
|
837
1757
|
const router = useRouter();
|
|
838
1758
|
const { isPending, isActive } = useActive(options ? {
|
|
839
1759
|
href: props.href,
|
|
@@ -847,11 +1767,11 @@ const ActionNavigationButton = (props) => {
|
|
|
847
1767
|
};
|
|
848
1768
|
const className = buttonProps.className || "";
|
|
849
1769
|
if (isActive && options !== false && classNameActive) buttonProps.className = `${className} ${classNameActive}`.trim();
|
|
850
|
-
if (
|
|
1770
|
+
if (buttonAnchorProps || anchor) return /* @__PURE__ */ jsx(Anchor, {
|
|
851
1771
|
component: "a",
|
|
852
1772
|
...anchorProps,
|
|
853
1773
|
...buttonProps,
|
|
854
|
-
...
|
|
1774
|
+
...buttonAnchorProps,
|
|
855
1775
|
onClick: combinedOnClick,
|
|
856
1776
|
children: props.children
|
|
857
1777
|
});
|
|
@@ -874,6 +1794,38 @@ const ActionHrefButton = (props) => {
|
|
|
874
1794
|
children: props.children
|
|
875
1795
|
});
|
|
876
1796
|
};
|
|
1797
|
+
const ActionMenuItem = (props) => {
|
|
1798
|
+
const { item, index } = props;
|
|
1799
|
+
const router = useRouter();
|
|
1800
|
+
const action = useAction({ handler: async (e) => {
|
|
1801
|
+
await item.onClick?.();
|
|
1802
|
+
} }, [item.onClick]);
|
|
1803
|
+
if (item.type === "divider") return /* @__PURE__ */ jsx(Menu.Divider, {}, index);
|
|
1804
|
+
if (item.type === "label") return /* @__PURE__ */ jsx(Menu.Label, { children: item.label }, index);
|
|
1805
|
+
if (item.children && item.children.length > 0) return /* @__PURE__ */ jsxs(Menu, {
|
|
1806
|
+
trigger: "hover",
|
|
1807
|
+
position: "right-start",
|
|
1808
|
+
offset: 2,
|
|
1809
|
+
children: [/* @__PURE__ */ jsx(Menu.Target, { children: /* @__PURE__ */ jsx(Menu.Item, {
|
|
1810
|
+
leftSection: item.icon,
|
|
1811
|
+
rightSection: /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }),
|
|
1812
|
+
children: item.label
|
|
1813
|
+
}) }), /* @__PURE__ */ jsx(Menu.Dropdown, { children: item.children.map((child, childIndex) => /* @__PURE__ */ jsx(ActionMenuItem, {
|
|
1814
|
+
item: child,
|
|
1815
|
+
index: childIndex
|
|
1816
|
+
}, childIndex)) })]
|
|
1817
|
+
}, index);
|
|
1818
|
+
const menuItemProps = {};
|
|
1819
|
+
if (props.item.onClick) menuItemProps.onClick = action.run;
|
|
1820
|
+
else if (props.item.href) Object.assign(menuItemProps, router.anchor(props.item.href));
|
|
1821
|
+
return /* @__PURE__ */ jsx(Menu.Item, {
|
|
1822
|
+
leftSection: item.icon ?? (item.active ? /* @__PURE__ */ jsx(IconCheck, { size: ui.sizes.icon.sm }) : /* @__PURE__ */ jsx(Flex$1, { w: ui.sizes.icon.sm })),
|
|
1823
|
+
onClick: item.onClick,
|
|
1824
|
+
color: item.color,
|
|
1825
|
+
...menuItemProps,
|
|
1826
|
+
children: item.label
|
|
1827
|
+
}, index);
|
|
1828
|
+
};
|
|
877
1829
|
|
|
878
1830
|
//#endregion
|
|
879
1831
|
//#region ../../src/core/components/buttons/BurgerButton.tsx
|
|
@@ -926,11 +1878,11 @@ const DarkModeButton = (props) => {
|
|
|
926
1878
|
const toggleColorScheme = () => {
|
|
927
1879
|
setColorScheme((document.documentElement.getAttribute("data-mantine-color-scheme") ?? "light") === "dark" ? "light" : "dark");
|
|
928
1880
|
};
|
|
929
|
-
const size = props.size ?? "
|
|
930
|
-
const iconSize = ui.sizes.icon[size] ?? ui.sizes.icon.
|
|
1881
|
+
const size = props.size ?? "sm";
|
|
1882
|
+
const iconSize = ui.sizes.icon[size] ?? ui.sizes.icon.sm;
|
|
931
1883
|
return /* @__PURE__ */ jsx(ActionButton, {
|
|
932
1884
|
onClick: toggleColorScheme,
|
|
933
|
-
variant: props.variant ?? "
|
|
1885
|
+
variant: props.variant ?? "default",
|
|
934
1886
|
size,
|
|
935
1887
|
"aria-label": "Toggle color scheme",
|
|
936
1888
|
icon: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(IconSun, {
|
|
@@ -949,7 +1901,7 @@ const DarkModeButton = (props) => {
|
|
|
949
1901
|
const LanguageButton = (props) => {
|
|
950
1902
|
const i18n = useI18n();
|
|
951
1903
|
return /* @__PURE__ */ jsx(ActionButton, {
|
|
952
|
-
variant: "
|
|
1904
|
+
variant: "default",
|
|
953
1905
|
icon: IconLanguage,
|
|
954
1906
|
menu: { items: i18n.languages.map((lang) => ({
|
|
955
1907
|
label: i18n.tr(lang),
|
|
@@ -968,8 +1920,7 @@ const OmnibarButton = (props) => {
|
|
|
968
1920
|
if (props.collapsed) return /* @__PURE__ */ jsx(ActionButton, {
|
|
969
1921
|
variant: "subtle",
|
|
970
1922
|
onClick: spotlight.open,
|
|
971
|
-
|
|
972
|
-
icon: /* @__PURE__ */ jsx(IconSearch, { size: 16 }),
|
|
1923
|
+
icon: IconSearch,
|
|
973
1924
|
tooltip: {
|
|
974
1925
|
label: "Search",
|
|
975
1926
|
position: "right"
|
|
@@ -1006,20 +1957,258 @@ const OmnibarButton = (props) => {
|
|
|
1006
1957
|
});
|
|
1007
1958
|
};
|
|
1008
1959
|
|
|
1960
|
+
//#endregion
|
|
1961
|
+
//#region ../../src/core/hooks/useDialog.ts
|
|
1962
|
+
/**
|
|
1963
|
+
* Use this hook to access the Dialog Service for showing various dialog types.
|
|
1964
|
+
*
|
|
1965
|
+
* @example
|
|
1966
|
+
* ```tsx
|
|
1967
|
+
* const dialog = useDialog();
|
|
1968
|
+
* await dialog.alert({ title: "Alert", message: "This is an alert message" });
|
|
1969
|
+
* const confirmed = await dialog.confirm({ title: "Confirm", message: "Are you sure?" });
|
|
1970
|
+
* const input = await dialog.prompt({ title: "Input", message: "Enter your name:" });
|
|
1971
|
+
* ```
|
|
1972
|
+
*/
|
|
1973
|
+
const useDialog = () => {
|
|
1974
|
+
return useInject(DialogService);
|
|
1975
|
+
};
|
|
1976
|
+
|
|
1977
|
+
//#endregion
|
|
1978
|
+
//#region ../../src/core/components/buttons/ThemeExpertModal.tsx
|
|
1979
|
+
const MANTINE_COLORS = [
|
|
1980
|
+
"red",
|
|
1981
|
+
"pink",
|
|
1982
|
+
"grape",
|
|
1983
|
+
"violet",
|
|
1984
|
+
"indigo",
|
|
1985
|
+
"blue",
|
|
1986
|
+
"cyan",
|
|
1987
|
+
"teal",
|
|
1988
|
+
"green",
|
|
1989
|
+
"lime",
|
|
1990
|
+
"yellow",
|
|
1991
|
+
"orange"
|
|
1992
|
+
];
|
|
1993
|
+
const RADIUS_OPTIONS = [
|
|
1994
|
+
{
|
|
1995
|
+
label: "xs",
|
|
1996
|
+
value: "xs"
|
|
1997
|
+
},
|
|
1998
|
+
{
|
|
1999
|
+
label: "sm",
|
|
2000
|
+
value: "sm"
|
|
2001
|
+
},
|
|
2002
|
+
{
|
|
2003
|
+
label: "md",
|
|
2004
|
+
value: "md"
|
|
2005
|
+
},
|
|
2006
|
+
{
|
|
2007
|
+
label: "lg",
|
|
2008
|
+
value: "lg"
|
|
2009
|
+
},
|
|
2010
|
+
{
|
|
2011
|
+
label: "xl",
|
|
2012
|
+
value: "xl"
|
|
2013
|
+
}
|
|
2014
|
+
];
|
|
2015
|
+
const SIZE_OPTIONS = [
|
|
2016
|
+
{
|
|
2017
|
+
label: "xs",
|
|
2018
|
+
value: "xs"
|
|
2019
|
+
},
|
|
2020
|
+
{
|
|
2021
|
+
label: "sm",
|
|
2022
|
+
value: "sm"
|
|
2023
|
+
},
|
|
2024
|
+
{
|
|
2025
|
+
label: "md",
|
|
2026
|
+
value: "md"
|
|
2027
|
+
},
|
|
2028
|
+
{
|
|
2029
|
+
label: "lg",
|
|
2030
|
+
value: "lg"
|
|
2031
|
+
},
|
|
2032
|
+
{
|
|
2033
|
+
label: "xl",
|
|
2034
|
+
value: "xl"
|
|
2035
|
+
}
|
|
2036
|
+
];
|
|
2037
|
+
const FONT_OPTIONS = [
|
|
2038
|
+
{
|
|
2039
|
+
label: "System",
|
|
2040
|
+
value: ""
|
|
2041
|
+
},
|
|
2042
|
+
{
|
|
2043
|
+
label: "Inter",
|
|
2044
|
+
value: "Inter, sans-serif"
|
|
2045
|
+
},
|
|
2046
|
+
{
|
|
2047
|
+
label: "Mono",
|
|
2048
|
+
value: "ui-monospace, SFMono-Regular, Menlo, monospace"
|
|
2049
|
+
},
|
|
2050
|
+
{
|
|
2051
|
+
label: "Serif",
|
|
2052
|
+
value: "Georgia, 'Times New Roman', serif"
|
|
2053
|
+
}
|
|
2054
|
+
];
|
|
2055
|
+
const ThemeExpertModal = () => {
|
|
2056
|
+
const [, , expert] = useTheme();
|
|
2057
|
+
const dialog = useDialog();
|
|
2058
|
+
const mantineTheme = useMantineTheme();
|
|
2059
|
+
const { overrides, setOverrides } = expert;
|
|
2060
|
+
const currentColor = overrides.primaryColor || mantineTheme.primaryColor;
|
|
2061
|
+
const currentRadius = overrides.radius || mantineTheme.defaultRadius || "md";
|
|
2062
|
+
const currentFont = overrides.fontFamily || "";
|
|
2063
|
+
const currentFontSize = overrides.fontSize || "md";
|
|
2064
|
+
const currentScale = overrides.scale || "md";
|
|
2065
|
+
const updateOverrides = (patch) => {
|
|
2066
|
+
setOverrides({
|
|
2067
|
+
...overrides,
|
|
2068
|
+
...patch
|
|
2069
|
+
});
|
|
2070
|
+
};
|
|
2071
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2072
|
+
direction: "column",
|
|
2073
|
+
gap: "lg",
|
|
2074
|
+
children: [
|
|
2075
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2076
|
+
direction: "column",
|
|
2077
|
+
gap: "xs",
|
|
2078
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
2079
|
+
fw: 500,
|
|
2080
|
+
size: "sm",
|
|
2081
|
+
children: "Primary Color"
|
|
2082
|
+
}), /* @__PURE__ */ jsx(SimpleGrid, {
|
|
2083
|
+
cols: 6,
|
|
2084
|
+
spacing: "xs",
|
|
2085
|
+
children: MANTINE_COLORS.map((color) => /* @__PURE__ */ jsx(Flex$1, {
|
|
2086
|
+
justify: "center",
|
|
2087
|
+
children: /* @__PURE__ */ jsx(ColorSwatch, {
|
|
2088
|
+
color: mantineTheme.colors[color]?.[6] ?? color,
|
|
2089
|
+
onClick: () => updateOverrides({ primaryColor: color }),
|
|
2090
|
+
style: { cursor: "pointer" },
|
|
2091
|
+
size: 32,
|
|
2092
|
+
children: currentColor === color && /* @__PURE__ */ jsx(IconCheck, {
|
|
2093
|
+
size: 14,
|
|
2094
|
+
color: "white"
|
|
2095
|
+
})
|
|
2096
|
+
})
|
|
2097
|
+
}, color))
|
|
2098
|
+
})]
|
|
2099
|
+
}),
|
|
2100
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2101
|
+
direction: "column",
|
|
2102
|
+
gap: "xs",
|
|
2103
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
2104
|
+
fw: 500,
|
|
2105
|
+
size: "sm",
|
|
2106
|
+
children: "Border Radius"
|
|
2107
|
+
}), /* @__PURE__ */ jsx(Flex$1, {
|
|
2108
|
+
gap: "xs",
|
|
2109
|
+
children: RADIUS_OPTIONS.map((opt) => /* @__PURE__ */ jsx(ActionButton, {
|
|
2110
|
+
variant: String(currentRadius) === opt.value ? "filled" : "default",
|
|
2111
|
+
size: "xs",
|
|
2112
|
+
flex: 1,
|
|
2113
|
+
onClick: () => updateOverrides({ radius: opt.value }),
|
|
2114
|
+
children: opt.label
|
|
2115
|
+
}, opt.value))
|
|
2116
|
+
})]
|
|
2117
|
+
}),
|
|
2118
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2119
|
+
direction: "column",
|
|
2120
|
+
gap: "xs",
|
|
2121
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
2122
|
+
fw: 500,
|
|
2123
|
+
size: "sm",
|
|
2124
|
+
children: "Font Family"
|
|
2125
|
+
}), /* @__PURE__ */ jsx(Select, {
|
|
2126
|
+
data: FONT_OPTIONS,
|
|
2127
|
+
value: currentFont,
|
|
2128
|
+
onChange: (value) => updateOverrides({ fontFamily: value ?? "" }),
|
|
2129
|
+
allowDeselect: false
|
|
2130
|
+
})]
|
|
2131
|
+
}),
|
|
2132
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2133
|
+
direction: "column",
|
|
2134
|
+
gap: "xs",
|
|
2135
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
2136
|
+
fw: 500,
|
|
2137
|
+
size: "sm",
|
|
2138
|
+
children: "Font Size"
|
|
2139
|
+
}), /* @__PURE__ */ jsx(Flex$1, {
|
|
2140
|
+
gap: "xs",
|
|
2141
|
+
children: SIZE_OPTIONS.map((opt) => /* @__PURE__ */ jsx(ActionButton, {
|
|
2142
|
+
variant: currentFontSize === opt.value ? "filled" : "default",
|
|
2143
|
+
size: "xs",
|
|
2144
|
+
flex: 1,
|
|
2145
|
+
onClick: () => updateOverrides({ fontSize: opt.value }),
|
|
2146
|
+
children: opt.label
|
|
2147
|
+
}, opt.value))
|
|
2148
|
+
})]
|
|
2149
|
+
}),
|
|
2150
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2151
|
+
direction: "column",
|
|
2152
|
+
gap: "xs",
|
|
2153
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
2154
|
+
fw: 500,
|
|
2155
|
+
size: "sm",
|
|
2156
|
+
children: "Scale"
|
|
2157
|
+
}), /* @__PURE__ */ jsx(Flex$1, {
|
|
2158
|
+
gap: "xs",
|
|
2159
|
+
children: SIZE_OPTIONS.map((opt) => /* @__PURE__ */ jsx(ActionButton, {
|
|
2160
|
+
variant: currentScale === opt.value ? "filled" : "default",
|
|
2161
|
+
size: "xs",
|
|
2162
|
+
flex: 1,
|
|
2163
|
+
onClick: () => updateOverrides({ scale: opt.value }),
|
|
2164
|
+
children: opt.label
|
|
2165
|
+
}, opt.value))
|
|
2166
|
+
})]
|
|
2167
|
+
}),
|
|
2168
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
2169
|
+
justify: "space-between",
|
|
2170
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2171
|
+
variant: "subtle",
|
|
2172
|
+
color: "red",
|
|
2173
|
+
onClick: () => expert.resetOverrides(),
|
|
2174
|
+
children: "Reset"
|
|
2175
|
+
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
2176
|
+
variant: "default",
|
|
2177
|
+
px: "xl",
|
|
2178
|
+
onClick: () => dialog.close(),
|
|
2179
|
+
children: "OK"
|
|
2180
|
+
})]
|
|
2181
|
+
})
|
|
2182
|
+
]
|
|
2183
|
+
});
|
|
2184
|
+
};
|
|
2185
|
+
|
|
1009
2186
|
//#endregion
|
|
1010
2187
|
//#region ../../src/core/components/buttons/ThemeButton.tsx
|
|
1011
2188
|
const ThemeButton = (props) => {
|
|
2189
|
+
const { expert, ...actionProps } = props;
|
|
1012
2190
|
const [theme, setTheme] = useTheme();
|
|
1013
2191
|
const themeList = useStore(alephaThemeListAtom)[0];
|
|
2192
|
+
const dialog = useDialog();
|
|
2193
|
+
const items = themeList.map((it, index) => ({
|
|
2194
|
+
label: it.name,
|
|
2195
|
+
onClick: () => setTheme({ index }),
|
|
2196
|
+
active: theme.name === it.name
|
|
2197
|
+
}));
|
|
2198
|
+
if (expert) items.push({ type: "divider" }, {
|
|
2199
|
+
label: "Customize...",
|
|
2200
|
+
onClick: () => {
|
|
2201
|
+
dialog.open({
|
|
2202
|
+
title: "Customize Theme",
|
|
2203
|
+
content: /* @__PURE__ */ jsx(ThemeExpertModal, {})
|
|
2204
|
+
});
|
|
2205
|
+
}
|
|
2206
|
+
});
|
|
1014
2207
|
return /* @__PURE__ */ jsx(ActionButton, {
|
|
1015
|
-
variant: "
|
|
2208
|
+
variant: "default",
|
|
1016
2209
|
icon: IconPalette,
|
|
1017
|
-
menu: { items
|
|
1018
|
-
|
|
1019
|
-
onClick: () => setTheme({ index }),
|
|
1020
|
-
active: theme.name === it.name
|
|
1021
|
-
})) },
|
|
1022
|
-
...props
|
|
2210
|
+
menu: { items },
|
|
2211
|
+
...actionProps
|
|
1023
2212
|
});
|
|
1024
2213
|
};
|
|
1025
2214
|
|
|
@@ -1030,8 +2219,7 @@ const ToggleSidebarButton = (props) => {
|
|
|
1030
2219
|
return /* @__PURE__ */ jsx(ActionButton, {
|
|
1031
2220
|
icon: sidebar.collapsed ? IconLayoutSidebarRightCollapse : IconLayoutSidebarLeftCollapse,
|
|
1032
2221
|
visibleFrom: "md",
|
|
1033
|
-
variant: "
|
|
1034
|
-
size: "md",
|
|
2222
|
+
variant: "default",
|
|
1035
2223
|
onClick: () => {
|
|
1036
2224
|
setSidebar({
|
|
1037
2225
|
...sidebar,
|
|
@@ -1048,99 +2236,103 @@ const ToggleSidebarButton = (props) => {
|
|
|
1048
2236
|
|
|
1049
2237
|
//#endregion
|
|
1050
2238
|
//#region ../../src/core/components/data/DetailDrawer.tsx
|
|
1051
|
-
const DetailDrawer = (
|
|
1052
|
-
opened,
|
|
1053
|
-
|
|
1054
|
-
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
justify: "space-between",
|
|
1061
|
-
align: "flex-start",
|
|
1062
|
-
style: { borderBottom: "1px solid var(--mantine-color-default-border)" },
|
|
2239
|
+
const DetailDrawer = (props) => {
|
|
2240
|
+
const { opened, onClose, title, subtitle, status, actions, tabs, children, loading, size = "xl", defaultTab } = props;
|
|
2241
|
+
return /* @__PURE__ */ jsxs(Drawer, {
|
|
2242
|
+
opened,
|
|
2243
|
+
onClose,
|
|
2244
|
+
position: "right",
|
|
2245
|
+
size,
|
|
2246
|
+
withCloseButton: false,
|
|
2247
|
+
padding: 0,
|
|
1063
2248
|
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
flex: 1
|
|
1069
|
-
},
|
|
2249
|
+
p: "md",
|
|
2250
|
+
justify: "space-between",
|
|
2251
|
+
align: "flex-start",
|
|
2252
|
+
style: { borderBottom: "1px solid var(--mantine-color-default-border)" },
|
|
1070
2253
|
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
2254
|
+
direction: "column",
|
|
2255
|
+
gap: 2,
|
|
2256
|
+
style: {
|
|
2257
|
+
minWidth: 0,
|
|
2258
|
+
flex: 1
|
|
2259
|
+
},
|
|
2260
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
2261
|
+
gap: "xs",
|
|
2262
|
+
align: "center",
|
|
2263
|
+
children: [status && /* @__PURE__ */ jsx(Flex$1, {
|
|
2264
|
+
w: 8,
|
|
2265
|
+
h: 8,
|
|
2266
|
+
style: {
|
|
2267
|
+
borderRadius: "50%",
|
|
2268
|
+
backgroundColor: status.active ? "var(--mantine-color-green-6)" : "var(--mantine-color-red-6)",
|
|
2269
|
+
flexShrink: 0
|
|
2270
|
+
}
|
|
2271
|
+
}), /* @__PURE__ */ jsx(Text$1, {
|
|
2272
|
+
size: "lg",
|
|
2273
|
+
fw: 600,
|
|
2274
|
+
truncate: true,
|
|
2275
|
+
children: title
|
|
2276
|
+
})]
|
|
2277
|
+
}), subtitle && /* @__PURE__ */ jsx(Text$1, {
|
|
2278
|
+
size: "sm",
|
|
2279
|
+
c: "dimmed",
|
|
2280
|
+
truncate: true,
|
|
2281
|
+
children: subtitle
|
|
2282
|
+
})]
|
|
2283
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
1071
2284
|
gap: "xs",
|
|
1072
2285
|
align: "center",
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
2286
|
+
style: { flexShrink: 0 },
|
|
2287
|
+
children: [actions && actions.length > 0 && /* @__PURE__ */ jsx(ActionButton, {
|
|
2288
|
+
variant: "default",
|
|
2289
|
+
size: "xs",
|
|
2290
|
+
menu: {
|
|
2291
|
+
items: actions,
|
|
2292
|
+
position: "bottom-end",
|
|
2293
|
+
width: 200
|
|
2294
|
+
},
|
|
2295
|
+
children: "Actions"
|
|
2296
|
+
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
2297
|
+
variant: "subtle",
|
|
2298
|
+
size: "xs",
|
|
2299
|
+
c: "dimmed",
|
|
2300
|
+
onClick: onClose,
|
|
2301
|
+
children: "Close"
|
|
1086
2302
|
})]
|
|
1087
|
-
}), subtitle && /* @__PURE__ */ jsx(Text$1, {
|
|
1088
|
-
size: "sm",
|
|
1089
|
-
c: "dimmed",
|
|
1090
|
-
truncate: true,
|
|
1091
|
-
children: subtitle
|
|
1092
2303
|
})]
|
|
1093
|
-
}), /* @__PURE__ */
|
|
1094
|
-
|
|
2304
|
+
}), loading ? /* @__PURE__ */ jsx(Flex$1, {
|
|
2305
|
+
flex: 1,
|
|
2306
|
+
justify: "center",
|
|
1095
2307
|
align: "center",
|
|
1096
|
-
|
|
1097
|
-
children:
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
size: "xs",
|
|
1109
|
-
c: "dimmed",
|
|
1110
|
-
onClick: onClose,
|
|
1111
|
-
children: "Close"
|
|
1112
|
-
})]
|
|
1113
|
-
})]
|
|
1114
|
-
}), loading ? /* @__PURE__ */ jsx(Flex$1, {
|
|
1115
|
-
flex: 1,
|
|
1116
|
-
justify: "center",
|
|
1117
|
-
align: "center",
|
|
1118
|
-
py: "xl",
|
|
1119
|
-
children: /* @__PURE__ */ jsx(Loader, {})
|
|
1120
|
-
}) : tabs && tabs.length > 0 ? /* @__PURE__ */ jsxs(Tabs, {
|
|
1121
|
-
defaultValue: defaultTab || tabs[0].value,
|
|
1122
|
-
children: [/* @__PURE__ */ jsx(Tabs.List, {
|
|
1123
|
-
px: "md",
|
|
1124
|
-
children: tabs.map((tab) => /* @__PURE__ */ jsx(Tabs.Tab, {
|
|
2308
|
+
py: "xl",
|
|
2309
|
+
children: /* @__PURE__ */ jsx(Loader, {})
|
|
2310
|
+
}) : tabs && tabs.length > 0 ? /* @__PURE__ */ jsxs(Tabs, {
|
|
2311
|
+
defaultValue: defaultTab || tabs[0].value,
|
|
2312
|
+
children: [/* @__PURE__ */ jsx(Tabs.List, {
|
|
2313
|
+
px: "md",
|
|
2314
|
+
children: tabs.map((tab) => /* @__PURE__ */ jsx(Tabs.Tab, {
|
|
2315
|
+
value: tab.value,
|
|
2316
|
+
leftSection: tab.icon ? /* @__PURE__ */ jsx(tab.icon, { size: 14 }) : void 0,
|
|
2317
|
+
children: tab.label
|
|
2318
|
+
}, tab.value))
|
|
2319
|
+
}), tabs.map((tab) => /* @__PURE__ */ jsx(Tabs.Panel, {
|
|
1125
2320
|
value: tab.value,
|
|
1126
|
-
|
|
1127
|
-
children: tab.
|
|
1128
|
-
}, tab.value))
|
|
1129
|
-
})
|
|
1130
|
-
|
|
2321
|
+
p: "md",
|
|
2322
|
+
children: tab.content
|
|
2323
|
+
}, tab.value))]
|
|
2324
|
+
}) : /* @__PURE__ */ jsx(Flex$1, {
|
|
2325
|
+
direction: "column",
|
|
1131
2326
|
p: "md",
|
|
1132
|
-
children
|
|
1133
|
-
}
|
|
1134
|
-
})
|
|
1135
|
-
|
|
1136
|
-
p: "md",
|
|
1137
|
-
children
|
|
1138
|
-
})]
|
|
1139
|
-
});
|
|
2327
|
+
children
|
|
2328
|
+
})]
|
|
2329
|
+
});
|
|
2330
|
+
};
|
|
1140
2331
|
|
|
1141
2332
|
//#endregion
|
|
1142
2333
|
//#region ../../src/core/components/data/DetailList.tsx
|
|
1143
|
-
const DetailList = (
|
|
2334
|
+
const DetailList = (props) => {
|
|
2335
|
+
const { items, columns = 1 } = props;
|
|
1144
2336
|
return /* @__PURE__ */ jsx(Grid, {
|
|
1145
2337
|
gutter: "xs",
|
|
1146
2338
|
children: items.filter((item) => !item.hidden).map((item) => /* @__PURE__ */ jsx(Grid.Col, {
|
|
@@ -1219,7 +2411,7 @@ const StatCards = ({ items }) => /* @__PURE__ */ jsx(Flex$1, {
|
|
|
1219
2411
|
//#endregion
|
|
1220
2412
|
//#region ../../src/core/components/Flex.tsx
|
|
1221
2413
|
const Flex = forwardRef((props, ref) => {
|
|
1222
|
-
const { fill, center, centerX, centerY, col, ...rest } = props;
|
|
2414
|
+
const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, overflow, ...rest } = props;
|
|
1223
2415
|
if (fill) rest.flex ??= 1;
|
|
1224
2416
|
if (col) rest.direction ??= "column";
|
|
1225
2417
|
if (center) {
|
|
@@ -1228,6 +2420,21 @@ const Flex = forwardRef((props, ref) => {
|
|
|
1228
2420
|
}
|
|
1229
2421
|
if (centerX) rest.justify ??= "center";
|
|
1230
2422
|
if (centerY) rest.align ??= "center";
|
|
2423
|
+
if (ground) rest.bg = "var(--alepha-ground)";
|
|
2424
|
+
else if (surface) rest.bg = "var(--alepha-surface)";
|
|
2425
|
+
else if (elevated) rest.bg = "var(--alepha-elevated)";
|
|
2426
|
+
if (rounded) rest.bdrs = rounded === true ? "md" : rounded;
|
|
2427
|
+
if (bordered) rest.bd = "1px solid var(--alepha-border)";
|
|
2428
|
+
if (borderedTop) rest.style = {
|
|
2429
|
+
borderTop: "1px solid var(--alepha-border)",
|
|
2430
|
+
...rest.style ?? {}
|
|
2431
|
+
};
|
|
2432
|
+
if (borderedBottom) rest.style = {
|
|
2433
|
+
borderBottom: "1px solid var(--alepha-border)",
|
|
2434
|
+
...rest.style ?? {}
|
|
2435
|
+
};
|
|
2436
|
+
if (shadowed) rest.className = `${rest.className ?? ""} shadow-${shadowed === true ? "md" : shadowed}`.trim();
|
|
2437
|
+
if (overflow) rest.className = `${rest.className ?? ""} overflow-auto`.trim();
|
|
1231
2438
|
return /* @__PURE__ */ jsx(Flex$1, {
|
|
1232
2439
|
ref,
|
|
1233
2440
|
...rest
|
|
@@ -1251,6 +2458,7 @@ const AppBar = (props) => {
|
|
|
1251
2458
|
if ("type" in item) {
|
|
1252
2459
|
if (item.type === "burger") return /* @__PURE__ */ jsx(BurgerButton, {}, index);
|
|
1253
2460
|
if (item.type === "dark") return /* @__PURE__ */ jsx(DarkModeButton, { ...item.props }, index);
|
|
2461
|
+
if (item.type === "theme") return /* @__PURE__ */ jsx(ThemeButton, { ...item.props }, index);
|
|
1254
2462
|
if (item.type === "search") return /* @__PURE__ */ jsx(OmnibarButton, { ...item.props }, index);
|
|
1255
2463
|
if (item.type === "lang") return /* @__PURE__ */ jsx(LanguageButton, { ...item.props }, index);
|
|
1256
2464
|
if (item.type === "spacer") return /* @__PURE__ */ jsx(Flex, { w: 16 }, index);
|
|
@@ -1364,7 +2572,8 @@ const AppBar = (props) => {
|
|
|
1364
2572
|
* Pages should define a `label` in their `$page()` options for best results.
|
|
1365
2573
|
* Falls back to the page name converted to Title Case.
|
|
1366
2574
|
*/
|
|
1367
|
-
const Breadcrumb = (
|
|
2575
|
+
const Breadcrumb = (props) => {
|
|
2576
|
+
const { home = "Home", separator, size = "sm", ...groupProps } = props;
|
|
1368
2577
|
const state = useRouterState();
|
|
1369
2578
|
const router = useRouter();
|
|
1370
2579
|
const crumbs = [];
|
|
@@ -1419,11 +2628,175 @@ const Container = forwardRef((props, ref) => {
|
|
|
1419
2628
|
});
|
|
1420
2629
|
Container.displayName = "Container";
|
|
1421
2630
|
|
|
2631
|
+
//#endregion
|
|
2632
|
+
//#region ../../src/core/helpers/renderIcon.tsx
|
|
2633
|
+
const renderIcon = (icon, size) => {
|
|
2634
|
+
if (!icon) return null;
|
|
2635
|
+
if (isValidElement(icon)) return icon;
|
|
2636
|
+
if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui.sizes.icon.md });
|
|
2637
|
+
return icon;
|
|
2638
|
+
};
|
|
2639
|
+
|
|
2640
|
+
//#endregion
|
|
2641
|
+
//#region ../../src/core/components/Text.tsx
|
|
2642
|
+
const INTENT_COLORS = {
|
|
2643
|
+
primary: "blue",
|
|
2644
|
+
info: "cyan",
|
|
2645
|
+
success: "green",
|
|
2646
|
+
warning: "yellow",
|
|
2647
|
+
danger: "red"
|
|
2648
|
+
};
|
|
2649
|
+
const Text = forwardRef((props, ref) => {
|
|
2650
|
+
const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
|
|
2651
|
+
if (intent) rest.c ??= INTENT_COLORS[intent];
|
|
2652
|
+
if (bold) rest.fw ??= 700;
|
|
2653
|
+
if (light) rest.fw ??= 300;
|
|
2654
|
+
if (italic) rest.fs ??= "italic";
|
|
2655
|
+
if (muted) rest.c ??= "dimmed";
|
|
2656
|
+
if (small) rest.size ??= "xs";
|
|
2657
|
+
if (uppercase) rest.tt ??= "uppercase";
|
|
2658
|
+
if (capitalize) rest.tt ??= "capitalize";
|
|
2659
|
+
if (center) rest.ta ??= "center";
|
|
2660
|
+
if (monospace) rest.ff ??= "monospace";
|
|
2661
|
+
if (title) rest.size ??= "xl";
|
|
2662
|
+
return /* @__PURE__ */ jsx(Text$1, {
|
|
2663
|
+
ref,
|
|
2664
|
+
...rest
|
|
2665
|
+
});
|
|
2666
|
+
});
|
|
2667
|
+
Text.displayName = "Text";
|
|
2668
|
+
|
|
2669
|
+
//#endregion
|
|
2670
|
+
//#region ../../src/core/components/layout/SidebarCollapsedItem.tsx
|
|
2671
|
+
const SidebarCollapsedItem = (props) => {
|
|
2672
|
+
const router = useRouter();
|
|
2673
|
+
const handleItemClick = () => {
|
|
2674
|
+
props.onItemClick?.(props.item);
|
|
2675
|
+
props.item.onClick?.();
|
|
2676
|
+
};
|
|
2677
|
+
const hasChildren = props.item.children && props.item.children.length > 0;
|
|
2678
|
+
const menu = hasChildren ? {
|
|
2679
|
+
on: "hover",
|
|
2680
|
+
position: "right",
|
|
2681
|
+
menuProps: {
|
|
2682
|
+
arrowPosition: "center",
|
|
2683
|
+
arrowSize: 10,
|
|
2684
|
+
withArrow: true
|
|
2685
|
+
},
|
|
2686
|
+
items: [{
|
|
2687
|
+
type: "label",
|
|
2688
|
+
label: props.item.label
|
|
2689
|
+
}, ...props.item.children.filter((child) => !child.can || child.can()).map((child) => ({
|
|
2690
|
+
label: child.label,
|
|
2691
|
+
icon: renderIcon(child.icon, ui.sizes.icon.sm),
|
|
2692
|
+
href: child.href,
|
|
2693
|
+
active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
|
|
2694
|
+
}))]
|
|
2695
|
+
} : void 0;
|
|
2696
|
+
return /* @__PURE__ */ jsx(Flex, {
|
|
2697
|
+
w: "100%",
|
|
2698
|
+
justify: "center",
|
|
2699
|
+
pos: "relative",
|
|
2700
|
+
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
2701
|
+
size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
|
|
2702
|
+
bd: 0,
|
|
2703
|
+
variant: "default",
|
|
2704
|
+
propsActive: { variant: "outline" },
|
|
2705
|
+
tooltip: hasChildren ? void 0 : {
|
|
2706
|
+
label: props.item.label,
|
|
2707
|
+
position: "right"
|
|
2708
|
+
},
|
|
2709
|
+
onClick: hasChildren ? void 0 : handleItemClick,
|
|
2710
|
+
icon: renderIcon(props.item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
|
|
2711
|
+
href: hasChildren ? void 0 : props.item.href,
|
|
2712
|
+
target: hasChildren ? void 0 : props.item.target,
|
|
2713
|
+
menu,
|
|
2714
|
+
...props.item.actionProps
|
|
2715
|
+
})
|
|
2716
|
+
});
|
|
2717
|
+
};
|
|
2718
|
+
|
|
2719
|
+
//#endregion
|
|
2720
|
+
//#region ../../src/core/components/layout/SidebarItem.tsx
|
|
2721
|
+
const SidebarItem = (props) => {
|
|
2722
|
+
const maxLevel = 2;
|
|
2723
|
+
const router = useRouter();
|
|
2724
|
+
const isActive = useCallback((item) => {
|
|
2725
|
+
if (!item.children) return false;
|
|
2726
|
+
for (const child of item.children) {
|
|
2727
|
+
if (child.href) {
|
|
2728
|
+
if (router.isActive(child.href)) return true;
|
|
2729
|
+
}
|
|
2730
|
+
if (isActive(child)) return true;
|
|
2731
|
+
}
|
|
2732
|
+
return false;
|
|
2733
|
+
}, []);
|
|
2734
|
+
const [isOpen, setIsOpen] = useState(isActive(props.item));
|
|
2735
|
+
useEvents({ "react:transition:end": () => {
|
|
2736
|
+
if (isActive(props.item)) setIsOpen(true);
|
|
2737
|
+
} }, []);
|
|
2738
|
+
if (props.level > maxLevel) return null;
|
|
2739
|
+
const handleItemClick = (e) => {
|
|
2740
|
+
if (!props.item.target) e.preventDefault();
|
|
2741
|
+
if (props.item.children && props.item.children.length > 0) setIsOpen(!isOpen);
|
|
2742
|
+
else {
|
|
2743
|
+
props.onItemClick?.(props.item);
|
|
2744
|
+
props.item.onClick?.();
|
|
2745
|
+
}
|
|
2746
|
+
};
|
|
2747
|
+
return /* @__PURE__ */ jsxs(Flex, {
|
|
2748
|
+
direction: "column",
|
|
2749
|
+
ps: props.level === 0 ? 0 : 32,
|
|
2750
|
+
pos: "relative",
|
|
2751
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2752
|
+
w: "100%",
|
|
2753
|
+
justify: "space-between",
|
|
2754
|
+
href: props.item.href,
|
|
2755
|
+
target: props.item.target,
|
|
2756
|
+
size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
|
|
2757
|
+
bd: 0,
|
|
2758
|
+
fw: "normal",
|
|
2759
|
+
variant: "default",
|
|
2760
|
+
propsActive: { variant: "outline" },
|
|
2761
|
+
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
2762
|
+
onClick: handleItemClick,
|
|
2763
|
+
leftSection: /* @__PURE__ */ jsxs(Flex, {
|
|
2764
|
+
w: "100%",
|
|
2765
|
+
align: "center",
|
|
2766
|
+
gap: "sm",
|
|
2767
|
+
children: [renderIcon(props.item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex, {
|
|
2768
|
+
direction: "column",
|
|
2769
|
+
children: /* @__PURE__ */ jsx(Flex, { children: props.item.label })
|
|
2770
|
+
})]
|
|
2771
|
+
}),
|
|
2772
|
+
rightSection: props.item.children ? /* @__PURE__ */ jsx(Flex, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
|
|
2773
|
+
...props.item.actionProps
|
|
2774
|
+
}), props.item.children && isOpen && /* @__PURE__ */ jsxs(Flex, {
|
|
2775
|
+
direction: "column",
|
|
2776
|
+
"data-parent-level": props.level,
|
|
2777
|
+
gap: 2,
|
|
2778
|
+
py: 2,
|
|
2779
|
+
children: [/* @__PURE__ */ jsx(Flex, { style: {
|
|
2780
|
+
position: "absolute",
|
|
2781
|
+
width: 1,
|
|
2782
|
+
background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
|
|
2783
|
+
top: 48,
|
|
2784
|
+
left: 20 + 32 * props.level,
|
|
2785
|
+
bottom: 16
|
|
2786
|
+
} }), props.item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
|
|
2787
|
+
item: child,
|
|
2788
|
+
level: props.level + 1,
|
|
2789
|
+
onItemClick: props.onItemClick,
|
|
2790
|
+
theme: props.theme
|
|
2791
|
+
}, index))]
|
|
2792
|
+
})]
|
|
2793
|
+
});
|
|
2794
|
+
};
|
|
2795
|
+
|
|
1422
2796
|
//#endregion
|
|
1423
2797
|
//#region ../../src/core/components/layout/Sidebar.tsx
|
|
1424
2798
|
const Sidebar = (props) => {
|
|
1425
2799
|
const router = useRouter();
|
|
1426
|
-
const { onItemClick } = props;
|
|
1427
2800
|
const divider = (key, fill, collapsed) => {
|
|
1428
2801
|
return /* @__PURE__ */ jsx(Flex, {
|
|
1429
2802
|
h: 1,
|
|
@@ -1441,6 +2814,9 @@ const Sidebar = (props) => {
|
|
|
1441
2814
|
if (item.type === "divider") return divider(key, item.fill, collapsed);
|
|
1442
2815
|
if (item.type === "search") return /* @__PURE__ */ jsx(Flex, {
|
|
1443
2816
|
mb: "xs",
|
|
2817
|
+
w: "100%",
|
|
2818
|
+
justify: "center",
|
|
2819
|
+
pos: "relative",
|
|
1444
2820
|
children: /* @__PURE__ */ jsx(OmnibarButton, { collapsed })
|
|
1445
2821
|
}, key);
|
|
1446
2822
|
if (item.type === "toggle") return /* @__PURE__ */ jsx(ToggleSidebarButton, {}, key);
|
|
@@ -1448,7 +2824,7 @@ const Sidebar = (props) => {
|
|
|
1448
2824
|
if (item.children && item.children.length > 0) {
|
|
1449
2825
|
if (!item.children.some((child) => !("can" in child) || !child.can || child.can())) return null;
|
|
1450
2826
|
}
|
|
1451
|
-
if (collapsed) return /* @__PURE__ */
|
|
2827
|
+
if (collapsed) return /* @__PURE__ */ jsx(Fragment$1, { children: item.children?.map((child, index) => renderNode(child, `s${key}-${index}`, collapsed)) }, key);
|
|
1452
2828
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Flex, {
|
|
1453
2829
|
mt: "md",
|
|
1454
2830
|
align: "center",
|
|
@@ -1471,13 +2847,13 @@ const Sidebar = (props) => {
|
|
|
1471
2847
|
if (collapsed) return /* @__PURE__ */ jsx(SidebarCollapsedItem, {
|
|
1472
2848
|
item,
|
|
1473
2849
|
level: 0,
|
|
1474
|
-
onItemClick,
|
|
2850
|
+
onItemClick: props.onItemClick,
|
|
1475
2851
|
theme: props.theme ?? {}
|
|
1476
2852
|
}, key);
|
|
1477
2853
|
return /* @__PURE__ */ jsx(SidebarItem, {
|
|
1478
2854
|
item,
|
|
1479
2855
|
level: 0,
|
|
1480
|
-
onItemClick,
|
|
2856
|
+
onItemClick: props.onItemClick,
|
|
1481
2857
|
theme: props.theme ?? {}
|
|
1482
2858
|
}, key);
|
|
1483
2859
|
};
|
|
@@ -1498,7 +2874,7 @@ const Sidebar = (props) => {
|
|
|
1498
2874
|
return [];
|
|
1499
2875
|
};
|
|
1500
2876
|
const padding = "md";
|
|
1501
|
-
const gap = props.items ? props.gap ??
|
|
2877
|
+
const gap = props.items ? props.gap ?? 8 : "xs";
|
|
1502
2878
|
const menu = useMemo(() => getSidebarNodes(), [props.items, props.autoPopulateMenu]);
|
|
1503
2879
|
const renderSidebar = (collapsed) => /* @__PURE__ */ jsxs(Flex, {
|
|
1504
2880
|
flex: 1,
|
|
@@ -1540,117 +2916,6 @@ const Sidebar = (props) => {
|
|
|
1540
2916
|
})] });
|
|
1541
2917
|
return renderSidebar(false);
|
|
1542
2918
|
};
|
|
1543
|
-
const SidebarItem = (props) => {
|
|
1544
|
-
const { item, level } = props;
|
|
1545
|
-
const maxLevel = 2;
|
|
1546
|
-
const router = useRouter();
|
|
1547
|
-
const isActive = useCallback((item) => {
|
|
1548
|
-
if (!item.children) return false;
|
|
1549
|
-
for (const child of item.children) {
|
|
1550
|
-
if (child.href) {
|
|
1551
|
-
if (router.isActive(child.href)) return true;
|
|
1552
|
-
}
|
|
1553
|
-
if (isActive(child)) return true;
|
|
1554
|
-
}
|
|
1555
|
-
return false;
|
|
1556
|
-
}, []);
|
|
1557
|
-
const [isOpen, setIsOpen] = useState(isActive(item));
|
|
1558
|
-
useEvents({ "react:transition:end": () => {
|
|
1559
|
-
if (isActive(item)) setIsOpen(true);
|
|
1560
|
-
} }, []);
|
|
1561
|
-
if (level > maxLevel) return null;
|
|
1562
|
-
const handleItemClick = (e) => {
|
|
1563
|
-
if (!props.item.target) e.preventDefault();
|
|
1564
|
-
if (item.children && item.children.length > 0) setIsOpen(!isOpen);
|
|
1565
|
-
else {
|
|
1566
|
-
props.onItemClick?.(item);
|
|
1567
|
-
item.onClick?.();
|
|
1568
|
-
}
|
|
1569
|
-
};
|
|
1570
|
-
return /* @__PURE__ */ jsxs(Flex, {
|
|
1571
|
-
direction: "column",
|
|
1572
|
-
ps: level === 0 ? 0 : 32,
|
|
1573
|
-
pos: "relative",
|
|
1574
|
-
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
1575
|
-
w: "100%",
|
|
1576
|
-
justify: "space-between",
|
|
1577
|
-
href: props.item.href,
|
|
1578
|
-
target: props.item.target,
|
|
1579
|
-
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
1580
|
-
bd: 0,
|
|
1581
|
-
fw: "normal",
|
|
1582
|
-
variant: "default",
|
|
1583
|
-
propsActive: {
|
|
1584
|
-
variant: "outline",
|
|
1585
|
-
fw: "bold"
|
|
1586
|
-
},
|
|
1587
|
-
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
1588
|
-
onClick: handleItemClick,
|
|
1589
|
-
leftSection: /* @__PURE__ */ jsxs(Flex, {
|
|
1590
|
-
w: "100%",
|
|
1591
|
-
align: "center",
|
|
1592
|
-
gap: "sm",
|
|
1593
|
-
children: [renderIcon(item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex, {
|
|
1594
|
-
direction: "column",
|
|
1595
|
-
children: /* @__PURE__ */ jsx(Flex, { children: item.label })
|
|
1596
|
-
})]
|
|
1597
|
-
}),
|
|
1598
|
-
rightSection: item.children ? /* @__PURE__ */ jsx(Flex, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
|
|
1599
|
-
...props.item.actionProps
|
|
1600
|
-
}), item.children && isOpen && /* @__PURE__ */ jsxs(Flex, {
|
|
1601
|
-
direction: "column",
|
|
1602
|
-
"data-parent-level": level,
|
|
1603
|
-
children: [/* @__PURE__ */ jsx(Flex, { style: {
|
|
1604
|
-
position: "absolute",
|
|
1605
|
-
width: 1,
|
|
1606
|
-
background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
|
|
1607
|
-
top: 48,
|
|
1608
|
-
left: 20 + 32 * level,
|
|
1609
|
-
bottom: 16
|
|
1610
|
-
} }), item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
|
|
1611
|
-
item: child,
|
|
1612
|
-
level: level + 1,
|
|
1613
|
-
onItemClick: props.onItemClick,
|
|
1614
|
-
theme: props.theme
|
|
1615
|
-
}, index))]
|
|
1616
|
-
})]
|
|
1617
|
-
});
|
|
1618
|
-
};
|
|
1619
|
-
const SidebarCollapsedItem = (props) => {
|
|
1620
|
-
const { item, level } = props;
|
|
1621
|
-
const router = useRouter();
|
|
1622
|
-
const handleItemClick = () => {
|
|
1623
|
-
props.onItemClick?.(item);
|
|
1624
|
-
item.onClick?.();
|
|
1625
|
-
};
|
|
1626
|
-
const hasChildren = item.children && item.children.length > 0;
|
|
1627
|
-
const menu = hasChildren ? {
|
|
1628
|
-
on: "hover",
|
|
1629
|
-
position: "right",
|
|
1630
|
-
items: item.children.filter((child) => !child.can || child.can()).map((child) => ({
|
|
1631
|
-
label: child.label,
|
|
1632
|
-
icon: renderIcon(child.icon, ui.sizes.icon.sm),
|
|
1633
|
-
href: child.href,
|
|
1634
|
-
active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
|
|
1635
|
-
}))
|
|
1636
|
-
} : void 0;
|
|
1637
|
-
return /* @__PURE__ */ jsx(ActionButton, {
|
|
1638
|
-
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
1639
|
-
variant: "subtle",
|
|
1640
|
-
variantActive: "default",
|
|
1641
|
-
tooltip: hasChildren ? void 0 : {
|
|
1642
|
-
label: item.label,
|
|
1643
|
-
position: "right"
|
|
1644
|
-
},
|
|
1645
|
-
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
1646
|
-
onClick: hasChildren ? void 0 : handleItemClick,
|
|
1647
|
-
icon: renderIcon(item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
|
|
1648
|
-
href: hasChildren ? void 0 : props.item.href,
|
|
1649
|
-
target: hasChildren ? void 0 : props.item.target,
|
|
1650
|
-
menu,
|
|
1651
|
-
...props.item.actionProps
|
|
1652
|
-
});
|
|
1653
|
-
};
|
|
1654
2919
|
|
|
1655
2920
|
//#endregion
|
|
1656
2921
|
//#region ../../src/core/components/layout/DashboardShell.tsx
|
|
@@ -1691,13 +2956,16 @@ const DashboardShell = (props) => {
|
|
|
1691
2956
|
const fHeight = props.footerHeight ?? 24;
|
|
1692
2957
|
const headerHeight = hasAppBar ? hHeight : 0;
|
|
1693
2958
|
const footerHeight = footerElement ? fHeight : 0;
|
|
2959
|
+
const navbarWidth = collapsed ? collapsedWidth : expandedWidth;
|
|
2960
|
+
const mainContent = props.children ?? /* @__PURE__ */ jsx(NestedView, {});
|
|
1694
2961
|
return /* @__PURE__ */ jsxs(AppShell, {
|
|
1695
2962
|
layout: "alt",
|
|
1696
2963
|
w: "100%",
|
|
2964
|
+
h: "100vh",
|
|
1697
2965
|
flex: 1,
|
|
1698
2966
|
header: hasAppBar ? { height: hHeight } : void 0,
|
|
1699
2967
|
navbar: hasSidebar ? {
|
|
1700
|
-
width: { base:
|
|
2968
|
+
width: { base: navbarWidth },
|
|
1701
2969
|
breakpoint: "md",
|
|
1702
2970
|
collapsed: { mobile: sidebar.closed }
|
|
1703
2971
|
} : void 0,
|
|
@@ -1712,13 +2980,12 @@ const DashboardShell = (props) => {
|
|
|
1712
2980
|
})
|
|
1713
2981
|
}),
|
|
1714
2982
|
hasSidebar && /* @__PURE__ */ jsxs(AppShell.Navbar, {
|
|
1715
|
-
className: "alepha-sidebar-navbar",
|
|
1716
2983
|
...props.appShellNavbarProps,
|
|
1717
2984
|
children: [
|
|
1718
2985
|
props.navbarHeader ? /* @__PURE__ */ jsx(Flex, {
|
|
1719
2986
|
style: { borderBottom: "1px solid var(--mantine-color-default-border)" },
|
|
1720
2987
|
h: headerHeight,
|
|
1721
|
-
children: props.navbarHeader
|
|
2988
|
+
children: props.navbarHeader({ collapsed })
|
|
1722
2989
|
}) : null,
|
|
1723
2990
|
/* @__PURE__ */ jsx(Sidebar, {
|
|
1724
2991
|
...props.sidebarProps ?? {},
|
|
@@ -1732,53 +2999,30 @@ const DashboardShell = (props) => {
|
|
|
1732
2999
|
]
|
|
1733
3000
|
}),
|
|
1734
3001
|
/* @__PURE__ */ jsx(AppShell.Main, {
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
|
|
1745
|
-
|
|
1746
|
-
|
|
1747
|
-
|
|
1748
|
-
|
|
1749
|
-
|
|
1750
|
-
primary: "blue",
|
|
1751
|
-
info: "cyan",
|
|
1752
|
-
success: "green",
|
|
1753
|
-
warning: "yellow",
|
|
1754
|
-
danger: "red"
|
|
1755
|
-
};
|
|
1756
|
-
const Text = forwardRef((props, ref) => {
|
|
1757
|
-
const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
|
|
1758
|
-
if (intent) rest.c ??= INTENT_COLORS[intent];
|
|
1759
|
-
if (bold) rest.fw ??= 700;
|
|
1760
|
-
if (light) rest.fw ??= 300;
|
|
1761
|
-
if (italic) rest.fs ??= "italic";
|
|
1762
|
-
if (muted) rest.c ??= "dimmed";
|
|
1763
|
-
if (small) rest.size ??= "sm";
|
|
1764
|
-
if (uppercase) rest.tt ??= "uppercase";
|
|
1765
|
-
if (capitalize) rest.tt ??= "capitalize";
|
|
1766
|
-
if (center) rest.ta ??= "center";
|
|
1767
|
-
if (monospace) rest.ff ??= "monospace";
|
|
1768
|
-
if (title) rest.size ??= "xl";
|
|
1769
|
-
return /* @__PURE__ */ jsx(Text$1, {
|
|
1770
|
-
ref,
|
|
1771
|
-
...rest
|
|
3002
|
+
display: "flex",
|
|
3003
|
+
bg: "var(--alepha-ground)",
|
|
3004
|
+
pos: "relative",
|
|
3005
|
+
h: props.fill ? "100%" : "inherit",
|
|
3006
|
+
...props.appShellMainProps,
|
|
3007
|
+
children: props.container ? /* @__PURE__ */ jsx(Container, {
|
|
3008
|
+
...typeof props.container === "boolean" ? {} : props.container,
|
|
3009
|
+
children: mainContent
|
|
3010
|
+
}) : mainContent
|
|
3011
|
+
}),
|
|
3012
|
+
footerElement && /* @__PURE__ */ jsx(AppShell.Footer, {
|
|
3013
|
+
...props.appShellFooterProps,
|
|
3014
|
+
children: footerElement
|
|
3015
|
+
})
|
|
3016
|
+
]
|
|
1772
3017
|
});
|
|
1773
|
-
}
|
|
1774
|
-
Text.displayName = "Text";
|
|
3018
|
+
};
|
|
1775
3019
|
|
|
1776
3020
|
//#endregion
|
|
1777
3021
|
//#region ../../src/core/form/utils/parseInput.ts
|
|
1778
3022
|
const parseInput = (props, form) => {
|
|
1779
3023
|
const disabled = false;
|
|
1780
3024
|
const id = props.input.props.id;
|
|
1781
|
-
const label = props.
|
|
3025
|
+
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);
|
|
1782
3026
|
const description = props.description ?? ("description" in props.input.schema && typeof props.input.schema.description === "string" ? props.input.schema.description : void 0);
|
|
1783
3027
|
const error = form.error && form.error instanceof TypeBoxError ? form.error.value.message : void 0;
|
|
1784
3028
|
const icon = !props.icon ? getDefaultIcon({
|
|
@@ -1786,17 +3030,20 @@ const parseInput = (props, form) => {
|
|
|
1786
3030
|
format: props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0,
|
|
1787
3031
|
name: props.input.props.name,
|
|
1788
3032
|
isEnum: props.input.schema && "enum" in props.input.schema && Boolean(props.input.schema.enum),
|
|
1789
|
-
isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array"
|
|
1790
|
-
|
|
3033
|
+
isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array",
|
|
3034
|
+
size: props.size
|
|
3035
|
+
}) : isValidElement(props.icon) ? props.icon : createElement(props.icon, { size: ui.sizes.icon.sm });
|
|
1791
3036
|
const format = props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0;
|
|
1792
3037
|
const required = props.input.required;
|
|
1793
3038
|
const schema = props.input.schema;
|
|
3039
|
+
const testId = props.input.props?.["data-testid"];
|
|
1794
3040
|
const inputProps = {
|
|
1795
3041
|
label,
|
|
1796
3042
|
description,
|
|
1797
3043
|
error,
|
|
1798
3044
|
required,
|
|
1799
|
-
disabled
|
|
3045
|
+
disabled,
|
|
3046
|
+
...testId ? { "data-testid": testId } : {}
|
|
1800
3047
|
};
|
|
1801
3048
|
if ("minLength" in schema && typeof schema.minLength === "number") inputProps.minLength = schema.minLength;
|
|
1802
3049
|
if ("maxLength" in schema && typeof schema.maxLength === "number") inputProps.maxLength = schema.maxLength;
|
|
@@ -1821,8 +3068,8 @@ const useArrayItems = (input) => {
|
|
|
1821
3068
|
const alepha = useAlepha();
|
|
1822
3069
|
const keyCounter = useRef(0);
|
|
1823
3070
|
const [items, setItemsState] = useState(() => {
|
|
1824
|
-
const
|
|
1825
|
-
if (Array.isArray(
|
|
3071
|
+
const initial = input?.initialValue;
|
|
3072
|
+
if (Array.isArray(initial)) return initial.map((value) => ({
|
|
1826
3073
|
key: keyCounter.current++,
|
|
1827
3074
|
value
|
|
1828
3075
|
}));
|
|
@@ -1848,22 +3095,9 @@ const useArrayItems = (input) => {
|
|
|
1848
3095
|
if (!input?.form) return;
|
|
1849
3096
|
const formId = input.form.id;
|
|
1850
3097
|
const fieldPath = input.path;
|
|
1851
|
-
|
|
1852
|
-
if (event.id === formId) {
|
|
1853
|
-
const defaultValue = input.props?.defaultValue;
|
|
1854
|
-
keyCounter.current = 0;
|
|
1855
|
-
if (Array.isArray(defaultValue)) setItemsState(defaultValue.map((value) => ({
|
|
1856
|
-
key: keyCounter.current++,
|
|
1857
|
-
value
|
|
1858
|
-
})));
|
|
1859
|
-
else setItemsState([]);
|
|
1860
|
-
}
|
|
1861
|
-
}), alepha.events.on("form:change", (event) => {
|
|
3098
|
+
return alepha.events.on("form:change", (event) => {
|
|
1862
3099
|
if (event.id === formId && event.path === fieldPath) syncFromFormValue(event.value);
|
|
1863
|
-
})
|
|
1864
|
-
return () => {
|
|
1865
|
-
for (const unsub of listeners) unsub();
|
|
1866
|
-
};
|
|
3100
|
+
});
|
|
1867
3101
|
}, [
|
|
1868
3102
|
alepha,
|
|
1869
3103
|
input,
|
|
@@ -1888,10 +3122,10 @@ const createArrayItemInput = (parentInput, itemSchema, index, _itemKey, value, o
|
|
|
1888
3122
|
path: `${parentInput.path}/${index}`,
|
|
1889
3123
|
required: false,
|
|
1890
3124
|
form: parentInput.form,
|
|
3125
|
+
initialValue: value,
|
|
1891
3126
|
props: {
|
|
1892
3127
|
id: `${parentInput.props.id}-${index}`,
|
|
1893
|
-
name: `${parentInput.props.name}[${index}]
|
|
1894
|
-
defaultValue: value
|
|
3128
|
+
name: `${parentInput.props.name}[${index}]`
|
|
1895
3129
|
},
|
|
1896
3130
|
set: onValueChange
|
|
1897
3131
|
};
|
|
@@ -1906,10 +3140,10 @@ const createArrayItemFieldInput = (parentInput, itemSchema, fieldName, index, _i
|
|
|
1906
3140
|
path: `${parentInput.path}/${index}/${fieldName}`,
|
|
1907
3141
|
required: itemSchema.required?.includes(fieldName) ?? false,
|
|
1908
3142
|
form: parentInput.form,
|
|
3143
|
+
initialValue: itemValue?.[fieldName],
|
|
1909
3144
|
props: {
|
|
1910
3145
|
id: `${parentInput.props.id}-${index}-${fieldName}`,
|
|
1911
|
-
name: `${parentInput.props.name}[${index}].${fieldName}
|
|
1912
|
-
defaultValue: itemValue?.[fieldName]
|
|
3146
|
+
name: `${parentInput.props.name}[${index}].${fieldName}`
|
|
1913
3147
|
},
|
|
1914
3148
|
set: (value) => onFieldChange(fieldName, value)
|
|
1915
3149
|
};
|
|
@@ -2127,7 +3361,9 @@ const ControlArray = (props) => {
|
|
|
2127
3361
|
* Automatically detects date formats from schema and renders appropriate picker.
|
|
2128
3362
|
*/
|
|
2129
3363
|
const ControlDate = (props) => {
|
|
2130
|
-
const
|
|
3364
|
+
const form = useFormState(props.input);
|
|
3365
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3366
|
+
const { inputProps, id, icon, format } = parseInput(props, form);
|
|
2131
3367
|
if (!props.input?.props) return null;
|
|
2132
3368
|
if (props.datetime || format === "date-time") {
|
|
2133
3369
|
const dateTimePickerProps = typeof props.datetime === "object" ? props.datetime : {};
|
|
@@ -2135,10 +3371,8 @@ const ControlDate = (props) => {
|
|
|
2135
3371
|
...inputProps,
|
|
2136
3372
|
id,
|
|
2137
3373
|
leftSection: icon,
|
|
2138
|
-
|
|
2139
|
-
onChange: (
|
|
2140
|
-
props.input.set(value ? new Date(value).toISOString() : void 0);
|
|
2141
|
-
},
|
|
3374
|
+
value: value ? new Date(value) : null,
|
|
3375
|
+
onChange: (val) => setValue(val ? new Date(val).toISOString() : void 0),
|
|
2142
3376
|
...dateTimePickerProps
|
|
2143
3377
|
});
|
|
2144
3378
|
}
|
|
@@ -2148,10 +3382,8 @@ const ControlDate = (props) => {
|
|
|
2148
3382
|
...inputProps,
|
|
2149
3383
|
id,
|
|
2150
3384
|
leftSection: icon,
|
|
2151
|
-
|
|
2152
|
-
onChange: (
|
|
2153
|
-
props.input.set(value ? new Date(value).toISOString().slice(0, 10) : void 0);
|
|
2154
|
-
},
|
|
3385
|
+
value: value ? new Date(value) : null,
|
|
3386
|
+
onChange: (val) => setValue(val ? new Date(val).toISOString().slice(0, 10) : void 0),
|
|
2155
3387
|
...dateInputProps
|
|
2156
3388
|
});
|
|
2157
3389
|
}
|
|
@@ -2161,10 +3393,8 @@ const ControlDate = (props) => {
|
|
|
2161
3393
|
...inputProps,
|
|
2162
3394
|
id,
|
|
2163
3395
|
leftSection: icon,
|
|
2164
|
-
|
|
2165
|
-
onChange: (event) =>
|
|
2166
|
-
props.input.set(event.currentTarget.value);
|
|
2167
|
-
},
|
|
3396
|
+
value: value ?? "",
|
|
3397
|
+
onChange: (event) => setValue(event.currentTarget.value),
|
|
2168
3398
|
...timeInputProps
|
|
2169
3399
|
});
|
|
2170
3400
|
}
|
|
@@ -2177,14 +3407,10 @@ const ControlDate = (props) => {
|
|
|
2177
3407
|
*
|
|
2178
3408
|
*/
|
|
2179
3409
|
const ControlNumber = (props) => {
|
|
2180
|
-
const
|
|
2181
|
-
const
|
|
2182
|
-
const
|
|
2183
|
-
useEvents({ "form:reset": (event) => {
|
|
2184
|
-
if (event.id === props.input?.form.id && ref.current) setValue(props.input.props.defaultValue);
|
|
2185
|
-
} }, [props.input]);
|
|
3410
|
+
const form = useFormState(props.input);
|
|
3411
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3412
|
+
const { inputProps, id, icon } = parseInput(props, form);
|
|
2186
3413
|
if (!props.input?.props) return null;
|
|
2187
|
-
const { type, ...inputPropsWithoutType } = props.input.props;
|
|
2188
3414
|
if (props.sliderProps) {
|
|
2189
3415
|
const min = props.sliderProps.min ?? inputProps.minimum ?? 0;
|
|
2190
3416
|
const max = props.sliderProps.max ?? inputProps.maximum ?? 100;
|
|
@@ -2197,34 +3423,25 @@ const ControlNumber = (props) => {
|
|
|
2197
3423
|
},
|
|
2198
3424
|
children: /* @__PURE__ */ jsx(Slider, {
|
|
2199
3425
|
...inputProps,
|
|
2200
|
-
ref,
|
|
2201
3426
|
id,
|
|
2202
|
-
...inputPropsWithoutType,
|
|
2203
3427
|
...props.sliderProps,
|
|
2204
|
-
value,
|
|
3428
|
+
value: value ?? 0,
|
|
2205
3429
|
min,
|
|
2206
3430
|
max,
|
|
2207
3431
|
label: () => value,
|
|
2208
|
-
onChange: (val) =>
|
|
2209
|
-
setValue(val);
|
|
2210
|
-
props.input.set(val);
|
|
2211
|
-
}
|
|
3432
|
+
onChange: (val) => setValue(val)
|
|
2212
3433
|
})
|
|
2213
3434
|
})
|
|
2214
3435
|
});
|
|
2215
3436
|
}
|
|
2216
3437
|
return /* @__PURE__ */ jsx(NumberInput, {
|
|
2217
3438
|
...inputProps,
|
|
2218
|
-
ref,
|
|
2219
3439
|
id,
|
|
2220
3440
|
leftSection: icon,
|
|
2221
|
-
...inputPropsWithoutType,
|
|
2222
3441
|
...props.numberInputProps,
|
|
2223
3442
|
value: value ?? "",
|
|
2224
3443
|
onChange: (val) => {
|
|
2225
|
-
|
|
2226
|
-
setValue(newValue);
|
|
2227
|
-
props.input.set(newValue);
|
|
3444
|
+
setValue(val !== null ? Number(val) : void 0);
|
|
2228
3445
|
}
|
|
2229
3446
|
});
|
|
2230
3447
|
};
|
|
@@ -2307,92 +3524,9 @@ const ControlObject = (props) => {
|
|
|
2307
3524
|
};
|
|
2308
3525
|
|
|
2309
3526
|
//#endregion
|
|
2310
|
-
//#region ../../src/core/form/components/
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
* Generates query strings for parseQueryString syntax.
|
|
2314
|
-
*/
|
|
2315
|
-
const ControlQueryBuilder = ({ schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps }) => {
|
|
2316
|
-
const [helpOpened, setHelpOpened] = useState(false);
|
|
2317
|
-
const [textValue, setTextValue] = useState(value);
|
|
2318
|
-
const inputRef = useRef(null);
|
|
2319
|
-
const fields = schema ? extractSchemaFields(schema) : [];
|
|
2320
|
-
const [error, setError] = useState(null);
|
|
2321
|
-
const isValid = (value) => {
|
|
2322
|
-
try {
|
|
2323
|
-
parseQueryString(value.trim());
|
|
2324
|
-
} catch (e) {
|
|
2325
|
-
setError(e.message);
|
|
2326
|
-
return false;
|
|
2327
|
-
}
|
|
2328
|
-
setError(null);
|
|
2329
|
-
return true;
|
|
2330
|
-
};
|
|
2331
|
-
const handleTextChange = (newValue) => {
|
|
2332
|
-
setTextValue(newValue);
|
|
2333
|
-
if (isValid(newValue)) onChange?.(newValue);
|
|
2334
|
-
};
|
|
2335
|
-
const handleClear = () => {
|
|
2336
|
-
setTextValue("");
|
|
2337
|
-
onChange?.("");
|
|
2338
|
-
isValid("");
|
|
2339
|
-
};
|
|
2340
|
-
const handleInsert = (text) => {
|
|
2341
|
-
const newValue = textValue ? `${textValue}${text} ` : `${text} `;
|
|
2342
|
-
setTextValue(newValue);
|
|
2343
|
-
if (isValid(newValue)) onChange?.(newValue);
|
|
2344
|
-
setTimeout(() => {
|
|
2345
|
-
inputRef.current?.focus();
|
|
2346
|
-
const length = inputRef.current?.value.length || 0;
|
|
2347
|
-
inputRef.current?.setSelectionRange(length, length);
|
|
2348
|
-
}, 0);
|
|
2349
|
-
};
|
|
2350
|
-
useEvents({ "form:change": (event) => {
|
|
2351
|
-
if (event.id === inputRef.current?.form?.id) {
|
|
2352
|
-
if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
|
|
2353
|
-
}
|
|
2354
|
-
} }, []);
|
|
2355
|
-
return /* @__PURE__ */ jsxs(Popover, {
|
|
2356
|
-
width: 800,
|
|
2357
|
-
position: "bottom-start",
|
|
2358
|
-
shadow: "md",
|
|
2359
|
-
opened: helpOpened,
|
|
2360
|
-
onChange: setHelpOpened,
|
|
2361
|
-
closeOnClickOutside: true,
|
|
2362
|
-
closeOnEscape: true,
|
|
2363
|
-
transitionProps: {
|
|
2364
|
-
transition: "fade-up",
|
|
2365
|
-
duration: 200,
|
|
2366
|
-
timingFunction: "ease"
|
|
2367
|
-
},
|
|
2368
|
-
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
|
|
2369
|
-
ref: inputRef,
|
|
2370
|
-
placeholder,
|
|
2371
|
-
value: textValue,
|
|
2372
|
-
onChange: (e) => handleTextChange(e.currentTarget.value),
|
|
2373
|
-
onFocus: () => setHelpOpened(true),
|
|
2374
|
-
leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
|
|
2375
|
-
rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
|
|
2376
|
-
size: "sm",
|
|
2377
|
-
variant: "subtle",
|
|
2378
|
-
color: "gray",
|
|
2379
|
-
onClick: handleClear,
|
|
2380
|
-
children: /* @__PURE__ */ jsx(IconX, { size: 14 })
|
|
2381
|
-
}),
|
|
2382
|
-
...textInputProps
|
|
2383
|
-
}) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
2384
|
-
bg: "transparent",
|
|
2385
|
-
p: "xs",
|
|
2386
|
-
bd: `1px solid ${ui.colors.border}`,
|
|
2387
|
-
style: { backdropFilter: "blur(20px)" },
|
|
2388
|
-
children: /* @__PURE__ */ jsx(QueryHelp, {
|
|
2389
|
-
fields,
|
|
2390
|
-
onInsert: handleInsert
|
|
2391
|
-
})
|
|
2392
|
-
})]
|
|
2393
|
-
});
|
|
2394
|
-
};
|
|
2395
|
-
function QueryHelp({ fields, onInsert }) {
|
|
3527
|
+
//#region ../../src/core/form/components/ControlQueryBuilderHelp.tsx
|
|
3528
|
+
const ControlQueryBuilderHelp = (props) => {
|
|
3529
|
+
const { fields, onInsert } = props;
|
|
2396
3530
|
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2397
3531
|
gap: "md",
|
|
2398
3532
|
align: "flex-start",
|
|
@@ -2555,111 +3689,314 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2555
3689
|
})
|
|
2556
3690
|
]
|
|
2557
3691
|
});
|
|
2558
|
-
}
|
|
3692
|
+
};
|
|
3693
|
+
|
|
3694
|
+
//#endregion
|
|
3695
|
+
//#region ../../src/core/form/components/ControlQueryBuilder.tsx
|
|
3696
|
+
/**
|
|
3697
|
+
* Query builder with text input and help popover.
|
|
3698
|
+
* Generates query strings for parseQueryString syntax.
|
|
3699
|
+
*/
|
|
3700
|
+
const ControlQueryBuilder = (props) => {
|
|
3701
|
+
const { schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps } = props;
|
|
3702
|
+
const [helpOpened, setHelpOpened] = useState(false);
|
|
3703
|
+
const [textValue, setTextValue] = useState(value);
|
|
3704
|
+
const inputRef = useRef(null);
|
|
3705
|
+
const fields = schema ? extractSchemaFields(schema) : [];
|
|
3706
|
+
const [error, setError] = useState(null);
|
|
3707
|
+
const isValid = (value) => {
|
|
3708
|
+
try {
|
|
3709
|
+
parseQueryString(value.trim());
|
|
3710
|
+
} catch (e) {
|
|
3711
|
+
setError(e.message);
|
|
3712
|
+
return false;
|
|
3713
|
+
}
|
|
3714
|
+
setError(null);
|
|
3715
|
+
return true;
|
|
3716
|
+
};
|
|
3717
|
+
const handleTextChange = (newValue) => {
|
|
3718
|
+
setTextValue(newValue);
|
|
3719
|
+
if (isValid(newValue)) onChange?.(newValue);
|
|
3720
|
+
};
|
|
3721
|
+
const handleClear = () => {
|
|
3722
|
+
setTextValue("");
|
|
3723
|
+
onChange?.("");
|
|
3724
|
+
isValid("");
|
|
3725
|
+
};
|
|
3726
|
+
const handleInsert = (text) => {
|
|
3727
|
+
const newValue = textValue ? `${textValue}${text} ` : `${text} `;
|
|
3728
|
+
setTextValue(newValue);
|
|
3729
|
+
if (isValid(newValue)) onChange?.(newValue);
|
|
3730
|
+
setTimeout(() => {
|
|
3731
|
+
inputRef.current?.focus();
|
|
3732
|
+
const length = inputRef.current?.value.length || 0;
|
|
3733
|
+
inputRef.current?.setSelectionRange(length, length);
|
|
3734
|
+
}, 0);
|
|
3735
|
+
};
|
|
3736
|
+
useEvents({ "form:change": (event) => {
|
|
3737
|
+
if (event.id === inputRef.current?.form?.id) {
|
|
3738
|
+
if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
|
|
3739
|
+
}
|
|
3740
|
+
} }, []);
|
|
3741
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
3742
|
+
width: 800,
|
|
3743
|
+
position: "bottom-start",
|
|
3744
|
+
shadow: "md",
|
|
3745
|
+
opened: helpOpened,
|
|
3746
|
+
onChange: setHelpOpened,
|
|
3747
|
+
closeOnClickOutside: true,
|
|
3748
|
+
closeOnEscape: true,
|
|
3749
|
+
transitionProps: {
|
|
3750
|
+
transition: "fade-up",
|
|
3751
|
+
duration: 200,
|
|
3752
|
+
timingFunction: "ease"
|
|
3753
|
+
},
|
|
3754
|
+
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
|
|
3755
|
+
ref: inputRef,
|
|
3756
|
+
placeholder,
|
|
3757
|
+
value: textValue,
|
|
3758
|
+
onChange: (e) => handleTextChange(e.currentTarget.value),
|
|
3759
|
+
onFocus: () => setHelpOpened(true),
|
|
3760
|
+
leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
|
|
3761
|
+
rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
|
|
3762
|
+
size: "sm",
|
|
3763
|
+
variant: "subtle",
|
|
3764
|
+
color: "gray",
|
|
3765
|
+
onClick: handleClear,
|
|
3766
|
+
children: /* @__PURE__ */ jsx(IconX, { size: 14 })
|
|
3767
|
+
}),
|
|
3768
|
+
...textInputProps
|
|
3769
|
+
}) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3770
|
+
bg: "transparent",
|
|
3771
|
+
p: "xs",
|
|
3772
|
+
bd: `1px solid ${ui.colors.border}`,
|
|
3773
|
+
style: { backdropFilter: "blur(20px)" },
|
|
3774
|
+
children: /* @__PURE__ */ jsx(ControlQueryBuilderHelp, {
|
|
3775
|
+
fields,
|
|
3776
|
+
onInsert: handleInsert
|
|
3777
|
+
})
|
|
3778
|
+
})]
|
|
3779
|
+
});
|
|
3780
|
+
};
|
|
2559
3781
|
|
|
2560
3782
|
//#endregion
|
|
2561
3783
|
//#region ../../src/core/form/components/ControlSelect.tsx
|
|
2562
3784
|
/**
|
|
2563
|
-
* ControlSelect component for handling Select, MultiSelect, and TagsInput.
|
|
3785
|
+
* ControlSelect component for handling Select, MultiSelect, Autocomplete, and TagsInput.
|
|
2564
3786
|
*
|
|
2565
3787
|
* Features:
|
|
2566
3788
|
* - Basic Select with enum support
|
|
2567
3789
|
* - MultiSelect for array of enums
|
|
2568
|
-
* -
|
|
2569
|
-
* -
|
|
2570
|
-
* -
|
|
2571
|
-
* -
|
|
3790
|
+
* - Autocomplete for creatable single values
|
|
3791
|
+
* - TagsInput for creatable array values
|
|
3792
|
+
* - Async lazy loading with auto short/long mode detection
|
|
3793
|
+
* - Short mode: client-side filtering with cached data
|
|
3794
|
+
* - Long mode: debounced server search
|
|
2572
3795
|
*
|
|
2573
3796
|
* Automatically detects enum values and array types from schema.
|
|
2574
3797
|
*/
|
|
2575
3798
|
const ControlSelect = (props) => {
|
|
2576
|
-
const
|
|
3799
|
+
const form = useFormState(props.input);
|
|
3800
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3801
|
+
const { inputProps, id, icon } = parseInput(props, form);
|
|
2577
3802
|
const isArray = props.input.schema && "type" in props.input.schema && props.input.schema.type === "array";
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
const items = props.input.schema.items;
|
|
2581
|
-
if ("enum" in items && Array.isArray(items.enum)) itemsEnum = items.enum;
|
|
2582
|
-
}
|
|
3803
|
+
const isNumeric = props.input.schema && "type" in props.input.schema && (props.input.schema.type === "integer" || props.input.schema.type === "number");
|
|
3804
|
+
const isBoolean = props.input.schema && "type" in props.input.schema && props.input.schema.type === "boolean";
|
|
2583
3805
|
const enumValues = props.input.schema && "enum" in props.input.schema && Array.isArray(props.input.schema.enum) ? props.input.schema.enum : [];
|
|
2584
|
-
const
|
|
3806
|
+
const { data: asyncData, loading, mode, search } = useAsyncLoader(props.loader, props.loaderThreshold ?? 100, props.loaderDebounce ?? 300, props.input.initialValue);
|
|
3807
|
+
const [staticData, setStaticData] = useState([]);
|
|
3808
|
+
const enumKey = JSON.stringify(enumValues);
|
|
2585
3809
|
useEffect(() => {
|
|
2586
|
-
if (!props.input?.props) return;
|
|
2587
|
-
if (
|
|
2588
|
-
|
|
2589
|
-
|
|
3810
|
+
if (!props.input?.props || props.loader) return;
|
|
3811
|
+
if (isBoolean && enumValues.length === 0) setStaticData([{
|
|
3812
|
+
value: "true",
|
|
3813
|
+
label: "True"
|
|
3814
|
+
}, {
|
|
3815
|
+
value: "false",
|
|
3816
|
+
label: "False"
|
|
3817
|
+
}]);
|
|
3818
|
+
else setStaticData(enumValues);
|
|
3819
|
+
}, [
|
|
3820
|
+
props.input,
|
|
3821
|
+
props.loader,
|
|
3822
|
+
enumKey,
|
|
3823
|
+
isBoolean
|
|
3824
|
+
]);
|
|
3825
|
+
const data = props.loader ? asyncData : staticData;
|
|
2590
3826
|
if (!props.input?.props) return null;
|
|
2591
|
-
|
|
2592
|
-
|
|
3827
|
+
/**
|
|
3828
|
+
* Coerce value for numeric schemas — Select values are always strings.
|
|
3829
|
+
*/
|
|
3830
|
+
const coerceValue = (val) => {
|
|
3831
|
+
if (val == null) return val;
|
|
3832
|
+
if (isNumeric) return Number(val);
|
|
3833
|
+
if (isBoolean) return val === "true";
|
|
3834
|
+
return val;
|
|
3835
|
+
};
|
|
3836
|
+
if (props.segmentedProps) {
|
|
3837
|
+
const segmentedControlProps = typeof props.segmentedProps === "object" ? props.segmentedProps : {};
|
|
3838
|
+
const segmentedData = segmentedControlProps.data ?? data.slice(0, 10);
|
|
2593
3839
|
return /* @__PURE__ */ jsx(Input.Wrapper, {
|
|
2594
3840
|
...inputProps,
|
|
2595
|
-
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
2602
|
-
|
|
2603
|
-
|
|
3841
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
3842
|
+
my: "calc(var(--mantine-spacing-xs) / 2)",
|
|
3843
|
+
children: /* @__PURE__ */ jsx(SegmentedControl, {
|
|
3844
|
+
disabled: inputProps.disabled,
|
|
3845
|
+
value: value != null ? String(value) : "",
|
|
3846
|
+
...segmentedControlProps,
|
|
3847
|
+
onChange: (val) => {
|
|
3848
|
+
setValue(coerceValue(val));
|
|
3849
|
+
},
|
|
3850
|
+
data: segmentedData
|
|
3851
|
+
})
|
|
3852
|
+
})
|
|
2604
3853
|
});
|
|
2605
3854
|
}
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
3855
|
+
const sharedProps = {
|
|
3856
|
+
size: props.size,
|
|
3857
|
+
id,
|
|
3858
|
+
leftSection: loading ? /* @__PURE__ */ jsx(Loader, {
|
|
3859
|
+
color: "gray",
|
|
3860
|
+
size: 10
|
|
3861
|
+
}) : icon,
|
|
3862
|
+
data
|
|
3863
|
+
};
|
|
3864
|
+
const selectableProps = {
|
|
3865
|
+
...sharedProps,
|
|
3866
|
+
searchable: true,
|
|
3867
|
+
rightSection: /* @__PURE__ */ jsx("span", {})
|
|
3868
|
+
};
|
|
3869
|
+
const longModeProps = mode === "long" ? {
|
|
3870
|
+
filter: ({ options }) => options,
|
|
3871
|
+
onSearchChange: search.run
|
|
3872
|
+
} : {};
|
|
3873
|
+
if (props.creatable && (isArray || props.tagsInputProps)) {
|
|
3874
|
+
const tagsInputExtraProps = props.tagsInputProps ?? {};
|
|
3875
|
+
return /* @__PURE__ */ jsx(TagsInput, {
|
|
2609
3876
|
...inputProps,
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
3877
|
+
...sharedProps,
|
|
3878
|
+
...longModeProps,
|
|
3879
|
+
value: Array.isArray(value) ? value : [],
|
|
3880
|
+
onChange: (val) => {
|
|
3881
|
+
setValue(val);
|
|
3882
|
+
},
|
|
3883
|
+
...tagsInputExtraProps
|
|
2616
3884
|
});
|
|
2617
3885
|
}
|
|
2618
|
-
if (
|
|
2619
|
-
const
|
|
2620
|
-
return /* @__PURE__ */ jsx(
|
|
3886
|
+
if (props.creatable) {
|
|
3887
|
+
const autocompleteExtraProps = props.autocompleteProps ?? {};
|
|
3888
|
+
return /* @__PURE__ */ jsx(Autocomplete, {
|
|
2621
3889
|
...inputProps,
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
props.input.set(value);
|
|
3890
|
+
...sharedProps,
|
|
3891
|
+
...longModeProps,
|
|
3892
|
+
value: value != null ? String(value) : "",
|
|
3893
|
+
onChange: (val) => {
|
|
3894
|
+
setValue(coerceValue(val));
|
|
2628
3895
|
},
|
|
2629
|
-
...
|
|
3896
|
+
...autocompleteExtraProps
|
|
2630
3897
|
});
|
|
2631
3898
|
}
|
|
2632
|
-
if (isArray
|
|
2633
|
-
const
|
|
2634
|
-
value,
|
|
2635
|
-
label: value
|
|
2636
|
-
})) || [];
|
|
2637
|
-
const multiSelectProps = typeof props.multi === "object" ? props.multi : {};
|
|
3899
|
+
if (isArray || props.multiSelectProps) {
|
|
3900
|
+
const multiSelectExtraProps = typeof props.multiSelectProps === "object" ? props.multiSelectProps : {};
|
|
2638
3901
|
return /* @__PURE__ */ jsx(MultiSelect, {
|
|
2639
3902
|
...inputProps,
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
onChange: (value) => {
|
|
2646
|
-
props.input.set(value);
|
|
3903
|
+
...selectableProps,
|
|
3904
|
+
...longModeProps,
|
|
3905
|
+
value: Array.isArray(value) ? value : [],
|
|
3906
|
+
onChange: (val) => {
|
|
3907
|
+
setValue(val);
|
|
2647
3908
|
},
|
|
2648
|
-
...
|
|
3909
|
+
...multiSelectExtraProps
|
|
2649
3910
|
});
|
|
2650
3911
|
}
|
|
2651
|
-
const
|
|
3912
|
+
const selectExtraProps = typeof props.selectProps === "object" ? props.selectProps : {};
|
|
3913
|
+
if (mode === "static") return /* @__PURE__ */ jsx(Select, {
|
|
3914
|
+
...inputProps,
|
|
3915
|
+
...selectableProps,
|
|
3916
|
+
value: value != null ? String(value) : null,
|
|
3917
|
+
onChange: (val) => {
|
|
3918
|
+
setValue(coerceValue(val));
|
|
3919
|
+
},
|
|
3920
|
+
...selectExtraProps
|
|
3921
|
+
});
|
|
2652
3922
|
return /* @__PURE__ */ jsx(Select, {
|
|
2653
3923
|
...inputProps,
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2658
|
-
|
|
2659
|
-
|
|
2660
|
-
...
|
|
3924
|
+
...selectableProps,
|
|
3925
|
+
...longModeProps,
|
|
3926
|
+
value: value != null ? String(value) : null,
|
|
3927
|
+
onChange: (val) => {
|
|
3928
|
+
setValue(coerceValue(val));
|
|
3929
|
+
},
|
|
3930
|
+
...selectExtraProps
|
|
2661
3931
|
});
|
|
2662
3932
|
};
|
|
3933
|
+
/**
|
|
3934
|
+
* Hook for async select data loading with auto short/long mode detection.
|
|
3935
|
+
*/
|
|
3936
|
+
const useAsyncLoader = (loader, threshold, debounceMs, defaultValue) => {
|
|
3937
|
+
const [data, setData] = useState([]);
|
|
3938
|
+
const [loading, setLoading] = useState(false);
|
|
3939
|
+
const [mode, setMode] = useState("static");
|
|
3940
|
+
const cache = useRef(/* @__PURE__ */ new Map());
|
|
3941
|
+
useAction({
|
|
3942
|
+
name: "select:loader:init",
|
|
3943
|
+
runOnInit: true,
|
|
3944
|
+
handler: async () => {
|
|
3945
|
+
if (!loader) {
|
|
3946
|
+
setMode("static");
|
|
3947
|
+
return;
|
|
3948
|
+
}
|
|
3949
|
+
setLoading(true);
|
|
3950
|
+
try {
|
|
3951
|
+
const result = await loader("");
|
|
3952
|
+
const isShort = result.length <= threshold;
|
|
3953
|
+
setMode(isShort ? "short" : "long");
|
|
3954
|
+
cache.current.set("", result);
|
|
3955
|
+
setData(result);
|
|
3956
|
+
if (!isShort && defaultValue != null && String(defaultValue) !== "") {
|
|
3957
|
+
const resolved = await loader("", [String(defaultValue)]);
|
|
3958
|
+
if (resolved.length > 0) setData((prev) => {
|
|
3959
|
+
const existing = new Set(prev.map((d) => typeof d === "string" ? d : d.value));
|
|
3960
|
+
const newItems = resolved.filter((r) => {
|
|
3961
|
+
const val = typeof r === "string" ? r : r.value;
|
|
3962
|
+
return !existing.has(val);
|
|
3963
|
+
});
|
|
3964
|
+
return [...prev, ...newItems];
|
|
3965
|
+
});
|
|
3966
|
+
}
|
|
3967
|
+
} finally {
|
|
3968
|
+
setLoading(false);
|
|
3969
|
+
}
|
|
3970
|
+
}
|
|
3971
|
+
}, [loader, threshold]);
|
|
3972
|
+
return {
|
|
3973
|
+
data,
|
|
3974
|
+
loading,
|
|
3975
|
+
mode,
|
|
3976
|
+
search: useAction({
|
|
3977
|
+
debounce: debounceMs,
|
|
3978
|
+
handler: async (text) => {
|
|
3979
|
+
if (!loader || mode !== "long") return;
|
|
3980
|
+
if (cache.current.has(text)) {
|
|
3981
|
+
setData(cache.current.get(text));
|
|
3982
|
+
return;
|
|
3983
|
+
}
|
|
3984
|
+
setLoading(true);
|
|
3985
|
+
try {
|
|
3986
|
+
const result = await loader(text);
|
|
3987
|
+
cache.current.set(text, result);
|
|
3988
|
+
setData(result);
|
|
3989
|
+
} finally {
|
|
3990
|
+
setLoading(false);
|
|
3991
|
+
}
|
|
3992
|
+
}
|
|
3993
|
+
}, [
|
|
3994
|
+
loader,
|
|
3995
|
+
mode,
|
|
3996
|
+
debounceMs
|
|
3997
|
+
])
|
|
3998
|
+
};
|
|
3999
|
+
};
|
|
2663
4000
|
|
|
2664
4001
|
//#endregion
|
|
2665
4002
|
//#region ../../src/core/form/components/Control.tsx
|
|
@@ -2689,6 +4026,7 @@ const ControlSelect = (props) => {
|
|
|
2689
4026
|
*/
|
|
2690
4027
|
const Control = (_props) => {
|
|
2691
4028
|
const form = useFormState(_props.input, ["error"]);
|
|
4029
|
+
const [value, setValue] = useFieldValue(_props.input);
|
|
2692
4030
|
if (!_props.input?.props) return null;
|
|
2693
4031
|
const { inputProps, id, icon, format, schema } = parseInput(_props, form);
|
|
2694
4032
|
const props = {
|
|
@@ -2696,12 +4034,11 @@ const Control = (_props) => {
|
|
|
2696
4034
|
...schema.$control
|
|
2697
4035
|
};
|
|
2698
4036
|
if (props.query) return /* @__PURE__ */ jsx(ControlQueryBuilder, {
|
|
2699
|
-
...props.input.props,
|
|
2700
4037
|
...inputProps,
|
|
2701
4038
|
schema: props.query,
|
|
2702
|
-
value
|
|
2703
|
-
onChange: (
|
|
2704
|
-
|
|
4039
|
+
value,
|
|
4040
|
+
onChange: (val) => {
|
|
4041
|
+
setValue(val);
|
|
2705
4042
|
}
|
|
2706
4043
|
});
|
|
2707
4044
|
if (props.custom) {
|
|
@@ -2712,9 +4049,9 @@ const Control = (_props) => {
|
|
|
2712
4049
|
flex: 1,
|
|
2713
4050
|
mt: "calc(var(--mantine-spacing-xs) / 2)",
|
|
2714
4051
|
children: /* @__PURE__ */ jsx(Custom, {
|
|
2715
|
-
|
|
2716
|
-
onChange: (
|
|
2717
|
-
|
|
4052
|
+
value,
|
|
4053
|
+
onChange: (val) => {
|
|
4054
|
+
setValue(val);
|
|
2718
4055
|
}
|
|
2719
4056
|
})
|
|
2720
4057
|
})
|
|
@@ -2725,7 +4062,7 @@ const Control = (_props) => {
|
|
|
2725
4062
|
const controlObjectProps = typeof props.object === "object" ? props.object : {};
|
|
2726
4063
|
return /* @__PURE__ */ jsx(ControlObject, {
|
|
2727
4064
|
input: props.input,
|
|
2728
|
-
|
|
4065
|
+
label: props.label,
|
|
2729
4066
|
description: props.description,
|
|
2730
4067
|
...controlObjectProps
|
|
2731
4068
|
});
|
|
@@ -2736,18 +4073,18 @@ const Control = (_props) => {
|
|
|
2736
4073
|
const controlArrayProps = typeof props.array === "object" ? props.array : {};
|
|
2737
4074
|
return /* @__PURE__ */ jsx(ControlArray, {
|
|
2738
4075
|
input: props.input,
|
|
2739
|
-
|
|
4076
|
+
label: props.label,
|
|
2740
4077
|
description: props.description,
|
|
2741
4078
|
...controlArrayProps
|
|
2742
4079
|
});
|
|
2743
4080
|
}
|
|
2744
|
-
if (props.number || props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
|
|
4081
|
+
if (props.number || !props.select && props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
|
|
2745
4082
|
const controlNumberProps = typeof props.number === "object" ? props.number : {};
|
|
2746
4083
|
if (props.slider) controlNumberProps.sliderProps ??= {};
|
|
2747
4084
|
return /* @__PURE__ */ jsx(ControlNumber, {
|
|
2748
4085
|
size: props.size,
|
|
2749
4086
|
input: props.input,
|
|
2750
|
-
|
|
4087
|
+
label: props.label,
|
|
2751
4088
|
description: props.description,
|
|
2752
4089
|
icon,
|
|
2753
4090
|
...controlNumberProps
|
|
@@ -2760,9 +4097,7 @@ const Control = (_props) => {
|
|
|
2760
4097
|
size: props.size,
|
|
2761
4098
|
id,
|
|
2762
4099
|
leftSection: icon,
|
|
2763
|
-
onChange: (file) =>
|
|
2764
|
-
props.input.set(file);
|
|
2765
|
-
},
|
|
4100
|
+
onChange: (file) => setValue(file),
|
|
2766
4101
|
...fileInputProps
|
|
2767
4102
|
});
|
|
2768
4103
|
}
|
|
@@ -2773,17 +4108,18 @@ const Control = (_props) => {
|
|
|
2773
4108
|
size: props.size,
|
|
2774
4109
|
id,
|
|
2775
4110
|
leftSection: icon,
|
|
2776
|
-
|
|
4111
|
+
value: value ?? "",
|
|
4112
|
+
onChange: (val) => setValue(val),
|
|
2777
4113
|
...colorInputProps
|
|
2778
4114
|
});
|
|
2779
4115
|
}
|
|
2780
4116
|
if (props.input.schema && "enum" in props.input.schema && props.input.schema.enum || isArray && !isArrayOfObjects || props.select) {
|
|
2781
4117
|
const opts = typeof props.select === "object" ? props.select : {};
|
|
2782
|
-
if (props.segmented) opts.
|
|
4118
|
+
if (props.segmented) opts.segmentedProps ??= {};
|
|
2783
4119
|
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
2784
4120
|
size: props.size,
|
|
2785
4121
|
input: props.input,
|
|
2786
|
-
|
|
4122
|
+
label: props.label,
|
|
2787
4123
|
description: props.description,
|
|
2788
4124
|
icon,
|
|
2789
4125
|
...opts
|
|
@@ -2797,16 +4133,16 @@ const Control = (_props) => {
|
|
|
2797
4133
|
size: props.size,
|
|
2798
4134
|
id,
|
|
2799
4135
|
color: "blue",
|
|
2800
|
-
|
|
4136
|
+
checked: Boolean(value),
|
|
2801
4137
|
onChange: (event) => {
|
|
2802
|
-
|
|
4138
|
+
setValue(event.currentTarget.checked);
|
|
2803
4139
|
},
|
|
2804
4140
|
...switchProps
|
|
2805
4141
|
});
|
|
2806
4142
|
}
|
|
2807
4143
|
const opts = {
|
|
2808
4144
|
input: props.input,
|
|
2809
|
-
|
|
4145
|
+
selectProps: { data: [{
|
|
2810
4146
|
value: "true",
|
|
2811
4147
|
label: "Yes"
|
|
2812
4148
|
}, {
|
|
@@ -2816,7 +4152,7 @@ const Control = (_props) => {
|
|
|
2816
4152
|
};
|
|
2817
4153
|
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
2818
4154
|
size: props.size,
|
|
2819
|
-
|
|
4155
|
+
label: props.label,
|
|
2820
4156
|
description: props.description,
|
|
2821
4157
|
icon,
|
|
2822
4158
|
...opts
|
|
@@ -2829,7 +4165,8 @@ const Control = (_props) => {
|
|
|
2829
4165
|
size: props.size,
|
|
2830
4166
|
id,
|
|
2831
4167
|
leftSection: icon,
|
|
2832
|
-
|
|
4168
|
+
value: value ?? "",
|
|
4169
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
2833
4170
|
...passwordInputProps
|
|
2834
4171
|
});
|
|
2835
4172
|
}
|
|
@@ -2840,14 +4177,15 @@ const Control = (_props) => {
|
|
|
2840
4177
|
size: props.size,
|
|
2841
4178
|
id,
|
|
2842
4179
|
leftSection: icon,
|
|
2843
|
-
|
|
4180
|
+
value: value ?? "",
|
|
4181
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
2844
4182
|
...textAreaProps
|
|
2845
4183
|
});
|
|
2846
4184
|
}
|
|
2847
4185
|
if (props.date || props.datetime || props.time || format === "date" || format === "date-time" || format === "time") return /* @__PURE__ */ jsx(ControlDate, {
|
|
2848
4186
|
size: props.size,
|
|
2849
4187
|
input: props.input,
|
|
2850
|
-
|
|
4188
|
+
label: props.label,
|
|
2851
4189
|
description: props.description,
|
|
2852
4190
|
icon,
|
|
2853
4191
|
date: props.date,
|
|
@@ -2862,7 +4200,7 @@ const Control = (_props) => {
|
|
|
2862
4200
|
case "uri": return "url";
|
|
2863
4201
|
case "tel":
|
|
2864
4202
|
case "phone": return "tel";
|
|
2865
|
-
default: return;
|
|
4203
|
+
default: return props.input.props.type ?? "text";
|
|
2866
4204
|
}
|
|
2867
4205
|
};
|
|
2868
4206
|
return /* @__PURE__ */ jsx(TextInput, {
|
|
@@ -2871,14 +4209,9 @@ const Control = (_props) => {
|
|
|
2871
4209
|
id,
|
|
2872
4210
|
leftSection: icon,
|
|
2873
4211
|
type: getInputType(),
|
|
2874
|
-
|
|
2875
|
-
|
|
2876
|
-
|
|
2877
|
-
"label",
|
|
2878
|
-
"input",
|
|
2879
|
-
"description",
|
|
2880
|
-
"error"
|
|
2881
|
-
]
|
|
4212
|
+
value: value ?? "",
|
|
4213
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
4214
|
+
...textInputProps
|
|
2882
4215
|
});
|
|
2883
4216
|
};
|
|
2884
4217
|
|
|
@@ -2927,6 +4260,7 @@ const Control = (_props) => {
|
|
|
2927
4260
|
*/
|
|
2928
4261
|
const TypeForm = (props) => {
|
|
2929
4262
|
const { form, columns = 3, children, controlProps, fieldControlProps, skipFormElement = false, skipSubmitButton = false, submitButtonProps, fill = true, size } = props;
|
|
4263
|
+
const { dirty } = useFormState(form, ["dirty"]);
|
|
2930
4264
|
const schema = props.schema || form.options.schema;
|
|
2931
4265
|
if (!schema?.properties) return null;
|
|
2932
4266
|
const supportedFields = Object.keys(schema.properties);
|
|
@@ -2989,10 +4323,12 @@ const TypeForm = (props) => {
|
|
|
2989
4323
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2990
4324
|
variant: "subtle",
|
|
2991
4325
|
type: "reset",
|
|
4326
|
+
disabled: !dirty,
|
|
2992
4327
|
children: "Reset"
|
|
2993
4328
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
2994
4329
|
intent: "primary",
|
|
2995
4330
|
form,
|
|
4331
|
+
disabled: !dirty,
|
|
2996
4332
|
...submitButtonProps,
|
|
2997
4333
|
children: submitButtonProps?.children ?? "Submit"
|
|
2998
4334
|
})]
|
|
@@ -3031,33 +4367,27 @@ const dialogForm = (form, options) => ({
|
|
|
3031
4367
|
});
|
|
3032
4368
|
|
|
3033
4369
|
//#endregion
|
|
3034
|
-
//#region ../../src/core/
|
|
3035
|
-
const
|
|
3036
|
-
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
|
|
3044
|
-
|
|
3045
|
-
|
|
3046
|
-
|
|
3047
|
-
|
|
3048
|
-
|
|
3049
|
-
|
|
3050
|
-
|
|
3051
|
-
* const confirmed = await dialog.confirm({ title: "Confirm", message: "Are you sure?" });
|
|
3052
|
-
* const input = await dialog.prompt({ title: "Input", message: "Enter your name:" });
|
|
3053
|
-
* ```
|
|
3054
|
-
*/
|
|
3055
|
-
const useDialog = () => {
|
|
3056
|
-
return useInject(DialogService);
|
|
4370
|
+
//#region ../../src/core/json/components/JsonViewerCopyButton.tsx
|
|
4371
|
+
const JsonViewerCopyButton = (props) => {
|
|
4372
|
+
const [copied, setCopied] = useState(false);
|
|
4373
|
+
const handleCopy = useCallback((e) => {
|
|
4374
|
+
e.stopPropagation();
|
|
4375
|
+
navigator.clipboard.writeText(props.value);
|
|
4376
|
+
setCopied(true);
|
|
4377
|
+
setTimeout(() => setCopied(false), 1500);
|
|
4378
|
+
}, [props.value]);
|
|
4379
|
+
return /* @__PURE__ */ jsx(ActionIcon, {
|
|
4380
|
+
size: props.iconSize + 4,
|
|
4381
|
+
variant: "transparent",
|
|
4382
|
+
c: copied ? "green" : "dimmed",
|
|
4383
|
+
onClick: handleCopy,
|
|
4384
|
+
className: "alepha-json-viewer-copy",
|
|
4385
|
+
children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: props.iconSize }) : /* @__PURE__ */ jsx(IconCopy, { size: props.iconSize })
|
|
4386
|
+
});
|
|
3057
4387
|
};
|
|
3058
4388
|
|
|
3059
4389
|
//#endregion
|
|
3060
|
-
//#region ../../src/core/json/components/
|
|
4390
|
+
//#region ../../src/core/json/components/JsonViewerShared.ts
|
|
3061
4391
|
const SIZE_CONFIG = {
|
|
3062
4392
|
xs: {
|
|
3063
4393
|
icon: 14,
|
|
@@ -3106,77 +4436,21 @@ const getValueType = (val) => {
|
|
|
3106
4436
|
if (Array.isArray(val)) return "array";
|
|
3107
4437
|
return typeof val;
|
|
3108
4438
|
};
|
|
3109
|
-
|
|
3110
|
-
|
|
3111
|
-
|
|
3112
|
-
|
|
3113
|
-
|
|
3114
|
-
label: key ?? "",
|
|
3115
|
-
nodeValue: data,
|
|
3116
|
-
nodeKey: key,
|
|
3117
|
-
path: currentPath,
|
|
3118
|
-
isArrayItem
|
|
3119
|
-
};
|
|
3120
|
-
const type = getValueType(data);
|
|
3121
|
-
if (type === "object" || type === "array") {
|
|
3122
|
-
const children = (type === "array" ? data.map((v, i) => [String(i), v]) : Object.entries(data)).map(([k, v]) => buildTreeNodes(v, currentPath, k, type === "array", maxDepth)).filter((n) => n !== null);
|
|
3123
|
-
return {
|
|
3124
|
-
value: nodeId,
|
|
3125
|
-
label: key ?? "",
|
|
3126
|
-
nodeValue: data,
|
|
3127
|
-
nodeKey: key,
|
|
3128
|
-
path: currentPath,
|
|
3129
|
-
isArrayItem,
|
|
3130
|
-
children: children.length > 0 ? children : void 0
|
|
3131
|
-
};
|
|
3132
|
-
}
|
|
3133
|
-
return {
|
|
3134
|
-
value: nodeId,
|
|
3135
|
-
label: key ?? "",
|
|
3136
|
-
nodeValue: data,
|
|
3137
|
-
nodeKey: key,
|
|
3138
|
-
path: currentPath,
|
|
3139
|
-
isArrayItem
|
|
3140
|
-
};
|
|
3141
|
-
}
|
|
3142
|
-
function getExpandedIds(nodes, targetDepth, currentDepth = 0) {
|
|
3143
|
-
if (currentDepth >= targetDepth) return [];
|
|
3144
|
-
const ids = [];
|
|
3145
|
-
for (const node of nodes) if (node.children) {
|
|
3146
|
-
ids.push(node.value);
|
|
3147
|
-
ids.push(...getExpandedIds(node.children, targetDepth, currentDepth + 1));
|
|
3148
|
-
}
|
|
3149
|
-
return ids;
|
|
3150
|
-
}
|
|
3151
|
-
const CopyButton$1 = ({ value, iconSize }) => {
|
|
3152
|
-
const [copied, setCopied] = useState(false);
|
|
3153
|
-
const handleCopy = useCallback((e) => {
|
|
3154
|
-
e.stopPropagation();
|
|
3155
|
-
navigator.clipboard.writeText(value);
|
|
3156
|
-
setCopied(true);
|
|
3157
|
-
setTimeout(() => setCopied(false), 1500);
|
|
3158
|
-
}, [value]);
|
|
3159
|
-
return /* @__PURE__ */ jsx(ActionIcon, {
|
|
3160
|
-
size: iconSize + 4,
|
|
3161
|
-
variant: "transparent",
|
|
3162
|
-
c: copied ? "green" : "dimmed",
|
|
3163
|
-
onClick: handleCopy,
|
|
3164
|
-
className: "alepha-json-viewer-copy",
|
|
3165
|
-
children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: iconSize }) : /* @__PURE__ */ jsx(IconCopy, { size: iconSize })
|
|
3166
|
-
});
|
|
3167
|
-
};
|
|
3168
|
-
const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, showQuotes, showCopyButton, renderValue }) => {
|
|
3169
|
-
const { nodeValue, nodeKey, path, isArrayItem, isRoot } = node;
|
|
4439
|
+
|
|
4440
|
+
//#endregion
|
|
4441
|
+
//#region ../../src/core/json/components/JsonViewerRowNode.tsx
|
|
4442
|
+
const JsonViewerRowNode = (props) => {
|
|
4443
|
+
const { nodeValue, nodeKey, path, isArrayItem } = props.node;
|
|
3170
4444
|
const type = getValueType(nodeValue);
|
|
3171
4445
|
const isExpandable = type === "object" || type === "array";
|
|
3172
4446
|
const getPreview = () => {
|
|
3173
4447
|
if (!isExpandable) return null;
|
|
3174
4448
|
const count = (type === "array" ? nodeValue : Object.keys(nodeValue)).length;
|
|
3175
4449
|
const label = type === "array" ? "item" : "key";
|
|
3176
|
-
if (!expanded) return /* @__PURE__ */ jsx(Text$1, {
|
|
4450
|
+
if (!props.expanded) return /* @__PURE__ */ jsx(Text$1, {
|
|
3177
4451
|
fs: "italic",
|
|
3178
4452
|
component: "span",
|
|
3179
|
-
size,
|
|
4453
|
+
size: props.size,
|
|
3180
4454
|
style: STYLES.preview,
|
|
3181
4455
|
children: count === 0 ? type === "array" ? "[]" : "{}" : type === "array" ? `[ ${count} ${count === 1 ? label : `${label}s`} ]` : `{ ${count} ${count === 1 ? label : `${label}s`} }`
|
|
3182
4456
|
});
|
|
@@ -3186,25 +4460,25 @@ const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, show
|
|
|
3186
4460
|
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
3187
4461
|
gap: 6,
|
|
3188
4462
|
wrap: "nowrap",
|
|
3189
|
-
...elementProps,
|
|
3190
|
-
className: `alepha-json-viewer-row ${elementProps.className || ""}`,
|
|
4463
|
+
...props.elementProps,
|
|
4464
|
+
className: `alepha-json-viewer-row ${props.elementProps.className || ""}`,
|
|
3191
4465
|
children: [
|
|
3192
|
-
hasChildren ? expanded ? /* @__PURE__ */ jsx(IconChevronDown, {
|
|
3193
|
-
size: config.icon,
|
|
4466
|
+
props.hasChildren ? props.expanded ? /* @__PURE__ */ jsx(IconChevronDown, {
|
|
4467
|
+
size: props.config.icon,
|
|
3194
4468
|
style: STYLES.chevron
|
|
3195
4469
|
}) : /* @__PURE__ */ jsx(IconChevronRight, {
|
|
3196
|
-
size: config.icon,
|
|
4470
|
+
size: props.config.icon,
|
|
3197
4471
|
style: STYLES.chevron
|
|
3198
4472
|
}) : /* @__PURE__ */ jsx("span", { style: {
|
|
3199
|
-
width: config.icon,
|
|
4473
|
+
width: props.config.icon,
|
|
3200
4474
|
flexShrink: 0
|
|
3201
4475
|
} }),
|
|
3202
4476
|
nodeKey !== void 0 && !isArrayItem && /* @__PURE__ */ jsxs(Text$1, {
|
|
3203
4477
|
component: "span",
|
|
3204
|
-
size,
|
|
4478
|
+
size: props.size,
|
|
3205
4479
|
children: [/* @__PURE__ */ jsx("span", {
|
|
3206
4480
|
style: STYLES.key,
|
|
3207
|
-
children: showQuotes ? `"${nodeKey}"` : nodeKey
|
|
4481
|
+
children: props.showQuotes ? `"${nodeKey}"` : nodeKey
|
|
3208
4482
|
}), /* @__PURE__ */ jsx("span", {
|
|
3209
4483
|
style: STYLES.colon,
|
|
3210
4484
|
children: ":"
|
|
@@ -3212,7 +4486,7 @@ const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, show
|
|
|
3212
4486
|
}),
|
|
3213
4487
|
nodeKey !== void 0 && isArrayItem && /* @__PURE__ */ jsxs(Text$1, {
|
|
3214
4488
|
component: "span",
|
|
3215
|
-
size,
|
|
4489
|
+
size: props.size,
|
|
3216
4490
|
children: [/* @__PURE__ */ jsx("span", {
|
|
3217
4491
|
style: STYLES.key,
|
|
3218
4492
|
children: nodeKey
|
|
@@ -3221,25 +4495,29 @@ const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, show
|
|
|
3221
4495
|
children: ":"
|
|
3222
4496
|
})]
|
|
3223
4497
|
}),
|
|
3224
|
-
hasChildren ? getPreview() : isExpandable ? type === "array" ? /* @__PURE__ */ jsx(Text$1, {
|
|
4498
|
+
props.hasChildren ? getPreview() : isExpandable ? type === "array" ? /* @__PURE__ */ jsx(Text$1, {
|
|
3225
4499
|
component: "span",
|
|
3226
|
-
size,
|
|
4500
|
+
size: props.size,
|
|
3227
4501
|
style: STYLES.preview,
|
|
3228
4502
|
children: "[]"
|
|
3229
4503
|
}) : /* @__PURE__ */ jsx(Text$1, {
|
|
3230
4504
|
component: "span",
|
|
3231
|
-
size,
|
|
4505
|
+
size: props.size,
|
|
3232
4506
|
style: STYLES.preview,
|
|
3233
4507
|
children: "{}"
|
|
3234
|
-
}) : renderValue(nodeValue, nodeKey, path),
|
|
3235
|
-
showCopyButton && /* @__PURE__ */ jsx(
|
|
4508
|
+
}) : props.renderValue(nodeValue, nodeKey, path),
|
|
4509
|
+
props.showCopyButton && /* @__PURE__ */ jsx(JsonViewerCopyButton, {
|
|
3236
4510
|
value: getCopyValue(),
|
|
3237
|
-
iconSize: config.icon
|
|
4511
|
+
iconSize: props.config.icon
|
|
3238
4512
|
})
|
|
3239
4513
|
]
|
|
3240
4514
|
});
|
|
3241
4515
|
};
|
|
3242
|
-
|
|
4516
|
+
|
|
4517
|
+
//#endregion
|
|
4518
|
+
//#region ../../src/core/json/components/JsonViewer.tsx
|
|
4519
|
+
const JsonViewer = (props) => {
|
|
4520
|
+
const { data, defaultExpandedDepth = 2, maxDepth = 10, size = "sm", showQuotes = false, showCopyButton = true, formatValue } = props;
|
|
3243
4521
|
const config = SIZE_CONFIG[size] || SIZE_CONFIG.sm;
|
|
3244
4522
|
const treeData = useMemo(() => {
|
|
3245
4523
|
const type = getValueType(data);
|
|
@@ -3319,7 +4597,7 @@ const JsonViewer = ({ data, defaultExpandedDepth = 2, maxDepth = 10, size = "sm"
|
|
|
3319
4597
|
size
|
|
3320
4598
|
]);
|
|
3321
4599
|
const renderNode = useCallback(({ node, expanded, hasChildren, elementProps }) => {
|
|
3322
|
-
return /* @__PURE__ */ jsx(
|
|
4600
|
+
return /* @__PURE__ */ jsx(JsonViewerRowNode, {
|
|
3323
4601
|
node,
|
|
3324
4602
|
expanded,
|
|
3325
4603
|
hasChildren,
|
|
@@ -3351,6 +4629,54 @@ const JsonViewer = ({ data, defaultExpandedDepth = 2, maxDepth = 10, size = "sm"
|
|
|
3351
4629
|
styles: { root: STYLES.root }
|
|
3352
4630
|
});
|
|
3353
4631
|
};
|
|
4632
|
+
/**
|
|
4633
|
+
* Convert JSON to tree data structure.
|
|
4634
|
+
*/
|
|
4635
|
+
const buildTreeNodes = (data, path = [], key, isArrayItem = false, maxDepth = 10) => {
|
|
4636
|
+
const currentPath = key !== void 0 ? [...path, key] : path;
|
|
4637
|
+
const nodeId = currentPath.length > 0 ? currentPath.join(".") : "root";
|
|
4638
|
+
if (currentPath.length > maxDepth) return {
|
|
4639
|
+
value: nodeId,
|
|
4640
|
+
label: key ?? "",
|
|
4641
|
+
nodeValue: data,
|
|
4642
|
+
nodeKey: key,
|
|
4643
|
+
path: currentPath,
|
|
4644
|
+
isArrayItem
|
|
4645
|
+
};
|
|
4646
|
+
const type = getValueType(data);
|
|
4647
|
+
if (type === "object" || type === "array") {
|
|
4648
|
+
const children = (type === "array" ? data.map((v, i) => [String(i), v]) : Object.entries(data)).map(([k, v]) => buildTreeNodes(v, currentPath, k, type === "array", maxDepth)).filter((n) => n !== null);
|
|
4649
|
+
return {
|
|
4650
|
+
value: nodeId,
|
|
4651
|
+
label: key ?? "",
|
|
4652
|
+
nodeValue: data,
|
|
4653
|
+
nodeKey: key,
|
|
4654
|
+
path: currentPath,
|
|
4655
|
+
isArrayItem,
|
|
4656
|
+
children: children.length > 0 ? children : void 0
|
|
4657
|
+
};
|
|
4658
|
+
}
|
|
4659
|
+
return {
|
|
4660
|
+
value: nodeId,
|
|
4661
|
+
label: key ?? "",
|
|
4662
|
+
nodeValue: data,
|
|
4663
|
+
nodeKey: key,
|
|
4664
|
+
path: currentPath,
|
|
4665
|
+
isArrayItem
|
|
4666
|
+
};
|
|
4667
|
+
};
|
|
4668
|
+
/**
|
|
4669
|
+
* Get all expandable node IDs up to a certain depth.
|
|
4670
|
+
*/
|
|
4671
|
+
const getExpandedIds = (nodes, targetDepth, currentDepth = 0) => {
|
|
4672
|
+
if (currentDepth >= targetDepth) return [];
|
|
4673
|
+
const ids = [];
|
|
4674
|
+
for (const node of nodes) if (node.children) {
|
|
4675
|
+
ids.push(node.value);
|
|
4676
|
+
ids.push(...getExpandedIds(node.children, targetDepth, currentDepth + 1));
|
|
4677
|
+
}
|
|
4678
|
+
return ids;
|
|
4679
|
+
};
|
|
3354
4680
|
|
|
3355
4681
|
//#endregion
|
|
3356
4682
|
//#region ../../src/core/json/factories/dialogJson.tsx
|
|
@@ -3394,7 +4720,8 @@ const DEFAULT_MAX_VISIBLE_COLUMNS = 8;
|
|
|
3394
4720
|
|
|
3395
4721
|
//#endregion
|
|
3396
4722
|
//#region ../../src/core/table/components/DataTableFilters.tsx
|
|
3397
|
-
const DataTableFilters = (
|
|
4723
|
+
const DataTableFilters = (props) => {
|
|
4724
|
+
const { schema, form, typeFormProps, filterVisibility } = props;
|
|
3398
4725
|
const visibleSchema = useMemo(() => {
|
|
3399
4726
|
const visibleKeys = Object.keys(schema.properties).filter((key) => filterVisibility[key] !== false);
|
|
3400
4727
|
if (visibleKeys.length === 0) return null;
|
|
@@ -3405,13 +4732,14 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
3405
4732
|
return t.object(visibleProps);
|
|
3406
4733
|
}, [schema, filterVisibility]);
|
|
3407
4734
|
if (!visibleSchema) return null;
|
|
3408
|
-
return /* @__PURE__ */ jsx(Flex
|
|
3409
|
-
|
|
4735
|
+
return /* @__PURE__ */ jsx(Flex, {
|
|
4736
|
+
surface: true,
|
|
4737
|
+
flex: 1,
|
|
4738
|
+
mt: -4,
|
|
3410
4739
|
p: "xs",
|
|
3411
|
-
|
|
3412
|
-
|
|
4740
|
+
m: "xs",
|
|
4741
|
+
bdrs: "md",
|
|
3413
4742
|
children: /* @__PURE__ */ jsx(TypeForm, {
|
|
3414
|
-
size: "xs",
|
|
3415
4743
|
...typeFormProps,
|
|
3416
4744
|
skipSubmitButton: true,
|
|
3417
4745
|
fill: true,
|
|
@@ -3422,7 +4750,7 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
3422
4750
|
sm: 2,
|
|
3423
4751
|
md: 3,
|
|
3424
4752
|
lg: 4,
|
|
3425
|
-
xl:
|
|
4753
|
+
xl: 5
|
|
3426
4754
|
}
|
|
3427
4755
|
})
|
|
3428
4756
|
});
|
|
@@ -3430,48 +4758,64 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
3430
4758
|
|
|
3431
4759
|
//#endregion
|
|
3432
4760
|
//#region ../../src/core/table/components/DataTablePagination.tsx
|
|
3433
|
-
const DataTablePagination = ({ page, size, totalPages, onPageChange, onSizeChange }) => {
|
|
3434
|
-
|
|
4761
|
+
const DataTablePagination = ({ page, size, totalPages, totalElements, isFirst, isLast, offset, numberOfElements, onPageChange, onSizeChange }) => {
|
|
4762
|
+
const from = numberOfElements > 0 ? offset + 1 : 0;
|
|
4763
|
+
const to = offset + numberOfElements;
|
|
4764
|
+
const hasTotal = totalPages != null;
|
|
4765
|
+
return /* @__PURE__ */ jsxs(Flex, {
|
|
3435
4766
|
align: "center",
|
|
3436
|
-
justify: "
|
|
4767
|
+
justify: "space-between",
|
|
3437
4768
|
gap: "md",
|
|
3438
|
-
|
|
4769
|
+
px: "xs",
|
|
4770
|
+
py: 4,
|
|
3439
4771
|
style: { borderTop: "1px solid var(--alepha-border)" },
|
|
3440
|
-
children: [/* @__PURE__ */ jsx(Flex
|
|
3441
|
-
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
}
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
},
|
|
3460
|
-
{
|
|
3461
|
-
value: "50",
|
|
3462
|
-
label: "50"
|
|
4772
|
+
children: [/* @__PURE__ */ jsx(Flex, {
|
|
4773
|
+
align: "center",
|
|
4774
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
4775
|
+
size: "xs",
|
|
4776
|
+
c: "dimmed",
|
|
4777
|
+
children: totalElements != null ? `Showing ${from} - ${to} of ${totalElements}` : `Showing ${from} - ${to}`
|
|
4778
|
+
})
|
|
4779
|
+
}), /* @__PURE__ */ jsxs(Flex, {
|
|
4780
|
+
align: "center",
|
|
4781
|
+
gap: "md",
|
|
4782
|
+
children: [/* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(Select, {
|
|
4783
|
+
color: "gray",
|
|
4784
|
+
c: "gray",
|
|
4785
|
+
size: "xs",
|
|
4786
|
+
w: 96,
|
|
4787
|
+
variant: "default",
|
|
4788
|
+
value: size,
|
|
4789
|
+
onChange: (value) => {
|
|
4790
|
+
if (value) onSizeChange(Number(value));
|
|
3463
4791
|
},
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3472
|
-
|
|
3473
|
-
|
|
3474
|
-
|
|
4792
|
+
data: [
|
|
4793
|
+
{
|
|
4794
|
+
value: "10",
|
|
4795
|
+
label: "10"
|
|
4796
|
+
},
|
|
4797
|
+
{
|
|
4798
|
+
value: "25",
|
|
4799
|
+
label: "25"
|
|
4800
|
+
},
|
|
4801
|
+
{
|
|
4802
|
+
value: "50",
|
|
4803
|
+
label: "50"
|
|
4804
|
+
},
|
|
4805
|
+
{
|
|
4806
|
+
value: "100",
|
|
4807
|
+
label: "100"
|
|
4808
|
+
}
|
|
4809
|
+
]
|
|
4810
|
+
}) }), /* @__PURE__ */ jsx(Flex, { children: /* @__PURE__ */ jsx(Pagination, {
|
|
4811
|
+
size: "sm",
|
|
4812
|
+
withEdges: hasTotal,
|
|
4813
|
+
withPages: hasTotal,
|
|
4814
|
+
total: hasTotal ? totalPages : isLast !== false ? page : page + 1,
|
|
4815
|
+
value: page,
|
|
4816
|
+
onChange: onPageChange
|
|
4817
|
+
}) })]
|
|
4818
|
+
})]
|
|
3475
4819
|
});
|
|
3476
4820
|
};
|
|
3477
4821
|
|
|
@@ -3518,7 +4862,7 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3518
4862
|
timingFunction: "ease"
|
|
3519
4863
|
},
|
|
3520
4864
|
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3521
|
-
variant: "
|
|
4865
|
+
variant: "minimal",
|
|
3522
4866
|
icon: IconColumns,
|
|
3523
4867
|
onClick: () => setOpened((o) => !o)
|
|
3524
4868
|
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
@@ -3548,12 +4892,12 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3548
4892
|
gap: 4,
|
|
3549
4893
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
3550
4894
|
size: "compact-xs",
|
|
3551
|
-
variant: "
|
|
4895
|
+
variant: "minimal",
|
|
3552
4896
|
onClick: handleShowAll,
|
|
3553
4897
|
children: "All"
|
|
3554
4898
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
3555
4899
|
size: "compact-xs",
|
|
3556
|
-
variant: "
|
|
4900
|
+
variant: "minimal",
|
|
3557
4901
|
onClick: handleDefault,
|
|
3558
4902
|
children: "Default"
|
|
3559
4903
|
})]
|
|
@@ -3619,7 +4963,7 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3619
4963
|
timingFunction: "ease"
|
|
3620
4964
|
},
|
|
3621
4965
|
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3622
|
-
variant: "
|
|
4966
|
+
variant: "minimal",
|
|
3623
4967
|
icon: IconFilter,
|
|
3624
4968
|
onClick: () => setOpened((o) => !o)
|
|
3625
4969
|
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
@@ -3649,12 +4993,12 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3649
4993
|
gap: 4,
|
|
3650
4994
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
3651
4995
|
size: "compact-xs",
|
|
3652
|
-
variant: "
|
|
4996
|
+
variant: "minimal",
|
|
3653
4997
|
onClick: handleShowAll,
|
|
3654
4998
|
children: "All"
|
|
3655
4999
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
3656
5000
|
size: "compact-xs",
|
|
3657
|
-
variant: "
|
|
5001
|
+
variant: "minimal",
|
|
3658
5002
|
onClick: handleHideAll,
|
|
3659
5003
|
children: "None"
|
|
3660
5004
|
})]
|
|
@@ -3693,7 +5037,7 @@ const extractText = (node) => {
|
|
|
3693
5037
|
const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility, onColumnVisibilityChange, onFilterVisibilityChange, actions, onRefresh, items, withExport, selectedItems = [], checkboxActions, onClearSelection }) => {
|
|
3694
5038
|
const hasSelection = selectedItems.length > 0;
|
|
3695
5039
|
const exportableColumns = useCallback(() => {
|
|
3696
|
-
return Object.entries(columns).filter(([key
|
|
5040
|
+
return Object.entries(columns).filter(([key]) => columnVisibility[key] !== false);
|
|
3697
5041
|
}, [columns, columnVisibility]);
|
|
3698
5042
|
const buildRows = useCallback(() => {
|
|
3699
5043
|
const cols = exportableColumns();
|
|
@@ -3730,11 +5074,10 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3730
5074
|
};
|
|
3731
5075
|
await action.onClick(ctx);
|
|
3732
5076
|
};
|
|
3733
|
-
return /* @__PURE__ */ jsxs(Flex
|
|
5077
|
+
return /* @__PURE__ */ jsxs(Flex, {
|
|
3734
5078
|
p: "xs",
|
|
3735
|
-
style: { borderBottom: "1px solid var(--alepha-border)" },
|
|
3736
5079
|
children: [
|
|
3737
|
-
/* @__PURE__ */ jsxs(Flex
|
|
5080
|
+
/* @__PURE__ */ jsxs(Flex, {
|
|
3738
5081
|
gap: 4,
|
|
3739
5082
|
align: "center",
|
|
3740
5083
|
children: [
|
|
@@ -3749,7 +5092,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3749
5092
|
onVisibilityChange: onColumnVisibilityChange
|
|
3750
5093
|
}),
|
|
3751
5094
|
withExport && /* @__PURE__ */ jsx(ActionButton, {
|
|
3752
|
-
variant: "
|
|
5095
|
+
variant: "minimal",
|
|
3753
5096
|
icon: IconDownload,
|
|
3754
5097
|
menu: { items: [{
|
|
3755
5098
|
label: "Export as CSV",
|
|
@@ -3772,7 +5115,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3772
5115
|
children: [selectedItems.length, " selected"]
|
|
3773
5116
|
}),
|
|
3774
5117
|
/* @__PURE__ */ jsx(ActionButton, {
|
|
3775
|
-
variant: "
|
|
5118
|
+
variant: "minimal",
|
|
3776
5119
|
size: "compact-sm",
|
|
3777
5120
|
icon: IconX,
|
|
3778
5121
|
onClick: onClearSelection,
|
|
@@ -3789,14 +5132,14 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3789
5132
|
] })
|
|
3790
5133
|
]
|
|
3791
5134
|
}),
|
|
3792
|
-
/* @__PURE__ */ jsx(Flex
|
|
3793
|
-
/* @__PURE__ */ jsxs(Flex
|
|
5135
|
+
/* @__PURE__ */ jsx(Flex, { flex: 1 }),
|
|
5136
|
+
/* @__PURE__ */ jsxs(Flex, {
|
|
3794
5137
|
gap: "xs",
|
|
3795
5138
|
children: [actions?.map((props, index) => !isValidElement(props) ? /* @__PURE__ */ jsx(ActionButton, {
|
|
3796
5139
|
...props,
|
|
3797
5140
|
children: props.label
|
|
3798
5141
|
}, index) : props), /* @__PURE__ */ jsx(ActionButton, {
|
|
3799
|
-
variant: "
|
|
5142
|
+
variant: "minimal",
|
|
3800
5143
|
icon: IconRefresh,
|
|
3801
5144
|
onClick: onRefresh
|
|
3802
5145
|
})]
|
|
@@ -3905,12 +5248,16 @@ const FIT_STYLE = {
|
|
|
3905
5248
|
};
|
|
3906
5249
|
const DataTable = (props) => {
|
|
3907
5250
|
const [items, setItems] = useState(typeof props.items === "function" ? { content: [] } : props.items);
|
|
3908
|
-
const
|
|
5251
|
+
const itemsRef = useRef(items);
|
|
5252
|
+
const [loaded, setLoaded] = useState(typeof props.items !== "function" || !props.submitOnInit);
|
|
5253
|
+
const defaultSize = props.defaultSize || (props.infinityScroll ? 100 : 10);
|
|
3909
5254
|
const [page, setPage] = useState(1);
|
|
3910
5255
|
const [size, setSize] = useState(String(defaultSize));
|
|
3911
5256
|
const [currentPage, setCurrentPage] = useState(0);
|
|
3912
5257
|
const alepha = useInject(Alepha);
|
|
5258
|
+
itemsRef.current = items;
|
|
3913
5259
|
const sentinelRef = useRef(null);
|
|
5260
|
+
const debounceRef = useRef(null);
|
|
3914
5261
|
const [columnVisibility, setColumnVisibility] = useState(() => {
|
|
3915
5262
|
const entries = Object.entries(props.columns);
|
|
3916
5263
|
let visibleCount = 0;
|
|
@@ -3983,13 +5330,14 @@ const DataTable = (props) => {
|
|
|
3983
5330
|
}),
|
|
3984
5331
|
handler: async (values) => {
|
|
3985
5332
|
if (typeof props.items === "function") {
|
|
3986
|
-
const response = await props.items(values, { items:
|
|
5333
|
+
const response = await props.items(values, { items: itemsRef.current.content });
|
|
3987
5334
|
if (props.infinityScroll && values.page > 0) setItems((prev) => ({
|
|
3988
5335
|
...response,
|
|
3989
5336
|
content: [...prev.content, ...response.content]
|
|
3990
5337
|
}));
|
|
3991
5338
|
else setItems(response);
|
|
3992
5339
|
setCurrentPage(values.page);
|
|
5340
|
+
if (!loaded) setLoaded(true);
|
|
3993
5341
|
}
|
|
3994
5342
|
},
|
|
3995
5343
|
onReset: async () => {
|
|
@@ -4009,9 +5357,23 @@ const DataTable = (props) => {
|
|
|
4009
5357
|
return;
|
|
4010
5358
|
}
|
|
4011
5359
|
props.onFilterChange?.(key, value, form);
|
|
5360
|
+
if (props.skipSubmitOnChange) return;
|
|
5361
|
+
form.input.page.set(0);
|
|
5362
|
+
const delay = props.debounce ?? 300;
|
|
5363
|
+
if (delay > 0) {
|
|
5364
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5365
|
+
debounceRef.current = setTimeout(() => {
|
|
5366
|
+
form.submit();
|
|
5367
|
+
}, delay);
|
|
5368
|
+
} else await form.submit();
|
|
4012
5369
|
}
|
|
4013
|
-
}, [
|
|
5370
|
+
}, []);
|
|
4014
5371
|
const dt = useInject(DateTimeProvider);
|
|
5372
|
+
useEffect(() => {
|
|
5373
|
+
return () => {
|
|
5374
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5375
|
+
};
|
|
5376
|
+
}, []);
|
|
4015
5377
|
useEffect(() => {
|
|
4016
5378
|
if (props.submitOnInit) form.submit();
|
|
4017
5379
|
if (props.submitEvery) {
|
|
@@ -4042,7 +5404,7 @@ const DataTable = (props) => {
|
|
|
4042
5404
|
currentPage,
|
|
4043
5405
|
form
|
|
4044
5406
|
]);
|
|
4045
|
-
const totalColumns = visibleColumns.length + (panelConfig ? 1 : 0) + (props.withCheckbox ? 1 : 0);
|
|
5407
|
+
const totalColumns = visibleColumns.length + (panelConfig ? 1 : 0) + (props.withCheckbox ? 1 : 0) + (props.rowActions ? 1 : 0);
|
|
4046
5408
|
const checkboxHeader = props.withCheckbox ? /* @__PURE__ */ jsx(Table.Th, {
|
|
4047
5409
|
style: { width: 40 },
|
|
4048
5410
|
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
@@ -4065,18 +5427,20 @@ const DataTable = (props) => {
|
|
|
4065
5427
|
userSelect: "none"
|
|
4066
5428
|
} : {}
|
|
4067
5429
|
},
|
|
4068
|
-
children: /* @__PURE__ */ jsxs(Flex
|
|
5430
|
+
children: /* @__PURE__ */ jsxs(Flex, {
|
|
4069
5431
|
align: "center",
|
|
4070
5432
|
gap: 4,
|
|
4071
|
-
children: [/* @__PURE__ */ jsx(Text
|
|
5433
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
5434
|
+
bold: true,
|
|
5435
|
+
muted: true,
|
|
4072
5436
|
size: "xs",
|
|
4073
5437
|
children: col.label
|
|
4074
|
-
}), col.sortable && /* @__PURE__ */ jsxs(Flex
|
|
5438
|
+
}), col.sortable && /* @__PURE__ */ jsxs(Flex, {
|
|
4075
5439
|
c: "dimmed",
|
|
4076
5440
|
children: [
|
|
4077
|
-
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.
|
|
4078
|
-
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.
|
|
4079
|
-
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.
|
|
5441
|
+
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.xs }),
|
|
5442
|
+
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.xs }),
|
|
5443
|
+
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.xs })
|
|
4080
5444
|
]
|
|
4081
5445
|
})]
|
|
4082
5446
|
})
|
|
@@ -4113,7 +5477,7 @@ const DataTable = (props) => {
|
|
|
4113
5477
|
toggleExpand(itemKey);
|
|
4114
5478
|
},
|
|
4115
5479
|
style: { display: "inline-flex" },
|
|
4116
|
-
children: /* @__PURE__ */ jsx(Flex
|
|
5480
|
+
children: /* @__PURE__ */ jsx(Flex, {
|
|
4117
5481
|
c: "dimmed",
|
|
4118
5482
|
align: "center",
|
|
4119
5483
|
justify: "center",
|
|
@@ -4136,32 +5500,49 @@ const DataTable = (props) => {
|
|
|
4136
5500
|
form,
|
|
4137
5501
|
alepha
|
|
4138
5502
|
};
|
|
4139
|
-
|
|
4140
|
-
const rowActions = col.actions(item, ctx).filter((a) => a.visible !== false);
|
|
4141
|
-
return /* @__PURE__ */ jsx(Table.Td, {
|
|
4142
|
-
py: 2,
|
|
4143
|
-
px: 4,
|
|
4144
|
-
style: col.fit ? FIT_STYLE : void 0,
|
|
4145
|
-
onClick: (e) => e.stopPropagation(),
|
|
4146
|
-
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
4147
|
-
gap: 4,
|
|
4148
|
-
children: rowActions.map(({ visible: _, ...actionProps }, i) => /* @__PURE__ */ jsx(ActionButton, {
|
|
4149
|
-
variant: "subtle",
|
|
4150
|
-
size: "xs",
|
|
4151
|
-
preventDefault: true,
|
|
4152
|
-
h: 20,
|
|
4153
|
-
...actionProps
|
|
4154
|
-
}, i))
|
|
4155
|
-
})
|
|
4156
|
-
}, key);
|
|
4157
|
-
}
|
|
5503
|
+
const content = col.value?.(item, ctx);
|
|
4158
5504
|
return /* @__PURE__ */ jsx(Table.Td, {
|
|
4159
|
-
py: 2,
|
|
4160
|
-
px: 4,
|
|
4161
5505
|
style: col.fit ? FIT_STYLE : void 0,
|
|
4162
|
-
children: col.
|
|
5506
|
+
children: col.action ? /* @__PURE__ */ jsx(ActionButton, {
|
|
5507
|
+
td: "inherit",
|
|
5508
|
+
unstyled: true,
|
|
5509
|
+
...col.action(item),
|
|
5510
|
+
children: content
|
|
5511
|
+
}) : content
|
|
4163
5512
|
}, key);
|
|
4164
|
-
})
|
|
5513
|
+
}),
|
|
5514
|
+
props.rowActions && (() => {
|
|
5515
|
+
const ctx = {
|
|
5516
|
+
index,
|
|
5517
|
+
form,
|
|
5518
|
+
alepha
|
|
5519
|
+
};
|
|
5520
|
+
const actions = props.rowActions(item, ctx).filter((a) => a.visible !== false);
|
|
5521
|
+
if (actions.length === 0) return /* @__PURE__ */ jsx(Table.Td, { style: FIT_STYLE });
|
|
5522
|
+
return /* @__PURE__ */ jsx(Table.Td, {
|
|
5523
|
+
py: 2,
|
|
5524
|
+
px: 4,
|
|
5525
|
+
style: FIT_STYLE,
|
|
5526
|
+
onClick: (e) => e.stopPropagation(),
|
|
5527
|
+
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
5528
|
+
variant: "minimal",
|
|
5529
|
+
size: "xs",
|
|
5530
|
+
icon: IconDotsVertical,
|
|
5531
|
+
menu: { items: actions.map((action) => {
|
|
5532
|
+
const Icon = action.icon;
|
|
5533
|
+
return {
|
|
5534
|
+
label: action.label ?? (typeof action.tooltip === "string" ? action.tooltip : void 0),
|
|
5535
|
+
icon: Icon && isComponentType(Icon) ? /* @__PURE__ */ jsx(Icon, { size: 14 }) : Icon,
|
|
5536
|
+
onClick: action.onClick ? async () => {
|
|
5537
|
+
await action.onClick();
|
|
5538
|
+
if (!action.skipRefresh) await form.submit();
|
|
5539
|
+
} : void 0,
|
|
5540
|
+
color: action.color
|
|
5541
|
+
};
|
|
5542
|
+
}) }
|
|
5543
|
+
})
|
|
5544
|
+
});
|
|
5545
|
+
})()
|
|
4165
5546
|
]
|
|
4166
5547
|
}, itemKey)];
|
|
4167
5548
|
if (panelConfig && showPanel && isExpanded) elements.push(/* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
@@ -4179,13 +5560,19 @@ const DataTable = (props) => {
|
|
|
4179
5560
|
"sort"
|
|
4180
5561
|
]);
|
|
4181
5562
|
}, [props.filters, form.options.schema]);
|
|
4182
|
-
return /* @__PURE__ */ jsxs(Flex
|
|
5563
|
+
return /* @__PURE__ */ jsxs(Flex, {
|
|
5564
|
+
gap: "xs",
|
|
4183
5565
|
flex: 1,
|
|
4184
5566
|
p: 0,
|
|
4185
|
-
bdrs: "sm",
|
|
4186
5567
|
direction: "column",
|
|
4187
|
-
|
|
4188
|
-
|
|
5568
|
+
style: { overflow: "hidden" },
|
|
5569
|
+
children: [/* @__PURE__ */ jsxs(Flex, {
|
|
5570
|
+
rounded: true,
|
|
5571
|
+
bordered: true,
|
|
5572
|
+
elevated: true,
|
|
5573
|
+
shadowed: "xs",
|
|
5574
|
+
col: true,
|
|
5575
|
+
children: [/* @__PURE__ */ jsx(DataTableToolbar, {
|
|
4189
5576
|
columns: props.columns,
|
|
4190
5577
|
filters: props.filters,
|
|
4191
5578
|
columnVisibility,
|
|
@@ -4199,71 +5586,97 @@ const DataTable = (props) => {
|
|
|
4199
5586
|
selectedItems: selection.selectedItems,
|
|
4200
5587
|
checkboxActions: props.checkboxActions,
|
|
4201
5588
|
onClearSelection: selection.clear
|
|
4202
|
-
}),
|
|
4203
|
-
filterSchema && props.filters && /* @__PURE__ */ jsx(DataTableFilters, {
|
|
5589
|
+
}), filterSchema && props.filters && /* @__PURE__ */ jsx(DataTableFilters, {
|
|
4204
5590
|
schema: filterSchema,
|
|
4205
5591
|
form,
|
|
4206
5592
|
typeFormProps: props.typeFormProps,
|
|
4207
5593
|
filterVisibility
|
|
4208
|
-
})
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
|
|
4217
|
-
|
|
4218
|
-
|
|
4219
|
-
|
|
4220
|
-
|
|
4221
|
-
|
|
4222
|
-
|
|
4223
|
-
|
|
4224
|
-
|
|
4225
|
-
|
|
4226
|
-
|
|
4227
|
-
|
|
4228
|
-
|
|
4229
|
-
|
|
4230
|
-
|
|
4231
|
-
|
|
4232
|
-
|
|
4233
|
-
|
|
5594
|
+
})]
|
|
5595
|
+
}), /* @__PURE__ */ jsxs(Flex, {
|
|
5596
|
+
col: true,
|
|
5597
|
+
rounded: true,
|
|
5598
|
+
bordered: true,
|
|
5599
|
+
elevated: true,
|
|
5600
|
+
shadowed: "xs",
|
|
5601
|
+
flex: 1,
|
|
5602
|
+
style: { minHeight: 0 },
|
|
5603
|
+
children: [
|
|
5604
|
+
/* @__PURE__ */ jsx(Flex, {
|
|
5605
|
+
className: "overflow-auto",
|
|
5606
|
+
flex: 1,
|
|
5607
|
+
style: { minHeight: 0 },
|
|
5608
|
+
col: true,
|
|
5609
|
+
children: /* @__PURE__ */ jsxs(Table, {
|
|
5610
|
+
"aria-label": "Data table",
|
|
5611
|
+
withRowBorders: true,
|
|
5612
|
+
highlightOnHover: true,
|
|
5613
|
+
...props.tableProps,
|
|
5614
|
+
children: [/* @__PURE__ */ jsx(Table.Thead, {
|
|
5615
|
+
bdrs: "md",
|
|
5616
|
+
style: {
|
|
5617
|
+
position: "sticky",
|
|
5618
|
+
top: 0,
|
|
5619
|
+
zIndex: 1,
|
|
5620
|
+
backgroundColor: "var(--alepha-elevated)"
|
|
5621
|
+
},
|
|
5622
|
+
children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
5623
|
+
panelConfig && /* @__PURE__ */ jsx(Table.Th, { style: { width: 36 } }),
|
|
5624
|
+
checkboxHeader,
|
|
5625
|
+
head,
|
|
5626
|
+
props.rowActions && /* @__PURE__ */ jsx(Table.Th, { style: FIT_STYLE })
|
|
5627
|
+
] })
|
|
5628
|
+
}), /* @__PURE__ */ jsx(Table.Tbody, { children: !loaded || form.submitting ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
5629
|
+
colSpan: totalColumns || 1,
|
|
5630
|
+
py: "sm",
|
|
5631
|
+
children: /* @__PURE__ */ jsx(Flex, {
|
|
5632
|
+
justify: "center",
|
|
5633
|
+
p: "md",
|
|
5634
|
+
children: /* @__PURE__ */ jsx(Loader, {
|
|
5635
|
+
size: "sm",
|
|
5636
|
+
type: "dots"
|
|
5637
|
+
})
|
|
5638
|
+
})
|
|
5639
|
+
}) }) : rows.length === 0 ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
4234
5640
|
colSpan: totalColumns || 1,
|
|
4235
5641
|
py: "xl",
|
|
4236
|
-
|
|
4237
|
-
|
|
4238
|
-
|
|
4239
|
-
|
|
4240
|
-
|
|
5642
|
+
children: /* @__PURE__ */ jsx(Flex, {
|
|
5643
|
+
justify: "center",
|
|
5644
|
+
children: /* @__PURE__ */ jsx(Text, {
|
|
5645
|
+
c: "dimmed",
|
|
5646
|
+
size: "sm",
|
|
5647
|
+
children: props.emptyLabel ?? "No results"
|
|
5648
|
+
})
|
|
4241
5649
|
})
|
|
4242
|
-
}) })]
|
|
4243
|
-
})
|
|
5650
|
+
}) }) : rows })]
|
|
5651
|
+
})
|
|
5652
|
+
}),
|
|
5653
|
+
props.infinityScroll && /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
|
|
5654
|
+
!props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
|
|
5655
|
+
page,
|
|
5656
|
+
size,
|
|
5657
|
+
totalPages: items.page?.totalPages,
|
|
5658
|
+
totalElements: items.page?.totalElements,
|
|
5659
|
+
isFirst: items.page?.isFirst,
|
|
5660
|
+
isLast: items.page?.isLast,
|
|
5661
|
+
offset: items.page?.offset ?? 0,
|
|
5662
|
+
numberOfElements: items.content.length,
|
|
5663
|
+
onPageChange: (value) => {
|
|
5664
|
+
form.input.page.set(value - 1);
|
|
5665
|
+
},
|
|
5666
|
+
onSizeChange: (value) => {
|
|
5667
|
+
form.input.size.set(value);
|
|
5668
|
+
}
|
|
5669
|
+
}),
|
|
5670
|
+
drawerConfig && /* @__PURE__ */ jsx(Drawer, {
|
|
5671
|
+
opened: drawerItem !== null,
|
|
5672
|
+
onClose: () => setDrawerItem(null),
|
|
5673
|
+
position: "right",
|
|
5674
|
+
size: "xl",
|
|
5675
|
+
...drawerConfig.props,
|
|
5676
|
+
children: drawerItem && drawerConfig.render(drawerItem)
|
|
4244
5677
|
})
|
|
4245
|
-
|
|
4246
|
-
|
|
4247
|
-
!props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
|
|
4248
|
-
page,
|
|
4249
|
-
size,
|
|
4250
|
-
totalPages: items.page?.totalPages ?? 1,
|
|
4251
|
-
onPageChange: (value) => {
|
|
4252
|
-
form.input.page.set(value - 1);
|
|
4253
|
-
},
|
|
4254
|
-
onSizeChange: (value) => {
|
|
4255
|
-
form.input.size.set(value);
|
|
4256
|
-
}
|
|
4257
|
-
}),
|
|
4258
|
-
drawerConfig && /* @__PURE__ */ jsx(Drawer, {
|
|
4259
|
-
opened: drawerItem !== null,
|
|
4260
|
-
onClose: () => setDrawerItem(null),
|
|
4261
|
-
position: "right",
|
|
4262
|
-
size: "xl",
|
|
4263
|
-
...drawerConfig.props,
|
|
4264
|
-
children: drawerItem && drawerConfig.render(drawerItem)
|
|
4265
|
-
})
|
|
4266
|
-
]
|
|
5678
|
+
]
|
|
5679
|
+
})]
|
|
4267
5680
|
});
|
|
4268
5681
|
};
|
|
4269
5682
|
|
|
@@ -4391,8 +5804,8 @@ const OPERATOR_INFO = {
|
|
|
4391
5804
|
* Get the default icon for an input based on its type, format, or name.
|
|
4392
5805
|
*/
|
|
4393
5806
|
const getDefaultIcon = (params) => {
|
|
4394
|
-
const { type, format, name, isEnum, isArray, size = "
|
|
4395
|
-
const iconSize = ui.sizes.icon[size];
|
|
5807
|
+
const { type, format, name, isEnum, isArray, size = "xs" } = params;
|
|
5808
|
+
const iconSize = ui.sizes.icon[size] - 4;
|
|
4396
5809
|
if (format) switch (format) {
|
|
4397
5810
|
case "email": return /* @__PURE__ */ jsx(IconMail, { size: iconSize });
|
|
4398
5811
|
case "url":
|
|
@@ -4505,5 +5918,5 @@ const AlephaUI = $module({
|
|
|
4505
5918
|
});
|
|
4506
5919
|
|
|
4507
5920
|
//#endregion
|
|
4508
|
-
export { $ui, ActionButton, DashboardShell as AdminShell, DashboardShell, AlephaMantineProvider, AlephaUI, AlertDialog, AppBar, Breadcrumb as Breadcrumbs, BurgerButton, ClipboardButton, ConfirmDialog, Container, Control, ControlArray, ControlDate, ControlNumber, ControlObject, ControlQueryBuilder, ControlSelect, DarkModeButton, DataTable, DetailDrawer, DetailList, DialogService, Flex, Heading, JsonViewer, LanguageButton, OPERATOR_INFO, Omnibar, OmnibarButton, PromptDialog, Sidebar, ToggleSidebarButton as SidebarCollapseButton, StatCards, Text, ThemeButton, ThemeProvider, ToastService, TypeForm, UiRouter, alephaSidebarAtom, alephaThemeAtom, alephaThemeListAtom, capitalize, defaultTheme, dialogForm, dialogJson, extractSchemaFields, getDefaultIcon, getOperatorsForField, isComponentType, midnightTheme, prettyName, renderIcon, toTitleCase, ui, useDialog, useTheme, useToast };
|
|
5921
|
+
export { $ui, ActionButton, DashboardShell as AdminShell, DashboardShell, AlephaMantineProvider, AlephaUI, AlertDialog, AppBar, Breadcrumb as Breadcrumbs, BurgerButton, ClipboardButton, ConfirmDialog, Container, Control, ControlArray, ControlDate, ControlNumber, ControlObject, ControlQueryBuilder, ControlSelect, DarkModeButton, DataTable, DetailDrawer, DetailList, DialogService, Flex, Heading, JsonViewer, LanguageButton, OPERATOR_INFO, Omnibar, OmnibarButton, PromptDialog, Sidebar, ToggleSidebarButton as SidebarCollapseButton, SidebarCollapsedItem, SidebarItem, StatCards, Text, ThemeButton, ThemeProvider, ToastService, TypeForm, UiRouter, alephaSidebarAtom, alephaThemeAtom, alephaThemeListAtom, alephaThemeOverridesAtom, capitalize, defaultTheme, dialogForm, dialogJson, extractSchemaFields, getDefaultIcon, getOperatorsForField, isComponentType, midnightTheme, prettyName, renderIcon, toTitleCase, ui, useDialog, useTheme, useToast };
|
|
4509
5922
|
//# sourceMappingURL=index.js.map
|