@dbcdk/react-components 0.0.9 → 0.0.12
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/accordion/Accordion.d.ts +27 -0
- package/dist/components/accordion/Accordion.js +66 -0
- package/dist/components/accordion/Accordion.module.css +87 -0
- package/dist/components/button/Button.module.css +1 -0
- package/dist/components/card/Card.d.ts +21 -3
- package/dist/components/card/Card.js +17 -2
- package/dist/components/card/Card.module.css +59 -0
- package/dist/components/circle/Circle.d.ts +5 -1
- package/dist/components/circle/Circle.js +2 -2
- package/dist/components/circle/Circle.module.css +60 -4
- package/dist/components/code-block/CodeBlock.js +1 -1
- package/dist/components/code-block/CodeBlock.module.css +30 -17
- package/dist/components/copy-button/CopyButton.d.ts +1 -0
- package/dist/components/copy-button/CopyButton.js +10 -2
- package/dist/components/datetime-picker/DateTimePicker.d.ts +4 -8
- package/dist/components/datetime-picker/DateTimePicker.js +72 -92
- package/dist/components/datetime-picker/dateTimeHelpers.d.ts +14 -12
- package/dist/components/datetime-picker/dateTimeHelpers.js +25 -45
- package/dist/components/filter-field/FilterField.js +16 -11
- package/dist/components/filter-field/FilterField.module.css +133 -12
- package/dist/components/forms/checkbox/Checkbox.d.ts +4 -10
- package/dist/components/forms/checkbox/Checkbox.js +3 -5
- package/dist/components/forms/checkbox-group/CheckboxGroup.js +1 -1
- package/dist/components/forms/checkbox-group/CheckboxGroup.module.css +1 -1
- package/dist/components/forms/input/Input.d.ts +1 -0
- package/dist/components/forms/input/Input.js +2 -4
- package/dist/components/forms/input/Input.module.css +10 -11
- package/dist/components/forms/input-container/InputContainer.d.ts +2 -1
- package/dist/components/forms/input-container/InputContainer.js +3 -3
- package/dist/components/forms/input-container/InputContainer.module.css +65 -0
- package/dist/components/forms/radio-buttons/RadioButton.d.ts +36 -0
- package/dist/components/forms/radio-buttons/RadioButton.js +26 -0
- package/dist/components/forms/radio-buttons/RadioButtonGroup.d.ts +25 -0
- package/dist/components/forms/radio-buttons/RadioButtonGroup.js +19 -0
- package/dist/components/forms/radio-buttons/RadioButtons.module.css +117 -0
- package/dist/components/forms/select/Select.d.ts +1 -1
- package/dist/components/forms/select/Select.js +3 -3
- package/dist/components/forms/text-area/Textarea.js +3 -3
- package/dist/components/forms/text-area/Textarea.module.css +8 -1
- package/dist/components/headline/Headline.d.ts +2 -7
- package/dist/components/headline/Headline.js +5 -2
- package/dist/components/headline/Headline.module.css +61 -2
- package/dist/components/hyperlink/Hyperlink.d.ts +19 -6
- package/dist/components/hyperlink/Hyperlink.js +35 -7
- package/dist/components/hyperlink/Hyperlink.module.css +50 -2
- package/dist/components/icon/Icon.module.css +1 -0
- package/dist/components/interval-select/IntervalSelect.js +1 -1
- package/dist/components/menu/Menu.d.ts +32 -0
- package/dist/components/menu/Menu.js +73 -13
- package/dist/components/menu/Menu.module.css +72 -4
- package/dist/components/nav-bar/NavBar.d.ts +24 -6
- package/dist/components/overlay/modal/Modal.module.css +2 -2
- package/dist/components/overlay/side-panel/SidePanel.d.ts +12 -4
- package/dist/components/overlay/side-panel/SidePanel.js +77 -4
- package/dist/components/overlay/side-panel/SidePanel.module.css +149 -28
- package/dist/components/overlay/side-panel/useSidePanel.d.ts +1 -1
- package/dist/components/overlay/side-panel/useSidePanel.js +2 -2
- package/dist/components/overlay/tooltip/useTooltipTrigger.js +4 -2
- package/dist/components/page-layout/PageLayout.js +0 -2
- package/dist/components/popover/Popover.js +1 -1
- package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.d.ts +5 -5
- package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.js +36 -24
- package/dist/components/sidebar/components/expandable-sidebar-item/ExpandableSidebarItem.module.css +0 -3
- package/dist/components/sidebar/components/sidebar-container/SidebarContainer.d.ts +3 -1
- package/dist/components/sidebar/components/sidebar-container/SidebarContainer.js +4 -3
- package/dist/components/sidebar/components/sidebar-container/SidebarContainer.module.css +109 -79
- package/dist/components/sidebar/components/sidebar-items/SidebarItems.js +16 -3
- package/dist/components/sidebar/components/sidebar-items/SidebarItems.module.css +20 -0
- package/dist/components/sidebar/providers/SidebarProvider.d.ts +4 -1
- package/dist/components/sidebar/providers/SidebarProvider.js +85 -58
- package/dist/components/skeleton-loader/SkeletonLoader.d.ts +1 -1
- package/dist/components/skeleton-loader/SkeletonLoader.js +15 -12
- package/dist/components/split-button/SplitButton.d.ts +1 -1
- package/dist/components/split-button/SplitButton.js +3 -1
- package/dist/components/split-button/SplitButton.module.css +4 -4
- package/dist/components/state-page/StatePage.d.ts +9 -0
- package/dist/components/state-page/StatePage.js +20 -0
- package/dist/components/state-page/StatePage.module.css +9 -0
- package/dist/components/state-page/empty.d.ts +2 -0
- package/dist/components/state-page/empty.js +2 -0
- package/dist/components/state-page/error.d.ts +2 -0
- package/dist/components/state-page/error.js +2 -0
- package/dist/components/state-page/notFound.d.ts +2 -0
- package/dist/components/state-page/notFound.js +2 -0
- package/dist/components/sticky-footer-layout/StickyFooterLayout.d.ts +19 -0
- package/dist/components/sticky-footer-layout/StickyFooterLayout.js +27 -0
- package/dist/components/table/Table.d.ts +9 -4
- package/dist/components/table/Table.js +6 -9
- package/dist/components/table/Table.module.css +180 -59
- package/dist/components/table/components/empty-state/EmptyState.d.ts +1 -1
- package/dist/components/table/components/empty-state/EmptyState.js +6 -7
- package/dist/components/table/components/table-settings/TableSettings.d.ts +13 -3
- package/dist/components/table/components/table-settings/TableSettings.js +55 -4
- package/dist/components/table/tanstack.d.ts +12 -1
- package/dist/components/table/tanstack.js +75 -23
- package/dist/components/toast/Toast.js +5 -1
- package/dist/components/toast/Toast.module.css +40 -15
- package/dist/components/toast/provider/ToastProvider.js +1 -0
- package/dist/hooks/useTableSettings.d.ts +23 -4
- package/dist/hooks/useTableSettings.js +64 -17
- package/dist/hooks/useTimeDuration.js +9 -3
- package/dist/hooks/useViewportFill.js +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +6 -1
- package/dist/src/styles/styles.css +60 -25
- package/dist/styles/animation.d.ts +5 -0
- package/dist/styles/animation.js +5 -0
- package/dist/styles/styles.css +60 -25
- package/dist/styles/themes/dbc/dark.css +1 -1
- package/dist/styles/themes/dbc/light.css +2 -1
- package/dist/utils/localStorage.utils.d.ts +19 -0
- package/dist/utils/localStorage.utils.js +78 -0
- package/package.json +1 -1
|
@@ -1,54 +1,66 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { ChevronDown } from 'lucide-react';
|
|
4
|
-
import { useCallback, useEffect, useState } from 'react';
|
|
4
|
+
import { useCallback, useEffect, useMemo, useState } from 'react';
|
|
5
5
|
import styles from './ExpandableSidebarItem.module.css';
|
|
6
6
|
import { Button } from '../../../button/Button';
|
|
7
7
|
import { useSidebar } from '../../providers/SidebarProvider';
|
|
8
|
+
import { ExpandableSidebarItem as ExpandableChild } from '../expandable-sidebar-item/ExpandableSidebarItem';
|
|
8
9
|
import { SidebarItemContent } from '../sidebar-item-content/SidebarItemContent';
|
|
9
10
|
import { SidebarItem } from '../SidebarItem';
|
|
11
|
+
const isGroup = (item) => item.type === 'group';
|
|
12
|
+
const isExpandable = (item) => item.type === 'expandable';
|
|
10
13
|
export function ExpandableSidebarItem({ items, label, icon, component: Component, href, }) {
|
|
11
|
-
const { defaultExpanded, resetExpandAll, isSidebarCollapsed, handleSidebarCollapseChange,
|
|
12
|
-
|
|
14
|
+
const { defaultExpanded, resetExpandAll, isSidebarCollapsed, handleSidebarCollapseChange, expandItem, collapseItem, isExpanded, } = useSidebar();
|
|
15
|
+
// Local-only state for animation coordination
|
|
13
16
|
const [closing, setClosing] = useState(false);
|
|
14
17
|
const [ready, setReady] = useState(false);
|
|
15
18
|
useEffect(() => {
|
|
16
19
|
setReady(true);
|
|
17
20
|
}, []);
|
|
21
|
+
// Single source of truth: expanded comes from provider state
|
|
22
|
+
const expanded = useMemo(() => isExpanded(href), [href, isExpanded]);
|
|
23
|
+
// Expand-all behavior (e.g. search)
|
|
18
24
|
useEffect(() => {
|
|
19
|
-
if (
|
|
20
|
-
setExpanded(true);
|
|
21
|
-
}
|
|
22
|
-
}, [expandedItems, href]);
|
|
23
|
-
useEffect(() => {
|
|
24
|
-
if (defaultExpanded === null) {
|
|
25
|
+
if (defaultExpanded === null)
|
|
25
26
|
return;
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
27
|
+
if (defaultExpanded)
|
|
28
|
+
expandItem(href);
|
|
29
|
+
else
|
|
30
|
+
collapseItem(href);
|
|
31
|
+
}, [defaultExpanded, expandItem, collapseItem, href]);
|
|
29
32
|
const handleAnimationEnd = useCallback(() => {
|
|
30
|
-
if (ready)
|
|
31
|
-
|
|
33
|
+
if (!ready)
|
|
34
|
+
return;
|
|
35
|
+
if (closing) {
|
|
36
|
+
// After collapse animation, commit closed state
|
|
37
|
+
collapseItem(href);
|
|
32
38
|
setClosing(false);
|
|
33
39
|
}
|
|
34
|
-
}, [closing, ready]);
|
|
40
|
+
}, [closing, ready, collapseItem, href]);
|
|
35
41
|
const toggleAccordion = useCallback((e, onlyExpand = false) => {
|
|
36
42
|
e === null || e === void 0 ? void 0 : e.preventDefault();
|
|
37
43
|
e === null || e === void 0 ? void 0 : e.stopPropagation();
|
|
38
44
|
resetExpandAll();
|
|
39
|
-
handleSidebarCollapseChange
|
|
45
|
+
handleSidebarCollapseChange(false);
|
|
40
46
|
if (!expanded) {
|
|
41
|
-
|
|
47
|
+
expandItem(href);
|
|
42
48
|
return;
|
|
43
49
|
}
|
|
44
50
|
if (!isSidebarCollapsed && !onlyExpand) {
|
|
51
|
+
// Start collapse animation; state commit happens onAnimationEnd
|
|
45
52
|
setClosing(true);
|
|
46
53
|
}
|
|
47
|
-
}, [expanded, handleSidebarCollapseChange, isSidebarCollapsed, resetExpandAll]);
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
+
}, [expanded, expandItem, href, handleSidebarCollapseChange, isSidebarCollapsed, resetExpandAll]);
|
|
55
|
+
const renderNavItem = (item, key) => {
|
|
56
|
+
var _a, _b;
|
|
57
|
+
if (isGroup(item)) {
|
|
58
|
+
return (_jsxs("div", { className: styles.group, children: [_jsx("div", { className: styles.groupLabel, children: item.label }), (_a = item.children) === null || _a === void 0 ? void 0 : _a.map((child, idx) => renderNavItem(child, `${key}-${idx}`))] }, key));
|
|
59
|
+
}
|
|
60
|
+
if (isExpandable(item)) {
|
|
61
|
+
return (_jsx(ExpandableChild, { items: (_b = item.children) !== null && _b !== void 0 ? _b : [], label: item.label, icon: item.icon, href: item.href, component: item.component }, key));
|
|
62
|
+
}
|
|
63
|
+
return (_jsx(SidebarItem, { component: item.component, label: item.label, icon: item.icon, href: item.href }, key));
|
|
64
|
+
};
|
|
65
|
+
return (_jsxs("div", { className: `${styles.container} ${expanded ? styles.expanded : ''}`, children: [_jsx(Component, { onClick: () => toggleAccordion(undefined, true), children: _jsx(SidebarItemContent, { icon: icon, label: label, href: href, disableActiveStyles: expanded, suffixIcon: isSidebarCollapsed ? null : (_jsx(Button, { variant: "outlined", onClick: toggleAccordion, children: _jsx(ChevronDown, { className: `${styles.chevron} ${expanded ? styles.chevronExpanded : ''}` }) })) }) }), expanded && !isSidebarCollapsed && (_jsx("div", { onAnimationEnd: handleAnimationEnd, className: `${styles.childrenContainer} ${closing ? 'animate--collapse' : ''} ${expanded ? 'animate--expand' : 'visually-hidden'}`, children: items.map((item, idx) => renderNavItem(item, `${href}-${idx}`)) }))] }));
|
|
54
66
|
}
|
|
@@ -5,5 +5,7 @@ interface SidebarContainerProps {
|
|
|
5
5
|
productLogo?: ReactNode;
|
|
6
6
|
activeLink?: string;
|
|
7
7
|
}
|
|
8
|
-
export declare function SidebarContainer({ logo,
|
|
8
|
+
export declare function SidebarContainer({ logo, // DBC Digital (company)
|
|
9
|
+
productLogo, // DataIO (product)
|
|
10
|
+
activeLink, }: SidebarContainerProps): JSX.Element;
|
|
9
11
|
export {};
|
|
@@ -2,12 +2,13 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { ChevronLeft } from 'lucide-react';
|
|
3
3
|
import { Logo } from '../../../../assets/logo';
|
|
4
4
|
import { Button } from '../../../../components/button/Button';
|
|
5
|
-
import { Headline } from '../../../../components/headline/Headline';
|
|
6
5
|
import { SidebarItems } from '../../../../components/sidebar/components/sidebar-items/SidebarItems';
|
|
7
6
|
import SidenavFiltering from '../../../../components/sidebar/components/sidenav-filteirng/SidenavFiltering';
|
|
8
7
|
import { useSidebar } from '../../../../components/sidebar/providers/SidebarProvider';
|
|
9
8
|
import styles from './SidebarContainer.module.css';
|
|
10
|
-
export function SidebarContainer({ logo,
|
|
9
|
+
export function SidebarContainer({ logo, // DBC Digital (company)
|
|
10
|
+
productLogo, // DataIO (product)
|
|
11
|
+
activeLink, }) {
|
|
11
12
|
const { isSidebarCollapsed, handleSidebarCollapseChange } = useSidebar();
|
|
12
|
-
return (_jsxs("div", { className: `${styles.container} ${isSidebarCollapsed ? styles.collapsed : ''}`, children: [
|
|
13
|
+
return (_jsxs("div", { className: `${styles.container} ${isSidebarCollapsed ? styles.collapsed : ''}`, children: [_jsx("div", { className: styles.header, children: _jsxs("div", { className: styles.productHeader, children: [_jsx("div", { className: styles.productLogo, children: productLogo }), _jsx(Button, { size: "md", variant: "inline", "aria-label": "Collapse sidebar", icon: _jsx(ChevronLeft, { className: isSidebarCollapsed ? styles.collapsedIcon : '' }), onClick: () => handleSidebarCollapseChange(!isSidebarCollapsed) })] }) }), _jsxs("div", { className: styles.content, children: [_jsx("div", { className: styles.filter, children: _jsx(SidenavFiltering, {}) }), _jsx("div", { className: `${styles.links} hideScrollBar`, children: _jsx(SidebarItems, { activeLink: activeLink }) })] }), _jsx("div", { className: styles.footer, children: _jsx("div", { className: styles.companyLogo, children: logo !== null && logo !== void 0 ? logo : _jsx(Logo, {}) }) })] }));
|
|
13
14
|
}
|
|
@@ -4,152 +4,182 @@
|
|
|
4
4
|
overflow: auto;
|
|
5
5
|
display: flex;
|
|
6
6
|
flex-direction: column;
|
|
7
|
-
gap: var(--spacing-
|
|
7
|
+
gap: var(--spacing-md);
|
|
8
8
|
width: var(--sidebar-width);
|
|
9
9
|
inline-size: var(--sidebar-width);
|
|
10
10
|
box-sizing: border-box;
|
|
11
11
|
border-inline-end: var(--border-width-thin) solid var(--color-border-default);
|
|
12
|
-
|
|
12
|
+
|
|
13
13
|
transition:
|
|
14
14
|
width var(--transition-fast) var(--ease-standard),
|
|
15
15
|
inline-size var(--transition-fast) var(--ease-standard);
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
/* Collapsed state */
|
|
18
19
|
.container.collapsed {
|
|
19
20
|
width: var(--component-size-lg);
|
|
20
21
|
inline-size: var(--component-size-lg);
|
|
21
22
|
box-sizing: content-box;
|
|
22
23
|
gap: var(--spacing-sm);
|
|
23
|
-
.content {
|
|
24
|
-
gap: var(--spacing-2xs);
|
|
25
|
-
}
|
|
26
24
|
}
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
.container
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
width: 100%;
|
|
33
|
-
padding: var(--spacing-xs);
|
|
34
|
-
color: var(--color-fg-muted);
|
|
26
|
+
/* Global links / focus */
|
|
27
|
+
.container a {
|
|
28
|
+
text-decoration: none;
|
|
29
|
+
color: inherit;
|
|
35
30
|
}
|
|
36
31
|
|
|
37
|
-
.container:
|
|
38
|
-
.container:
|
|
39
|
-
|
|
32
|
+
.container a:focus-visible,
|
|
33
|
+
.container button:focus-visible {
|
|
34
|
+
outline: none;
|
|
35
|
+
box-shadow: var(--focus-ring);
|
|
40
36
|
}
|
|
41
37
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
38
|
+
/* HEADER (product + collapse) */
|
|
39
|
+
.header {
|
|
40
|
+
flex: 0 0 auto;
|
|
45
41
|
border-bottom: 1px solid var(--color-border-default);
|
|
46
|
-
padding
|
|
42
|
+
padding: 0 var(--spacing-sm);
|
|
43
|
+
min-block-size: 60px;
|
|
44
|
+
display: flex;
|
|
45
|
+
justify-content: space-between;
|
|
47
46
|
}
|
|
48
47
|
|
|
49
|
-
.
|
|
48
|
+
.productHeader {
|
|
50
49
|
display: flex;
|
|
51
|
-
flex-direction: column;
|
|
52
50
|
align-items: center;
|
|
53
|
-
justify-content:
|
|
51
|
+
justify-content: space-between;
|
|
52
|
+
gap: var(--spacing-sm);
|
|
53
|
+
flex-grow: 1;
|
|
54
54
|
}
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
/* Product logo container */
|
|
57
|
+
.productLogo {
|
|
57
58
|
display: flex;
|
|
58
59
|
align-items: center;
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
padding-right: var(--spacing-xxs);
|
|
60
|
+
max-inline-size: 100%;
|
|
61
|
+
min-width: 0;
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
/* Keep product logo visible in expanded state */
|
|
65
|
+
.productLogo img,
|
|
66
|
+
.productLogo svg {
|
|
67
|
+
inline-size: 50px;
|
|
68
|
+
max-inline-size: 100%;
|
|
69
|
+
block-size: auto;
|
|
67
70
|
}
|
|
68
71
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
border: 0;
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
72
|
+
/* Collapse button */
|
|
73
|
+
.productHeader button {
|
|
74
|
+
border-radius: 0;
|
|
75
|
+
min-height: var(--component-size-md);
|
|
76
|
+
padding: var(--spacing-xs);
|
|
77
|
+
color: var(--color-fg-muted);
|
|
78
|
+
flex: 0 0 auto;
|
|
76
79
|
}
|
|
77
80
|
|
|
78
|
-
|
|
79
|
-
.
|
|
80
|
-
|
|
81
|
-
|
|
81
|
+
/* Rotate icon when collapsed */
|
|
82
|
+
.collapsedIcon {
|
|
83
|
+
transform: rotate(180deg);
|
|
84
|
+
transition: transform 0.3s ease;
|
|
82
85
|
}
|
|
83
86
|
|
|
87
|
+
/* CONTENT */
|
|
88
|
+
.content {
|
|
89
|
+
overflow: auto;
|
|
90
|
+
flex: 1 1 auto;
|
|
91
|
+
overflow-y: visible;
|
|
92
|
+
display: flex;
|
|
93
|
+
flex-direction: column;
|
|
94
|
+
position: relative;
|
|
95
|
+
width: 100%;
|
|
96
|
+
gap: 5px;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
.container:not(.collapsed) .content {
|
|
100
|
+
gap: var(--spacing-md);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
/* FILTER */
|
|
104
|
+
.filter button {
|
|
105
|
+
border-radius: 0;
|
|
106
|
+
min-height: var(--component-size-md);
|
|
107
|
+
width: 100%;
|
|
108
|
+
padding: var(--spacing-xs);
|
|
109
|
+
color: var(--color-fg-muted);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.container:not(.collapsed) .filter {
|
|
113
|
+
padding-inline: var(--spacing-xs);
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* LINKS */
|
|
84
117
|
.links {
|
|
85
118
|
overflow: auto;
|
|
86
119
|
display: flex;
|
|
87
120
|
flex-grow: 1;
|
|
88
|
-
overflow: auto;
|
|
89
121
|
flex-direction: column;
|
|
90
122
|
gap: 2px;
|
|
91
123
|
font-size: var(--font-size-sm);
|
|
92
124
|
}
|
|
93
125
|
|
|
94
126
|
.container:not(.collapsed) .links {
|
|
95
|
-
padding-inline: var(--spacing-
|
|
127
|
+
padding-inline: var(--spacing-xs);
|
|
96
128
|
}
|
|
97
129
|
|
|
98
|
-
.
|
|
130
|
+
.container .links button {
|
|
131
|
+
background: none;
|
|
132
|
+
border: 0;
|
|
133
|
+
font-size: inherit;
|
|
134
|
+
color: inherit;
|
|
135
|
+
display: inline-flex;
|
|
136
|
+
padding: 0;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/* FOOTER (company logo) */
|
|
140
|
+
.footer {
|
|
99
141
|
flex: 0 0 auto;
|
|
142
|
+
border-top: 1px solid var(--color-border-default);
|
|
143
|
+
padding: var(--spacing-sm);
|
|
100
144
|
display: flex;
|
|
101
|
-
|
|
145
|
+
justify-content: center;
|
|
102
146
|
}
|
|
103
147
|
|
|
104
|
-
.
|
|
105
|
-
|
|
148
|
+
.companyLogo {
|
|
149
|
+
opacity: 0.6;
|
|
106
150
|
}
|
|
107
151
|
|
|
108
|
-
.
|
|
109
|
-
|
|
152
|
+
.companyLogo svg {
|
|
153
|
+
width: 80px;
|
|
154
|
+
height: auto;
|
|
155
|
+
display: block;
|
|
110
156
|
}
|
|
111
|
-
|
|
157
|
+
|
|
158
|
+
/* Hide company logo in collapsed state */
|
|
159
|
+
.container.collapsed .companyLogo {
|
|
112
160
|
display: none;
|
|
113
161
|
}
|
|
114
162
|
|
|
115
|
-
.logo
|
|
116
|
-
|
|
117
|
-
inline-size: 50px;
|
|
118
|
-
max-inline-size: 100%;
|
|
119
|
-
block-size: auto;
|
|
163
|
+
.logo {
|
|
164
|
+
display: none;
|
|
120
165
|
}
|
|
121
166
|
|
|
167
|
+
/* === Collapsed header behavior ===
|
|
168
|
+
Hide product logo entirely so the collapse button can truly center. */
|
|
122
169
|
.container.collapsed .productLogo {
|
|
123
170
|
display: none;
|
|
124
171
|
}
|
|
125
|
-
.productLogo {
|
|
126
|
-
max-inline-size: 100%;
|
|
127
|
-
padding: 0 var(--spacing-sm);
|
|
128
|
-
}
|
|
129
172
|
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
173
|
+
/* Center the collapse button in collapsed state */
|
|
174
|
+
.container.collapsed .productHeader {
|
|
175
|
+
justify-content: center;
|
|
176
|
+
gap: 0;
|
|
133
177
|
}
|
|
134
178
|
|
|
135
|
-
.
|
|
136
|
-
|
|
137
|
-
transition: transform 0.3s ease;
|
|
138
|
-
}
|
|
139
|
-
.content {
|
|
140
|
-
overflow: auto;
|
|
141
|
-
flex: 1 1 auto;
|
|
142
|
-
overflow-y: visible;
|
|
143
|
-
display: flex;
|
|
144
|
-
flex-direction: column;
|
|
145
|
-
position: relative;
|
|
146
|
-
width: 100%;
|
|
147
|
-
gap: 5px;
|
|
148
|
-
&:not(.collapsed) {
|
|
149
|
-
gap: var(--spacing-md);
|
|
150
|
-
}
|
|
179
|
+
.container.collapsed .header {
|
|
180
|
+
padding: 0;
|
|
151
181
|
}
|
|
152
182
|
|
|
153
|
-
.
|
|
154
|
-
|
|
183
|
+
.container.collapsed .productHeader button {
|
|
184
|
+
margin-inline: auto;
|
|
155
185
|
}
|
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx,
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { useEffect } from 'react';
|
|
4
|
+
import styles from './SidebarItems.module.css';
|
|
4
5
|
import { useSidebar } from '../../providers/SidebarProvider';
|
|
5
6
|
import { ExpandableSidebarItem } from '../expandable-sidebar-item/ExpandableSidebarItem';
|
|
6
7
|
import { SidebarItem } from '../SidebarItem';
|
|
7
8
|
export function SidebarItems({ activeLink }) {
|
|
8
|
-
const { filteredItems, setActiveLink } = useSidebar();
|
|
9
|
+
const { filteredItems, setActiveLink, isSidebarCollapsed } = useSidebar();
|
|
9
10
|
useEffect(() => {
|
|
10
11
|
setActiveLink(activeLink !== null && activeLink !== void 0 ? activeLink : '');
|
|
11
12
|
}, [activeLink, setActiveLink]);
|
|
12
|
-
|
|
13
|
+
const renderItem = (item, key) => {
|
|
14
|
+
var _a, _b;
|
|
15
|
+
if (item.type === 'group') {
|
|
16
|
+
return isSidebarCollapsed ? ((_a = item.children) === null || _a === void 0 ? void 0 : _a.map((child, idx) => renderItem(child, `${key}-c${idx}`))) : (_jsxs("div", { className: styles.group, children: [_jsx("div", { className: styles.groupLabel, children: item.label }), (_b = item.children) === null || _b === void 0 ? void 0 : _b.map((child, idx) => renderItem(child, `${key}-c${idx}`))] }, key));
|
|
17
|
+
}
|
|
18
|
+
if (item.type === 'expandable') {
|
|
19
|
+
const { component: Component, label, icon, children, href } = item;
|
|
20
|
+
return (_jsx(ExpandableSidebarItem, { items: children, label: label, icon: icon, href: href, component: Component }, key));
|
|
21
|
+
}
|
|
22
|
+
const { component: Component, label, icon, href } = item;
|
|
23
|
+
return _jsx(SidebarItem, { component: Component, label: label, icon: icon, href: href }, key);
|
|
24
|
+
};
|
|
25
|
+
return filteredItems === null || filteredItems === void 0 ? void 0 : filteredItems.map((item, idx) => renderItem(item, `nav-${idx}-${item.label}`));
|
|
13
26
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.group {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
gap: var(--spacing-xxs);
|
|
5
|
+
margin-top: var(--spacing-xs);
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.group:first-child {
|
|
9
|
+
margin-top: 0;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.groupLabel {
|
|
13
|
+
padding: 0 var(--spacing-xs);
|
|
14
|
+
margin: var(--spacing-xs) 0;
|
|
15
|
+
font-size: var(--font-size-xs);
|
|
16
|
+
font-weight: var(--font-weight-medium);
|
|
17
|
+
color: var(--color-fg-subtle);
|
|
18
|
+
letter-spacing: 0.04em;
|
|
19
|
+
text-transform: uppercase;
|
|
20
|
+
}
|
|
@@ -3,7 +3,7 @@ import * as React from 'react';
|
|
|
3
3
|
import { NavBarItem } from '../../../components/nav-bar/NavBar';
|
|
4
4
|
export type SidebarContextValue = {
|
|
5
5
|
defaultExpanded: boolean | null;
|
|
6
|
-
expandedItems: Set<string
|
|
6
|
+
expandedItems: Set<string>;
|
|
7
7
|
resetExpandAll: () => void;
|
|
8
8
|
activeQuery: string;
|
|
9
9
|
areItemsCollapsed: boolean;
|
|
@@ -13,6 +13,9 @@ export type SidebarContextValue = {
|
|
|
13
13
|
filteredItems?: NavBarItem[];
|
|
14
14
|
activeLink?: string;
|
|
15
15
|
setActiveLink: (href: string) => void;
|
|
16
|
+
expandItem: (href: string) => void;
|
|
17
|
+
collapseItem: (href: string) => void;
|
|
18
|
+
isExpanded: (href: string) => boolean;
|
|
16
19
|
isSidebarCollapsed: boolean;
|
|
17
20
|
handleSidebarCollapseChange: (collapsed: boolean) => void;
|
|
18
21
|
};
|