@wallarm-org/design-system 1.24.0 → 1.25.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/dist/components/AppShell/story-content/_storyAccountDropdown.d.ts +4 -1
- package/dist/components/AppShell/story-content/_storyAccountDropdown.js +64 -56
- package/dist/components/AppShell/story-content/_storyConfigRenderer.d.ts +4 -1
- package/dist/components/AppShell/story-content/_storyConfigRenderer.js +8 -5
- package/dist/components/AppShell/story-content/index.d.ts +1 -1
- package/dist/components/AppShell/story-content/index.js +1 -1
- package/dist/components/DropdownMenu/DropdownMenuRadioItem.js +1 -1
- package/dist/components/NavPanel/NavPanelBack.js +1 -1
- package/dist/components/NavPanel/NavPanelGroupLabel.js +1 -1
- package/dist/components/NavPanel/NavPanelSkeleton.js +1 -1
- package/dist/components/NavPanel/classes.js +4 -4
- package/dist/components/NavRail/NavRail.d.ts +7 -0
- package/dist/components/NavRail/NavRail.js +5 -3
- package/dist/components/NavRail/NavRailBody.js +6 -1
- package/dist/components/NavRail/NavRailContext.d.ts +2 -1
- package/dist/components/NavRail/NavRailContext.js +1 -1
- package/dist/components/NavRail/NavRailFooter.js +6 -1
- package/dist/components/NavRail/NavRailItem.d.ts +4 -0
- package/dist/components/NavRail/NavRailItem.js +31 -6
- package/dist/components/NavRail/NavRailSkeleton.js +24 -4
- package/dist/components/NavRail/classes.d.ts +12 -1
- package/dist/components/NavRail/classes.js +48 -7
- package/dist/components/NavRail/index.d.ts +1 -1
- package/dist/components/SearchModal/SearchModal.js +1 -0
- package/dist/components/Skeleton/Skeleton.d.ts +1 -1
- package/dist/components/Skeleton/Skeleton.js +1 -0
- package/dist/index.d.ts +1 -1
- package/dist/metadata/components.json +42 -11
- package/dist/theme/radius.css +1 -0
- package/package.json +1 -1
|
@@ -1,5 +1,8 @@
|
|
|
1
|
+
import { type NavRailMode } from '../../NavRail';
|
|
1
2
|
import type { Theme } from '../../ThemeProvider';
|
|
2
|
-
export type SidebarMode = 'adaptive' | 'expanded';
|
|
3
|
+
export type SidebarMode = 'adaptive' | 'expanded' | 'collapsed' | 'compact';
|
|
4
|
+
/** Adaptive collapses the rail inside a product and expands it on Home; the other modes pin it. */
|
|
5
|
+
export declare const railModeFor: (mode: SidebarMode, onHome: boolean) => NavRailMode;
|
|
3
6
|
export declare const AccountDropdown: ({ sidebarMode, onSidebarModeChange, theme, onThemeChange, }: {
|
|
4
7
|
sidebarMode: SidebarMode;
|
|
5
8
|
onSidebarModeChange: (mode: SidebarMode) => void;
|
|
@@ -1,18 +1,42 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
2
|
+
import { Fragment } from "react";
|
|
3
|
+
import { LogOut, PanelLeftDashed, PencilRuler, Settings, User, UserRound } from "../../../icons/index.js";
|
|
4
|
+
import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemContent, DropdownMenuItemIcon, DropdownMenuItemText, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenuTriggerItem } from "../../DropdownMenu/index.js";
|
|
4
5
|
import { NavRailItem } from "../../NavRail/index.js";
|
|
5
6
|
import { HStack, VStack } from "../../Stack/index.js";
|
|
6
7
|
import { Text } from "../../Text/index.js";
|
|
8
|
+
const railModeFor = (mode, onHome)=>{
|
|
9
|
+
if ('adaptive' === mode) return onHome ? 'expanded' : 'collapsed';
|
|
10
|
+
return mode;
|
|
11
|
+
};
|
|
7
12
|
const USER_NAME = 'Meow Meow';
|
|
8
13
|
const USER_EMAIL = 'meow@meow.com';
|
|
14
|
+
const THEMES = [
|
|
15
|
+
'light',
|
|
16
|
+
'dark'
|
|
17
|
+
];
|
|
18
|
+
const SIDEBAR_MODE_GROUPS = [
|
|
19
|
+
[
|
|
20
|
+
'adaptive'
|
|
21
|
+
],
|
|
22
|
+
[
|
|
23
|
+
'expanded',
|
|
24
|
+
'collapsed'
|
|
25
|
+
],
|
|
26
|
+
[
|
|
27
|
+
'compact'
|
|
28
|
+
]
|
|
29
|
+
];
|
|
30
|
+
const SIDEBAR_MODES = SIDEBAR_MODE_GROUPS.flat();
|
|
9
31
|
const THEME_LABELS = {
|
|
10
32
|
light: 'Light',
|
|
11
33
|
dark: 'Dark'
|
|
12
34
|
};
|
|
13
35
|
const SIDEBAR_MODE_LABELS = {
|
|
14
36
|
adaptive: 'Adaptive',
|
|
15
|
-
expanded: 'Always expanded'
|
|
37
|
+
expanded: 'Always expanded',
|
|
38
|
+
collapsed: 'Always collapsed',
|
|
39
|
+
compact: 'Compact'
|
|
16
40
|
};
|
|
17
41
|
const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChange })=>/*#__PURE__*/ jsxs(DropdownMenu, {
|
|
18
42
|
positioning: {
|
|
@@ -25,8 +49,9 @@ const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChang
|
|
|
25
49
|
children: [
|
|
26
50
|
/*#__PURE__*/ jsx(DropdownMenuTrigger, {
|
|
27
51
|
children: /*#__PURE__*/ jsx(NavRailItem, {
|
|
28
|
-
icon:
|
|
29
|
-
label: USER_NAME
|
|
52
|
+
icon: UserRound,
|
|
53
|
+
label: USER_NAME,
|
|
54
|
+
avatar: true
|
|
30
55
|
})
|
|
31
56
|
}),
|
|
32
57
|
/*#__PURE__*/ jsxs(DropdownMenuContent, {
|
|
@@ -79,7 +104,7 @@ const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChang
|
|
|
79
104
|
/*#__PURE__*/ jsxs(DropdownMenuItemContent, {
|
|
80
105
|
children: [
|
|
81
106
|
/*#__PURE__*/ jsx(DropdownMenuItemText, {
|
|
82
|
-
children: "
|
|
107
|
+
children: "Appearance"
|
|
83
108
|
}),
|
|
84
109
|
/*#__PURE__*/ jsx(Text, {
|
|
85
110
|
size: "xs",
|
|
@@ -90,32 +115,21 @@ const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChang
|
|
|
90
115
|
})
|
|
91
116
|
]
|
|
92
117
|
}),
|
|
93
|
-
/*#__PURE__*/
|
|
118
|
+
/*#__PURE__*/ jsx(DropdownMenuContent, {
|
|
94
119
|
className: "w-132",
|
|
95
|
-
children:
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
120
|
+
children: /*#__PURE__*/ jsx(DropdownMenuRadioGroup, {
|
|
121
|
+
value: theme,
|
|
122
|
+
onValueChange: ({ value })=>{
|
|
123
|
+
const next = THEMES.find((t)=>t === value);
|
|
124
|
+
if (next) onThemeChange(next);
|
|
125
|
+
},
|
|
126
|
+
children: THEMES.map((t)=>/*#__PURE__*/ jsx(DropdownMenuRadioItem, {
|
|
127
|
+
value: t,
|
|
128
|
+
children: /*#__PURE__*/ jsx(DropdownMenuItemText, {
|
|
129
|
+
children: THEME_LABELS[t]
|
|
104
130
|
})
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
/*#__PURE__*/ jsxs(DropdownMenuItem, {
|
|
108
|
-
onSelect: ()=>onThemeChange('dark'),
|
|
109
|
-
children: [
|
|
110
|
-
/*#__PURE__*/ jsx(DropdownMenuItemText, {
|
|
111
|
-
children: "Dark"
|
|
112
|
-
}),
|
|
113
|
-
'dark' === theme && /*#__PURE__*/ jsx(DropdownMenuShortcut, {
|
|
114
|
-
children: /*#__PURE__*/ jsx(Check, {})
|
|
115
|
-
})
|
|
116
|
-
]
|
|
117
|
-
})
|
|
118
|
-
]
|
|
131
|
+
}, t))
|
|
132
|
+
})
|
|
119
133
|
})
|
|
120
134
|
]
|
|
121
135
|
}),
|
|
@@ -140,32 +154,26 @@ const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChang
|
|
|
140
154
|
})
|
|
141
155
|
]
|
|
142
156
|
}),
|
|
143
|
-
/*#__PURE__*/
|
|
157
|
+
/*#__PURE__*/ jsx(DropdownMenuContent, {
|
|
144
158
|
className: "w-200",
|
|
145
|
-
children:
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
'expanded' === sidebarMode && /*#__PURE__*/ jsx(DropdownMenuShortcut, {
|
|
164
|
-
children: /*#__PURE__*/ jsx(Check, {})
|
|
165
|
-
})
|
|
166
|
-
]
|
|
167
|
-
})
|
|
168
|
-
]
|
|
159
|
+
children: /*#__PURE__*/ jsx(DropdownMenuRadioGroup, {
|
|
160
|
+
value: sidebarMode,
|
|
161
|
+
onValueChange: ({ value })=>{
|
|
162
|
+
const next = SIDEBAR_MODES.find((m)=>m === value);
|
|
163
|
+
if (next) onSidebarModeChange(next);
|
|
164
|
+
},
|
|
165
|
+
children: SIDEBAR_MODE_GROUPS.map((group, index)=>/*#__PURE__*/ jsxs(Fragment, {
|
|
166
|
+
children: [
|
|
167
|
+
index > 0 && /*#__PURE__*/ jsx(DropdownMenuSeparator, {}),
|
|
168
|
+
group.map((m)=>/*#__PURE__*/ jsx(DropdownMenuRadioItem, {
|
|
169
|
+
value: m,
|
|
170
|
+
children: /*#__PURE__*/ jsx(DropdownMenuItemText, {
|
|
171
|
+
children: SIDEBAR_MODE_LABELS[m]
|
|
172
|
+
})
|
|
173
|
+
}, m))
|
|
174
|
+
]
|
|
175
|
+
}, group.join('-')))
|
|
176
|
+
})
|
|
169
177
|
})
|
|
170
178
|
]
|
|
171
179
|
}),
|
|
@@ -184,4 +192,4 @@ const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChang
|
|
|
184
192
|
})
|
|
185
193
|
]
|
|
186
194
|
});
|
|
187
|
-
export { AccountDropdown };
|
|
195
|
+
export { AccountDropdown, railModeFor };
|
|
@@ -3,7 +3,10 @@ import { type Product } from './_storyLib';
|
|
|
3
3
|
export interface ConfigRemoteProps {
|
|
4
4
|
config: NavConfig;
|
|
5
5
|
basePath?: string;
|
|
6
|
+
/** Fake a 2s load whenever the product changes, to show the panel and content skeletons. */
|
|
7
|
+
simulateLoading?: boolean;
|
|
6
8
|
}
|
|
7
|
-
export declare const RemoteForProduct: ({ product }: {
|
|
9
|
+
export declare const RemoteForProduct: ({ product, simulateLoading, }: {
|
|
8
10
|
product: Product;
|
|
11
|
+
simulateLoading?: boolean;
|
|
9
12
|
}) => import("react").JSX.Element;
|
|
@@ -31,16 +31,18 @@ const RemotePageContent = ()=>{
|
|
|
31
31
|
]
|
|
32
32
|
});
|
|
33
33
|
};
|
|
34
|
-
const ConfigRemote = ({ config, basePath })=>{
|
|
35
|
-
const [loading, setLoading] = useState(
|
|
34
|
+
const ConfigRemote = ({ config, basePath, simulateLoading = true })=>{
|
|
35
|
+
const [loading, setLoading] = useState(simulateLoading);
|
|
36
36
|
useEffect(()=>{
|
|
37
|
+
if (!simulateLoading) return;
|
|
37
38
|
setLoading(true);
|
|
38
39
|
const timer = setTimeout(()=>{
|
|
39
40
|
setLoading(false);
|
|
40
41
|
}, 2000);
|
|
41
42
|
return ()=>clearTimeout(timer);
|
|
42
43
|
}, [
|
|
43
|
-
config.productLabel
|
|
44
|
+
config.productLabel,
|
|
45
|
+
simulateLoading
|
|
44
46
|
]);
|
|
45
47
|
return /*#__PURE__*/ jsx(RemoteShell, {
|
|
46
48
|
config: config,
|
|
@@ -67,12 +69,13 @@ const ConfigRemote = ({ config, basePath })=>{
|
|
|
67
69
|
})
|
|
68
70
|
});
|
|
69
71
|
};
|
|
70
|
-
const RemoteForProduct = ({ product })=>{
|
|
72
|
+
const RemoteForProduct = ({ product, simulateLoading = true })=>{
|
|
71
73
|
if ('home' === product) return /*#__PURE__*/ jsx(HomeContent, {});
|
|
72
74
|
const { config } = PRODUCT_CONFIGS[product];
|
|
73
75
|
return /*#__PURE__*/ jsx(ConfigRemote, {
|
|
74
76
|
config: config,
|
|
75
|
-
basePath: `/${product}
|
|
77
|
+
basePath: `/${product}`,
|
|
78
|
+
simulateLoading: simulateLoading
|
|
76
79
|
});
|
|
77
80
|
};
|
|
78
81
|
export { RemoteForProduct };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AccountDropdown, type SidebarMode } from './_storyAccountDropdown';
|
|
1
|
+
export { AccountDropdown, railModeFor, type SidebarMode } from './_storyAccountDropdown';
|
|
2
2
|
export { RemoteForProduct } from './_storyConfigRenderer';
|
|
3
3
|
export { HeaderActions } from './_storyHeaderActions';
|
|
4
4
|
export { HomeContent } from './_storyHomeContent';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { AccountDropdown } from "./_storyAccountDropdown.js";
|
|
1
|
+
export { AccountDropdown, railModeFor } from "./_storyAccountDropdown.js";
|
|
2
2
|
export { RemoteForProduct } from "./_storyConfigRenderer.js";
|
|
3
3
|
export { HeaderActions } from "./_storyHeaderActions.js";
|
|
4
4
|
export { HomeContent } from "./_storyHomeContent.js";
|
|
@@ -15,7 +15,7 @@ const DropdownMenuRadioItem = ({ children, value, disabled, closeOnSelect, varia
|
|
|
15
15
|
"data-testid": testId,
|
|
16
16
|
className: cn(dropdownMenuItemVariants({
|
|
17
17
|
variant
|
|
18
|
-
}), className),
|
|
18
|
+
}), 'data-[state=checked]:bg-states-primary-active', className),
|
|
19
19
|
children: [
|
|
20
20
|
children,
|
|
21
21
|
/*#__PURE__*/ jsx(DropdownMenuItemIndicator, {
|
|
@@ -11,7 +11,7 @@ const NavPanelBack = ({ ref, className, children, ...props })=>{
|
|
|
11
11
|
type: "button",
|
|
12
12
|
"data-slot": "nav-panel-back",
|
|
13
13
|
"data-testid": testId,
|
|
14
|
-
className: cn('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-
|
|
14
|
+
className: cn('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-10 p-8 text-sm text-text-primary transition-colors outline-none hover:overlay-states-primary-hover focus-visible:overlay-states-primary-hover active:overlay-states-primary-pressed', className),
|
|
15
15
|
children: [
|
|
16
16
|
/*#__PURE__*/ jsx(CornerUpLeft, {
|
|
17
17
|
size: "md"
|
|
@@ -22,7 +22,7 @@ const NavPanelGroupLabel = ({ ref, icon: Icon, className, children, ...props })=
|
|
|
22
22
|
style: {
|
|
23
23
|
paddingLeft: 8 + depth * indent
|
|
24
24
|
},
|
|
25
|
-
className: cn('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-
|
|
25
|
+
className: cn('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-10 py-8 pr-8 text-sm text-text-primary transition-colors outline-none hover:overlay-states-primary-hover focus-visible:overlay-states-primary-hover active:overlay-states-primary-pressed', className),
|
|
26
26
|
children: [
|
|
27
27
|
Icon && /*#__PURE__*/ jsx("span", {
|
|
28
28
|
className: "flex shrink-0 items-center justify-center",
|
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
|
-
const navPanelItemVariants = cva('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-
|
|
2
|
+
const navPanelItemVariants = cva('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-10 p-8 text-sm text-text-primary transition-colors outline-none', {
|
|
3
3
|
variants: {
|
|
4
4
|
active: {
|
|
5
5
|
true: 'overlay-states-primary-active font-semibold',
|
|
6
|
-
false: '
|
|
6
|
+
false: 'hover:overlay-states-primary-hover focus-visible:overlay-states-primary-hover active:overlay-states-primary-pressed'
|
|
7
7
|
}
|
|
8
8
|
},
|
|
9
9
|
defaultVariants: {
|
|
10
10
|
active: false
|
|
11
11
|
}
|
|
12
12
|
});
|
|
13
|
-
const navPanelGroupItemVariants = cva('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-
|
|
13
|
+
const navPanelGroupItemVariants = cva('overlay flex h-32 shrink-0 w-full cursor-pointer items-center gap-8 rounded-10 py-8 pr-8 text-sm text-text-primary transition-colors outline-none', {
|
|
14
14
|
variants: {
|
|
15
15
|
active: {
|
|
16
16
|
true: 'overlay-states-primary-active font-semibold',
|
|
17
|
-
false: '
|
|
17
|
+
false: 'hover:overlay-states-primary-hover focus-visible:overlay-states-primary-hover active:overlay-states-primary-pressed'
|
|
18
18
|
}
|
|
19
19
|
},
|
|
20
20
|
defaultVariants: {
|
|
@@ -1,8 +1,15 @@
|
|
|
1
1
|
import type { FC, HTMLAttributes, ReactNode, Ref } from 'react';
|
|
2
2
|
import { type TestableProps } from '../../utils/testId';
|
|
3
|
+
import { type NavRailMode } from './NavRailContext';
|
|
3
4
|
export interface NavRailProps extends HTMLAttributes<HTMLElement>, TestableProps {
|
|
4
5
|
ref?: Ref<HTMLElement>;
|
|
5
6
|
children?: ReactNode;
|
|
7
|
+
/**
|
|
8
|
+
* How the rail lays out its items: `expanded` (icon beside label), `collapsed` (icon only) or
|
|
9
|
+
* `compact` (icon over a short label). Wins over `collapsed` when both are set.
|
|
10
|
+
*/
|
|
11
|
+
mode?: NavRailMode;
|
|
12
|
+
/** Shorthand for `mode='collapsed'`, kept so existing hosts keep working. Prefer `mode`. */
|
|
6
13
|
collapsed?: boolean;
|
|
7
14
|
}
|
|
8
15
|
export declare const NavRail: FC<NavRailProps>;
|
|
@@ -6,8 +6,9 @@ import { cn } from "../../utils/cn.js";
|
|
|
6
6
|
import { TestIdProvider } from "../../utils/testId.js";
|
|
7
7
|
import { navRailVariants } from "./classes.js";
|
|
8
8
|
import { NavRailContextProvider } from "./NavRailContext.js";
|
|
9
|
-
const NavRail = ({ ref, collapsed = false, className, children, 'data-testid': testId, ...props })=>{
|
|
9
|
+
const NavRail = ({ ref, mode: modeProp, collapsed = false, className, children, 'data-testid': testId, ...props })=>{
|
|
10
10
|
const internalRef = useRef(null);
|
|
11
|
+
const mode = modeProp ?? (collapsed ? 'collapsed' : 'expanded');
|
|
11
12
|
const focusPanel = useCallback(()=>{
|
|
12
13
|
const panel = document.querySelector('[data-slot="nav-panel"]');
|
|
13
14
|
const target = panel?.querySelector('[tabindex="0"]');
|
|
@@ -37,16 +38,17 @@ const NavRail = ({ ref, collapsed = false, className, children, 'data-testid': t
|
|
|
37
38
|
value: testId,
|
|
38
39
|
children: /*#__PURE__*/ jsx(NavRailContextProvider, {
|
|
39
40
|
value: {
|
|
40
|
-
|
|
41
|
+
mode
|
|
41
42
|
},
|
|
42
43
|
children: /*#__PURE__*/ jsx("nav", {
|
|
43
44
|
...props,
|
|
44
45
|
ref: composeRefs(internalRef, ref),
|
|
45
46
|
"aria-label": "Global navigation",
|
|
46
47
|
"data-slot": "nav-rail",
|
|
48
|
+
"data-mode": mode,
|
|
47
49
|
"data-testid": testId,
|
|
48
50
|
className: cn(navRailVariants({
|
|
49
|
-
|
|
51
|
+
mode
|
|
50
52
|
}), className),
|
|
51
53
|
children: children
|
|
52
54
|
})
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
3
|
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
import { navRailBodyVariants } from "./classes.js";
|
|
5
|
+
import { useNavRailContext } from "./NavRailContext.js";
|
|
4
6
|
const NavRailBody = ({ ref, className, children, ...props })=>{
|
|
7
|
+
const { mode } = useNavRailContext();
|
|
5
8
|
const testId = useTestId('body');
|
|
6
9
|
return /*#__PURE__*/ jsx("div", {
|
|
7
10
|
...props,
|
|
8
11
|
ref: ref,
|
|
9
12
|
"data-slot": "nav-rail-body",
|
|
10
13
|
"data-testid": testId,
|
|
11
|
-
className: cn(
|
|
14
|
+
className: cn(navRailBodyVariants({
|
|
15
|
+
mode
|
|
16
|
+
}), className),
|
|
12
17
|
children: children
|
|
13
18
|
});
|
|
14
19
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
|
+
export type NavRailMode = 'expanded' | 'collapsed' | 'compact';
|
|
1
2
|
interface NavRailContextValue {
|
|
2
|
-
|
|
3
|
+
mode: NavRailMode;
|
|
3
4
|
}
|
|
4
5
|
export declare const NavRailContextProvider: import("react").Provider<NavRailContextValue>;
|
|
5
6
|
export declare function useNavRailContext(): NavRailContextValue;
|
|
@@ -1,14 +1,19 @@
|
|
|
1
1
|
import { jsx } from "react/jsx-runtime";
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
3
|
import { useTestId } from "../../utils/testId.js";
|
|
4
|
+
import { navRailFooterVariants } from "./classes.js";
|
|
5
|
+
import { useNavRailContext } from "./NavRailContext.js";
|
|
4
6
|
const NavRailFooter = ({ ref, className, children, ...props })=>{
|
|
7
|
+
const { mode } = useNavRailContext();
|
|
5
8
|
const testId = useTestId('footer');
|
|
6
9
|
return /*#__PURE__*/ jsx("div", {
|
|
7
10
|
...props,
|
|
8
11
|
ref: ref,
|
|
9
12
|
"data-slot": "nav-rail-footer",
|
|
10
13
|
"data-testid": testId,
|
|
11
|
-
className: cn(
|
|
14
|
+
className: cn(navRailFooterVariants({
|
|
15
|
+
mode
|
|
16
|
+
}), className),
|
|
12
17
|
children: children
|
|
13
18
|
});
|
|
14
19
|
};
|
|
@@ -8,5 +8,9 @@ export interface NavRailItemProps extends AnchorHTMLAttributes<HTMLAnchorElement
|
|
|
8
8
|
label: ReactNode;
|
|
9
9
|
shortcut?: string[];
|
|
10
10
|
active?: boolean;
|
|
11
|
+
/** Seats the icon on a soft plate, for the signed-in user's item at the foot of the rail. */
|
|
12
|
+
avatar?: boolean;
|
|
13
|
+
/** User photo for the plate (implies `avatar`). The icon stays underneath and returns if the photo fails to load. */
|
|
14
|
+
avatarSrc?: string;
|
|
11
15
|
}
|
|
12
16
|
export declare const NavRailItem: FC<NavRailItemProps>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Fragment, useRef } from "react";
|
|
2
|
+
import { Fragment, useRef, useState } from "react";
|
|
3
3
|
import { composeRefs } from "@radix-ui/react-compose-refs";
|
|
4
4
|
import { Slot, Slottable } from "@radix-ui/react-slot";
|
|
5
5
|
import { cn } from "../../utils/cn.js";
|
|
@@ -8,35 +8,60 @@ import { Kbd } from "../Kbd/index.js";
|
|
|
8
8
|
import { Tooltip } from "../Tooltip/index.js";
|
|
9
9
|
import { TooltipContent } from "../Tooltip/TooltipContent.js";
|
|
10
10
|
import { TooltipTrigger } from "../Tooltip/TooltipTrigger.js";
|
|
11
|
-
import { navRailItemVariants } from "./classes.js";
|
|
11
|
+
import { navRailItemCompactLabelClassName, navRailItemVariants } from "./classes.js";
|
|
12
12
|
import { useNavRailContext } from "./NavRailContext.js";
|
|
13
13
|
import { useShortcut } from "./useShortcut.js";
|
|
14
|
-
const NavRailItem = ({ ref, asChild = false, icon: Icon, label, shortcut, active = false, className, children, 'data-testid': testIdProp, ...props })=>{
|
|
15
|
-
const {
|
|
14
|
+
const NavRailItem = ({ ref, asChild = false, icon: Icon, label, shortcut, active = false, avatar = false, avatarSrc, className, children, 'data-testid': testIdProp, ...props })=>{
|
|
15
|
+
const { mode } = useNavRailContext();
|
|
16
16
|
const testId = useTestId('item', testIdProp);
|
|
17
17
|
const Comp = asChild ? Slot : 'a';
|
|
18
18
|
const internalRef = useRef(null);
|
|
19
|
+
const [failedSrc, setFailedSrc] = useState();
|
|
20
|
+
const photo = avatarSrc && avatarSrc !== failedSrc ? avatarSrc : void 0;
|
|
21
|
+
const hasPlate = avatar || void 0 !== avatarSrc;
|
|
22
|
+
const showsLabel = 'expanded' === mode || 'compact' === mode && !hasPlate;
|
|
23
|
+
const fallbackName = showsLabel || 'string' != typeof label ? void 0 : label;
|
|
19
24
|
useShortcut(shortcut, internalRef);
|
|
20
25
|
const element = /*#__PURE__*/ jsxs(Comp, {
|
|
21
26
|
...props,
|
|
22
27
|
ref: composeRefs(internalRef, ref),
|
|
28
|
+
"aria-label": props['aria-label'] ?? fallbackName,
|
|
23
29
|
"aria-current": active ? 'page' : void 0,
|
|
24
30
|
"data-slot": "nav-rail-item",
|
|
25
31
|
"data-testid": testId,
|
|
26
32
|
className: cn(navRailItemVariants({
|
|
33
|
+
mode,
|
|
27
34
|
active
|
|
28
35
|
}), className),
|
|
29
36
|
children: [
|
|
30
37
|
/*#__PURE__*/ jsx("span", {
|
|
31
38
|
className: "flex shrink-0 items-center justify-center",
|
|
32
|
-
children: /*#__PURE__*/
|
|
39
|
+
children: hasPlate ? /*#__PURE__*/ jsxs("span", {
|
|
40
|
+
"data-slot": "nav-rail-item-avatar",
|
|
41
|
+
className: cn('-m-4 grid size-24 place-items-center overflow-hidden rounded-8 bg-states-primary-hover *:col-start-1 *:row-start-1', !photo && 'border border-border-primary'),
|
|
42
|
+
children: [
|
|
43
|
+
/*#__PURE__*/ jsx(Icon, {
|
|
44
|
+
size: "md"
|
|
45
|
+
}),
|
|
46
|
+
photo && /*#__PURE__*/ jsx("img", {
|
|
47
|
+
src: photo,
|
|
48
|
+
alt: "",
|
|
49
|
+
className: "size-full object-cover",
|
|
50
|
+
onError: ()=>setFailedSrc(photo)
|
|
51
|
+
})
|
|
52
|
+
]
|
|
53
|
+
}) : /*#__PURE__*/ jsx(Icon, {
|
|
33
54
|
size: "md"
|
|
34
55
|
})
|
|
35
56
|
}),
|
|
36
|
-
|
|
57
|
+
'expanded' === mode && /*#__PURE__*/ jsx("span", {
|
|
37
58
|
className: cn('truncate whitespace-nowrap transition-[opacity,width] duration-200 pl-8'),
|
|
38
59
|
children: label
|
|
39
60
|
}),
|
|
61
|
+
showsLabel && 'compact' === mode && /*#__PURE__*/ jsx("span", {
|
|
62
|
+
className: navRailItemCompactLabelClassName,
|
|
63
|
+
children: label
|
|
64
|
+
}),
|
|
40
65
|
/*#__PURE__*/ jsx(Slottable, {
|
|
41
66
|
children: children
|
|
42
67
|
})
|
|
@@ -2,20 +2,40 @@ import { jsx } from "react/jsx-runtime";
|
|
|
2
2
|
import { cn } from "../../utils/cn.js";
|
|
3
3
|
import { useTestId } from "../../utils/testId.js";
|
|
4
4
|
import { Skeleton } from "../Skeleton/index.js";
|
|
5
|
+
import { navRailSkeletonVariants } from "./classes.js";
|
|
6
|
+
import { useNavRailContext } from "./NavRailContext.js";
|
|
7
|
+
const SKELETON_BARS = {
|
|
8
|
+
expanded: {
|
|
9
|
+
width: '100%',
|
|
10
|
+
height: '28px'
|
|
11
|
+
},
|
|
12
|
+
collapsed: {
|
|
13
|
+
width: '28px',
|
|
14
|
+
height: '28px'
|
|
15
|
+
},
|
|
16
|
+
compact: {
|
|
17
|
+
width: '54px',
|
|
18
|
+
height: '38px'
|
|
19
|
+
}
|
|
20
|
+
};
|
|
5
21
|
const NavRailSkeleton = ({ ref, className, count = 4, ...props })=>{
|
|
22
|
+
const { mode } = useNavRailContext();
|
|
6
23
|
const testId = useTestId('skeleton');
|
|
24
|
+
const bar = SKELETON_BARS[mode];
|
|
7
25
|
return /*#__PURE__*/ jsx("div", {
|
|
8
26
|
...props,
|
|
9
27
|
ref: ref,
|
|
10
28
|
"data-slot": "nav-rail-skeleton",
|
|
11
29
|
"data-testid": testId,
|
|
12
|
-
className: cn(
|
|
30
|
+
className: cn(navRailSkeletonVariants({
|
|
31
|
+
mode
|
|
32
|
+
}), className),
|
|
13
33
|
children: Array.from({
|
|
14
34
|
length: count
|
|
15
35
|
}, (_, i)=>/*#__PURE__*/ jsx(Skeleton, {
|
|
16
|
-
width:
|
|
17
|
-
height:
|
|
18
|
-
rounded:
|
|
36
|
+
width: bar.width,
|
|
37
|
+
height: bar.height,
|
|
38
|
+
rounded: 10
|
|
19
39
|
}, i))
|
|
20
40
|
});
|
|
21
41
|
};
|
|
@@ -1,6 +1,17 @@
|
|
|
1
1
|
export declare const navRailVariants: (props?: ({
|
|
2
|
-
|
|
2
|
+
mode?: "collapsed" | "compact" | "expanded" | null | undefined;
|
|
3
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
4
|
+
export declare const navRailBodyVariants: (props?: ({
|
|
5
|
+
mode?: "collapsed" | "compact" | "expanded" | null | undefined;
|
|
6
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
7
|
+
export declare const navRailFooterVariants: (props?: ({
|
|
8
|
+
mode?: "collapsed" | "compact" | "expanded" | null | undefined;
|
|
9
|
+
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
10
|
+
export declare const navRailSkeletonVariants: (props?: ({
|
|
11
|
+
mode?: "collapsed" | "compact" | "expanded" | null | undefined;
|
|
3
12
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
4
13
|
export declare const navRailItemVariants: (props?: ({
|
|
14
|
+
mode?: "collapsed" | "compact" | "expanded" | null | undefined;
|
|
5
15
|
active?: boolean | null | undefined;
|
|
6
16
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
|
17
|
+
export declare const navRailItemCompactLabelClassName = "line-clamp-2 w-56 shrink-0 text-center text-2xs font-medium text-ellipsis break-normal";
|
|
@@ -1,24 +1,65 @@
|
|
|
1
1
|
import { cva } from "class-variance-authority";
|
|
2
2
|
const navRailVariants = cva('flex h-full shrink-0 flex-col overflow-hidden px-8 pt-6 pb-12 transition-[width] duration-200 ease-in-out', {
|
|
3
3
|
variants: {
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
mode: {
|
|
5
|
+
expanded: 'w-[184px]',
|
|
6
|
+
collapsed: 'w-[48px]',
|
|
7
|
+
compact: 'w-[78px]'
|
|
7
8
|
}
|
|
8
9
|
},
|
|
9
10
|
defaultVariants: {
|
|
10
|
-
|
|
11
|
+
mode: 'expanded'
|
|
11
12
|
}
|
|
12
13
|
});
|
|
13
|
-
const
|
|
14
|
+
const railGap = {
|
|
15
|
+
expanded: 'gap-2',
|
|
16
|
+
collapsed: 'gap-2',
|
|
17
|
+
compact: 'gap-4'
|
|
18
|
+
};
|
|
19
|
+
const navRailBodyVariants = cva('flex min-h-0 flex-1 flex-col overflow-y-auto overscroll-none [scrollbar-width:thin]', {
|
|
14
20
|
variants: {
|
|
21
|
+
mode: railGap
|
|
22
|
+
},
|
|
23
|
+
defaultVariants: {
|
|
24
|
+
mode: 'expanded'
|
|
25
|
+
}
|
|
26
|
+
});
|
|
27
|
+
const navRailFooterVariants = cva('mt-auto flex flex-col', {
|
|
28
|
+
variants: {
|
|
29
|
+
mode: railGap
|
|
30
|
+
},
|
|
31
|
+
defaultVariants: {
|
|
32
|
+
mode: 'expanded'
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
const navRailSkeletonVariants = cva('flex flex-col items-center py-2', {
|
|
36
|
+
variants: {
|
|
37
|
+
mode: {
|
|
38
|
+
expanded: 'gap-6',
|
|
39
|
+
collapsed: 'gap-6',
|
|
40
|
+
compact: 'gap-8'
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
defaultVariants: {
|
|
44
|
+
mode: 'expanded'
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
const navRailItemVariants = cva('overlay flex w-full cursor-pointer items-center rounded-10 text-sm text-text-primary transition-colors outline-none data-[state=open]:overlay-states-primary-active', {
|
|
48
|
+
variants: {
|
|
49
|
+
mode: {
|
|
50
|
+
expanded: 'h-32 p-8',
|
|
51
|
+
collapsed: 'h-32 p-8',
|
|
52
|
+
compact: 'min-h-42 flex-col justify-center gap-2 px-8 py-6'
|
|
53
|
+
},
|
|
15
54
|
active: {
|
|
16
55
|
true: 'overlay-states-primary-active',
|
|
17
|
-
false: '
|
|
56
|
+
false: 'hover:overlay-states-primary-hover focus-visible:overlay-states-primary-hover active:overlay-states-primary-pressed'
|
|
18
57
|
}
|
|
19
58
|
},
|
|
20
59
|
defaultVariants: {
|
|
60
|
+
mode: 'expanded',
|
|
21
61
|
active: false
|
|
22
62
|
}
|
|
23
63
|
});
|
|
24
|
-
|
|
64
|
+
const navRailItemCompactLabelClassName = 'line-clamp-2 w-56 shrink-0 text-center text-2xs font-medium text-ellipsis break-normal';
|
|
65
|
+
export { navRailBodyVariants, navRailFooterVariants, navRailItemCompactLabelClassName, navRailItemVariants, navRailSkeletonVariants, navRailVariants };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export { NavRail, type NavRailProps } from './NavRail';
|
|
2
2
|
export { NavRailBody, type NavRailBodyProps } from './NavRailBody';
|
|
3
|
-
export { useNavRailContext } from './NavRailContext';
|
|
3
|
+
export { type NavRailMode, useNavRailContext } from './NavRailContext';
|
|
4
4
|
export { NavRailFooter, type NavRailFooterProps } from './NavRailFooter';
|
|
5
5
|
export { NavRailItem, type NavRailItemProps } from './NavRailItem';
|
|
6
6
|
export { NavRailSeparator, type NavRailSeparatorProps } from './NavRailSeparator';
|
|
@@ -29,6 +29,7 @@ const SearchModal = ({ children, open, onOpenChange, onQueryChange, 'data-testid
|
|
|
29
29
|
children: /*#__PURE__*/ jsx("div", {
|
|
30
30
|
"data-slot": "search-modal",
|
|
31
31
|
"data-testid": testId,
|
|
32
|
+
className: "contents",
|
|
32
33
|
children: /*#__PURE__*/ jsx(Dialog.Root, {
|
|
33
34
|
open: open,
|
|
34
35
|
onOpenChange: handleOpenChange,
|
|
@@ -3,7 +3,7 @@ import { type VariantProps } from 'class-variance-authority';
|
|
|
3
3
|
import type { TestableProps } from '../../utils/testId';
|
|
4
4
|
declare const skeletonVariants: (props?: ({
|
|
5
5
|
transparent?: boolean | null | undefined;
|
|
6
|
-
rounded?: "full" | "none" | 2 | 4 | 6 | 8 | 12 | 16 | 24 | 32 | null | undefined;
|
|
6
|
+
rounded?: "full" | "none" | 2 | 4 | 6 | 8 | 10 | 12 | 16 | 24 | 32 | null | undefined;
|
|
7
7
|
withDimensions?: boolean | null | undefined;
|
|
8
8
|
withChildren?: boolean | null | undefined;
|
|
9
9
|
} & import("class-variance-authority/types").ClassProp) | undefined) => string;
|
package/dist/index.d.ts
CHANGED
|
@@ -52,7 +52,7 @@ export { Link, type LinkProps } from './components/Link';
|
|
|
52
52
|
export { List, ListIcon, type ListIconProps, ListItem, type ListItemProps, type ListProps, } from './components/List';
|
|
53
53
|
export { Loader, type LoaderProps } from './components/Loader';
|
|
54
54
|
export { Logo, type LogoProps, type LogoSize, type LogoStyle, type LogoType, } from './components/Logo';
|
|
55
|
-
export { NavRail, NavRailBody, type NavRailBodyProps, NavRailFooter, type NavRailFooterProps, NavRailItem, type NavRailItemProps, type NavRailProps, NavRailSeparator, type NavRailSeparatorProps, NavRailSkeleton, type NavRailSkeletonProps, } from './components/NavRail';
|
|
55
|
+
export { NavRail, NavRailBody, type NavRailBodyProps, NavRailFooter, type NavRailFooterProps, NavRailItem, type NavRailItemProps, type NavRailMode, type NavRailProps, NavRailSeparator, type NavRailSeparatorProps, NavRailSkeleton, type NavRailSkeletonProps, } from './components/NavRail';
|
|
56
56
|
export { NumberInput, type NumberInputProps } from './components/NumberInput';
|
|
57
57
|
export { NumericBadge, type NumericBadgeProps, } from './components/NumericBadge';
|
|
58
58
|
export { OverflowTooltip, OverflowTooltipContent, type OverflowTooltipContentProps, type OverflowTooltipProps, } from './components/OverflowTooltip';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "1.
|
|
3
|
-
"generatedAt": "2026-09-
|
|
2
|
+
"version": "1.24.0",
|
|
3
|
+
"generatedAt": "2026-09-28T08:13:10.040Z",
|
|
4
4
|
"components": [
|
|
5
5
|
{
|
|
6
6
|
"name": "Accordion",
|
|
@@ -5341,17 +5341,22 @@
|
|
|
5341
5341
|
"examples": [
|
|
5342
5342
|
{
|
|
5343
5343
|
"name": "Basic",
|
|
5344
|
-
"code": "({ ambient }) =>
|
|
5345
|
-
"description": "The three regions composed once — `AppShellHeader`, `AppShellRail`, `AppShellRemote` — with the content surface being the only part that scrolls."
|
|
5344
|
+
"code": "({ ambient }) => <Shell ambient={ambient} />",
|
|
5345
|
+
"description": "The three regions composed once — `AppShellHeader`, `AppShellRail`, `AppShellRemote` — with the content surface being the only part that scrolls. Pick a product in the rail to drill into it, and the account item at the bottom for appearance and sidebar mode."
|
|
5346
|
+
},
|
|
5347
|
+
{
|
|
5348
|
+
"name": "Loading",
|
|
5349
|
+
"code": "({ ambient, loading }) => (\n <Shell ambient={ambient} loading={loading} simulateProductLoading />\n)",
|
|
5350
|
+
"description": "How the shell looks while the platform loads. The header actions and the product rail hold skeletons that sit exactly where the real items land, so nothing jumps when they arrive. Turn `loading` off in Controls to watch the swap. Opening a product also shows its own panel and content loading."
|
|
5346
5351
|
},
|
|
5347
5352
|
{
|
|
5348
5353
|
"name": "RevealFlow",
|
|
5349
|
-
"code": "() => {\n const pathname = useLocationPathname();\n const activeProduct = deriveProduct(pathname);\n\n const [splashDone, setSplashDone] = useState(false);\n const [sidebarMode, setSidebarMode] = useState<SidebarMode>('adaptive');\n const [revealKey, setRevealKey] = useState(0);\n const { theme, setTheme } = useTheme();\n const
|
|
5354
|
+
"code": "() => {\n const pathname = useLocationPathname();\n const activeProduct = deriveProduct(pathname);\n\n const [splashDone, setSplashDone] = useState(false);\n const [sidebarMode, setSidebarMode] = useState<SidebarMode>('adaptive');\n const [revealKey, setRevealKey] = useState(0);\n const { theme, setTheme } = useTheme();\n const railMode = railModeFor(sidebarMode, activeProduct === 'home');\n\n useEffect(() => {\n if (splashDone) return;\n const timer = setTimeout(() => setSplashDone(true), 2000);\n return () => clearTimeout(timer);\n }, [splashDone]);\n\n const handleReplay = () => {\n setSplashDone(false);\n setRevealKey(k => k + 1);\n };\n\n if (!splashDone) {\n return (\n <div key={revealKey} className='h-screen w-screen bg-bg-page-bg'>\n <SplashScreen />\n </div>\n );\n }\n\n return (\n <AppShell key={revealKey} reveal>\n <AppShellHeader>\n <TopHeader>\n <TopHeaderLogo href='/'>\n <WallarmLogo />\n </TopHeaderLogo>\n\n <TopHeaderActions>\n <HeaderActions />\n </TopHeaderActions>\n </TopHeader>\n </AppShellHeader>\n\n <AppShellRail>\n <NavRail mode={railMode}>\n <NavRailBody>\n <NavRailItem\n icon={Home}\n label='Home'\n shortcut={['G', 'H']}\n active={activeProduct === 'home'}\n onClick={() => navigateToProduct('home')}\n />\n <RecentDropdown />\n\n <NavRailSeparator />\n\n <ProductNavItems activeProduct={activeProduct} />\n </NavRailBody>\n\n <NavRailFooterContent\n activeProduct={activeProduct}\n sidebarMode={sidebarMode}\n onSidebarModeChange={setSidebarMode}\n theme={theme}\n onThemeChange={setTheme}\n />\n </NavRail>\n </AppShellRail>\n\n <AppShellRemote>\n <div className='flex gap-8 absolute top-4 right-4 z-10'>\n <Button variant='ghost' size='small' color='neutral' onClick={handleReplay}>\n Replay animation\n </Button>\n </div>\n\n <RemoteForProduct product={activeProduct} />\n </AppShellRemote>\n </AppShell>\n );\n}",
|
|
5350
5355
|
"description": "`reveal` animates the chrome in on the first application load only. Leave it unset for an ordinary screen; this exists for prototyping the boot moment itself."
|
|
5351
5356
|
},
|
|
5352
5357
|
{
|
|
5353
5358
|
"name": "LoginFlow",
|
|
5354
|
-
"code": "() => {\n const pathname = useLocationPathname();\n const activeProduct = deriveProduct(pathname);\n\n const [splashVisible, setSplashVisible] = useState(true);\n const [showShell, setShowShell] = useState(false);\n const [revealed, setRevealed] = useState(false);\n const [flowKey, setFlowKey] = useState(0);\n const [sidebarMode, setSidebarMode] = useState<SidebarMode>('adaptive');\n const { theme, setTheme } = useTheme();\n const
|
|
5359
|
+
"code": "() => {\n const pathname = useLocationPathname();\n const activeProduct = deriveProduct(pathname);\n\n const [splashVisible, setSplashVisible] = useState(true);\n const [showShell, setShowShell] = useState(false);\n const [revealed, setRevealed] = useState(false);\n const [flowKey, setFlowKey] = useState(0);\n const [sidebarMode, setSidebarMode] = useState<SidebarMode>('adaptive');\n const { theme, setTheme } = useTheme();\n const railMode = railModeFor(sidebarMode, activeProduct === 'home');\n\n useEffect(() => {\n if (!splashVisible) return;\n const timer = setTimeout(() => setSplashVisible(false), 2000);\n return () => clearTimeout(timer);\n }, [splashVisible]);\n\n const handleSignIn = () => {\n setShowShell(true);\n };\n\n const handleReplay = () => {\n setShowShell(false);\n setRevealed(false);\n setSplashVisible(true);\n setFlowKey(k => k + 1);\n };\n\n return (\n <div\n key={flowKey}\n className='relative h-screen w-screen overflow-hidden bg-component-app-shell-bg'\n >\n {!revealed && (\n <AnimatedBackground\n className='absolute inset-0'\n style={{\n opacity: showShell ? 0 : 1,\n transition: showShell ? 'opacity 400ms cubic-bezier(0.4, 0, 0.2, 1)' : undefined,\n }}\n />\n )}\n\n {!showShell && (\n <div className='absolute inset-0 flex items-center justify-center z-10'>\n <SplashScreen\n visible={splashVisible}\n shrinkTarget={CARD_DIMENSIONS}\n className='bg-bg-page-bg shadow-lg'\n >\n <div className='flex h-full w-full flex-col items-center justify-center gap-16 p-24'>\n <Text size='xl'>Sign In</Text>\n <div className='flex w-full flex-col gap-12'>\n <Input placeholder='Email' />\n <Input placeholder='Password' type='password' />\n </div>\n <Button variant='primary' color='brand' className='w-full' onClick={handleSignIn}>\n Sign In\n </Button>\n </div>\n </SplashScreen>\n </div>\n )}\n\n {showShell && (\n <div className='absolute inset-0'>\n <AppShell expandFrom={CARD_DIMENSIONS} onRevealed={() => setRevealed(true)}>\n <AppShellHeader>\n <TopHeader>\n <TopHeaderLogo href='/'>\n <WallarmLogo />\n </TopHeaderLogo>\n\n <TopHeaderActions>\n <HeaderActions />\n </TopHeaderActions>\n </TopHeader>\n </AppShellHeader>\n\n <AppShellRail>\n <NavRail mode={railMode}>\n <NavRailBody>\n <NavRailItem\n icon={Home}\n label='Home'\n active={activeProduct === 'home'}\n onClick={() => navigateToProduct('home')}\n />\n\n <NavRailSeparator />\n\n <ProductNavItems activeProduct={activeProduct} />\n </NavRailBody>\n <NavRailFooterContent\n activeProduct={activeProduct}\n sidebarMode={sidebarMode}\n onSidebarModeChange={setSidebarMode}\n theme={theme}\n onThemeChange={setTheme}\n />\n </NavRail>\n </AppShellRail>\n\n <AppShellRemote>\n <div className='flex gap-8 absolute top-4 right-4 z-10'>\n <Button variant='ghost' size='small' color='neutral' onClick={handleReplay}>\n Replay animation\n </Button>\n </div>\n <RemoteForProduct product={activeProduct} />\n </AppShellRemote>\n </AppShell>\n </div>\n )}\n </div>\n );\n}",
|
|
5355
5360
|
"description": "The whole entrance: the splash hands off, the content surface expands from the sign-in card into the full shell. `onRevealed` fires when it has settled."
|
|
5356
5361
|
}
|
|
5357
5362
|
]
|
|
@@ -44743,10 +44748,17 @@
|
|
|
44743
44748
|
"name": "NavRail",
|
|
44744
44749
|
"importPath": "@wallarm-org/design-system/NavRail",
|
|
44745
44750
|
"props": [
|
|
44751
|
+
{
|
|
44752
|
+
"name": "mode",
|
|
44753
|
+
"type": "NavRailMode | undefined",
|
|
44754
|
+
"required": false,
|
|
44755
|
+
"description": "How the rail lays out its items: `expanded` (icon beside label), `collapsed` (icon only) or\n`compact` (icon over a short label). Wins over `collapsed` when both are set."
|
|
44756
|
+
},
|
|
44746
44757
|
{
|
|
44747
44758
|
"name": "collapsed",
|
|
44748
44759
|
"type": "boolean | undefined",
|
|
44749
44760
|
"required": false,
|
|
44761
|
+
"description": "Shorthand for `mode='collapsed'`, kept so existing hosts keep working. Prefer `mode`.",
|
|
44750
44762
|
"defaultValue": "false"
|
|
44751
44763
|
},
|
|
44752
44764
|
{
|
|
@@ -45022,12 +45034,13 @@
|
|
|
45022
45034
|
],
|
|
45023
45035
|
"variants": [
|
|
45024
45036
|
{
|
|
45025
|
-
"name": "
|
|
45037
|
+
"name": "mode",
|
|
45026
45038
|
"options": [
|
|
45027
|
-
"
|
|
45028
|
-
"
|
|
45039
|
+
"expanded",
|
|
45040
|
+
"collapsed",
|
|
45041
|
+
"compact"
|
|
45029
45042
|
],
|
|
45030
|
-
"defaultValue": "
|
|
45043
|
+
"defaultValue": "expanded"
|
|
45031
45044
|
},
|
|
45032
45045
|
{
|
|
45033
45046
|
"name": "active",
|
|
@@ -45619,6 +45632,19 @@
|
|
|
45619
45632
|
"required": false,
|
|
45620
45633
|
"defaultValue": "false"
|
|
45621
45634
|
},
|
|
45635
|
+
{
|
|
45636
|
+
"name": "avatar",
|
|
45637
|
+
"type": "boolean | undefined",
|
|
45638
|
+
"required": false,
|
|
45639
|
+
"description": "Seats the icon on a soft plate, for the signed-in user's item at the foot of the rail.",
|
|
45640
|
+
"defaultValue": "false"
|
|
45641
|
+
},
|
|
45642
|
+
{
|
|
45643
|
+
"name": "avatarSrc",
|
|
45644
|
+
"type": "string | undefined",
|
|
45645
|
+
"required": false,
|
|
45646
|
+
"description": "User photo for the plate (implies `avatar`). The icon stays underneath and returns if the photo fails to load."
|
|
45647
|
+
},
|
|
45622
45648
|
{
|
|
45623
45649
|
"name": "download",
|
|
45624
45650
|
"type": "any",
|
|
@@ -78930,7 +78956,7 @@
|
|
|
78930
78956
|
},
|
|
78931
78957
|
{
|
|
78932
78958
|
"name": "rounded",
|
|
78933
|
-
"type": "{ none: string; full: string; 2: string; 4: string; 6: string; 8: string; 12: string; 16: string; 24: string; 32: string; }",
|
|
78959
|
+
"type": "{ none: string; full: string; 2: string; 4: string; 6: string; 8: string; 10: string; 12: string; 16: string; 24: string; 32: string; }",
|
|
78934
78960
|
"required": false,
|
|
78935
78961
|
"defaultValue": "6"
|
|
78936
78962
|
},
|
|
@@ -78979,6 +79005,7 @@
|
|
|
78979
79005
|
"4",
|
|
78980
79006
|
"6",
|
|
78981
79007
|
"8",
|
|
79008
|
+
"10",
|
|
78982
79009
|
"12",
|
|
78983
79010
|
"16",
|
|
78984
79011
|
"24",
|
|
@@ -101447,6 +101474,10 @@
|
|
|
101447
101474
|
"name": "--radius-8",
|
|
101448
101475
|
"value": "8px"
|
|
101449
101476
|
},
|
|
101477
|
+
{
|
|
101478
|
+
"name": "--radius-10",
|
|
101479
|
+
"value": "10px"
|
|
101480
|
+
},
|
|
101450
101481
|
{
|
|
101451
101482
|
"name": "--radius-12",
|
|
101452
101483
|
"value": "12px"
|
package/dist/theme/radius.css
CHANGED