@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
|
@@ -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, Divider, Drawer, Fieldset, FileInput, Flex, Grid, Image, Input, Kbd, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, Paper, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, SimpleGrid, Slider, Switch, Table, TagsInput, Text, TextInput, Textarea, Tooltip, 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, Divider, Drawer, Fieldset, FileInput, Flex, Grid, Image, Input, Kbd, Loader, MantineProvider, Menu, MultiSelect, NumberInput, Pagination, Paper, PasswordInput, Popover, ScrollArea, SegmentedControl, Select, Slider, Switch, Table, TagsInput, Text, 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
|
-
if (newTheme.name) document.documentElement.setAttribute("data-theme", newTheme.name);
|
|
1063
|
+
if (!this.alepha.isBrowser()) return;
|
|
1064
|
+
this.alepha.inject(BrowserHeadProvider).refreshGlobalHead();
|
|
199
1065
|
}
|
|
1066
|
+
slugify(name) {
|
|
1067
|
+
return name.toLowerCase().replace(/\s+/g, "-");
|
|
1068
|
+
}
|
|
1069
|
+
static FONT_SIZE_MULTIPLIERS = {
|
|
1070
|
+
xs: .85,
|
|
1071
|
+
sm: .925,
|
|
1072
|
+
md: 1,
|
|
1073
|
+
lg: 1.1,
|
|
1074
|
+
xl: 1.25
|
|
1075
|
+
};
|
|
1076
|
+
static SCALE_VALUES = {
|
|
1077
|
+
xs: .85,
|
|
1078
|
+
sm: .925,
|
|
1079
|
+
md: 1,
|
|
1080
|
+
lg: 1.1,
|
|
1081
|
+
xl: 1.25
|
|
1082
|
+
};
|
|
1083
|
+
static DEFAULT_FONT_SIZES = {
|
|
1084
|
+
xs: "0.75rem",
|
|
1085
|
+
sm: "0.875rem",
|
|
1086
|
+
md: "1rem",
|
|
1087
|
+
lg: "1.125rem",
|
|
1088
|
+
xl: "1.25rem"
|
|
1089
|
+
};
|
|
200
1090
|
getTheme() {
|
|
201
1091
|
const index = this.getThemeIndex();
|
|
202
1092
|
const list = this.alepha.store.get(alephaThemeListAtom);
|
|
203
|
-
|
|
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, { 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
|
|
@@ -905,11 +1857,11 @@ const DarkModeButton = (props) => {
|
|
|
905
1857
|
const toggleColorScheme = () => {
|
|
906
1858
|
setColorScheme((document.documentElement.getAttribute("data-mantine-color-scheme") ?? "light") === "dark" ? "light" : "dark");
|
|
907
1859
|
};
|
|
908
|
-
const size = props.size ?? "
|
|
909
|
-
const iconSize = ui.sizes.icon[size] ?? ui.sizes.icon.
|
|
1860
|
+
const size = props.size ?? "sm";
|
|
1861
|
+
const iconSize = ui.sizes.icon[size] ?? ui.sizes.icon.sm;
|
|
910
1862
|
return /* @__PURE__ */ jsx(ActionButton, {
|
|
911
1863
|
onClick: toggleColorScheme,
|
|
912
|
-
variant: props.variant ?? "
|
|
1864
|
+
variant: props.variant ?? "default",
|
|
913
1865
|
size,
|
|
914
1866
|
"aria-label": "Toggle color scheme",
|
|
915
1867
|
icon: /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(IconSun, {
|
|
@@ -928,7 +1880,7 @@ const DarkModeButton = (props) => {
|
|
|
928
1880
|
const LanguageButton = (props) => {
|
|
929
1881
|
const i18n = useI18n();
|
|
930
1882
|
return /* @__PURE__ */ jsx(ActionButton, {
|
|
931
|
-
variant: "
|
|
1883
|
+
variant: "default",
|
|
932
1884
|
icon: IconLanguage,
|
|
933
1885
|
menu: { items: i18n.languages.map((lang) => ({
|
|
934
1886
|
label: i18n.tr(lang),
|
|
@@ -947,8 +1899,7 @@ const OmnibarButton = (props) => {
|
|
|
947
1899
|
if (props.collapsed) return /* @__PURE__ */ jsx(ActionButton, {
|
|
948
1900
|
variant: "subtle",
|
|
949
1901
|
onClick: spotlight.open,
|
|
950
|
-
|
|
951
|
-
icon: /* @__PURE__ */ jsx(IconSearch, { size: 16 }),
|
|
1902
|
+
icon: IconSearch,
|
|
952
1903
|
tooltip: {
|
|
953
1904
|
label: "Search",
|
|
954
1905
|
position: "right"
|
|
@@ -985,6 +1936,261 @@ const OmnibarButton = (props) => {
|
|
|
985
1936
|
});
|
|
986
1937
|
};
|
|
987
1938
|
|
|
1939
|
+
//#endregion
|
|
1940
|
+
//#region ../../src/core/hooks/useDialog.ts
|
|
1941
|
+
/**
|
|
1942
|
+
* Use this hook to access the Dialog Service for showing various dialog types.
|
|
1943
|
+
*
|
|
1944
|
+
* @example
|
|
1945
|
+
* ```tsx
|
|
1946
|
+
* const dialog = useDialog();
|
|
1947
|
+
* await dialog.alert({ title: "Alert", message: "This is an alert message" });
|
|
1948
|
+
* const confirmed = await dialog.confirm({ title: "Confirm", message: "Are you sure?" });
|
|
1949
|
+
* const input = await dialog.prompt({ title: "Input", message: "Enter your name:" });
|
|
1950
|
+
* ```
|
|
1951
|
+
*/
|
|
1952
|
+
const useDialog = () => {
|
|
1953
|
+
return useInject(DialogService);
|
|
1954
|
+
};
|
|
1955
|
+
|
|
1956
|
+
//#endregion
|
|
1957
|
+
//#region ../../src/core/components/buttons/ThemeExpertModal.tsx
|
|
1958
|
+
const MANTINE_COLORS = [
|
|
1959
|
+
"red",
|
|
1960
|
+
"pink",
|
|
1961
|
+
"grape",
|
|
1962
|
+
"violet",
|
|
1963
|
+
"indigo",
|
|
1964
|
+
"blue",
|
|
1965
|
+
"cyan",
|
|
1966
|
+
"teal",
|
|
1967
|
+
"green",
|
|
1968
|
+
"lime",
|
|
1969
|
+
"yellow",
|
|
1970
|
+
"orange"
|
|
1971
|
+
];
|
|
1972
|
+
const RADIUS_OPTIONS = [
|
|
1973
|
+
{
|
|
1974
|
+
label: "xs",
|
|
1975
|
+
value: "xs"
|
|
1976
|
+
},
|
|
1977
|
+
{
|
|
1978
|
+
label: "sm",
|
|
1979
|
+
value: "sm"
|
|
1980
|
+
},
|
|
1981
|
+
{
|
|
1982
|
+
label: "md",
|
|
1983
|
+
value: "md"
|
|
1984
|
+
},
|
|
1985
|
+
{
|
|
1986
|
+
label: "lg",
|
|
1987
|
+
value: "lg"
|
|
1988
|
+
},
|
|
1989
|
+
{
|
|
1990
|
+
label: "xl",
|
|
1991
|
+
value: "xl"
|
|
1992
|
+
}
|
|
1993
|
+
];
|
|
1994
|
+
const SIZE_OPTIONS = [
|
|
1995
|
+
{
|
|
1996
|
+
label: "xs",
|
|
1997
|
+
value: "xs"
|
|
1998
|
+
},
|
|
1999
|
+
{
|
|
2000
|
+
label: "sm",
|
|
2001
|
+
value: "sm"
|
|
2002
|
+
},
|
|
2003
|
+
{
|
|
2004
|
+
label: "md",
|
|
2005
|
+
value: "md"
|
|
2006
|
+
},
|
|
2007
|
+
{
|
|
2008
|
+
label: "lg",
|
|
2009
|
+
value: "lg"
|
|
2010
|
+
},
|
|
2011
|
+
{
|
|
2012
|
+
label: "xl",
|
|
2013
|
+
value: "xl"
|
|
2014
|
+
}
|
|
2015
|
+
];
|
|
2016
|
+
const FONT_OPTIONS = [
|
|
2017
|
+
{
|
|
2018
|
+
label: "System",
|
|
2019
|
+
value: ""
|
|
2020
|
+
},
|
|
2021
|
+
{
|
|
2022
|
+
label: "Inter",
|
|
2023
|
+
value: "Inter, sans-serif"
|
|
2024
|
+
},
|
|
2025
|
+
{
|
|
2026
|
+
label: "Mono",
|
|
2027
|
+
value: "ui-monospace, SFMono-Regular, Menlo, monospace"
|
|
2028
|
+
},
|
|
2029
|
+
{
|
|
2030
|
+
label: "Serif",
|
|
2031
|
+
value: "Georgia, 'Times New Roman', serif"
|
|
2032
|
+
}
|
|
2033
|
+
];
|
|
2034
|
+
const ThemeExpertModal = () => {
|
|
2035
|
+
const [, , expert] = useTheme();
|
|
2036
|
+
const dialog = useDialog();
|
|
2037
|
+
const mantineTheme = useMantineTheme();
|
|
2038
|
+
const { overrides, setOverrides } = expert;
|
|
2039
|
+
const currentColor = overrides.primaryColor || mantineTheme.primaryColor;
|
|
2040
|
+
const currentRadius = overrides.radius || mantineTheme.defaultRadius || "md";
|
|
2041
|
+
const currentFont = overrides.fontFamily || "";
|
|
2042
|
+
const currentFontSize = overrides.fontSize || "md";
|
|
2043
|
+
const currentScale = overrides.scale || "md";
|
|
2044
|
+
const updateOverrides = (patch) => {
|
|
2045
|
+
setOverrides({
|
|
2046
|
+
...overrides,
|
|
2047
|
+
...patch
|
|
2048
|
+
});
|
|
2049
|
+
};
|
|
2050
|
+
return /* @__PURE__ */ jsxs(Flex, {
|
|
2051
|
+
direction: "column",
|
|
2052
|
+
gap: "lg",
|
|
2053
|
+
children: [
|
|
2054
|
+
/* @__PURE__ */ jsxs(Flex, {
|
|
2055
|
+
direction: "column",
|
|
2056
|
+
gap: "xs",
|
|
2057
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2058
|
+
fw: 500,
|
|
2059
|
+
size: "sm",
|
|
2060
|
+
children: "Primary Color"
|
|
2061
|
+
}), /* @__PURE__ */ jsx(SimpleGrid, {
|
|
2062
|
+
cols: 6,
|
|
2063
|
+
spacing: "xs",
|
|
2064
|
+
children: MANTINE_COLORS.map((color) => /* @__PURE__ */ jsx(Flex, {
|
|
2065
|
+
justify: "center",
|
|
2066
|
+
children: /* @__PURE__ */ jsx(ColorSwatch, {
|
|
2067
|
+
color: mantineTheme.colors[color]?.[6] ?? color,
|
|
2068
|
+
onClick: () => updateOverrides({ primaryColor: color }),
|
|
2069
|
+
style: { cursor: "pointer" },
|
|
2070
|
+
size: 32,
|
|
2071
|
+
children: currentColor === color && /* @__PURE__ */ jsx(IconCheck, {
|
|
2072
|
+
size: 14,
|
|
2073
|
+
color: "white"
|
|
2074
|
+
})
|
|
2075
|
+
})
|
|
2076
|
+
}, color))
|
|
2077
|
+
})]
|
|
2078
|
+
}),
|
|
2079
|
+
/* @__PURE__ */ jsxs(Flex, {
|
|
2080
|
+
direction: "column",
|
|
2081
|
+
gap: "xs",
|
|
2082
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2083
|
+
fw: 500,
|
|
2084
|
+
size: "sm",
|
|
2085
|
+
children: "Border Radius"
|
|
2086
|
+
}), /* @__PURE__ */ jsx(Flex, {
|
|
2087
|
+
gap: "xs",
|
|
2088
|
+
children: RADIUS_OPTIONS.map((opt) => /* @__PURE__ */ jsx(ActionButton, {
|
|
2089
|
+
variant: String(currentRadius) === opt.value ? "filled" : "default",
|
|
2090
|
+
size: "xs",
|
|
2091
|
+
flex: 1,
|
|
2092
|
+
onClick: () => updateOverrides({ radius: opt.value }),
|
|
2093
|
+
children: opt.label
|
|
2094
|
+
}, opt.value))
|
|
2095
|
+
})]
|
|
2096
|
+
}),
|
|
2097
|
+
/* @__PURE__ */ jsxs(Flex, {
|
|
2098
|
+
direction: "column",
|
|
2099
|
+
gap: "xs",
|
|
2100
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2101
|
+
fw: 500,
|
|
2102
|
+
size: "sm",
|
|
2103
|
+
children: "Font Family"
|
|
2104
|
+
}), /* @__PURE__ */ jsx(Select, {
|
|
2105
|
+
data: FONT_OPTIONS,
|
|
2106
|
+
value: currentFont,
|
|
2107
|
+
onChange: (value) => updateOverrides({ fontFamily: value ?? "" }),
|
|
2108
|
+
allowDeselect: false
|
|
2109
|
+
})]
|
|
2110
|
+
}),
|
|
2111
|
+
/* @__PURE__ */ jsxs(Flex, {
|
|
2112
|
+
direction: "column",
|
|
2113
|
+
gap: "xs",
|
|
2114
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2115
|
+
fw: 500,
|
|
2116
|
+
size: "sm",
|
|
2117
|
+
children: "Font Size"
|
|
2118
|
+
}), /* @__PURE__ */ jsx(Flex, {
|
|
2119
|
+
gap: "xs",
|
|
2120
|
+
children: SIZE_OPTIONS.map((opt) => /* @__PURE__ */ jsx(ActionButton, {
|
|
2121
|
+
variant: currentFontSize === opt.value ? "filled" : "default",
|
|
2122
|
+
size: "xs",
|
|
2123
|
+
flex: 1,
|
|
2124
|
+
onClick: () => updateOverrides({ fontSize: opt.value }),
|
|
2125
|
+
children: opt.label
|
|
2126
|
+
}, opt.value))
|
|
2127
|
+
})]
|
|
2128
|
+
}),
|
|
2129
|
+
/* @__PURE__ */ jsxs(Flex, {
|
|
2130
|
+
direction: "column",
|
|
2131
|
+
gap: "xs",
|
|
2132
|
+
children: [/* @__PURE__ */ jsx(Text, {
|
|
2133
|
+
fw: 500,
|
|
2134
|
+
size: "sm",
|
|
2135
|
+
children: "Scale"
|
|
2136
|
+
}), /* @__PURE__ */ jsx(Flex, {
|
|
2137
|
+
gap: "xs",
|
|
2138
|
+
children: SIZE_OPTIONS.map((opt) => /* @__PURE__ */ jsx(ActionButton, {
|
|
2139
|
+
variant: currentScale === opt.value ? "filled" : "default",
|
|
2140
|
+
size: "xs",
|
|
2141
|
+
flex: 1,
|
|
2142
|
+
onClick: () => updateOverrides({ scale: opt.value }),
|
|
2143
|
+
children: opt.label
|
|
2144
|
+
}, opt.value))
|
|
2145
|
+
})]
|
|
2146
|
+
}),
|
|
2147
|
+
/* @__PURE__ */ jsxs(Flex, {
|
|
2148
|
+
justify: "space-between",
|
|
2149
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2150
|
+
variant: "subtle",
|
|
2151
|
+
color: "red",
|
|
2152
|
+
onClick: () => expert.resetOverrides(),
|
|
2153
|
+
children: "Reset"
|
|
2154
|
+
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
2155
|
+
variant: "default",
|
|
2156
|
+
px: "xl",
|
|
2157
|
+
onClick: () => dialog.close(),
|
|
2158
|
+
children: "OK"
|
|
2159
|
+
})]
|
|
2160
|
+
})
|
|
2161
|
+
]
|
|
2162
|
+
});
|
|
2163
|
+
};
|
|
2164
|
+
|
|
2165
|
+
//#endregion
|
|
2166
|
+
//#region ../../src/core/components/buttons/ThemeButton.tsx
|
|
2167
|
+
const ThemeButton = (props) => {
|
|
2168
|
+
const { expert, ...actionProps } = props;
|
|
2169
|
+
const [theme, setTheme] = useTheme();
|
|
2170
|
+
const themeList = useStore(alephaThemeListAtom)[0];
|
|
2171
|
+
const dialog = useDialog();
|
|
2172
|
+
const items = themeList.map((it, index) => ({
|
|
2173
|
+
label: it.name,
|
|
2174
|
+
onClick: () => setTheme({ index }),
|
|
2175
|
+
active: theme.name === it.name
|
|
2176
|
+
}));
|
|
2177
|
+
if (expert) items.push({ type: "divider" }, {
|
|
2178
|
+
label: "Customize...",
|
|
2179
|
+
onClick: () => {
|
|
2180
|
+
dialog.open({
|
|
2181
|
+
title: "Customize Theme",
|
|
2182
|
+
content: /* @__PURE__ */ jsx(ThemeExpertModal, {})
|
|
2183
|
+
});
|
|
2184
|
+
}
|
|
2185
|
+
});
|
|
2186
|
+
return /* @__PURE__ */ jsx(ActionButton, {
|
|
2187
|
+
variant: "default",
|
|
2188
|
+
icon: IconPalette,
|
|
2189
|
+
menu: { items },
|
|
2190
|
+
...actionProps
|
|
2191
|
+
});
|
|
2192
|
+
};
|
|
2193
|
+
|
|
988
2194
|
//#endregion
|
|
989
2195
|
//#region ../../src/core/components/buttons/ToggleSidebarButton.tsx
|
|
990
2196
|
const ToggleSidebarButton = (props) => {
|
|
@@ -992,8 +2198,7 @@ const ToggleSidebarButton = (props) => {
|
|
|
992
2198
|
return /* @__PURE__ */ jsx(ActionButton, {
|
|
993
2199
|
icon: sidebar.collapsed ? IconLayoutSidebarRightCollapse : IconLayoutSidebarLeftCollapse,
|
|
994
2200
|
visibleFrom: "md",
|
|
995
|
-
variant: "
|
|
996
|
-
size: "md",
|
|
2201
|
+
variant: "default",
|
|
997
2202
|
onClick: () => {
|
|
998
2203
|
setSidebar({
|
|
999
2204
|
...sidebar,
|
|
@@ -1011,7 +2216,7 @@ const ToggleSidebarButton = (props) => {
|
|
|
1011
2216
|
//#endregion
|
|
1012
2217
|
//#region ../../src/core/components/Flex.tsx
|
|
1013
2218
|
const Flex$1 = forwardRef((props, ref) => {
|
|
1014
|
-
const { fill, center, centerX, centerY, col, ...rest } = props;
|
|
2219
|
+
const { fill, center, centerX, centerY, col, ground, surface, elevated, rounded, bordered, borderedTop, borderedBottom, shadowed, overflow, ...rest } = props;
|
|
1015
2220
|
if (fill) rest.flex ??= 1;
|
|
1016
2221
|
if (col) rest.direction ??= "column";
|
|
1017
2222
|
if (center) {
|
|
@@ -1020,6 +2225,21 @@ const Flex$1 = forwardRef((props, ref) => {
|
|
|
1020
2225
|
}
|
|
1021
2226
|
if (centerX) rest.justify ??= "center";
|
|
1022
2227
|
if (centerY) rest.align ??= "center";
|
|
2228
|
+
if (ground) rest.bg = "var(--alepha-ground)";
|
|
2229
|
+
else if (surface) rest.bg = "var(--alepha-surface)";
|
|
2230
|
+
else if (elevated) rest.bg = "var(--alepha-elevated)";
|
|
2231
|
+
if (rounded) rest.bdrs = rounded === true ? "md" : rounded;
|
|
2232
|
+
if (bordered) rest.bd = "1px solid var(--alepha-border)";
|
|
2233
|
+
if (borderedTop) rest.style = {
|
|
2234
|
+
borderTop: "1px solid var(--alepha-border)",
|
|
2235
|
+
...rest.style ?? {}
|
|
2236
|
+
};
|
|
2237
|
+
if (borderedBottom) rest.style = {
|
|
2238
|
+
borderBottom: "1px solid var(--alepha-border)",
|
|
2239
|
+
...rest.style ?? {}
|
|
2240
|
+
};
|
|
2241
|
+
if (shadowed) rest.className = `${rest.className ?? ""} shadow-${shadowed === true ? "md" : shadowed}`.trim();
|
|
2242
|
+
if (overflow) rest.className = `${rest.className ?? ""} overflow-auto`.trim();
|
|
1023
2243
|
return /* @__PURE__ */ jsx(Flex, {
|
|
1024
2244
|
ref,
|
|
1025
2245
|
...rest
|
|
@@ -1043,6 +2263,7 @@ const AppBar = (props) => {
|
|
|
1043
2263
|
if ("type" in item) {
|
|
1044
2264
|
if (item.type === "burger") return /* @__PURE__ */ jsx(BurgerButton, {}, index);
|
|
1045
2265
|
if (item.type === "dark") return /* @__PURE__ */ jsx(DarkModeButton, { ...item.props }, index);
|
|
2266
|
+
if (item.type === "theme") return /* @__PURE__ */ jsx(ThemeButton, { ...item.props }, index);
|
|
1046
2267
|
if (item.type === "search") return /* @__PURE__ */ jsx(OmnibarButton, { ...item.props }, index);
|
|
1047
2268
|
if (item.type === "lang") return /* @__PURE__ */ jsx(LanguageButton, { ...item.props }, index);
|
|
1048
2269
|
if (item.type === "spacer") return /* @__PURE__ */ jsx(Flex$1, { w: 16 }, index);
|
|
@@ -1156,7 +2377,8 @@ const AppBar = (props) => {
|
|
|
1156
2377
|
* Pages should define a `label` in their `$page()` options for best results.
|
|
1157
2378
|
* Falls back to the page name converted to Title Case.
|
|
1158
2379
|
*/
|
|
1159
|
-
const Breadcrumb = (
|
|
2380
|
+
const Breadcrumb = (props) => {
|
|
2381
|
+
const { home = "Home", separator, size = "sm", ...groupProps } = props;
|
|
1160
2382
|
const state = useRouterState();
|
|
1161
2383
|
const router = useRouter();
|
|
1162
2384
|
const crumbs = [];
|
|
@@ -1211,11 +2433,175 @@ const Container$1 = forwardRef((props, ref) => {
|
|
|
1211
2433
|
});
|
|
1212
2434
|
Container$1.displayName = "Container";
|
|
1213
2435
|
|
|
2436
|
+
//#endregion
|
|
2437
|
+
//#region ../../src/core/helpers/renderIcon.tsx
|
|
2438
|
+
const renderIcon = (icon, size) => {
|
|
2439
|
+
if (!icon) return null;
|
|
2440
|
+
if (isValidElement(icon)) return icon;
|
|
2441
|
+
if (isComponentType(icon)) return /* @__PURE__ */ jsx(icon, { size: size ?? ui.sizes.icon.md });
|
|
2442
|
+
return icon;
|
|
2443
|
+
};
|
|
2444
|
+
|
|
2445
|
+
//#endregion
|
|
2446
|
+
//#region ../../src/core/components/Text.tsx
|
|
2447
|
+
const INTENT_COLORS = {
|
|
2448
|
+
primary: "blue",
|
|
2449
|
+
info: "cyan",
|
|
2450
|
+
success: "green",
|
|
2451
|
+
warning: "yellow",
|
|
2452
|
+
danger: "red"
|
|
2453
|
+
};
|
|
2454
|
+
const Text$1 = forwardRef((props, ref) => {
|
|
2455
|
+
const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
|
|
2456
|
+
if (intent) rest.c ??= INTENT_COLORS[intent];
|
|
2457
|
+
if (bold) rest.fw ??= 700;
|
|
2458
|
+
if (light) rest.fw ??= 300;
|
|
2459
|
+
if (italic) rest.fs ??= "italic";
|
|
2460
|
+
if (muted) rest.c ??= "dimmed";
|
|
2461
|
+
if (small) rest.size ??= "xs";
|
|
2462
|
+
if (uppercase) rest.tt ??= "uppercase";
|
|
2463
|
+
if (capitalize) rest.tt ??= "capitalize";
|
|
2464
|
+
if (center) rest.ta ??= "center";
|
|
2465
|
+
if (monospace) rest.ff ??= "monospace";
|
|
2466
|
+
if (title) rest.size ??= "xl";
|
|
2467
|
+
return /* @__PURE__ */ jsx(Text, {
|
|
2468
|
+
ref,
|
|
2469
|
+
...rest
|
|
2470
|
+
});
|
|
2471
|
+
});
|
|
2472
|
+
Text$1.displayName = "Text";
|
|
2473
|
+
|
|
2474
|
+
//#endregion
|
|
2475
|
+
//#region ../../src/core/components/layout/SidebarCollapsedItem.tsx
|
|
2476
|
+
const SidebarCollapsedItem = (props) => {
|
|
2477
|
+
const router = useRouter();
|
|
2478
|
+
const handleItemClick = () => {
|
|
2479
|
+
props.onItemClick?.(props.item);
|
|
2480
|
+
props.item.onClick?.();
|
|
2481
|
+
};
|
|
2482
|
+
const hasChildren = props.item.children && props.item.children.length > 0;
|
|
2483
|
+
const menu = hasChildren ? {
|
|
2484
|
+
on: "hover",
|
|
2485
|
+
position: "right",
|
|
2486
|
+
menuProps: {
|
|
2487
|
+
arrowPosition: "center",
|
|
2488
|
+
arrowSize: 10,
|
|
2489
|
+
withArrow: true
|
|
2490
|
+
},
|
|
2491
|
+
items: [{
|
|
2492
|
+
type: "label",
|
|
2493
|
+
label: props.item.label
|
|
2494
|
+
}, ...props.item.children.filter((child) => !child.can || child.can()).map((child) => ({
|
|
2495
|
+
label: child.label,
|
|
2496
|
+
icon: renderIcon(child.icon, ui.sizes.icon.sm),
|
|
2497
|
+
href: child.href,
|
|
2498
|
+
active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
|
|
2499
|
+
}))]
|
|
2500
|
+
} : void 0;
|
|
2501
|
+
return /* @__PURE__ */ jsx(Flex$1, {
|
|
2502
|
+
w: "100%",
|
|
2503
|
+
justify: "center",
|
|
2504
|
+
pos: "relative",
|
|
2505
|
+
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
2506
|
+
size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
|
|
2507
|
+
bd: 0,
|
|
2508
|
+
variant: "default",
|
|
2509
|
+
propsActive: { variant: "outline" },
|
|
2510
|
+
tooltip: hasChildren ? void 0 : {
|
|
2511
|
+
label: props.item.label,
|
|
2512
|
+
position: "right"
|
|
2513
|
+
},
|
|
2514
|
+
onClick: hasChildren ? void 0 : handleItemClick,
|
|
2515
|
+
icon: renderIcon(props.item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
|
|
2516
|
+
href: hasChildren ? void 0 : props.item.href,
|
|
2517
|
+
target: hasChildren ? void 0 : props.item.target,
|
|
2518
|
+
menu,
|
|
2519
|
+
...props.item.actionProps
|
|
2520
|
+
})
|
|
2521
|
+
});
|
|
2522
|
+
};
|
|
2523
|
+
|
|
2524
|
+
//#endregion
|
|
2525
|
+
//#region ../../src/core/components/layout/SidebarItem.tsx
|
|
2526
|
+
const SidebarItem = (props) => {
|
|
2527
|
+
const maxLevel = 2;
|
|
2528
|
+
const router = useRouter();
|
|
2529
|
+
const isActive = useCallback((item) => {
|
|
2530
|
+
if (!item.children) return false;
|
|
2531
|
+
for (const child of item.children) {
|
|
2532
|
+
if (child.href) {
|
|
2533
|
+
if (router.isActive(child.href)) return true;
|
|
2534
|
+
}
|
|
2535
|
+
if (isActive(child)) return true;
|
|
2536
|
+
}
|
|
2537
|
+
return false;
|
|
2538
|
+
}, []);
|
|
2539
|
+
const [isOpen, setIsOpen] = useState(isActive(props.item));
|
|
2540
|
+
useEvents({ "react:transition:end": () => {
|
|
2541
|
+
if (isActive(props.item)) setIsOpen(true);
|
|
2542
|
+
} }, []);
|
|
2543
|
+
if (props.level > maxLevel) return null;
|
|
2544
|
+
const handleItemClick = (e) => {
|
|
2545
|
+
if (!props.item.target) e.preventDefault();
|
|
2546
|
+
if (props.item.children && props.item.children.length > 0) setIsOpen(!isOpen);
|
|
2547
|
+
else {
|
|
2548
|
+
props.onItemClick?.(props.item);
|
|
2549
|
+
props.item.onClick?.();
|
|
2550
|
+
}
|
|
2551
|
+
};
|
|
2552
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
2553
|
+
direction: "column",
|
|
2554
|
+
ps: props.level === 0 ? 0 : 32,
|
|
2555
|
+
pos: "relative",
|
|
2556
|
+
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2557
|
+
w: "100%",
|
|
2558
|
+
justify: "space-between",
|
|
2559
|
+
href: props.item.href,
|
|
2560
|
+
target: props.item.target,
|
|
2561
|
+
size: props.item.theme?.size ?? props.theme.button?.size ?? (props.level === 0 ? "sm" : "xs"),
|
|
2562
|
+
bd: 0,
|
|
2563
|
+
fw: "normal",
|
|
2564
|
+
variant: "default",
|
|
2565
|
+
propsActive: { variant: "outline" },
|
|
2566
|
+
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
2567
|
+
onClick: handleItemClick,
|
|
2568
|
+
leftSection: /* @__PURE__ */ jsxs(Flex$1, {
|
|
2569
|
+
w: "100%",
|
|
2570
|
+
align: "center",
|
|
2571
|
+
gap: "sm",
|
|
2572
|
+
children: [renderIcon(props.item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex$1, {
|
|
2573
|
+
direction: "column",
|
|
2574
|
+
children: /* @__PURE__ */ jsx(Flex$1, { children: props.item.label })
|
|
2575
|
+
})]
|
|
2576
|
+
}),
|
|
2577
|
+
rightSection: props.item.children ? /* @__PURE__ */ jsx(Flex$1, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
|
|
2578
|
+
...props.item.actionProps
|
|
2579
|
+
}), props.item.children && isOpen && /* @__PURE__ */ jsxs(Flex$1, {
|
|
2580
|
+
direction: "column",
|
|
2581
|
+
"data-parent-level": props.level,
|
|
2582
|
+
gap: 2,
|
|
2583
|
+
py: 2,
|
|
2584
|
+
children: [/* @__PURE__ */ jsx(Flex$1, { style: {
|
|
2585
|
+
position: "absolute",
|
|
2586
|
+
width: 1,
|
|
2587
|
+
background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
|
|
2588
|
+
top: 48,
|
|
2589
|
+
left: 20 + 32 * props.level,
|
|
2590
|
+
bottom: 16
|
|
2591
|
+
} }), props.item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
|
|
2592
|
+
item: child,
|
|
2593
|
+
level: props.level + 1,
|
|
2594
|
+
onItemClick: props.onItemClick,
|
|
2595
|
+
theme: props.theme
|
|
2596
|
+
}, index))]
|
|
2597
|
+
})]
|
|
2598
|
+
});
|
|
2599
|
+
};
|
|
2600
|
+
|
|
1214
2601
|
//#endregion
|
|
1215
2602
|
//#region ../../src/core/components/layout/Sidebar.tsx
|
|
1216
2603
|
const Sidebar = (props) => {
|
|
1217
2604
|
const router = useRouter();
|
|
1218
|
-
const { onItemClick } = props;
|
|
1219
2605
|
const divider = (key, fill, collapsed) => {
|
|
1220
2606
|
return /* @__PURE__ */ jsx(Flex$1, {
|
|
1221
2607
|
h: 1,
|
|
@@ -1233,6 +2619,9 @@ const Sidebar = (props) => {
|
|
|
1233
2619
|
if (item.type === "divider") return divider(key, item.fill, collapsed);
|
|
1234
2620
|
if (item.type === "search") return /* @__PURE__ */ jsx(Flex$1, {
|
|
1235
2621
|
mb: "xs",
|
|
2622
|
+
w: "100%",
|
|
2623
|
+
justify: "center",
|
|
2624
|
+
pos: "relative",
|
|
1236
2625
|
children: /* @__PURE__ */ jsx(OmnibarButton, { collapsed })
|
|
1237
2626
|
}, key);
|
|
1238
2627
|
if (item.type === "toggle") return /* @__PURE__ */ jsx(ToggleSidebarButton, {}, key);
|
|
@@ -1240,7 +2629,7 @@ const Sidebar = (props) => {
|
|
|
1240
2629
|
if (item.children && item.children.length > 0) {
|
|
1241
2630
|
if (!item.children.some((child) => !("can" in child) || !child.can || child.can())) return null;
|
|
1242
2631
|
}
|
|
1243
|
-
if (collapsed) return /* @__PURE__ */
|
|
2632
|
+
if (collapsed) return /* @__PURE__ */ jsx(Fragment$1, { children: item.children?.map((child, index) => renderNode(child, `s${key}-${index}`, collapsed)) }, key);
|
|
1244
2633
|
return /* @__PURE__ */ jsxs(Fragment$1, { children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
1245
2634
|
mt: "md",
|
|
1246
2635
|
align: "center",
|
|
@@ -1263,13 +2652,13 @@ const Sidebar = (props) => {
|
|
|
1263
2652
|
if (collapsed) return /* @__PURE__ */ jsx(SidebarCollapsedItem, {
|
|
1264
2653
|
item,
|
|
1265
2654
|
level: 0,
|
|
1266
|
-
onItemClick,
|
|
2655
|
+
onItemClick: props.onItemClick,
|
|
1267
2656
|
theme: props.theme ?? {}
|
|
1268
2657
|
}, key);
|
|
1269
2658
|
return /* @__PURE__ */ jsx(SidebarItem, {
|
|
1270
2659
|
item,
|
|
1271
2660
|
level: 0,
|
|
1272
|
-
onItemClick,
|
|
2661
|
+
onItemClick: props.onItemClick,
|
|
1273
2662
|
theme: props.theme ?? {}
|
|
1274
2663
|
}, key);
|
|
1275
2664
|
};
|
|
@@ -1290,7 +2679,7 @@ const Sidebar = (props) => {
|
|
|
1290
2679
|
return [];
|
|
1291
2680
|
};
|
|
1292
2681
|
const padding = "md";
|
|
1293
|
-
const gap = props.items ? props.gap ??
|
|
2682
|
+
const gap = props.items ? props.gap ?? 8 : "xs";
|
|
1294
2683
|
const menu = useMemo(() => getSidebarNodes(), [props.items, props.autoPopulateMenu]);
|
|
1295
2684
|
const renderSidebar = (collapsed) => /* @__PURE__ */ jsxs(Flex$1, {
|
|
1296
2685
|
flex: 1,
|
|
@@ -1332,117 +2721,6 @@ const Sidebar = (props) => {
|
|
|
1332
2721
|
})] });
|
|
1333
2722
|
return renderSidebar(false);
|
|
1334
2723
|
};
|
|
1335
|
-
const SidebarItem = (props) => {
|
|
1336
|
-
const { item, level } = props;
|
|
1337
|
-
const maxLevel = 2;
|
|
1338
|
-
const router = useRouter();
|
|
1339
|
-
const isActive = useCallback((item) => {
|
|
1340
|
-
if (!item.children) return false;
|
|
1341
|
-
for (const child of item.children) {
|
|
1342
|
-
if (child.href) {
|
|
1343
|
-
if (router.isActive(child.href)) return true;
|
|
1344
|
-
}
|
|
1345
|
-
if (isActive(child)) return true;
|
|
1346
|
-
}
|
|
1347
|
-
return false;
|
|
1348
|
-
}, []);
|
|
1349
|
-
const [isOpen, setIsOpen] = useState(isActive(item));
|
|
1350
|
-
useEvents({ "react:transition:end": () => {
|
|
1351
|
-
if (isActive(item)) setIsOpen(true);
|
|
1352
|
-
} }, []);
|
|
1353
|
-
if (level > maxLevel) return null;
|
|
1354
|
-
const handleItemClick = (e) => {
|
|
1355
|
-
if (!props.item.target) e.preventDefault();
|
|
1356
|
-
if (item.children && item.children.length > 0) setIsOpen(!isOpen);
|
|
1357
|
-
else {
|
|
1358
|
-
props.onItemClick?.(item);
|
|
1359
|
-
item.onClick?.();
|
|
1360
|
-
}
|
|
1361
|
-
};
|
|
1362
|
-
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
1363
|
-
direction: "column",
|
|
1364
|
-
ps: level === 0 ? 0 : 32,
|
|
1365
|
-
pos: "relative",
|
|
1366
|
-
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
1367
|
-
w: "100%",
|
|
1368
|
-
justify: "space-between",
|
|
1369
|
-
href: props.item.href,
|
|
1370
|
-
target: props.item.target,
|
|
1371
|
-
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
1372
|
-
bd: 0,
|
|
1373
|
-
fw: "normal",
|
|
1374
|
-
variant: "default",
|
|
1375
|
-
propsActive: {
|
|
1376
|
-
variant: "outline",
|
|
1377
|
-
fw: "bold"
|
|
1378
|
-
},
|
|
1379
|
-
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
1380
|
-
onClick: handleItemClick,
|
|
1381
|
-
leftSection: /* @__PURE__ */ jsxs(Flex$1, {
|
|
1382
|
-
w: "100%",
|
|
1383
|
-
align: "center",
|
|
1384
|
-
gap: "sm",
|
|
1385
|
-
children: [renderIcon(item.icon, ui.sizes.icon.sm), /* @__PURE__ */ jsx(Flex$1, {
|
|
1386
|
-
direction: "column",
|
|
1387
|
-
children: /* @__PURE__ */ jsx(Flex$1, { children: item.label })
|
|
1388
|
-
})]
|
|
1389
|
-
}),
|
|
1390
|
-
rightSection: item.children ? /* @__PURE__ */ jsx(Flex$1, { children: isOpen ? /* @__PURE__ */ jsx(IconChevronDown, { size: 14 }) : /* @__PURE__ */ jsx(IconChevronRight, { size: 14 }) }) : props.item.rightSection,
|
|
1391
|
-
...props.item.actionProps
|
|
1392
|
-
}), item.children && isOpen && /* @__PURE__ */ jsxs(Flex$1, {
|
|
1393
|
-
direction: "column",
|
|
1394
|
-
"data-parent-level": level,
|
|
1395
|
-
children: [/* @__PURE__ */ jsx(Flex$1, { style: {
|
|
1396
|
-
position: "absolute",
|
|
1397
|
-
width: 1,
|
|
1398
|
-
background: "linear-gradient(to bottom, transparent, var(--mantine-color-default-border), transparent)",
|
|
1399
|
-
top: 48,
|
|
1400
|
-
left: 20 + 32 * level,
|
|
1401
|
-
bottom: 16
|
|
1402
|
-
} }), item.children.filter((child) => !child.can || child.can()).map((child, index) => /* @__PURE__ */ jsx(SidebarItem, {
|
|
1403
|
-
item: child,
|
|
1404
|
-
level: level + 1,
|
|
1405
|
-
onItemClick: props.onItemClick,
|
|
1406
|
-
theme: props.theme
|
|
1407
|
-
}, index))]
|
|
1408
|
-
})]
|
|
1409
|
-
});
|
|
1410
|
-
};
|
|
1411
|
-
const SidebarCollapsedItem = (props) => {
|
|
1412
|
-
const { item, level } = props;
|
|
1413
|
-
const router = useRouter();
|
|
1414
|
-
const handleItemClick = () => {
|
|
1415
|
-
props.onItemClick?.(item);
|
|
1416
|
-
item.onClick?.();
|
|
1417
|
-
};
|
|
1418
|
-
const hasChildren = item.children && item.children.length > 0;
|
|
1419
|
-
const menu = hasChildren ? {
|
|
1420
|
-
on: "hover",
|
|
1421
|
-
position: "right",
|
|
1422
|
-
items: item.children.filter((child) => !child.can || child.can()).map((child) => ({
|
|
1423
|
-
label: child.label,
|
|
1424
|
-
icon: renderIcon(child.icon, ui.sizes.icon.sm),
|
|
1425
|
-
href: child.href,
|
|
1426
|
-
active: child.href ? router.isActive(child.href, { startWith: child.activeStartsWith }) : void 0
|
|
1427
|
-
}))
|
|
1428
|
-
} : void 0;
|
|
1429
|
-
return /* @__PURE__ */ jsx(ActionButton, {
|
|
1430
|
-
size: props.item.theme?.size ?? props.theme.button?.size ?? (level === 0 ? "sm" : "xs"),
|
|
1431
|
-
variant: "subtle",
|
|
1432
|
-
variantActive: "default",
|
|
1433
|
-
tooltip: hasChildren ? void 0 : {
|
|
1434
|
-
label: item.label,
|
|
1435
|
-
position: "right"
|
|
1436
|
-
},
|
|
1437
|
-
radius: props.item.theme?.radius ?? props.theme.button?.radius ?? "md",
|
|
1438
|
-
onClick: hasChildren ? void 0 : handleItemClick,
|
|
1439
|
-
icon: renderIcon(item.icon, ui.sizes.icon.sm) ?? /* @__PURE__ */ jsx(IconSquareRounded, { size: ui.sizes.icon.sm }),
|
|
1440
|
-
href: hasChildren ? void 0 : props.item.href,
|
|
1441
|
-
target: hasChildren ? void 0 : props.item.target,
|
|
1442
|
-
menu,
|
|
1443
|
-
...props.item.actionProps
|
|
1444
|
-
});
|
|
1445
|
-
};
|
|
1446
2724
|
|
|
1447
2725
|
//#endregion
|
|
1448
2726
|
//#region ../../src/core/components/layout/DashboardShell.tsx
|
|
@@ -1483,13 +2761,16 @@ const DashboardShell = (props) => {
|
|
|
1483
2761
|
const fHeight = props.footerHeight ?? 24;
|
|
1484
2762
|
const headerHeight = hasAppBar ? hHeight : 0;
|
|
1485
2763
|
const footerHeight = footerElement ? fHeight : 0;
|
|
2764
|
+
const navbarWidth = collapsed ? collapsedWidth : expandedWidth;
|
|
2765
|
+
const mainContent = props.children ?? /* @__PURE__ */ jsx(NestedView, {});
|
|
1486
2766
|
return /* @__PURE__ */ jsxs(AppShell, {
|
|
1487
2767
|
layout: "alt",
|
|
1488
2768
|
w: "100%",
|
|
2769
|
+
h: "100vh",
|
|
1489
2770
|
flex: 1,
|
|
1490
2771
|
header: hasAppBar ? { height: hHeight } : void 0,
|
|
1491
2772
|
navbar: hasSidebar ? {
|
|
1492
|
-
width: { base:
|
|
2773
|
+
width: { base: navbarWidth },
|
|
1493
2774
|
breakpoint: "md",
|
|
1494
2775
|
collapsed: { mobile: sidebar.closed }
|
|
1495
2776
|
} : void 0,
|
|
@@ -1504,73 +2785,49 @@ const DashboardShell = (props) => {
|
|
|
1504
2785
|
})
|
|
1505
2786
|
}),
|
|
1506
2787
|
hasSidebar && /* @__PURE__ */ jsxs(AppShell.Navbar, {
|
|
1507
|
-
className: "alepha-sidebar-navbar",
|
|
1508
2788
|
...props.appShellNavbarProps,
|
|
1509
2789
|
children: [
|
|
1510
2790
|
props.navbarHeader ? /* @__PURE__ */ jsx(Flex$1, {
|
|
1511
2791
|
style: { borderBottom: "1px solid var(--mantine-color-default-border)" },
|
|
1512
2792
|
h: headerHeight,
|
|
1513
|
-
children: props.navbarHeader
|
|
2793
|
+
children: props.navbarHeader({ collapsed })
|
|
1514
2794
|
}) : null,
|
|
1515
2795
|
/* @__PURE__ */ jsx(Sidebar, {
|
|
1516
2796
|
...props.sidebarProps ?? {},
|
|
1517
2797
|
collapsed
|
|
1518
|
-
}),
|
|
1519
|
-
props.navbarFooter ? /* @__PURE__ */ jsx(Flex$1, {
|
|
1520
|
-
style: { borderTop: "1px solid var(--mantine-color-default-border)" },
|
|
1521
|
-
h: footerHeight,
|
|
1522
|
-
children: props.navbarFooter
|
|
1523
|
-
}) : null
|
|
1524
|
-
]
|
|
1525
|
-
}),
|
|
1526
|
-
/* @__PURE__ */ jsx(AppShell.Main, {
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
primary: "blue",
|
|
1543
|
-
info: "cyan",
|
|
1544
|
-
success: "green",
|
|
1545
|
-
warning: "yellow",
|
|
1546
|
-
danger: "red"
|
|
1547
|
-
};
|
|
1548
|
-
const Text$1 = forwardRef((props, ref) => {
|
|
1549
|
-
const { intent, bold, italic, light, muted, small, uppercase, capitalize, center, monospace, title, ...rest } = props;
|
|
1550
|
-
if (intent) rest.c ??= INTENT_COLORS[intent];
|
|
1551
|
-
if (bold) rest.fw ??= 700;
|
|
1552
|
-
if (light) rest.fw ??= 300;
|
|
1553
|
-
if (italic) rest.fs ??= "italic";
|
|
1554
|
-
if (muted) rest.c ??= "dimmed";
|
|
1555
|
-
if (small) rest.size ??= "sm";
|
|
1556
|
-
if (uppercase) rest.tt ??= "uppercase";
|
|
1557
|
-
if (capitalize) rest.tt ??= "capitalize";
|
|
1558
|
-
if (center) rest.ta ??= "center";
|
|
1559
|
-
if (monospace) rest.ff ??= "monospace";
|
|
1560
|
-
if (title) rest.size ??= "xl";
|
|
1561
|
-
return /* @__PURE__ */ jsx(Text, {
|
|
1562
|
-
ref,
|
|
1563
|
-
...rest
|
|
2798
|
+
}),
|
|
2799
|
+
props.navbarFooter ? /* @__PURE__ */ jsx(Flex$1, {
|
|
2800
|
+
style: { borderTop: "1px solid var(--mantine-color-default-border)" },
|
|
2801
|
+
h: footerHeight,
|
|
2802
|
+
children: props.navbarFooter
|
|
2803
|
+
}) : null
|
|
2804
|
+
]
|
|
2805
|
+
}),
|
|
2806
|
+
/* @__PURE__ */ jsx(AppShell.Main, {
|
|
2807
|
+
display: "flex",
|
|
2808
|
+
bg: "var(--alepha-ground)",
|
|
2809
|
+
pos: "relative",
|
|
2810
|
+
h: props.fill ? "100%" : "inherit",
|
|
2811
|
+
...props.appShellMainProps,
|
|
2812
|
+
children: props.container ? /* @__PURE__ */ jsx(Container$1, {
|
|
2813
|
+
...typeof props.container === "boolean" ? {} : props.container,
|
|
2814
|
+
children: mainContent
|
|
2815
|
+
}) : mainContent
|
|
2816
|
+
}),
|
|
2817
|
+
footerElement && /* @__PURE__ */ jsx(AppShell.Footer, {
|
|
2818
|
+
...props.appShellFooterProps,
|
|
2819
|
+
children: footerElement
|
|
2820
|
+
})
|
|
2821
|
+
]
|
|
1564
2822
|
});
|
|
1565
|
-
}
|
|
1566
|
-
Text$1.displayName = "Text";
|
|
2823
|
+
};
|
|
1567
2824
|
|
|
1568
2825
|
//#endregion
|
|
1569
2826
|
//#region ../../src/core/form/utils/parseInput.ts
|
|
1570
2827
|
const parseInput = (props, form) => {
|
|
1571
2828
|
const disabled = false;
|
|
1572
2829
|
const id = props.input.props.id;
|
|
1573
|
-
const label = props.
|
|
2830
|
+
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);
|
|
1574
2831
|
const description = props.description ?? ("description" in props.input.schema && typeof props.input.schema.description === "string" ? props.input.schema.description : void 0);
|
|
1575
2832
|
const error = form.error && form.error instanceof TypeBoxError ? form.error.value.message : void 0;
|
|
1576
2833
|
const icon = !props.icon ? getDefaultIcon({
|
|
@@ -1578,17 +2835,20 @@ const parseInput = (props, form) => {
|
|
|
1578
2835
|
format: props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0,
|
|
1579
2836
|
name: props.input.props.name,
|
|
1580
2837
|
isEnum: props.input.schema && "enum" in props.input.schema && Boolean(props.input.schema.enum),
|
|
1581
|
-
isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array"
|
|
1582
|
-
|
|
2838
|
+
isArray: props.input.schema && "type" in props.input.schema && props.input.schema.type === "array",
|
|
2839
|
+
size: props.size
|
|
2840
|
+
}) : isValidElement(props.icon) ? props.icon : createElement(props.icon, { size: ui.sizes.icon.sm });
|
|
1583
2841
|
const format = props.input.schema && "format" in props.input.schema && typeof props.input.schema.format === "string" ? props.input.schema.format : void 0;
|
|
1584
2842
|
const required = props.input.required;
|
|
1585
2843
|
const schema = props.input.schema;
|
|
2844
|
+
const testId = props.input.props?.["data-testid"];
|
|
1586
2845
|
const inputProps = {
|
|
1587
2846
|
label,
|
|
1588
2847
|
description,
|
|
1589
2848
|
error,
|
|
1590
2849
|
required,
|
|
1591
|
-
disabled
|
|
2850
|
+
disabled,
|
|
2851
|
+
...testId ? { "data-testid": testId } : {}
|
|
1592
2852
|
};
|
|
1593
2853
|
if ("minLength" in schema && typeof schema.minLength === "number") inputProps.minLength = schema.minLength;
|
|
1594
2854
|
if ("maxLength" in schema && typeof schema.maxLength === "number") inputProps.maxLength = schema.maxLength;
|
|
@@ -1613,8 +2873,8 @@ const useArrayItems = (input) => {
|
|
|
1613
2873
|
const alepha = useAlepha();
|
|
1614
2874
|
const keyCounter = useRef(0);
|
|
1615
2875
|
const [items, setItemsState] = useState(() => {
|
|
1616
|
-
const
|
|
1617
|
-
if (Array.isArray(
|
|
2876
|
+
const initial = input?.initialValue;
|
|
2877
|
+
if (Array.isArray(initial)) return initial.map((value) => ({
|
|
1618
2878
|
key: keyCounter.current++,
|
|
1619
2879
|
value
|
|
1620
2880
|
}));
|
|
@@ -1640,22 +2900,9 @@ const useArrayItems = (input) => {
|
|
|
1640
2900
|
if (!input?.form) return;
|
|
1641
2901
|
const formId = input.form.id;
|
|
1642
2902
|
const fieldPath = input.path;
|
|
1643
|
-
|
|
1644
|
-
if (event.id === formId) {
|
|
1645
|
-
const defaultValue = input.props?.defaultValue;
|
|
1646
|
-
keyCounter.current = 0;
|
|
1647
|
-
if (Array.isArray(defaultValue)) setItemsState(defaultValue.map((value) => ({
|
|
1648
|
-
key: keyCounter.current++,
|
|
1649
|
-
value
|
|
1650
|
-
})));
|
|
1651
|
-
else setItemsState([]);
|
|
1652
|
-
}
|
|
1653
|
-
}), alepha.events.on("form:change", (event) => {
|
|
2903
|
+
return alepha.events.on("form:change", (event) => {
|
|
1654
2904
|
if (event.id === formId && event.path === fieldPath) syncFromFormValue(event.value);
|
|
1655
|
-
})
|
|
1656
|
-
return () => {
|
|
1657
|
-
for (const unsub of listeners) unsub();
|
|
1658
|
-
};
|
|
2905
|
+
});
|
|
1659
2906
|
}, [
|
|
1660
2907
|
alepha,
|
|
1661
2908
|
input,
|
|
@@ -1680,10 +2927,10 @@ const createArrayItemInput = (parentInput, itemSchema, index, _itemKey, value, o
|
|
|
1680
2927
|
path: `${parentInput.path}/${index}`,
|
|
1681
2928
|
required: false,
|
|
1682
2929
|
form: parentInput.form,
|
|
2930
|
+
initialValue: value,
|
|
1683
2931
|
props: {
|
|
1684
2932
|
id: `${parentInput.props.id}-${index}`,
|
|
1685
|
-
name: `${parentInput.props.name}[${index}]
|
|
1686
|
-
defaultValue: value
|
|
2933
|
+
name: `${parentInput.props.name}[${index}]`
|
|
1687
2934
|
},
|
|
1688
2935
|
set: onValueChange
|
|
1689
2936
|
};
|
|
@@ -1698,10 +2945,10 @@ const createArrayItemFieldInput = (parentInput, itemSchema, fieldName, index, _i
|
|
|
1698
2945
|
path: `${parentInput.path}/${index}/${fieldName}`,
|
|
1699
2946
|
required: itemSchema.required?.includes(fieldName) ?? false,
|
|
1700
2947
|
form: parentInput.form,
|
|
2948
|
+
initialValue: itemValue?.[fieldName],
|
|
1701
2949
|
props: {
|
|
1702
2950
|
id: `${parentInput.props.id}-${index}-${fieldName}`,
|
|
1703
|
-
name: `${parentInput.props.name}[${index}].${fieldName}
|
|
1704
|
-
defaultValue: itemValue?.[fieldName]
|
|
2951
|
+
name: `${parentInput.props.name}[${index}].${fieldName}`
|
|
1705
2952
|
},
|
|
1706
2953
|
set: (value) => onFieldChange(fieldName, value)
|
|
1707
2954
|
};
|
|
@@ -1919,7 +3166,9 @@ const ControlArray = (props) => {
|
|
|
1919
3166
|
* Automatically detects date formats from schema and renders appropriate picker.
|
|
1920
3167
|
*/
|
|
1921
3168
|
const ControlDate = (props) => {
|
|
1922
|
-
const
|
|
3169
|
+
const form = useFormState(props.input);
|
|
3170
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3171
|
+
const { inputProps, id, icon, format } = parseInput(props, form);
|
|
1923
3172
|
if (!props.input?.props) return null;
|
|
1924
3173
|
if (props.datetime || format === "date-time") {
|
|
1925
3174
|
const dateTimePickerProps = typeof props.datetime === "object" ? props.datetime : {};
|
|
@@ -1927,10 +3176,8 @@ const ControlDate = (props) => {
|
|
|
1927
3176
|
...inputProps,
|
|
1928
3177
|
id,
|
|
1929
3178
|
leftSection: icon,
|
|
1930
|
-
|
|
1931
|
-
onChange: (
|
|
1932
|
-
props.input.set(value ? new Date(value).toISOString() : void 0);
|
|
1933
|
-
},
|
|
3179
|
+
value: value ? new Date(value) : null,
|
|
3180
|
+
onChange: (val) => setValue(val ? new Date(val).toISOString() : void 0),
|
|
1934
3181
|
...dateTimePickerProps
|
|
1935
3182
|
});
|
|
1936
3183
|
}
|
|
@@ -1940,10 +3187,8 @@ const ControlDate = (props) => {
|
|
|
1940
3187
|
...inputProps,
|
|
1941
3188
|
id,
|
|
1942
3189
|
leftSection: icon,
|
|
1943
|
-
|
|
1944
|
-
onChange: (
|
|
1945
|
-
props.input.set(value ? new Date(value).toISOString().slice(0, 10) : void 0);
|
|
1946
|
-
},
|
|
3190
|
+
value: value ? new Date(value) : null,
|
|
3191
|
+
onChange: (val) => setValue(val ? new Date(val).toISOString().slice(0, 10) : void 0),
|
|
1947
3192
|
...dateInputProps
|
|
1948
3193
|
});
|
|
1949
3194
|
}
|
|
@@ -1953,10 +3198,8 @@ const ControlDate = (props) => {
|
|
|
1953
3198
|
...inputProps,
|
|
1954
3199
|
id,
|
|
1955
3200
|
leftSection: icon,
|
|
1956
|
-
|
|
1957
|
-
onChange: (event) =>
|
|
1958
|
-
props.input.set(event.currentTarget.value);
|
|
1959
|
-
},
|
|
3201
|
+
value: value ?? "",
|
|
3202
|
+
onChange: (event) => setValue(event.currentTarget.value),
|
|
1960
3203
|
...timeInputProps
|
|
1961
3204
|
});
|
|
1962
3205
|
}
|
|
@@ -1969,14 +3212,10 @@ const ControlDate = (props) => {
|
|
|
1969
3212
|
*
|
|
1970
3213
|
*/
|
|
1971
3214
|
const ControlNumber = (props) => {
|
|
1972
|
-
const
|
|
1973
|
-
const
|
|
1974
|
-
const
|
|
1975
|
-
useEvents({ "form:reset": (event) => {
|
|
1976
|
-
if (event.id === props.input?.form.id && ref.current) setValue(props.input.props.defaultValue);
|
|
1977
|
-
} }, [props.input]);
|
|
3215
|
+
const form = useFormState(props.input);
|
|
3216
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3217
|
+
const { inputProps, id, icon } = parseInput(props, form);
|
|
1978
3218
|
if (!props.input?.props) return null;
|
|
1979
|
-
const { type, ...inputPropsWithoutType } = props.input.props;
|
|
1980
3219
|
if (props.sliderProps) {
|
|
1981
3220
|
const min = props.sliderProps.min ?? inputProps.minimum ?? 0;
|
|
1982
3221
|
const max = props.sliderProps.max ?? inputProps.maximum ?? 100;
|
|
@@ -1989,34 +3228,25 @@ const ControlNumber = (props) => {
|
|
|
1989
3228
|
},
|
|
1990
3229
|
children: /* @__PURE__ */ jsx(Slider, {
|
|
1991
3230
|
...inputProps,
|
|
1992
|
-
ref,
|
|
1993
3231
|
id,
|
|
1994
|
-
...inputPropsWithoutType,
|
|
1995
3232
|
...props.sliderProps,
|
|
1996
|
-
value,
|
|
3233
|
+
value: value ?? 0,
|
|
1997
3234
|
min,
|
|
1998
3235
|
max,
|
|
1999
3236
|
label: () => value,
|
|
2000
|
-
onChange: (val) =>
|
|
2001
|
-
setValue(val);
|
|
2002
|
-
props.input.set(val);
|
|
2003
|
-
}
|
|
3237
|
+
onChange: (val) => setValue(val)
|
|
2004
3238
|
})
|
|
2005
3239
|
})
|
|
2006
3240
|
});
|
|
2007
3241
|
}
|
|
2008
3242
|
return /* @__PURE__ */ jsx(NumberInput, {
|
|
2009
3243
|
...inputProps,
|
|
2010
|
-
ref,
|
|
2011
3244
|
id,
|
|
2012
3245
|
leftSection: icon,
|
|
2013
|
-
...inputPropsWithoutType,
|
|
2014
3246
|
...props.numberInputProps,
|
|
2015
3247
|
value: value ?? "",
|
|
2016
3248
|
onChange: (val) => {
|
|
2017
|
-
|
|
2018
|
-
setValue(newValue);
|
|
2019
|
-
props.input.set(newValue);
|
|
3249
|
+
setValue(val !== null ? Number(val) : void 0);
|
|
2020
3250
|
}
|
|
2021
3251
|
});
|
|
2022
3252
|
};
|
|
@@ -2099,92 +3329,9 @@ const ControlObject = (props) => {
|
|
|
2099
3329
|
};
|
|
2100
3330
|
|
|
2101
3331
|
//#endregion
|
|
2102
|
-
//#region ../../src/core/form/components/
|
|
2103
|
-
|
|
2104
|
-
|
|
2105
|
-
* Generates query strings for parseQueryString syntax.
|
|
2106
|
-
*/
|
|
2107
|
-
const ControlQueryBuilder = ({ schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps }) => {
|
|
2108
|
-
const [helpOpened, setHelpOpened] = useState(false);
|
|
2109
|
-
const [textValue, setTextValue] = useState(value);
|
|
2110
|
-
const inputRef = useRef(null);
|
|
2111
|
-
const fields = schema ? extractSchemaFields(schema) : [];
|
|
2112
|
-
const [error, setError] = useState(null);
|
|
2113
|
-
const isValid = (value) => {
|
|
2114
|
-
try {
|
|
2115
|
-
parseQueryString(value.trim());
|
|
2116
|
-
} catch (e) {
|
|
2117
|
-
setError(e.message);
|
|
2118
|
-
return false;
|
|
2119
|
-
}
|
|
2120
|
-
setError(null);
|
|
2121
|
-
return true;
|
|
2122
|
-
};
|
|
2123
|
-
const handleTextChange = (newValue) => {
|
|
2124
|
-
setTextValue(newValue);
|
|
2125
|
-
if (isValid(newValue)) onChange?.(newValue);
|
|
2126
|
-
};
|
|
2127
|
-
const handleClear = () => {
|
|
2128
|
-
setTextValue("");
|
|
2129
|
-
onChange?.("");
|
|
2130
|
-
isValid("");
|
|
2131
|
-
};
|
|
2132
|
-
const handleInsert = (text) => {
|
|
2133
|
-
const newValue = textValue ? `${textValue}${text} ` : `${text} `;
|
|
2134
|
-
setTextValue(newValue);
|
|
2135
|
-
if (isValid(newValue)) onChange?.(newValue);
|
|
2136
|
-
setTimeout(() => {
|
|
2137
|
-
inputRef.current?.focus();
|
|
2138
|
-
const length = inputRef.current?.value.length || 0;
|
|
2139
|
-
inputRef.current?.setSelectionRange(length, length);
|
|
2140
|
-
}, 0);
|
|
2141
|
-
};
|
|
2142
|
-
useEvents({ "form:change": (event) => {
|
|
2143
|
-
if (event.id === inputRef.current?.form?.id) {
|
|
2144
|
-
if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
|
|
2145
|
-
}
|
|
2146
|
-
} }, []);
|
|
2147
|
-
return /* @__PURE__ */ jsxs(Popover, {
|
|
2148
|
-
width: 800,
|
|
2149
|
-
position: "bottom-start",
|
|
2150
|
-
shadow: "md",
|
|
2151
|
-
opened: helpOpened,
|
|
2152
|
-
onChange: setHelpOpened,
|
|
2153
|
-
closeOnClickOutside: true,
|
|
2154
|
-
closeOnEscape: true,
|
|
2155
|
-
transitionProps: {
|
|
2156
|
-
transition: "fade-up",
|
|
2157
|
-
duration: 200,
|
|
2158
|
-
timingFunction: "ease"
|
|
2159
|
-
},
|
|
2160
|
-
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
|
|
2161
|
-
ref: inputRef,
|
|
2162
|
-
placeholder,
|
|
2163
|
-
value: textValue,
|
|
2164
|
-
onChange: (e) => handleTextChange(e.currentTarget.value),
|
|
2165
|
-
onFocus: () => setHelpOpened(true),
|
|
2166
|
-
leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
|
|
2167
|
-
rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
|
|
2168
|
-
size: "sm",
|
|
2169
|
-
variant: "subtle",
|
|
2170
|
-
color: "gray",
|
|
2171
|
-
onClick: handleClear,
|
|
2172
|
-
children: /* @__PURE__ */ jsx(IconX, { size: 14 })
|
|
2173
|
-
}),
|
|
2174
|
-
...textInputProps
|
|
2175
|
-
}) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
2176
|
-
bg: "transparent",
|
|
2177
|
-
p: "xs",
|
|
2178
|
-
bd: `1px solid ${ui.colors.border}`,
|
|
2179
|
-
style: { backdropFilter: "blur(20px)" },
|
|
2180
|
-
children: /* @__PURE__ */ jsx(QueryHelp, {
|
|
2181
|
-
fields,
|
|
2182
|
-
onInsert: handleInsert
|
|
2183
|
-
})
|
|
2184
|
-
})]
|
|
2185
|
-
});
|
|
2186
|
-
};
|
|
2187
|
-
function QueryHelp({ fields, onInsert }) {
|
|
3332
|
+
//#region ../../src/core/form/components/ControlQueryBuilderHelp.tsx
|
|
3333
|
+
const ControlQueryBuilderHelp = (props) => {
|
|
3334
|
+
const { fields, onInsert } = props;
|
|
2188
3335
|
return /* @__PURE__ */ jsxs(Flex, {
|
|
2189
3336
|
gap: "md",
|
|
2190
3337
|
align: "flex-start",
|
|
@@ -2347,110 +3494,313 @@ function QueryHelp({ fields, onInsert }) {
|
|
|
2347
3494
|
})
|
|
2348
3495
|
]
|
|
2349
3496
|
});
|
|
2350
|
-
}
|
|
3497
|
+
};
|
|
3498
|
+
|
|
3499
|
+
//#endregion
|
|
3500
|
+
//#region ../../src/core/form/components/ControlQueryBuilder.tsx
|
|
3501
|
+
/**
|
|
3502
|
+
* Query builder with text input and help popover.
|
|
3503
|
+
* Generates query strings for parseQueryString syntax.
|
|
3504
|
+
*/
|
|
3505
|
+
const ControlQueryBuilder = (props) => {
|
|
3506
|
+
const { schema, value = "", onChange, placeholder = "Enter query or click for assistance...", ...textInputProps } = props;
|
|
3507
|
+
const [helpOpened, setHelpOpened] = useState(false);
|
|
3508
|
+
const [textValue, setTextValue] = useState(value);
|
|
3509
|
+
const inputRef = useRef(null);
|
|
3510
|
+
const fields = schema ? extractSchemaFields(schema) : [];
|
|
3511
|
+
const [error, setError] = useState(null);
|
|
3512
|
+
const isValid = (value) => {
|
|
3513
|
+
try {
|
|
3514
|
+
parseQueryString(value.trim());
|
|
3515
|
+
} catch (e) {
|
|
3516
|
+
setError(e.message);
|
|
3517
|
+
return false;
|
|
3518
|
+
}
|
|
3519
|
+
setError(null);
|
|
3520
|
+
return true;
|
|
3521
|
+
};
|
|
3522
|
+
const handleTextChange = (newValue) => {
|
|
3523
|
+
setTextValue(newValue);
|
|
3524
|
+
if (isValid(newValue)) onChange?.(newValue);
|
|
3525
|
+
};
|
|
3526
|
+
const handleClear = () => {
|
|
3527
|
+
setTextValue("");
|
|
3528
|
+
onChange?.("");
|
|
3529
|
+
isValid("");
|
|
3530
|
+
};
|
|
3531
|
+
const handleInsert = (text) => {
|
|
3532
|
+
const newValue = textValue ? `${textValue}${text} ` : `${text} `;
|
|
3533
|
+
setTextValue(newValue);
|
|
3534
|
+
if (isValid(newValue)) onChange?.(newValue);
|
|
3535
|
+
setTimeout(() => {
|
|
3536
|
+
inputRef.current?.focus();
|
|
3537
|
+
const length = inputRef.current?.value.length || 0;
|
|
3538
|
+
inputRef.current?.setSelectionRange(length, length);
|
|
3539
|
+
}, 0);
|
|
3540
|
+
};
|
|
3541
|
+
useEvents({ "form:change": (event) => {
|
|
3542
|
+
if (event.id === inputRef.current?.form?.id) {
|
|
3543
|
+
if (event.path === textInputProps["data-path"]) setTextValue(event.value ?? "");
|
|
3544
|
+
}
|
|
3545
|
+
} }, []);
|
|
3546
|
+
return /* @__PURE__ */ jsxs(Popover, {
|
|
3547
|
+
width: 800,
|
|
3548
|
+
position: "bottom-start",
|
|
3549
|
+
shadow: "md",
|
|
3550
|
+
opened: helpOpened,
|
|
3551
|
+
onChange: setHelpOpened,
|
|
3552
|
+
closeOnClickOutside: true,
|
|
3553
|
+
closeOnEscape: true,
|
|
3554
|
+
transitionProps: {
|
|
3555
|
+
transition: "fade-up",
|
|
3556
|
+
duration: 200,
|
|
3557
|
+
timingFunction: "ease"
|
|
3558
|
+
},
|
|
3559
|
+
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx(TextInput, {
|
|
3560
|
+
ref: inputRef,
|
|
3561
|
+
placeholder,
|
|
3562
|
+
value: textValue,
|
|
3563
|
+
onChange: (e) => handleTextChange(e.currentTarget.value),
|
|
3564
|
+
onFocus: () => setHelpOpened(true),
|
|
3565
|
+
leftSection: error ? /* @__PURE__ */ jsx(IconInfoTriangle, { size: 16 }) : /* @__PURE__ */ jsx(IconFilter, { size: 16 }),
|
|
3566
|
+
rightSection: textValue && /* @__PURE__ */ jsx(ActionIcon, {
|
|
3567
|
+
size: "sm",
|
|
3568
|
+
variant: "subtle",
|
|
3569
|
+
color: "gray",
|
|
3570
|
+
onClick: handleClear,
|
|
3571
|
+
children: /* @__PURE__ */ jsx(IconX, { size: 14 })
|
|
3572
|
+
}),
|
|
3573
|
+
...textInputProps
|
|
3574
|
+
}) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
3575
|
+
bg: "transparent",
|
|
3576
|
+
p: "xs",
|
|
3577
|
+
bd: `1px solid ${ui.colors.border}`,
|
|
3578
|
+
style: { backdropFilter: "blur(20px)" },
|
|
3579
|
+
children: /* @__PURE__ */ jsx(ControlQueryBuilderHelp, {
|
|
3580
|
+
fields,
|
|
3581
|
+
onInsert: handleInsert
|
|
3582
|
+
})
|
|
3583
|
+
})]
|
|
3584
|
+
});
|
|
3585
|
+
};
|
|
2351
3586
|
|
|
2352
3587
|
//#endregion
|
|
2353
3588
|
//#region ../../src/core/form/components/ControlSelect.tsx
|
|
2354
3589
|
/**
|
|
2355
|
-
* ControlSelect component for handling Select, MultiSelect, and TagsInput.
|
|
3590
|
+
* ControlSelect component for handling Select, MultiSelect, Autocomplete, and TagsInput.
|
|
2356
3591
|
*
|
|
2357
3592
|
* Features:
|
|
2358
3593
|
* - Basic Select with enum support
|
|
2359
3594
|
* - MultiSelect for array of enums
|
|
2360
|
-
* -
|
|
2361
|
-
* -
|
|
2362
|
-
* -
|
|
2363
|
-
* -
|
|
3595
|
+
* - Autocomplete for creatable single values
|
|
3596
|
+
* - TagsInput for creatable array values
|
|
3597
|
+
* - Async lazy loading with auto short/long mode detection
|
|
3598
|
+
* - Short mode: client-side filtering with cached data
|
|
3599
|
+
* - Long mode: debounced server search
|
|
2364
3600
|
*
|
|
2365
3601
|
* Automatically detects enum values and array types from schema.
|
|
2366
3602
|
*/
|
|
2367
3603
|
const ControlSelect = (props) => {
|
|
2368
|
-
const
|
|
3604
|
+
const form = useFormState(props.input);
|
|
3605
|
+
const [value, setValue] = useFieldValue(props.input);
|
|
3606
|
+
const { inputProps, id, icon } = parseInput(props, form);
|
|
2369
3607
|
const isArray = props.input.schema && "type" in props.input.schema && props.input.schema.type === "array";
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
const items = props.input.schema.items;
|
|
2373
|
-
if ("enum" in items && Array.isArray(items.enum)) itemsEnum = items.enum;
|
|
2374
|
-
}
|
|
3608
|
+
const isNumeric = props.input.schema && "type" in props.input.schema && (props.input.schema.type === "integer" || props.input.schema.type === "number");
|
|
3609
|
+
const isBoolean = props.input.schema && "type" in props.input.schema && props.input.schema.type === "boolean";
|
|
2375
3610
|
const enumValues = props.input.schema && "enum" in props.input.schema && Array.isArray(props.input.schema.enum) ? props.input.schema.enum : [];
|
|
2376
|
-
const
|
|
3611
|
+
const { data: asyncData, loading, mode, search } = useAsyncLoader(props.loader, props.loaderThreshold ?? 100, props.loaderDebounce ?? 300, props.input.initialValue);
|
|
3612
|
+
const [staticData, setStaticData] = useState([]);
|
|
3613
|
+
const enumKey = JSON.stringify(enumValues);
|
|
2377
3614
|
useEffect(() => {
|
|
2378
|
-
if (!props.input?.props) return;
|
|
2379
|
-
if (
|
|
2380
|
-
|
|
2381
|
-
|
|
3615
|
+
if (!props.input?.props || props.loader) return;
|
|
3616
|
+
if (isBoolean && enumValues.length === 0) setStaticData([{
|
|
3617
|
+
value: "true",
|
|
3618
|
+
label: "True"
|
|
3619
|
+
}, {
|
|
3620
|
+
value: "false",
|
|
3621
|
+
label: "False"
|
|
3622
|
+
}]);
|
|
3623
|
+
else setStaticData(enumValues);
|
|
3624
|
+
}, [
|
|
3625
|
+
props.input,
|
|
3626
|
+
props.loader,
|
|
3627
|
+
enumKey,
|
|
3628
|
+
isBoolean
|
|
3629
|
+
]);
|
|
3630
|
+
const data = props.loader ? asyncData : staticData;
|
|
2382
3631
|
if (!props.input?.props) return null;
|
|
2383
|
-
|
|
2384
|
-
|
|
3632
|
+
/**
|
|
3633
|
+
* Coerce value for numeric schemas — Select values are always strings.
|
|
3634
|
+
*/
|
|
3635
|
+
const coerceValue = (val) => {
|
|
3636
|
+
if (val == null) return val;
|
|
3637
|
+
if (isNumeric) return Number(val);
|
|
3638
|
+
if (isBoolean) return val === "true";
|
|
3639
|
+
return val;
|
|
3640
|
+
};
|
|
3641
|
+
if (props.segmentedProps) {
|
|
3642
|
+
const segmentedControlProps = typeof props.segmentedProps === "object" ? props.segmentedProps : {};
|
|
3643
|
+
const segmentedData = segmentedControlProps.data ?? data.slice(0, 10);
|
|
2385
3644
|
return /* @__PURE__ */ jsx(Input.Wrapper, {
|
|
2386
3645
|
...inputProps,
|
|
2387
|
-
children: /* @__PURE__ */ jsx(Flex, {
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
|
|
2392
|
-
|
|
2393
|
-
|
|
2394
|
-
|
|
2395
|
-
|
|
3646
|
+
children: /* @__PURE__ */ jsx(Flex, {
|
|
3647
|
+
my: "calc(var(--mantine-spacing-xs) / 2)",
|
|
3648
|
+
children: /* @__PURE__ */ jsx(SegmentedControl, {
|
|
3649
|
+
disabled: inputProps.disabled,
|
|
3650
|
+
value: value != null ? String(value) : "",
|
|
3651
|
+
...segmentedControlProps,
|
|
3652
|
+
onChange: (val) => {
|
|
3653
|
+
setValue(coerceValue(val));
|
|
3654
|
+
},
|
|
3655
|
+
data: segmentedData
|
|
3656
|
+
})
|
|
3657
|
+
})
|
|
2396
3658
|
});
|
|
2397
3659
|
}
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
3660
|
+
const sharedProps = {
|
|
3661
|
+
size: props.size,
|
|
3662
|
+
id,
|
|
3663
|
+
leftSection: loading ? /* @__PURE__ */ jsx(Loader, {
|
|
3664
|
+
color: "gray",
|
|
3665
|
+
size: 10
|
|
3666
|
+
}) : icon,
|
|
3667
|
+
data
|
|
3668
|
+
};
|
|
3669
|
+
const selectableProps = {
|
|
3670
|
+
...sharedProps,
|
|
3671
|
+
searchable: true,
|
|
3672
|
+
rightSection: /* @__PURE__ */ jsx("span", {})
|
|
3673
|
+
};
|
|
3674
|
+
const longModeProps = mode === "long" ? {
|
|
3675
|
+
filter: ({ options }) => options,
|
|
3676
|
+
onSearchChange: search.run
|
|
3677
|
+
} : {};
|
|
3678
|
+
if (props.creatable && (isArray || props.tagsInputProps)) {
|
|
3679
|
+
const tagsInputExtraProps = props.tagsInputProps ?? {};
|
|
3680
|
+
return /* @__PURE__ */ jsx(TagsInput, {
|
|
2401
3681
|
...inputProps,
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
3682
|
+
...sharedProps,
|
|
3683
|
+
...longModeProps,
|
|
3684
|
+
value: Array.isArray(value) ? value : [],
|
|
3685
|
+
onChange: (val) => {
|
|
3686
|
+
setValue(val);
|
|
3687
|
+
},
|
|
3688
|
+
...tagsInputExtraProps
|
|
2408
3689
|
});
|
|
2409
3690
|
}
|
|
2410
|
-
if (
|
|
2411
|
-
const
|
|
2412
|
-
return /* @__PURE__ */ jsx(
|
|
3691
|
+
if (props.creatable) {
|
|
3692
|
+
const autocompleteExtraProps = props.autocompleteProps ?? {};
|
|
3693
|
+
return /* @__PURE__ */ jsx(Autocomplete, {
|
|
2413
3694
|
...inputProps,
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
props.input.set(value);
|
|
3695
|
+
...sharedProps,
|
|
3696
|
+
...longModeProps,
|
|
3697
|
+
value: value != null ? String(value) : "",
|
|
3698
|
+
onChange: (val) => {
|
|
3699
|
+
setValue(coerceValue(val));
|
|
2420
3700
|
},
|
|
2421
|
-
...
|
|
3701
|
+
...autocompleteExtraProps
|
|
2422
3702
|
});
|
|
2423
3703
|
}
|
|
2424
|
-
if (isArray
|
|
2425
|
-
const
|
|
2426
|
-
value,
|
|
2427
|
-
label: value
|
|
2428
|
-
})) || [];
|
|
2429
|
-
const multiSelectProps = typeof props.multi === "object" ? props.multi : {};
|
|
3704
|
+
if (isArray || props.multiSelectProps) {
|
|
3705
|
+
const multiSelectExtraProps = typeof props.multiSelectProps === "object" ? props.multiSelectProps : {};
|
|
2430
3706
|
return /* @__PURE__ */ jsx(MultiSelect, {
|
|
2431
3707
|
...inputProps,
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
onChange: (value) => {
|
|
2438
|
-
props.input.set(value);
|
|
3708
|
+
...selectableProps,
|
|
3709
|
+
...longModeProps,
|
|
3710
|
+
value: Array.isArray(value) ? value : [],
|
|
3711
|
+
onChange: (val) => {
|
|
3712
|
+
setValue(val);
|
|
2439
3713
|
},
|
|
2440
|
-
...
|
|
3714
|
+
...multiSelectExtraProps
|
|
2441
3715
|
});
|
|
2442
3716
|
}
|
|
2443
|
-
const
|
|
3717
|
+
const selectExtraProps = typeof props.selectProps === "object" ? props.selectProps : {};
|
|
3718
|
+
if (mode === "static") return /* @__PURE__ */ jsx(Select, {
|
|
3719
|
+
...inputProps,
|
|
3720
|
+
...selectableProps,
|
|
3721
|
+
value: value != null ? String(value) : null,
|
|
3722
|
+
onChange: (val) => {
|
|
3723
|
+
setValue(coerceValue(val));
|
|
3724
|
+
},
|
|
3725
|
+
...selectExtraProps
|
|
3726
|
+
});
|
|
2444
3727
|
return /* @__PURE__ */ jsx(Select, {
|
|
2445
3728
|
...inputProps,
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
3729
|
+
...selectableProps,
|
|
3730
|
+
...longModeProps,
|
|
3731
|
+
value: value != null ? String(value) : null,
|
|
3732
|
+
onChange: (val) => {
|
|
3733
|
+
setValue(coerceValue(val));
|
|
3734
|
+
},
|
|
3735
|
+
...selectExtraProps
|
|
3736
|
+
});
|
|
3737
|
+
};
|
|
3738
|
+
/**
|
|
3739
|
+
* Hook for async select data loading with auto short/long mode detection.
|
|
3740
|
+
*/
|
|
3741
|
+
const useAsyncLoader = (loader, threshold, debounceMs, defaultValue) => {
|
|
3742
|
+
const [data, setData] = useState([]);
|
|
3743
|
+
const [loading, setLoading] = useState(false);
|
|
3744
|
+
const [mode, setMode] = useState("static");
|
|
3745
|
+
const cache = useRef(/* @__PURE__ */ new Map());
|
|
3746
|
+
useAction({
|
|
3747
|
+
name: "select:loader:init",
|
|
3748
|
+
runOnInit: true,
|
|
3749
|
+
handler: async () => {
|
|
3750
|
+
if (!loader) {
|
|
3751
|
+
setMode("static");
|
|
3752
|
+
return;
|
|
3753
|
+
}
|
|
3754
|
+
setLoading(true);
|
|
3755
|
+
try {
|
|
3756
|
+
const result = await loader("");
|
|
3757
|
+
const isShort = result.length <= threshold;
|
|
3758
|
+
setMode(isShort ? "short" : "long");
|
|
3759
|
+
cache.current.set("", result);
|
|
3760
|
+
setData(result);
|
|
3761
|
+
if (!isShort && defaultValue != null && String(defaultValue) !== "") {
|
|
3762
|
+
const resolved = await loader("", [String(defaultValue)]);
|
|
3763
|
+
if (resolved.length > 0) setData((prev) => {
|
|
3764
|
+
const existing = new Set(prev.map((d) => typeof d === "string" ? d : d.value));
|
|
3765
|
+
const newItems = resolved.filter((r) => {
|
|
3766
|
+
const val = typeof r === "string" ? r : r.value;
|
|
3767
|
+
return !existing.has(val);
|
|
3768
|
+
});
|
|
3769
|
+
return [...prev, ...newItems];
|
|
3770
|
+
});
|
|
3771
|
+
}
|
|
3772
|
+
} finally {
|
|
3773
|
+
setLoading(false);
|
|
3774
|
+
}
|
|
3775
|
+
}
|
|
3776
|
+
}, [loader, threshold]);
|
|
3777
|
+
return {
|
|
2450
3778
|
data,
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
3779
|
+
loading,
|
|
3780
|
+
mode,
|
|
3781
|
+
search: useAction({
|
|
3782
|
+
debounce: debounceMs,
|
|
3783
|
+
handler: async (text) => {
|
|
3784
|
+
if (!loader || mode !== "long") return;
|
|
3785
|
+
if (cache.current.has(text)) {
|
|
3786
|
+
setData(cache.current.get(text));
|
|
3787
|
+
return;
|
|
3788
|
+
}
|
|
3789
|
+
setLoading(true);
|
|
3790
|
+
try {
|
|
3791
|
+
const result = await loader(text);
|
|
3792
|
+
cache.current.set(text, result);
|
|
3793
|
+
setData(result);
|
|
3794
|
+
} finally {
|
|
3795
|
+
setLoading(false);
|
|
3796
|
+
}
|
|
3797
|
+
}
|
|
3798
|
+
}, [
|
|
3799
|
+
loader,
|
|
3800
|
+
mode,
|
|
3801
|
+
debounceMs
|
|
3802
|
+
])
|
|
3803
|
+
};
|
|
2454
3804
|
};
|
|
2455
3805
|
|
|
2456
3806
|
//#endregion
|
|
@@ -2481,6 +3831,7 @@ const ControlSelect = (props) => {
|
|
|
2481
3831
|
*/
|
|
2482
3832
|
const Control = (_props) => {
|
|
2483
3833
|
const form = useFormState(_props.input, ["error"]);
|
|
3834
|
+
const [value, setValue] = useFieldValue(_props.input);
|
|
2484
3835
|
if (!_props.input?.props) return null;
|
|
2485
3836
|
const { inputProps, id, icon, format, schema } = parseInput(_props, form);
|
|
2486
3837
|
const props = {
|
|
@@ -2488,12 +3839,11 @@ const Control = (_props) => {
|
|
|
2488
3839
|
...schema.$control
|
|
2489
3840
|
};
|
|
2490
3841
|
if (props.query) return /* @__PURE__ */ jsx(ControlQueryBuilder, {
|
|
2491
|
-
...props.input.props,
|
|
2492
3842
|
...inputProps,
|
|
2493
3843
|
schema: props.query,
|
|
2494
|
-
value
|
|
2495
|
-
onChange: (
|
|
2496
|
-
|
|
3844
|
+
value,
|
|
3845
|
+
onChange: (val) => {
|
|
3846
|
+
setValue(val);
|
|
2497
3847
|
}
|
|
2498
3848
|
});
|
|
2499
3849
|
if (props.custom) {
|
|
@@ -2504,9 +3854,9 @@ const Control = (_props) => {
|
|
|
2504
3854
|
flex: 1,
|
|
2505
3855
|
mt: "calc(var(--mantine-spacing-xs) / 2)",
|
|
2506
3856
|
children: /* @__PURE__ */ jsx(Custom, {
|
|
2507
|
-
|
|
2508
|
-
onChange: (
|
|
2509
|
-
|
|
3857
|
+
value,
|
|
3858
|
+
onChange: (val) => {
|
|
3859
|
+
setValue(val);
|
|
2510
3860
|
}
|
|
2511
3861
|
})
|
|
2512
3862
|
})
|
|
@@ -2517,7 +3867,7 @@ const Control = (_props) => {
|
|
|
2517
3867
|
const controlObjectProps = typeof props.object === "object" ? props.object : {};
|
|
2518
3868
|
return /* @__PURE__ */ jsx(ControlObject, {
|
|
2519
3869
|
input: props.input,
|
|
2520
|
-
|
|
3870
|
+
label: props.label,
|
|
2521
3871
|
description: props.description,
|
|
2522
3872
|
...controlObjectProps
|
|
2523
3873
|
});
|
|
@@ -2528,18 +3878,18 @@ const Control = (_props) => {
|
|
|
2528
3878
|
const controlArrayProps = typeof props.array === "object" ? props.array : {};
|
|
2529
3879
|
return /* @__PURE__ */ jsx(ControlArray, {
|
|
2530
3880
|
input: props.input,
|
|
2531
|
-
|
|
3881
|
+
label: props.label,
|
|
2532
3882
|
description: props.description,
|
|
2533
3883
|
...controlArrayProps
|
|
2534
3884
|
});
|
|
2535
3885
|
}
|
|
2536
|
-
if (props.number || props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
|
|
3886
|
+
if (props.number || !props.select && props.input.schema && "type" in props.input.schema && (props.input.schema.type === "number" || props.input.schema.type === "integer")) {
|
|
2537
3887
|
const controlNumberProps = typeof props.number === "object" ? props.number : {};
|
|
2538
3888
|
if (props.slider) controlNumberProps.sliderProps ??= {};
|
|
2539
3889
|
return /* @__PURE__ */ jsx(ControlNumber, {
|
|
2540
3890
|
size: props.size,
|
|
2541
3891
|
input: props.input,
|
|
2542
|
-
|
|
3892
|
+
label: props.label,
|
|
2543
3893
|
description: props.description,
|
|
2544
3894
|
icon,
|
|
2545
3895
|
...controlNumberProps
|
|
@@ -2552,9 +3902,7 @@ const Control = (_props) => {
|
|
|
2552
3902
|
size: props.size,
|
|
2553
3903
|
id,
|
|
2554
3904
|
leftSection: icon,
|
|
2555
|
-
onChange: (file) =>
|
|
2556
|
-
props.input.set(file);
|
|
2557
|
-
},
|
|
3905
|
+
onChange: (file) => setValue(file),
|
|
2558
3906
|
...fileInputProps
|
|
2559
3907
|
});
|
|
2560
3908
|
}
|
|
@@ -2565,17 +3913,18 @@ const Control = (_props) => {
|
|
|
2565
3913
|
size: props.size,
|
|
2566
3914
|
id,
|
|
2567
3915
|
leftSection: icon,
|
|
2568
|
-
|
|
3916
|
+
value: value ?? "",
|
|
3917
|
+
onChange: (val) => setValue(val),
|
|
2569
3918
|
...colorInputProps
|
|
2570
3919
|
});
|
|
2571
3920
|
}
|
|
2572
3921
|
if (props.input.schema && "enum" in props.input.schema && props.input.schema.enum || isArray && !isArrayOfObjects || props.select) {
|
|
2573
3922
|
const opts = typeof props.select === "object" ? props.select : {};
|
|
2574
|
-
if (props.segmented) opts.
|
|
3923
|
+
if (props.segmented) opts.segmentedProps ??= {};
|
|
2575
3924
|
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
2576
3925
|
size: props.size,
|
|
2577
3926
|
input: props.input,
|
|
2578
|
-
|
|
3927
|
+
label: props.label,
|
|
2579
3928
|
description: props.description,
|
|
2580
3929
|
icon,
|
|
2581
3930
|
...opts
|
|
@@ -2589,16 +3938,16 @@ const Control = (_props) => {
|
|
|
2589
3938
|
size: props.size,
|
|
2590
3939
|
id,
|
|
2591
3940
|
color: "blue",
|
|
2592
|
-
|
|
3941
|
+
checked: Boolean(value),
|
|
2593
3942
|
onChange: (event) => {
|
|
2594
|
-
|
|
3943
|
+
setValue(event.currentTarget.checked);
|
|
2595
3944
|
},
|
|
2596
3945
|
...switchProps
|
|
2597
3946
|
});
|
|
2598
3947
|
}
|
|
2599
3948
|
const opts = {
|
|
2600
3949
|
input: props.input,
|
|
2601
|
-
|
|
3950
|
+
selectProps: { data: [{
|
|
2602
3951
|
value: "true",
|
|
2603
3952
|
label: "Yes"
|
|
2604
3953
|
}, {
|
|
@@ -2608,7 +3957,7 @@ const Control = (_props) => {
|
|
|
2608
3957
|
};
|
|
2609
3958
|
return /* @__PURE__ */ jsx(ControlSelect, {
|
|
2610
3959
|
size: props.size,
|
|
2611
|
-
|
|
3960
|
+
label: props.label,
|
|
2612
3961
|
description: props.description,
|
|
2613
3962
|
icon,
|
|
2614
3963
|
...opts
|
|
@@ -2621,7 +3970,8 @@ const Control = (_props) => {
|
|
|
2621
3970
|
size: props.size,
|
|
2622
3971
|
id,
|
|
2623
3972
|
leftSection: icon,
|
|
2624
|
-
|
|
3973
|
+
value: value ?? "",
|
|
3974
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
2625
3975
|
...passwordInputProps
|
|
2626
3976
|
});
|
|
2627
3977
|
}
|
|
@@ -2632,14 +3982,15 @@ const Control = (_props) => {
|
|
|
2632
3982
|
size: props.size,
|
|
2633
3983
|
id,
|
|
2634
3984
|
leftSection: icon,
|
|
2635
|
-
|
|
3985
|
+
value: value ?? "",
|
|
3986
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
2636
3987
|
...textAreaProps
|
|
2637
3988
|
});
|
|
2638
3989
|
}
|
|
2639
3990
|
if (props.date || props.datetime || props.time || format === "date" || format === "date-time" || format === "time") return /* @__PURE__ */ jsx(ControlDate, {
|
|
2640
3991
|
size: props.size,
|
|
2641
3992
|
input: props.input,
|
|
2642
|
-
|
|
3993
|
+
label: props.label,
|
|
2643
3994
|
description: props.description,
|
|
2644
3995
|
icon,
|
|
2645
3996
|
date: props.date,
|
|
@@ -2654,7 +4005,7 @@ const Control = (_props) => {
|
|
|
2654
4005
|
case "uri": return "url";
|
|
2655
4006
|
case "tel":
|
|
2656
4007
|
case "phone": return "tel";
|
|
2657
|
-
default: return;
|
|
4008
|
+
default: return props.input.props.type ?? "text";
|
|
2658
4009
|
}
|
|
2659
4010
|
};
|
|
2660
4011
|
return /* @__PURE__ */ jsx(TextInput, {
|
|
@@ -2663,14 +4014,9 @@ const Control = (_props) => {
|
|
|
2663
4014
|
id,
|
|
2664
4015
|
leftSection: icon,
|
|
2665
4016
|
type: getInputType(),
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
"label",
|
|
2670
|
-
"input",
|
|
2671
|
-
"description",
|
|
2672
|
-
"error"
|
|
2673
|
-
]
|
|
4017
|
+
value: value ?? "",
|
|
4018
|
+
onChange: (ev) => setValue(ev.target.value),
|
|
4019
|
+
...textInputProps
|
|
2674
4020
|
});
|
|
2675
4021
|
};
|
|
2676
4022
|
|
|
@@ -2719,6 +4065,7 @@ const Control = (_props) => {
|
|
|
2719
4065
|
*/
|
|
2720
4066
|
const TypeForm = (props) => {
|
|
2721
4067
|
const { form, columns = 3, children, controlProps, fieldControlProps, skipFormElement = false, skipSubmitButton = false, submitButtonProps, fill = true, size } = props;
|
|
4068
|
+
const { dirty } = useFormState(form, ["dirty"]);
|
|
2722
4069
|
const schema = props.schema || form.options.schema;
|
|
2723
4070
|
if (!schema?.properties) return null;
|
|
2724
4071
|
const supportedFields = Object.keys(schema.properties);
|
|
@@ -2781,10 +4128,12 @@ const TypeForm = (props) => {
|
|
|
2781
4128
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
2782
4129
|
variant: "subtle",
|
|
2783
4130
|
type: "reset",
|
|
4131
|
+
disabled: !dirty,
|
|
2784
4132
|
children: "Reset"
|
|
2785
4133
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
2786
4134
|
intent: "primary",
|
|
2787
4135
|
form,
|
|
4136
|
+
disabled: !dirty,
|
|
2788
4137
|
...submitButtonProps,
|
|
2789
4138
|
children: submitButtonProps?.children ?? "Submit"
|
|
2790
4139
|
})]
|
|
@@ -2804,33 +4153,27 @@ const TypeForm = (props) => {
|
|
|
2804
4153
|
};
|
|
2805
4154
|
|
|
2806
4155
|
//#endregion
|
|
2807
|
-
//#region ../../src/core/
|
|
2808
|
-
const
|
|
2809
|
-
|
|
2810
|
-
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
* const confirmed = await dialog.confirm({ title: "Confirm", message: "Are you sure?" });
|
|
2825
|
-
* const input = await dialog.prompt({ title: "Input", message: "Enter your name:" });
|
|
2826
|
-
* ```
|
|
2827
|
-
*/
|
|
2828
|
-
const useDialog = () => {
|
|
2829
|
-
return useInject(DialogService);
|
|
4156
|
+
//#region ../../src/core/json/components/JsonViewerCopyButton.tsx
|
|
4157
|
+
const JsonViewerCopyButton = (props) => {
|
|
4158
|
+
const [copied, setCopied] = useState(false);
|
|
4159
|
+
const handleCopy = useCallback((e) => {
|
|
4160
|
+
e.stopPropagation();
|
|
4161
|
+
navigator.clipboard.writeText(props.value);
|
|
4162
|
+
setCopied(true);
|
|
4163
|
+
setTimeout(() => setCopied(false), 1500);
|
|
4164
|
+
}, [props.value]);
|
|
4165
|
+
return /* @__PURE__ */ jsx(ActionIcon, {
|
|
4166
|
+
size: props.iconSize + 4,
|
|
4167
|
+
variant: "transparent",
|
|
4168
|
+
c: copied ? "green" : "dimmed",
|
|
4169
|
+
onClick: handleCopy,
|
|
4170
|
+
className: "alepha-json-viewer-copy",
|
|
4171
|
+
children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: props.iconSize }) : /* @__PURE__ */ jsx(IconCopy, { size: props.iconSize })
|
|
4172
|
+
});
|
|
2830
4173
|
};
|
|
2831
4174
|
|
|
2832
4175
|
//#endregion
|
|
2833
|
-
//#region ../../src/core/json/components/
|
|
4176
|
+
//#region ../../src/core/json/components/JsonViewerShared.ts
|
|
2834
4177
|
const SIZE_CONFIG = {
|
|
2835
4178
|
xs: {
|
|
2836
4179
|
icon: 14,
|
|
@@ -2879,77 +4222,21 @@ const getValueType = (val) => {
|
|
|
2879
4222
|
if (Array.isArray(val)) return "array";
|
|
2880
4223
|
return typeof val;
|
|
2881
4224
|
};
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
|
|
2887
|
-
label: key ?? "",
|
|
2888
|
-
nodeValue: data,
|
|
2889
|
-
nodeKey: key,
|
|
2890
|
-
path: currentPath,
|
|
2891
|
-
isArrayItem
|
|
2892
|
-
};
|
|
2893
|
-
const type = getValueType(data);
|
|
2894
|
-
if (type === "object" || type === "array") {
|
|
2895
|
-
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);
|
|
2896
|
-
return {
|
|
2897
|
-
value: nodeId,
|
|
2898
|
-
label: key ?? "",
|
|
2899
|
-
nodeValue: data,
|
|
2900
|
-
nodeKey: key,
|
|
2901
|
-
path: currentPath,
|
|
2902
|
-
isArrayItem,
|
|
2903
|
-
children: children.length > 0 ? children : void 0
|
|
2904
|
-
};
|
|
2905
|
-
}
|
|
2906
|
-
return {
|
|
2907
|
-
value: nodeId,
|
|
2908
|
-
label: key ?? "",
|
|
2909
|
-
nodeValue: data,
|
|
2910
|
-
nodeKey: key,
|
|
2911
|
-
path: currentPath,
|
|
2912
|
-
isArrayItem
|
|
2913
|
-
};
|
|
2914
|
-
}
|
|
2915
|
-
function getExpandedIds(nodes, targetDepth, currentDepth = 0) {
|
|
2916
|
-
if (currentDepth >= targetDepth) return [];
|
|
2917
|
-
const ids = [];
|
|
2918
|
-
for (const node of nodes) if (node.children) {
|
|
2919
|
-
ids.push(node.value);
|
|
2920
|
-
ids.push(...getExpandedIds(node.children, targetDepth, currentDepth + 1));
|
|
2921
|
-
}
|
|
2922
|
-
return ids;
|
|
2923
|
-
}
|
|
2924
|
-
const CopyButton = ({ value, iconSize }) => {
|
|
2925
|
-
const [copied, setCopied] = useState(false);
|
|
2926
|
-
const handleCopy = useCallback((e) => {
|
|
2927
|
-
e.stopPropagation();
|
|
2928
|
-
navigator.clipboard.writeText(value);
|
|
2929
|
-
setCopied(true);
|
|
2930
|
-
setTimeout(() => setCopied(false), 1500);
|
|
2931
|
-
}, [value]);
|
|
2932
|
-
return /* @__PURE__ */ jsx(ActionIcon, {
|
|
2933
|
-
size: iconSize + 4,
|
|
2934
|
-
variant: "transparent",
|
|
2935
|
-
c: copied ? "green" : "dimmed",
|
|
2936
|
-
onClick: handleCopy,
|
|
2937
|
-
className: "alepha-json-viewer-copy",
|
|
2938
|
-
children: copied ? /* @__PURE__ */ jsx(IconCheck, { size: iconSize }) : /* @__PURE__ */ jsx(IconCopy, { size: iconSize })
|
|
2939
|
-
});
|
|
2940
|
-
};
|
|
2941
|
-
const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, showQuotes, showCopyButton, renderValue }) => {
|
|
2942
|
-
const { nodeValue, nodeKey, path, isArrayItem, isRoot } = node;
|
|
4225
|
+
|
|
4226
|
+
//#endregion
|
|
4227
|
+
//#region ../../src/core/json/components/JsonViewerRowNode.tsx
|
|
4228
|
+
const JsonViewerRowNode = (props) => {
|
|
4229
|
+
const { nodeValue, nodeKey, path, isArrayItem } = props.node;
|
|
2943
4230
|
const type = getValueType(nodeValue);
|
|
2944
4231
|
const isExpandable = type === "object" || type === "array";
|
|
2945
4232
|
const getPreview = () => {
|
|
2946
4233
|
if (!isExpandable) return null;
|
|
2947
4234
|
const count = (type === "array" ? nodeValue : Object.keys(nodeValue)).length;
|
|
2948
4235
|
const label = type === "array" ? "item" : "key";
|
|
2949
|
-
if (!expanded) return /* @__PURE__ */ jsx(Text, {
|
|
4236
|
+
if (!props.expanded) return /* @__PURE__ */ jsx(Text, {
|
|
2950
4237
|
fs: "italic",
|
|
2951
4238
|
component: "span",
|
|
2952
|
-
size,
|
|
4239
|
+
size: props.size,
|
|
2953
4240
|
style: STYLES.preview,
|
|
2954
4241
|
children: count === 0 ? type === "array" ? "[]" : "{}" : type === "array" ? `[ ${count} ${count === 1 ? label : `${label}s`} ]` : `{ ${count} ${count === 1 ? label : `${label}s`} }`
|
|
2955
4242
|
});
|
|
@@ -2959,25 +4246,25 @@ const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, show
|
|
|
2959
4246
|
return /* @__PURE__ */ jsxs(Flex, {
|
|
2960
4247
|
gap: 6,
|
|
2961
4248
|
wrap: "nowrap",
|
|
2962
|
-
...elementProps,
|
|
2963
|
-
className: `alepha-json-viewer-row ${elementProps.className || ""}`,
|
|
4249
|
+
...props.elementProps,
|
|
4250
|
+
className: `alepha-json-viewer-row ${props.elementProps.className || ""}`,
|
|
2964
4251
|
children: [
|
|
2965
|
-
hasChildren ? expanded ? /* @__PURE__ */ jsx(IconChevronDown, {
|
|
2966
|
-
size: config.icon,
|
|
4252
|
+
props.hasChildren ? props.expanded ? /* @__PURE__ */ jsx(IconChevronDown, {
|
|
4253
|
+
size: props.config.icon,
|
|
2967
4254
|
style: STYLES.chevron
|
|
2968
4255
|
}) : /* @__PURE__ */ jsx(IconChevronRight, {
|
|
2969
|
-
size: config.icon,
|
|
4256
|
+
size: props.config.icon,
|
|
2970
4257
|
style: STYLES.chevron
|
|
2971
4258
|
}) : /* @__PURE__ */ jsx("span", { style: {
|
|
2972
|
-
width: config.icon,
|
|
4259
|
+
width: props.config.icon,
|
|
2973
4260
|
flexShrink: 0
|
|
2974
4261
|
} }),
|
|
2975
4262
|
nodeKey !== void 0 && !isArrayItem && /* @__PURE__ */ jsxs(Text, {
|
|
2976
4263
|
component: "span",
|
|
2977
|
-
size,
|
|
4264
|
+
size: props.size,
|
|
2978
4265
|
children: [/* @__PURE__ */ jsx("span", {
|
|
2979
4266
|
style: STYLES.key,
|
|
2980
|
-
children: showQuotes ? `"${nodeKey}"` : nodeKey
|
|
4267
|
+
children: props.showQuotes ? `"${nodeKey}"` : nodeKey
|
|
2981
4268
|
}), /* @__PURE__ */ jsx("span", {
|
|
2982
4269
|
style: STYLES.colon,
|
|
2983
4270
|
children: ":"
|
|
@@ -2985,7 +4272,7 @@ const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, show
|
|
|
2985
4272
|
}),
|
|
2986
4273
|
nodeKey !== void 0 && isArrayItem && /* @__PURE__ */ jsxs(Text, {
|
|
2987
4274
|
component: "span",
|
|
2988
|
-
size,
|
|
4275
|
+
size: props.size,
|
|
2989
4276
|
children: [/* @__PURE__ */ jsx("span", {
|
|
2990
4277
|
style: STYLES.key,
|
|
2991
4278
|
children: nodeKey
|
|
@@ -2994,25 +4281,29 @@ const RowNode = ({ node, expanded, hasChildren, elementProps, size, config, show
|
|
|
2994
4281
|
children: ":"
|
|
2995
4282
|
})]
|
|
2996
4283
|
}),
|
|
2997
|
-
hasChildren ? getPreview() : isExpandable ? type === "array" ? /* @__PURE__ */ jsx(Text, {
|
|
4284
|
+
props.hasChildren ? getPreview() : isExpandable ? type === "array" ? /* @__PURE__ */ jsx(Text, {
|
|
2998
4285
|
component: "span",
|
|
2999
|
-
size,
|
|
4286
|
+
size: props.size,
|
|
3000
4287
|
style: STYLES.preview,
|
|
3001
4288
|
children: "[]"
|
|
3002
4289
|
}) : /* @__PURE__ */ jsx(Text, {
|
|
3003
4290
|
component: "span",
|
|
3004
|
-
size,
|
|
4291
|
+
size: props.size,
|
|
3005
4292
|
style: STYLES.preview,
|
|
3006
4293
|
children: "{}"
|
|
3007
|
-
}) : renderValue(nodeValue, nodeKey, path),
|
|
3008
|
-
showCopyButton && /* @__PURE__ */ jsx(
|
|
4294
|
+
}) : props.renderValue(nodeValue, nodeKey, path),
|
|
4295
|
+
props.showCopyButton && /* @__PURE__ */ jsx(JsonViewerCopyButton, {
|
|
3009
4296
|
value: getCopyValue(),
|
|
3010
|
-
iconSize: config.icon
|
|
4297
|
+
iconSize: props.config.icon
|
|
3011
4298
|
})
|
|
3012
4299
|
]
|
|
3013
4300
|
});
|
|
3014
4301
|
};
|
|
3015
|
-
|
|
4302
|
+
|
|
4303
|
+
//#endregion
|
|
4304
|
+
//#region ../../src/core/json/components/JsonViewer.tsx
|
|
4305
|
+
const JsonViewer = (props) => {
|
|
4306
|
+
const { data, defaultExpandedDepth = 2, maxDepth = 10, size = "sm", showQuotes = false, showCopyButton = true, formatValue } = props;
|
|
3016
4307
|
const config = SIZE_CONFIG[size] || SIZE_CONFIG.sm;
|
|
3017
4308
|
const treeData = useMemo(() => {
|
|
3018
4309
|
const type = getValueType(data);
|
|
@@ -3092,7 +4383,7 @@ const JsonViewer = ({ data, defaultExpandedDepth = 2, maxDepth = 10, size = "sm"
|
|
|
3092
4383
|
size
|
|
3093
4384
|
]);
|
|
3094
4385
|
const renderNode = useCallback(({ node, expanded, hasChildren, elementProps }) => {
|
|
3095
|
-
return /* @__PURE__ */ jsx(
|
|
4386
|
+
return /* @__PURE__ */ jsx(JsonViewerRowNode, {
|
|
3096
4387
|
node,
|
|
3097
4388
|
expanded,
|
|
3098
4389
|
hasChildren,
|
|
@@ -3124,6 +4415,54 @@ const JsonViewer = ({ data, defaultExpandedDepth = 2, maxDepth = 10, size = "sm"
|
|
|
3124
4415
|
styles: { root: STYLES.root }
|
|
3125
4416
|
});
|
|
3126
4417
|
};
|
|
4418
|
+
/**
|
|
4419
|
+
* Convert JSON to tree data structure.
|
|
4420
|
+
*/
|
|
4421
|
+
const buildTreeNodes = (data, path = [], key, isArrayItem = false, maxDepth = 10) => {
|
|
4422
|
+
const currentPath = key !== void 0 ? [...path, key] : path;
|
|
4423
|
+
const nodeId = currentPath.length > 0 ? currentPath.join(".") : "root";
|
|
4424
|
+
if (currentPath.length > maxDepth) return {
|
|
4425
|
+
value: nodeId,
|
|
4426
|
+
label: key ?? "",
|
|
4427
|
+
nodeValue: data,
|
|
4428
|
+
nodeKey: key,
|
|
4429
|
+
path: currentPath,
|
|
4430
|
+
isArrayItem
|
|
4431
|
+
};
|
|
4432
|
+
const type = getValueType(data);
|
|
4433
|
+
if (type === "object" || type === "array") {
|
|
4434
|
+
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);
|
|
4435
|
+
return {
|
|
4436
|
+
value: nodeId,
|
|
4437
|
+
label: key ?? "",
|
|
4438
|
+
nodeValue: data,
|
|
4439
|
+
nodeKey: key,
|
|
4440
|
+
path: currentPath,
|
|
4441
|
+
isArrayItem,
|
|
4442
|
+
children: children.length > 0 ? children : void 0
|
|
4443
|
+
};
|
|
4444
|
+
}
|
|
4445
|
+
return {
|
|
4446
|
+
value: nodeId,
|
|
4447
|
+
label: key ?? "",
|
|
4448
|
+
nodeValue: data,
|
|
4449
|
+
nodeKey: key,
|
|
4450
|
+
path: currentPath,
|
|
4451
|
+
isArrayItem
|
|
4452
|
+
};
|
|
4453
|
+
};
|
|
4454
|
+
/**
|
|
4455
|
+
* Get all expandable node IDs up to a certain depth.
|
|
4456
|
+
*/
|
|
4457
|
+
const getExpandedIds = (nodes, targetDepth, currentDepth = 0) => {
|
|
4458
|
+
if (currentDepth >= targetDepth) return [];
|
|
4459
|
+
const ids = [];
|
|
4460
|
+
for (const node of nodes) if (node.children) {
|
|
4461
|
+
ids.push(node.value);
|
|
4462
|
+
ids.push(...getExpandedIds(node.children, targetDepth, currentDepth + 1));
|
|
4463
|
+
}
|
|
4464
|
+
return ids;
|
|
4465
|
+
};
|
|
3127
4466
|
|
|
3128
4467
|
//#endregion
|
|
3129
4468
|
//#region ../../src/core/table/interfaces/types.ts
|
|
@@ -3131,7 +4470,8 @@ const DEFAULT_MAX_VISIBLE_COLUMNS = 8;
|
|
|
3131
4470
|
|
|
3132
4471
|
//#endregion
|
|
3133
4472
|
//#region ../../src/core/table/components/DataTableFilters.tsx
|
|
3134
|
-
const DataTableFilters = (
|
|
4473
|
+
const DataTableFilters = (props) => {
|
|
4474
|
+
const { schema, form, typeFormProps, filterVisibility } = props;
|
|
3135
4475
|
const visibleSchema = useMemo(() => {
|
|
3136
4476
|
const visibleKeys = Object.keys(schema.properties).filter((key) => filterVisibility[key] !== false);
|
|
3137
4477
|
if (visibleKeys.length === 0) return null;
|
|
@@ -3142,13 +4482,14 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
3142
4482
|
return t.object(visibleProps);
|
|
3143
4483
|
}, [schema, filterVisibility]);
|
|
3144
4484
|
if (!visibleSchema) return null;
|
|
3145
|
-
return /* @__PURE__ */ jsx(Flex, {
|
|
3146
|
-
|
|
4485
|
+
return /* @__PURE__ */ jsx(Flex$1, {
|
|
4486
|
+
surface: true,
|
|
4487
|
+
flex: 1,
|
|
4488
|
+
mt: -4,
|
|
3147
4489
|
p: "xs",
|
|
3148
|
-
|
|
3149
|
-
|
|
4490
|
+
m: "xs",
|
|
4491
|
+
bdrs: "md",
|
|
3150
4492
|
children: /* @__PURE__ */ jsx(TypeForm, {
|
|
3151
|
-
size: "xs",
|
|
3152
4493
|
...typeFormProps,
|
|
3153
4494
|
skipSubmitButton: true,
|
|
3154
4495
|
fill: true,
|
|
@@ -3159,7 +4500,7 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
3159
4500
|
sm: 2,
|
|
3160
4501
|
md: 3,
|
|
3161
4502
|
lg: 4,
|
|
3162
|
-
xl:
|
|
4503
|
+
xl: 5
|
|
3163
4504
|
}
|
|
3164
4505
|
})
|
|
3165
4506
|
});
|
|
@@ -3167,48 +4508,64 @@ const DataTableFilters = ({ schema, form, typeFormProps, filterVisibility }) =>
|
|
|
3167
4508
|
|
|
3168
4509
|
//#endregion
|
|
3169
4510
|
//#region ../../src/core/table/components/DataTablePagination.tsx
|
|
3170
|
-
const DataTablePagination = ({ page, size, totalPages, onPageChange, onSizeChange }) => {
|
|
3171
|
-
|
|
4511
|
+
const DataTablePagination = ({ page, size, totalPages, totalElements, isFirst, isLast, offset, numberOfElements, onPageChange, onSizeChange }) => {
|
|
4512
|
+
const from = numberOfElements > 0 ? offset + 1 : 0;
|
|
4513
|
+
const to = offset + numberOfElements;
|
|
4514
|
+
const hasTotal = totalPages != null;
|
|
4515
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
3172
4516
|
align: "center",
|
|
3173
|
-
justify: "
|
|
4517
|
+
justify: "space-between",
|
|
3174
4518
|
gap: "md",
|
|
3175
|
-
|
|
4519
|
+
px: "xs",
|
|
4520
|
+
py: 4,
|
|
3176
4521
|
style: { borderTop: "1px solid var(--alepha-border)" },
|
|
3177
|
-
children: [/* @__PURE__ */ jsx(Flex, {
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
}
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3194
|
-
|
|
3195
|
-
|
|
3196
|
-
},
|
|
3197
|
-
{
|
|
3198
|
-
value: "50",
|
|
3199
|
-
label: "50"
|
|
4522
|
+
children: [/* @__PURE__ */ jsx(Flex$1, {
|
|
4523
|
+
align: "center",
|
|
4524
|
+
children: /* @__PURE__ */ jsx(Text$1, {
|
|
4525
|
+
size: "xs",
|
|
4526
|
+
c: "dimmed",
|
|
4527
|
+
children: totalElements != null ? `Showing ${from} - ${to} of ${totalElements}` : `Showing ${from} - ${to}`
|
|
4528
|
+
})
|
|
4529
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
4530
|
+
align: "center",
|
|
4531
|
+
gap: "md",
|
|
4532
|
+
children: [/* @__PURE__ */ jsx(Flex$1, { children: /* @__PURE__ */ jsx(Select, {
|
|
4533
|
+
color: "gray",
|
|
4534
|
+
c: "gray",
|
|
4535
|
+
size: "xs",
|
|
4536
|
+
w: 96,
|
|
4537
|
+
variant: "default",
|
|
4538
|
+
value: size,
|
|
4539
|
+
onChange: (value) => {
|
|
4540
|
+
if (value) onSizeChange(Number(value));
|
|
3200
4541
|
},
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
4542
|
+
data: [
|
|
4543
|
+
{
|
|
4544
|
+
value: "10",
|
|
4545
|
+
label: "10"
|
|
4546
|
+
},
|
|
4547
|
+
{
|
|
4548
|
+
value: "25",
|
|
4549
|
+
label: "25"
|
|
4550
|
+
},
|
|
4551
|
+
{
|
|
4552
|
+
value: "50",
|
|
4553
|
+
label: "50"
|
|
4554
|
+
},
|
|
4555
|
+
{
|
|
4556
|
+
value: "100",
|
|
4557
|
+
label: "100"
|
|
4558
|
+
}
|
|
4559
|
+
]
|
|
4560
|
+
}) }), /* @__PURE__ */ jsx(Flex$1, { children: /* @__PURE__ */ jsx(Pagination, {
|
|
4561
|
+
size: "sm",
|
|
4562
|
+
withEdges: hasTotal,
|
|
4563
|
+
withPages: hasTotal,
|
|
4564
|
+
total: hasTotal ? totalPages : isLast !== false ? page : page + 1,
|
|
4565
|
+
value: page,
|
|
4566
|
+
onChange: onPageChange
|
|
4567
|
+
}) })]
|
|
4568
|
+
})]
|
|
3212
4569
|
});
|
|
3213
4570
|
};
|
|
3214
4571
|
|
|
@@ -3255,7 +4612,7 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3255
4612
|
timingFunction: "ease"
|
|
3256
4613
|
},
|
|
3257
4614
|
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3258
|
-
variant: "
|
|
4615
|
+
variant: "minimal",
|
|
3259
4616
|
icon: IconColumns,
|
|
3260
4617
|
onClick: () => setOpened((o) => !o)
|
|
3261
4618
|
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
@@ -3285,12 +4642,12 @@ const ColumnPicker = ({ columns, visibility, onVisibilityChange }) => {
|
|
|
3285
4642
|
gap: 4,
|
|
3286
4643
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
3287
4644
|
size: "compact-xs",
|
|
3288
|
-
variant: "
|
|
4645
|
+
variant: "minimal",
|
|
3289
4646
|
onClick: handleShowAll,
|
|
3290
4647
|
children: "All"
|
|
3291
4648
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
3292
4649
|
size: "compact-xs",
|
|
3293
|
-
variant: "
|
|
4650
|
+
variant: "minimal",
|
|
3294
4651
|
onClick: handleDefault,
|
|
3295
4652
|
children: "Default"
|
|
3296
4653
|
})]
|
|
@@ -3356,7 +4713,7 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3356
4713
|
timingFunction: "ease"
|
|
3357
4714
|
},
|
|
3358
4715
|
children: [/* @__PURE__ */ jsx(Popover.Target, { children: /* @__PURE__ */ jsx("div", { children: /* @__PURE__ */ jsx(ActionButton, {
|
|
3359
|
-
variant: "
|
|
4716
|
+
variant: "minimal",
|
|
3360
4717
|
icon: IconFilter,
|
|
3361
4718
|
onClick: () => setOpened((o) => !o)
|
|
3362
4719
|
}) }) }), /* @__PURE__ */ jsx(Popover.Dropdown, {
|
|
@@ -3386,12 +4743,12 @@ const FilterPicker = ({ schema, visibility, onVisibilityChange }) => {
|
|
|
3386
4743
|
gap: 4,
|
|
3387
4744
|
children: [/* @__PURE__ */ jsx(ActionButton, {
|
|
3388
4745
|
size: "compact-xs",
|
|
3389
|
-
variant: "
|
|
4746
|
+
variant: "minimal",
|
|
3390
4747
|
onClick: handleShowAll,
|
|
3391
4748
|
children: "All"
|
|
3392
4749
|
}), /* @__PURE__ */ jsx(ActionButton, {
|
|
3393
4750
|
size: "compact-xs",
|
|
3394
|
-
variant: "
|
|
4751
|
+
variant: "minimal",
|
|
3395
4752
|
onClick: handleHideAll,
|
|
3396
4753
|
children: "None"
|
|
3397
4754
|
})]
|
|
@@ -3430,7 +4787,7 @@ const extractText = (node) => {
|
|
|
3430
4787
|
const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility, onColumnVisibilityChange, onFilterVisibilityChange, actions, onRefresh, items, withExport, selectedItems = [], checkboxActions, onClearSelection }) => {
|
|
3431
4788
|
const hasSelection = selectedItems.length > 0;
|
|
3432
4789
|
const exportableColumns = useCallback(() => {
|
|
3433
|
-
return Object.entries(columns).filter(([key
|
|
4790
|
+
return Object.entries(columns).filter(([key]) => columnVisibility[key] !== false);
|
|
3434
4791
|
}, [columns, columnVisibility]);
|
|
3435
4792
|
const buildRows = useCallback(() => {
|
|
3436
4793
|
const cols = exportableColumns();
|
|
@@ -3467,11 +4824,10 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3467
4824
|
};
|
|
3468
4825
|
await action.onClick(ctx);
|
|
3469
4826
|
};
|
|
3470
|
-
return /* @__PURE__ */ jsxs(Flex, {
|
|
4827
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
3471
4828
|
p: "xs",
|
|
3472
|
-
style: { borderBottom: "1px solid var(--alepha-border)" },
|
|
3473
4829
|
children: [
|
|
3474
|
-
/* @__PURE__ */ jsxs(Flex, {
|
|
4830
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
3475
4831
|
gap: 4,
|
|
3476
4832
|
align: "center",
|
|
3477
4833
|
children: [
|
|
@@ -3486,7 +4842,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3486
4842
|
onVisibilityChange: onColumnVisibilityChange
|
|
3487
4843
|
}),
|
|
3488
4844
|
withExport && /* @__PURE__ */ jsx(ActionButton, {
|
|
3489
|
-
variant: "
|
|
4845
|
+
variant: "minimal",
|
|
3490
4846
|
icon: IconDownload,
|
|
3491
4847
|
menu: { items: [{
|
|
3492
4848
|
label: "Export as CSV",
|
|
@@ -3509,7 +4865,7 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3509
4865
|
children: [selectedItems.length, " selected"]
|
|
3510
4866
|
}),
|
|
3511
4867
|
/* @__PURE__ */ jsx(ActionButton, {
|
|
3512
|
-
variant: "
|
|
4868
|
+
variant: "minimal",
|
|
3513
4869
|
size: "compact-sm",
|
|
3514
4870
|
icon: IconX,
|
|
3515
4871
|
onClick: onClearSelection,
|
|
@@ -3526,14 +4882,14 @@ const DataTableToolbar = ({ columns, filters, columnVisibility, filterVisibility
|
|
|
3526
4882
|
] })
|
|
3527
4883
|
]
|
|
3528
4884
|
}),
|
|
3529
|
-
/* @__PURE__ */ jsx(Flex, { flex: 1 }),
|
|
3530
|
-
/* @__PURE__ */ jsxs(Flex, {
|
|
4885
|
+
/* @__PURE__ */ jsx(Flex$1, { flex: 1 }),
|
|
4886
|
+
/* @__PURE__ */ jsxs(Flex$1, {
|
|
3531
4887
|
gap: "xs",
|
|
3532
4888
|
children: [actions?.map((props, index) => !isValidElement(props) ? /* @__PURE__ */ jsx(ActionButton, {
|
|
3533
4889
|
...props,
|
|
3534
4890
|
children: props.label
|
|
3535
4891
|
}, index) : props), /* @__PURE__ */ jsx(ActionButton, {
|
|
3536
|
-
variant: "
|
|
4892
|
+
variant: "minimal",
|
|
3537
4893
|
icon: IconRefresh,
|
|
3538
4894
|
onClick: onRefresh
|
|
3539
4895
|
})]
|
|
@@ -3642,12 +4998,16 @@ const FIT_STYLE = {
|
|
|
3642
4998
|
};
|
|
3643
4999
|
const DataTable = (props) => {
|
|
3644
5000
|
const [items, setItems] = useState(typeof props.items === "function" ? { content: [] } : props.items);
|
|
3645
|
-
const
|
|
5001
|
+
const itemsRef = useRef(items);
|
|
5002
|
+
const [loaded, setLoaded] = useState(typeof props.items !== "function" || !props.submitOnInit);
|
|
5003
|
+
const defaultSize = props.defaultSize || (props.infinityScroll ? 100 : 10);
|
|
3646
5004
|
const [page, setPage] = useState(1);
|
|
3647
5005
|
const [size, setSize] = useState(String(defaultSize));
|
|
3648
5006
|
const [currentPage, setCurrentPage] = useState(0);
|
|
3649
5007
|
const alepha = useInject(Alepha);
|
|
5008
|
+
itemsRef.current = items;
|
|
3650
5009
|
const sentinelRef = useRef(null);
|
|
5010
|
+
const debounceRef = useRef(null);
|
|
3651
5011
|
const [columnVisibility, setColumnVisibility] = useState(() => {
|
|
3652
5012
|
const entries = Object.entries(props.columns);
|
|
3653
5013
|
let visibleCount = 0;
|
|
@@ -3720,13 +5080,14 @@ const DataTable = (props) => {
|
|
|
3720
5080
|
}),
|
|
3721
5081
|
handler: async (values) => {
|
|
3722
5082
|
if (typeof props.items === "function") {
|
|
3723
|
-
const response = await props.items(values, { items:
|
|
5083
|
+
const response = await props.items(values, { items: itemsRef.current.content });
|
|
3724
5084
|
if (props.infinityScroll && values.page > 0) setItems((prev) => ({
|
|
3725
5085
|
...response,
|
|
3726
5086
|
content: [...prev.content, ...response.content]
|
|
3727
5087
|
}));
|
|
3728
5088
|
else setItems(response);
|
|
3729
5089
|
setCurrentPage(values.page);
|
|
5090
|
+
if (!loaded) setLoaded(true);
|
|
3730
5091
|
}
|
|
3731
5092
|
},
|
|
3732
5093
|
onReset: async () => {
|
|
@@ -3746,9 +5107,23 @@ const DataTable = (props) => {
|
|
|
3746
5107
|
return;
|
|
3747
5108
|
}
|
|
3748
5109
|
props.onFilterChange?.(key, value, form);
|
|
5110
|
+
if (props.skipSubmitOnChange) return;
|
|
5111
|
+
form.input.page.set(0);
|
|
5112
|
+
const delay = props.debounce ?? 300;
|
|
5113
|
+
if (delay > 0) {
|
|
5114
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5115
|
+
debounceRef.current = setTimeout(() => {
|
|
5116
|
+
form.submit();
|
|
5117
|
+
}, delay);
|
|
5118
|
+
} else await form.submit();
|
|
3749
5119
|
}
|
|
3750
|
-
}, [
|
|
5120
|
+
}, []);
|
|
3751
5121
|
const dt = useInject(DateTimeProvider);
|
|
5122
|
+
useEffect(() => {
|
|
5123
|
+
return () => {
|
|
5124
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
5125
|
+
};
|
|
5126
|
+
}, []);
|
|
3752
5127
|
useEffect(() => {
|
|
3753
5128
|
if (props.submitOnInit) form.submit();
|
|
3754
5129
|
if (props.submitEvery) {
|
|
@@ -3779,7 +5154,7 @@ const DataTable = (props) => {
|
|
|
3779
5154
|
currentPage,
|
|
3780
5155
|
form
|
|
3781
5156
|
]);
|
|
3782
|
-
const totalColumns = visibleColumns.length + (panelConfig ? 1 : 0) + (props.withCheckbox ? 1 : 0);
|
|
5157
|
+
const totalColumns = visibleColumns.length + (panelConfig ? 1 : 0) + (props.withCheckbox ? 1 : 0) + (props.rowActions ? 1 : 0);
|
|
3783
5158
|
const checkboxHeader = props.withCheckbox ? /* @__PURE__ */ jsx(Table.Th, {
|
|
3784
5159
|
style: { width: 40 },
|
|
3785
5160
|
children: /* @__PURE__ */ jsx(Checkbox, {
|
|
@@ -3802,18 +5177,20 @@ const DataTable = (props) => {
|
|
|
3802
5177
|
userSelect: "none"
|
|
3803
5178
|
} : {}
|
|
3804
5179
|
},
|
|
3805
|
-
children: /* @__PURE__ */ jsxs(Flex, {
|
|
5180
|
+
children: /* @__PURE__ */ jsxs(Flex$1, {
|
|
3806
5181
|
align: "center",
|
|
3807
5182
|
gap: 4,
|
|
3808
|
-
children: [/* @__PURE__ */ jsx(Text, {
|
|
5183
|
+
children: [/* @__PURE__ */ jsx(Text$1, {
|
|
5184
|
+
bold: true,
|
|
5185
|
+
muted: true,
|
|
3809
5186
|
size: "xs",
|
|
3810
5187
|
children: col.label
|
|
3811
|
-
}), col.sortable && /* @__PURE__ */ jsxs(Flex, {
|
|
5188
|
+
}), col.sortable && /* @__PURE__ */ jsxs(Flex$1, {
|
|
3812
5189
|
c: "dimmed",
|
|
3813
5190
|
children: [
|
|
3814
|
-
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.
|
|
3815
|
-
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.
|
|
3816
|
-
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.
|
|
5191
|
+
sortDir === "asc" && /* @__PURE__ */ jsx(IconArrowUp, { size: ui.sizes.icon.xs }),
|
|
5192
|
+
sortDir === "desc" && /* @__PURE__ */ jsx(IconArrowDown, { size: ui.sizes.icon.xs }),
|
|
5193
|
+
sortDir === null && /* @__PURE__ */ jsx(IconArrowsSort, { size: ui.sizes.icon.xs })
|
|
3817
5194
|
]
|
|
3818
5195
|
})]
|
|
3819
5196
|
})
|
|
@@ -3850,7 +5227,7 @@ const DataTable = (props) => {
|
|
|
3850
5227
|
toggleExpand(itemKey);
|
|
3851
5228
|
},
|
|
3852
5229
|
style: { display: "inline-flex" },
|
|
3853
|
-
children: /* @__PURE__ */ jsx(Flex, {
|
|
5230
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
3854
5231
|
c: "dimmed",
|
|
3855
5232
|
align: "center",
|
|
3856
5233
|
justify: "center",
|
|
@@ -3873,32 +5250,49 @@ const DataTable = (props) => {
|
|
|
3873
5250
|
form,
|
|
3874
5251
|
alepha
|
|
3875
5252
|
};
|
|
3876
|
-
|
|
3877
|
-
const rowActions = col.actions(item, ctx).filter((a) => a.visible !== false);
|
|
3878
|
-
return /* @__PURE__ */ jsx(Table.Td, {
|
|
3879
|
-
py: 2,
|
|
3880
|
-
px: 4,
|
|
3881
|
-
style: col.fit ? FIT_STYLE : void 0,
|
|
3882
|
-
onClick: (e) => e.stopPropagation(),
|
|
3883
|
-
children: /* @__PURE__ */ jsx(Flex, {
|
|
3884
|
-
gap: 4,
|
|
3885
|
-
children: rowActions.map(({ visible: _, ...actionProps }, i) => /* @__PURE__ */ jsx(ActionButton, {
|
|
3886
|
-
variant: "subtle",
|
|
3887
|
-
size: "xs",
|
|
3888
|
-
preventDefault: true,
|
|
3889
|
-
h: 20,
|
|
3890
|
-
...actionProps
|
|
3891
|
-
}, i))
|
|
3892
|
-
})
|
|
3893
|
-
}, key);
|
|
3894
|
-
}
|
|
5253
|
+
const content = col.value?.(item, ctx);
|
|
3895
5254
|
return /* @__PURE__ */ jsx(Table.Td, {
|
|
3896
|
-
py: 2,
|
|
3897
|
-
px: 4,
|
|
3898
5255
|
style: col.fit ? FIT_STYLE : void 0,
|
|
3899
|
-
children: col.
|
|
5256
|
+
children: col.action ? /* @__PURE__ */ jsx(ActionButton, {
|
|
5257
|
+
td: "inherit",
|
|
5258
|
+
unstyled: true,
|
|
5259
|
+
...col.action(item),
|
|
5260
|
+
children: content
|
|
5261
|
+
}) : content
|
|
3900
5262
|
}, key);
|
|
3901
|
-
})
|
|
5263
|
+
}),
|
|
5264
|
+
props.rowActions && (() => {
|
|
5265
|
+
const ctx = {
|
|
5266
|
+
index,
|
|
5267
|
+
form,
|
|
5268
|
+
alepha
|
|
5269
|
+
};
|
|
5270
|
+
const actions = props.rowActions(item, ctx).filter((a) => a.visible !== false);
|
|
5271
|
+
if (actions.length === 0) return /* @__PURE__ */ jsx(Table.Td, { style: FIT_STYLE });
|
|
5272
|
+
return /* @__PURE__ */ jsx(Table.Td, {
|
|
5273
|
+
py: 2,
|
|
5274
|
+
px: 4,
|
|
5275
|
+
style: FIT_STYLE,
|
|
5276
|
+
onClick: (e) => e.stopPropagation(),
|
|
5277
|
+
children: /* @__PURE__ */ jsx(ActionButton, {
|
|
5278
|
+
variant: "minimal",
|
|
5279
|
+
size: "xs",
|
|
5280
|
+
icon: IconDotsVertical,
|
|
5281
|
+
menu: { items: actions.map((action) => {
|
|
5282
|
+
const Icon = action.icon;
|
|
5283
|
+
return {
|
|
5284
|
+
label: action.label ?? (typeof action.tooltip === "string" ? action.tooltip : void 0),
|
|
5285
|
+
icon: Icon && isComponentType(Icon) ? /* @__PURE__ */ jsx(Icon, { size: 14 }) : Icon,
|
|
5286
|
+
onClick: action.onClick ? async () => {
|
|
5287
|
+
await action.onClick();
|
|
5288
|
+
if (!action.skipRefresh) await form.submit();
|
|
5289
|
+
} : void 0,
|
|
5290
|
+
color: action.color
|
|
5291
|
+
};
|
|
5292
|
+
}) }
|
|
5293
|
+
})
|
|
5294
|
+
});
|
|
5295
|
+
})()
|
|
3902
5296
|
]
|
|
3903
5297
|
}, itemKey)];
|
|
3904
5298
|
if (panelConfig && showPanel && isExpanded) elements.push(/* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
@@ -3916,13 +5310,19 @@ const DataTable = (props) => {
|
|
|
3916
5310
|
"sort"
|
|
3917
5311
|
]);
|
|
3918
5312
|
}, [props.filters, form.options.schema]);
|
|
3919
|
-
return /* @__PURE__ */ jsxs(Flex, {
|
|
5313
|
+
return /* @__PURE__ */ jsxs(Flex$1, {
|
|
5314
|
+
gap: "xs",
|
|
3920
5315
|
flex: 1,
|
|
3921
5316
|
p: 0,
|
|
3922
|
-
bdrs: "sm",
|
|
3923
5317
|
direction: "column",
|
|
3924
|
-
|
|
3925
|
-
|
|
5318
|
+
style: { overflow: "hidden" },
|
|
5319
|
+
children: [/* @__PURE__ */ jsxs(Flex$1, {
|
|
5320
|
+
rounded: true,
|
|
5321
|
+
bordered: true,
|
|
5322
|
+
elevated: true,
|
|
5323
|
+
shadowed: "xs",
|
|
5324
|
+
col: true,
|
|
5325
|
+
children: [/* @__PURE__ */ jsx(DataTableToolbar, {
|
|
3926
5326
|
columns: props.columns,
|
|
3927
5327
|
filters: props.filters,
|
|
3928
5328
|
columnVisibility,
|
|
@@ -3936,71 +5336,97 @@ const DataTable = (props) => {
|
|
|
3936
5336
|
selectedItems: selection.selectedItems,
|
|
3937
5337
|
checkboxActions: props.checkboxActions,
|
|
3938
5338
|
onClearSelection: selection.clear
|
|
3939
|
-
}),
|
|
3940
|
-
filterSchema && props.filters && /* @__PURE__ */ jsx(DataTableFilters, {
|
|
5339
|
+
}), filterSchema && props.filters && /* @__PURE__ */ jsx(DataTableFilters, {
|
|
3941
5340
|
schema: filterSchema,
|
|
3942
5341
|
form,
|
|
3943
5342
|
typeFormProps: props.typeFormProps,
|
|
3944
5343
|
filterVisibility
|
|
3945
|
-
})
|
|
3946
|
-
|
|
3947
|
-
|
|
3948
|
-
|
|
3949
|
-
|
|
3950
|
-
|
|
3951
|
-
|
|
3952
|
-
|
|
3953
|
-
|
|
3954
|
-
|
|
3955
|
-
|
|
3956
|
-
|
|
3957
|
-
|
|
3958
|
-
|
|
3959
|
-
|
|
3960
|
-
|
|
3961
|
-
|
|
3962
|
-
|
|
3963
|
-
|
|
3964
|
-
|
|
3965
|
-
|
|
3966
|
-
|
|
3967
|
-
|
|
3968
|
-
|
|
3969
|
-
|
|
3970
|
-
|
|
5344
|
+
})]
|
|
5345
|
+
}), /* @__PURE__ */ jsxs(Flex$1, {
|
|
5346
|
+
col: true,
|
|
5347
|
+
rounded: true,
|
|
5348
|
+
bordered: true,
|
|
5349
|
+
elevated: true,
|
|
5350
|
+
shadowed: "xs",
|
|
5351
|
+
flex: 1,
|
|
5352
|
+
style: { minHeight: 0 },
|
|
5353
|
+
children: [
|
|
5354
|
+
/* @__PURE__ */ jsx(Flex$1, {
|
|
5355
|
+
className: "overflow-auto",
|
|
5356
|
+
flex: 1,
|
|
5357
|
+
style: { minHeight: 0 },
|
|
5358
|
+
col: true,
|
|
5359
|
+
children: /* @__PURE__ */ jsxs(Table, {
|
|
5360
|
+
"aria-label": "Data table",
|
|
5361
|
+
withRowBorders: true,
|
|
5362
|
+
highlightOnHover: true,
|
|
5363
|
+
...props.tableProps,
|
|
5364
|
+
children: [/* @__PURE__ */ jsx(Table.Thead, {
|
|
5365
|
+
bdrs: "md",
|
|
5366
|
+
style: {
|
|
5367
|
+
position: "sticky",
|
|
5368
|
+
top: 0,
|
|
5369
|
+
zIndex: 1,
|
|
5370
|
+
backgroundColor: "var(--alepha-elevated)"
|
|
5371
|
+
},
|
|
5372
|
+
children: /* @__PURE__ */ jsxs(Table.Tr, { children: [
|
|
5373
|
+
panelConfig && /* @__PURE__ */ jsx(Table.Th, { style: { width: 36 } }),
|
|
5374
|
+
checkboxHeader,
|
|
5375
|
+
head,
|
|
5376
|
+
props.rowActions && /* @__PURE__ */ jsx(Table.Th, { style: FIT_STYLE })
|
|
5377
|
+
] })
|
|
5378
|
+
}), /* @__PURE__ */ jsx(Table.Tbody, { children: !loaded || form.submitting ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
5379
|
+
colSpan: totalColumns || 1,
|
|
5380
|
+
py: "sm",
|
|
5381
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
5382
|
+
justify: "center",
|
|
5383
|
+
p: "md",
|
|
5384
|
+
children: /* @__PURE__ */ jsx(Loader, {
|
|
5385
|
+
size: "sm",
|
|
5386
|
+
type: "dots"
|
|
5387
|
+
})
|
|
5388
|
+
})
|
|
5389
|
+
}) }) : rows.length === 0 ? /* @__PURE__ */ jsx(Table.Tr, { children: /* @__PURE__ */ jsx(Table.Td, {
|
|
3971
5390
|
colSpan: totalColumns || 1,
|
|
3972
5391
|
py: "xl",
|
|
3973
|
-
|
|
3974
|
-
|
|
3975
|
-
|
|
3976
|
-
|
|
3977
|
-
|
|
5392
|
+
children: /* @__PURE__ */ jsx(Flex$1, {
|
|
5393
|
+
justify: "center",
|
|
5394
|
+
children: /* @__PURE__ */ jsx(Text$1, {
|
|
5395
|
+
c: "dimmed",
|
|
5396
|
+
size: "sm",
|
|
5397
|
+
children: props.emptyLabel ?? "No results"
|
|
5398
|
+
})
|
|
3978
5399
|
})
|
|
3979
|
-
}) })]
|
|
3980
|
-
})
|
|
5400
|
+
}) }) : rows })]
|
|
5401
|
+
})
|
|
5402
|
+
}),
|
|
5403
|
+
props.infinityScroll && /* @__PURE__ */ jsx("div", { ref: sentinelRef }),
|
|
5404
|
+
!props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
|
|
5405
|
+
page,
|
|
5406
|
+
size,
|
|
5407
|
+
totalPages: items.page?.totalPages,
|
|
5408
|
+
totalElements: items.page?.totalElements,
|
|
5409
|
+
isFirst: items.page?.isFirst,
|
|
5410
|
+
isLast: items.page?.isLast,
|
|
5411
|
+
offset: items.page?.offset ?? 0,
|
|
5412
|
+
numberOfElements: items.content.length,
|
|
5413
|
+
onPageChange: (value) => {
|
|
5414
|
+
form.input.page.set(value - 1);
|
|
5415
|
+
},
|
|
5416
|
+
onSizeChange: (value) => {
|
|
5417
|
+
form.input.size.set(value);
|
|
5418
|
+
}
|
|
5419
|
+
}),
|
|
5420
|
+
drawerConfig && /* @__PURE__ */ jsx(Drawer, {
|
|
5421
|
+
opened: drawerItem !== null,
|
|
5422
|
+
onClose: () => setDrawerItem(null),
|
|
5423
|
+
position: "right",
|
|
5424
|
+
size: "xl",
|
|
5425
|
+
...drawerConfig.props,
|
|
5426
|
+
children: drawerItem && drawerConfig.render(drawerItem)
|
|
3981
5427
|
})
|
|
3982
|
-
|
|
3983
|
-
|
|
3984
|
-
!props.infinityScroll && /* @__PURE__ */ jsx(DataTablePagination, {
|
|
3985
|
-
page,
|
|
3986
|
-
size,
|
|
3987
|
-
totalPages: items.page?.totalPages ?? 1,
|
|
3988
|
-
onPageChange: (value) => {
|
|
3989
|
-
form.input.page.set(value - 1);
|
|
3990
|
-
},
|
|
3991
|
-
onSizeChange: (value) => {
|
|
3992
|
-
form.input.size.set(value);
|
|
3993
|
-
}
|
|
3994
|
-
}),
|
|
3995
|
-
drawerConfig && /* @__PURE__ */ jsx(Drawer, {
|
|
3996
|
-
opened: drawerItem !== null,
|
|
3997
|
-
onClose: () => setDrawerItem(null),
|
|
3998
|
-
position: "right",
|
|
3999
|
-
size: "xl",
|
|
4000
|
-
...drawerConfig.props,
|
|
4001
|
-
children: drawerItem && drawerConfig.render(drawerItem)
|
|
4002
|
-
})
|
|
4003
|
-
]
|
|
5428
|
+
]
|
|
5429
|
+
})]
|
|
4004
5430
|
});
|
|
4005
5431
|
};
|
|
4006
5432
|
|
|
@@ -4099,8 +5525,8 @@ const OPERATOR_INFO = {
|
|
|
4099
5525
|
* Get the default icon for an input based on its type, format, or name.
|
|
4100
5526
|
*/
|
|
4101
5527
|
const getDefaultIcon = (params) => {
|
|
4102
|
-
const { type, format, name, isEnum, isArray, size = "
|
|
4103
|
-
const iconSize = ui.sizes.icon[size];
|
|
5528
|
+
const { type, format, name, isEnum, isArray, size = "xs" } = params;
|
|
5529
|
+
const iconSize = ui.sizes.icon[size] - 4;
|
|
4104
5530
|
if (format) switch (format) {
|
|
4105
5531
|
case "email": return /* @__PURE__ */ jsx(IconMail, { size: iconSize });
|
|
4106
5532
|
case "url":
|
|
@@ -4213,5 +5639,5 @@ const AlephaUI = $module({
|
|
|
4213
5639
|
});
|
|
4214
5640
|
|
|
4215
5641
|
//#endregion
|
|
4216
|
-
export { AlephaMantineProvider as _,
|
|
4217
|
-
//# sourceMappingURL=core-
|
|
5642
|
+
export { AlephaMantineProvider as _, TypeForm as a, Sidebar as c, Heading as d, Flex$1 as f, ui as g, ActionButton as h, JsonViewer as i, Text$1 as l, useDialog as m, capitalize as n, Control as o, ToggleSidebarButton as p, DataTable as r, DashboardShell as s, AlephaUI as t, Breadcrumb as u, useToast as v };
|
|
5643
|
+
//# sourceMappingURL=core-DFgB3yU4.js.map
|