@alepha/ui 0.18.0 → 0.18.2
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-BJhIwfD6.js} +17 -38
- package/dist/admin/AdminApiKeys-BJhIwfD6.js.map +1 -0
- package/dist/admin/{AdminAudits-Bgbf04hO.js → AdminAudits-DzD_4cDt.js} +23 -19
- package/dist/admin/AdminAudits-DzD_4cDt.js.map +1 -0
- package/dist/admin/AdminDashboard-C92tIc6x.js +67 -0
- package/dist/admin/AdminDashboard-C92tIc6x.js.map +1 -0
- package/dist/admin/{AdminFiles-B9a7G3cY.js → AdminFiles-DLpfhBkf.js} +3 -7
- package/dist/admin/AdminFiles-DLpfhBkf.js.map +1 -0
- package/dist/admin/{AdminJobDashboard-DaTwf5OY.js → AdminJobDashboard-KIOkeMgE.js} +2 -2
- package/dist/admin/{AdminJobDashboard-DaTwf5OY.js.map → AdminJobDashboard-KIOkeMgE.js.map} +1 -1
- package/dist/admin/{AdminJobExecutions-B9cek5dl.js → AdminJobExecutions-D0Yo_PU0.js} +24 -36
- package/dist/admin/AdminJobExecutions-D0Yo_PU0.js.map +1 -0
- package/dist/admin/{AdminJobRegistry-DFgV3oqx.js → AdminJobRegistry-PFajqaGK.js} +10 -18
- package/dist/admin/AdminJobRegistry-PFajqaGK.js.map +1 -0
- package/dist/admin/AdminLayout-B1DXZHDn.js +61 -0
- package/dist/admin/AdminLayout-B1DXZHDn.js.map +1 -0
- package/dist/admin/{AdminParameters-DHw9ATgl.js → AdminParameters-BspPeqp_.js} +2 -2
- package/dist/admin/{AdminParameters-DHw9ATgl.js.map → AdminParameters-BspPeqp_.js.map} +1 -1
- package/dist/admin/{AdminSessions-BhGJPI3z.js → AdminSessions-BnH5CZQl.js} +48 -53
- package/dist/admin/AdminSessions-BnH5CZQl.js.map +1 -0
- package/dist/admin/{AdminUserLayout-BdC4Te8m.js → AdminUserLayout-DUbC6-BI.js} +2 -2
- package/dist/admin/{AdminUserLayout-BdC4Te8m.js.map → AdminUserLayout-DUbC6-BI.js.map} +1 -1
- package/dist/admin/{AdminUserProfile-DAt23fqY.js → AdminUserProfile-DuTUnjdG.js} +3 -3
- package/dist/admin/{AdminUserProfile-DAt23fqY.js.map → AdminUserProfile-DuTUnjdG.js.map} +1 -1
- package/dist/admin/{AdminUserSessions-1uzcx02z.js → AdminUserSessions-DvZdAGpL.js} +33 -35
- package/dist/admin/AdminUserSessions-DvZdAGpL.js.map +1 -0
- package/dist/admin/AdminUsers-CR9z0g_5.js +206 -0
- package/dist/admin/AdminUsers-CR9z0g_5.js.map +1 -0
- package/dist/admin/{AuthLayout-DFJvCvzw.js → AuthLayout-DsUfp9RG.js} +2 -2
- package/dist/admin/{AuthLayout-DFJvCvzw.js.map → AuthLayout-DsUfp9RG.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-BGheURrg.js → Login-DHbYJKwg.js} +3 -3
- package/dist/{auth/Login-Denw_UGy.js.map → admin/Login-DHbYJKwg.js.map} +1 -1
- package/dist/{auth/Profile-BMX_Ar_s.js → admin/Profile-B2EcIDB9.js} +2 -2
- package/dist/{auth/Profile-BMX_Ar_s.js.map → admin/Profile-B2EcIDB9.js.map} +1 -1
- package/dist/admin/{Register-Cs10l8vX.js → Register-Z3fxRbUF.js} +3 -3
- package/dist/{demo/Register-a70LPgs2.js.map → admin/Register-Z3fxRbUF.js.map} +1 -1
- package/dist/admin/{ResetPassword-BwDdfkGH.js → ResetPassword-_Y1qTTKh.js} +2 -2
- package/dist/admin/{ResetPassword-BwDdfkGH.js.map → ResetPassword-_Y1qTTKh.js.map} +1 -1
- package/dist/admin/{VerifyEmail-DfXHAiQl.js → VerifyEmail-Bg22bwcC.js} +2 -2
- package/dist/admin/{VerifyEmail-DfXHAiQl.js.map → VerifyEmail-Bg22bwcC.js.map} +1 -1
- package/dist/admin/{core-2xoLiT0o.js → core-BVO_TQxb.js} +1474 -233
- package/dist/admin/core-BVO_TQxb.js.map +1 -0
- package/dist/admin/index.d.ts +29 -4
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +448 -69
- package/dist/admin/index.js.map +1 -1
- package/dist/auth/{AuthLayout-CAE1pX9s.js → AuthLayout-C161NeF6.js} +2 -2
- package/dist/auth/{AuthLayout-CAE1pX9s.js.map → AuthLayout-C161NeF6.js.map} +1 -1
- package/dist/auth/{Login-Denw_UGy.js → Login-C7jIqf00.js} +2 -2
- package/dist/{admin/Login-BGheURrg.js.map → auth/Login-C7jIqf00.js.map} +1 -1
- package/dist/{admin/Profile-B-c9pCPf.js → auth/Profile-BMpXJ0oi.js} +2 -2
- package/dist/{demo/Profile-CWqti7FB.js.map → auth/Profile-BMpXJ0oi.js.map} +1 -1
- package/dist/auth/{Register-6hi_cpfF.js → Register-2gx8qll-.js} +2 -2
- package/dist/auth/{Register-6hi_cpfF.js.map → Register-2gx8qll-.js.map} +1 -1
- package/dist/{demo/ResetPassword-DWN0lzr5.js → auth/ResetPassword-DBxt9hKk.js} +2 -2
- package/dist/auth/{ResetPassword-CqfTk1FI.js.map → ResetPassword-DBxt9hKk.js.map} +1 -1
- package/dist/{demo/VerifyEmail-DZWL72K4.js → auth/VerifyEmail-Z80Ubajk.js} +2 -2
- package/dist/auth/{VerifyEmail-nWiSTMjF.js.map → VerifyEmail-Z80Ubajk.js.map} +1 -1
- package/dist/auth/{core-niW0sFLv.js → core-DyfeVr5c.js} +1002 -38
- package/dist/auth/core-DyfeVr5c.js.map +1 -0
- package/dist/auth/index.d.ts +12 -1
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +12 -13
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +95 -14
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +1473 -232
- package/dist/core/index.js.map +1 -1
- package/dist/demo/{AuthLayout-jLa0aKsI.js → AuthLayout-DN-ClJQk.js} +2 -2
- package/dist/demo/{AuthLayout-jLa0aKsI.js.map → AuthLayout-DN-ClJQk.js.map} +1 -1
- package/dist/demo/{DemoButton-BmaWZVwf.js → DemoButton-CGUyR9eM.js} +3 -3
- package/dist/demo/{DemoButton-BmaWZVwf.js.map → DemoButton-CGUyR9eM.js.map} +1 -1
- package/dist/demo/{DemoDataTable-Z9xyV221.js → DemoDataTable-QFG-xXSx.js} +15 -19
- package/dist/demo/DemoDataTable-QFG-xXSx.js.map +1 -0
- package/dist/demo/{DemoDialog-4ItHLf9t.js → DemoDialog-DW8QEvD1.js} +2 -2
- package/dist/demo/{DemoDialog-4ItHLf9t.js.map → DemoDialog-DW8QEvD1.js.map} +1 -1
- package/dist/demo/{DemoFlex-EtVq8QfX.js → DemoFlex-CAhLUanT.js} +3 -3
- package/dist/demo/{DemoFlex-EtVq8QfX.js.map → DemoFlex-CAhLUanT.js.map} +1 -1
- package/dist/demo/{DemoHeading-BS-vGfkI.js → DemoHeading-yIFmNjHB.js} +3 -3
- package/dist/demo/{DemoHeading-BS-vGfkI.js.map → DemoHeading-yIFmNjHB.js.map} +1 -1
- package/dist/demo/{DemoHome-Clbn8AmS.js → DemoHome-BSGuBHus.js} +2 -2
- package/dist/demo/{DemoHome-Clbn8AmS.js.map → DemoHome-BSGuBHus.js.map} +1 -1
- package/dist/demo/{DemoJsonViewer-DkIX_ky2.js → DemoJsonViewer-DsA2IpgV.js} +3 -3
- package/dist/demo/{DemoJsonViewer-DkIX_ky2.js.map → DemoJsonViewer-DsA2IpgV.js.map} +1 -1
- package/dist/demo/{DemoLayout-C56xb5EE.js → DemoLayout-Cy6xjn6P.js} +2 -2
- package/dist/demo/{DemoLayout-C56xb5EE.js.map → DemoLayout-Cy6xjn6P.js.map} +1 -1
- package/dist/demo/{DemoLogin-BZwpicOS.js → DemoLogin-vqxgTu4P.js} +8 -8
- package/dist/demo/{DemoLogin-BZwpicOS.js.map → DemoLogin-vqxgTu4P.js.map} +1 -1
- package/dist/demo/{DemoRegister-C7_qc4MJ.js → DemoRegister-YHPvPg77.js} +8 -8
- package/dist/demo/{DemoRegister-C7_qc4MJ.js.map → DemoRegister-YHPvPg77.js.map} +1 -1
- package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js → DemoResetPassword-mOW18Zlm.js} +8 -8
- package/dist/demo/{DemoResetPassword-BI1Ct4Dw.js.map → DemoResetPassword-mOW18Zlm.js.map} +1 -1
- package/dist/demo/{DemoSidebar-CcBo4ltC.js → DemoSidebar-od7aLjP_.js} +3 -3
- package/dist/demo/{DemoSidebar-CcBo4ltC.js.map → DemoSidebar-od7aLjP_.js.map} +1 -1
- package/dist/demo/{DemoText-CzXuUn3g.js → DemoText-DU3JeRS0.js} +3 -3
- package/dist/demo/{DemoText-CzXuUn3g.js.map → DemoText-DU3JeRS0.js.map} +1 -1
- package/dist/demo/{DemoToast-BgHDhWrX.js → DemoToast-CUJEiPRa.js} +2 -2
- package/dist/demo/{DemoToast-BgHDhWrX.js.map → DemoToast-CUJEiPRa.js.map} +1 -1
- package/dist/demo/{DemoTypeForm-DDzWoMSV.js → DemoTypeForm-C1dNkahD.js} +3 -3
- package/dist/demo/{DemoTypeForm-DDzWoMSV.js.map → DemoTypeForm-C1dNkahD.js.map} +1 -1
- package/dist/demo/{DemoVerifyEmail-C_Irdnov.js → DemoVerifyEmail-D9EcXZ38.js} +8 -8
- package/dist/demo/{DemoVerifyEmail-C_Irdnov.js.map → DemoVerifyEmail-D9EcXZ38.js.map} +1 -1
- package/dist/demo/{Login-hSOU3jZc.js → Login-CoYf_P_F.js} +2 -2
- package/dist/demo/{Login-hSOU3jZc.js.map → Login-CoYf_P_F.js.map} +1 -1
- package/dist/demo/{Profile-CWqti7FB.js → Profile-BE_Y3co2.js} +2 -2
- package/dist/{admin/Profile-B-c9pCPf.js.map → demo/Profile-BE_Y3co2.js.map} +1 -1
- package/dist/demo/{Register-a70LPgs2.js → Register-fXHmBpr3.js} +2 -2
- package/dist/{admin/Register-Cs10l8vX.js.map → demo/Register-fXHmBpr3.js.map} +1 -1
- package/dist/{auth/ResetPassword-CqfTk1FI.js → demo/ResetPassword-CAPj8MO3.js} +2 -2
- package/dist/demo/{ResetPassword-DWN0lzr5.js.map → ResetPassword-CAPj8MO3.js.map} +1 -1
- package/dist/demo/{Showcase-Dq3MISpd.js → Showcase-BtEU0pY9.js} +2 -2
- package/dist/demo/{Showcase-Dq3MISpd.js.map → Showcase-BtEU0pY9.js.map} +1 -1
- package/dist/{auth/VerifyEmail-nWiSTMjF.js → demo/VerifyEmail-DFmdCdYs.js} +2 -2
- package/dist/demo/{VerifyEmail-DZWL72K4.js.map → VerifyEmail-DFmdCdYs.js.map} +1 -1
- package/dist/demo/{auth-d6n3xbug.js → auth-Djd7SKiw.js} +8 -8
- package/dist/demo/{auth-d6n3xbug.js.map → auth-Djd7SKiw.js.map} +1 -1
- package/dist/demo/{core-RCUw1Q-a.js → core-B7LNjM78.js} +1484 -226
- package/dist/demo/core-B7LNjM78.js.map +1 -0
- package/dist/demo/index.js +17 -17
- package/package.json +4 -4
- package/src/admin/{AdminRouter.ts → AdminRouter.tsx} +128 -19
- 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/sessions/AdminSessions.tsx +71 -71
- 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/buttons/UserButton.tsx +1 -3
- 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 +91 -1
- package/src/core/components/Text.tsx +1 -1
- package/src/core/components/buttons/ActionButton.tsx +15 -19
- 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/layout/AppBar.tsx +10 -0
- package/src/core/components/layout/DashboardShell.tsx +10 -7
- package/src/core/components/layout/Sidebar.tsx +60 -52
- package/src/core/constants/ui.ts +5 -5
- package/src/core/hooks/useTheme.ts +26 -3
- package/src/core/index.ts +6 -1
- package/src/core/interfaces/AlephaTheme.ts +2 -0
- package/src/core/providers/ThemeProvider.ts +108 -8
- package/src/core/services/DialogService.tsx +24 -3
- package/src/core/styles.css +26 -23
- package/src/core/table/components/DataTable.tsx +167 -137
- package/src/core/table/components/DataTableFilters.tsx +1 -6
- package/src/core/table/components/DataTablePagination.tsx +51 -28
- package/src/core/table/components/DataTableToolbar.tsx +9 -4
- package/src/core/table/index.ts +1 -0
- package/src/core/table/interfaces/types.ts +13 -9
- package/src/demo/components/core/DemoDataTable.tsx +15 -19
- 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/AdminSessions-BhGJPI3z.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/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/core-niW0sFLv.js.map +0 -1
- package/dist/demo/DemoDataTable-Z9xyV221.js.map +0 -1
- package/dist/demo/core-RCUw1Q-a.js.map +0 -1
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ColorSwatch,
|
|
3
|
+
Flex,
|
|
4
|
+
Select,
|
|
5
|
+
SimpleGrid,
|
|
6
|
+
Text,
|
|
7
|
+
useMantineTheme,
|
|
8
|
+
} from "@mantine/core";
|
|
9
|
+
import { IconCheck } from "@tabler/icons-react";
|
|
10
|
+
import type { AlephaThemeOverrides } from "../../atoms/alephaThemeOverridesAtom.ts";
|
|
11
|
+
import { useDialog } from "../../hooks/useDialog.ts";
|
|
12
|
+
import { useTheme } from "../../hooks/useTheme.ts";
|
|
13
|
+
import ActionButton from "./ActionButton.tsx";
|
|
14
|
+
|
|
15
|
+
const MANTINE_COLORS = [
|
|
16
|
+
"red",
|
|
17
|
+
"pink",
|
|
18
|
+
"grape",
|
|
19
|
+
"violet",
|
|
20
|
+
"indigo",
|
|
21
|
+
"blue",
|
|
22
|
+
"cyan",
|
|
23
|
+
"teal",
|
|
24
|
+
"green",
|
|
25
|
+
"lime",
|
|
26
|
+
"yellow",
|
|
27
|
+
"orange",
|
|
28
|
+
];
|
|
29
|
+
|
|
30
|
+
const RADIUS_OPTIONS = [
|
|
31
|
+
{ label: "xs", value: "xs" },
|
|
32
|
+
{ label: "sm", value: "sm" },
|
|
33
|
+
{ label: "md", value: "md" },
|
|
34
|
+
{ label: "lg", value: "lg" },
|
|
35
|
+
{ label: "xl", value: "xl" },
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
const SIZE_OPTIONS = [
|
|
39
|
+
{ label: "xs", value: "xs" },
|
|
40
|
+
{ label: "sm", value: "sm" },
|
|
41
|
+
{ label: "md", value: "md" },
|
|
42
|
+
{ label: "lg", value: "lg" },
|
|
43
|
+
{ label: "xl", value: "xl" },
|
|
44
|
+
];
|
|
45
|
+
|
|
46
|
+
const FONT_OPTIONS = [
|
|
47
|
+
{ label: "System", value: "" },
|
|
48
|
+
{ label: "Inter", value: "Inter, sans-serif" },
|
|
49
|
+
{ label: "Mono", value: "ui-monospace, SFMono-Regular, Menlo, monospace" },
|
|
50
|
+
{ label: "Serif", value: "Georgia, 'Times New Roman', serif" },
|
|
51
|
+
];
|
|
52
|
+
|
|
53
|
+
const ThemeExpertModal = () => {
|
|
54
|
+
const [, , expert] = useTheme();
|
|
55
|
+
const dialog = useDialog();
|
|
56
|
+
const mantineTheme = useMantineTheme();
|
|
57
|
+
const { overrides, setOverrides } = expert;
|
|
58
|
+
|
|
59
|
+
const currentColor = overrides.primaryColor || mantineTheme.primaryColor;
|
|
60
|
+
const currentRadius = overrides.radius || mantineTheme.defaultRadius || "md";
|
|
61
|
+
const currentFont = overrides.fontFamily || "";
|
|
62
|
+
const currentFontSize = overrides.fontSize || "md";
|
|
63
|
+
const currentScale = overrides.scale || "md";
|
|
64
|
+
|
|
65
|
+
const updateOverrides = (patch: Partial<AlephaThemeOverrides>) => {
|
|
66
|
+
setOverrides({ ...overrides, ...patch });
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
return (
|
|
70
|
+
<Flex direction="column" gap="lg">
|
|
71
|
+
<Flex direction="column" gap="xs">
|
|
72
|
+
<Text fw={500} size="sm">
|
|
73
|
+
Primary Color
|
|
74
|
+
</Text>
|
|
75
|
+
<SimpleGrid cols={6} spacing="xs">
|
|
76
|
+
{MANTINE_COLORS.map((color) => (
|
|
77
|
+
<Flex key={color} justify="center">
|
|
78
|
+
<ColorSwatch
|
|
79
|
+
color={mantineTheme.colors[color]?.[6] ?? color}
|
|
80
|
+
onClick={() => updateOverrides({ primaryColor: color })}
|
|
81
|
+
style={{ cursor: "pointer" }}
|
|
82
|
+
size={32}
|
|
83
|
+
>
|
|
84
|
+
{currentColor === color && (
|
|
85
|
+
<IconCheck size={14} color="white" />
|
|
86
|
+
)}
|
|
87
|
+
</ColorSwatch>
|
|
88
|
+
</Flex>
|
|
89
|
+
))}
|
|
90
|
+
</SimpleGrid>
|
|
91
|
+
</Flex>
|
|
92
|
+
|
|
93
|
+
<Flex direction="column" gap="xs">
|
|
94
|
+
<Text fw={500} size="sm">
|
|
95
|
+
Border Radius
|
|
96
|
+
</Text>
|
|
97
|
+
<Flex gap="xs">
|
|
98
|
+
{RADIUS_OPTIONS.map((opt) => (
|
|
99
|
+
<ActionButton
|
|
100
|
+
key={opt.value}
|
|
101
|
+
variant={
|
|
102
|
+
String(currentRadius) === opt.value ? "filled" : "default"
|
|
103
|
+
}
|
|
104
|
+
size="xs"
|
|
105
|
+
flex={1}
|
|
106
|
+
onClick={() => updateOverrides({ radius: opt.value })}
|
|
107
|
+
>
|
|
108
|
+
{opt.label}
|
|
109
|
+
</ActionButton>
|
|
110
|
+
))}
|
|
111
|
+
</Flex>
|
|
112
|
+
</Flex>
|
|
113
|
+
|
|
114
|
+
<Flex direction="column" gap="xs">
|
|
115
|
+
<Text fw={500} size="sm">
|
|
116
|
+
Font Family
|
|
117
|
+
</Text>
|
|
118
|
+
<Select
|
|
119
|
+
data={FONT_OPTIONS}
|
|
120
|
+
value={currentFont}
|
|
121
|
+
onChange={(value) => updateOverrides({ fontFamily: value ?? "" })}
|
|
122
|
+
allowDeselect={false}
|
|
123
|
+
/>
|
|
124
|
+
</Flex>
|
|
125
|
+
|
|
126
|
+
<Flex direction="column" gap="xs">
|
|
127
|
+
<Text fw={500} size="sm">
|
|
128
|
+
Font Size
|
|
129
|
+
</Text>
|
|
130
|
+
<Flex gap="xs">
|
|
131
|
+
{SIZE_OPTIONS.map((opt) => (
|
|
132
|
+
<ActionButton
|
|
133
|
+
key={opt.value}
|
|
134
|
+
variant={currentFontSize === opt.value ? "filled" : "default"}
|
|
135
|
+
size="xs"
|
|
136
|
+
flex={1}
|
|
137
|
+
onClick={() => updateOverrides({ fontSize: opt.value })}
|
|
138
|
+
>
|
|
139
|
+
{opt.label}
|
|
140
|
+
</ActionButton>
|
|
141
|
+
))}
|
|
142
|
+
</Flex>
|
|
143
|
+
</Flex>
|
|
144
|
+
|
|
145
|
+
<Flex direction="column" gap="xs">
|
|
146
|
+
<Text fw={500} size="sm">
|
|
147
|
+
Scale
|
|
148
|
+
</Text>
|
|
149
|
+
<Flex gap="xs">
|
|
150
|
+
{SIZE_OPTIONS.map((opt) => (
|
|
151
|
+
<ActionButton
|
|
152
|
+
key={opt.value}
|
|
153
|
+
variant={currentScale === opt.value ? "filled" : "default"}
|
|
154
|
+
size="xs"
|
|
155
|
+
flex={1}
|
|
156
|
+
onClick={() => updateOverrides({ scale: opt.value })}
|
|
157
|
+
>
|
|
158
|
+
{opt.label}
|
|
159
|
+
</ActionButton>
|
|
160
|
+
))}
|
|
161
|
+
</Flex>
|
|
162
|
+
</Flex>
|
|
163
|
+
|
|
164
|
+
<Flex justify="space-between">
|
|
165
|
+
<ActionButton
|
|
166
|
+
variant="subtle"
|
|
167
|
+
color="red"
|
|
168
|
+
onClick={() => expert.resetOverrides()}
|
|
169
|
+
>
|
|
170
|
+
Reset
|
|
171
|
+
</ActionButton>
|
|
172
|
+
<ActionButton
|
|
173
|
+
variant={"default"}
|
|
174
|
+
px={"xl"}
|
|
175
|
+
onClick={() => dialog.close()}
|
|
176
|
+
>
|
|
177
|
+
OK
|
|
178
|
+
</ActionButton>
|
|
179
|
+
</Flex>
|
|
180
|
+
</Flex>
|
|
181
|
+
);
|
|
182
|
+
};
|
|
183
|
+
|
|
184
|
+
export default ThemeExpertModal;
|
|
@@ -8,6 +8,7 @@ import {
|
|
|
8
8
|
OmnibarButton,
|
|
9
9
|
type OmnibarButtonProps,
|
|
10
10
|
Text,
|
|
11
|
+
ThemeButton,
|
|
11
12
|
} from "@alepha/ui";
|
|
12
13
|
import {
|
|
13
14
|
Anchor,
|
|
@@ -25,6 +26,7 @@ export type AppBarItem =
|
|
|
25
26
|
| AppBarElement
|
|
26
27
|
| AppBarBurger
|
|
27
28
|
| AppBarDark
|
|
29
|
+
| AppBarTheme
|
|
28
30
|
| AppBarSearch
|
|
29
31
|
| AppBarLang
|
|
30
32
|
| AppBarSpacer
|
|
@@ -54,6 +56,11 @@ export interface AppBarDark extends AppBarAbstractItem {
|
|
|
54
56
|
props?: Partial<ActionProps>;
|
|
55
57
|
}
|
|
56
58
|
|
|
59
|
+
export interface AppBarTheme extends AppBarAbstractItem {
|
|
60
|
+
type: "theme";
|
|
61
|
+
props?: Partial<ActionProps>;
|
|
62
|
+
}
|
|
63
|
+
|
|
57
64
|
export interface AppBarSearch extends AppBarAbstractItem {
|
|
58
65
|
type: "search";
|
|
59
66
|
props?: OmnibarButtonProps;
|
|
@@ -175,6 +182,9 @@ const AppBar = (props: AppBarProps) => {
|
|
|
175
182
|
if (item.type === "dark") {
|
|
176
183
|
return <DarkModeButton key={index} {...item.props} />;
|
|
177
184
|
}
|
|
185
|
+
if (item.type === "theme") {
|
|
186
|
+
return <ThemeButton key={index} {...item.props} />;
|
|
187
|
+
}
|
|
178
188
|
if (item.type === "search") {
|
|
179
189
|
return <OmnibarButton key={index} {...item.props} />;
|
|
180
190
|
}
|
|
@@ -37,7 +37,7 @@ export interface DashboardShellProps {
|
|
|
37
37
|
/**
|
|
38
38
|
* Content rendered above the Sidebar inside the navbar (e.g. logo).
|
|
39
39
|
*/
|
|
40
|
-
navbarHeader?: ReactNode;
|
|
40
|
+
navbarHeader?: (props: { collapsed: boolean }) => ReactNode;
|
|
41
41
|
|
|
42
42
|
/**
|
|
43
43
|
* Content rendered below the Sidebar inside the navbar (e.g. toggle button).
|
|
@@ -136,6 +136,7 @@ const DashboardShell = (props: DashboardShellProps) => {
|
|
|
136
136
|
<AppShell
|
|
137
137
|
layout={"alt"}
|
|
138
138
|
w={"100%"}
|
|
139
|
+
h={"100vh"}
|
|
139
140
|
flex={1}
|
|
140
141
|
header={hasAppBar ? { height: hHeight } : undefined}
|
|
141
142
|
navbar={
|
|
@@ -159,10 +160,7 @@ const DashboardShell = (props: DashboardShellProps) => {
|
|
|
159
160
|
)}
|
|
160
161
|
|
|
161
162
|
{hasSidebar && (
|
|
162
|
-
<AppShell.Navbar
|
|
163
|
-
className="alepha-sidebar-navbar"
|
|
164
|
-
{...props.appShellNavbarProps}
|
|
165
|
-
>
|
|
163
|
+
<AppShell.Navbar {...props.appShellNavbarProps}>
|
|
166
164
|
{props.navbarHeader ? (
|
|
167
165
|
<Flex
|
|
168
166
|
style={{
|
|
@@ -170,7 +168,7 @@ const DashboardShell = (props: DashboardShellProps) => {
|
|
|
170
168
|
}}
|
|
171
169
|
h={headerHeight}
|
|
172
170
|
>
|
|
173
|
-
{props.navbarHeader}
|
|
171
|
+
{props.navbarHeader({ collapsed })}
|
|
174
172
|
</Flex>
|
|
175
173
|
) : null}
|
|
176
174
|
<Sidebar {...(props.sidebarProps ?? {})} collapsed={collapsed} />
|
|
@@ -187,7 +185,12 @@ const DashboardShell = (props: DashboardShellProps) => {
|
|
|
187
185
|
</AppShell.Navbar>
|
|
188
186
|
)}
|
|
189
187
|
|
|
190
|
-
<AppShell.Main
|
|
188
|
+
<AppShell.Main
|
|
189
|
+
display={"flex"}
|
|
190
|
+
bg={"var(--alepha-ground)"}
|
|
191
|
+
pos={"relative"}
|
|
192
|
+
{...props.appShellMainProps}
|
|
193
|
+
>
|
|
191
194
|
{props.children ?? <NestedView />}
|
|
192
195
|
</AppShell.Main>
|
|
193
196
|
|
|
@@ -89,7 +89,7 @@ export const Sidebar = (props: SidebarProps) => {
|
|
|
89
89
|
|
|
90
90
|
if (item.type === "search") {
|
|
91
91
|
return (
|
|
92
|
-
<Flex key={key} mb="xs">
|
|
92
|
+
<Flex key={key} mb="xs" w={"100%"} justify="center" pos={"relative"}>
|
|
93
93
|
<OmnibarButton collapsed={collapsed} />
|
|
94
94
|
</Flex>
|
|
95
95
|
);
|
|
@@ -112,7 +112,6 @@ export const Sidebar = (props: SidebarProps) => {
|
|
|
112
112
|
if (collapsed) {
|
|
113
113
|
return (
|
|
114
114
|
<Fragment key={key}>
|
|
115
|
-
{divider(`${key}-d`, undefined, collapsed)}
|
|
116
115
|
{item.children?.map((child, index) =>
|
|
117
116
|
renderNode(child, `s${key}-${index}`, collapsed),
|
|
118
117
|
)}
|
|
@@ -202,7 +201,7 @@ export const Sidebar = (props: SidebarProps) => {
|
|
|
202
201
|
};
|
|
203
202
|
|
|
204
203
|
const padding = "md";
|
|
205
|
-
const gap = props.items ? (props.gap ??
|
|
204
|
+
const gap = props.items ? (props.gap ?? 8) : "xs";
|
|
206
205
|
const menu = useMemo(
|
|
207
206
|
() => getSidebarNodes(),
|
|
208
207
|
[props.items, props.autoPopulateMenu],
|
|
@@ -316,17 +315,11 @@ export const SidebarItem = (props: SidebarItemProps) => {
|
|
|
316
315
|
props.theme.button?.size ??
|
|
317
316
|
(level === 0 ? "sm" : "xs")
|
|
318
317
|
}
|
|
319
|
-
// tooltip={
|
|
320
|
-
// item.description
|
|
321
|
-
// ? { label: item.description, position: "right" }
|
|
322
|
-
// : undefined
|
|
323
|
-
// }
|
|
324
318
|
bd={0}
|
|
325
319
|
fw={"normal"}
|
|
326
320
|
variant={"default"}
|
|
327
321
|
propsActive={{
|
|
328
322
|
variant: "outline",
|
|
329
|
-
fw: "bold",
|
|
330
323
|
}}
|
|
331
324
|
radius={props.item.theme?.radius ?? props.theme.button?.radius ?? "md"}
|
|
332
325
|
onClick={handleItemClick}
|
|
@@ -355,7 +348,7 @@ export const SidebarItem = (props: SidebarItemProps) => {
|
|
|
355
348
|
/>
|
|
356
349
|
|
|
357
350
|
{item.children && isOpen && (
|
|
358
|
-
<Flex direction={"column"} data-parent-level={level}>
|
|
351
|
+
<Flex direction={"column"} data-parent-level={level} gap={2} py={2}>
|
|
359
352
|
<Flex
|
|
360
353
|
style={{
|
|
361
354
|
position: "absolute",
|
|
@@ -401,52 +394,67 @@ const SidebarCollapsedItem = (props: SidebarItemProps) => {
|
|
|
401
394
|
? {
|
|
402
395
|
on: "hover",
|
|
403
396
|
position: "right",
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
397
|
+
menuProps: {
|
|
398
|
+
arrowPosition: "center",
|
|
399
|
+
arrowSize: 10,
|
|
400
|
+
withArrow: true,
|
|
401
|
+
},
|
|
402
|
+
items: [
|
|
403
|
+
{
|
|
404
|
+
type: "label",
|
|
405
|
+
label: item.label,
|
|
406
|
+
},
|
|
407
|
+
...item
|
|
408
|
+
.children!.filter((child) => !child.can || child.can())
|
|
409
|
+
.map(
|
|
410
|
+
(child): ActionMenuItem => ({
|
|
411
|
+
label: child.label as string,
|
|
412
|
+
icon: renderIcon(child.icon, ui.sizes.icon.sm),
|
|
413
|
+
href: child.href,
|
|
414
|
+
active: child.href
|
|
415
|
+
? router.isActive(child.href, {
|
|
416
|
+
startWith: child.activeStartsWith,
|
|
417
|
+
})
|
|
418
|
+
: undefined,
|
|
419
|
+
}),
|
|
420
|
+
),
|
|
421
|
+
],
|
|
418
422
|
}
|
|
419
423
|
: undefined;
|
|
420
424
|
|
|
421
425
|
return (
|
|
422
|
-
<
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
426
|
+
<Flex w={"100%"} justify="center" pos={"relative"}>
|
|
427
|
+
<ActionButton
|
|
428
|
+
size={
|
|
429
|
+
props.item.theme?.size ??
|
|
430
|
+
props.theme.button?.size ??
|
|
431
|
+
(level === 0 ? "sm" : "xs")
|
|
432
|
+
}
|
|
433
|
+
bd={0}
|
|
434
|
+
variant={"default"}
|
|
435
|
+
propsActive={{
|
|
436
|
+
variant: "outline",
|
|
437
|
+
}}
|
|
438
|
+
tooltip={
|
|
439
|
+
hasChildren
|
|
440
|
+
? undefined
|
|
441
|
+
: {
|
|
442
|
+
label: item.label,
|
|
443
|
+
position: "right",
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
onClick={hasChildren ? undefined : handleItemClick}
|
|
447
|
+
icon={
|
|
448
|
+
renderIcon(item.icon, ui.sizes.icon.sm) ?? (
|
|
449
|
+
<IconSquareRounded size={ui.sizes.icon.sm} />
|
|
450
|
+
)
|
|
451
|
+
}
|
|
452
|
+
href={hasChildren ? undefined : (props.item.href as any)}
|
|
453
|
+
target={hasChildren ? undefined : props.item.target}
|
|
454
|
+
menu={menu}
|
|
455
|
+
{...props.item.actionProps}
|
|
456
|
+
/>
|
|
457
|
+
</Flex>
|
|
450
458
|
);
|
|
451
459
|
};
|
|
452
460
|
|
package/src/core/constants/ui.ts
CHANGED
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
export const ui = {
|
|
2
2
|
colors: {
|
|
3
3
|
transparent: "transparent",
|
|
4
|
-
background: "var(--alepha-
|
|
4
|
+
background: "var(--alepha-ground)",
|
|
5
5
|
surface: "var(--alepha-surface)",
|
|
6
6
|
elevated: "var(--alepha-elevated)",
|
|
7
7
|
border: "var(--alepha-border)",
|
|
8
8
|
},
|
|
9
9
|
sizes: {
|
|
10
10
|
icon: {
|
|
11
|
-
xs:
|
|
12
|
-
sm:
|
|
13
|
-
md:
|
|
14
|
-
lg:
|
|
11
|
+
xs: 16,
|
|
12
|
+
sm: 20,
|
|
13
|
+
md: 24,
|
|
14
|
+
lg: 28,
|
|
15
15
|
xl: 32,
|
|
16
16
|
},
|
|
17
17
|
},
|
|
@@ -3,23 +3,36 @@ import {
|
|
|
3
3
|
alephaThemeAtom,
|
|
4
4
|
type CurrentAlephaTheme,
|
|
5
5
|
} from "../atoms/alephaThemeAtom.ts";
|
|
6
|
+
import {
|
|
7
|
+
type AlephaThemeOverrides,
|
|
8
|
+
alephaThemeOverridesAtom,
|
|
9
|
+
} from "../atoms/alephaThemeOverridesAtom.ts";
|
|
6
10
|
import type { AlephaTheme } from "../interfaces/AlephaTheme.ts";
|
|
7
11
|
import { ThemeProvider } from "../providers/ThemeProvider.ts";
|
|
8
12
|
|
|
13
|
+
export interface ThemeExpert {
|
|
14
|
+
overrides: AlephaThemeOverrides;
|
|
15
|
+
setOverrides: (overrides: AlephaThemeOverrides) => void;
|
|
16
|
+
resetOverrides: () => void;
|
|
17
|
+
}
|
|
18
|
+
|
|
9
19
|
/**
|
|
10
20
|
* Hook to get and set the current theme.
|
|
11
21
|
*
|
|
12
|
-
* Returns a tuple with the current theme
|
|
22
|
+
* Returns a tuple with the current theme, a function to set the theme,
|
|
23
|
+
* and expert mode controls for fine-grained customization.
|
|
13
24
|
*
|
|
14
25
|
* ```tsx
|
|
15
|
-
* const [theme, setTheme] = useTheme();
|
|
26
|
+
* const [theme, setTheme, expert] = useTheme();
|
|
16
27
|
* ```
|
|
17
28
|
*/
|
|
18
29
|
export const useTheme = (): [
|
|
19
30
|
AlephaTheme,
|
|
20
31
|
(theme: CurrentAlephaTheme) => void,
|
|
32
|
+
ThemeExpert,
|
|
21
33
|
] => {
|
|
22
34
|
useStore(alephaThemeAtom);
|
|
35
|
+
useStore(alephaThemeOverridesAtom);
|
|
23
36
|
|
|
24
37
|
const themeProvider = useInject(ThemeProvider);
|
|
25
38
|
const theme = themeProvider.getTheme();
|
|
@@ -27,5 +40,15 @@ export const useTheme = (): [
|
|
|
27
40
|
themeProvider.setTheme(theme.index);
|
|
28
41
|
};
|
|
29
42
|
|
|
30
|
-
|
|
43
|
+
const expert: ThemeExpert = {
|
|
44
|
+
overrides: themeProvider.getThemeOverrides(),
|
|
45
|
+
setOverrides: (overrides: AlephaThemeOverrides) => {
|
|
46
|
+
themeProvider.setThemeOverrides(overrides);
|
|
47
|
+
},
|
|
48
|
+
resetOverrides: () => {
|
|
49
|
+
themeProvider.resetThemeOverrides();
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
return [theme, setTheme, expert] as const;
|
|
31
54
|
};
|
package/src/core/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ import { AlephaReactI18n } from "alepha/react/i18n";
|
|
|
5
5
|
import type { ComponentType, ReactNode } from "react";
|
|
6
6
|
import { alephaSidebarAtom } from "./atoms/alephaSidebarAtom.ts";
|
|
7
7
|
import { alephaThemeAtom } from "./atoms/alephaThemeAtom.ts";
|
|
8
|
+
import { alephaThemeOverridesAtom } from "./atoms/alephaThemeOverridesAtom.ts";
|
|
8
9
|
import { ThemeProvider } from "./providers/ThemeProvider.ts";
|
|
9
10
|
import { DialogService } from "./services/DialogService.tsx";
|
|
10
11
|
import { ToastService } from "./services/ToastService.tsx";
|
|
@@ -15,6 +16,7 @@ import { UiRouter } from "./UiRouter.ts";
|
|
|
15
16
|
export * from "./atoms/alephaSidebarAtom.ts";
|
|
16
17
|
export * from "./atoms/alephaThemeAtom.ts";
|
|
17
18
|
export * from "./atoms/alephaThemeListAtom.ts";
|
|
19
|
+
export * from "./atoms/alephaThemeOverridesAtom.ts";
|
|
18
20
|
export * from "./atoms/themes/default.ts";
|
|
19
21
|
export * from "./atoms/themes/midnight.ts";
|
|
20
22
|
export type { AlephaMantineProviderProps } from "./components/AlephaMantineProvider.tsx";
|
|
@@ -109,7 +111,7 @@ export * from "./form/index.ts";
|
|
|
109
111
|
export * from "./helpers/isComponentType.ts";
|
|
110
112
|
export * from "./helpers/renderIcon.tsx";
|
|
111
113
|
export { useDialog } from "./hooks/useDialog.ts";
|
|
112
|
-
export { useTheme } from "./hooks/useTheme.ts";
|
|
114
|
+
export { type ThemeExpert, useTheme } from "./hooks/useTheme.ts";
|
|
113
115
|
export { useToast } from "./hooks/useToast.ts";
|
|
114
116
|
export * from "./interfaces/AlephaIntent.ts";
|
|
115
117
|
// JSON
|
|
@@ -140,6 +142,9 @@ declare module "alepha" {
|
|
|
140
142
|
interface State {
|
|
141
143
|
[alephaSidebarAtom.key]?: Static<typeof alephaSidebarAtom.schema>;
|
|
142
144
|
[alephaThemeAtom.key]?: Static<typeof alephaThemeAtom.schema>;
|
|
145
|
+
[alephaThemeOverridesAtom.key]?: Static<
|
|
146
|
+
typeof alephaThemeOverridesAtom.schema
|
|
147
|
+
>;
|
|
143
148
|
}
|
|
144
149
|
}
|
|
145
150
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import type { MantineThemeOverride } from "@mantine/core";
|
|
2
|
+
import type { SimpleHead } from "alepha/react/head";
|
|
2
3
|
|
|
3
4
|
export type AlephaTheme = MantineThemeOverride & {
|
|
4
5
|
name: string;
|
|
5
6
|
description: string;
|
|
6
7
|
defaultColorScheme?: "light" | "dark"; // or "system"
|
|
8
|
+
head?: Pick<SimpleHead, "link" | "meta" | "script">;
|
|
7
9
|
};
|