@beydesign/storybook 0.2.29 → 0.3.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/index.d.ts +0 -2
- package/dist/index.js +0 -2
- package/dist/stories/Form/Dropdown.js +38 -31
- package/dist/stories/Form/FileUpload/FileUpload.js +26 -16
- package/dist/stories/Form/FileUpload/FileUploading.js +35 -25
- package/dist/stories/Form/FileUpload/UploadedFile.js +15 -4
- package/dist/stories/Form/FileUpload/UploadedFile.stories.js +21 -26
- package/dist/stories/Form/types.d.ts +5 -9
- package/dist/stories/{Drawer → Navigation/Drawer}/Drawer.d.ts +4 -0
- package/dist/stories/Navigation/Drawer/Drawer.js +81 -0
- package/dist/stories/{Drawer → Navigation/Drawer}/Drawer.stories.js +1 -1
- package/dist/stories/Navigation/Drawer/DrawerBody.d.ts +9 -0
- package/dist/stories/Navigation/Drawer/DrawerBody.js +73 -0
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerCreditsCard.js +3 -3
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerCreditsCard.stories.js +1 -1
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerCreditsCardSkeleton.js +1 -1
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerCreditsCardSkeleton.stories.js +1 -1
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerNavItem.d.ts +1 -1
- package/dist/stories/Navigation/Drawer/DrawerNavItem.js +22 -0
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerNavItem.stories.js +1 -1
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerProfile.js +3 -3
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerProfile.stories.js +1 -1
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerProfileSkeleton.js +1 -1
- package/dist/stories/{Drawer → Navigation/Drawer}/DrawerProfileSkeleton.stories.js +1 -1
- package/dist/stories/{Drawer → Navigation/Drawer}/index.d.ts +1 -0
- package/dist/stories/{Drawer → Navigation/Drawer}/index.js +1 -0
- package/dist/stories/{Drawer → Navigation/Drawer}/types.d.ts +44 -34
- package/dist/stories/Navigation/Drawer/types.js +7 -0
- package/dist/stories/Navigation/MobileNav.d.ts +15 -0
- package/dist/stories/Navigation/MobileNav.js +97 -0
- package/dist/stories/Navigation/MobileNav.stories.d.ts +25 -0
- package/dist/stories/Navigation/MobileNav.stories.js +65 -0
- package/dist/stories/Navigation/MobileNavBar.js +3 -13
- package/dist/stories/Navigation/MobileNavBar.stories.js +5 -18
- package/dist/stories/Navigation/SettingsPage.stories.d.ts +19 -0
- package/dist/stories/Navigation/SettingsPage.stories.js +75 -0
- package/dist/stories/Navigation/SubNav/SubNav.d.ts +14 -0
- package/dist/stories/Navigation/SubNav/SubNav.js +16 -0
- package/dist/stories/{Settings/SettingsNav.stories.d.ts → Navigation/SubNav/SubNav.stories.d.ts} +3 -3
- package/dist/stories/{Settings/SettingsNav.stories.js → Navigation/SubNav/SubNav.stories.js} +3 -3
- package/dist/stories/Navigation/SubNav/SubNavBody.d.ts +10 -0
- package/dist/stories/Navigation/SubNav/SubNavBody.js +91 -0
- package/dist/stories/Navigation/SubNav/SubNavItem.d.ts +10 -0
- package/dist/stories/Navigation/SubNav/SubNavItem.js +12 -0
- package/dist/stories/Navigation/SubNav/index.d.ts +4 -0
- package/dist/stories/Navigation/SubNav/index.js +4 -0
- package/dist/stories/Navigation/SubNav/types.d.ts +54 -0
- package/dist/stories/Navigation/index.d.ts +3 -0
- package/dist/stories/Navigation/index.js +3 -0
- package/dist/stories/Navigation/internal/NavPanel.d.ts +21 -0
- package/dist/stories/Navigation/internal/NavPanel.js +45 -0
- package/dist/stories/Navigation/internal/NavRow.d.ts +45 -0
- package/dist/stories/Navigation/internal/NavRow.js +79 -0
- package/dist/stories/Navigation/internal/index.d.ts +11 -0
- package/dist/stories/Navigation/internal/index.js +11 -0
- package/dist/stories/Navigation/internal/types.d.ts +71 -0
- package/dist/stories/Navigation/internal/types.js +30 -0
- package/dist/stories/Navigation/navigation.fixtures.d.ts +22 -0
- package/dist/stories/Navigation/navigation.fixtures.js +64 -0
- package/dist/stories/Navigation/types.d.ts +24 -1
- package/dist/stories/UI/Menu.js +3 -1
- package/dist/stories/UI/types.d.ts +2 -0
- package/package.json +1 -1
- package/dist/stories/Drawer/Drawer.js +0 -163
- package/dist/stories/Drawer/DrawerNavItem.js +0 -87
- package/dist/stories/Drawer/types.js +0 -29
- package/dist/stories/Settings/SettingsNav.d.ts +0 -10
- package/dist/stories/Settings/SettingsNav.js +0 -97
- package/dist/stories/Settings/SettingsNavItem.d.ts +0 -9
- package/dist/stories/Settings/SettingsNavItem.js +0 -75
- package/dist/stories/Settings/SettingsPage.stories.d.ts +0 -11
- package/dist/stories/Settings/SettingsPage.stories.js +0 -93
- package/dist/stories/Settings/index.d.ts +0 -3
- package/dist/stories/Settings/index.js +0 -3
- package/dist/stories/Settings/types.d.ts +0 -68
- /package/dist/stories/{Drawer → Navigation/Drawer}/Drawer.stories.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerCreditsCard.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerCreditsCard.stories.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerCreditsCardSkeleton.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerCreditsCardSkeleton.stories.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerIcons.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerIcons.js +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerNavItem.stories.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerProfile.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerProfile.stories.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerProfileSkeleton.d.ts +0 -0
- /package/dist/stories/{Drawer → Navigation/Drawer}/DrawerProfileSkeleton.stories.d.ts +0 -0
- /package/dist/stories/{Settings → Navigation/SubNav}/types.js +0 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Expanded / collapsed size shared across every navigation panel and its
|
|
3
|
+
* sub-components.
|
|
4
|
+
*/
|
|
5
|
+
export var NavPanelSize;
|
|
6
|
+
(function (NavPanelSize) {
|
|
7
|
+
NavPanelSize["Expanded"] = "Expanded";
|
|
8
|
+
NavPanelSize["Collapsed"] = "Collapsed";
|
|
9
|
+
})(NavPanelSize || (NavPanelSize = {}));
|
|
10
|
+
/**
|
|
11
|
+
* Visual state of a single navigation item.
|
|
12
|
+
* `Hover` is mostly useful for documentation/Storybook — at runtime an
|
|
13
|
+
* `Inactive` item also picks up the hover styling on real pointer hover.
|
|
14
|
+
*/
|
|
15
|
+
export var NavItemState;
|
|
16
|
+
(function (NavItemState) {
|
|
17
|
+
NavItemState["Active"] = "Active";
|
|
18
|
+
NavItemState["Inactive"] = "Inactive";
|
|
19
|
+
NavItemState["Hover"] = "Hover";
|
|
20
|
+
NavItemState["Disabled"] = "Disabled";
|
|
21
|
+
})(NavItemState || (NavItemState = {}));
|
|
22
|
+
/**
|
|
23
|
+
* Hierarchy of a navigation item. `First` is a top-level entry (36px row),
|
|
24
|
+
* `Secondary` is a nested sub-item (28px row, lighter weight).
|
|
25
|
+
*/
|
|
26
|
+
export var NavItemHierarchy;
|
|
27
|
+
(function (NavItemHierarchy) {
|
|
28
|
+
NavItemHierarchy["First"] = "First";
|
|
29
|
+
NavItemHierarchy["Secondary"] = "Secondary";
|
|
30
|
+
})(NavItemHierarchy || (NavItemHierarchy = {}));
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { DrawerNavItemConfig } from './Drawer';
|
|
2
|
+
import type { SubNavSection } from './SubNav';
|
|
3
|
+
/**
|
|
4
|
+
* Sample navigation config shared by the navigation stories.
|
|
5
|
+
*
|
|
6
|
+
* The point of this file is the point of the whole design: ONE config drives
|
|
7
|
+
* both layouts. On desktop `settingsSections` renders as a `SubNav` panel
|
|
8
|
+
* beside the `Drawer`; on mobile the very same array rides along on the
|
|
9
|
+
* Settings item's `subNav` and becomes the second pane of `MobileNav`.
|
|
10
|
+
*/
|
|
11
|
+
export declare const settingsSections: SubNavSection[];
|
|
12
|
+
export declare const drawerNavItems: DrawerNavItemConfig[];
|
|
13
|
+
export declare const credits: {
|
|
14
|
+
usedCredits: number;
|
|
15
|
+
maxCredits: number;
|
|
16
|
+
};
|
|
17
|
+
export declare const profile: {
|
|
18
|
+
name: string;
|
|
19
|
+
email: string;
|
|
20
|
+
};
|
|
21
|
+
/** Display names for the settings keys, for the example page's content area. */
|
|
22
|
+
export declare const settingsLabels: Record<string, string>;
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Sample navigation config shared by the navigation stories.
|
|
3
|
+
*
|
|
4
|
+
* The point of this file is the point of the whole design: ONE config drives
|
|
5
|
+
* both layouts. On desktop `settingsSections` renders as a `SubNav` panel
|
|
6
|
+
* beside the `Drawer`; on mobile the very same array rides along on the
|
|
7
|
+
* Settings item's `subNav` and becomes the second pane of `MobileNav`.
|
|
8
|
+
*/
|
|
9
|
+
export const settingsSections = [
|
|
10
|
+
{
|
|
11
|
+
key: 'business',
|
|
12
|
+
title: 'Your business',
|
|
13
|
+
items: [{ key: 'branding', text: 'Branding', icon: 'StarFour' }],
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
key: 'team',
|
|
17
|
+
title: 'Team',
|
|
18
|
+
items: [{ key: 'members', text: 'Members', icon: 'UsersThree' }],
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
key: 'billing',
|
|
22
|
+
title: 'Billing & plans',
|
|
23
|
+
items: [
|
|
24
|
+
{ key: 'subscription', text: 'Subscription', icon: 'CreditCard' },
|
|
25
|
+
{ key: 'invoices', text: 'Invoices', icon: 'FileText' },
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
key: 'developers',
|
|
30
|
+
title: 'Developers',
|
|
31
|
+
items: [
|
|
32
|
+
{ key: 'api-keys', text: 'API keys', icon: 'Key' },
|
|
33
|
+
{ key: 'webhooks', text: 'Webhooks', icon: 'Graph' },
|
|
34
|
+
],
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
export const drawerNavItems = [
|
|
38
|
+
{ key: 'home', text: 'Home', icon: 'House' },
|
|
39
|
+
{ key: 'avatars', text: 'Avatars', icon: 'UserFocus' },
|
|
40
|
+
{ key: 'agents', text: 'My Agents', icon: 'Headset' },
|
|
41
|
+
{ key: 'ttv', text: 'Text-to-Video', icon: 'VideoCamera' },
|
|
42
|
+
{ key: 'kb', text: 'Knowledge Base', icon: 'Book' },
|
|
43
|
+
{ key: 'conversations', text: 'Conversations', icon: 'ChatTeardropDots' },
|
|
44
|
+
{ key: 'analytics', text: 'Analytics', icon: 'ChartBar' },
|
|
45
|
+
{ key: 'api', text: 'API keys', icon: 'Key' },
|
|
46
|
+
{ key: 'developers', text: 'Developers', icon: 'BracketsCurly' },
|
|
47
|
+
{
|
|
48
|
+
key: 'settings',
|
|
49
|
+
text: 'Settings',
|
|
50
|
+
icon: 'GearSix',
|
|
51
|
+
subNav: { title: 'Settings', sections: settingsSections },
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
export const credits = { usedCredits: 500, maxCredits: 2000 };
|
|
55
|
+
export const profile = { name: 'Emma Novak', email: 'emma@example.com' };
|
|
56
|
+
/** Display names for the settings keys, for the example page's content area. */
|
|
57
|
+
export const settingsLabels = {
|
|
58
|
+
branding: 'Branding',
|
|
59
|
+
members: 'Members',
|
|
60
|
+
subscription: 'Subscription',
|
|
61
|
+
invoices: 'Invoices',
|
|
62
|
+
'api-keys': 'API keys',
|
|
63
|
+
webhooks: 'Webhooks',
|
|
64
|
+
};
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { CSSProperties } from 'react';
|
|
1
2
|
import { SxProps, Theme } from '@mui/material';
|
|
2
3
|
import { IconName } from '../../utils';
|
|
3
4
|
import { AvatarProps } from '../UI';
|
|
4
5
|
import { CreditsCardProps } from '../Credits';
|
|
5
|
-
import { DrawerProps } from '
|
|
6
|
+
import { DrawerBodyProps, DrawerProps } from './Drawer';
|
|
6
7
|
/**
|
|
7
8
|
* Header component props
|
|
8
9
|
*/
|
|
@@ -185,6 +186,28 @@ export interface ProcessHeaderProps {
|
|
|
185
186
|
/** The class name to apply to the component */
|
|
186
187
|
className?: string;
|
|
187
188
|
}
|
|
189
|
+
/**
|
|
190
|
+
* Props for the {@link MobileNav} overlay — the single navigation panel used
|
|
191
|
+
* below the mobile breakpoint, which holds the `Drawer` and any `subNav` as
|
|
192
|
+
* pushable panes.
|
|
193
|
+
*/
|
|
194
|
+
export interface MobileNavProps extends Omit<DrawerBodyProps, 'size' | 'onSubNavOpen'> {
|
|
195
|
+
/** Whether the overlay is open. */
|
|
196
|
+
open: boolean;
|
|
197
|
+
/**
|
|
198
|
+
* Fired with the next open value — when the scrim is clicked, Esc is pressed,
|
|
199
|
+
* or the user navigates from a nav item.
|
|
200
|
+
*/
|
|
201
|
+
onOpenChange: (open: boolean) => void;
|
|
202
|
+
/** Panel width. Defaults to `315px`, matching the mobile design. */
|
|
203
|
+
width?: string;
|
|
204
|
+
/** The class name to apply to the component */
|
|
205
|
+
className?: string;
|
|
206
|
+
/** The style object to apply to the sliding panel */
|
|
207
|
+
style?: CSSProperties;
|
|
208
|
+
/** Renders as `data-testid` for testing. */
|
|
209
|
+
testId?: string;
|
|
210
|
+
}
|
|
188
211
|
/**
|
|
189
212
|
* Mobile navigation bar props
|
|
190
213
|
*/
|
package/dist/stories/UI/Menu.js
CHANGED
|
@@ -4,14 +4,16 @@ import { Fragment, useState } from 'react';
|
|
|
4
4
|
import { MainButton, ButtonDisplayMode, ButtonHierarchy, ButtonType, ButtonSize, } from '../Buttons';
|
|
5
5
|
import { Typography, TypographySize, TypographyWeight } from '../Typography';
|
|
6
6
|
import { getIconComponent } from '../../utils';
|
|
7
|
-
export const Menu = ({ icon = 'DotsThreeOutline', iconWeight = 'bold', items, style, testKey, size = ButtonSize.xl, hierarchy = ButtonHierarchy.Tertiary, }) => {
|
|
7
|
+
export const Menu = ({ icon = 'DotsThreeOutline', iconWeight = 'bold', items, style, testKey, size = ButtonSize.xl, hierarchy = ButtonHierarchy.Tertiary, onOpenChange, }) => {
|
|
8
8
|
const [anchorEl, setAnchorEl] = useState(null);
|
|
9
9
|
const open = Boolean(anchorEl);
|
|
10
10
|
const handleClick = (event) => {
|
|
11
11
|
setAnchorEl(event.currentTarget);
|
|
12
|
+
onOpenChange?.(true);
|
|
12
13
|
};
|
|
13
14
|
const handleClose = () => {
|
|
14
15
|
setAnchorEl(null);
|
|
16
|
+
onOpenChange?.(false);
|
|
15
17
|
};
|
|
16
18
|
const handleMenuItemClick = (item, event) => {
|
|
17
19
|
handleClose();
|
|
@@ -217,6 +217,8 @@ export type MenuProps = {
|
|
|
217
217
|
size?: ButtonSize;
|
|
218
218
|
/** Hierarchy of the trigger button */
|
|
219
219
|
hierarchy?: ButtonHierarchy;
|
|
220
|
+
/** Called when the menu opens (true) or closes (false) */
|
|
221
|
+
onOpenChange?: (open: boolean) => void;
|
|
220
222
|
};
|
|
221
223
|
/**
|
|
222
224
|
* Check icon color variants
|
package/package.json
CHANGED
|
@@ -1,163 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { useState } from 'react';
|
|
3
|
-
import styled from '@emotion/styled';
|
|
4
|
-
import { DrawerSize, DrawerNavItemState, DrawerNavItemHierarchy, } from './types';
|
|
5
|
-
import { DrawerNavItem } from './DrawerNavItem';
|
|
6
|
-
import { DrawerCreditsCard } from './DrawerCreditsCard';
|
|
7
|
-
import { DrawerCreditsCardSkeleton } from './DrawerCreditsCardSkeleton';
|
|
8
|
-
import { DrawerProfile } from './DrawerProfile';
|
|
9
|
-
import { DrawerProfileSkeleton } from './DrawerProfileSkeleton';
|
|
10
|
-
import { Logo, LogoVariant } from '../UI';
|
|
11
|
-
import { getIconComponent } from '../../utils';
|
|
12
|
-
const EXPANDED_WIDTH = '238px';
|
|
13
|
-
const COLLAPSED_WIDTH = '68px';
|
|
14
|
-
/** Composed from the semantic `shadow-sm` design token. */
|
|
15
|
-
const SHADOW_SM = 'var(--global-shadows-shadow-sm-offset-x) var(--global-shadows-shadow-sm-offset-y) var(--global-shadows-shadow-sm-blur) var(--global-shadows-shadow-sm-spread) var(--global-shadows-shadow-sm-color)';
|
|
16
|
-
/**
|
|
17
|
-
* Non-clipping outer shell. The toggle lives here (a sibling of the scroll
|
|
18
|
-
* area) so it can overhang the right edge without being clipped by the panel's
|
|
19
|
-
* `overflow`.
|
|
20
|
-
*/
|
|
21
|
-
const Shell = styled.aside `
|
|
22
|
-
position: relative;
|
|
23
|
-
flex-shrink: 0;
|
|
24
|
-
height: 100vh;
|
|
25
|
-
width: ${({ $collapsed }) => ($collapsed ? COLLAPSED_WIDTH : EXPANDED_WIDTH)};
|
|
26
|
-
transition: width 0.3s ease-in-out;
|
|
27
|
-
`;
|
|
28
|
-
const Scroll = styled.div `
|
|
29
|
-
box-sizing: border-box;
|
|
30
|
-
display: flex;
|
|
31
|
-
flex-direction: column;
|
|
32
|
-
height: 100%;
|
|
33
|
-
width: 100%;
|
|
34
|
-
padding: var(--spacing-tokens-size-in-px-spacing-spacing-xl, 16px)
|
|
35
|
-
var(--spacing-tokens-size-in-px-spacing-spacing-xl, 16px)
|
|
36
|
-
var(--spacing-tokens-size-in-px-spacing-spacing-2xl, 24px);
|
|
37
|
-
background-color: var(--color-background-bg-page-contrast);
|
|
38
|
-
border-right: 1px solid var(--color-border-border-subtle);
|
|
39
|
-
overflow-x: hidden;
|
|
40
|
-
overflow-y: auto;
|
|
41
|
-
|
|
42
|
-
/* Theme-aware thin scrollbar */
|
|
43
|
-
scrollbar-width: thin;
|
|
44
|
-
scrollbar-color: var(--color-border-border-component) transparent;
|
|
45
|
-
|
|
46
|
-
&::-webkit-scrollbar {
|
|
47
|
-
width: 6px;
|
|
48
|
-
}
|
|
49
|
-
&::-webkit-scrollbar-track {
|
|
50
|
-
background: transparent;
|
|
51
|
-
}
|
|
52
|
-
&::-webkit-scrollbar-thumb {
|
|
53
|
-
background-color: var(--color-border-border-component);
|
|
54
|
-
border-radius: var(--spacing-tokens-size-in-px-radius-radius-full);
|
|
55
|
-
}
|
|
56
|
-
&::-webkit-scrollbar-thumb:hover {
|
|
57
|
-
background-color: var(--color-text-text-subtle);
|
|
58
|
-
}
|
|
59
|
-
`;
|
|
60
|
-
const LogoHeader = styled.div `
|
|
61
|
-
display: flex;
|
|
62
|
-
align-items: center;
|
|
63
|
-
justify-content: ${({ $collapsed }) => $collapsed ? 'center' : 'flex-start'};
|
|
64
|
-
height: 38px;
|
|
65
|
-
min-height: 38px;
|
|
66
|
-
margin-bottom: 40px;
|
|
67
|
-
`;
|
|
68
|
-
const Nav = styled.nav `
|
|
69
|
-
display: flex;
|
|
70
|
-
flex-direction: column;
|
|
71
|
-
flex: 1;
|
|
72
|
-
justify-content: space-between;
|
|
73
|
-
gap: var(--spacing-tokens-size-in-px-spacing-spacing-2xl, 24px);
|
|
74
|
-
`;
|
|
75
|
-
const NavTop = styled.div `
|
|
76
|
-
display: flex;
|
|
77
|
-
flex-direction: column;
|
|
78
|
-
gap: var(--spacing-tokens-size-in-px-spacing-spacing-lg, 12px);
|
|
79
|
-
`;
|
|
80
|
-
const Footer = styled.div `
|
|
81
|
-
display: flex;
|
|
82
|
-
flex-direction: column;
|
|
83
|
-
gap: var(--spacing-tokens-size-in-px-spacing-spacing-2xl, 24px);
|
|
84
|
-
`;
|
|
85
|
-
const FooterSlot = styled.div `
|
|
86
|
-
display: flex;
|
|
87
|
-
justify-content: center;
|
|
88
|
-
`;
|
|
89
|
-
const ToggleButton = styled.button `
|
|
90
|
-
appearance: none;
|
|
91
|
-
position: absolute;
|
|
92
|
-
top: 52px;
|
|
93
|
-
right: -16px;
|
|
94
|
-
z-index: 2;
|
|
95
|
-
display: inline-flex;
|
|
96
|
-
align-items: center;
|
|
97
|
-
justify-content: center;
|
|
98
|
-
width: 32px;
|
|
99
|
-
height: 32px;
|
|
100
|
-
padding: 0;
|
|
101
|
-
border: 1px solid var(--color-border-border-subtle);
|
|
102
|
-
border-radius: var(--spacing-tokens-size-in-px-radius-radius-full);
|
|
103
|
-
background-color: var(--color-background-bg-element);
|
|
104
|
-
color: var(--color-text-text-paragraph);
|
|
105
|
-
cursor: pointer;
|
|
106
|
-
box-shadow: ${SHADOW_SM};
|
|
107
|
-
transition: color 0.2s ease-in-out;
|
|
108
|
-
|
|
109
|
-
&:hover {
|
|
110
|
-
color: var(--color-text-text-clicable);
|
|
111
|
-
}
|
|
112
|
-
`;
|
|
113
|
-
/** Rotates the chevron smoothly between expanded (◀) and collapsed (▶). */
|
|
114
|
-
const ToggleIcon = styled.span `
|
|
115
|
-
display: inline-flex;
|
|
116
|
-
transform: rotate(${({ $collapsed }) => ($collapsed ? '180deg' : '0deg')});
|
|
117
|
-
transition: transform 0.3s ease-in-out;
|
|
118
|
-
|
|
119
|
-
@media (prefers-reduced-motion: reduce) {
|
|
120
|
-
transition: none;
|
|
121
|
-
}
|
|
122
|
-
`;
|
|
123
|
-
const resolveState = (item, activeKey) => {
|
|
124
|
-
if (item.state)
|
|
125
|
-
return item.state;
|
|
126
|
-
if (item.disabled)
|
|
127
|
-
return DrawerNavItemState.Disabled;
|
|
128
|
-
const key = item.key ?? item.text;
|
|
129
|
-
if (activeKey !== undefined && key === activeKey) {
|
|
130
|
-
return DrawerNavItemState.Active;
|
|
131
|
-
}
|
|
132
|
-
return DrawerNavItemState.Inactive;
|
|
133
|
-
};
|
|
134
|
-
/**
|
|
135
|
-
* Composed application sidebar ("Drawer"): logo header, navigation list,
|
|
136
|
-
* credits card and user-profile footer, with a floating collapse/expand
|
|
137
|
-
* toggle. Collapse state can be controlled (`collapsed` + `onToggle`) or left
|
|
138
|
-
* uncontrolled (`defaultCollapsed`). Every colour, space and radius resolves to
|
|
139
|
-
* `@beydesign/tokens` CSS variables, so it renders correctly in light and dark.
|
|
140
|
-
*/
|
|
141
|
-
export const Drawer = ({ navItems, activeKey, collapsed, defaultCollapsed = false, onToggle, showToggle = true, credits, creditsLoading = false, profile, profileLoading = false, logo, className, style, testId, }) => {
|
|
142
|
-
const isControlled = collapsed !== undefined;
|
|
143
|
-
const [internalCollapsed, setInternalCollapsed] = useState(defaultCollapsed);
|
|
144
|
-
const isCollapsed = isControlled ? collapsed : internalCollapsed;
|
|
145
|
-
const drawerSize = isCollapsed ? DrawerSize.Collapsed : DrawerSize.Expanded;
|
|
146
|
-
const handleToggle = () => {
|
|
147
|
-
const next = !isCollapsed;
|
|
148
|
-
if (!isControlled)
|
|
149
|
-
setInternalCollapsed(next);
|
|
150
|
-
onToggle?.(next);
|
|
151
|
-
};
|
|
152
|
-
const handleItemClick = (item) => {
|
|
153
|
-
if (item.disabled)
|
|
154
|
-
return;
|
|
155
|
-
if (item.link) {
|
|
156
|
-
window.location.href = item.link;
|
|
157
|
-
}
|
|
158
|
-
else {
|
|
159
|
-
item.onClick?.();
|
|
160
|
-
}
|
|
161
|
-
};
|
|
162
|
-
return (_jsxs(Shell, { "$collapsed": isCollapsed, className: className, style: style, "data-testid": testId, children: [_jsxs(Scroll, { children: [_jsx(LogoHeader, { "$collapsed": isCollapsed, children: _jsx(Logo, { variant: isCollapsed ? LogoVariant.Icon : LogoVariant.Horizontal, color: logo?.color ?? 'var(--color-foreground-fg-brand-logo)', gradient: logo?.gradient, svgUrl: logo?.svgUrl }) }), _jsxs(Nav, { children: [_jsx(NavTop, { children: navItems.map((item) => (_jsx(DrawerNavItem, { text: item.text, icon: item.icon, state: resolveState(item, activeKey), size: drawerSize, hierarchy: item.hierarchy ?? DrawerNavItemHierarchy.First, showBadge: item.showBadge, badgeText: item.badgeText, onClick: () => handleItemClick(item) }, item.key ?? item.text))) }), (credits || creditsLoading || profile || profileLoading) && (_jsxs(Footer, { children: [(credits || creditsLoading) && (_jsx(FooterSlot, { "$collapsed": isCollapsed, children: creditsLoading ? (_jsx(DrawerCreditsCardSkeleton, { size: drawerSize })) : (_jsx(DrawerCreditsCard, { ...credits, size: drawerSize })) })), (profile || profileLoading) && (_jsx(FooterSlot, { "$collapsed": isCollapsed, children: profileLoading ? (_jsx(DrawerProfileSkeleton, { size: drawerSize })) : (profile && _jsx(DrawerProfile, { ...profile, size: drawerSize })) }))] }))] })] }), showToggle && (_jsx(ToggleButton, { type: "button", onClick: handleToggle, "aria-label": isCollapsed ? 'Expand sidebar' : 'Collapse sidebar', children: _jsx(ToggleIcon, { "$collapsed": isCollapsed, children: getIconComponent('CaretLeft', { size: 16, weight: 'bold' }) }) }))] }));
|
|
163
|
-
};
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import styled from '@emotion/styled';
|
|
3
|
-
import { DrawerNavItemState, DrawerNavItemHierarchy, DrawerSize, } from './types';
|
|
4
|
-
import { Typography, TypographySize, TypographyWeight } from '../Typography';
|
|
5
|
-
import { Badge, BadgeColor, BadgeSize } from '../UI';
|
|
6
|
-
import { getIconComponent } from '../../utils';
|
|
7
|
-
const ACTIVE_FG = 'var(--color-text-text-clicable)';
|
|
8
|
-
const INACTIVE_FG = 'var(--color-text-text-subtle)';
|
|
9
|
-
const ACTIVE_BG = 'var(--color-background-bg-brand-transparent)';
|
|
10
|
-
const HOVER_BG = 'var(--color-background-bg-brand-transparent-hover)';
|
|
11
|
-
const foreground = (state) => state === DrawerNavItemState.Active || state === DrawerNavItemState.Hover
|
|
12
|
-
? ACTIVE_FG
|
|
13
|
-
: INACTIVE_FG;
|
|
14
|
-
const background = (state) => {
|
|
15
|
-
if (state === DrawerNavItemState.Active)
|
|
16
|
-
return ACTIVE_BG;
|
|
17
|
-
if (state === DrawerNavItemState.Hover)
|
|
18
|
-
return HOVER_BG;
|
|
19
|
-
return 'transparent';
|
|
20
|
-
};
|
|
21
|
-
const StyledNavItem = styled.button `
|
|
22
|
-
appearance: none;
|
|
23
|
-
font: inherit;
|
|
24
|
-
text-align: left;
|
|
25
|
-
border: none;
|
|
26
|
-
box-sizing: border-box;
|
|
27
|
-
display: flex;
|
|
28
|
-
align-items: center;
|
|
29
|
-
justify-content: ${({ $collapsed }) => $collapsed ? 'center' : 'flex-start'};
|
|
30
|
-
gap: var(--spacing-tokens-size-in-px-spacing-spacing-md, 8px);
|
|
31
|
-
width: ${({ $collapsed }) => ($collapsed ? '36px' : '100%')};
|
|
32
|
-
height: ${({ $collapsed }) => ($collapsed ? '36px' : 'auto')};
|
|
33
|
-
align-self: ${({ $collapsed }) => ($collapsed ? 'center' : 'stretch')};
|
|
34
|
-
padding: ${({ $collapsed, $hierarchy }) => {
|
|
35
|
-
if ($collapsed)
|
|
36
|
-
return '0';
|
|
37
|
-
return $hierarchy === DrawerNavItemHierarchy.Secondary
|
|
38
|
-
? 'var(--spacing-tokens-size-in-px-spacing-spacing-xs, 4px) var(--spacing-tokens-size-in-px-spacing-spacing-md, 8px)'
|
|
39
|
-
: 'var(--spacing-tokens-size-in-px-spacing-spacing-md, 8px)';
|
|
40
|
-
}};
|
|
41
|
-
border-radius: var(--spacing-tokens-size-in-px-spacing-spacing-md, 8px);
|
|
42
|
-
color: ${({ $state }) => foreground($state)};
|
|
43
|
-
background-color: ${({ $state }) => background($state)};
|
|
44
|
-
opacity: ${({ $state }) => $state === DrawerNavItemState.Disabled ? 0.5 : 1};
|
|
45
|
-
cursor: ${({ $state }) => $state === DrawerNavItemState.Disabled ? 'not-allowed' : 'pointer'};
|
|
46
|
-
transition:
|
|
47
|
-
background-color 0.2s ease-in-out,
|
|
48
|
-
color 0.2s ease-in-out,
|
|
49
|
-
padding 0.3s ease-in-out;
|
|
50
|
-
|
|
51
|
-
&:hover {
|
|
52
|
-
${({ $state }) => $state === DrawerNavItemState.Inactive
|
|
53
|
-
? `background-color: ${HOVER_BG}; color: ${ACTIVE_FG};`
|
|
54
|
-
: ''}
|
|
55
|
-
}
|
|
56
|
-
`;
|
|
57
|
-
const IconSlot = styled.span `
|
|
58
|
-
display: inline-flex;
|
|
59
|
-
flex-shrink: 0;
|
|
60
|
-
color: inherit;
|
|
61
|
-
`;
|
|
62
|
-
const Label = styled.span `
|
|
63
|
-
display: inline-flex;
|
|
64
|
-
flex: 1 1 0;
|
|
65
|
-
min-width: 0;
|
|
66
|
-
white-space: nowrap;
|
|
67
|
-
overflow: hidden;
|
|
68
|
-
text-overflow: ellipsis;
|
|
69
|
-
color: inherit;
|
|
70
|
-
`;
|
|
71
|
-
/**
|
|
72
|
-
* A single navigation row for the {@link Drawer}. Supports active / inactive /
|
|
73
|
-
* hover / disabled states, first / secondary hierarchy and expanded / collapsed
|
|
74
|
-
* sizes. All colours resolve to theme tokens, so it adapts to light and dark.
|
|
75
|
-
*/
|
|
76
|
-
export const DrawerNavItem = ({ text, icon, state = DrawerNavItemState.Inactive, size = DrawerSize.Expanded, hierarchy = DrawerNavItemHierarchy.First, showBadge = false, badgeText = 'Coming Soon', onClick, className, style, testId, }) => {
|
|
77
|
-
const isCollapsed = size === DrawerSize.Collapsed;
|
|
78
|
-
const isDisabled = state === DrawerNavItemState.Disabled;
|
|
79
|
-
const isSecondary = hierarchy === DrawerNavItemHierarchy.Secondary;
|
|
80
|
-
const handleClick = () => {
|
|
81
|
-
if (!isDisabled)
|
|
82
|
-
onClick?.();
|
|
83
|
-
};
|
|
84
|
-
return (_jsxs(StyledNavItem, { type: "button", "$state": state, "$collapsed": isCollapsed, "$hierarchy": hierarchy, className: className, style: style, onClick: handleClick, disabled: isDisabled, title: isCollapsed ? text : undefined, "data-testid": testId, children: [_jsx(IconSlot, { children: getIconComponent(icon, { size: 20 }) }), !isCollapsed && (_jsxs(_Fragment, { children: [_jsx(Label, { children: _jsx(Typography, { size: isSecondary ? TypographySize.TextXS : TypographySize.TextS, weight: isSecondary
|
|
85
|
-
? TypographyWeight.Medium
|
|
86
|
-
: TypographyWeight.SemiBold, color: "inherit", children: text }) }), showBadge && (_jsx(Badge, { size: BadgeSize.xs, icon: "ClockCountdown", showIcon: true, text: badgeText, color: BadgeColor.Default }))] }))] }));
|
|
87
|
-
};
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Expanded / collapsed size shared across the Drawer and its sub-components.
|
|
3
|
-
*/
|
|
4
|
-
export var DrawerSize;
|
|
5
|
-
(function (DrawerSize) {
|
|
6
|
-
DrawerSize["Expanded"] = "Expanded";
|
|
7
|
-
DrawerSize["Collapsed"] = "Collapsed";
|
|
8
|
-
})(DrawerSize || (DrawerSize = {}));
|
|
9
|
-
/**
|
|
10
|
-
* Visual state of a single navigation item.
|
|
11
|
-
* `Hover` is mostly useful for documentation/Storybook — at runtime an
|
|
12
|
-
* `Inactive` item also picks up the hover styling on real pointer hover.
|
|
13
|
-
*/
|
|
14
|
-
export var DrawerNavItemState;
|
|
15
|
-
(function (DrawerNavItemState) {
|
|
16
|
-
DrawerNavItemState["Active"] = "Active";
|
|
17
|
-
DrawerNavItemState["Inactive"] = "Inactive";
|
|
18
|
-
DrawerNavItemState["Hover"] = "Hover";
|
|
19
|
-
DrawerNavItemState["Disabled"] = "Disabled";
|
|
20
|
-
})(DrawerNavItemState || (DrawerNavItemState = {}));
|
|
21
|
-
/**
|
|
22
|
-
* Hierarchy of a navigation item. `First` is a top-level entry (36px row),
|
|
23
|
-
* `Secondary` is a nested sub-item (28px row, lighter weight).
|
|
24
|
-
*/
|
|
25
|
-
export var DrawerNavItemHierarchy;
|
|
26
|
-
(function (DrawerNavItemHierarchy) {
|
|
27
|
-
DrawerNavItemHierarchy["First"] = "First";
|
|
28
|
-
DrawerNavItemHierarchy["Secondary"] = "Secondary";
|
|
29
|
-
})(DrawerNavItemHierarchy || (DrawerNavItemHierarchy = {}));
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { SettingsNavProps } from './types';
|
|
3
|
-
/**
|
|
4
|
-
* Secondary navigation for the Settings area: a "Settings" heading followed by
|
|
5
|
-
* titled sections of {@link SettingsNavItem} rows. Sits beside the primary
|
|
6
|
-
* {@link Drawer} and only appears on settings pages. Every colour, space and
|
|
7
|
-
* radius resolves to `@beydesign/tokens` CSS variables, so it renders correctly
|
|
8
|
-
* in light and dark.
|
|
9
|
-
*/
|
|
10
|
-
export declare const SettingsNav: React.FC<SettingsNavProps>;
|
|
@@ -1,97 +0,0 @@
|
|
|
1
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import styled from '@emotion/styled';
|
|
3
|
-
import { SettingsNavItem } from './SettingsNavItem';
|
|
4
|
-
import { DrawerNavItemState } from '../Drawer/types';
|
|
5
|
-
import { Typography, TypographySize, TypographyWeight } from '../Typography';
|
|
6
|
-
const WIDTH = '238px';
|
|
7
|
-
const Shell = styled.aside `
|
|
8
|
-
box-sizing: border-box;
|
|
9
|
-
display: flex;
|
|
10
|
-
flex-direction: column;
|
|
11
|
-
flex-shrink: 0;
|
|
12
|
-
width: ${WIDTH};
|
|
13
|
-
height: 100vh;
|
|
14
|
-
padding: var(--spacing-tokens-size-in-px-spacing-spacing-xl, 16px)
|
|
15
|
-
var(--spacing-tokens-size-in-px-spacing-spacing-xl, 16px)
|
|
16
|
-
var(--spacing-tokens-size-in-px-spacing-spacing-2xl, 24px);
|
|
17
|
-
background-color: var(--color-background-bg-page-contrast);
|
|
18
|
-
border-right: 1px solid var(--color-border-border-component);
|
|
19
|
-
overflow-x: hidden;
|
|
20
|
-
overflow-y: auto;
|
|
21
|
-
|
|
22
|
-
scrollbar-width: thin;
|
|
23
|
-
scrollbar-color: var(--color-border-border-component) transparent;
|
|
24
|
-
|
|
25
|
-
&::-webkit-scrollbar {
|
|
26
|
-
width: 6px;
|
|
27
|
-
}
|
|
28
|
-
&::-webkit-scrollbar-track {
|
|
29
|
-
background: transparent;
|
|
30
|
-
}
|
|
31
|
-
&::-webkit-scrollbar-thumb {
|
|
32
|
-
background-color: var(--color-border-border-component);
|
|
33
|
-
border-radius: var(--spacing-tokens-size-in-px-radius-radius-full);
|
|
34
|
-
}
|
|
35
|
-
&::-webkit-scrollbar-thumb:hover {
|
|
36
|
-
background-color: var(--color-text-text-subtle);
|
|
37
|
-
}
|
|
38
|
-
`;
|
|
39
|
-
const Content = styled.div `
|
|
40
|
-
display: flex;
|
|
41
|
-
flex-direction: column;
|
|
42
|
-
gap: var(--spacing-tokens-size-in-px-spacing-spacing-2xl, 20px);
|
|
43
|
-
height: 100%;
|
|
44
|
-
`;
|
|
45
|
-
const Header = styled.div `
|
|
46
|
-
padding: 0 var(--spacing-tokens-size-in-px-spacing-spacing-md, 8px);
|
|
47
|
-
`;
|
|
48
|
-
const Sections = styled.nav `
|
|
49
|
-
display: flex;
|
|
50
|
-
flex-direction: column;
|
|
51
|
-
gap: var(--spacing-tokens-size-in-px-spacing-spacing-2xl, 20px);
|
|
52
|
-
`;
|
|
53
|
-
const Section = styled.div `
|
|
54
|
-
display: flex;
|
|
55
|
-
flex-direction: column;
|
|
56
|
-
gap: var(--spacing-tokens-size-in-px-spacing-spacing-md, 8px);
|
|
57
|
-
`;
|
|
58
|
-
const SectionTitle = styled.div `
|
|
59
|
-
padding: 0 var(--spacing-tokens-size-in-px-spacing-spacing-md, 8px);
|
|
60
|
-
text-transform: uppercase;
|
|
61
|
-
`;
|
|
62
|
-
const Items = styled.div `
|
|
63
|
-
display: flex;
|
|
64
|
-
flex-direction: column;
|
|
65
|
-
gap: var(--spacing-tokens-size-in-px-spacing-spacing-xs, 4px);
|
|
66
|
-
`;
|
|
67
|
-
const resolveState = (item, activeKey) => {
|
|
68
|
-
if (item.state)
|
|
69
|
-
return item.state;
|
|
70
|
-
if (item.disabled)
|
|
71
|
-
return DrawerNavItemState.Disabled;
|
|
72
|
-
const key = item.key ?? item.text;
|
|
73
|
-
if (activeKey !== undefined && key === activeKey) {
|
|
74
|
-
return DrawerNavItemState.Active;
|
|
75
|
-
}
|
|
76
|
-
return DrawerNavItemState.Inactive;
|
|
77
|
-
};
|
|
78
|
-
/**
|
|
79
|
-
* Secondary navigation for the Settings area: a "Settings" heading followed by
|
|
80
|
-
* titled sections of {@link SettingsNavItem} rows. Sits beside the primary
|
|
81
|
-
* {@link Drawer} and only appears on settings pages. Every colour, space and
|
|
82
|
-
* radius resolves to `@beydesign/tokens` CSS variables, so it renders correctly
|
|
83
|
-
* in light and dark.
|
|
84
|
-
*/
|
|
85
|
-
export const SettingsNav = ({ title = 'Settings', sections, activeKey, className, style, testId, }) => {
|
|
86
|
-
const handleItemClick = (item) => {
|
|
87
|
-
if (item.disabled)
|
|
88
|
-
return;
|
|
89
|
-
if (item.link) {
|
|
90
|
-
window.location.href = item.link;
|
|
91
|
-
}
|
|
92
|
-
else {
|
|
93
|
-
item.onClick?.();
|
|
94
|
-
}
|
|
95
|
-
};
|
|
96
|
-
return (_jsx(Shell, { className: className, style: style, "data-testid": testId, children: _jsxs(Content, { children: [_jsx(Header, { children: _jsx(Typography, { size: TypographySize.HeadingS, weight: TypographyWeight.Bold, color: "var(--color-text-text-title)", children: title }) }), _jsx(Sections, { children: sections.map((section, sectionIndex) => (_jsxs(Section, { children: [section.title && (_jsx(SectionTitle, { children: _jsx(Typography, { size: TypographySize.TextXS, weight: TypographyWeight.SemiBold, color: "var(--color-text-text-subtle)", children: section.title }) })), _jsx(Items, { children: section.items.map((item) => (_jsx(SettingsNavItem, { text: item.text, icon: item.icon, state: resolveState(item, activeKey), showBadge: item.showBadge, badgeText: item.badgeText, onClick: () => handleItemClick(item) }, item.key ?? item.text))) })] }, section.key ?? section.title ?? sectionIndex))) })] }) }));
|
|
97
|
-
};
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import React from 'react';
|
|
2
|
-
import type { SettingsNavItemProps } from './types';
|
|
3
|
-
/**
|
|
4
|
-
* A single navigation row for the {@link SettingsNav}. Deliberately more compact
|
|
5
|
-
* than {@link DrawerNavItem} — 28px tall (4px vertical padding), a 16px icon and
|
|
6
|
-
* a Medium-weight label — to read as secondary navigation. All colours resolve
|
|
7
|
-
* to theme tokens, so it adapts to light and dark.
|
|
8
|
-
*/
|
|
9
|
-
export declare const SettingsNavItem: React.FC<SettingsNavItemProps>;
|