@jameskabz/nextcraft-ui 0.7.2 → 0.7.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/components/craft-create-edit-drawer.cjs +5 -2
- package/dist/components/craft-create-edit-drawer.cjs.map +1 -1
- package/dist/components/craft-create-edit-drawer.d.cts +2 -1
- package/dist/components/craft-create-edit-drawer.d.ts +2 -1
- package/dist/components/craft-create-edit-drawer.js +5 -2
- package/dist/components/craft-create-edit-drawer.js.map +1 -1
- package/dist/components/craft-icon.cjs +15 -9
- package/dist/components/craft-icon.cjs.map +1 -1
- package/dist/components/craft-icon.d.cts +1 -1
- package/dist/components/craft-icon.d.ts +1 -1
- package/dist/components/craft-icon.js +15 -9
- package/dist/components/craft-icon.js.map +1 -1
- package/dist/components/layout/app-shell.cjs +5 -5
- package/dist/components/layout/app-shell.cjs.map +1 -1
- package/dist/components/layout/app-shell.js +5 -5
- package/dist/components/layout/app-shell.js.map +1 -1
- package/dist/components/layout/app-template.cjs +21 -1
- package/dist/components/layout/app-template.cjs.map +1 -1
- package/dist/components/layout/app-template.d.cts +7 -1
- package/dist/components/layout/app-template.d.ts +7 -1
- package/dist/components/layout/app-template.js +21 -1
- package/dist/components/layout/app-template.js.map +1 -1
- package/dist/components/layout/breadcrumbs.cjs +17 -7
- package/dist/components/layout/breadcrumbs.cjs.map +1 -1
- package/dist/components/layout/breadcrumbs.js +17 -7
- package/dist/components/layout/breadcrumbs.js.map +1 -1
- package/dist/components/layout/sidebar.cjs +107 -10
- package/dist/components/layout/sidebar.cjs.map +1 -1
- package/dist/components/layout/sidebar.d.cts +7 -1
- package/dist/components/layout/sidebar.d.ts +7 -1
- package/dist/components/layout/sidebar.js +97 -10
- package/dist/components/layout/sidebar.js.map +1 -1
- package/dist/components/layout/top-nav.cjs +18 -6
- package/dist/components/layout/top-nav.cjs.map +1 -1
- package/dist/components/layout/top-nav.d.cts +3 -1
- package/dist/components/layout/top-nav.d.ts +3 -1
- package/dist/components/layout/top-nav.js +18 -6
- package/dist/components/layout/top-nav.js.map +1 -1
- package/dist/styles.css +155 -8
- package/package.json +1 -1
|
@@ -56,7 +56,8 @@ function CraftCreateEditDrawer({
|
|
|
56
56
|
footer,
|
|
57
57
|
disableSubmitWhenInvalid = true,
|
|
58
58
|
closeOnSubmit = true,
|
|
59
|
-
side = "right"
|
|
59
|
+
side = "right",
|
|
60
|
+
loading
|
|
60
61
|
}) {
|
|
61
62
|
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
|
|
62
63
|
const isControlled = typeof open === "boolean";
|
|
@@ -69,7 +70,8 @@ function CraftCreateEditDrawer({
|
|
|
69
70
|
[isControlled, onOpenChange]
|
|
70
71
|
);
|
|
71
72
|
const formId = React.useId();
|
|
72
|
-
const
|
|
73
|
+
const isSubmitting = loading != null ? loading : form.formState.isSubmitting;
|
|
74
|
+
const isSubmitDisabled = isSubmitting || disableSubmitWhenInvalid && !form.formState.isValid;
|
|
73
75
|
const handleSubmit = form.handleSubmit(async (values) => {
|
|
74
76
|
await onSubmit(values);
|
|
75
77
|
if (closeOnSubmit) setOpen(false);
|
|
@@ -85,6 +87,7 @@ function CraftCreateEditDrawer({
|
|
|
85
87
|
variant: "solid",
|
|
86
88
|
form: formId,
|
|
87
89
|
disabled: isSubmitDisabled,
|
|
90
|
+
loading: isSubmitting,
|
|
88
91
|
children: resolvedSubmitLabel
|
|
89
92
|
}
|
|
90
93
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/craft-create-edit-drawer.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { FormProvider, type FieldValues, type UseFormReturn } from \"react-hook-form\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\nimport { CraftDrawer } from \"@/components/craft-drawer\";\nimport { CraftButton } from \"@/components/craft-button\";\n\nexport type CraftCreateEditDrawerProps<TValues extends FieldValues> = {\n mode?: \"create\" | \"edit\";\n form: UseFormReturn<TValues>;\n onSubmit: (values: TValues) => void | Promise<void>;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: React.ReactNode;\n title?: React.ReactNode;\n description?: React.ReactNode;\n submitLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n tone?: ThemeName;\n className?: string;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n disableSubmitWhenInvalid?: boolean;\n closeOnSubmit?: boolean;\n side?: \"left\" | \"right\";\n};\n\nexport function CraftCreateEditDrawer<TValues extends FieldValues>({\n mode = \"create\",\n form,\n onSubmit,\n open,\n defaultOpen = false,\n onOpenChange,\n trigger,\n title,\n description,\n submitLabel,\n cancelLabel = \"Cancel\",\n tone,\n className,\n children,\n footer,\n disableSubmitWhenInvalid = true,\n closeOnSubmit = true,\n side = \"right\",\n}: CraftCreateEditDrawerProps<TValues>) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);\n const isControlled = typeof open === \"boolean\";\n const isOpen = isControlled ? open : uncontrolledOpen;\n\n const setOpen = React.useCallback(\n (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange]\n );\n\n const formId = React.useId();\n const isSubmitDisabled =\n disableSubmitWhenInvalid && !form.formState.isValid;\n\n const handleSubmit = form.handleSubmit(async (values) => {\n await onSubmit(values);\n if (closeOnSubmit) setOpen(false);\n });\n\n const resolvedTitle = title ?? (mode === \"create\" ? \"Create item\" : \"Edit item\");\n const resolvedSubmitLabel =\n submitLabel ?? (mode === \"create\" ? \"Create\" : \"Save changes\");\n\n const footerContent = footer ?? (\n <div className=\"flex flex-wrap items-center justify-end gap-3\">\n <CraftButton type=\"button\" variant=\"ghost\" onClick={() => setOpen(false)}>\n {cancelLabel}\n </CraftButton>\n <CraftButton\n type=\"submit\"\n variant=\"solid\"\n form={formId}\n disabled={isSubmitDisabled}\n >\n {resolvedSubmitLabel}\n </CraftButton>\n </div>\n );\n\n return (\n <FormProvider {...form}>\n <CraftDrawer\n open={isOpen}\n onOpenChange={setOpen}\n trigger={trigger}\n title={resolvedTitle}\n tone={tone}\n side={side}\n className={cn(\"flex flex-col\", className)}\n footer={footerContent}\n >\n <form id={formId} onSubmit={handleSubmit} className=\"space-y-5\">\n {description && (\n <p className=\"text-sm text-[rgb(var(--nc-fg-muted))]\">\n {description}\n </p>\n )}\n {children}\n </form>\n </CraftDrawer>\n </FormProvider>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../src/components/craft-create-edit-drawer.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { FormProvider, type FieldValues, type UseFormReturn } from \"react-hook-form\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\nimport { CraftDrawer } from \"@/components/craft-drawer\";\nimport { CraftButton } from \"@/components/craft-button\";\n\nexport type CraftCreateEditDrawerProps<TValues extends FieldValues> = {\n mode?: \"create\" | \"edit\";\n form: UseFormReturn<TValues>;\n onSubmit: (values: TValues) => void | Promise<void>;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: React.ReactNode;\n title?: React.ReactNode;\n description?: React.ReactNode;\n submitLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n tone?: ThemeName;\n className?: string;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n disableSubmitWhenInvalid?: boolean;\n closeOnSubmit?: boolean;\n side?: \"left\" | \"right\";\n loading?: boolean;\n};\n\nexport function CraftCreateEditDrawer<TValues extends FieldValues>({\n mode = \"create\",\n form,\n onSubmit,\n open,\n defaultOpen = false,\n onOpenChange,\n trigger,\n title,\n description,\n submitLabel,\n cancelLabel = \"Cancel\",\n tone,\n className,\n children,\n footer,\n disableSubmitWhenInvalid = true,\n closeOnSubmit = true,\n side = \"right\",\n loading,\n}: CraftCreateEditDrawerProps<TValues>) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);\n const isControlled = typeof open === \"boolean\";\n const isOpen = isControlled ? open : uncontrolledOpen;\n\n const setOpen = React.useCallback(\n (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange]\n );\n\n const formId = React.useId();\n const isSubmitting = loading ?? form.formState.isSubmitting;\n const isSubmitDisabled =\n isSubmitting || (disableSubmitWhenInvalid && !form.formState.isValid);\n\n const handleSubmit = form.handleSubmit(async (values) => {\n await onSubmit(values);\n if (closeOnSubmit) setOpen(false);\n });\n\n const resolvedTitle = title ?? (mode === \"create\" ? \"Create item\" : \"Edit item\");\n const resolvedSubmitLabel =\n submitLabel ?? (mode === \"create\" ? \"Create\" : \"Save changes\");\n\n const footerContent = footer ?? (\n <div className=\"flex flex-wrap items-center justify-end gap-3\">\n <CraftButton type=\"button\" variant=\"ghost\" onClick={() => setOpen(false)}>\n {cancelLabel}\n </CraftButton>\n <CraftButton\n type=\"submit\"\n variant=\"solid\"\n form={formId}\n disabled={isSubmitDisabled}\n loading={isSubmitting}\n >\n {resolvedSubmitLabel}\n </CraftButton>\n </div>\n );\n\n return (\n <FormProvider {...form}>\n <CraftDrawer\n open={isOpen}\n onOpenChange={setOpen}\n trigger={trigger}\n title={resolvedTitle}\n tone={tone}\n side={side}\n className={cn(\"flex flex-col\", className)}\n footer={footerContent}\n >\n <form id={formId} onSubmit={handleSubmit} className=\"space-y-5\">\n {description && (\n <p className=\"text-sm text-[rgb(var(--nc-fg-muted))]\">\n {description}\n </p>\n )}\n {children}\n </form>\n </CraftDrawer>\n </FormProvider>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgFI;AA9EJ,YAAuB;AACvB,6BAAmE;AAEnE,gBAAmB;AAEnB,0BAA4B;AAC5B,0BAA4B;AAwBrB,SAAS,sBAAmD;AAAA,EACjE,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,2BAA2B;AAAA,EAC3B,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP;AACF,GAAwC;AACtC,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAAS,WAAW;AAC1E,QAAM,eAAe,OAAO,SAAS;AACrC,QAAM,SAAS,eAAe,OAAO;AAErC,QAAM,UAAU,MAAM;AAAA,IACpB,CAAC,SAAkB;AACjB,UAAI,CAAC,aAAc,qBAAoB,IAAI;AAC3C,mDAAe;AAAA,IACjB;AAAA,IACA,CAAC,cAAc,YAAY;AAAA,EAC7B;AAEA,QAAM,SAAS,MAAM,MAAM;AAC3B,QAAM,eAAe,4BAAW,KAAK,UAAU;AAC/C,QAAM,mBACJ,gBAAiB,4BAA4B,CAAC,KAAK,UAAU;AAE/D,QAAM,eAAe,KAAK,aAAa,OAAO,WAAW;AACvD,UAAM,SAAS,MAAM;AACrB,QAAI,cAAe,SAAQ,KAAK;AAAA,EAClC,CAAC;AAED,QAAM,gBAAgB,wBAAU,SAAS,WAAW,gBAAgB;AACpE,QAAM,sBACJ,oCAAgB,SAAS,WAAW,WAAW;AAEjD,QAAM,gBAAgB,0BACpB,6CAAC,SAAI,WAAU,iDACb;AAAA,gDAAC,mCAAY,MAAK,UAAS,SAAQ,SAAQ,SAAS,MAAM,QAAQ,KAAK,GACpE,uBACH;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS;AAAA,QAER;AAAA;AAAA,IACH;AAAA,KACF;AAGF,SACE,4CAAC,uCAAc,GAAG,MAChB;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,cAAc;AAAA,MACd;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,eAAW,cAAG,iBAAiB,SAAS;AAAA,MACxC,QAAQ;AAAA,MAER,uDAAC,UAAK,IAAI,QAAQ,UAAU,cAAc,WAAU,aACjD;AAAA,uBACC,4CAAC,OAAE,WAAU,0CACV,uBACH;AAAA,QAED;AAAA,SACH;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
|
|
@@ -22,7 +22,8 @@ type CraftCreateEditDrawerProps<TValues extends FieldValues> = {
|
|
|
22
22
|
disableSubmitWhenInvalid?: boolean;
|
|
23
23
|
closeOnSubmit?: boolean;
|
|
24
24
|
side?: "left" | "right";
|
|
25
|
+
loading?: boolean;
|
|
25
26
|
};
|
|
26
|
-
declare function CraftCreateEditDrawer<TValues extends FieldValues>({ mode, form, onSubmit, open, defaultOpen, onOpenChange, trigger, title, description, submitLabel, cancelLabel, tone, className, children, footer, disableSubmitWhenInvalid, closeOnSubmit, side, }: CraftCreateEditDrawerProps<TValues>): react_jsx_runtime.JSX.Element;
|
|
27
|
+
declare function CraftCreateEditDrawer<TValues extends FieldValues>({ mode, form, onSubmit, open, defaultOpen, onOpenChange, trigger, title, description, submitLabel, cancelLabel, tone, className, children, footer, disableSubmitWhenInvalid, closeOnSubmit, side, loading, }: CraftCreateEditDrawerProps<TValues>): react_jsx_runtime.JSX.Element;
|
|
27
28
|
|
|
28
29
|
export { CraftCreateEditDrawer, type CraftCreateEditDrawerProps };
|
|
@@ -22,7 +22,8 @@ type CraftCreateEditDrawerProps<TValues extends FieldValues> = {
|
|
|
22
22
|
disableSubmitWhenInvalid?: boolean;
|
|
23
23
|
closeOnSubmit?: boolean;
|
|
24
24
|
side?: "left" | "right";
|
|
25
|
+
loading?: boolean;
|
|
25
26
|
};
|
|
26
|
-
declare function CraftCreateEditDrawer<TValues extends FieldValues>({ mode, form, onSubmit, open, defaultOpen, onOpenChange, trigger, title, description, submitLabel, cancelLabel, tone, className, children, footer, disableSubmitWhenInvalid, closeOnSubmit, side, }: CraftCreateEditDrawerProps<TValues>): react_jsx_runtime.JSX.Element;
|
|
27
|
+
declare function CraftCreateEditDrawer<TValues extends FieldValues>({ mode, form, onSubmit, open, defaultOpen, onOpenChange, trigger, title, description, submitLabel, cancelLabel, tone, className, children, footer, disableSubmitWhenInvalid, closeOnSubmit, side, loading, }: CraftCreateEditDrawerProps<TValues>): react_jsx_runtime.JSX.Element;
|
|
27
28
|
|
|
28
29
|
export { CraftCreateEditDrawer, type CraftCreateEditDrawerProps };
|
|
@@ -23,7 +23,8 @@ function CraftCreateEditDrawer({
|
|
|
23
23
|
footer,
|
|
24
24
|
disableSubmitWhenInvalid = true,
|
|
25
25
|
closeOnSubmit = true,
|
|
26
|
-
side = "right"
|
|
26
|
+
side = "right",
|
|
27
|
+
loading
|
|
27
28
|
}) {
|
|
28
29
|
const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);
|
|
29
30
|
const isControlled = typeof open === "boolean";
|
|
@@ -36,7 +37,8 @@ function CraftCreateEditDrawer({
|
|
|
36
37
|
[isControlled, onOpenChange]
|
|
37
38
|
);
|
|
38
39
|
const formId = React.useId();
|
|
39
|
-
const
|
|
40
|
+
const isSubmitting = loading != null ? loading : form.formState.isSubmitting;
|
|
41
|
+
const isSubmitDisabled = isSubmitting || disableSubmitWhenInvalid && !form.formState.isValid;
|
|
40
42
|
const handleSubmit = form.handleSubmit(async (values) => {
|
|
41
43
|
await onSubmit(values);
|
|
42
44
|
if (closeOnSubmit) setOpen(false);
|
|
@@ -52,6 +54,7 @@ function CraftCreateEditDrawer({
|
|
|
52
54
|
variant: "solid",
|
|
53
55
|
form: formId,
|
|
54
56
|
disabled: isSubmitDisabled,
|
|
57
|
+
loading: isSubmitting,
|
|
55
58
|
children: resolvedSubmitLabel
|
|
56
59
|
}
|
|
57
60
|
)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/craft-create-edit-drawer.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { FormProvider, type FieldValues, type UseFormReturn } from \"react-hook-form\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\nimport { CraftDrawer } from \"@/components/craft-drawer\";\nimport { CraftButton } from \"@/components/craft-button\";\n\nexport type CraftCreateEditDrawerProps<TValues extends FieldValues> = {\n mode?: \"create\" | \"edit\";\n form: UseFormReturn<TValues>;\n onSubmit: (values: TValues) => void | Promise<void>;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: React.ReactNode;\n title?: React.ReactNode;\n description?: React.ReactNode;\n submitLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n tone?: ThemeName;\n className?: string;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n disableSubmitWhenInvalid?: boolean;\n closeOnSubmit?: boolean;\n side?: \"left\" | \"right\";\n};\n\nexport function CraftCreateEditDrawer<TValues extends FieldValues>({\n mode = \"create\",\n form,\n onSubmit,\n open,\n defaultOpen = false,\n onOpenChange,\n trigger,\n title,\n description,\n submitLabel,\n cancelLabel = \"Cancel\",\n tone,\n className,\n children,\n footer,\n disableSubmitWhenInvalid = true,\n closeOnSubmit = true,\n side = \"right\",\n}: CraftCreateEditDrawerProps<TValues>) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);\n const isControlled = typeof open === \"boolean\";\n const isOpen = isControlled ? open : uncontrolledOpen;\n\n const setOpen = React.useCallback(\n (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange]\n );\n\n const formId = React.useId();\n const isSubmitDisabled =\n disableSubmitWhenInvalid && !form.formState.isValid;\n\n const handleSubmit = form.handleSubmit(async (values) => {\n await onSubmit(values);\n if (closeOnSubmit) setOpen(false);\n });\n\n const resolvedTitle = title ?? (mode === \"create\" ? \"Create item\" : \"Edit item\");\n const resolvedSubmitLabel =\n submitLabel ?? (mode === \"create\" ? \"Create\" : \"Save changes\");\n\n const footerContent = footer ?? (\n <div className=\"flex flex-wrap items-center justify-end gap-3\">\n <CraftButton type=\"button\" variant=\"ghost\" onClick={() => setOpen(false)}>\n {cancelLabel}\n </CraftButton>\n <CraftButton\n type=\"submit\"\n variant=\"solid\"\n form={formId}\n disabled={isSubmitDisabled}\n >\n {resolvedSubmitLabel}\n </CraftButton>\n </div>\n );\n\n return (\n <FormProvider {...form}>\n <CraftDrawer\n open={isOpen}\n onOpenChange={setOpen}\n trigger={trigger}\n title={resolvedTitle}\n tone={tone}\n side={side}\n className={cn(\"flex flex-col\", className)}\n footer={footerContent}\n >\n <form id={formId} onSubmit={handleSubmit} className=\"space-y-5\">\n {description && (\n <p className=\"text-sm text-[rgb(var(--nc-fg-muted))]\">\n {description}\n </p>\n )}\n {children}\n </form>\n </CraftDrawer>\n </FormProvider>\n );\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../src/components/craft-create-edit-drawer.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { FormProvider, type FieldValues, type UseFormReturn } from \"react-hook-form\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\nimport { CraftDrawer } from \"@/components/craft-drawer\";\nimport { CraftButton } from \"@/components/craft-button\";\n\nexport type CraftCreateEditDrawerProps<TValues extends FieldValues> = {\n mode?: \"create\" | \"edit\";\n form: UseFormReturn<TValues>;\n onSubmit: (values: TValues) => void | Promise<void>;\n open?: boolean;\n defaultOpen?: boolean;\n onOpenChange?: (open: boolean) => void;\n trigger?: React.ReactNode;\n title?: React.ReactNode;\n description?: React.ReactNode;\n submitLabel?: React.ReactNode;\n cancelLabel?: React.ReactNode;\n tone?: ThemeName;\n className?: string;\n children?: React.ReactNode;\n footer?: React.ReactNode;\n disableSubmitWhenInvalid?: boolean;\n closeOnSubmit?: boolean;\n side?: \"left\" | \"right\";\n loading?: boolean;\n};\n\nexport function CraftCreateEditDrawer<TValues extends FieldValues>({\n mode = \"create\",\n form,\n onSubmit,\n open,\n defaultOpen = false,\n onOpenChange,\n trigger,\n title,\n description,\n submitLabel,\n cancelLabel = \"Cancel\",\n tone,\n className,\n children,\n footer,\n disableSubmitWhenInvalid = true,\n closeOnSubmit = true,\n side = \"right\",\n loading,\n}: CraftCreateEditDrawerProps<TValues>) {\n const [uncontrolledOpen, setUncontrolledOpen] = React.useState(defaultOpen);\n const isControlled = typeof open === \"boolean\";\n const isOpen = isControlled ? open : uncontrolledOpen;\n\n const setOpen = React.useCallback(\n (next: boolean) => {\n if (!isControlled) setUncontrolledOpen(next);\n onOpenChange?.(next);\n },\n [isControlled, onOpenChange]\n );\n\n const formId = React.useId();\n const isSubmitting = loading ?? form.formState.isSubmitting;\n const isSubmitDisabled =\n isSubmitting || (disableSubmitWhenInvalid && !form.formState.isValid);\n\n const handleSubmit = form.handleSubmit(async (values) => {\n await onSubmit(values);\n if (closeOnSubmit) setOpen(false);\n });\n\n const resolvedTitle = title ?? (mode === \"create\" ? \"Create item\" : \"Edit item\");\n const resolvedSubmitLabel =\n submitLabel ?? (mode === \"create\" ? \"Create\" : \"Save changes\");\n\n const footerContent = footer ?? (\n <div className=\"flex flex-wrap items-center justify-end gap-3\">\n <CraftButton type=\"button\" variant=\"ghost\" onClick={() => setOpen(false)}>\n {cancelLabel}\n </CraftButton>\n <CraftButton\n type=\"submit\"\n variant=\"solid\"\n form={formId}\n disabled={isSubmitDisabled}\n loading={isSubmitting}\n >\n {resolvedSubmitLabel}\n </CraftButton>\n </div>\n );\n\n return (\n <FormProvider {...form}>\n <CraftDrawer\n open={isOpen}\n onOpenChange={setOpen}\n trigger={trigger}\n title={resolvedTitle}\n tone={tone}\n side={side}\n className={cn(\"flex flex-col\", className)}\n footer={footerContent}\n >\n <form id={formId} onSubmit={handleSubmit} className=\"space-y-5\">\n {description && (\n <p className=\"text-sm text-[rgb(var(--nc-fg-muted))]\">\n {description}\n </p>\n )}\n {children}\n </form>\n </CraftDrawer>\n </FormProvider>\n );\n}\n"],"mappings":";AAgFI,SACE,KADF;AA9EJ,YAAY,WAAW;AACvB,SAAS,oBAA0D;AAEnE,SAAS,UAAU;AAEnB,SAAS,mBAAmB;AAC5B,SAAS,mBAAmB;AAwBrB,SAAS,sBAAmD;AAAA,EACjE,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,2BAA2B;AAAA,EAC3B,gBAAgB;AAAA,EAChB,OAAO;AAAA,EACP;AACF,GAAwC;AACtC,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,MAAM,SAAS,WAAW;AAC1E,QAAM,eAAe,OAAO,SAAS;AACrC,QAAM,SAAS,eAAe,OAAO;AAErC,QAAM,UAAU,MAAM;AAAA,IACpB,CAAC,SAAkB;AACjB,UAAI,CAAC,aAAc,qBAAoB,IAAI;AAC3C,mDAAe;AAAA,IACjB;AAAA,IACA,CAAC,cAAc,YAAY;AAAA,EAC7B;AAEA,QAAM,SAAS,MAAM,MAAM;AAC3B,QAAM,eAAe,4BAAW,KAAK,UAAU;AAC/C,QAAM,mBACJ,gBAAiB,4BAA4B,CAAC,KAAK,UAAU;AAE/D,QAAM,eAAe,KAAK,aAAa,OAAO,WAAW;AACvD,UAAM,SAAS,MAAM;AACrB,QAAI,cAAe,SAAQ,KAAK;AAAA,EAClC,CAAC;AAED,QAAM,gBAAgB,wBAAU,SAAS,WAAW,gBAAgB;AACpE,QAAM,sBACJ,oCAAgB,SAAS,WAAW,WAAW;AAEjD,QAAM,gBAAgB,0BACpB,qBAAC,SAAI,WAAU,iDACb;AAAA,wBAAC,eAAY,MAAK,UAAS,SAAQ,SAAQ,SAAS,MAAM,QAAQ,KAAK,GACpE,uBACH;AAAA,IACA;AAAA,MAAC;AAAA;AAAA,QACC,MAAK;AAAA,QACL,SAAQ;AAAA,QACR,MAAM;AAAA,QACN,UAAU;AAAA,QACV,SAAS;AAAA,QAER;AAAA;AAAA,IACH;AAAA,KACF;AAGF,SACE,oBAAC,gBAAc,GAAG,MAChB;AAAA,IAAC;AAAA;AAAA,MACC,MAAM;AAAA,MACN,cAAc;AAAA,MACd;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,MACA,WAAW,GAAG,iBAAiB,SAAS;AAAA,MACxC,QAAQ;AAAA,MAER,+BAAC,UAAK,IAAI,QAAQ,UAAU,cAAc,WAAU,aACjD;AAAA,uBACC,oBAAC,OAAE,WAAU,0CACV,uBACH;AAAA,QAED;AAAA,SACH;AAAA;AAAA,EACF,GACF;AAEJ;","names":[]}
|
|
@@ -59,20 +59,26 @@ function CraftIcon({
|
|
|
59
59
|
const registry = icons != null ? icons : contextRegistry;
|
|
60
60
|
const icon = registry == null ? void 0 : registry[name];
|
|
61
61
|
if (!icon) {
|
|
62
|
-
const
|
|
63
|
-
xs: "xs",
|
|
64
|
-
sm: "sm",
|
|
65
|
-
md: "
|
|
66
|
-
lg: "
|
|
67
|
-
xl: "
|
|
68
|
-
|
|
62
|
+
const sizeClassMap = {
|
|
63
|
+
xs: "text-xs",
|
|
64
|
+
sm: "text-sm",
|
|
65
|
+
md: "text-base",
|
|
66
|
+
lg: "text-lg",
|
|
67
|
+
xl: "text-xl",
|
|
68
|
+
"2xl": "text-2xl",
|
|
69
|
+
"3xl": "text-3xl",
|
|
70
|
+
"4xl": "text-4xl"
|
|
69
71
|
};
|
|
70
72
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
71
73
|
import_react_fontawesome.FontAwesomeIcon,
|
|
72
74
|
{
|
|
73
75
|
icon: [prefix, name],
|
|
74
|
-
|
|
75
|
-
|
|
76
|
+
className: (0, import_cn.cn)(
|
|
77
|
+
color ? `text-${color}` : "text-current",
|
|
78
|
+
"inline-block",
|
|
79
|
+
size ? sizeClassMap[size] : null,
|
|
80
|
+
className
|
|
81
|
+
),
|
|
76
82
|
"aria-hidden": ariaLabel ? void 0 : true,
|
|
77
83
|
"aria-label": ariaLabel,
|
|
78
84
|
role: ariaLabel ? "img" : void 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/craft-icon.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { library, type IconName, type IconPrefix } from \"@fortawesome/fontawesome-svg-core\";\nimport { fas } from \"@fortawesome/free-solid-svg-icons\";\nimport { far } from \"@fortawesome/free-regular-svg-icons\";\nimport { fab } from \"@fortawesome/free-brands-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type CraftIconRegistry = Record<string, React.ReactNode>;\n\nconst CraftIconContext = React.createContext<CraftIconRegistry | null>(null);\n\nexport type CraftIconProviderProps = {\n icons: CraftIconRegistry;\n children: React.ReactNode;\n};\n\nexport function CraftIconProvider({ icons, children }: CraftIconProviderProps) {\n return <CraftIconContext.Provider value={icons}>{children}</CraftIconContext.Provider>;\n}\n\nexport type CraftIconProps = {\n name: IconName | string;\n prefix?: IconPrefix;\n size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"
|
|
1
|
+
{"version":3,"sources":["../../src/components/craft-icon.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { library, type IconName, type IconPrefix } from \"@fortawesome/fontawesome-svg-core\";\nimport { fas } from \"@fortawesome/free-solid-svg-icons\";\nimport { far } from \"@fortawesome/free-regular-svg-icons\";\nimport { fab } from \"@fortawesome/free-brands-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type CraftIconRegistry = Record<string, React.ReactNode>;\n\nconst CraftIconContext = React.createContext<CraftIconRegistry | null>(null);\n\nexport type CraftIconProviderProps = {\n icons: CraftIconRegistry;\n children: React.ReactNode;\n};\n\nexport function CraftIconProvider({ icons, children }: CraftIconProviderProps) {\n return <CraftIconContext.Provider value={icons}>{children}</CraftIconContext.Provider>;\n}\n\nexport type CraftIconProps = {\n name: IconName | string;\n prefix?: IconPrefix;\n size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"4xl\";\n color?: string;\n className?: string;\n \"aria-label\"?: string;\n icons?: CraftIconRegistry;\n};\n\nlibrary.add(fas, far, fab);\n\nexport function CraftIcon({\n name,\n prefix = \"fas\",\n size = \"md\",\n color,\n className,\n \"aria-label\": ariaLabel,\n icons,\n}: CraftIconProps) {\n const contextRegistry = React.useContext(CraftIconContext);\n const registry = icons ?? contextRegistry;\n const icon = registry?.[name];\n\n if (!icon) {\n const sizeClassMap = {\n xs: \"text-xs\",\n sm: \"text-sm\",\n md: \"text-base\",\n lg: \"text-lg\",\n xl: \"text-xl\",\n \"2xl\": \"text-2xl\",\n \"3xl\": \"text-3xl\",\n \"4xl\": \"text-4xl\",\n } as const;\n\n return (\n <FontAwesomeIcon\n icon={[prefix, name as IconName]}\n className={cn(\n color ? `text-${color}` : \"text-current\",\n \"inline-block\",\n size ? sizeClassMap[size] : null,\n className\n )}\n aria-hidden={ariaLabel ? undefined : true}\n aria-label={ariaLabel}\n role={ariaLabel ? \"img\" : undefined}\n />\n );\n }\n\n type IconElementProps = {\n className?: string;\n \"aria-hidden\"?: boolean;\n \"aria-label\"?: string;\n };\n\n if (React.isValidElement<IconElementProps>(icon)) {\n return React.cloneElement(icon, {\n className: cn(icon.props.className, className),\n \"aria-hidden\": ariaLabel ? undefined : true,\n \"aria-label\": ariaLabel,\n });\n }\n\n return (\n <span className={className} aria-label={ariaLabel}>\n {icon}\n </span>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqBS;AAnBT,YAAuB;AACvB,kCAAwD;AACxD,kCAAoB;AACpB,oCAAoB;AACpB,mCAAoB;AACpB,+BAAgC;AAEhC,gBAAmB;AAInB,MAAM,mBAAmB,MAAM,cAAwC,IAAI;AAOpE,SAAS,kBAAkB,EAAE,OAAO,SAAS,GAA2B;AAC7E,SAAO,4CAAC,iBAAiB,UAAjB,EAA0B,OAAO,OAAQ,UAAS;AAC5D;AAYA,oCAAQ,IAAI,iCAAK,mCAAK,gCAAG;AAElB,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,SAAS;AAAA,EACT,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AACF,GAAmB;AACjB,QAAM,kBAAkB,MAAM,WAAW,gBAAgB;AACzD,QAAM,WAAW,wBAAS;AAC1B,QAAM,OAAO,qCAAW;AAExB,MAAI,CAAC,MAAM;AACT,UAAM,eAAe;AAAA,MACnB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,CAAC,QAAQ,IAAgB;AAAA,QAC/B,eAAW;AAAA,UACT,QAAQ,QAAQ,KAAK,KAAK;AAAA,UAC1B;AAAA,UACA,OAAO,aAAa,IAAI,IAAI;AAAA,UAC5B;AAAA,QACF;AAAA,QACA,eAAa,YAAY,SAAY;AAAA,QACrC,cAAY;AAAA,QACZ,MAAM,YAAY,QAAQ;AAAA;AAAA,IAC5B;AAAA,EAEJ;AAQA,MAAI,MAAM,eAAiC,IAAI,GAAG;AAChD,WAAO,MAAM,aAAa,MAAM;AAAA,MAC9B,eAAW,cAAG,KAAK,MAAM,WAAW,SAAS;AAAA,MAC7C,eAAe,YAAY,SAAY;AAAA,MACvC,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAEA,SACE,4CAAC,UAAK,WAAsB,cAAY,WACrC,gBACH;AAEJ;","names":[]}
|
|
@@ -11,7 +11,7 @@ declare function CraftIconProvider({ icons, children }: CraftIconProviderProps):
|
|
|
11
11
|
type CraftIconProps = {
|
|
12
12
|
name: IconName | string;
|
|
13
13
|
prefix?: IconPrefix;
|
|
14
|
-
size?: "xs" | "sm" | "md" | "lg" | "xl" | "
|
|
14
|
+
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl";
|
|
15
15
|
color?: string;
|
|
16
16
|
className?: string;
|
|
17
17
|
"aria-label"?: string;
|
|
@@ -11,7 +11,7 @@ declare function CraftIconProvider({ icons, children }: CraftIconProviderProps):
|
|
|
11
11
|
type CraftIconProps = {
|
|
12
12
|
name: IconName | string;
|
|
13
13
|
prefix?: IconPrefix;
|
|
14
|
-
size?: "xs" | "sm" | "md" | "lg" | "xl" | "
|
|
14
|
+
size?: "xs" | "sm" | "md" | "lg" | "xl" | "2xl" | "3xl" | "4xl";
|
|
15
15
|
color?: string;
|
|
16
16
|
className?: string;
|
|
17
17
|
"aria-label"?: string;
|
|
@@ -25,20 +25,26 @@ function CraftIcon({
|
|
|
25
25
|
const registry = icons != null ? icons : contextRegistry;
|
|
26
26
|
const icon = registry == null ? void 0 : registry[name];
|
|
27
27
|
if (!icon) {
|
|
28
|
-
const
|
|
29
|
-
xs: "xs",
|
|
30
|
-
sm: "sm",
|
|
31
|
-
md: "
|
|
32
|
-
lg: "
|
|
33
|
-
xl: "
|
|
34
|
-
|
|
28
|
+
const sizeClassMap = {
|
|
29
|
+
xs: "text-xs",
|
|
30
|
+
sm: "text-sm",
|
|
31
|
+
md: "text-base",
|
|
32
|
+
lg: "text-lg",
|
|
33
|
+
xl: "text-xl",
|
|
34
|
+
"2xl": "text-2xl",
|
|
35
|
+
"3xl": "text-3xl",
|
|
36
|
+
"4xl": "text-4xl"
|
|
35
37
|
};
|
|
36
38
|
return /* @__PURE__ */ jsx(
|
|
37
39
|
FontAwesomeIcon,
|
|
38
40
|
{
|
|
39
41
|
icon: [prefix, name],
|
|
40
|
-
|
|
41
|
-
|
|
42
|
+
className: cn(
|
|
43
|
+
color ? `text-${color}` : "text-current",
|
|
44
|
+
"inline-block",
|
|
45
|
+
size ? sizeClassMap[size] : null,
|
|
46
|
+
className
|
|
47
|
+
),
|
|
42
48
|
"aria-hidden": ariaLabel ? void 0 : true,
|
|
43
49
|
"aria-label": ariaLabel,
|
|
44
50
|
role: ariaLabel ? "img" : void 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/components/craft-icon.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { library, type IconName, type IconPrefix } from \"@fortawesome/fontawesome-svg-core\";\nimport { fas } from \"@fortawesome/free-solid-svg-icons\";\nimport { far } from \"@fortawesome/free-regular-svg-icons\";\nimport { fab } from \"@fortawesome/free-brands-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type CraftIconRegistry = Record<string, React.ReactNode>;\n\nconst CraftIconContext = React.createContext<CraftIconRegistry | null>(null);\n\nexport type CraftIconProviderProps = {\n icons: CraftIconRegistry;\n children: React.ReactNode;\n};\n\nexport function CraftIconProvider({ icons, children }: CraftIconProviderProps) {\n return <CraftIconContext.Provider value={icons}>{children}</CraftIconContext.Provider>;\n}\n\nexport type CraftIconProps = {\n name: IconName | string;\n prefix?: IconPrefix;\n size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"
|
|
1
|
+
{"version":3,"sources":["../../src/components/craft-icon.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\nimport { library, type IconName, type IconPrefix } from \"@fortawesome/fontawesome-svg-core\";\nimport { fas } from \"@fortawesome/free-solid-svg-icons\";\nimport { far } from \"@fortawesome/free-regular-svg-icons\";\nimport { fab } from \"@fortawesome/free-brands-svg-icons\";\nimport { FontAwesomeIcon } from \"@fortawesome/react-fontawesome\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type CraftIconRegistry = Record<string, React.ReactNode>;\n\nconst CraftIconContext = React.createContext<CraftIconRegistry | null>(null);\n\nexport type CraftIconProviderProps = {\n icons: CraftIconRegistry;\n children: React.ReactNode;\n};\n\nexport function CraftIconProvider({ icons, children }: CraftIconProviderProps) {\n return <CraftIconContext.Provider value={icons}>{children}</CraftIconContext.Provider>;\n}\n\nexport type CraftIconProps = {\n name: IconName | string;\n prefix?: IconPrefix;\n size?: \"xs\" | \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"3xl\" | \"4xl\";\n color?: string;\n className?: string;\n \"aria-label\"?: string;\n icons?: CraftIconRegistry;\n};\n\nlibrary.add(fas, far, fab);\n\nexport function CraftIcon({\n name,\n prefix = \"fas\",\n size = \"md\",\n color,\n className,\n \"aria-label\": ariaLabel,\n icons,\n}: CraftIconProps) {\n const contextRegistry = React.useContext(CraftIconContext);\n const registry = icons ?? contextRegistry;\n const icon = registry?.[name];\n\n if (!icon) {\n const sizeClassMap = {\n xs: \"text-xs\",\n sm: \"text-sm\",\n md: \"text-base\",\n lg: \"text-lg\",\n xl: \"text-xl\",\n \"2xl\": \"text-2xl\",\n \"3xl\": \"text-3xl\",\n \"4xl\": \"text-4xl\",\n } as const;\n\n return (\n <FontAwesomeIcon\n icon={[prefix, name as IconName]}\n className={cn(\n color ? `text-${color}` : \"text-current\",\n \"inline-block\",\n size ? sizeClassMap[size] : null,\n className\n )}\n aria-hidden={ariaLabel ? undefined : true}\n aria-label={ariaLabel}\n role={ariaLabel ? \"img\" : undefined}\n />\n );\n }\n\n type IconElementProps = {\n className?: string;\n \"aria-hidden\"?: boolean;\n \"aria-label\"?: string;\n };\n\n if (React.isValidElement<IconElementProps>(icon)) {\n return React.cloneElement(icon, {\n className: cn(icon.props.className, className),\n \"aria-hidden\": ariaLabel ? undefined : true,\n \"aria-label\": ariaLabel,\n });\n }\n\n return (\n <span className={className} aria-label={ariaLabel}>\n {icon}\n </span>\n );\n}\n"],"mappings":";AAqBS;AAnBT,YAAY,WAAW;AACvB,SAAS,eAA+C;AACxD,SAAS,WAAW;AACpB,SAAS,WAAW;AACpB,SAAS,WAAW;AACpB,SAAS,uBAAuB;AAEhC,SAAS,UAAU;AAInB,MAAM,mBAAmB,MAAM,cAAwC,IAAI;AAOpE,SAAS,kBAAkB,EAAE,OAAO,SAAS,GAA2B;AAC7E,SAAO,oBAAC,iBAAiB,UAAjB,EAA0B,OAAO,OAAQ,UAAS;AAC5D;AAYA,QAAQ,IAAI,KAAK,KAAK,GAAG;AAElB,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,SAAS;AAAA,EACT,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA,cAAc;AAAA,EACd;AACF,GAAmB;AACjB,QAAM,kBAAkB,MAAM,WAAW,gBAAgB;AACzD,QAAM,WAAW,wBAAS;AAC1B,QAAM,OAAO,qCAAW;AAExB,MAAI,CAAC,MAAM;AACT,UAAM,eAAe;AAAA,MACnB,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAEA,WACE;AAAA,MAAC;AAAA;AAAA,QACC,MAAM,CAAC,QAAQ,IAAgB;AAAA,QAC/B,WAAW;AAAA,UACT,QAAQ,QAAQ,KAAK,KAAK;AAAA,UAC1B;AAAA,UACA,OAAO,aAAa,IAAI,IAAI;AAAA,UAC5B;AAAA,QACF;AAAA,QACA,eAAa,YAAY,SAAY;AAAA,QACrC,cAAY;AAAA,QACZ,MAAM,YAAY,QAAQ;AAAA;AAAA,IAC5B;AAAA,EAEJ;AAQA,MAAI,MAAM,eAAiC,IAAI,GAAG;AAChD,WAAO,MAAM,aAAa,MAAM;AAAA,MAC9B,WAAW,GAAG,KAAK,MAAM,WAAW,SAAS;AAAA,MAC7C,eAAe,YAAY,SAAY;AAAA,MACvC,cAAc;AAAA,IAChB,CAAC;AAAA,EACH;AAEA,SACE,oBAAC,UAAK,WAAsB,cAAY,WACrC,gBACH;AAEJ;","names":[]}
|
|
@@ -28,15 +28,15 @@ function AppShell({ className, sidebar, topNav, children, ...props }) {
|
|
|
28
28
|
"div",
|
|
29
29
|
{
|
|
30
30
|
className: (0, import_cn.cn)(
|
|
31
|
-
"grid min-h-screen grid-cols-1 gap-
|
|
31
|
+
"grid min-h-screen grid-cols-1 gap-4 bg-background p-4 lg:grid-cols-[var(--nc-sidebar-width,72px)_1fr] lg:gap-5 lg:p-5",
|
|
32
32
|
className
|
|
33
33
|
),
|
|
34
34
|
...props,
|
|
35
35
|
children: [
|
|
36
|
-
sidebar && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "h-full lg:sticky lg:top-
|
|
37
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex flex-col gap-
|
|
38
|
-
topNav && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "lg:sticky lg:top-
|
|
39
|
-
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("main", { className: "flex-1", children })
|
|
36
|
+
sidebar && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "relative z-30 h-full overflow-visible lg:sticky lg:top-4 lg:self-start lg:max-h-[calc(100vh-2rem)] lg:overflow-y-auto", children: sidebar }),
|
|
37
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "flex min-w-0 flex-col gap-4 lg:gap-5", children: [
|
|
38
|
+
topNav && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "lg:sticky lg:top-4 lg:z-20", children: topNav }),
|
|
39
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("main", { className: "min-w-0 flex-1", children })
|
|
40
40
|
] })
|
|
41
41
|
]
|
|
42
42
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layout/app-shell.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type AppShellProps = React.HTMLAttributes<HTMLDivElement> & {\n sidebar?: React.ReactNode;\n topNav?: React.ReactNode;\n};\n\nexport function AppShell({ className, sidebar, topNav, children, ...props }: AppShellProps) {\n return (\n <div\n className={cn(\n \"grid min-h-screen grid-cols-1 gap-
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layout/app-shell.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type AppShellProps = React.HTMLAttributes<HTMLDivElement> & {\n sidebar?: React.ReactNode;\n topNav?: React.ReactNode;\n};\n\nexport function AppShell({ className, sidebar, topNav, children, ...props }: AppShellProps) {\n return (\n <div\n className={cn(\n \"grid min-h-screen grid-cols-1 gap-4 bg-background p-4 lg:grid-cols-[var(--nc-sidebar-width,72px)_1fr] lg:gap-5 lg:p-5\",\n className\n )}\n {...props}\n >\n {sidebar && (\n <div className=\"relative z-30 h-full overflow-visible lg:sticky lg:top-4 lg:self-start lg:max-h-[calc(100vh-2rem)] lg:overflow-y-auto\">\n {sidebar}\n </div>\n )}\n <div className=\"flex min-w-0 flex-col gap-4 lg:gap-5\">\n {topNav && <div className=\"lg:sticky lg:top-4 lg:z-20\">{topNav}</div>}\n <main className=\"min-w-0 flex-1\">{children}</main>\n </div>\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAmBQ;AAjBR,gBAAmB;AAOZ,SAAS,SAAS,EAAE,WAAW,SAAS,QAAQ,UAAU,GAAG,MAAM,GAAkB;AAC1F,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA,mBACC,4CAAC,SAAI,WAAU,yHACZ,mBACH;AAAA,QAEF,6CAAC,SAAI,WAAU,wCACZ;AAAA,oBAAU,4CAAC,SAAI,WAAU,8BAA8B,kBAAO;AAAA,UAC/D,4CAAC,UAAK,WAAU,kBAAkB,UAAS;AAAA,WAC7C;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -5,15 +5,15 @@ function AppShell({ className, sidebar, topNav, children, ...props }) {
|
|
|
5
5
|
"div",
|
|
6
6
|
{
|
|
7
7
|
className: cn(
|
|
8
|
-
"grid min-h-screen grid-cols-1 gap-
|
|
8
|
+
"grid min-h-screen grid-cols-1 gap-4 bg-background p-4 lg:grid-cols-[var(--nc-sidebar-width,72px)_1fr] lg:gap-5 lg:p-5",
|
|
9
9
|
className
|
|
10
10
|
),
|
|
11
11
|
...props,
|
|
12
12
|
children: [
|
|
13
|
-
sidebar && /* @__PURE__ */ jsx("div", { className: "h-full lg:sticky lg:top-
|
|
14
|
-
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-
|
|
15
|
-
topNav && /* @__PURE__ */ jsx("div", { className: "lg:sticky lg:top-
|
|
16
|
-
/* @__PURE__ */ jsx("main", { className: "flex-1", children })
|
|
13
|
+
sidebar && /* @__PURE__ */ jsx("div", { className: "relative z-30 h-full overflow-visible lg:sticky lg:top-4 lg:self-start lg:max-h-[calc(100vh-2rem)] lg:overflow-y-auto", children: sidebar }),
|
|
14
|
+
/* @__PURE__ */ jsxs("div", { className: "flex min-w-0 flex-col gap-4 lg:gap-5", children: [
|
|
15
|
+
topNav && /* @__PURE__ */ jsx("div", { className: "lg:sticky lg:top-4 lg:z-20", children: topNav }),
|
|
16
|
+
/* @__PURE__ */ jsx("main", { className: "min-w-0 flex-1", children })
|
|
17
17
|
] })
|
|
18
18
|
]
|
|
19
19
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layout/app-shell.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type AppShellProps = React.HTMLAttributes<HTMLDivElement> & {\n sidebar?: React.ReactNode;\n topNav?: React.ReactNode;\n};\n\nexport function AppShell({ className, sidebar, topNav, children, ...props }: AppShellProps) {\n return (\n <div\n className={cn(\n \"grid min-h-screen grid-cols-1 gap-
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layout/app-shell.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type AppShellProps = React.HTMLAttributes<HTMLDivElement> & {\n sidebar?: React.ReactNode;\n topNav?: React.ReactNode;\n};\n\nexport function AppShell({ className, sidebar, topNav, children, ...props }: AppShellProps) {\n return (\n <div\n className={cn(\n \"grid min-h-screen grid-cols-1 gap-4 bg-background p-4 lg:grid-cols-[var(--nc-sidebar-width,72px)_1fr] lg:gap-5 lg:p-5\",\n className\n )}\n {...props}\n >\n {sidebar && (\n <div className=\"relative z-30 h-full overflow-visible lg:sticky lg:top-4 lg:self-start lg:max-h-[calc(100vh-2rem)] lg:overflow-y-auto\">\n {sidebar}\n </div>\n )}\n <div className=\"flex min-w-0 flex-col gap-4 lg:gap-5\">\n {topNav && <div className=\"lg:sticky lg:top-4 lg:z-20\">{topNav}</div>}\n <main className=\"min-w-0 flex-1\">{children}</main>\n </div>\n </div>\n );\n}\n"],"mappings":"AAmBQ,cAIF,YAJE;AAjBR,SAAS,UAAU;AAOZ,SAAS,SAAS,EAAE,WAAW,SAAS,QAAQ,UAAU,GAAG,MAAM,GAAkB;AAC1F,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH;AAAA,mBACC,oBAAC,SAAI,WAAU,yHACZ,mBACH;AAAA,QAEF,qBAAC,SAAI,WAAU,wCACZ;AAAA,oBAAU,oBAAC,SAAI,WAAU,8BAA8B,kBAAO;AAAA,UAC/D,oBAAC,UAAK,WAAU,kBAAkB,UAAS;AAAA,WAC7C;AAAA;AAAA;AAAA,EACF;AAEJ;","names":[]}
|
|
@@ -48,10 +48,22 @@ function AppTemplate({
|
|
|
48
48
|
icons,
|
|
49
49
|
activePath,
|
|
50
50
|
getActivePath,
|
|
51
|
+
sidebarDefaultExpanded = false,
|
|
52
|
+
sidebarExpanded,
|
|
53
|
+
onSidebarExpandedChange,
|
|
54
|
+
sidebarCollapsedWidth = "72px",
|
|
55
|
+
sidebarExpandedWidth = "224px",
|
|
56
|
+
sidebarHoverExpand = true,
|
|
51
57
|
children
|
|
52
58
|
}) {
|
|
53
59
|
const sidebarConfig = config.sidebar;
|
|
54
60
|
const headerConfig = config.header;
|
|
61
|
+
const [internalExpanded, setInternalExpanded] = React.useState(sidebarDefaultExpanded);
|
|
62
|
+
const resolvedExpanded = sidebarExpanded != null ? sidebarExpanded : internalExpanded;
|
|
63
|
+
const setExpanded = (next) => {
|
|
64
|
+
if (sidebarExpanded === void 0) setInternalExpanded(next);
|
|
65
|
+
onSidebarExpandedChange == null ? void 0 : onSidebarExpandedChange(next);
|
|
66
|
+
};
|
|
55
67
|
const resolvedActivePath = activePath != null ? activePath : getActivePath == null ? void 0 : getActivePath();
|
|
56
68
|
const buildIcon = React.useCallback(
|
|
57
69
|
(name) => {
|
|
@@ -76,12 +88,20 @@ function AppTemplate({
|
|
|
76
88
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
77
89
|
import_app_shell.AppShell,
|
|
78
90
|
{
|
|
91
|
+
style: {
|
|
92
|
+
"--nc-sidebar-width": resolvedExpanded ? sidebarExpandedWidth : sidebarCollapsedWidth
|
|
93
|
+
},
|
|
79
94
|
sidebar: sidebarConfig && sidebarItems ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
80
95
|
import_sidebar.Sidebar,
|
|
81
96
|
{
|
|
82
97
|
title: sidebarConfig.title,
|
|
83
98
|
items: sidebarItems,
|
|
84
|
-
footer: sidebarFooterNode
|
|
99
|
+
footer: sidebarFooterNode,
|
|
100
|
+
hoverExpand: sidebarHoverExpand,
|
|
101
|
+
expanded: resolvedExpanded,
|
|
102
|
+
onExpandedChange: setExpanded,
|
|
103
|
+
collapsedWidth: sidebarCollapsedWidth,
|
|
104
|
+
expandedWidth: sidebarExpandedWidth
|
|
85
105
|
}
|
|
86
106
|
) : void 0,
|
|
87
107
|
topNav: headerConfig ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layout/app-template.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { AppShell } from \"./app-shell\";\nimport { CraftIcon } from \"@/components/craft-icon\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\nimport { Sidebar, type SidebarItem } from \"./sidebar\";\nimport { TopNav } from \"./top-nav\";\nimport type { LayoutConfig, LayoutSidebarItem } from \"./layout-config\";\n\nexport type AppTemplateProps = {\n config: LayoutConfig;\n headerActions?: React.ReactNode;\n headerBreadcrumb?: React.ReactNode;\n sidebarFooter?: React.ReactNode;\n resolveIcon?: (name: string) => React.ReactNode;\n icons?: Record<string, React.ReactNode>;\n activePath?: string;\n getActivePath?: () => string | undefined;\n children: React.ReactNode;\n};\n\nexport function AppTemplate({\n config,\n headerActions,\n headerBreadcrumb,\n sidebarFooter,\n resolveIcon,\n icons,\n activePath,\n getActivePath,\n children,\n}: AppTemplateProps) {\n const sidebarConfig = config.sidebar;\n const headerConfig = config.header;\n\n const resolvedActivePath = activePath ?? getActivePath?.();\n\n const buildIcon = React.useCallback(\n (name?: string) => {\n if (!name) return undefined;\n if (resolveIcon) return resolveIcon(name);\n if (icons?.[name]) return icons[name];\n return <CraftIcon name={name} size=\"lg\"/>;\n },\n [icons, resolveIcon]\n );\n\n const sidebarItems: SidebarItem[] | null = sidebarConfig\n ? sidebarConfig.items.map((item: LayoutSidebarItem) => ({\n label: item.label,\n href: item.href,\n active:\n item.active ??\n (resolvedActivePath && item.href\n ? item.href === resolvedActivePath\n : false),\n icon: buildIcon(item.icon),\n }))\n : null;\n\n const breadcrumbNode =\n headerBreadcrumb ??\n (headerConfig?.breadcrumb ? (\n <Breadcrumbs items={headerConfig.breadcrumb} />\n ) : null);\n\n const sidebarFooterNode =\n sidebarFooter ??\n (sidebarConfig?.footerText ? (\n <div className=\"text-xs text-[rgb(var(--nc-fg-muted))]\">\n {sidebarConfig.footerText}\n </div>\n ) : null);\n\n return (\n <AppShell\n sidebar={\n sidebarConfig && sidebarItems ? (\n <Sidebar\n title={sidebarConfig.title}\n items={sidebarItems}\n footer={sidebarFooterNode}\n />\n ) : undefined\n }\n topNav={\n headerConfig ? (\n <TopNav\n title={headerConfig.title}\n breadcrumb={breadcrumbNode}\n actions={headerActions}\n />\n ) : undefined\n }\n >\n {children}\n </AppShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layout/app-template.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { AppShell } from \"./app-shell\";\nimport { CraftIcon } from \"@/components/craft-icon\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\nimport { Sidebar, type SidebarItem } from \"./sidebar\";\nimport { TopNav } from \"./top-nav\";\nimport type { LayoutConfig, LayoutSidebarItem } from \"./layout-config\";\n\nexport type AppTemplateProps = {\n config: LayoutConfig;\n headerActions?: React.ReactNode;\n headerBreadcrumb?: React.ReactNode;\n sidebarFooter?: React.ReactNode;\n resolveIcon?: (name: string) => React.ReactNode;\n icons?: Record<string, React.ReactNode>;\n activePath?: string;\n getActivePath?: () => string | undefined;\n sidebarDefaultExpanded?: boolean;\n sidebarExpanded?: boolean;\n onSidebarExpandedChange?: (expanded: boolean) => void;\n sidebarCollapsedWidth?: string;\n sidebarExpandedWidth?: string;\n sidebarHoverExpand?: boolean;\n children: React.ReactNode;\n};\n\nexport function AppTemplate({\n config,\n headerActions,\n headerBreadcrumb,\n sidebarFooter,\n resolveIcon,\n icons,\n activePath,\n getActivePath,\n sidebarDefaultExpanded = false,\n sidebarExpanded,\n onSidebarExpandedChange,\n sidebarCollapsedWidth = \"72px\",\n sidebarExpandedWidth = \"224px\",\n sidebarHoverExpand = true,\n children,\n}: AppTemplateProps) {\n const sidebarConfig = config.sidebar;\n const headerConfig = config.header;\n\n const [internalExpanded, setInternalExpanded] =\n React.useState(sidebarDefaultExpanded);\n const resolvedExpanded = sidebarExpanded ?? internalExpanded;\n const setExpanded = (next: boolean) => {\n if (sidebarExpanded === undefined) setInternalExpanded(next);\n onSidebarExpandedChange?.(next);\n };\n\n const resolvedActivePath = activePath ?? getActivePath?.();\n\n const buildIcon = React.useCallback(\n (name?: string) => {\n if (!name) return undefined;\n if (resolveIcon) return resolveIcon(name);\n if (icons?.[name]) return icons[name];\n return <CraftIcon name={name} size=\"lg\"/>;\n },\n [icons, resolveIcon]\n );\n\n const sidebarItems: SidebarItem[] | null = sidebarConfig\n ? sidebarConfig.items.map((item: LayoutSidebarItem) => ({\n label: item.label,\n href: item.href,\n active:\n item.active ??\n (resolvedActivePath && item.href\n ? item.href === resolvedActivePath\n : false),\n icon: buildIcon(item.icon),\n }))\n : null;\n\n const breadcrumbNode =\n headerBreadcrumb ??\n (headerConfig?.breadcrumb ? (\n <Breadcrumbs items={headerConfig.breadcrumb} />\n ) : null);\n\n const sidebarFooterNode =\n sidebarFooter ??\n (sidebarConfig?.footerText ? (\n <div className=\"text-xs text-[rgb(var(--nc-fg-muted))]\">\n {sidebarConfig.footerText}\n </div>\n ) : null);\n\n return (\n <AppShell\n style={\n {\n \"--nc-sidebar-width\": resolvedExpanded\n ? sidebarExpandedWidth\n : sidebarCollapsedWidth,\n } as React.CSSProperties\n }\n sidebar={\n sidebarConfig && sidebarItems ? (\n <Sidebar\n title={sidebarConfig.title}\n items={sidebarItems}\n footer={sidebarFooterNode}\n hoverExpand={sidebarHoverExpand}\n expanded={resolvedExpanded}\n onExpandedChange={setExpanded}\n collapsedWidth={sidebarCollapsedWidth}\n expandedWidth={sidebarExpandedWidth}\n />\n ) : undefined\n }\n topNav={\n headerConfig ? (\n <TopNav\n title={headerConfig.title}\n breadcrumb={breadcrumbNode}\n actions={headerActions}\n />\n ) : undefined\n }\n >\n {children}\n </AppShell>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAgEa;AA9Db,YAAuB;AAEvB,uBAAyB;AACzB,wBAA0B;AAC1B,yBAA4B;AAC5B,qBAA0C;AAC1C,qBAAuB;AAqBhB,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,yBAAyB;AAAA,EACzB;AAAA,EACA;AAAA,EACA,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB;AACF,GAAqB;AACnB,QAAM,gBAAgB,OAAO;AAC7B,QAAM,eAAe,OAAO;AAE5B,QAAM,CAAC,kBAAkB,mBAAmB,IAC1C,MAAM,SAAS,sBAAsB;AACvC,QAAM,mBAAmB,4CAAmB;AAC5C,QAAM,cAAc,CAAC,SAAkB;AACrC,QAAI,oBAAoB,OAAW,qBAAoB,IAAI;AAC3D,uEAA0B;AAAA,EAC5B;AAEA,QAAM,qBAAqB,kCAAc;AAEzC,QAAM,YAAY,MAAM;AAAA,IACtB,CAAC,SAAkB;AACjB,UAAI,CAAC,KAAM,QAAO;AAClB,UAAI,YAAa,QAAO,YAAY,IAAI;AACxC,UAAI,+BAAQ,MAAO,QAAO,MAAM,IAAI;AACpC,aAAO,4CAAC,+BAAU,MAAY,MAAK,MAAI;AAAA,IACzC;AAAA,IACA,CAAC,OAAO,WAAW;AAAA,EACrB;AAEA,QAAM,eAAqC,gBACvC,cAAc,MAAM,IAAI,CAAC,SAAyB;AAtExD;AAsE4D;AAAA,MACpD,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,SACE,UAAK,WAAL,YACC,sBAAsB,KAAK,OACxB,KAAK,SAAS,qBACd;AAAA,MACN,MAAM,UAAU,KAAK,IAAI;AAAA,IAC3B;AAAA,GAAE,IACF;AAEJ,QAAM,iBACJ,+CACC,6CAAc,cACb,4CAAC,kCAAY,OAAO,aAAa,YAAY,IAC3C;AAEN,QAAM,oBACJ,yCACC,+CAAe,cACd,4CAAC,SAAI,WAAU,0CACZ,wBAAc,YACjB,IACE;AAEN,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OACE;AAAA,QACE,sBAAsB,mBAClB,uBACA;AAAA,MACN;AAAA,MAEF,SACE,iBAAiB,eACf;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,cAAc;AAAA,UACrB,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,UAAU;AAAA,UACV,kBAAkB;AAAA,UAClB,gBAAgB;AAAA,UAChB,eAAe;AAAA;AAAA,MACjB,IACE;AAAA,MAEN,QACE,eACE;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,aAAa;AAAA,UACpB,YAAY;AAAA,UACZ,SAAS;AAAA;AAAA,MACX,IACE;AAAA,MAGL;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -11,8 +11,14 @@ type AppTemplateProps = {
|
|
|
11
11
|
icons?: Record<string, React.ReactNode>;
|
|
12
12
|
activePath?: string;
|
|
13
13
|
getActivePath?: () => string | undefined;
|
|
14
|
+
sidebarDefaultExpanded?: boolean;
|
|
15
|
+
sidebarExpanded?: boolean;
|
|
16
|
+
onSidebarExpandedChange?: (expanded: boolean) => void;
|
|
17
|
+
sidebarCollapsedWidth?: string;
|
|
18
|
+
sidebarExpandedWidth?: string;
|
|
19
|
+
sidebarHoverExpand?: boolean;
|
|
14
20
|
children: React.ReactNode;
|
|
15
21
|
};
|
|
16
|
-
declare function AppTemplate({ config, headerActions, headerBreadcrumb, sidebarFooter, resolveIcon, icons, activePath, getActivePath, children, }: AppTemplateProps): react_jsx_runtime.JSX.Element;
|
|
22
|
+
declare function AppTemplate({ config, headerActions, headerBreadcrumb, sidebarFooter, resolveIcon, icons, activePath, getActivePath, sidebarDefaultExpanded, sidebarExpanded, onSidebarExpandedChange, sidebarCollapsedWidth, sidebarExpandedWidth, sidebarHoverExpand, children, }: AppTemplateProps): react_jsx_runtime.JSX.Element;
|
|
17
23
|
|
|
18
24
|
export { AppTemplate, type AppTemplateProps };
|
|
@@ -11,8 +11,14 @@ type AppTemplateProps = {
|
|
|
11
11
|
icons?: Record<string, React.ReactNode>;
|
|
12
12
|
activePath?: string;
|
|
13
13
|
getActivePath?: () => string | undefined;
|
|
14
|
+
sidebarDefaultExpanded?: boolean;
|
|
15
|
+
sidebarExpanded?: boolean;
|
|
16
|
+
onSidebarExpandedChange?: (expanded: boolean) => void;
|
|
17
|
+
sidebarCollapsedWidth?: string;
|
|
18
|
+
sidebarExpandedWidth?: string;
|
|
19
|
+
sidebarHoverExpand?: boolean;
|
|
14
20
|
children: React.ReactNode;
|
|
15
21
|
};
|
|
16
|
-
declare function AppTemplate({ config, headerActions, headerBreadcrumb, sidebarFooter, resolveIcon, icons, activePath, getActivePath, children, }: AppTemplateProps): react_jsx_runtime.JSX.Element;
|
|
22
|
+
declare function AppTemplate({ config, headerActions, headerBreadcrumb, sidebarFooter, resolveIcon, icons, activePath, getActivePath, sidebarDefaultExpanded, sidebarExpanded, onSidebarExpandedChange, sidebarCollapsedWidth, sidebarExpandedWidth, sidebarHoverExpand, children, }: AppTemplateProps): react_jsx_runtime.JSX.Element;
|
|
17
23
|
|
|
18
24
|
export { AppTemplate, type AppTemplateProps };
|
|
@@ -15,10 +15,22 @@ function AppTemplate({
|
|
|
15
15
|
icons,
|
|
16
16
|
activePath,
|
|
17
17
|
getActivePath,
|
|
18
|
+
sidebarDefaultExpanded = false,
|
|
19
|
+
sidebarExpanded,
|
|
20
|
+
onSidebarExpandedChange,
|
|
21
|
+
sidebarCollapsedWidth = "72px",
|
|
22
|
+
sidebarExpandedWidth = "224px",
|
|
23
|
+
sidebarHoverExpand = true,
|
|
18
24
|
children
|
|
19
25
|
}) {
|
|
20
26
|
const sidebarConfig = config.sidebar;
|
|
21
27
|
const headerConfig = config.header;
|
|
28
|
+
const [internalExpanded, setInternalExpanded] = React.useState(sidebarDefaultExpanded);
|
|
29
|
+
const resolvedExpanded = sidebarExpanded != null ? sidebarExpanded : internalExpanded;
|
|
30
|
+
const setExpanded = (next) => {
|
|
31
|
+
if (sidebarExpanded === void 0) setInternalExpanded(next);
|
|
32
|
+
onSidebarExpandedChange == null ? void 0 : onSidebarExpandedChange(next);
|
|
33
|
+
};
|
|
22
34
|
const resolvedActivePath = activePath != null ? activePath : getActivePath == null ? void 0 : getActivePath();
|
|
23
35
|
const buildIcon = React.useCallback(
|
|
24
36
|
(name) => {
|
|
@@ -43,12 +55,20 @@ function AppTemplate({
|
|
|
43
55
|
return /* @__PURE__ */ jsx(
|
|
44
56
|
AppShell,
|
|
45
57
|
{
|
|
58
|
+
style: {
|
|
59
|
+
"--nc-sidebar-width": resolvedExpanded ? sidebarExpandedWidth : sidebarCollapsedWidth
|
|
60
|
+
},
|
|
46
61
|
sidebar: sidebarConfig && sidebarItems ? /* @__PURE__ */ jsx(
|
|
47
62
|
Sidebar,
|
|
48
63
|
{
|
|
49
64
|
title: sidebarConfig.title,
|
|
50
65
|
items: sidebarItems,
|
|
51
|
-
footer: sidebarFooterNode
|
|
66
|
+
footer: sidebarFooterNode,
|
|
67
|
+
hoverExpand: sidebarHoverExpand,
|
|
68
|
+
expanded: resolvedExpanded,
|
|
69
|
+
onExpandedChange: setExpanded,
|
|
70
|
+
collapsedWidth: sidebarCollapsedWidth,
|
|
71
|
+
expandedWidth: sidebarExpandedWidth
|
|
52
72
|
}
|
|
53
73
|
) : void 0,
|
|
54
74
|
topNav: headerConfig ? /* @__PURE__ */ jsx(
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layout/app-template.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { AppShell } from \"./app-shell\";\nimport { CraftIcon } from \"@/components/craft-icon\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\nimport { Sidebar, type SidebarItem } from \"./sidebar\";\nimport { TopNav } from \"./top-nav\";\nimport type { LayoutConfig, LayoutSidebarItem } from \"./layout-config\";\n\nexport type AppTemplateProps = {\n config: LayoutConfig;\n headerActions?: React.ReactNode;\n headerBreadcrumb?: React.ReactNode;\n sidebarFooter?: React.ReactNode;\n resolveIcon?: (name: string) => React.ReactNode;\n icons?: Record<string, React.ReactNode>;\n activePath?: string;\n getActivePath?: () => string | undefined;\n children: React.ReactNode;\n};\n\nexport function AppTemplate({\n config,\n headerActions,\n headerBreadcrumb,\n sidebarFooter,\n resolveIcon,\n icons,\n activePath,\n getActivePath,\n children,\n}: AppTemplateProps) {\n const sidebarConfig = config.sidebar;\n const headerConfig = config.header;\n\n const resolvedActivePath = activePath ?? getActivePath?.();\n\n const buildIcon = React.useCallback(\n (name?: string) => {\n if (!name) return undefined;\n if (resolveIcon) return resolveIcon(name);\n if (icons?.[name]) return icons[name];\n return <CraftIcon name={name} size=\"lg\"/>;\n },\n [icons, resolveIcon]\n );\n\n const sidebarItems: SidebarItem[] | null = sidebarConfig\n ? sidebarConfig.items.map((item: LayoutSidebarItem) => ({\n label: item.label,\n href: item.href,\n active:\n item.active ??\n (resolvedActivePath && item.href\n ? item.href === resolvedActivePath\n : false),\n icon: buildIcon(item.icon),\n }))\n : null;\n\n const breadcrumbNode =\n headerBreadcrumb ??\n (headerConfig?.breadcrumb ? (\n <Breadcrumbs items={headerConfig.breadcrumb} />\n ) : null);\n\n const sidebarFooterNode =\n sidebarFooter ??\n (sidebarConfig?.footerText ? (\n <div className=\"text-xs text-[rgb(var(--nc-fg-muted))]\">\n {sidebarConfig.footerText}\n </div>\n ) : null);\n\n return (\n <AppShell\n sidebar={\n sidebarConfig && sidebarItems ? (\n <Sidebar\n title={sidebarConfig.title}\n items={sidebarItems}\n footer={sidebarFooterNode}\n />\n ) : undefined\n }\n topNav={\n headerConfig ? (\n <TopNav\n title={headerConfig.title}\n breadcrumb={breadcrumbNode}\n actions={headerActions}\n />\n ) : undefined\n }\n >\n {children}\n </AppShell>\n );\n}\n"],"mappings":";
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layout/app-template.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nimport { AppShell } from \"./app-shell\";\nimport { CraftIcon } from \"@/components/craft-icon\";\nimport { Breadcrumbs } from \"./breadcrumbs\";\nimport { Sidebar, type SidebarItem } from \"./sidebar\";\nimport { TopNav } from \"./top-nav\";\nimport type { LayoutConfig, LayoutSidebarItem } from \"./layout-config\";\n\nexport type AppTemplateProps = {\n config: LayoutConfig;\n headerActions?: React.ReactNode;\n headerBreadcrumb?: React.ReactNode;\n sidebarFooter?: React.ReactNode;\n resolveIcon?: (name: string) => React.ReactNode;\n icons?: Record<string, React.ReactNode>;\n activePath?: string;\n getActivePath?: () => string | undefined;\n sidebarDefaultExpanded?: boolean;\n sidebarExpanded?: boolean;\n onSidebarExpandedChange?: (expanded: boolean) => void;\n sidebarCollapsedWidth?: string;\n sidebarExpandedWidth?: string;\n sidebarHoverExpand?: boolean;\n children: React.ReactNode;\n};\n\nexport function AppTemplate({\n config,\n headerActions,\n headerBreadcrumb,\n sidebarFooter,\n resolveIcon,\n icons,\n activePath,\n getActivePath,\n sidebarDefaultExpanded = false,\n sidebarExpanded,\n onSidebarExpandedChange,\n sidebarCollapsedWidth = \"72px\",\n sidebarExpandedWidth = \"224px\",\n sidebarHoverExpand = true,\n children,\n}: AppTemplateProps) {\n const sidebarConfig = config.sidebar;\n const headerConfig = config.header;\n\n const [internalExpanded, setInternalExpanded] =\n React.useState(sidebarDefaultExpanded);\n const resolvedExpanded = sidebarExpanded ?? internalExpanded;\n const setExpanded = (next: boolean) => {\n if (sidebarExpanded === undefined) setInternalExpanded(next);\n onSidebarExpandedChange?.(next);\n };\n\n const resolvedActivePath = activePath ?? getActivePath?.();\n\n const buildIcon = React.useCallback(\n (name?: string) => {\n if (!name) return undefined;\n if (resolveIcon) return resolveIcon(name);\n if (icons?.[name]) return icons[name];\n return <CraftIcon name={name} size=\"lg\"/>;\n },\n [icons, resolveIcon]\n );\n\n const sidebarItems: SidebarItem[] | null = sidebarConfig\n ? sidebarConfig.items.map((item: LayoutSidebarItem) => ({\n label: item.label,\n href: item.href,\n active:\n item.active ??\n (resolvedActivePath && item.href\n ? item.href === resolvedActivePath\n : false),\n icon: buildIcon(item.icon),\n }))\n : null;\n\n const breadcrumbNode =\n headerBreadcrumb ??\n (headerConfig?.breadcrumb ? (\n <Breadcrumbs items={headerConfig.breadcrumb} />\n ) : null);\n\n const sidebarFooterNode =\n sidebarFooter ??\n (sidebarConfig?.footerText ? (\n <div className=\"text-xs text-[rgb(var(--nc-fg-muted))]\">\n {sidebarConfig.footerText}\n </div>\n ) : null);\n\n return (\n <AppShell\n style={\n {\n \"--nc-sidebar-width\": resolvedExpanded\n ? sidebarExpandedWidth\n : sidebarCollapsedWidth,\n } as React.CSSProperties\n }\n sidebar={\n sidebarConfig && sidebarItems ? (\n <Sidebar\n title={sidebarConfig.title}\n items={sidebarItems}\n footer={sidebarFooterNode}\n hoverExpand={sidebarHoverExpand}\n expanded={resolvedExpanded}\n onExpandedChange={setExpanded}\n collapsedWidth={sidebarCollapsedWidth}\n expandedWidth={sidebarExpandedWidth}\n />\n ) : undefined\n }\n topNav={\n headerConfig ? (\n <TopNav\n title={headerConfig.title}\n breadcrumb={breadcrumbNode}\n actions={headerActions}\n />\n ) : undefined\n }\n >\n {children}\n </AppShell>\n );\n}\n"],"mappings":";AAgEa;AA9Db,YAAY,WAAW;AAEvB,SAAS,gBAAgB;AACzB,SAAS,iBAAiB;AAC1B,SAAS,mBAAmB;AAC5B,SAAS,eAAiC;AAC1C,SAAS,cAAc;AAqBhB,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,yBAAyB;AAAA,EACzB;AAAA,EACA;AAAA,EACA,wBAAwB;AAAA,EACxB,uBAAuB;AAAA,EACvB,qBAAqB;AAAA,EACrB;AACF,GAAqB;AACnB,QAAM,gBAAgB,OAAO;AAC7B,QAAM,eAAe,OAAO;AAE5B,QAAM,CAAC,kBAAkB,mBAAmB,IAC1C,MAAM,SAAS,sBAAsB;AACvC,QAAM,mBAAmB,4CAAmB;AAC5C,QAAM,cAAc,CAAC,SAAkB;AACrC,QAAI,oBAAoB,OAAW,qBAAoB,IAAI;AAC3D,uEAA0B;AAAA,EAC5B;AAEA,QAAM,qBAAqB,kCAAc;AAEzC,QAAM,YAAY,MAAM;AAAA,IACtB,CAAC,SAAkB;AACjB,UAAI,CAAC,KAAM,QAAO;AAClB,UAAI,YAAa,QAAO,YAAY,IAAI;AACxC,UAAI,+BAAQ,MAAO,QAAO,MAAM,IAAI;AACpC,aAAO,oBAAC,aAAU,MAAY,MAAK,MAAI;AAAA,IACzC;AAAA,IACA,CAAC,OAAO,WAAW;AAAA,EACrB;AAEA,QAAM,eAAqC,gBACvC,cAAc,MAAM,IAAI,CAAC,SAAyB;AAtExD;AAsE4D;AAAA,MACpD,OAAO,KAAK;AAAA,MACZ,MAAM,KAAK;AAAA,MACX,SACE,UAAK,WAAL,YACC,sBAAsB,KAAK,OACxB,KAAK,SAAS,qBACd;AAAA,MACN,MAAM,UAAU,KAAK,IAAI;AAAA,IAC3B;AAAA,GAAE,IACF;AAEJ,QAAM,iBACJ,+CACC,6CAAc,cACb,oBAAC,eAAY,OAAO,aAAa,YAAY,IAC3C;AAEN,QAAM,oBACJ,yCACC,+CAAe,cACd,oBAAC,SAAI,WAAU,0CACZ,wBAAc,YACjB,IACE;AAEN,SACE;AAAA,IAAC;AAAA;AAAA,MACC,OACE;AAAA,QACE,sBAAsB,mBAClB,uBACA;AAAA,MACN;AAAA,MAEF,SACE,iBAAiB,eACf;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,cAAc;AAAA,UACrB,OAAO;AAAA,UACP,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,UAAU;AAAA,UACV,kBAAkB;AAAA,UAClB,gBAAgB;AAAA,UAChB,eAAe;AAAA;AAAA,MACjB,IACE;AAAA,MAEN,QACE,eACE;AAAA,QAAC;AAAA;AAAA,UACC,OAAO,aAAa;AAAA,UACpB,YAAY;AAAA,UACZ,SAAS;AAAA;AAAA,MACX,IACE;AAAA,MAGL;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -24,13 +24,23 @@ module.exports = __toCommonJS(breadcrumbs_exports);
|
|
|
24
24
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
25
25
|
var import_cn = require("../../utils/cn");
|
|
26
26
|
function Breadcrumbs({ className, items, ...props }) {
|
|
27
|
-
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
27
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
28
|
+
"nav",
|
|
29
|
+
{
|
|
30
|
+
className: (0, import_cn.cn)(
|
|
31
|
+
"flex items-center text-xs text-[rgb(var(--nc-fg-muted))]",
|
|
32
|
+
className
|
|
33
|
+
),
|
|
34
|
+
...props,
|
|
35
|
+
children: items.map((item, index) => {
|
|
36
|
+
const content = item.href ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)("a", { href: item.href, className: "transition hover:text-[rgb(var(--nc-fg))]", children: item.label }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "text-[rgb(var(--nc-fg))]", children: item.label });
|
|
37
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("span", { className: "flex items-center", children: [
|
|
38
|
+
content,
|
|
39
|
+
index < items.length - 1 && /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: "mx-2 text-[rgb(var(--nc-fg-soft))]", children: "/" })
|
|
40
|
+
] }, `${item.label}-${index}`);
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
);
|
|
34
44
|
}
|
|
35
45
|
// Annotate the CommonJS export names for ESM import in node:
|
|
36
46
|
0 && (module.exports = {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/components/layout/breadcrumbs.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type BreadcrumbItem = {\n label: React.ReactNode;\n href?: string;\n};\n\nexport type BreadcrumbsProps = React.HTMLAttributes<HTMLElement> & {\n items: BreadcrumbItem[];\n};\n\nexport function Breadcrumbs({ className, items, ...props }: BreadcrumbsProps) {\n return (\n <nav
|
|
1
|
+
{"version":3,"sources":["../../../src/components/layout/breadcrumbs.tsx"],"sourcesContent":["import * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\n\nexport type BreadcrumbItem = {\n label: React.ReactNode;\n href?: string;\n};\n\nexport type BreadcrumbsProps = React.HTMLAttributes<HTMLElement> & {\n items: BreadcrumbItem[];\n};\n\nexport function Breadcrumbs({ className, items, ...props }: BreadcrumbsProps) {\n return (\n <nav\n className={cn(\n \"flex items-center text-xs text-[rgb(var(--nc-fg-muted))]\",\n className\n )}\n {...props}\n >\n {items.map((item, index) => {\n const content = item.href ? (\n <a href={item.href} className=\"transition hover:text-[rgb(var(--nc-fg))]\">\n {item.label}\n </a>\n ) : (\n <span className=\"text-[rgb(var(--nc-fg))]\">{item.label}</span>\n );\n\n return (\n <span key={`${item.label}-${index}`} className=\"flex items-center\">\n {content}\n {index < items.length - 1 && (\n <span className=\"mx-2 text-[rgb(var(--nc-fg-soft))]\">/</span>\n )}\n </span>\n );\n })}\n </nav>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAwBU;AAtBV,gBAAmB;AAWZ,SAAS,YAAY,EAAE,WAAW,OAAO,GAAG,MAAM,GAAqB;AAC5E,SACE;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,QACT;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEH,gBAAM,IAAI,CAAC,MAAM,UAAU;AAC1B,cAAM,UAAU,KAAK,OACnB,4CAAC,OAAE,MAAM,KAAK,MAAM,WAAU,6CAC3B,eAAK,OACR,IAEA,4CAAC,UAAK,WAAU,4BAA4B,eAAK,OAAM;AAGzD,eACE,6CAAC,UAAoC,WAAU,qBAC5C;AAAA;AAAA,UACA,QAAQ,MAAM,SAAS,KACtB,4CAAC,UAAK,WAAU,sCAAqC,eAAC;AAAA,aAH/C,GAAG,KAAK,KAAK,IAAI,KAAK,EAKjC;AAAA,MAEJ,CAAC;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -1,13 +1,23 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../../utils/cn";
|
|
3
3
|
function Breadcrumbs({ className, items, ...props }) {
|
|
4
|
-
return /* @__PURE__ */ jsx(
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
4
|
+
return /* @__PURE__ */ jsx(
|
|
5
|
+
"nav",
|
|
6
|
+
{
|
|
7
|
+
className: cn(
|
|
8
|
+
"flex items-center text-xs text-[rgb(var(--nc-fg-muted))]",
|
|
9
|
+
className
|
|
10
|
+
),
|
|
11
|
+
...props,
|
|
12
|
+
children: items.map((item, index) => {
|
|
13
|
+
const content = item.href ? /* @__PURE__ */ jsx("a", { href: item.href, className: "transition hover:text-[rgb(var(--nc-fg))]", children: item.label }) : /* @__PURE__ */ jsx("span", { className: "text-[rgb(var(--nc-fg))]", children: item.label });
|
|
14
|
+
return /* @__PURE__ */ jsxs("span", { className: "flex items-center", children: [
|
|
15
|
+
content,
|
|
16
|
+
index < items.length - 1 && /* @__PURE__ */ jsx("span", { className: "mx-2 text-[rgb(var(--nc-fg-soft))]", children: "/" })
|
|
17
|
+
] }, `${item.label}-${index}`);
|
|
18
|
+
})
|
|
19
|
+
}
|
|
20
|
+
);
|
|
11
21
|
}
|
|
12
22
|
export {
|
|
13
23
|
Breadcrumbs
|