@lobehub/ui 5.59.0 → 5.60.0
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/es/ActionIcon/style.mjs +8 -2
- package/es/ActionIcon/style.mjs.map +1 -1
- package/es/awesome/Grainient/Grainient.d.mts +11 -0
- package/es/awesome/Grainient/Grainient.mjs +311 -0
- package/es/awesome/Grainient/Grainient.mjs.map +1 -0
- package/es/awesome/Grainient/index.d.mts +3 -0
- package/es/awesome/Grainient/style.mjs +25 -0
- package/es/awesome/Grainient/style.mjs.map +1 -0
- package/es/awesome/Grainient/type.d.mts +122 -0
- package/es/awesome/index.d.mts +4 -1
- package/es/awesome/index.mjs +2 -1
- package/es/base-ui/ActionIcon/style.mjs +8 -2
- package/es/base-ui/ActionIcon/style.mjs.map +1 -1
- package/es/dashboard/AuthLayout/Aside.d.mts +10 -0
- package/es/dashboard/AuthLayout/Aside.mjs +30 -0
- package/es/dashboard/AuthLayout/Aside.mjs.map +1 -0
- package/es/dashboard/AuthLayout/AuthLayout.d.mts +3 -1
- package/es/dashboard/AuthLayout/AuthLayout.mjs +93 -37
- package/es/dashboard/AuthLayout/AuthLayout.mjs.map +1 -1
- package/es/dashboard/AuthLayout/index.d.mts +3 -2
- package/es/dashboard/AuthLayout/style.mjs +120 -1
- package/es/dashboard/AuthLayout/style.mjs.map +1 -1
- package/es/dashboard/AuthLayout/type.d.mts +39 -3
- package/es/dashboard/AuthTools/AuthLocaleSwitch.d.mts +10 -0
- package/es/dashboard/AuthTools/AuthLocaleSwitch.mjs +32 -0
- package/es/dashboard/AuthTools/AuthLocaleSwitch.mjs.map +1 -0
- package/es/dashboard/AuthTools/AuthThemeSwitch.d.mts +10 -0
- package/es/dashboard/AuthTools/AuthThemeSwitch.mjs +59 -0
- package/es/dashboard/AuthTools/AuthThemeSwitch.mjs.map +1 -0
- package/es/dashboard/AuthTools/index.d.mts +4 -0
- package/es/dashboard/AuthTools/style.mjs +63 -0
- package/es/dashboard/AuthTools/style.mjs.map +1 -0
- package/es/dashboard/AuthTools/type.d.mts +30 -0
- package/es/dashboard/ConsoleNav/Skeleton.d.mts +15 -0
- package/es/dashboard/ConsoleNav/Skeleton.mjs +81 -0
- package/es/dashboard/ConsoleNav/Skeleton.mjs.map +1 -0
- package/es/dashboard/ConsoleNav/index.d.mts +3 -2
- package/es/dashboard/ConsoleNav/style.mjs +15 -0
- package/es/dashboard/ConsoleNav/style.mjs.map +1 -1
- package/es/dashboard/ConsoleNav/type.d.mts +14 -1
- package/es/dashboard/ConsoleShell/ConsoleShell.d.mts +1 -1
- package/es/dashboard/ConsoleShell/ConsoleShell.mjs +11 -3
- package/es/dashboard/ConsoleShell/ConsoleShell.mjs.map +1 -1
- package/es/dashboard/ConsoleShell/style.mjs +6 -0
- package/es/dashboard/ConsoleShell/style.mjs.map +1 -1
- package/es/dashboard/ConsoleShell/type.d.mts +9 -0
- package/es/dashboard/FilterSidebar/FilterSidebar.mjs +18 -17
- package/es/dashboard/FilterSidebar/FilterSidebar.mjs.map +1 -1
- package/es/dashboard/FilterStrip/FilterStrip.mjs +36 -32
- package/es/dashboard/FilterStrip/FilterStrip.mjs.map +1 -1
- package/es/dashboard/FilterStrip/style.mjs +2 -1
- package/es/dashboard/FilterStrip/style.mjs.map +1 -1
- package/es/dashboard/MetricStrip/MetricCell.mjs +81 -0
- package/es/dashboard/MetricStrip/MetricCell.mjs.map +1 -0
- package/es/dashboard/MetricStrip/MetricStrip.d.mts +5 -2
- package/es/dashboard/MetricStrip/MetricStrip.mjs +33 -62
- package/es/dashboard/MetricStrip/MetricStrip.mjs.map +1 -1
- package/es/dashboard/MetricStrip/style.mjs +49 -4
- package/es/dashboard/MetricStrip/style.mjs.map +1 -1
- package/es/dashboard/MetricStrip/type.d.mts +12 -0
- package/es/dashboard/PageSkeleton/PageSkeleton.mjs +20 -18
- package/es/dashboard/PageSkeleton/PageSkeleton.mjs.map +1 -1
- package/es/dashboard/PageSkeleton/style.mjs +1 -1
- package/es/dashboard/PageSkeleton/style.mjs.map +1 -1
- package/es/dashboard/PanelSurface/PanelSurface.mjs +4 -1
- package/es/dashboard/PanelSurface/PanelSurface.mjs.map +1 -1
- package/es/dashboard/StatCard/StatCard.d.mts +2 -1
- package/es/dashboard/StatCard/StatCard.mjs +24 -72
- package/es/dashboard/StatCard/StatCard.mjs.map +1 -1
- package/es/dashboard/StatCard/type.d.mts +16 -5
- package/es/dashboard/Surface/Surface.mjs +26 -10
- package/es/dashboard/Surface/Surface.mjs.map +1 -1
- package/es/dashboard/Surface/index.d.mts +2 -2
- package/es/dashboard/Surface/link.d.mts +6 -1
- package/es/dashboard/Surface/link.mjs +12 -1
- package/es/dashboard/Surface/link.mjs.map +1 -1
- package/es/dashboard/Surface/style.d.mts +22 -3
- package/es/dashboard/Surface/style.mjs +95 -26
- package/es/dashboard/Surface/style.mjs.map +1 -1
- package/es/dashboard/index.d.mts +10 -4
- package/es/dashboard/index.mjs +7 -3
- package/package.json +1 -1
- package/es/dashboard/StatCard/style.mjs +0 -135
- package/es/dashboard/StatCard/style.mjs.map +0 -1
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { createStaticStyles } from "antd-style";
|
|
2
|
+
//#region src/dashboard/AuthTools/style.ts
|
|
3
|
+
const styles = createStaticStyles(({ css, cssVar }) => ({
|
|
4
|
+
locale: css`
|
|
5
|
+
&& {
|
|
6
|
+
inline-size: fit-content;
|
|
7
|
+
min-inline-size: 120px;
|
|
8
|
+
block-size: 28px;
|
|
9
|
+
border-radius: 28px;
|
|
10
|
+
|
|
11
|
+
background: ${cssVar.colorBgLayout};
|
|
12
|
+
}
|
|
13
|
+
`,
|
|
14
|
+
localeIcon: css`
|
|
15
|
+
margin-inline-end: 2px;
|
|
16
|
+
`,
|
|
17
|
+
theme: css`
|
|
18
|
+
&& {
|
|
19
|
+
block-size: 28px;
|
|
20
|
+
padding: 2px;
|
|
21
|
+
border-radius: 28px;
|
|
22
|
+
}
|
|
23
|
+
`,
|
|
24
|
+
themeIcon: css`
|
|
25
|
+
inline-size: 16px;
|
|
26
|
+
block-size: 16px;
|
|
27
|
+
`,
|
|
28
|
+
themeIndicator: css`
|
|
29
|
+
&& {
|
|
30
|
+
border-radius: 22px;
|
|
31
|
+
}
|
|
32
|
+
`,
|
|
33
|
+
themeItem: css`
|
|
34
|
+
&& {
|
|
35
|
+
block-size: 22px;
|
|
36
|
+
padding-inline: 8px;
|
|
37
|
+
border-radius: 22px;
|
|
38
|
+
}
|
|
39
|
+
`,
|
|
40
|
+
themeLabel: css`
|
|
41
|
+
position: absolute;
|
|
42
|
+
|
|
43
|
+
overflow: hidden;
|
|
44
|
+
|
|
45
|
+
inline-size: 1px;
|
|
46
|
+
block-size: 1px;
|
|
47
|
+
padding: 0;
|
|
48
|
+
border: 0;
|
|
49
|
+
|
|
50
|
+
white-space: nowrap;
|
|
51
|
+
|
|
52
|
+
clip-path: inset(50%);
|
|
53
|
+
`,
|
|
54
|
+
toolRow: css`
|
|
55
|
+
display: flex;
|
|
56
|
+
gap: 8px;
|
|
57
|
+
align-items: center;
|
|
58
|
+
`
|
|
59
|
+
}));
|
|
60
|
+
//#endregion
|
|
61
|
+
export { styles };
|
|
62
|
+
|
|
63
|
+
//# sourceMappingURL=style.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/dashboard/AuthTools/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nexport const styles = createStaticStyles(({ css, cssVar }) => ({\n locale: css`\n && {\n inline-size: fit-content;\n min-inline-size: 120px;\n block-size: 28px;\n border-radius: 28px;\n\n background: ${cssVar.colorBgLayout};\n }\n `,\n localeIcon: css`\n margin-inline-end: 2px;\n `,\n theme: css`\n && {\n block-size: 28px;\n padding: 2px;\n border-radius: 28px;\n }\n `,\n themeIcon: css`\n inline-size: 16px;\n block-size: 16px;\n `,\n themeIndicator: css`\n && {\n border-radius: 22px;\n }\n `,\n themeItem: css`\n && {\n block-size: 22px;\n padding-inline: 8px;\n border-radius: 22px;\n }\n `,\n themeLabel: css`\n position: absolute;\n\n overflow: hidden;\n\n inline-size: 1px;\n block-size: 1px;\n padding: 0;\n border: 0;\n\n white-space: nowrap;\n\n clip-path: inset(50%);\n `,\n toolRow: css`\n display: flex;\n gap: 8px;\n align-items: center;\n `,\n}));\n"],"mappings":";;AAEA,MAAa,SAAS,oBAAoB,EAAE,KAAK,cAAc;CAC7D,QAAQ,GAAG;;;;;;;oBAOO,OAAO,cAAc;;;CAGvC,YAAY,GAAG;;;CAGf,OAAO,GAAG;;;;;;;CAOV,WAAW,GAAG;;;;CAId,gBAAgB,GAAG;;;;;CAKnB,WAAW,GAAG;;;;;;;CAOd,YAAY,GAAG;;;;;;;;;;;;;;CAcf,SAAS,GAAG;;;;;AAKd,EAAE"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { CSSProperties } from "react";
|
|
2
|
+
//#region src/dashboard/AuthTools/type.d.ts
|
|
3
|
+
type AuthThemeMode = 'auto' | 'dark' | 'light';
|
|
4
|
+
interface AuthThemeSwitchProps {
|
|
5
|
+
className?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Accessible names, also shown as tooltips. Labels are visually hidden.
|
|
8
|
+
* @default { auto: 'System', dark: 'Dark', light: 'Light' }
|
|
9
|
+
*/
|
|
10
|
+
labels?: Partial<Record<AuthThemeMode, string>>;
|
|
11
|
+
onChange?: (mode: AuthThemeMode) => void;
|
|
12
|
+
style?: CSSProperties;
|
|
13
|
+
value?: AuthThemeMode;
|
|
14
|
+
}
|
|
15
|
+
interface AuthLocaleOption {
|
|
16
|
+
label: string;
|
|
17
|
+
value: string;
|
|
18
|
+
}
|
|
19
|
+
interface AuthLocaleSwitchProps {
|
|
20
|
+
/** Accessible name of the select. @default 'Language' */
|
|
21
|
+
'aria-label'?: string;
|
|
22
|
+
'className'?: string;
|
|
23
|
+
'onChange'?: (locale: string) => void;
|
|
24
|
+
'options': AuthLocaleOption[];
|
|
25
|
+
'style'?: CSSProperties;
|
|
26
|
+
'value'?: string;
|
|
27
|
+
}
|
|
28
|
+
//#endregion
|
|
29
|
+
export { AuthLocaleOption, AuthLocaleSwitchProps, AuthThemeMode, AuthThemeSwitchProps };
|
|
30
|
+
//# sourceMappingURL=type.d.mts.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ConsoleNavSkeletonProps } from "./type.mjs";
|
|
2
|
+
//#region src/dashboard/ConsoleNav/Skeleton.d.ts
|
|
3
|
+
/**
|
|
4
|
+
* Placeholder for `ConsoleNav` while the session or menu loads. Rows use the nav's own item,
|
|
5
|
+
* group header and indent metrics, so swapping in the real nav does not shift anything.
|
|
6
|
+
*/
|
|
7
|
+
declare function ConsoleNavSkeleton({ className, groups, items }: ConsoleNavSkeletonProps): import("react").JSX.Element;
|
|
8
|
+
declare namespace ConsoleNavSkeleton {
|
|
9
|
+
var displayName: string;
|
|
10
|
+
}
|
|
11
|
+
/** Footer placeholder matching an account row: avatar plus name. */
|
|
12
|
+
declare function ConsoleFooterSkeleton(): import("react").JSX.Element;
|
|
13
|
+
//#endregion
|
|
14
|
+
export { ConsoleFooterSkeleton, ConsoleNavSkeleton as default };
|
|
15
|
+
//# sourceMappingURL=Skeleton.d.mts.map
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import Skeleton from "../../base-ui/Skeleton/index.mjs";
|
|
3
|
+
import { styles } from "./style.mjs";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
import { cx } from "antd-style";
|
|
6
|
+
//#region src/dashboard/ConsoleNav/Skeleton.tsx
|
|
7
|
+
const DEFAULT_GROUPS = [
|
|
8
|
+
3,
|
|
9
|
+
6,
|
|
10
|
+
4,
|
|
11
|
+
3
|
|
12
|
+
];
|
|
13
|
+
const Row = ({ group, index }) => /* @__PURE__ */ jsxs("div", {
|
|
14
|
+
className: cx(styles.item, styles.skeletonRow),
|
|
15
|
+
"data-indent": 0,
|
|
16
|
+
children: [/* @__PURE__ */ jsx(Skeleton, {
|
|
17
|
+
height: 16,
|
|
18
|
+
radius: 4,
|
|
19
|
+
width: 16
|
|
20
|
+
}), /* @__PURE__ */ jsx(Skeleton, {
|
|
21
|
+
height: 14,
|
|
22
|
+
radius: 4,
|
|
23
|
+
width: 56 + (index + group) % 3 * 20
|
|
24
|
+
})]
|
|
25
|
+
});
|
|
26
|
+
/**
|
|
27
|
+
* Placeholder for `ConsoleNav` while the session or menu loads. Rows use the nav's own item,
|
|
28
|
+
* group header and indent metrics, so swapping in the real nav does not shift anything.
|
|
29
|
+
*/
|
|
30
|
+
function ConsoleNavSkeleton({ className, groups = DEFAULT_GROUPS, items = 1 }) {
|
|
31
|
+
const counts = groups.map((group) => typeof group === "number" ? group : group.items?.length ?? 0);
|
|
32
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
33
|
+
"aria-hidden": true,
|
|
34
|
+
className: cx(styles.nav, className),
|
|
35
|
+
"data-console-nav-skeleton": "",
|
|
36
|
+
children: [Array.from({ length: items }, (_, index) => /* @__PURE__ */ jsx(Row, {
|
|
37
|
+
group: 0,
|
|
38
|
+
index
|
|
39
|
+
}, index)), counts.map((count, group) => /* @__PURE__ */ jsxs("div", {
|
|
40
|
+
className: styles.skeletonGroup,
|
|
41
|
+
children: [/* @__PURE__ */ jsx("div", {
|
|
42
|
+
className: cx(styles.groupHeader, styles.skeletonRow),
|
|
43
|
+
"data-level": 0,
|
|
44
|
+
children: /* @__PURE__ */ jsx(Skeleton, {
|
|
45
|
+
height: 12,
|
|
46
|
+
radius: 4,
|
|
47
|
+
width: 64 + group % 2 * 16
|
|
48
|
+
})
|
|
49
|
+
}), Array.from({ length: count }, (_, index) => /* @__PURE__ */ jsx("div", {
|
|
50
|
+
className: cx(styles.item, styles.skeletonRow),
|
|
51
|
+
"data-indent": 1,
|
|
52
|
+
children: /* @__PURE__ */ jsx(Skeleton, {
|
|
53
|
+
height: 14,
|
|
54
|
+
radius: 4,
|
|
55
|
+
width: 56 + (index + group) % 3 * 20
|
|
56
|
+
})
|
|
57
|
+
}, index))]
|
|
58
|
+
}, group))]
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
ConsoleNavSkeleton.displayName = "ConsoleNavSkeleton";
|
|
62
|
+
/** Footer placeholder matching an account row: avatar plus name. */
|
|
63
|
+
function ConsoleFooterSkeleton() {
|
|
64
|
+
return /* @__PURE__ */ jsxs("div", {
|
|
65
|
+
"aria-hidden": true,
|
|
66
|
+
className: styles.skeletonFooter,
|
|
67
|
+
children: [/* @__PURE__ */ jsx(Skeleton, {
|
|
68
|
+
height: 32,
|
|
69
|
+
radius: 16,
|
|
70
|
+
width: 32
|
|
71
|
+
}), /* @__PURE__ */ jsx(Skeleton, {
|
|
72
|
+
height: 14,
|
|
73
|
+
radius: 4,
|
|
74
|
+
width: 96
|
|
75
|
+
})]
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
//#endregion
|
|
79
|
+
export { ConsoleFooterSkeleton, ConsoleNavSkeleton as default };
|
|
80
|
+
|
|
81
|
+
//# sourceMappingURL=Skeleton.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Skeleton.mjs","names":[],"sources":["../../../src/dashboard/ConsoleNav/Skeleton.tsx"],"sourcesContent":["'use client';\n\nimport { cx } from 'antd-style';\n\nimport Skeleton from '@/base-ui/Skeleton';\n\nimport { styles } from './style';\nimport type { ConsoleNavGroup, ConsoleNavSkeletonProps } from './type';\n\nconst DEFAULT_GROUPS = [3, 6, 4, 3];\n\nconst Row = ({ group, index }: { group: number; index: number }) => (\n <div className={cx(styles.item, styles.skeletonRow)} data-indent={0}>\n <Skeleton height={16} radius={4} width={16} />\n <Skeleton height={14} radius={4} width={56 + ((index + group) % 3) * 20} />\n </div>\n);\n\n/**\n * Placeholder for `ConsoleNav` while the session or menu loads. Rows use the nav's own item,\n * group header and indent metrics, so swapping in the real nav does not shift anything.\n */\nfunction ConsoleNavSkeleton({\n className,\n groups = DEFAULT_GROUPS,\n items = 1,\n}: ConsoleNavSkeletonProps) {\n const counts = groups.map((group: number | ConsoleNavGroup) =>\n typeof group === 'number' ? group : (group.items?.length ?? 0),\n );\n return (\n <div aria-hidden className={cx(styles.nav, className)} data-console-nav-skeleton=\"\">\n {Array.from({ length: items }, (_, index) => (\n <Row group={0} index={index} key={index} />\n ))}\n {counts.map((count, group) => (\n <div className={styles.skeletonGroup} key={group}>\n <div className={cx(styles.groupHeader, styles.skeletonRow)} data-level={0}>\n <Skeleton height={12} radius={4} width={64 + (group % 2) * 16} />\n </div>\n {Array.from({ length: count }, (_, index) => (\n <div className={cx(styles.item, styles.skeletonRow)} data-indent={1} key={index}>\n <Skeleton height={14} radius={4} width={56 + ((index + group) % 3) * 20} />\n </div>\n ))}\n </div>\n ))}\n </div>\n );\n}\n\nConsoleNavSkeleton.displayName = 'ConsoleNavSkeleton';\n\n/** Footer placeholder matching an account row: avatar plus name. */\nexport function ConsoleFooterSkeleton() {\n return (\n <div aria-hidden className={styles.skeletonFooter}>\n <Skeleton height={32} radius={16} width={32} />\n <Skeleton height={14} radius={4} width={96} />\n </div>\n );\n}\n\nexport default ConsoleNavSkeleton;\n"],"mappings":";;;;;;AASA,MAAM,iBAAiB;CAAC;CAAG;CAAG;CAAG;AAAC;AAElC,MAAM,OAAO,EAAE,OAAO,YACpB,qBAAC,OAAD;CAAK,WAAW,GAAG,OAAO,MAAM,OAAO,WAAW;CAAG,eAAa;CAAlE,UAAA,CACE,oBAAC,UAAD;EAAU,QAAQ;EAAI,QAAQ;EAAG,OAAO;CAAK,CAAA,GAC7C,oBAAC,UAAD;EAAU,QAAQ;EAAI,QAAQ;EAAG,OAAO,MAAO,QAAQ,SAAS,IAAK;CAAK,CAAA,CACvE;;;;;;AAOP,SAAS,mBAAmB,EAC1B,WACA,SAAS,gBACT,QAAQ,KACkB;CAC1B,MAAM,SAAS,OAAO,KAAK,UACzB,OAAO,UAAU,WAAW,QAAS,MAAM,OAAO,UAAU,CAC9D;CACA,OACE,qBAAC,OAAD;EAAK,eAAA;EAAY,WAAW,GAAG,OAAO,KAAK,SAAS;EAAG,6BAA0B;EAAjF,UAAA,CACG,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,GAAG,UACjC,oBAAC,KAAD;GAAK,OAAO;GAAU;EAAoB,GAAR,KAAQ,CAC3C,GACA,OAAO,KAAK,OAAO,UAClB,qBAAC,OAAD;GAAK,WAAW,OAAO;GAAvB,UAAA,CACE,oBAAC,OAAD;IAAK,WAAW,GAAG,OAAO,aAAa,OAAO,WAAW;IAAG,cAAY;IACtE,UAAA,oBAAC,UAAD;KAAU,QAAQ;KAAI,QAAQ;KAAG,OAAO,KAAM,QAAQ,IAAK;IAAK,CAAA;GAC7D,CAAA,GACJ,MAAM,KAAK,EAAE,QAAQ,MAAM,IAAI,GAAG,UACjC,oBAAC,OAAD;IAAK,WAAW,GAAG,OAAO,MAAM,OAAO,WAAW;IAAG,eAAa;IAChE,UAAA,oBAAC,UAAD;KAAU,QAAQ;KAAI,QAAQ;KAAG,OAAO,MAAO,QAAQ,SAAS,IAAK;IAAK,CAAA;GACvE,GAFqE,KAErE,CACN,CACE;EATsC,GAAA,KAStC,CACN,CACE;;AAET;AAEA,mBAAmB,cAAc;;AAGjC,SAAgB,wBAAwB;CACtC,OACE,qBAAC,OAAD;EAAK,eAAA;EAAY,WAAW,OAAO;EAAnC,UAAA,CACE,oBAAC,UAAD;GAAU,QAAQ;GAAI,QAAQ;GAAI,OAAO;EAAK,CAAA,GAC9C,oBAAC,UAAD;GAAU,QAAQ;GAAI,QAAQ;GAAG,OAAO;EAAK,CAAA,CAC1C;;AAET"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { ConsoleNavGroup, ConsoleNavItem, ConsoleNavLinkProps, ConsoleNavProps } from "./type.mjs";
|
|
1
|
+
import { ConsoleNavGroup, ConsoleNavItem, ConsoleNavLinkProps, ConsoleNavProps, ConsoleNavSkeletonProps } from "./type.mjs";
|
|
2
2
|
import { resolveActiveHref } from "./active.mjs";
|
|
3
3
|
import ConsoleNav from "./ConsoleNav.mjs";
|
|
4
|
-
|
|
4
|
+
import ConsoleNavSkeleton, { ConsoleFooterSkeleton } from "./Skeleton.mjs";
|
|
5
|
+
export { ConsoleFooterSkeleton, type ConsoleNavGroup, type ConsoleNavItem, type ConsoleNavProps, ConsoleNavSkeleton, type ConsoleNavSkeletonProps, ConsoleNav as default, resolveActiveHref };
|
|
@@ -372,6 +372,21 @@ const styles = createStaticStyles(({ css, cssVar, responsive }) => {
|
|
|
372
372
|
@starting-style {
|
|
373
373
|
background: transparent;
|
|
374
374
|
}
|
|
375
|
+
`,
|
|
376
|
+
skeletonFooter: css`
|
|
377
|
+
display: flex;
|
|
378
|
+
gap: 10px;
|
|
379
|
+
align-items: center;
|
|
380
|
+
padding-inline: 4px;
|
|
381
|
+
`,
|
|
382
|
+
skeletonGroup: css`
|
|
383
|
+
display: flex;
|
|
384
|
+
flex-direction: column;
|
|
385
|
+
gap: 2px;
|
|
386
|
+
margin-block-start: 12px;
|
|
387
|
+
`,
|
|
388
|
+
skeletonRow: css`
|
|
389
|
+
pointer-events: none;
|
|
375
390
|
`,
|
|
376
391
|
topItems: css`
|
|
377
392
|
display: flex;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/dashboard/ConsoleNav/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nexport const styles = createStaticStyles(({ css, cssVar, responsive }) => {\n // Fades out at once on collapse, but waits on expand until the width has room for the text.\n const railFade = `\n transition: opacity 120ms ease 80ms;\n\n [data-collapsed='true'] & {\n opacity: 0;\n transition-delay: 0s;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `;\n\n return {\n badge: css`\n flex: none;\n\n min-inline-size: 20px;\n padding-inline: 6px;\n border-radius: 999px;\n\n font-size: ${cssVar.fontSizeSM};\n font-variant-numeric: tabular-nums;\n color: ${cssVar.colorError};\n text-align: center;\n\n background: color-mix(in srgb, ${cssVar.colorError} 12%, transparent);\n\n ${railFade}\n `,\n chevron: css`\n flex: none;\n transition:\n transform 160ms ease,\n opacity 120ms ease 80ms;\n\n &[data-expanded='false'] {\n transform: rotate(-90deg);\n }\n\n [data-collapsed='true'] & {\n opacity: 0;\n transition-delay: 0s;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n indicator: css`\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n\n width: 18px;\n height: 18px;\n margin-inline-start: -6px;\n\n color: ${cssVar.colorTextDescription};\n\n transition: transform 160ms ease;\n\n &[data-expanded='true'] {\n transform: rotate(90deg);\n }\n `,\n dot: css`\n position: absolute;\n inset-block-start: 7px;\n inset-inline-end: 9px;\n\n inline-size: 7px;\n block-size: 7px;\n border-radius: 999px;\n\n opacity: 0;\n background: ${cssVar.colorError};\n\n transition: opacity 120ms ease;\n\n [data-collapsed='true'] & {\n opacity: 1;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n fold: css`\n display: grid;\n grid-template-rows: 1fr;\n transition:\n grid-template-rows 200ms ease,\n margin 200ms ease,\n opacity 120ms ease;\n\n > div {\n overflow: hidden;\n min-block-size: 0;\n }\n\n &[data-folded='true'] {\n grid-template-rows: 0fr;\n opacity: 0;\n }\n\n &[data-folded='true']:not(:first-child) {\n margin-block-start: -2px;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n group: css`\n position: relative;\n\n display: flex;\n flex-direction: column;\n\n margin-block-start: 12px;\n\n transition: margin 200ms ease;\n\n &::before {\n content: '';\n\n position: absolute;\n inset-block-start: -6px;\n inset-inline: 0;\n\n block-size: 1px;\n\n opacity: 0;\n background: ${cssVar.colorBorderSecondary};\n\n transition: opacity 200ms ease;\n }\n\n &[data-level='0'][data-icon='true'] {\n margin-block-start: 2px;\n }\n\n &:not([data-level='0']) {\n margin-block-start: 6px;\n }\n\n [data-collapsed='true'] & + &[data-level='0'][data-icon='false']::before {\n opacity: 1;\n }\n\n [data-collapsed='true'] &[data-rail-empty='true'] {\n margin-block-start: 0;\n\n &::before {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n\n &::before {\n transition: none;\n }\n }\n `,\n groupHead: css`\n position: relative;\n display: flex;\n flex-direction: column;\n `,\n groupHeader: css`\n cursor: pointer;\n\n display: flex;\n gap: 8px;\n align-items: center;\n justify-content: space-between;\n\n min-block-size: 32px;\n padding-inline: 10px;\n border: none;\n border-radius: ${cssVar.borderRadius};\n\n font-size: ${cssVar.fontSizeSM};\n font-weight: 500;\n color: ${cssVar.colorTextSecondary};\n text-align: start;\n white-space: nowrap;\n\n background: none;\n\n &:hover,\n &[data-active='true'] {\n color: ${cssVar.colorText};\n }\n\n &[data-icon='true'] {\n gap: 10px;\n justify-content: flex-start;\n min-block-size: 36px;\n font-size: ${cssVar.fontSize};\n\n > [role='img'] {\n justify-content: center;\n inline-size: 18px;\n }\n }\n\n &[data-level='0'][data-icon='true']:hover {\n background: ${cssVar.colorFillTertiary};\n }\n\n /* Nested groups read as quiet subheadings with the indicator right after the label. */\n &:not([data-level='0']) {\n gap: 8px;\n justify-content: flex-start;\n\n min-block-size: 26px;\n\n font-size: ${cssVar.fontSizeSM};\n font-weight: 400;\n color: ${cssVar.colorTextDescription};\n\n > [data-label] {\n flex: 0 1 auto;\n }\n\n &:hover,\n &[data-active='true'] {\n color: ${cssVar.colorTextSecondary};\n }\n }\n\n &[data-indent='1'] {\n padding-inline-start: 38px;\n }\n\n &[data-indent='2'] {\n padding-inline-start: 56px;\n }\n\n > [role='img'] {\n display: flex;\n flex: none;\n }\n `,\n groupItems: css`\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-block-size: 0;\n `,\n groupPanel: css`\n display: grid;\n grid-template-rows: 1fr;\n transition: grid-template-rows 160ms ease;\n\n > div {\n overflow: hidden;\n }\n\n &[data-expanded='false'] {\n grid-template-rows: 0fr;\n }\n\n &[data-instant='true'] {\n transition: none;\n }\n `,\n item: css`\n position: relative;\n\n display: flex;\n gap: 10px;\n align-items: center;\n\n min-block-size: 36px;\n padding-inline: 10px;\n border-radius: ${cssVar.borderRadius};\n\n color: ${cssVar.colorTextSecondary};\n text-decoration: none;\n white-space: nowrap;\n\n transition:\n background 120ms ease,\n color 120ms ease;\n\n &:hover {\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillTertiary};\n }\n\n &[data-active='true'] {\n font-weight: 500;\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillSecondary};\n }\n\n &[data-indent='1'],\n &[data-indent='2'] {\n min-block-size: 32px;\n color: ${cssVar.colorText};\n }\n\n &[data-indent='1'] {\n padding-inline-start: 38px;\n }\n\n &[data-indent='2'] {\n padding-inline-start: 56px;\n }\n\n [data-collapsed='true'] &:not([data-indent='0']) {\n padding-inline-start: 10px;\n }\n\n > [role='img'] {\n display: flex;\n flex: none;\n }\n\n ${responsive.mobile} {\n min-block-size: 44px;\n }\n `,\n itemLabel: css`\n overflow: hidden;\n flex: 1;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n [data-collapsed='true'] & {\n text-overflow: clip;\n }\n\n ${railFade}\n `,\n nav: css`\n /* Scroll anchoring would jump the list in one frame while rail rows fold and unfold. */\n overflow-anchor: none;\n scrollbar-width: thin;\n\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 2px;\n\n min-block-size: 0;\n padding-block-end: 12px;\n padding-inline: 8px;\n `,\n railLink: css`\n position: absolute;\n inset: 0;\n border-radius: ${cssVar.borderRadius};\n transition: background 120ms ease;\n\n &:hover {\n background: ${cssVar.colorFillTertiary};\n }\n\n &[data-active='true'] {\n background: ${cssVar.colorFillSecondary};\n }\n\n @starting-style {\n background: transparent;\n }\n `,\n topItems: css`\n display: flex;\n flex-direction: column;\n gap: 2px;\n transition:\n margin 200ms ease,\n padding 200ms ease,\n border-color 200ms ease;\n\n &[data-divided='true'] {\n margin-block-end: 6px;\n padding-block-end: 8px;\n border-block-end: 1px solid ${cssVar.colorBorderSecondary};\n }\n\n [data-collapsed='true'] &[data-rail-empty='true'] {\n margin-block-end: 0;\n padding-block-end: 0;\n border-block-end-color: transparent;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n };\n});\n"],"mappings":";;AAEA,MAAa,SAAS,oBAAoB,EAAE,KAAK,QAAQ,iBAAiB;CAExE,MAAM,WAAW;;;;;;;;;;;;CAajB,OAAO;EACL,OAAO,GAAG;;;;;;;mBAOK,OAAO,WAAW;;eAEtB,OAAO,WAAW;;;uCAGM,OAAO,WAAW;;QAEjD,SAAS;;EAEb,SAAS,GAAG;;;;;;;;;;;;;;;;;;;EAmBZ,WAAW,GAAG;;;;;;;;;;eAUH,OAAO,qBAAqB;;;;;;;;EAQvC,KAAK,GAAG;;;;;;;;;;oBAUQ,OAAO,WAAW;;;;;;;;;;;;EAYlC,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BT,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;sBAoBQ,OAAO,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiC9C,WAAW,GAAG;;;;;EAKd,aAAa,GAAG;;;;;;;;;;;uBAWG,OAAO,aAAa;;mBAExB,OAAO,WAAW;;eAEtB,OAAO,mBAAmB;;;;;;;;iBAQxB,OAAO,UAAU;;;;;;;qBAOb,OAAO,SAAS;;;;;;;;;sBASf,OAAO,kBAAkB;;;;;;;;;;qBAU1B,OAAO,WAAW;;iBAEtB,OAAO,qBAAqB;;;;;;;;mBAQ1B,OAAO,mBAAmB;;;;;;;;;;;;;;;;;EAiBzC,YAAY,GAAG;;;;;;EAMf,YAAY,GAAG;;;;;;;;;;;;;;;;;EAiBf,MAAM,GAAG;;;;;;;;;uBASU,OAAO,aAAa;;eAE5B,OAAO,mBAAmB;;;;;;;;;iBASxB,OAAO,UAAU;sBACZ,OAAO,kBAAkB;;;;;iBAK9B,OAAO,UAAU;sBACZ,OAAO,mBAAmB;;;;;;iBAM/B,OAAO,UAAU;;;;;;;;;;;;;;;;;;;;QAoB1B,WAAW,OAAO;;;;EAItB,WAAW,GAAG;;;;;;;;;;QAUV,SAAS;;EAEb,KAAK,GAAG;;;;;;;;;;;;;;EAcR,UAAU,GAAG;;;uBAGM,OAAO,aAAa;;;;sBAIrB,OAAO,kBAAkB;;;;sBAIzB,OAAO,mBAAmB;;;;;;;EAO5C,UAAU,GAAG;;;;;;;;;;;;sCAYqB,OAAO,qBAAqB;;;;;;;;;;;;;CAahE;AACF,CAAC"}
|
|
1
|
+
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/dashboard/ConsoleNav/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nexport const styles = createStaticStyles(({ css, cssVar, responsive }) => {\n // Fades out at once on collapse, but waits on expand until the width has room for the text.\n const railFade = `\n transition: opacity 120ms ease 80ms;\n\n [data-collapsed='true'] & {\n opacity: 0;\n transition-delay: 0s;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `;\n\n return {\n badge: css`\n flex: none;\n\n min-inline-size: 20px;\n padding-inline: 6px;\n border-radius: 999px;\n\n font-size: ${cssVar.fontSizeSM};\n font-variant-numeric: tabular-nums;\n color: ${cssVar.colorError};\n text-align: center;\n\n background: color-mix(in srgb, ${cssVar.colorError} 12%, transparent);\n\n ${railFade}\n `,\n chevron: css`\n flex: none;\n transition:\n transform 160ms ease,\n opacity 120ms ease 80ms;\n\n &[data-expanded='false'] {\n transform: rotate(-90deg);\n }\n\n [data-collapsed='true'] & {\n opacity: 0;\n transition-delay: 0s;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n indicator: css`\n display: flex;\n flex: none;\n align-items: center;\n justify-content: center;\n\n width: 18px;\n height: 18px;\n margin-inline-start: -6px;\n\n color: ${cssVar.colorTextDescription};\n\n transition: transform 160ms ease;\n\n &[data-expanded='true'] {\n transform: rotate(90deg);\n }\n `,\n dot: css`\n position: absolute;\n inset-block-start: 7px;\n inset-inline-end: 9px;\n\n inline-size: 7px;\n block-size: 7px;\n border-radius: 999px;\n\n opacity: 0;\n background: ${cssVar.colorError};\n\n transition: opacity 120ms ease;\n\n [data-collapsed='true'] & {\n opacity: 1;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n fold: css`\n display: grid;\n grid-template-rows: 1fr;\n transition:\n grid-template-rows 200ms ease,\n margin 200ms ease,\n opacity 120ms ease;\n\n > div {\n overflow: hidden;\n min-block-size: 0;\n }\n\n &[data-folded='true'] {\n grid-template-rows: 0fr;\n opacity: 0;\n }\n\n &[data-folded='true']:not(:first-child) {\n margin-block-start: -2px;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n group: css`\n position: relative;\n\n display: flex;\n flex-direction: column;\n\n margin-block-start: 12px;\n\n transition: margin 200ms ease;\n\n &::before {\n content: '';\n\n position: absolute;\n inset-block-start: -6px;\n inset-inline: 0;\n\n block-size: 1px;\n\n opacity: 0;\n background: ${cssVar.colorBorderSecondary};\n\n transition: opacity 200ms ease;\n }\n\n &[data-level='0'][data-icon='true'] {\n margin-block-start: 2px;\n }\n\n &:not([data-level='0']) {\n margin-block-start: 6px;\n }\n\n [data-collapsed='true'] & + &[data-level='0'][data-icon='false']::before {\n opacity: 1;\n }\n\n [data-collapsed='true'] &[data-rail-empty='true'] {\n margin-block-start: 0;\n\n &::before {\n opacity: 0;\n }\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n\n &::before {\n transition: none;\n }\n }\n `,\n groupHead: css`\n position: relative;\n display: flex;\n flex-direction: column;\n `,\n groupHeader: css`\n cursor: pointer;\n\n display: flex;\n gap: 8px;\n align-items: center;\n justify-content: space-between;\n\n min-block-size: 32px;\n padding-inline: 10px;\n border: none;\n border-radius: ${cssVar.borderRadius};\n\n font-size: ${cssVar.fontSizeSM};\n font-weight: 500;\n color: ${cssVar.colorTextSecondary};\n text-align: start;\n white-space: nowrap;\n\n background: none;\n\n &:hover,\n &[data-active='true'] {\n color: ${cssVar.colorText};\n }\n\n &[data-icon='true'] {\n gap: 10px;\n justify-content: flex-start;\n min-block-size: 36px;\n font-size: ${cssVar.fontSize};\n\n > [role='img'] {\n justify-content: center;\n inline-size: 18px;\n }\n }\n\n &[data-level='0'][data-icon='true']:hover {\n background: ${cssVar.colorFillTertiary};\n }\n\n /* Nested groups read as quiet subheadings with the indicator right after the label. */\n &:not([data-level='0']) {\n gap: 8px;\n justify-content: flex-start;\n\n min-block-size: 26px;\n\n font-size: ${cssVar.fontSizeSM};\n font-weight: 400;\n color: ${cssVar.colorTextDescription};\n\n > [data-label] {\n flex: 0 1 auto;\n }\n\n &:hover,\n &[data-active='true'] {\n color: ${cssVar.colorTextSecondary};\n }\n }\n\n &[data-indent='1'] {\n padding-inline-start: 38px;\n }\n\n &[data-indent='2'] {\n padding-inline-start: 56px;\n }\n\n > [role='img'] {\n display: flex;\n flex: none;\n }\n `,\n groupItems: css`\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-block-size: 0;\n `,\n groupPanel: css`\n display: grid;\n grid-template-rows: 1fr;\n transition: grid-template-rows 160ms ease;\n\n > div {\n overflow: hidden;\n }\n\n &[data-expanded='false'] {\n grid-template-rows: 0fr;\n }\n\n &[data-instant='true'] {\n transition: none;\n }\n `,\n item: css`\n position: relative;\n\n display: flex;\n gap: 10px;\n align-items: center;\n\n min-block-size: 36px;\n padding-inline: 10px;\n border-radius: ${cssVar.borderRadius};\n\n color: ${cssVar.colorTextSecondary};\n text-decoration: none;\n white-space: nowrap;\n\n transition:\n background 120ms ease,\n color 120ms ease;\n\n &:hover {\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillTertiary};\n }\n\n &[data-active='true'] {\n font-weight: 500;\n color: ${cssVar.colorText};\n background: ${cssVar.colorFillSecondary};\n }\n\n &[data-indent='1'],\n &[data-indent='2'] {\n min-block-size: 32px;\n color: ${cssVar.colorText};\n }\n\n &[data-indent='1'] {\n padding-inline-start: 38px;\n }\n\n &[data-indent='2'] {\n padding-inline-start: 56px;\n }\n\n [data-collapsed='true'] &:not([data-indent='0']) {\n padding-inline-start: 10px;\n }\n\n > [role='img'] {\n display: flex;\n flex: none;\n }\n\n ${responsive.mobile} {\n min-block-size: 44px;\n }\n `,\n itemLabel: css`\n overflow: hidden;\n flex: 1;\n text-overflow: ellipsis;\n white-space: nowrap;\n\n [data-collapsed='true'] & {\n text-overflow: clip;\n }\n\n ${railFade}\n `,\n nav: css`\n /* Scroll anchoring would jump the list in one frame while rail rows fold and unfold. */\n overflow-anchor: none;\n scrollbar-width: thin;\n\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 2px;\n\n min-block-size: 0;\n padding-block-end: 12px;\n padding-inline: 8px;\n `,\n railLink: css`\n position: absolute;\n inset: 0;\n border-radius: ${cssVar.borderRadius};\n transition: background 120ms ease;\n\n &:hover {\n background: ${cssVar.colorFillTertiary};\n }\n\n &[data-active='true'] {\n background: ${cssVar.colorFillSecondary};\n }\n\n @starting-style {\n background: transparent;\n }\n `,\n skeletonFooter: css`\n display: flex;\n gap: 10px;\n align-items: center;\n padding-inline: 4px;\n `,\n skeletonGroup: css`\n display: flex;\n flex-direction: column;\n gap: 2px;\n margin-block-start: 12px;\n `,\n skeletonRow: css`\n pointer-events: none;\n `,\n topItems: css`\n display: flex;\n flex-direction: column;\n gap: 2px;\n transition:\n margin 200ms ease,\n padding 200ms ease,\n border-color 200ms ease;\n\n &[data-divided='true'] {\n margin-block-end: 6px;\n padding-block-end: 8px;\n border-block-end: 1px solid ${cssVar.colorBorderSecondary};\n }\n\n [data-collapsed='true'] &[data-rail-empty='true'] {\n margin-block-end: 0;\n padding-block-end: 0;\n border-block-end-color: transparent;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n };\n});\n"],"mappings":";;AAEA,MAAa,SAAS,oBAAoB,EAAE,KAAK,QAAQ,iBAAiB;CAExE,MAAM,WAAW;;;;;;;;;;;;CAajB,OAAO;EACL,OAAO,GAAG;;;;;;;mBAOK,OAAO,WAAW;;eAEtB,OAAO,WAAW;;;uCAGM,OAAO,WAAW;;QAEjD,SAAS;;EAEb,SAAS,GAAG;;;;;;;;;;;;;;;;;;;EAmBZ,WAAW,GAAG;;;;;;;;;;eAUH,OAAO,qBAAqB;;;;;;;;EAQvC,KAAK,GAAG;;;;;;;;;;oBAUQ,OAAO,WAAW;;;;;;;;;;;;EAYlC,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;EA0BT,OAAO,GAAG;;;;;;;;;;;;;;;;;;;;sBAoBQ,OAAO,qBAAqB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiC9C,WAAW,GAAG;;;;;EAKd,aAAa,GAAG;;;;;;;;;;;uBAWG,OAAO,aAAa;;mBAExB,OAAO,WAAW;;eAEtB,OAAO,mBAAmB;;;;;;;;iBAQxB,OAAO,UAAU;;;;;;;qBAOb,OAAO,SAAS;;;;;;;;;sBASf,OAAO,kBAAkB;;;;;;;;;;qBAU1B,OAAO,WAAW;;iBAEtB,OAAO,qBAAqB;;;;;;;;mBAQ1B,OAAO,mBAAmB;;;;;;;;;;;;;;;;;EAiBzC,YAAY,GAAG;;;;;;EAMf,YAAY,GAAG;;;;;;;;;;;;;;;;;EAiBf,MAAM,GAAG;;;;;;;;;uBASU,OAAO,aAAa;;eAE5B,OAAO,mBAAmB;;;;;;;;;iBASxB,OAAO,UAAU;sBACZ,OAAO,kBAAkB;;;;;iBAK9B,OAAO,UAAU;sBACZ,OAAO,mBAAmB;;;;;;iBAM/B,OAAO,UAAU;;;;;;;;;;;;;;;;;;;;QAoB1B,WAAW,OAAO;;;;EAItB,WAAW,GAAG;;;;;;;;;;QAUV,SAAS;;EAEb,KAAK,GAAG;;;;;;;;;;;;;;EAcR,UAAU,GAAG;;;uBAGM,OAAO,aAAa;;;;sBAIrB,OAAO,kBAAkB;;;;sBAIzB,OAAO,mBAAmB;;;;;;;EAO5C,gBAAgB,GAAG;;;;;;EAMnB,eAAe,GAAG;;;;;;EAMlB,aAAa,GAAG;;;EAGhB,UAAU,GAAG;;;;;;;;;;;;sCAYqB,OAAO,qBAAqB;;;;;;;;;;;;;CAahE;AACF,CAAC"}
|
|
@@ -66,6 +66,19 @@ interface ConsoleNavProps {
|
|
|
66
66
|
/** Persists which groups were opened or closed by hand. */
|
|
67
67
|
storageKey?: string;
|
|
68
68
|
}
|
|
69
|
+
interface ConsoleNavSkeletonProps {
|
|
70
|
+
className?: string;
|
|
71
|
+
/**
|
|
72
|
+
* Rows per group. Pass counts, or the real `ConsoleNavGroup[]` to mirror its item counts.
|
|
73
|
+
* @default [3, 6, 4, 3]
|
|
74
|
+
*/
|
|
75
|
+
groups?: Array<number | ConsoleNavGroup>;
|
|
76
|
+
/**
|
|
77
|
+
* Ungrouped rows before the groups.
|
|
78
|
+
* @default 1
|
|
79
|
+
*/
|
|
80
|
+
items?: number;
|
|
81
|
+
}
|
|
69
82
|
//#endregion
|
|
70
|
-
export { ConsoleNavGroup, ConsoleNavItem, ConsoleNavLinkProps, ConsoleNavProps };
|
|
83
|
+
export { ConsoleNavGroup, ConsoleNavItem, ConsoleNavLinkProps, ConsoleNavProps, ConsoleNavSkeletonProps };
|
|
71
84
|
//# sourceMappingURL=type.d.mts.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ConsoleShellProps } from "./type.mjs";
|
|
2
2
|
//#region src/dashboard/ConsoleShell/ConsoleShell.d.ts
|
|
3
|
-
declare function ConsoleShell({ brand, breadcrumb, children, className, collapsed, closeNavigationLabel, collapseLabel, defaultCollapsed, expandLabel, footer, hotkey, navigation, onCollapsedChange, openNavigationLabel, skipToContentLabel, storageKey, tools, ...rest }: ConsoleShellProps): import("react").JSX.Element;
|
|
3
|
+
declare function ConsoleShell({ brand, breadcrumb, children, className, collapsed, closeNavigationLabel, collapseLabel, defaultCollapsed, expandLabel, footer: footerProp, loading, loadingContent, loadingNavigation, hotkey, navigation: navigationProp, onCollapsedChange, openNavigationLabel, skipToContentLabel, storageKey, tools, ...rest }: ConsoleShellProps): import("react").JSX.Element;
|
|
4
4
|
declare namespace ConsoleShell {
|
|
5
5
|
var displayName: string;
|
|
6
6
|
}
|
|
@@ -4,9 +4,12 @@ import Button from "../../base-ui/Button/Button.mjs";
|
|
|
4
4
|
import Drawer from "../../base-ui/Drawer/Drawer.mjs";
|
|
5
5
|
import { ConsoleShellContext } from "./context.mjs";
|
|
6
6
|
import { useIsCompact, useLocalStorage, usePrefersReducedMotion } from "../hooks.mjs";
|
|
7
|
+
import ConsoleNavSkeleton, { ConsoleFooterSkeleton } from "../ConsoleNav/Skeleton.mjs";
|
|
7
8
|
import { styles } from "./style.mjs";
|
|
9
|
+
import PageLoading from "../PageSkeleton/PageSkeleton.mjs";
|
|
8
10
|
import { useEffect, useId, useRef, useState } from "react";
|
|
9
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
12
|
+
import { useThemeMode } from "antd-style";
|
|
10
13
|
import { PanelLeft, X } from "lucide-react";
|
|
11
14
|
//#region src/dashboard/ConsoleShell/ConsoleShell.tsx
|
|
12
15
|
function isTypingTarget(target) {
|
|
@@ -14,10 +17,14 @@ function isTypingTarget(target) {
|
|
|
14
17
|
const tag = target.tagName;
|
|
15
18
|
return tag === "INPUT" || tag === "TEXTAREA" || tag === "SELECT" || target.isContentEditable;
|
|
16
19
|
}
|
|
17
|
-
function ConsoleShell({ brand, breadcrumb, children, className, collapsed, closeNavigationLabel = "Close navigation", collapseLabel = "Collapse sidebar", defaultCollapsed = false, expandLabel = "Expand sidebar", footer, hotkey = true, navigation, onCollapsedChange, openNavigationLabel = "Open navigation", skipToContentLabel = "Skip to content", storageKey, tools, ...rest }) {
|
|
20
|
+
function ConsoleShell({ brand, breadcrumb, children, className, collapsed, closeNavigationLabel = "Close navigation", collapseLabel = "Collapse sidebar", defaultCollapsed = false, expandLabel = "Expand sidebar", footer: footerProp, loading, loadingContent, loadingNavigation, hotkey = true, navigation: navigationProp, onCollapsedChange, openNavigationLabel = "Open navigation", skipToContentLabel = "Skip to content", storageKey, tools, ...rest }) {
|
|
21
|
+
const navigation = loading ? loadingNavigation ?? /* @__PURE__ */ jsx(ConsoleNavSkeleton, {}) : navigationProp;
|
|
22
|
+
const footer = loading ? /* @__PURE__ */ jsx(ConsoleFooterSkeleton, {}) : footerProp;
|
|
23
|
+
const body = loading ? loadingContent ?? /* @__PURE__ */ jsx(PageLoading, {}) : children;
|
|
18
24
|
const mainId = `console-main-${useId().replaceAll(":", "")}`;
|
|
19
25
|
const shellRef = useRef(null);
|
|
20
26
|
const isCompact = useIsCompact();
|
|
27
|
+
const { isDarkMode } = useThemeMode();
|
|
21
28
|
const reducedMotion = usePrefersReducedMotion();
|
|
22
29
|
const [storedCollapsed, setStoredCollapsed] = useLocalStorage(storageKey, defaultCollapsed);
|
|
23
30
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
@@ -117,7 +124,7 @@ function ConsoleShell({ brand, breadcrumb, children, className, collapsed, close
|
|
|
117
124
|
})
|
|
118
125
|
}) : null,
|
|
119
126
|
/* @__PURE__ */ jsxs("div", {
|
|
120
|
-
className: styles.workspace
|
|
127
|
+
className: isDarkMode ? styles.workspace : `${styles.workspace} ${styles.workspaceLight}`,
|
|
121
128
|
children: [/* @__PURE__ */ jsxs("header", {
|
|
122
129
|
className: styles.topbar,
|
|
123
130
|
children: [
|
|
@@ -141,10 +148,11 @@ function ConsoleShell({ brand, breadcrumb, children, className, collapsed, close
|
|
|
141
148
|
}) : null
|
|
142
149
|
]
|
|
143
150
|
}), /* @__PURE__ */ jsx("main", {
|
|
151
|
+
"aria-busy": loading || void 0,
|
|
144
152
|
className: styles.main,
|
|
145
153
|
id: mainId,
|
|
146
154
|
tabIndex: -1,
|
|
147
|
-
children
|
|
155
|
+
children: body
|
|
148
156
|
})]
|
|
149
157
|
})
|
|
150
158
|
]
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConsoleShell.mjs","names":["Flexbox"],"sources":["../../../src/dashboard/ConsoleShell/ConsoleShell.tsx"],"sourcesContent":["'use client';\n\nimport { PanelLeft, X } from 'lucide-react';\nimport { useEffect, useId, useRef, useState } from 'react';\n\nimport Button from '@/base-ui/Button';\nimport { Drawer } from '@/base-ui/Drawer';\nimport { Flexbox } from '@/Flex';\n\nimport { useIsCompact, useLocalStorage, usePrefersReducedMotion } from '../hooks';\nimport { ConsoleShellContext } from './context';\nimport { styles } from './style';\nimport type { ConsoleShellProps, ConsoleShellState } from './type';\n\nfunction isTypingTarget(target: EventTarget | null) {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target.isContentEditable;\n}\n\nfunction ConsoleShell({\n brand,\n breadcrumb,\n children,\n className,\n collapsed,\n closeNavigationLabel = 'Close navigation',\n collapseLabel = 'Collapse sidebar',\n defaultCollapsed = false,\n expandLabel = 'Expand sidebar',\n footer,\n hotkey = true,\n navigation,\n onCollapsedChange,\n openNavigationLabel = 'Open navigation',\n skipToContentLabel = 'Skip to content',\n storageKey,\n tools,\n ...rest\n}: ConsoleShellProps) {\n const mainId = `console-main-${useId().replaceAll(':', '')}`;\n const shellRef = useRef<HTMLDivElement>(null);\n const isCompact = useIsCompact();\n const reducedMotion = usePrefersReducedMotion();\n const [storedCollapsed, setStoredCollapsed] = useLocalStorage(storageKey, defaultCollapsed);\n const [drawerOpen, setDrawerOpen] = useState(false);\n const isControlled = collapsed !== undefined;\n const railCollapsed = isControlled ? collapsed : storedCollapsed;\n const railed = railCollapsed && !isCompact;\n\n const setCollapsed = (next: boolean) => {\n if (!isControlled) setStoredCollapsed(next);\n onCollapsedChange?.(next);\n };\n\n const closeNavigation = () => setDrawerOpen(false);\n const toggleNavigation = () => {\n if (isCompact) {\n setDrawerOpen((open) => !open);\n return;\n }\n setCollapsed(!railCollapsed);\n };\n const toggleRef = useRef(toggleNavigation);\n toggleRef.current = toggleNavigation;\n\n useEffect(() => {\n if (!hotkey) return;\n const node = shellRef.current;\n if (!node) return;\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key.toLowerCase() !== 'b' || !(event.metaKey || event.ctrlKey) || event.altKey) {\n return;\n }\n if (event.repeat || isTypingTarget(event.target)) return;\n if (!node.contains(event.target as Node)) return;\n event.preventDefault();\n toggleRef.current();\n };\n\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n }, [hotkey]);\n\n const stateFor = (rail: boolean): ConsoleShellState => ({\n closeNavigation,\n collapsed: rail,\n compact: isCompact,\n });\n\n const sidebar = (rail: boolean) => (\n <ConsoleShellContext value={stateFor(rail)}>\n {brand || isCompact ? (\n <div className={styles.brand} data-collapsed={rail}>\n {brand}\n {isCompact ? (\n // In the drawer the close button sits in the brand row's flow, so it never\n // overlaps a brand switcher the way the drawer's floating close button did.\n <Button\n aria-label={closeNavigationLabel}\n className={styles.brandClose}\n icon={X}\n type=\"text\"\n onClick={closeNavigation}\n />\n ) : null}\n </div>\n ) : null}\n {navigation ? <div className={styles.navSlot}>{navigation}</div> : null}\n {footer ? <div className={styles.sidebarBottom}>{footer}</div> : null}\n </ConsoleShellContext>\n );\n\n const toggleLabel = isCompact ? openNavigationLabel : railed ? expandLabel : collapseLabel;\n\n return (\n <div\n className={className ? `${styles.shell} ${className}` : styles.shell}\n data-console-shell=\"\"\n ref={shellRef}\n {...rest}\n >\n <a\n className={styles.skipLink}\n href={`#${mainId}`}\n onClick={(event) => {\n event.preventDefault();\n document.getElementById(mainId)?.focus();\n }}\n >\n {skipToContentLabel}\n </a>\n <aside className={styles.sidebar} data-collapsed={railed} data-instant={reducedMotion}>\n {!isCompact && sidebar(railed)}\n </aside>\n {isCompact ? (\n <Drawer\n noHeader\n classNames={{ bodyContent: styles.drawerBody }}\n closable={false}\n open={drawerOpen}\n placement=\"left\"\n width={272}\n onClose={closeNavigation}\n >\n <Flexbox height=\"100%\">{sidebar(false)}</Flexbox>\n </Drawer>\n ) : null}\n <div
|
|
1
|
+
{"version":3,"file":"ConsoleShell.mjs","names":["Flexbox"],"sources":["../../../src/dashboard/ConsoleShell/ConsoleShell.tsx"],"sourcesContent":["'use client';\n\nimport { useThemeMode } from 'antd-style';\nimport { PanelLeft, X } from 'lucide-react';\nimport { useEffect, useId, useRef, useState } from 'react';\n\nimport Button from '@/base-ui/Button';\nimport { Drawer } from '@/base-ui/Drawer';\nimport { Flexbox } from '@/Flex';\n\nimport ConsoleNavSkeleton, { ConsoleFooterSkeleton } from '../ConsoleNav/Skeleton';\nimport { useIsCompact, useLocalStorage, usePrefersReducedMotion } from '../hooks';\nimport PageLoading from '../PageSkeleton';\nimport { ConsoleShellContext } from './context';\nimport { styles } from './style';\nimport type { ConsoleShellProps, ConsoleShellState } from './type';\n\nfunction isTypingTarget(target: EventTarget | null) {\n if (!(target instanceof HTMLElement)) return false;\n const tag = target.tagName;\n return tag === 'INPUT' || tag === 'TEXTAREA' || tag === 'SELECT' || target.isContentEditable;\n}\n\nfunction ConsoleShell({\n brand,\n breadcrumb,\n children,\n className,\n collapsed,\n closeNavigationLabel = 'Close navigation',\n collapseLabel = 'Collapse sidebar',\n defaultCollapsed = false,\n expandLabel = 'Expand sidebar',\n footer: footerProp,\n loading,\n loadingContent,\n loadingNavigation,\n hotkey = true,\n navigation: navigationProp,\n onCollapsedChange,\n openNavigationLabel = 'Open navigation',\n skipToContentLabel = 'Skip to content',\n storageKey,\n tools,\n ...rest\n}: ConsoleShellProps) {\n const navigation = loading ? (loadingNavigation ?? <ConsoleNavSkeleton />) : navigationProp;\n const footer = loading ? <ConsoleFooterSkeleton /> : footerProp;\n const body = loading ? (loadingContent ?? <PageLoading />) : children;\n const mainId = `console-main-${useId().replaceAll(':', '')}`;\n const shellRef = useRef<HTMLDivElement>(null);\n const isCompact = useIsCompact();\n const { isDarkMode } = useThemeMode();\n const reducedMotion = usePrefersReducedMotion();\n const [storedCollapsed, setStoredCollapsed] = useLocalStorage(storageKey, defaultCollapsed);\n const [drawerOpen, setDrawerOpen] = useState(false);\n const isControlled = collapsed !== undefined;\n const railCollapsed = isControlled ? collapsed : storedCollapsed;\n const railed = railCollapsed && !isCompact;\n\n const setCollapsed = (next: boolean) => {\n if (!isControlled) setStoredCollapsed(next);\n onCollapsedChange?.(next);\n };\n\n const closeNavigation = () => setDrawerOpen(false);\n const toggleNavigation = () => {\n if (isCompact) {\n setDrawerOpen((open) => !open);\n return;\n }\n setCollapsed(!railCollapsed);\n };\n const toggleRef = useRef(toggleNavigation);\n toggleRef.current = toggleNavigation;\n\n useEffect(() => {\n if (!hotkey) return;\n const node = shellRef.current;\n if (!node) return;\n\n const onKeyDown = (event: KeyboardEvent) => {\n if (event.key.toLowerCase() !== 'b' || !(event.metaKey || event.ctrlKey) || event.altKey) {\n return;\n }\n if (event.repeat || isTypingTarget(event.target)) return;\n if (!node.contains(event.target as Node)) return;\n event.preventDefault();\n toggleRef.current();\n };\n\n document.addEventListener('keydown', onKeyDown);\n return () => document.removeEventListener('keydown', onKeyDown);\n }, [hotkey]);\n\n const stateFor = (rail: boolean): ConsoleShellState => ({\n closeNavigation,\n collapsed: rail,\n compact: isCompact,\n });\n\n const sidebar = (rail: boolean) => (\n <ConsoleShellContext value={stateFor(rail)}>\n {brand || isCompact ? (\n <div className={styles.brand} data-collapsed={rail}>\n {brand}\n {isCompact ? (\n // In the drawer the close button sits in the brand row's flow, so it never\n // overlaps a brand switcher the way the drawer's floating close button did.\n <Button\n aria-label={closeNavigationLabel}\n className={styles.brandClose}\n icon={X}\n type=\"text\"\n onClick={closeNavigation}\n />\n ) : null}\n </div>\n ) : null}\n {navigation ? <div className={styles.navSlot}>{navigation}</div> : null}\n {footer ? <div className={styles.sidebarBottom}>{footer}</div> : null}\n </ConsoleShellContext>\n );\n\n const toggleLabel = isCompact ? openNavigationLabel : railed ? expandLabel : collapseLabel;\n\n return (\n <div\n className={className ? `${styles.shell} ${className}` : styles.shell}\n data-console-shell=\"\"\n ref={shellRef}\n {...rest}\n >\n <a\n className={styles.skipLink}\n href={`#${mainId}`}\n onClick={(event) => {\n event.preventDefault();\n document.getElementById(mainId)?.focus();\n }}\n >\n {skipToContentLabel}\n </a>\n <aside className={styles.sidebar} data-collapsed={railed} data-instant={reducedMotion}>\n {!isCompact && sidebar(railed)}\n </aside>\n {isCompact ? (\n <Drawer\n noHeader\n classNames={{ bodyContent: styles.drawerBody }}\n closable={false}\n open={drawerOpen}\n placement=\"left\"\n width={272}\n onClose={closeNavigation}\n >\n <Flexbox height=\"100%\">{sidebar(false)}</Flexbox>\n </Drawer>\n ) : null}\n <div\n className={isDarkMode ? styles.workspace : `${styles.workspace} ${styles.workspaceLight}`}\n >\n <header className={styles.topbar}>\n <Button\n aria-label={toggleLabel}\n icon={PanelLeft}\n type=\"text\"\n onClick={toggleNavigation}\n />\n <span aria-hidden className={styles.topbarDivider} />\n <div className={styles.topbarMain}>{breadcrumb}</div>\n {tools ? <div className={styles.tools}>{tools}</div> : null}\n </header>\n <main aria-busy={loading || undefined} className={styles.main} id={mainId} tabIndex={-1}>\n {body}\n </main>\n </div>\n </div>\n );\n}\n\nConsoleShell.displayName = 'ConsoleShell';\n\nexport default ConsoleShell;\n"],"mappings":"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"}
|
|
@@ -197,6 +197,12 @@ const styles = createStaticStyles(({ css, cssVar, responsive }) => ({
|
|
|
197
197
|
align-items: center;
|
|
198
198
|
|
|
199
199
|
margin-inline-start: auto;
|
|
200
|
+
`,
|
|
201
|
+
/** Light only: the content area sits midway between the layout canvas and container white. */
|
|
202
|
+
workspaceLight: css`
|
|
203
|
+
&& {
|
|
204
|
+
background: color-mix(in srgb, ${cssVar.colorBgLayout} 50%, ${cssVar.colorBgContainer});
|
|
205
|
+
}
|
|
200
206
|
`,
|
|
201
207
|
workspace: css`
|
|
202
208
|
overflow: hidden;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/dashboard/ConsoleShell/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nconst SIDEBAR_INLINE_SIZE = 248;\n// Twice the nav icon inset (8px nav padding + 10px item padding) plus the 18px icon, so the icons\n// land centered on the rail without moving sideways.\nconst SIDEBAR_RAIL_INLINE_SIZE = 54;\nconst WORKSPACE_INSET = 8;\n\n/**\n * `responsive.laptop`, not `responsive.tablet`. The aliases are named for\n * devices, and only `laptop` (max-width 991px) lines up with `useIsCompact`.\n */\nexport const styles = createStaticStyles(({ css, cssVar, responsive }) => ({\n brand: css`\n display: flex;\n flex: none;\n align-items: center;\n\n block-size: 56px;\n margin-block-start: ${WORKSPACE_INSET}px;\n padding-inline: 15px;\n\n color: ${cssVar.colorText};\n white-space: nowrap;\n\n ${responsive.laptop} {\n margin-block-start: 0;\n }\n `,\n /** Close button in the drawer's brand row: right edge, vertically centred with the brand. */\n brandClose: css`\n flex: none;\n margin-inline: auto -7px;\n `,\n brandAnchor: css`\n display: flex;\n align-items: center;\n\n inline-size: 100%;\n min-inline-size: 0;\n\n color: inherit;\n text-decoration: none;\n `,\n brandLockup: css`\n display: flex;\n gap: 10px;\n align-items: center;\n min-inline-size: 0;\n `,\n brandName: css`\n overflow: hidden;\n\n font-size: 14px;\n font-weight: 600;\n line-height: 1.3;\n color: ${cssVar.colorText};\n text-overflow: ellipsis;\n white-space: nowrap;\n\n transition: opacity 120ms ease 80ms;\n\n [data-collapsed='true'] & {\n text-overflow: clip;\n opacity: 0;\n transition-delay: 0s;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n main: css`\n overflow: auto;\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 20px;\n\n min-inline-size: 0;\n min-block-size: 0;\n padding: 24px;\n\n /*\n * A page that owns a full-height split sets data-page-layout=\"flush\" and\n * takes over padding and scrolling, so its sidebar can sit on the card edge.\n */\n &:has([data-page-layout='flush']) {\n overflow: hidden;\n gap: 0;\n padding: 0;\n }\n\n ${responsive.mobile} {\n gap: 16px;\n padding: 16px;\n }\n `,\n /**\n * The drawer body is the scroll container. Without its default padding the scrollbar sits on\n * the panel edge; the brand row, nav and footer keep their own insets.\n */\n drawerBody: css`\n && {\n min-block-size: 100%;\n padding: 0;\n }\n `,\n navSlot: css`\n display: flex;\n flex: 1;\n flex-direction: column;\n min-block-size: 0;\n `,\n shell: css`\n overflow: hidden;\n display: flex;\n flex: 1;\n\n block-size: 100%;\n min-block-size: 0;\n\n background: ${cssVar.colorBgLayout};\n `,\n sidebar: css`\n overflow: hidden;\n display: flex;\n flex: none;\n flex-direction: column;\n\n inline-size: ${SIDEBAR_INLINE_SIZE}px;\n block-size: 100%;\n min-block-size: 0;\n\n transition: inline-size 200ms ease;\n\n &[data-collapsed='true'] {\n inline-size: ${SIDEBAR_RAIL_INLINE_SIZE}px;\n }\n\n &[data-instant='true'] {\n transition: none;\n }\n\n ${responsive.laptop} {\n display: none;\n }\n `,\n sidebarBottom: css`\n flex: none;\n padding: 8px;\n `,\n skipLink: css`\n position: fixed;\n z-index: 2000;\n inset-block-start: -100px;\n inset-inline-start: 12px;\n\n padding-block: 8px;\n padding-inline: 12px;\n border-radius: ${cssVar.borderRadius};\n\n color: ${cssVar.colorText};\n\n background: ${cssVar.colorBgElevated};\n\n &:focus {\n inset-block-start: 12px;\n }\n `,\n topbar: css`\n display: flex;\n flex: none;\n gap: 8px;\n align-items: center;\n\n block-size: 56px;\n padding-inline: 12px;\n border-block-end: 1px solid ${cssVar.colorBorderSecondary};\n `,\n topbarDivider: css`\n flex: none;\n\n inline-size: 1px;\n block-size: 18px;\n margin-inline: 2px;\n\n background: ${cssVar.colorBorderSecondary};\n `,\n topbarMain: css`\n display: flex;\n flex: 1;\n align-items: center;\n min-inline-size: 0;\n `,\n tools: css`\n display: flex;\n flex: none;\n gap: 6px;\n align-items: center;\n\n margin-inline-start: auto;\n `,\n workspace: css`\n overflow: hidden;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-inline-size: 0;\n min-block-size: 0;\n margin-block: ${WORKSPACE_INSET}px;\n margin-inline: 0 ${WORKSPACE_INSET}px;\n border: 1px solid ${cssVar.colorBorderSecondary};\n border-radius: ${cssVar.borderRadiusLG};\n\n background: ${cssVar.colorBgContainer};\n box-shadow: ${cssVar.boxShadowTertiary};\n\n ${responsive.laptop} {\n margin: 0;\n border: none;\n border-radius: 0;\n box-shadow: none;\n }\n `,\n}));\n"],"mappings":";;AAEA,MAAM,sBAAsB;AAG5B,MAAM,2BAA2B;AACjC,MAAM,kBAAkB;;;;;AAMxB,MAAa,SAAS,oBAAoB,EAAE,KAAK,QAAQ,kBAAkB;CACzE,OAAO,GAAG;;;;;;0BAMc,gBAAgB;;;aAG7B,OAAO,UAAU;;;MAGxB,WAAW,OAAO;;;;;CAKtB,YAAY,GAAG;;;;CAIf,aAAa,GAAG;;;;;;;;;;CAUhB,aAAa,GAAG;;;;;;CAMhB,WAAW,GAAG;;;;;;aAMH,OAAO,UAAU;;;;;;;;;;;;;;;;CAgB5B,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;MAqBL,WAAW,OAAO;;;;;;;;;CAStB,YAAY,GAAG;;;;;;CAMf,SAAS,GAAG;;;;;;CAMZ,OAAO,GAAG;;;;;;;;kBAQM,OAAO,cAAc;;CAErC,SAAS,GAAG;;;;;;mBAMK,oBAAoB;;;;;;;qBAOlB,yBAAyB;;;;;;;MAOxC,WAAW,OAAO;;;;CAItB,eAAe,GAAG;;;;CAIlB,UAAU,GAAG;;;;;;;;qBAQM,OAAO,aAAa;;aAE5B,OAAO,UAAU;;kBAEZ,OAAO,gBAAgB;;;;;;CAMvC,QAAQ,GAAG;;;;;;;;kCAQqB,OAAO,qBAAqB;;CAE5D,eAAe,GAAG;;;;;;;kBAOF,OAAO,qBAAqB;;CAE5C,YAAY,GAAG;;;;;;CAMf,OAAO,GAAG
|
|
1
|
+
{"version":3,"file":"style.mjs","names":[],"sources":["../../../src/dashboard/ConsoleShell/style.ts"],"sourcesContent":["import { createStaticStyles } from 'antd-style';\n\nconst SIDEBAR_INLINE_SIZE = 248;\n// Twice the nav icon inset (8px nav padding + 10px item padding) plus the 18px icon, so the icons\n// land centered on the rail without moving sideways.\nconst SIDEBAR_RAIL_INLINE_SIZE = 54;\nconst WORKSPACE_INSET = 8;\n\n/**\n * `responsive.laptop`, not `responsive.tablet`. The aliases are named for\n * devices, and only `laptop` (max-width 991px) lines up with `useIsCompact`.\n */\nexport const styles = createStaticStyles(({ css, cssVar, responsive }) => ({\n brand: css`\n display: flex;\n flex: none;\n align-items: center;\n\n block-size: 56px;\n margin-block-start: ${WORKSPACE_INSET}px;\n padding-inline: 15px;\n\n color: ${cssVar.colorText};\n white-space: nowrap;\n\n ${responsive.laptop} {\n margin-block-start: 0;\n }\n `,\n /** Close button in the drawer's brand row: right edge, vertically centred with the brand. */\n brandClose: css`\n flex: none;\n margin-inline: auto -7px;\n `,\n brandAnchor: css`\n display: flex;\n align-items: center;\n\n inline-size: 100%;\n min-inline-size: 0;\n\n color: inherit;\n text-decoration: none;\n `,\n brandLockup: css`\n display: flex;\n gap: 10px;\n align-items: center;\n min-inline-size: 0;\n `,\n brandName: css`\n overflow: hidden;\n\n font-size: 14px;\n font-weight: 600;\n line-height: 1.3;\n color: ${cssVar.colorText};\n text-overflow: ellipsis;\n white-space: nowrap;\n\n transition: opacity 120ms ease 80ms;\n\n [data-collapsed='true'] & {\n text-overflow: clip;\n opacity: 0;\n transition-delay: 0s;\n }\n\n @media (prefers-reduced-motion: reduce) {\n transition: none;\n }\n `,\n main: css`\n overflow: auto;\n display: flex;\n flex: 1;\n flex-direction: column;\n gap: 20px;\n\n min-inline-size: 0;\n min-block-size: 0;\n padding: 24px;\n\n /*\n * A page that owns a full-height split sets data-page-layout=\"flush\" and\n * takes over padding and scrolling, so its sidebar can sit on the card edge.\n */\n &:has([data-page-layout='flush']) {\n overflow: hidden;\n gap: 0;\n padding: 0;\n }\n\n ${responsive.mobile} {\n gap: 16px;\n padding: 16px;\n }\n `,\n /**\n * The drawer body is the scroll container. Without its default padding the scrollbar sits on\n * the panel edge; the brand row, nav and footer keep their own insets.\n */\n drawerBody: css`\n && {\n min-block-size: 100%;\n padding: 0;\n }\n `,\n navSlot: css`\n display: flex;\n flex: 1;\n flex-direction: column;\n min-block-size: 0;\n `,\n shell: css`\n overflow: hidden;\n display: flex;\n flex: 1;\n\n block-size: 100%;\n min-block-size: 0;\n\n background: ${cssVar.colorBgLayout};\n `,\n sidebar: css`\n overflow: hidden;\n display: flex;\n flex: none;\n flex-direction: column;\n\n inline-size: ${SIDEBAR_INLINE_SIZE}px;\n block-size: 100%;\n min-block-size: 0;\n\n transition: inline-size 200ms ease;\n\n &[data-collapsed='true'] {\n inline-size: ${SIDEBAR_RAIL_INLINE_SIZE}px;\n }\n\n &[data-instant='true'] {\n transition: none;\n }\n\n ${responsive.laptop} {\n display: none;\n }\n `,\n sidebarBottom: css`\n flex: none;\n padding: 8px;\n `,\n skipLink: css`\n position: fixed;\n z-index: 2000;\n inset-block-start: -100px;\n inset-inline-start: 12px;\n\n padding-block: 8px;\n padding-inline: 12px;\n border-radius: ${cssVar.borderRadius};\n\n color: ${cssVar.colorText};\n\n background: ${cssVar.colorBgElevated};\n\n &:focus {\n inset-block-start: 12px;\n }\n `,\n topbar: css`\n display: flex;\n flex: none;\n gap: 8px;\n align-items: center;\n\n block-size: 56px;\n padding-inline: 12px;\n border-block-end: 1px solid ${cssVar.colorBorderSecondary};\n `,\n topbarDivider: css`\n flex: none;\n\n inline-size: 1px;\n block-size: 18px;\n margin-inline: 2px;\n\n background: ${cssVar.colorBorderSecondary};\n `,\n topbarMain: css`\n display: flex;\n flex: 1;\n align-items: center;\n min-inline-size: 0;\n `,\n tools: css`\n display: flex;\n flex: none;\n gap: 6px;\n align-items: center;\n\n margin-inline-start: auto;\n `,\n /** Light only: the content area sits midway between the layout canvas and container white. */\n workspaceLight: css`\n && {\n background: color-mix(in srgb, ${cssVar.colorBgLayout} 50%, ${cssVar.colorBgContainer});\n }\n `,\n workspace: css`\n overflow: hidden;\n display: flex;\n flex: 1;\n flex-direction: column;\n\n min-inline-size: 0;\n min-block-size: 0;\n margin-block: ${WORKSPACE_INSET}px;\n margin-inline: 0 ${WORKSPACE_INSET}px;\n border: 1px solid ${cssVar.colorBorderSecondary};\n border-radius: ${cssVar.borderRadiusLG};\n\n background: ${cssVar.colorBgContainer};\n box-shadow: ${cssVar.boxShadowTertiary};\n\n ${responsive.laptop} {\n margin: 0;\n border: none;\n border-radius: 0;\n box-shadow: none;\n }\n `,\n}));\n"],"mappings":";;AAEA,MAAM,sBAAsB;AAG5B,MAAM,2BAA2B;AACjC,MAAM,kBAAkB;;;;;AAMxB,MAAa,SAAS,oBAAoB,EAAE,KAAK,QAAQ,kBAAkB;CACzE,OAAO,GAAG;;;;;;0BAMc,gBAAgB;;;aAG7B,OAAO,UAAU;;;MAGxB,WAAW,OAAO;;;;;CAKtB,YAAY,GAAG;;;;CAIf,aAAa,GAAG;;;;;;;;;;CAUhB,aAAa,GAAG;;;;;;CAMhB,WAAW,GAAG;;;;;;aAMH,OAAO,UAAU;;;;;;;;;;;;;;;;CAgB5B,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;MAqBL,WAAW,OAAO;;;;;;;;;CAStB,YAAY,GAAG;;;;;;CAMf,SAAS,GAAG;;;;;;CAMZ,OAAO,GAAG;;;;;;;;kBAQM,OAAO,cAAc;;CAErC,SAAS,GAAG;;;;;;mBAMK,oBAAoB;;;;;;;qBAOlB,yBAAyB;;;;;;;MAOxC,WAAW,OAAO;;;;CAItB,eAAe,GAAG;;;;CAIlB,UAAU,GAAG;;;;;;;;qBAQM,OAAO,aAAa;;aAE5B,OAAO,UAAU;;kBAEZ,OAAO,gBAAgB;;;;;;CAMvC,QAAQ,GAAG;;;;;;;;kCAQqB,OAAO,qBAAqB;;CAE5D,eAAe,GAAG;;;;;;;kBAOF,OAAO,qBAAqB;;CAE5C,YAAY,GAAG;;;;;;CAMf,OAAO,GAAG;;;;;;;;;CASV,gBAAgB,GAAG;;uCAEkB,OAAO,cAAc,QAAQ,OAAO,iBAAiB;;;CAG1F,WAAW,GAAG;;;;;;;;oBAQI,gBAAgB;uBACb,gBAAgB;wBACf,OAAO,qBAAqB;qBAC/B,OAAO,eAAe;;kBAEzB,OAAO,iBAAiB;kBACxB,OAAO,kBAAkB;;MAErC,WAAW,OAAO;;;;;;;AAOxB,EAAE"}
|
|
@@ -52,6 +52,15 @@ interface ConsoleShellProps extends Omit<HTMLAttributes<HTMLDivElement>, 'title'
|
|
|
52
52
|
* @default true
|
|
53
53
|
*/
|
|
54
54
|
hotkey?: boolean;
|
|
55
|
+
/**
|
|
56
|
+
* Swap navigation and footer for skeletons, and render `loadingContent` (default `PageLoading`)
|
|
57
|
+
* in place of children. Brand, tools and `storageKey` still come from the caller.
|
|
58
|
+
*/
|
|
59
|
+
loading?: boolean;
|
|
60
|
+
/** Body while `loading`. Defaults to `<PageLoading />`. */
|
|
61
|
+
loadingContent?: ReactNode;
|
|
62
|
+
/** Skeleton nav shape while `loading`. Pass the real groups to mirror their row counts. */
|
|
63
|
+
loadingNavigation?: ReactNode;
|
|
55
64
|
/** Grouped navigation. Collapsed state comes from the shell. */
|
|
56
65
|
navigation?: ReactNode;
|
|
57
66
|
onCollapsedChange?: (collapsed: boolean) => void;
|
|
@@ -2,10 +2,10 @@
|
|
|
2
2
|
import Button from "../../base-ui/Button/Button.mjs";
|
|
3
3
|
import Drawer from "../../base-ui/Drawer/Drawer.mjs";
|
|
4
4
|
import DraggablePanel from "../../base-ui/DraggablePanel/DraggablePanel.mjs";
|
|
5
|
-
import {
|
|
5
|
+
import { useSurfaceCardClassName } from "../Surface/link.mjs";
|
|
6
6
|
import { useIsCompact, useLocalStorage } from "../hooks.mjs";
|
|
7
7
|
import { FilterSplitProvider } from "./context.mjs";
|
|
8
|
-
import { styles
|
|
8
|
+
import { styles } from "./style.mjs";
|
|
9
9
|
import { clampSidebarWidth, sidebarWidth } from "./width.mjs";
|
|
10
10
|
import { useState } from "react";
|
|
11
11
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
@@ -34,6 +34,7 @@ function usePageSidebar(wide, storageKey) {
|
|
|
34
34
|
};
|
|
35
35
|
}
|
|
36
36
|
function FilterSidebar({ body, children, flush, head, header, label, storageKey, summary, wide }) {
|
|
37
|
+
const cardClassName = useSurfaceCardClassName();
|
|
37
38
|
const isCompact = useIsCompact();
|
|
38
39
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
39
40
|
const sidebar = usePageSidebar(wide, storageKey);
|
|
@@ -41,7 +42,7 @@ function FilterSidebar({ body, children, flush, head, header, label, storageKey,
|
|
|
41
42
|
if (isCompact) return /* @__PURE__ */ jsx(FilterSplitProvider, {
|
|
42
43
|
active: !flush,
|
|
43
44
|
children: /* @__PURE__ */ jsxs("div", {
|
|
44
|
-
className: styles
|
|
45
|
+
className: styles.layout,
|
|
45
46
|
children: [
|
|
46
47
|
header,
|
|
47
48
|
/* @__PURE__ */ jsx(Button, {
|
|
@@ -57,12 +58,12 @@ function FilterSidebar({ body, children, flush, head, header, label, storageKey,
|
|
|
57
58
|
width: 300,
|
|
58
59
|
onClose: close,
|
|
59
60
|
children: /* @__PURE__ */ jsxs("div", {
|
|
60
|
-
className: styles
|
|
61
|
+
className: styles.drawerPanel,
|
|
61
62
|
children: [head?.(close), body(close)]
|
|
62
63
|
})
|
|
63
64
|
}),
|
|
64
65
|
/* @__PURE__ */ jsx("div", {
|
|
65
|
-
className: styles
|
|
66
|
+
className: styles.content,
|
|
66
67
|
children
|
|
67
68
|
})
|
|
68
69
|
]
|
|
@@ -71,7 +72,7 @@ function FilterSidebar({ body, children, flush, head, header, label, storageKey,
|
|
|
71
72
|
return /* @__PURE__ */ jsx(FilterSplitProvider, {
|
|
72
73
|
active: !flush,
|
|
73
74
|
children: /* @__PURE__ */ jsxs("div", {
|
|
74
|
-
className: flush ? styles
|
|
75
|
+
className: flush ? styles.layout : `${styles.layout} ${cardClassName}`,
|
|
75
76
|
"data-flush": flush ? true : void 0,
|
|
76
77
|
"data-page-layout": flush ? "flush" : void 0,
|
|
77
78
|
"data-split-card": flush ? void 0 : true,
|
|
@@ -79,8 +80,8 @@ function FilterSidebar({ body, children, flush, head, header, label, storageKey,
|
|
|
79
80
|
expandable: true,
|
|
80
81
|
showHandleWhenCollapsed: true,
|
|
81
82
|
"aria-label": label,
|
|
82
|
-
className: styles
|
|
83
|
-
classNames: { content: styles
|
|
83
|
+
className: styles.sidebar,
|
|
84
|
+
classNames: { content: styles.panel },
|
|
84
85
|
collapseThreshold: sidebarWidth.collapse,
|
|
85
86
|
"data-flush": flush ? true : void 0,
|
|
86
87
|
defaultSize: { width: wide ? sidebarWidth.wide : sidebarWidth.narrow },
|
|
@@ -94,15 +95,15 @@ function FilterSidebar({ body, children, flush, head, header, label, storageKey,
|
|
|
94
95
|
onExpandChange: sidebar.onExpandChange,
|
|
95
96
|
onSizeChange: (_delta, size) => sidebar.onSizeChange(size),
|
|
96
97
|
children: [head ? /* @__PURE__ */ jsx("div", {
|
|
97
|
-
className: styles
|
|
98
|
+
className: styles.head,
|
|
98
99
|
children: head(close)
|
|
99
100
|
}) : null, /* @__PURE__ */ jsx("div", {
|
|
100
|
-
className: styles
|
|
101
|
+
className: styles.body,
|
|
101
102
|
"data-flush": flush ? true : void 0,
|
|
102
103
|
children: body(close)
|
|
103
104
|
})]
|
|
104
105
|
}), /* @__PURE__ */ jsxs("div", {
|
|
105
|
-
className: styles
|
|
106
|
+
className: styles.content,
|
|
106
107
|
"data-flush": flush ? true : void 0,
|
|
107
108
|
children: [header, children]
|
|
108
109
|
})]
|
|
@@ -112,12 +113,12 @@ function FilterSidebar({ body, children, flush, head, header, label, storageKey,
|
|
|
112
113
|
FilterSidebar.displayName = "FilterSidebar";
|
|
113
114
|
function FilterRow({ count, name }) {
|
|
114
115
|
return /* @__PURE__ */ jsxs("span", {
|
|
115
|
-
className: styles
|
|
116
|
+
className: styles.row,
|
|
116
117
|
children: [/* @__PURE__ */ jsx("span", {
|
|
117
|
-
className: styles
|
|
118
|
+
className: styles.name,
|
|
118
119
|
children: name
|
|
119
120
|
}), count !== void 0 ? /* @__PURE__ */ jsx("span", {
|
|
120
|
-
className: styles
|
|
121
|
+
className: styles.count,
|
|
121
122
|
children: count
|
|
122
123
|
}) : null]
|
|
123
124
|
});
|
|
@@ -127,18 +128,18 @@ function FilterOption({ count, icon, label, name, onClick, selected, title }) {
|
|
|
127
128
|
return /* @__PURE__ */ jsxs("button", {
|
|
128
129
|
"aria-label": label,
|
|
129
130
|
"aria-pressed": selected,
|
|
130
|
-
className: styles
|
|
131
|
+
className: styles.option,
|
|
131
132
|
title,
|
|
132
133
|
type: "button",
|
|
133
134
|
onClick,
|
|
134
135
|
children: [
|
|
135
136
|
icon,
|
|
136
137
|
/* @__PURE__ */ jsx("span", {
|
|
137
|
-
className: styles
|
|
138
|
+
className: styles.name,
|
|
138
139
|
children: name
|
|
139
140
|
}),
|
|
140
141
|
count !== void 0 ? /* @__PURE__ */ jsx("span", {
|
|
141
|
-
className: styles
|
|
142
|
+
className: styles.count,
|
|
142
143
|
children: count
|
|
143
144
|
}) : null
|
|
144
145
|
]
|