@alepha/ui 0.15.1 → 0.15.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/AdminAudits-BU-p1g7A.js +3 -0
- package/dist/admin/{AdminAudits-DClGEVBj.js → AdminAudits-Oh7iAfQa.js} +5 -5
- package/dist/admin/AdminAudits-Oh7iAfQa.js.map +1 -0
- package/dist/admin/AdminFiles-Bg9feLFH.js +3 -0
- package/dist/admin/{AdminFiles-C76r1_Xz.js → AdminFiles-Cu8GHgQ3.js} +3 -3
- package/dist/admin/AdminFiles-Cu8GHgQ3.js.map +1 -0
- package/dist/admin/{AdminNotifications-Bsalygm5.js → AdminNotifications-CgYkBuG_.js} +3 -3
- package/dist/admin/AdminNotifications-CgYkBuG_.js.map +1 -0
- package/dist/admin/AdminNotifications-DmfGPqHe.js +3 -0
- package/dist/admin/{AdminParameters-CpmAWwqN.js → AdminParameters-Cl-R0nXt.js} +1 -1
- package/dist/admin/{AdminParameters-Bmxtnpv-.js → AdminParameters-hjNG_KXb.js} +4 -4
- package/dist/admin/AdminParameters-hjNG_KXb.js.map +1 -0
- package/dist/admin/{AdminSessions-DmK3R6pP.js → AdminSessions-Bey9cuy1.js} +4 -4
- package/dist/admin/AdminSessions-Bey9cuy1.js.map +1 -0
- package/dist/admin/AdminSessions-Cn4_jB04.js +3 -0
- package/dist/admin/{AdminUserAudits-BPMP1Qd2.js → AdminUserAudits-C7AN9jx7.js} +4 -4
- package/dist/admin/AdminUserAudits-C7AN9jx7.js.map +1 -0
- package/dist/admin/{AdminUserAudits-Brcenss9.js → AdminUserAudits-Cp_ERd2g.js} +1 -1
- package/dist/admin/{AdminUserCreate-CZjB6NKc.js → AdminUserCreate-BVIm4JdN.js} +5 -5
- package/dist/admin/AdminUserCreate-BVIm4JdN.js.map +1 -0
- package/dist/admin/{AdminUserCreate-Cx8bkYC2.js → AdminUserCreate-C1aInRDk.js} +1 -1
- package/dist/admin/{AdminUserDetails-8TYsqQBy.js → AdminUserDetails-Dcn3OwMC.js} +1 -1
- package/dist/admin/{AdminUserDetails-DuqCOBJK.js → AdminUserDetails-yM4x8JE6.js} +5 -5
- package/dist/admin/AdminUserDetails-yM4x8JE6.js.map +1 -0
- package/dist/admin/{AdminUserLayout-Dgk8s7Cd.js → AdminUserLayout-BnfBC1gD.js} +4 -4
- package/dist/admin/AdminUserLayout-BnfBC1gD.js.map +1 -0
- package/dist/admin/{AdminUserLayout-Bz2u_zQ4.js → AdminUserLayout-gb-nbggz.js} +1 -1
- package/dist/admin/{AdminUserSessions-DCpe8_T6.js → AdminUserSessions-kmkXG-xf.js} +4 -4
- package/dist/admin/AdminUserSessions-kmkXG-xf.js.map +1 -0
- package/dist/admin/AdminUserSessions-rvA0ztxn.js +3 -0
- package/dist/admin/{AdminUserSettings-qxDfowqh.js → AdminUserSettings-DZ9iWhJW.js} +5 -5
- package/dist/admin/AdminUserSettings-DZ9iWhJW.js.map +1 -0
- package/dist/admin/AdminUserSettings-Dg-wTRzN.js +3 -0
- package/dist/admin/{AdminUsers-ZlPsDz0T.js → AdminUsers-D6Y5K8Am.js} +5 -5
- package/dist/admin/AdminUsers-D6Y5K8Am.js.map +1 -0
- package/dist/admin/AdminUsers-RCaxccEW.js +3 -0
- package/dist/admin/index.d.ts +55 -36
- package/dist/admin/index.d.ts.map +1 -1
- package/dist/admin/index.js +54 -32
- package/dist/admin/index.js.map +1 -1
- package/dist/auth/{AuthLayout-CWzQ8rCe.js → AuthLayout-Dj5K4SIN.js} +2 -2
- package/dist/auth/AuthLayout-Dj5K4SIN.js.map +1 -0
- package/dist/auth/{Login-CyvKwy5e.js → Login-BBqTosqZ.js} +6 -6
- package/dist/auth/Login-BBqTosqZ.js.map +1 -0
- package/dist/auth/Login-CoU63mMR.js +4 -0
- package/dist/auth/Profile-Bxj8Nwom.js +150 -0
- package/dist/auth/Profile-Bxj8Nwom.js.map +1 -0
- package/dist/auth/Register-BV_oa_AK.js +4 -0
- package/dist/auth/{Register-C7Zp09Ks.js → Register-Ce675Crg.js} +8 -8
- package/dist/auth/Register-Ce675Crg.js.map +1 -0
- package/dist/auth/ResetPassword-D5wC8GAA.js +3 -0
- package/dist/auth/{ResetPassword-DYJSUC6B.js → ResetPassword-DWdt7c40.js} +5 -5
- package/dist/auth/ResetPassword-DWdt7c40.js.map +1 -0
- package/dist/auth/{VerifyEmail-CNXFIwWW.js → VerifyEmail-CI4JwByV.js} +4 -4
- package/dist/auth/VerifyEmail-CI4JwByV.js.map +1 -0
- package/dist/auth/VerifyEmail-DAfqVm5s.js +3 -0
- package/dist/auth/index.d.ts +36 -20
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +62 -17
- package/dist/auth/index.js.map +1 -1
- package/dist/core/index.d.ts +216 -71
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +733 -445
- package/dist/core/index.js.map +1 -1
- package/dist/demo/{DemoDataTable-DYbDYbs5.js → DemoDataTable-CguplbR7.js} +2 -2
- package/dist/demo/{DemoDataTable-DYbDYbs5.js.map → DemoDataTable-CguplbR7.js.map} +1 -1
- package/dist/demo/DemoJsonViewer-DIssGVlJ.js +4 -0
- package/dist/demo/{DemoJsonViewer-D_Hff1Q2.js → DemoJsonViewer-Dgdk3Txb.js} +3 -3
- package/dist/demo/{DemoJsonViewer-D_Hff1Q2.js.map → DemoJsonViewer-Dgdk3Txb.js.map} +1 -1
- package/dist/demo/{DemoLayout-DjIDm93B.js → DemoLayout-B20TEuhV.js} +2 -2
- package/dist/demo/DemoLayout-B20TEuhV.js.map +1 -0
- package/dist/demo/DemoLayout-DSRyf4qJ.js +3 -0
- package/dist/demo/{DemoLogin-BA_HiIRZ.js → DemoLogin-S-b15cmE.js} +7 -7
- package/dist/demo/DemoLogin-S-b15cmE.js.map +1 -0
- package/dist/demo/{DemoRegister-B6syaxP9.js → DemoRegister-B29MdAaZ.js} +9 -9
- package/dist/demo/DemoRegister-B29MdAaZ.js.map +1 -0
- package/dist/demo/{DemoResetPassword-BOcLG4GF.js → DemoResetPassword-CPTy88iK.js} +6 -6
- package/dist/demo/DemoResetPassword-CPTy88iK.js.map +1 -0
- package/dist/demo/{DemoSidebar-DpZXf7GO.js → DemoSidebar-MVmQKfMt.js} +2 -2
- package/dist/demo/{DemoSidebar-DpZXf7GO.js.map → DemoSidebar-MVmQKfMt.js.map} +1 -1
- package/dist/demo/{DemoTypeForm-BlLAcQqZ.js → DemoTypeForm-w-qtfRlC.js} +3 -3
- package/dist/demo/DemoTypeForm-w-qtfRlC.js.map +1 -0
- package/dist/demo/{DemoVerifyEmail-C-J7bXUQ.js → DemoVerifyEmail-C8FFJT5A.js} +5 -5
- package/dist/demo/DemoVerifyEmail-C8FFJT5A.js.map +1 -0
- package/dist/demo/{Showcase-HchhcsHV.js → Showcase-CQrMWars.js} +2 -2
- package/dist/demo/Showcase-CQrMWars.js.map +1 -0
- package/dist/demo/index.d.ts +25 -15
- package/dist/demo/index.d.ts.map +1 -1
- package/dist/demo/index.js +24 -14
- package/dist/demo/index.js.map +1 -1
- package/package.json +6 -6
- package/src/admin/AdminRouter.ts +4 -4
- package/src/admin/MainRouter.ts +1 -1
- package/src/admin/components/audits/AdminAudits.tsx +4 -4
- package/src/admin/components/files/AdminFiles.tsx +2 -2
- package/src/admin/components/jobs/AdminJobs.tsx +2 -2
- package/src/admin/components/notifications/AdminNotifications.tsx +2 -2
- package/src/admin/components/parameters/AdminParameters.tsx +1 -1
- package/src/admin/components/parameters/ParameterDetails.tsx +2 -2
- package/src/admin/components/parameters/ParameterHistory.tsx +1 -1
- package/src/admin/components/parameters/types.ts +9 -3
- package/src/admin/components/sessions/AdminSessions.tsx +3 -3
- package/src/admin/components/shared/AdminResourceHeader.tsx +1 -1
- package/src/admin/components/shared/AdminResourceTabs.tsx +1 -1
- package/src/admin/components/users/AdminUserAudits.tsx +3 -3
- package/src/admin/components/users/AdminUserCreate.tsx +4 -4
- package/src/admin/components/users/AdminUserDetails.tsx +4 -4
- package/src/admin/components/users/AdminUserLayout.tsx +3 -3
- package/src/admin/components/users/AdminUserSessions.tsx +3 -3
- package/src/admin/components/users/AdminUserSettings.tsx +4 -4
- package/src/admin/components/users/AdminUsers.tsx +4 -4
- package/src/admin/index.ts +27 -2
- package/src/auth/AuthI18n.ts +1 -1
- package/src/auth/AuthRouter.ts +14 -2
- package/src/auth/components/AuthLayout.tsx +1 -1
- package/src/auth/components/Login.tsx +5 -5
- package/src/auth/components/Profile.tsx +157 -0
- package/src/auth/components/Register.tsx +7 -7
- package/src/auth/components/ResetPassword.tsx +4 -4
- package/src/auth/components/VerifyEmail.tsx +3 -3
- package/src/auth/components/buttons/UserButton.tsx +35 -3
- package/src/auth/index.ts +25 -4
- package/src/core/UiRouter.ts +15 -0
- package/src/core/atoms/alephaSidebarAtom.ts +57 -0
- package/src/core/atoms/alephaThemeListAtom.ts +3 -1
- package/src/core/components/buttons/ActionButton.tsx +10 -10
- package/src/core/components/buttons/BurgerButton.tsx +5 -4
- package/src/core/components/buttons/LanguageButton.tsx +1 -1
- package/src/core/components/buttons/OmnibarButton.tsx +20 -1
- package/src/core/components/buttons/ThemeButton.tsx +1 -1
- package/src/core/components/buttons/ToggleSidebarButton.tsx +33 -23
- package/src/core/components/form/Control.tsx +1 -1
- package/src/core/components/form/ControlArray.tsx +2 -2
- package/src/core/components/form/ControlDate.tsx +1 -1
- package/src/core/components/form/ControlNumber.tsx +2 -2
- package/src/core/components/form/ControlObject.tsx +1 -1
- package/src/core/components/form/ControlQueryBuilder.tsx +1 -1
- package/src/core/components/form/ControlSelect.tsx +1 -1
- package/src/core/components/form/TypeForm.tsx +2 -2
- package/src/core/components/layout/AdminShell.tsx +236 -30
- package/src/core/components/layout/AlephaMantineProvider.tsx +3 -3
- package/src/core/components/layout/AppBar.tsx +235 -18
- package/src/core/components/layout/Omnibar.tsx +4 -4
- package/src/core/components/layout/Sidebar.tsx +43 -82
- package/src/core/components/table/DataTable.tsx +2 -2
- package/src/core/components/table/DataTableFilters.tsx +1 -1
- package/src/core/components/table/types.ts +1 -1
- package/src/core/hooks/useDialog.ts +1 -1
- package/src/core/hooks/useTheme.ts +1 -1
- package/src/core/hooks/useToast.ts +1 -1
- package/src/core/index.ts +46 -9
- package/src/core/providers/ThemeProvider.ts +1 -1
- package/src/core/styles.css +58 -0
- package/src/core/utils/parseInput.ts +1 -1
- package/src/demo/DemoRouter.ts +1 -1
- package/src/demo/components/DemoLayout.tsx +1 -1
- package/src/demo/components/core/DemoTypeForm.tsx +1 -1
- package/src/demo/components/json/DemoJsonViewer.tsx +1 -1
- package/src/demo/components/shared/Showcase.tsx +1 -1
- package/src/demo/index.ts +11 -1
- package/src/json/index.ts +13 -0
- package/dist/admin/AdminAudits-ColpiP4T.js +0 -3
- package/dist/admin/AdminAudits-DClGEVBj.js.map +0 -1
- package/dist/admin/AdminFiles-C5pqXN5B.js +0 -3
- package/dist/admin/AdminFiles-C76r1_Xz.js.map +0 -1
- package/dist/admin/AdminNotifications-BXixCBu9.js +0 -3
- package/dist/admin/AdminNotifications-Bsalygm5.js.map +0 -1
- package/dist/admin/AdminParameters-Bmxtnpv-.js.map +0 -1
- package/dist/admin/AdminSessions-CrkRvey3.js +0 -3
- package/dist/admin/AdminSessions-DmK3R6pP.js.map +0 -1
- package/dist/admin/AdminUserAudits-BPMP1Qd2.js.map +0 -1
- package/dist/admin/AdminUserCreate-CZjB6NKc.js.map +0 -1
- package/dist/admin/AdminUserDetails-DuqCOBJK.js.map +0 -1
- package/dist/admin/AdminUserLayout-Dgk8s7Cd.js.map +0 -1
- package/dist/admin/AdminUserSessions-DCpe8_T6.js.map +0 -1
- package/dist/admin/AdminUserSessions-beiJqY2D.js +0 -3
- package/dist/admin/AdminUserSettings-CxlInVnu.js +0 -3
- package/dist/admin/AdminUserSettings-qxDfowqh.js.map +0 -1
- package/dist/admin/AdminUsers-Bd0wMP8v.js +0 -3
- package/dist/admin/AdminUsers-ZlPsDz0T.js.map +0 -1
- package/dist/auth/AuthLayout-CWzQ8rCe.js.map +0 -1
- package/dist/auth/Login-CxOPyNFP.js +0 -4
- package/dist/auth/Login-CyvKwy5e.js.map +0 -1
- package/dist/auth/Register-C7Zp09Ks.js.map +0 -1
- package/dist/auth/Register-Cacr7YbA.js +0 -4
- package/dist/auth/ResetPassword-CMkx8Ibf.js +0 -3
- package/dist/auth/ResetPassword-DYJSUC6B.js.map +0 -1
- package/dist/auth/VerifyEmail-CNXFIwWW.js.map +0 -1
- package/dist/auth/VerifyEmail-DKyDlz96.js +0 -3
- package/dist/demo/DemoJsonViewer-DbWVDdz_.js +0 -4
- package/dist/demo/DemoLayout-DjIDm93B.js.map +0 -1
- package/dist/demo/DemoLayout-nNMajP_9.js +0 -3
- package/dist/demo/DemoLogin-BA_HiIRZ.js.map +0 -1
- package/dist/demo/DemoRegister-B6syaxP9.js.map +0 -1
- package/dist/demo/DemoResetPassword-BOcLG4GF.js.map +0 -1
- package/dist/demo/DemoTypeForm-BlLAcQqZ.js.map +0 -1
- package/dist/demo/DemoVerifyEmail-C-J7bXUQ.js.map +0 -1
- package/dist/demo/Showcase-HchhcsHV.js.map +0 -1
- package/src/core/RootRouter.ts +0 -9
|
@@ -1,15 +1,16 @@
|
|
|
1
|
-
import { useStore } from "@alepha/react";
|
|
2
1
|
import { Burger, type BurgerProps } from "@mantine/core";
|
|
2
|
+
import { useStore } from "alepha/react";
|
|
3
|
+
import { alephaSidebarAtom } from "../../atoms/alephaSidebarAtom.ts";
|
|
3
4
|
|
|
4
5
|
export interface BurgerButtonProps extends BurgerProps {}
|
|
5
6
|
|
|
6
7
|
const BurgerButton = (props: BurgerButtonProps) => {
|
|
7
|
-
const [
|
|
8
|
+
const [sidebar, setSidebar] = useStore(alephaSidebarAtom);
|
|
8
9
|
|
|
9
10
|
return (
|
|
10
11
|
<Burger
|
|
11
|
-
opened={opened}
|
|
12
|
-
onClick={() =>
|
|
12
|
+
opened={sidebar.opened}
|
|
13
|
+
onClick={() => setSidebar({ ...sidebar, opened: !sidebar.opened })}
|
|
13
14
|
hiddenFrom="sm"
|
|
14
15
|
size="sm"
|
|
15
16
|
{...props}
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Flex, Kbd, Text } from "@mantine/core";
|
|
2
|
+
import { useOs } from "@mantine/hooks";
|
|
2
3
|
import { spotlight } from "@mantine/spotlight";
|
|
3
4
|
import { IconSearch } from "@tabler/icons-react";
|
|
5
|
+
import { ClientOnly } from "alepha/react";
|
|
4
6
|
import ActionButton, { type ActionProps } from "./ActionButton.tsx";
|
|
5
7
|
|
|
6
8
|
export interface OmnibarButtonProps {
|
|
@@ -9,6 +11,23 @@ export interface OmnibarButtonProps {
|
|
|
9
11
|
}
|
|
10
12
|
|
|
11
13
|
const OmnibarButton = (props: OmnibarButtonProps) => {
|
|
14
|
+
const os = useOs();
|
|
15
|
+
const isMac = os === "macos" || os === "ios";
|
|
16
|
+
const shortcut = isMac ? "⌘" : "Ctrl";
|
|
17
|
+
|
|
18
|
+
if (props.collapsed) {
|
|
19
|
+
return (
|
|
20
|
+
<ActionButton
|
|
21
|
+
variant={"subtle"}
|
|
22
|
+
onClick={spotlight.open}
|
|
23
|
+
radius={"md"}
|
|
24
|
+
icon={<IconSearch size={16} />}
|
|
25
|
+
tooltip={{ label: "Search", position: "right" }}
|
|
26
|
+
{...props.actionProps}
|
|
27
|
+
/>
|
|
28
|
+
);
|
|
29
|
+
}
|
|
30
|
+
|
|
12
31
|
return (
|
|
13
32
|
<ActionButton
|
|
14
33
|
variant={"default"}
|
|
@@ -16,7 +35,7 @@ const OmnibarButton = (props: OmnibarButtonProps) => {
|
|
|
16
35
|
justify={"space-between"}
|
|
17
36
|
rightSection={
|
|
18
37
|
<Kbd visibleFrom={"sm"} size={"sm"}>
|
|
19
|
-
|
|
38
|
+
<ClientOnly>{shortcut}</ClientOnly>+K
|
|
20
39
|
</Kbd>
|
|
21
40
|
}
|
|
22
41
|
radius={"md"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { useStore } from "@alepha/react";
|
|
2
1
|
import { IconPalette } from "@tabler/icons-react";
|
|
2
|
+
import { useStore } from "alepha/react";
|
|
3
3
|
import { alephaThemeListAtom } from "../../atoms/alephaThemeListAtom.ts";
|
|
4
4
|
import { useTheme } from "../../hooks/useTheme.ts";
|
|
5
5
|
import ActionButton, { type ActionProps } from "./ActionButton.tsx";
|
|
@@ -1,33 +1,43 @@
|
|
|
1
|
-
import { useStore } from "@alepha/react";
|
|
2
|
-
import { Flex } from "@mantine/core";
|
|
3
1
|
import {
|
|
4
2
|
IconLayoutSidebarLeftCollapse,
|
|
5
3
|
IconLayoutSidebarRightCollapse,
|
|
6
4
|
} from "@tabler/icons-react";
|
|
7
|
-
import
|
|
5
|
+
import { useStore } from "alepha/react";
|
|
6
|
+
import { alephaSidebarAtom } from "../../atoms/alephaSidebarAtom.ts";
|
|
7
|
+
import ActionButton, { type ActionProps } from "./ActionButton.tsx";
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
type Props = ActionProps;
|
|
10
|
+
|
|
11
|
+
const ToggleSidebarButton = (props: Props) => {
|
|
12
|
+
const [sidebar, setSidebar] = useStore(alephaSidebarAtom);
|
|
11
13
|
|
|
12
14
|
return (
|
|
13
|
-
<
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
15
|
+
<ActionButton
|
|
16
|
+
icon={
|
|
17
|
+
sidebar.collapsed ? (
|
|
18
|
+
<IconLayoutSidebarRightCollapse />
|
|
19
|
+
) : (
|
|
20
|
+
<IconLayoutSidebarLeftCollapse />
|
|
21
|
+
)
|
|
22
|
+
}
|
|
23
|
+
visibleFrom={"sm"}
|
|
24
|
+
variant={"subtle"}
|
|
25
|
+
size={"md"}
|
|
26
|
+
onClick={() => {
|
|
27
|
+
const expanding = sidebar.collapsed;
|
|
28
|
+
setSidebar({
|
|
29
|
+
...sidebar,
|
|
30
|
+
collapsed: !sidebar.collapsed,
|
|
31
|
+
// Reset width to defaultWidth when expanding
|
|
32
|
+
width: expanding ? sidebar.defaultWidth : sidebar.width,
|
|
33
|
+
});
|
|
34
|
+
}}
|
|
35
|
+
tooltip={{
|
|
36
|
+
position: "right",
|
|
37
|
+
label: sidebar.collapsed ? "Show sidebar" : "Hide sidebar",
|
|
38
|
+
}}
|
|
39
|
+
{...props}
|
|
40
|
+
/>
|
|
31
41
|
);
|
|
32
42
|
};
|
|
33
43
|
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useFormState } from "@alepha/react/form";
|
|
2
1
|
import {
|
|
3
2
|
ColorInput,
|
|
4
3
|
type ColorInputProps,
|
|
@@ -20,6 +19,7 @@ import type {
|
|
|
20
19
|
DateTimePickerProps,
|
|
21
20
|
TimeInputProps,
|
|
22
21
|
} from "@mantine/dates";
|
|
22
|
+
import { useFormState } from "alepha/react/form";
|
|
23
23
|
import type { ComponentType } from "react";
|
|
24
24
|
import {
|
|
25
25
|
type GenericControlProps,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { useEvents } from "@alepha/react";
|
|
2
|
-
import type { BaseInputField } from "@alepha/react/form";
|
|
3
1
|
import {
|
|
4
2
|
ActionIcon,
|
|
5
3
|
Fieldset,
|
|
@@ -11,6 +9,8 @@ import {
|
|
|
11
9
|
} from "@mantine/core";
|
|
12
10
|
import { IconGripVertical, IconPlus, IconTrash } from "@tabler/icons-react";
|
|
13
11
|
import type { TObject, TSchema } from "alepha";
|
|
12
|
+
import { useEvents } from "alepha/react";
|
|
13
|
+
import type { BaseInputField } from "alepha/react/form";
|
|
14
14
|
import { useRef, useState } from "react";
|
|
15
15
|
import { ui } from "../../constants/ui.ts";
|
|
16
16
|
import {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useFormState } from "@alepha/react/form";
|
|
2
1
|
import {
|
|
3
2
|
DateInput,
|
|
4
3
|
type DateInputProps,
|
|
@@ -7,6 +6,7 @@ import {
|
|
|
7
6
|
TimeInput,
|
|
8
7
|
type TimeInputProps,
|
|
9
8
|
} from "@mantine/dates";
|
|
9
|
+
import { useFormState } from "alepha/react/form";
|
|
10
10
|
import {
|
|
11
11
|
type GenericControlProps,
|
|
12
12
|
parseInput,
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { useEvents } from "@alepha/react";
|
|
2
|
-
import { useFormState } from "@alepha/react/form";
|
|
3
1
|
import {
|
|
4
2
|
Input,
|
|
5
3
|
NumberInput,
|
|
@@ -7,6 +5,8 @@ import {
|
|
|
7
5
|
Slider,
|
|
8
6
|
type SliderProps,
|
|
9
7
|
} from "@mantine/core";
|
|
8
|
+
import { useEvents } from "alepha/react";
|
|
9
|
+
import { useFormState } from "alepha/react/form";
|
|
10
10
|
import { useRef, useState } from "react";
|
|
11
11
|
import {
|
|
12
12
|
type GenericControlProps,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BaseInputField, ObjectInputField } from "@alepha/react/form";
|
|
2
1
|
import { Fieldset, Grid, Stack, Text } from "@mantine/core";
|
|
3
2
|
import type { TObject } from "alepha";
|
|
3
|
+
import type { BaseInputField, ObjectInputField } from "alepha/react/form";
|
|
4
4
|
import {
|
|
5
5
|
type GenericControlProps,
|
|
6
6
|
parseInput,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useEvents } from "@alepha/react";
|
|
2
1
|
import {
|
|
3
2
|
ActionIcon,
|
|
4
3
|
Badge,
|
|
@@ -14,6 +13,7 @@ import {
|
|
|
14
13
|
import { IconFilter, IconInfoTriangle, IconX } from "@tabler/icons-react";
|
|
15
14
|
import type { TObject } from "alepha";
|
|
16
15
|
import { parseQueryString } from "alepha/orm";
|
|
16
|
+
import { useEvents } from "alepha/react";
|
|
17
17
|
import { useRef, useState } from "react";
|
|
18
18
|
import { ui } from "../../constants/ui.ts";
|
|
19
19
|
import {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { useFormState } from "@alepha/react/form";
|
|
2
1
|
import {
|
|
3
2
|
Autocomplete,
|
|
4
3
|
type AutocompleteProps,
|
|
@@ -13,6 +12,7 @@ import {
|
|
|
13
12
|
TagsInput,
|
|
14
13
|
type TagsInputProps,
|
|
15
14
|
} from "@mantine/core";
|
|
15
|
+
import { useFormState } from "alepha/react/form";
|
|
16
16
|
import { useEffect, useState } from "react";
|
|
17
17
|
import {
|
|
18
18
|
type GenericControlProps,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { FormModel } from "@alepha/react/form";
|
|
2
1
|
import { Card, Flex, type FlexProps, Grid } from "@mantine/core";
|
|
3
2
|
import type { TObject } from "alepha";
|
|
3
|
+
import type { FormModel } from "alepha/react/form";
|
|
4
4
|
import type { ReactNode } from "react";
|
|
5
5
|
import ActionButton, {
|
|
6
6
|
type ActionSubmitButtonProps,
|
|
@@ -55,7 +55,7 @@ export interface TypeFormProps<T extends TObject> {
|
|
|
55
55
|
* @example
|
|
56
56
|
* ```tsx
|
|
57
57
|
* import { t } from "alepha";
|
|
58
|
-
* import { useForm } from "
|
|
58
|
+
* import { useForm } from "alepha/react/form";
|
|
59
59
|
* import { TypeForm } from "@alepha/ui";
|
|
60
60
|
*
|
|
61
61
|
* const form = useForm({
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
import { useEvents, useStore } from "@alepha/react";
|
|
2
|
-
import { NestedView, useRouter } from "@alepha/react/router";
|
|
3
1
|
import {
|
|
4
2
|
AppShell,
|
|
5
3
|
type AppShellFooterProps,
|
|
@@ -7,8 +5,20 @@ import {
|
|
|
7
5
|
type AppShellMainProps,
|
|
8
6
|
type AppShellNavbarProps,
|
|
9
7
|
type AppShellProps,
|
|
8
|
+
Container,
|
|
9
|
+
type ContainerProps,
|
|
10
|
+
Flex,
|
|
10
11
|
} from "@mantine/core";
|
|
11
|
-
import {
|
|
12
|
+
import { useEvents, useStore } from "alepha/react";
|
|
13
|
+
import { NestedView, useRouter } from "alepha/react/router";
|
|
14
|
+
import {
|
|
15
|
+
type ReactNode,
|
|
16
|
+
useCallback,
|
|
17
|
+
useEffect,
|
|
18
|
+
useRef,
|
|
19
|
+
useState,
|
|
20
|
+
} from "react";
|
|
21
|
+
import { alephaSidebarAtom } from "../../atoms/alephaSidebarAtom.ts";
|
|
12
22
|
import { ui } from "../../constants/ui.ts";
|
|
13
23
|
import AppBar, { type AppBarProps } from "./AppBar.tsx";
|
|
14
24
|
import { Sidebar, type SidebarProps } from "./Sidebar.tsx";
|
|
@@ -25,36 +35,163 @@ export interface AdminShellProps {
|
|
|
25
35
|
footer?: ReactNode;
|
|
26
36
|
children?: ReactNode;
|
|
27
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Enable drag-to-resize for the sidebar.
|
|
40
|
+
* Width and constraints are configured in alephaSidebarAtom.
|
|
41
|
+
*/
|
|
42
|
+
sidebarResizable?: boolean;
|
|
43
|
+
|
|
28
44
|
noSidebarWhen?: {
|
|
29
45
|
/**
|
|
30
46
|
* Paths where the sidebar should be hidden.
|
|
31
47
|
*/
|
|
32
48
|
paths?: string[];
|
|
33
49
|
};
|
|
34
|
-
}
|
|
35
50
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
"alepha.ui.sidebar.opened"?: boolean;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Whether the sidebar is collapsed (narrow) or expanded (wide).
|
|
45
|
-
*/
|
|
46
|
-
"alepha.ui.sidebar.collapsed"?: boolean;
|
|
47
|
-
}
|
|
51
|
+
/**
|
|
52
|
+
* Wrap AppBar and main content in a Mantine Container.
|
|
53
|
+
* Pass `true` for default Container, or ContainerProps to customize.
|
|
54
|
+
*/
|
|
55
|
+
container?: boolean | ContainerProps;
|
|
48
56
|
}
|
|
49
57
|
|
|
50
58
|
const AdminShell = (props: AdminShellProps) => {
|
|
51
59
|
const router = useRouter();
|
|
52
|
-
const [
|
|
53
|
-
const
|
|
54
|
-
|
|
55
|
-
|
|
60
|
+
const [sidebar, setSidebar] = useStore(alephaSidebarAtom);
|
|
61
|
+
const { opened, collapsed } = sidebar;
|
|
62
|
+
|
|
63
|
+
// Initialize collapsed state from props on mount
|
|
64
|
+
useEffect(() => {
|
|
65
|
+
if (props.sidebarProps?.collapsed !== undefined) {
|
|
66
|
+
setSidebar({ ...sidebar, collapsed: props.sidebarProps.collapsed });
|
|
67
|
+
}
|
|
68
|
+
}, []);
|
|
69
|
+
|
|
70
|
+
// Resize state
|
|
71
|
+
const [isResizing, setIsResizing] = useState(false);
|
|
72
|
+
const [isHovering, setIsHovering] = useState(false);
|
|
73
|
+
const [collapseEffect, setCollapseEffect] = useState({
|
|
74
|
+
offset: 0,
|
|
75
|
+
opacity: 1,
|
|
76
|
+
});
|
|
77
|
+
const resizeRef = useRef<{ startX: number; startWidth: number } | null>(null);
|
|
78
|
+
|
|
79
|
+
// Use atom values for constraints
|
|
80
|
+
const {
|
|
81
|
+
collapsedWidth,
|
|
82
|
+
collapseThreshold,
|
|
83
|
+
maxWidth,
|
|
84
|
+
hoverDelay,
|
|
85
|
+
defaultWidth,
|
|
86
|
+
} = sidebar;
|
|
87
|
+
|
|
88
|
+
const handleResizeStart = useCallback(
|
|
89
|
+
(e: React.MouseEvent) => {
|
|
90
|
+
if (!props.sidebarResizable) return;
|
|
91
|
+
e.preventDefault();
|
|
92
|
+
|
|
93
|
+
// If collapsed and hovering, un-collapse first and start from defaultWidth
|
|
94
|
+
if (collapsed) {
|
|
95
|
+
setSidebar({ ...sidebar, collapsed: false, width: defaultWidth });
|
|
96
|
+
setIsResizing(true);
|
|
97
|
+
resizeRef.current = {
|
|
98
|
+
startX: e.clientX,
|
|
99
|
+
startWidth: defaultWidth,
|
|
100
|
+
};
|
|
101
|
+
} else {
|
|
102
|
+
setIsResizing(true);
|
|
103
|
+
resizeRef.current = {
|
|
104
|
+
startX: e.clientX,
|
|
105
|
+
startWidth: sidebar.width,
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
},
|
|
109
|
+
[props.sidebarResizable, collapsed, sidebar, setSidebar, defaultWidth],
|
|
56
110
|
);
|
|
57
111
|
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (!isResizing) return;
|
|
114
|
+
|
|
115
|
+
const handleMouseMove = (e: MouseEvent) => {
|
|
116
|
+
if (!resizeRef.current) return;
|
|
117
|
+
const delta = e.clientX - resizeRef.current.startX;
|
|
118
|
+
const rawWidth = resizeRef.current.startWidth + delta;
|
|
119
|
+
const newWidth = Math.min(Math.max(rawWidth, collapsedWidth), maxWidth);
|
|
120
|
+
|
|
121
|
+
// Visual effect when below collapse threshold
|
|
122
|
+
if (rawWidth < collapseThreshold) {
|
|
123
|
+
const progress = Math.max(
|
|
124
|
+
0,
|
|
125
|
+
(collapseThreshold - rawWidth) / collapseThreshold,
|
|
126
|
+
);
|
|
127
|
+
setCollapseEffect({
|
|
128
|
+
offset: -progress * collapsedWidth,
|
|
129
|
+
opacity: 1 - progress * 0.7,
|
|
130
|
+
});
|
|
131
|
+
setSidebar({ ...sidebar, width: collapseThreshold, collapsed: false });
|
|
132
|
+
} else {
|
|
133
|
+
setCollapseEffect({ offset: 0, opacity: 1 });
|
|
134
|
+
setSidebar({ ...sidebar, width: newWidth, collapsed: false });
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
const handleMouseUp = () => {
|
|
139
|
+
// If we released while in collapse zone, actually collapse
|
|
140
|
+
if (collapseEffect.offset < 0) {
|
|
141
|
+
setSidebar({ ...sidebar, collapsed: true });
|
|
142
|
+
}
|
|
143
|
+
setCollapseEffect({ offset: 0, opacity: 1 });
|
|
144
|
+
setIsResizing(false);
|
|
145
|
+
resizeRef.current = null;
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
document.addEventListener("mousemove", handleMouseMove);
|
|
149
|
+
document.addEventListener("mouseup", handleMouseUp);
|
|
150
|
+
|
|
151
|
+
return () => {
|
|
152
|
+
document.removeEventListener("mousemove", handleMouseMove);
|
|
153
|
+
document.removeEventListener("mouseup", handleMouseUp);
|
|
154
|
+
};
|
|
155
|
+
}, [
|
|
156
|
+
isResizing,
|
|
157
|
+
sidebar,
|
|
158
|
+
setSidebar,
|
|
159
|
+
collapsedWidth,
|
|
160
|
+
maxWidth,
|
|
161
|
+
collapseThreshold,
|
|
162
|
+
collapseEffect.offset,
|
|
163
|
+
]);
|
|
164
|
+
|
|
165
|
+
// Hover to expand when collapsed (with delay)
|
|
166
|
+
const hoverTimeoutRef = useRef<ReturnType<typeof setTimeout> | null>(null);
|
|
167
|
+
|
|
168
|
+
const handleNavbarMouseEnter = useCallback(() => {
|
|
169
|
+
if (collapsed) {
|
|
170
|
+
hoverTimeoutRef.current = setTimeout(() => {
|
|
171
|
+
setIsHovering(true);
|
|
172
|
+
}, hoverDelay);
|
|
173
|
+
}
|
|
174
|
+
}, [collapsed, hoverDelay]);
|
|
175
|
+
|
|
176
|
+
const handleNavbarMouseLeave = useCallback(() => {
|
|
177
|
+
if (hoverTimeoutRef.current) {
|
|
178
|
+
clearTimeout(hoverTimeoutRef.current);
|
|
179
|
+
hoverTimeoutRef.current = null;
|
|
180
|
+
}
|
|
181
|
+
setIsHovering(false);
|
|
182
|
+
}, []);
|
|
183
|
+
|
|
184
|
+
// Reset hover state when collapsed changes (e.g., when toggle button is clicked)
|
|
185
|
+
useEffect(() => {
|
|
186
|
+
if (collapsed) {
|
|
187
|
+
setIsHovering(false);
|
|
188
|
+
if (hoverTimeoutRef.current) {
|
|
189
|
+
clearTimeout(hoverTimeoutRef.current);
|
|
190
|
+
hoverTimeoutRef.current = null;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}, [collapsed]);
|
|
194
|
+
|
|
58
195
|
const shouldShowSidebar = () => {
|
|
59
196
|
if (props.noSidebarWhen?.paths) {
|
|
60
197
|
for (const path of props.noSidebarWhen.paths) {
|
|
@@ -78,10 +215,10 @@ const AdminShell = (props: AdminShellProps) => {
|
|
|
78
215
|
setShowSidebar(shouldShowSidebar());
|
|
79
216
|
},
|
|
80
217
|
"react:transition:begin": () => {
|
|
81
|
-
|
|
218
|
+
setSidebar({ ...sidebar, opened: false });
|
|
82
219
|
},
|
|
83
220
|
},
|
|
84
|
-
[],
|
|
221
|
+
[sidebar],
|
|
85
222
|
);
|
|
86
223
|
|
|
87
224
|
// Default AppBar items with burger button on the left
|
|
@@ -89,12 +226,28 @@ const AdminShell = (props: AdminShellProps) => {
|
|
|
89
226
|
{ position: "left" as const, type: "burger" as const },
|
|
90
227
|
];
|
|
91
228
|
|
|
229
|
+
// Forward container to appBarProps if not already set
|
|
230
|
+
const appBarProps = { ...props.appBarProps };
|
|
231
|
+
appBarProps.container ??= props.container;
|
|
232
|
+
|
|
92
233
|
const hasSidebar = showSidebar && props.sidebarProps !== undefined;
|
|
93
234
|
const hasAppBar = hasSidebar || props.appBarProps || props.header;
|
|
94
235
|
|
|
95
236
|
const headerHeight = hasAppBar ? 60 : 0;
|
|
96
237
|
const footerHeight = props.footer ? 24 : 0;
|
|
97
|
-
const
|
|
238
|
+
const expandedWidth = Math.max(sidebar.width, collapsedWidth);
|
|
239
|
+
|
|
240
|
+
// When collapsed but hovering, show defaultWidth (not current width)
|
|
241
|
+
const isExpandedByHover = collapsed && isHovering;
|
|
242
|
+
const effectiveCollapsed = collapsed && !isHovering;
|
|
243
|
+
const hoverWidth = Math.max(defaultWidth, collapsedWidth);
|
|
244
|
+
// When hovering, keep main content at collapsed width (sidebar overlays)
|
|
245
|
+
const sidebarWidth = hasSidebar
|
|
246
|
+
? effectiveCollapsed || isExpandedByHover
|
|
247
|
+
? collapsedWidth
|
|
248
|
+
: expandedWidth
|
|
249
|
+
: 0;
|
|
250
|
+
const canResize = props.sidebarResizable && !collapsed;
|
|
98
251
|
|
|
99
252
|
return (
|
|
100
253
|
<AppShell
|
|
@@ -105,7 +258,11 @@ const AdminShell = (props: AdminShellProps) => {
|
|
|
105
258
|
navbar={
|
|
106
259
|
hasSidebar
|
|
107
260
|
? {
|
|
108
|
-
|
|
261
|
+
// When hovering, keep collapsed width to avoid pushing content
|
|
262
|
+
width:
|
|
263
|
+
effectiveCollapsed || isExpandedByHover
|
|
264
|
+
? { base: collapsedWidth }
|
|
265
|
+
: { base: expandedWidth },
|
|
109
266
|
breakpoint: "sm",
|
|
110
267
|
collapsed: { mobile: !opened },
|
|
111
268
|
}
|
|
@@ -115,14 +272,49 @@ const AdminShell = (props: AdminShellProps) => {
|
|
|
115
272
|
{...props.appShellProps}
|
|
116
273
|
>
|
|
117
274
|
<AppShell.Header bg={ui.colors.surface} {...props.appShellHeaderProps}>
|
|
118
|
-
{props.header ??
|
|
119
|
-
<AppBar items={defaultAppBarItems} {...props.appBarProps} />
|
|
120
|
-
)}
|
|
275
|
+
{props.header ?? <AppBar items={defaultAppBarItems} {...appBarProps} />}
|
|
121
276
|
</AppShell.Header>
|
|
122
277
|
|
|
123
278
|
{hasSidebar && (
|
|
124
|
-
<AppShell.Navbar
|
|
125
|
-
|
|
279
|
+
<AppShell.Navbar
|
|
280
|
+
bg={ui.colors.surface}
|
|
281
|
+
className="alepha-sidebar-navbar"
|
|
282
|
+
data-resizing={isResizing}
|
|
283
|
+
data-hover-expanded={isExpandedByHover}
|
|
284
|
+
onMouseEnter={handleNavbarMouseEnter}
|
|
285
|
+
onMouseLeave={handleNavbarMouseLeave}
|
|
286
|
+
style={{
|
|
287
|
+
transform: collapseEffect.offset
|
|
288
|
+
? `translateX(${collapseEffect.offset}px)`
|
|
289
|
+
: undefined,
|
|
290
|
+
opacity: collapseEffect.opacity,
|
|
291
|
+
// When hovering, expand width visually as overlay
|
|
292
|
+
...(isExpandedByHover && {
|
|
293
|
+
width: hoverWidth,
|
|
294
|
+
zIndex: 200,
|
|
295
|
+
boxShadow: "var(--mantine-shadow-xl)",
|
|
296
|
+
}),
|
|
297
|
+
}}
|
|
298
|
+
{...props.appShellNavbarProps}
|
|
299
|
+
>
|
|
300
|
+
<Sidebar
|
|
301
|
+
{...(props.sidebarProps ?? {})}
|
|
302
|
+
collapsed={effectiveCollapsed}
|
|
303
|
+
/>
|
|
304
|
+
{(canResize || isExpandedByHover) && (
|
|
305
|
+
<Flex
|
|
306
|
+
pos="absolute"
|
|
307
|
+
right={-6}
|
|
308
|
+
top={0}
|
|
309
|
+
bottom={0}
|
|
310
|
+
w={12}
|
|
311
|
+
style={{
|
|
312
|
+
cursor: "col-resize",
|
|
313
|
+
userSelect: "none",
|
|
314
|
+
}}
|
|
315
|
+
onMouseDown={handleResizeStart}
|
|
316
|
+
/>
|
|
317
|
+
)}
|
|
126
318
|
</AppShell.Navbar>
|
|
127
319
|
)}
|
|
128
320
|
|
|
@@ -134,9 +326,23 @@ const AdminShell = (props: AdminShellProps) => {
|
|
|
134
326
|
display={"flex"}
|
|
135
327
|
flex={1}
|
|
136
328
|
style={{ flexDirection: "column" }}
|
|
329
|
+
className="alepha-sidebar-main"
|
|
330
|
+
data-resizing={isResizing}
|
|
137
331
|
{...props.appShellMainProps}
|
|
138
332
|
>
|
|
139
|
-
{props.
|
|
333
|
+
{props.container ? (
|
|
334
|
+
<Container
|
|
335
|
+
w={"100%"}
|
|
336
|
+
flex={1}
|
|
337
|
+
display="flex"
|
|
338
|
+
style={{ flexDirection: "column" }}
|
|
339
|
+
{...(typeof props.container === "boolean" ? {} : props.container)}
|
|
340
|
+
>
|
|
341
|
+
{props.children ?? <NestedView />}
|
|
342
|
+
</Container>
|
|
343
|
+
) : (
|
|
344
|
+
(props.children ?? <NestedView />)
|
|
345
|
+
)}
|
|
140
346
|
</AppShell.Main>
|
|
141
347
|
|
|
142
348
|
{props.footer && (
|
|
@@ -1,6 +1,3 @@
|
|
|
1
|
-
import { useEvents } from "@alepha/react";
|
|
2
|
-
import { FormValidationError } from "@alepha/react/form";
|
|
3
|
-
import { NestedView } from "@alepha/react/router";
|
|
4
1
|
import {
|
|
5
2
|
ColorSchemeScript,
|
|
6
3
|
type ColorSchemeScriptProps,
|
|
@@ -12,6 +9,9 @@ import { Notifications, type NotificationsProps } from "@mantine/notifications";
|
|
|
12
9
|
import type { NavigationProgressProps } from "@mantine/nprogress";
|
|
13
10
|
import { NavigationProgress, nprogress } from "@mantine/nprogress";
|
|
14
11
|
import { TypeBoxError } from "alepha";
|
|
12
|
+
import { useEvents } from "alepha/react";
|
|
13
|
+
import { FormValidationError } from "alepha/react/form";
|
|
14
|
+
import { NestedView } from "alepha/react/router";
|
|
15
15
|
import type { ReactNode } from "react";
|
|
16
16
|
import { useTheme } from "../../hooks/useTheme.ts";
|
|
17
17
|
import { useToast } from "../../hooks/useToast.ts";
|