@dbcdk/react-components 0.0.88 → 0.0.90
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 +1 -0
- package/dist/components/accordion/components/AccordionRow.js +1 -1
- package/dist/components/avatar/Avatar.js +16 -10
- package/dist/components/avatar/Avatar.module.css +33 -12
- package/dist/components/button/Button.js +8 -1
- package/dist/components/button/Button.module.css +2 -1
- package/dist/components/card/Card.d.ts +1 -5
- package/dist/components/card/Card.js +29 -4
- package/dist/components/card/Card.module.css +86 -98
- package/dist/components/card-container/CardContainer.d.ts +2 -1
- package/dist/components/card-container/CardContainer.js +2 -2
- package/dist/components/card-container/CardContainer.module.css +10 -9
- package/dist/components/clear-button/ClearButton.d.ts +2 -1
- package/dist/components/clear-button/ClearButton.js +6 -2
- package/dist/components/clear-button/ClearButton.module.css +6 -0
- package/dist/components/divider/Divider.d.ts +5 -0
- package/dist/components/divider/Divider.js +12 -0
- package/dist/components/forms/input/Input.d.ts +2 -1
- package/dist/components/forms/input/Input.js +6 -2
- package/dist/components/forms/input/Input.module.css +32 -0
- package/dist/components/forms/select/Select.d.ts +2 -1
- package/dist/components/forms/select/Select.js +2 -2
- package/dist/components/forms/typeahead/Typeahead.d.ts +2 -1
- package/dist/components/forms/typeahead/Typeahead.js +180 -118
- package/dist/components/forms/typeahead/Typeahead.module.css +4 -0
- package/dist/components/grid/Grid.d.ts +23 -0
- package/dist/components/grid/Grid.js +23 -0
- package/dist/components/grid/Grid.module.css +35 -0
- package/dist/components/headline/CollapsibleHeadline.d.ts +21 -0
- package/dist/components/headline/CollapsibleHeadline.js +29 -0
- package/dist/components/headline/Headline.d.ts +7 -5
- package/dist/components/headline/Headline.js +7 -6
- package/dist/components/headline/Headline.module.css +80 -8
- package/dist/components/nav-bar/NavBar.module.css +6 -2
- package/dist/components/overlay/modal/Modal.d.ts +2 -1
- package/dist/components/overlay/modal/Modal.js +5 -3
- package/dist/components/overlay/modal/provider/ModalProvider.js +2 -0
- package/dist/components/overlay/side-panel/SidePanel.d.ts +2 -1
- package/dist/components/overlay/side-panel/SidePanel.js +2 -2
- package/dist/components/page/Page.d.ts +5 -1
- package/dist/components/page/Page.js +6 -2
- package/dist/components/page/Page.module.css +54 -4
- package/dist/components/panel/Panel.d.ts +2 -1
- package/dist/components/panel/Panel.js +2 -2
- package/dist/components/popover/Popover.js +1 -1
- package/dist/components/stack/Stack.d.ts +16 -0
- package/dist/components/stack/Stack.js +19 -0
- package/dist/components/state-page/StatePage.d.ts +2 -1
- package/dist/components/state-page/StatePage.js +2 -2
- package/dist/components/table/Table.d.ts +1 -1
- package/dist/components/table/Table.js +22 -4
- package/dist/components/table/Table.module.css +14 -0
- package/dist/components/table/Table.types.d.ts +1 -0
- package/dist/components/tabs/Tabs.d.ts +3 -1
- package/dist/components/tabs/Tabs.js +4 -2
- package/dist/components/tabs/Tabs.module.css +4 -0
- package/dist/components/theme-button/ThemeButton.d.ts +1 -0
- package/dist/components/theme-button/ThemeButton.js +5 -1
- package/dist/components/toast/Toast.d.ts +2 -1
- package/dist/components/toast/Toast.js +2 -2
- package/dist/hooks/useViewportFill.d.ts +2 -6
- package/dist/hooks/useViewportFill.js +29 -24
- package/dist/index.d.ts +5 -0
- package/dist/index.js +5 -0
- package/dist/styles/css-helper-classes/flex.css +12 -0
- package/dist/styles/css-helper-classes/spacing.css +5 -0
- package/dist/styles/styles.css +154 -66
- package/dist/styles/themes/dbc/colors.css +10 -0
- package/dist/styles.css +154 -66
- package/package.json +1 -1
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
export type GridGap = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
3
|
+
export interface GridProps {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
gap?: GridGap;
|
|
6
|
+
/** Stretch direct children so cards/items in the same row get equal height */
|
|
7
|
+
equalHeight?: boolean;
|
|
8
|
+
className?: string;
|
|
9
|
+
style?: CSSProperties;
|
|
10
|
+
}
|
|
11
|
+
export declare function Grid({ children, gap, equalHeight, className, style }: GridProps): import("react/jsx-runtime").JSX.Element;
|
|
12
|
+
export interface GridItemProps {
|
|
13
|
+
children?: ReactNode;
|
|
14
|
+
/** Default span: <768px */
|
|
15
|
+
base?: number;
|
|
16
|
+
/** Medium span: ≥768px */
|
|
17
|
+
md?: number;
|
|
18
|
+
/** Large span: ≥1200px */
|
|
19
|
+
lg?: number;
|
|
20
|
+
className?: string;
|
|
21
|
+
style?: CSSProperties;
|
|
22
|
+
}
|
|
23
|
+
export declare function GridItem({ children, base, md, lg, className, style }: GridItemProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import styles from './Grid.module.css';
|
|
3
|
+
const GAP_TOKEN = {
|
|
4
|
+
none: '0',
|
|
5
|
+
xs: 'var(--spacing-xs)',
|
|
6
|
+
sm: 'var(--spacing-sm)',
|
|
7
|
+
md: 'var(--spacing-md)',
|
|
8
|
+
lg: 'var(--spacing-lg)',
|
|
9
|
+
xl: 'var(--spacing-xl)',
|
|
10
|
+
};
|
|
11
|
+
export function Grid({ children, gap = 'md', equalHeight = false, className, style }) {
|
|
12
|
+
return (_jsx("div", { className: [styles.grid, equalHeight && styles.equalHeight, className]
|
|
13
|
+
.filter(Boolean)
|
|
14
|
+
.join(' '), style: { gap: GAP_TOKEN[gap], ...style }, children: children }));
|
|
15
|
+
}
|
|
16
|
+
export function GridItem({ children, base = 12, md, lg, className, style }) {
|
|
17
|
+
return (_jsx("div", { className: [styles.item, className].filter(Boolean).join(' '), style: {
|
|
18
|
+
'--span-base': base,
|
|
19
|
+
...(md != null ? { '--span-md': md } : {}),
|
|
20
|
+
...(lg != null ? { '--span-lg': lg } : {}),
|
|
21
|
+
...style,
|
|
22
|
+
}, children: children }));
|
|
23
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
.grid {
|
|
2
|
+
display: grid;
|
|
3
|
+
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
4
|
+
align-items: start;
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.equalHeight {
|
|
8
|
+
align-items: stretch;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.item {
|
|
12
|
+
grid-column: span var(--span-base, 12);
|
|
13
|
+
min-inline-size: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.equalHeight .item {
|
|
17
|
+
display: flex;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
.equalHeight .item > * {
|
|
21
|
+
flex: 1;
|
|
22
|
+
min-inline-size: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
@media (min-width: 768px) {
|
|
26
|
+
.item {
|
|
27
|
+
grid-column: span var(--span-md, var(--span-base, 12));
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
@media (min-width: 1200px) {
|
|
32
|
+
.item {
|
|
33
|
+
grid-column: span var(--span-lg, var(--span-md, var(--span-base, 12)));
|
|
34
|
+
}
|
|
35
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
|
+
import type { HeadlineProps } from './Headline';
|
|
3
|
+
export interface CollapsibleHeadlineProps extends Omit<HeadlineProps, 'addition' | 'children'> {
|
|
4
|
+
/** The headline text — always visible. */
|
|
5
|
+
header: React.ReactNode;
|
|
6
|
+
/** Controlled expanded state. Required when `storageKey` is not set. */
|
|
7
|
+
expanded?: boolean;
|
|
8
|
+
/** Called when the toggle is clicked. */
|
|
9
|
+
onToggle?: () => void;
|
|
10
|
+
/** id of the panel element, used for aria-controls. Generated automatically if omitted. */
|
|
11
|
+
controls?: string;
|
|
12
|
+
/** Extra content rendered between the headline text and the toggle button. */
|
|
13
|
+
addition?: React.ReactNode;
|
|
14
|
+
/**
|
|
15
|
+
* When set the component manages its own expanded state, persisted to
|
|
16
|
+
* localStorage under this key. `expanded` is used as the initial value
|
|
17
|
+
* if nothing is stored yet; `onToggle` is still called after each toggle.
|
|
18
|
+
*/
|
|
19
|
+
storageKey?: string;
|
|
20
|
+
}
|
|
21
|
+
export declare function CollapsibleHeadline({ header, expanded, onToggle, controls, addition, storageKey, children, size, variant, weight, ...headlineProps }: PropsWithChildren<CollapsibleHeadlineProps>): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
+
import { ChevronDown } from 'lucide-react';
|
|
4
|
+
import { useId, useState } from 'react';
|
|
5
|
+
import { Headline } from './Headline';
|
|
6
|
+
import styles from './Headline.module.css';
|
|
7
|
+
import { Button } from '../button/Button';
|
|
8
|
+
export function CollapsibleHeadline({ header, expanded, onToggle, controls, addition, storageKey, children, size = 2, variant = 'muted', weight = 400, ...headlineProps }) {
|
|
9
|
+
const generatedId = useId();
|
|
10
|
+
const panelId = controls !== null && controls !== void 0 ? controls : generatedId;
|
|
11
|
+
const [internalExpanded, setInternalExpanded] = useState(() => {
|
|
12
|
+
if (!storageKey || typeof window === 'undefined')
|
|
13
|
+
return expanded !== null && expanded !== void 0 ? expanded : false;
|
|
14
|
+
const stored = localStorage.getItem(storageKey);
|
|
15
|
+
return stored !== null ? stored === 'true' : (expanded !== null && expanded !== void 0 ? expanded : false);
|
|
16
|
+
});
|
|
17
|
+
const isExpanded = storageKey ? internalExpanded : (expanded !== null && expanded !== void 0 ? expanded : false);
|
|
18
|
+
const handleToggle = () => {
|
|
19
|
+
if (storageKey) {
|
|
20
|
+
const next = !internalExpanded;
|
|
21
|
+
setInternalExpanded(next);
|
|
22
|
+
localStorage.setItem(storageKey, String(next));
|
|
23
|
+
}
|
|
24
|
+
onToggle === null || onToggle === void 0 ? void 0 : onToggle();
|
|
25
|
+
};
|
|
26
|
+
return (_jsxs("div", { className: styles.collapsibleRoot, children: [_jsxs(Headline, { ...headlineProps, variant: variant, weight: weight, size: size, addition: addition, children: [header, _jsx(Button, { shape: "round", type: "button", variant: "inline", "aria-expanded": isExpanded, "aria-controls": panelId, onClick: handleToggle, children: _jsx(ChevronDown, { "aria-hidden": true, className: [styles.toggleChevron, isExpanded ? styles.toggleChevronExpanded : '']
|
|
27
|
+
.filter(Boolean)
|
|
28
|
+
.join(' ') }) })] }), isExpanded && (_jsx("div", { id: panelId, className: styles.collapsiblePanel, children: children }))] }));
|
|
29
|
+
}
|
|
@@ -1,17 +1,19 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
2
|
import { Severity } from '../../constants/severity.types';
|
|
3
3
|
type HeadlineTone = 'dark' | 'light';
|
|
4
|
-
|
|
4
|
+
type HeadlineVariant = 'default' | 'muted';
|
|
5
|
+
export interface HeadlineProps extends React.AriaAttributes {
|
|
5
6
|
size?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
6
7
|
marker?: boolean;
|
|
7
8
|
disableMargin?: boolean;
|
|
8
9
|
severity?: Severity;
|
|
9
|
-
weight?: 500 | 600 | 700;
|
|
10
|
-
|
|
10
|
+
weight?: 400 | 500 | 600 | 700;
|
|
11
|
+
subheader?: React.ReactNode;
|
|
11
12
|
addition?: React.ReactNode;
|
|
12
13
|
icon?: React.ReactNode;
|
|
13
14
|
allowWrap?: boolean;
|
|
14
15
|
tone?: HeadlineTone;
|
|
16
|
+
variant?: HeadlineVariant;
|
|
15
17
|
}
|
|
16
|
-
export declare function Headline({ size, marker, disableMargin, children, severity, weight,
|
|
18
|
+
export declare function Headline({ size, marker, disableMargin, children, severity, weight, subheader, addition, icon, tone, variant, allowWrap, }: PropsWithChildren<HeadlineProps>): React.JSX.Element;
|
|
17
19
|
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import styles from './Headline.module.css';
|
|
4
4
|
import { SeverityBgColor } from '../../constants/severity';
|
|
5
5
|
import { Icon } from '../icon/Icon';
|
|
6
|
-
export function Headline({ size = 2, marker, disableMargin, children, severity, weight = 600,
|
|
6
|
+
export function Headline({ size = 2, marker, disableMargin, children, severity, weight = 600, subheader, addition, icon, tone, variant, allowWrap = true, }) {
|
|
7
7
|
const Tag = `h${size}`;
|
|
8
8
|
const containerClassName = [styles.headlineContainer, tone ? styles[`tone-${tone}`] : '']
|
|
9
9
|
.filter(Boolean)
|
|
@@ -12,14 +12,15 @@ export function Headline({ size = 2, marker, disableMargin, children, severity,
|
|
|
12
12
|
styles.headline,
|
|
13
13
|
disableMargin ? styles.noMargin : '',
|
|
14
14
|
marker ? styles.marker : '',
|
|
15
|
+
variant === 'muted' ? styles['variant-muted'] : '',
|
|
15
16
|
]
|
|
16
17
|
.filter(Boolean)
|
|
17
18
|
.join(' ');
|
|
18
19
|
const textClassName = [styles.text, allowWrap ? styles.wrap : styles.truncate]
|
|
19
20
|
.filter(Boolean)
|
|
20
21
|
.join(' ');
|
|
21
|
-
return (_jsxs(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
return (_jsx("div", { className: containerClassName, children: _jsxs("div", { className: styles.headlineBlock, children: [_jsxs("div", { className: styles.headlineRow, children: [_jsxs(Tag, { style: {
|
|
23
|
+
'--font-weight': weight,
|
|
24
|
+
'--marker-color': severity ? SeverityBgColor[severity] : undefined,
|
|
25
|
+
}, className: headlineClassName, children: [icon || (severity && !marker) ? (_jsx("span", { className: styles.icon, children: _jsx(Icon, { customIcon: icon, severity: severity }) })) : null, _jsx("span", { className: textClassName, children: children })] }), addition ? _jsx("div", { className: styles.addition, children: addition }) : null] }), subheader ? _jsx("div", { className: styles.subheader, children: subheader }) : null] }) }));
|
|
25
26
|
}
|
|
@@ -1,11 +1,24 @@
|
|
|
1
1
|
.headlineContainer {
|
|
2
2
|
display: flex;
|
|
3
|
-
align-items:
|
|
3
|
+
align-items: flex-start;
|
|
4
4
|
gap: var(--spacing-lg);
|
|
5
|
-
flex-wrap: wrap;
|
|
6
5
|
max-width: 100%;
|
|
6
|
+
min-width: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.headlineBlock {
|
|
10
|
+
display: flex;
|
|
11
|
+
flex-direction: column;
|
|
7
12
|
flex: 1 1 auto;
|
|
8
13
|
min-width: 0;
|
|
14
|
+
gap: var(--spacing-xxs);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.headlineRow {
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
gap: var(--spacing-lg);
|
|
21
|
+
min-width: 0;
|
|
9
22
|
}
|
|
10
23
|
|
|
11
24
|
/* Base headline */
|
|
@@ -17,7 +30,7 @@
|
|
|
17
30
|
margin-block: var(--spacing-xs);
|
|
18
31
|
|
|
19
32
|
/* Typography */
|
|
20
|
-
font-weight: var(--font-weight
|
|
33
|
+
font-weight: var(--font-weight, 600);
|
|
21
34
|
letter-spacing: var(--letter-spacing-tight);
|
|
22
35
|
line-height: var(--line-height-tight);
|
|
23
36
|
color: inherit;
|
|
@@ -27,6 +40,56 @@
|
|
|
27
40
|
min-width: 0; /* required for truncation inside flex */
|
|
28
41
|
}
|
|
29
42
|
|
|
43
|
+
/* CollapsibleHeadline wrapper */
|
|
44
|
+
.collapsibleRoot {
|
|
45
|
+
display: flex;
|
|
46
|
+
flex-direction: column;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.collapsiblePanel {
|
|
50
|
+
display: contents;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/* CollapsibleHeadline toggle button */
|
|
54
|
+
.toggleButton {
|
|
55
|
+
all: unset;
|
|
56
|
+
box-sizing: border-box;
|
|
57
|
+
display: inline-flex;
|
|
58
|
+
align-items: center;
|
|
59
|
+
justify-content: center;
|
|
60
|
+
flex: 0 0 auto;
|
|
61
|
+
padding: var(--spacing-2xs);
|
|
62
|
+
border-radius: var(--border-radius-sm);
|
|
63
|
+
cursor: pointer;
|
|
64
|
+
color: var(--color-fg-subtle);
|
|
65
|
+
transition: color var(--transition-fast) var(--ease-standard);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
.toggleButton:hover {
|
|
69
|
+
color: var(--color-fg-default);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
.toggleButton:focus-visible {
|
|
73
|
+
outline: none;
|
|
74
|
+
box-shadow: var(--focus-ring);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.toggleChevron {
|
|
78
|
+
display: block;
|
|
79
|
+
width: var(--icon-size-md);
|
|
80
|
+
height: var(--icon-size-md);
|
|
81
|
+
transition: transform var(--transition-normal) var(--ease-standard);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.toggleChevronExpanded {
|
|
85
|
+
transform: rotate(180deg);
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/* Variant overrides */
|
|
89
|
+
.variant-muted {
|
|
90
|
+
color: var(--color-fg-subtle);
|
|
91
|
+
}
|
|
92
|
+
|
|
30
93
|
/* Tone overrides */
|
|
31
94
|
.tone-dark .headline {
|
|
32
95
|
color: var(--color-fg-default);
|
|
@@ -58,15 +121,21 @@
|
|
|
58
121
|
pointer-events: none;
|
|
59
122
|
}
|
|
60
123
|
|
|
61
|
-
/*
|
|
62
|
-
.
|
|
63
|
-
|
|
64
|
-
opacity: 0.85;
|
|
65
|
-
font-size: var(--font-size-md);
|
|
124
|
+
/* Subheader */
|
|
125
|
+
.subheader {
|
|
126
|
+
font-size: var(--font-size-sm);
|
|
66
127
|
margin-block-start: calc(var(--spacing-2xs) * -1);
|
|
128
|
+
color: var(--color-fg-subtle);
|
|
67
129
|
line-height: var(--line-height-normal);
|
|
68
130
|
}
|
|
69
131
|
|
|
132
|
+
.addition {
|
|
133
|
+
display: flex;
|
|
134
|
+
flex: 1 1 auto;
|
|
135
|
+
min-width: 0;
|
|
136
|
+
align-items: center;
|
|
137
|
+
}
|
|
138
|
+
|
|
70
139
|
/* Icon */
|
|
71
140
|
.icon {
|
|
72
141
|
flex: 0 0 auto;
|
|
@@ -90,4 +159,7 @@
|
|
|
90
159
|
.wrap {
|
|
91
160
|
white-space: normal;
|
|
92
161
|
overflow: visible;
|
|
162
|
+
display: flex;
|
|
163
|
+
align-items: center;
|
|
164
|
+
gap: var(--spacing-xxs);
|
|
93
165
|
}
|
|
@@ -156,7 +156,6 @@
|
|
|
156
156
|
|
|
157
157
|
/* Hover + focus */
|
|
158
158
|
.link:hover {
|
|
159
|
-
background-color: var(--color-bg-hover-subtle);
|
|
160
159
|
color: var(--color-fg-default);
|
|
161
160
|
}
|
|
162
161
|
.link:focus-visible {
|
|
@@ -178,13 +177,18 @@
|
|
|
178
177
|
inset-block-end: 0;
|
|
179
178
|
inline-size: 0;
|
|
180
179
|
block-size: 2px;
|
|
181
|
-
background-color: var(--color-
|
|
180
|
+
background-color: var(--color-border-strong);
|
|
182
181
|
transition: inline-size var(--transition-fast) var(--ease-standard);
|
|
183
182
|
}
|
|
184
183
|
|
|
184
|
+
.link:hover::after {
|
|
185
|
+
inline-size: 100%;
|
|
186
|
+
}
|
|
187
|
+
|
|
185
188
|
.link.active::after,
|
|
186
189
|
.link[aria-current='page']::after {
|
|
187
190
|
inline-size: 100%;
|
|
191
|
+
background-color: var(--color-brand);
|
|
188
192
|
}
|
|
189
193
|
|
|
190
194
|
/* Icons/images inside links */
|
|
@@ -13,6 +13,7 @@ export type ModalProps = {
|
|
|
13
13
|
isOpen: boolean;
|
|
14
14
|
onRequestClose: () => void;
|
|
15
15
|
header?: ReactNode;
|
|
16
|
+
subheader?: ReactNode;
|
|
16
17
|
content?: ReactNode;
|
|
17
18
|
children?: ReactNode;
|
|
18
19
|
primaryAction?: ModalActionConfig;
|
|
@@ -23,4 +24,4 @@ export type ModalProps = {
|
|
|
23
24
|
dataCy?: string;
|
|
24
25
|
width?: number | string;
|
|
25
26
|
};
|
|
26
|
-
export declare function Modal({ isOpen, onRequestClose, header, content, children, primaryAction, secondaryAction, closeOnOverlayClick, severity, disableContentSpacing, isLoading, dataCy, width, }: ModalProps): React.ReactNode;
|
|
27
|
+
export declare function Modal({ isOpen, onRequestClose, header, subheader, content, children, primaryAction, secondaryAction, closeOnOverlayClick, severity, disableContentSpacing, isLoading, dataCy, width, }: ModalProps): React.ReactNode;
|
|
@@ -6,7 +6,7 @@ import { createPortal } from 'react-dom';
|
|
|
6
6
|
import { Button } from '../../../components/button/Button';
|
|
7
7
|
import { Headline } from '../../../components/headline/Headline';
|
|
8
8
|
import styles from './Modal.module.css';
|
|
9
|
-
export function Modal({ isOpen, onRequestClose, header, content, children, primaryAction, secondaryAction, closeOnOverlayClick = true, severity, disableContentSpacing = false, isLoading, dataCy, width, }) {
|
|
9
|
+
export function Modal({ isOpen, onRequestClose, header, subheader, content, children, primaryAction, secondaryAction, closeOnOverlayClick = true, severity, disableContentSpacing = false, isLoading, dataCy, width, }) {
|
|
10
10
|
const titleId = useId();
|
|
11
11
|
const dialogRef = useRef(null);
|
|
12
12
|
const lastActiveElementRef = useRef(null);
|
|
@@ -103,11 +103,13 @@ export function Modal({ isOpen, onRequestClose, header, content, children, prima
|
|
|
103
103
|
const stopPropagation = e => {
|
|
104
104
|
e.stopPropagation();
|
|
105
105
|
};
|
|
106
|
-
const resolvedSecondaryAction =
|
|
106
|
+
const resolvedSecondaryAction = primaryAction || secondaryAction
|
|
107
|
+
? { label: 'Luk', onClick: onRequestClose, ...secondaryAction }
|
|
108
|
+
: undefined;
|
|
107
109
|
const shouldRenderFooter = Boolean(primaryAction || resolvedSecondaryAction);
|
|
108
110
|
const body = children !== null && children !== void 0 ? children : content;
|
|
109
111
|
const resolvedWidth = typeof width === 'number' ? `${width}px` : typeof width === 'string' ? width : undefined;
|
|
110
112
|
return createPortal(_jsx("div", { className: styles.overlay, onClick: handleOverlayClick, children: _jsxs("div", { "data-cy": dataCy, ref: dialogRef, className: `${styles.modal} ${disableContentSpacing ? '' : styles.contentSpacing}`, style: resolvedWidth
|
|
111
113
|
? { ['--modal-width']: resolvedWidth }
|
|
112
|
-
: undefined, onClick: stopPropagation, role: "dialog", "aria-modal": "true", "aria-labelledby": header ? titleId : undefined, tabIndex: -1, children: [_jsxs("div", { className: styles.header, children: [header && (_jsx(Headline, { severity: severity, size: 3, disableMargin: true, children: header })), _jsx(Button, { type: "button", variant: "inline", onClick: () => onRequestCloseRef.current(), "aria-label": "Luk", shape: "round", icon: _jsx(X, {}) })] }), _jsx("div", { className: styles.body, children: body }), shouldRenderFooter && (_jsxs("div", { className: styles.footer, children: [resolvedSecondaryAction && (_jsxs(Button, { type: "button", onClick: resolvedSecondaryAction.onClick, disabled: isLoading, children: [resolvedSecondaryAction.icon && (_jsx("span", { className: styles.icon, children: resolvedSecondaryAction.icon })), _jsx("span", { children: resolvedSecondaryAction.label })] })), primaryAction && (_jsxs(Button, { type: "button", variant: primaryAction.severity || 'primary', onClick: primaryAction.onClick, disabled: primaryAction.disabled || isLoading, loading: isLoading, children: [primaryAction.icon && _jsx("span", { className: styles.icon, children: primaryAction.icon }), _jsx("span", { children: primaryAction.label })] }))] }))] }) }), document.body);
|
|
114
|
+
: undefined, onClick: stopPropagation, role: "dialog", "aria-modal": "true", "aria-labelledby": header ? titleId : undefined, tabIndex: -1, children: [_jsxs("div", { className: styles.header, children: [header && (_jsx(Headline, { severity: severity, size: 3, disableMargin: true, subheader: subheader, children: header })), _jsx(Button, { type: "button", variant: "inline", onClick: () => onRequestCloseRef.current(), "aria-label": "Luk", shape: "round", icon: _jsx(X, {}) })] }), _jsx("div", { className: styles.body, children: body }), shouldRenderFooter && (_jsxs("div", { className: styles.footer, children: [resolvedSecondaryAction && (_jsxs(Button, { type: "button", onClick: resolvedSecondaryAction.onClick, disabled: isLoading, children: [resolvedSecondaryAction.icon && (_jsx("span", { className: styles.icon, children: resolvedSecondaryAction.icon })), _jsx("span", { children: resolvedSecondaryAction.label })] })), primaryAction && (_jsxs(Button, { type: "button", variant: primaryAction.severity || 'primary', onClick: primaryAction.onClick, disabled: primaryAction.disabled || isLoading, loading: isLoading, children: [primaryAction.icon && _jsx("span", { className: styles.icon, children: primaryAction.icon }), _jsx("span", { children: primaryAction.label })] }))] }))] }) }), document.body);
|
|
113
115
|
}
|
|
@@ -47,12 +47,14 @@ export function ModalProvider({ children }) {
|
|
|
47
47
|
severity: confirmConfig.confirmButtonSeverity || 'primary',
|
|
48
48
|
onClick: () => {
|
|
49
49
|
resolvePending(true);
|
|
50
|
+
closeModal();
|
|
50
51
|
},
|
|
51
52
|
},
|
|
52
53
|
secondaryAction: {
|
|
53
54
|
label: cancelLabel,
|
|
54
55
|
onClick: () => {
|
|
55
56
|
resolvePending(false);
|
|
57
|
+
closeModal();
|
|
56
58
|
},
|
|
57
59
|
},
|
|
58
60
|
});
|
|
@@ -3,6 +3,7 @@ import { Severity } from '../../../constants/severity.types';
|
|
|
3
3
|
interface SidePanelProps {
|
|
4
4
|
children?: ReactNode;
|
|
5
5
|
header: ReactNode;
|
|
6
|
+
subheader?: ReactNode;
|
|
6
7
|
headerAddition?: ReactNode;
|
|
7
8
|
actions?: ReactNode;
|
|
8
9
|
onClose: (event?: React.MouseEvent<HTMLButtonElement> | React.MouseEvent<HTMLDivElement>) => void;
|
|
@@ -20,5 +21,5 @@ interface SidePanelProps {
|
|
|
20
21
|
onCloseDetails?: () => void;
|
|
21
22
|
detailsHeaderAddition?: ReactNode;
|
|
22
23
|
}
|
|
23
|
-
export declare function SidePanel({ isOpen, onClose, children, header, headerAddition, actions, showBackdrop, severity, showHeaderMarker, width, details, detailsHeader, detailsWidth, onCloseDetails, detailsHeaderAddition, ...props }: SidePanelProps & HTMLAttributes<HTMLElement>): ReactNode;
|
|
24
|
+
export declare function SidePanel({ isOpen, onClose, children, header, subheader, headerAddition, actions, showBackdrop, severity, showHeaderMarker, width, details, detailsHeader, detailsWidth, onCloseDetails, detailsHeaderAddition, ...props }: SidePanelProps & HTMLAttributes<HTMLElement>): ReactNode;
|
|
24
25
|
export {};
|
|
@@ -6,7 +6,7 @@ import { Button } from '../../../components/button/Button';
|
|
|
6
6
|
import { Headline } from '../../../components/headline/Headline';
|
|
7
7
|
import { MOTION_MS } from '../../../styles/animation';
|
|
8
8
|
import styles from './SidePanel.module.css';
|
|
9
|
-
export function SidePanel({ isOpen, onClose, children, header, headerAddition, actions, showBackdrop = true, severity, showHeaderMarker = true, width = '400px', details, detailsHeader = 'Output', detailsWidth = '420px', onCloseDetails, detailsHeaderAddition, ...props }) {
|
|
9
|
+
export function SidePanel({ isOpen, onClose, children, header, subheader, headerAddition, actions, showBackdrop = true, severity, showHeaderMarker = true, width = '400px', details, detailsHeader = 'Output', detailsWidth = '420px', onCloseDetails, detailsHeaderAddition, ...props }) {
|
|
10
10
|
const [mounted, setMounted] = useState(false);
|
|
11
11
|
const [shouldRender, setShouldRender] = useState(isOpen);
|
|
12
12
|
const [isActive, setIsActive] = useState(false);
|
|
@@ -76,7 +76,7 @@ export function SidePanel({ isOpen, onClose, children, header, headerAddition, a
|
|
|
76
76
|
}, "data-cy": "details-panel", role: "dialog", "aria-modal": "true", children: [hasDetails ? (_jsxs("aside", { className: styles.detailsCol, "data-cy": "details-panel-details", children: [_jsxs("div", { className: styles.detailsHeader, children: [_jsx("div", { className: styles.detailsTitle, children: detailsHeader }), _jsxs("div", { className: styles.detailsHeaderActions, children: [detailsHeaderAddition, onCloseDetails ? (_jsx(Button, { type: "button", size: "sm", variant: "outlined", onClick: e => {
|
|
77
77
|
e.stopPropagation();
|
|
78
78
|
onCloseDetails();
|
|
79
|
-
}, children: "Luk" })) : null] })] }), _jsx("div", { className: styles.detailsContent, children: details })] })) : null, _jsxs("section", { className: styles.mainCol, "data-cy": "details-panel-main", children: [_jsx("div", { className: styles.header, children: _jsxs("div", { className: "dbc-flex dbc-justify-between", children: [_jsx(Headline, { size: 3, disableMargin: true, severity: severity, marker: showHeaderMarker, children: header }), _jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xs", children: [headerAddition, _jsx(Button, { type: "button", size: "md", shape: "round", variant: "inline", onClick: e => {
|
|
79
|
+
}, children: "Luk" })) : null] })] }), _jsx("div", { className: styles.detailsContent, children: details })] })) : null, _jsxs("section", { className: styles.mainCol, "data-cy": "details-panel-main", children: [_jsx("div", { className: styles.header, children: _jsxs("div", { className: "dbc-flex dbc-justify-between", children: [_jsx(Headline, { size: 3, disableMargin: true, severity: severity, marker: showHeaderMarker, subheader: subheader, children: header }), _jsxs("span", { className: "dbc-flex dbc-items-center dbc-gap-xs", children: [headerAddition, _jsx(Button, { type: "button", size: "md", shape: "round", variant: "inline", onClick: e => {
|
|
80
80
|
e.stopPropagation();
|
|
81
81
|
onClose(e);
|
|
82
82
|
}, "aria-label": "Luk panel", "data-cy": "side-panel-close-button", children: _jsx(X, {}) })] })] }) }), _jsx("div", { className: styles.content, "data-cy": "details-panel-content", children: children }), actions && _jsx("div", { className: styles.actions, children: actions })] })] })] }), document.body);
|
|
@@ -3,12 +3,16 @@ import { Severity } from '../../constants/severity.types';
|
|
|
3
3
|
import { BreadcrumbItem } from '../breadcrumbs/Breadcrumbs';
|
|
4
4
|
interface PageProps {
|
|
5
5
|
header?: string;
|
|
6
|
+
subheader?: ReactNode;
|
|
6
7
|
severity?: Severity;
|
|
7
8
|
headerIcon?: ReactNode;
|
|
8
9
|
children?: ReactNode;
|
|
9
10
|
headerAddition?: ReactNode;
|
|
10
11
|
disableContentBox?: boolean;
|
|
12
|
+
disableTopPadding?: boolean;
|
|
13
|
+
maxWidth?: 'sm' | 'md' | 'lg';
|
|
11
14
|
breadcrumbs?: BreadcrumbItem[];
|
|
15
|
+
containScrolling?: boolean;
|
|
12
16
|
}
|
|
13
|
-
export declare function Page({ header, severity, headerIcon, headerAddition, breadcrumbs, disableContentBox, children, }: PageProps): ReactNode;
|
|
17
|
+
export declare function Page({ header, subheader, severity, headerIcon, headerAddition, breadcrumbs, disableContentBox, disableTopPadding, maxWidth, containScrolling, children, }: PageProps): ReactNode;
|
|
14
18
|
export {};
|
|
@@ -2,6 +2,10 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import styles from './Page.module.css';
|
|
3
3
|
import { Breadcrumbs } from '../breadcrumbs/Breadcrumbs';
|
|
4
4
|
import { Headline } from '../headline/Headline';
|
|
5
|
-
export function Page({ header, severity, headerIcon, headerAddition, breadcrumbs, disableContentBox, children, }) {
|
|
6
|
-
|
|
5
|
+
export function Page({ header, subheader, severity, headerIcon, headerAddition, breadcrumbs, disableContentBox, disableTopPadding = true, maxWidth, containScrolling = false, children, }) {
|
|
6
|
+
const maxWidthClass = maxWidth
|
|
7
|
+
? styles[`maxWidth${maxWidth.charAt(0).toUpperCase()}${maxWidth.slice(1)}`]
|
|
8
|
+
: '';
|
|
9
|
+
const hasHeadline = Boolean(header || subheader || headerAddition);
|
|
10
|
+
return (_jsxs("div", { className: `${styles.container} ${containScrolling ? styles.containScrolling : styles.documentScrolling} ${disableTopPadding ? styles.disableTopPadding : ''} ${maxWidthClass}`, children: [_jsx("div", { className: styles.headerContainer, children: _jsxs("div", { className: styles.headerMain, children: [breadcrumbs ? _jsx(Breadcrumbs, { items: breadcrumbs }) : null, hasHeadline ? (_jsx(Headline, { disableMargin: true, size: 2, severity: severity, icon: headerIcon, subheader: subheader, addition: headerAddition, children: header })) : null] }) }), _jsx("div", { className: `${styles.content} ${disableContentBox ? styles.disableContentBox : ''}`, children: children })] }));
|
|
7
11
|
}
|
|
@@ -1,24 +1,74 @@
|
|
|
1
1
|
.container {
|
|
2
|
-
padding: var(--spacing-md);
|
|
3
2
|
box-sizing: border-box;
|
|
4
3
|
display: flex;
|
|
5
4
|
flex-direction: column;
|
|
6
|
-
|
|
5
|
+
min-width: 0;
|
|
6
|
+
min-height: 0;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
.maxWidthSm,
|
|
10
|
+
.maxWidthMd,
|
|
11
|
+
.maxWidthLg {
|
|
12
|
+
margin-inline: auto;
|
|
13
|
+
width: 100%;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.maxWidthSm {
|
|
17
|
+
max-width: 560px;
|
|
18
|
+
}
|
|
19
|
+
.maxWidthMd {
|
|
20
|
+
max-width: 768px;
|
|
21
|
+
}
|
|
22
|
+
.maxWidthLg {
|
|
23
|
+
max-width: 1024px;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.containScrolling {
|
|
7
27
|
height: 100%;
|
|
28
|
+
overflow: hidden;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.documentScrolling {
|
|
32
|
+
height: auto;
|
|
33
|
+
overflow: visible;
|
|
8
34
|
}
|
|
9
35
|
|
|
10
36
|
.headerContainer {
|
|
11
37
|
display: flex;
|
|
12
|
-
|
|
13
|
-
align-items: center;
|
|
38
|
+
align-items: flex-start;
|
|
14
39
|
padding: var(--spacing-lg) 0;
|
|
40
|
+
gap: var(--spacing-md);
|
|
41
|
+
min-width: 0;
|
|
42
|
+
flex: 0 0 auto;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.disableTopPadding {
|
|
46
|
+
padding-block-start: 0;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.disableTopPadding .headerContainer {
|
|
50
|
+
padding-block-start: 0;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
.headerMain {
|
|
54
|
+
display: flex;
|
|
55
|
+
flex-direction: column;
|
|
56
|
+
gap: var(--spacing-md);
|
|
57
|
+
flex: 1 1 auto;
|
|
58
|
+
min-width: 0;
|
|
15
59
|
}
|
|
16
60
|
|
|
17
61
|
.content {
|
|
18
62
|
flex: 1 1 auto;
|
|
63
|
+
min-height: 0;
|
|
64
|
+
min-width: 0;
|
|
19
65
|
overflow: auto;
|
|
20
66
|
}
|
|
21
67
|
|
|
68
|
+
.documentScrolling .content {
|
|
69
|
+
overflow: visible;
|
|
70
|
+
}
|
|
71
|
+
|
|
22
72
|
.content:not(.disableContentBox) {
|
|
23
73
|
padding: var(--spacing-lg);
|
|
24
74
|
border: 1px solid var(--color-border-default);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { ReactNode, JSX } from 'react';
|
|
2
2
|
interface PanelProps {
|
|
3
3
|
header: ReactNode;
|
|
4
|
+
subheader?: ReactNode;
|
|
4
5
|
headerIcon?: ReactNode;
|
|
5
6
|
headerAddition?: ReactNode;
|
|
6
7
|
severity?: Severity;
|
|
@@ -8,5 +9,5 @@ interface PanelProps {
|
|
|
8
9
|
size?: 'sm' | 'md' | 'lg';
|
|
9
10
|
}
|
|
10
11
|
import { Severity } from '../../constants/severity.types';
|
|
11
|
-
export declare function Panel({ header, headerIcon, headerAddition, children, severity, size, }: PanelProps): JSX.Element;
|
|
12
|
+
export declare function Panel({ header, subheader, headerIcon, headerAddition, children, severity, size, }: PanelProps): JSX.Element;
|
|
12
13
|
export {};
|
|
@@ -2,6 +2,6 @@
|
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import styles from './Panel.module.css';
|
|
4
4
|
import { Headline } from '../headline/Headline';
|
|
5
|
-
export function Panel({ header, headerIcon, headerAddition, children, severity, size, }) {
|
|
6
|
-
return (_jsxs("section", { className: `${styles.container} ${size ? styles[size] : ''}`, children: [_jsx("div", { className: styles.header, children: _jsx(Headline, { disableMargin: true, size: size === 'sm' ? 4 : 3, icon: headerIcon, addition: headerAddition, severity: severity, children: header }) }), _jsx("div", { className: styles.content, children: children })] }));
|
|
5
|
+
export function Panel({ header, subheader, headerIcon, headerAddition, children, severity, size, }) {
|
|
6
|
+
return (_jsxs("section", { className: `${styles.container} ${size ? styles[size] : ''}`, children: [_jsx("div", { className: styles.header, children: _jsx(Headline, { disableMargin: true, size: size === 'sm' ? 4 : 3, icon: headerIcon, addition: headerAddition, subheader: subheader, severity: severity, children: header }) }), _jsx("div", { className: styles.content, children: children })] }));
|
|
7
7
|
}
|
|
@@ -219,7 +219,7 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
219
219
|
return;
|
|
220
220
|
(_b = (_a = triggerElRef.current) === null || _a === void 0 ? void 0 : _a.focus) === null || _b === void 0 ? void 0 : _b.call(_a);
|
|
221
221
|
}, [isOpen, returnFocus]);
|
|
222
|
-
const icon = isOpen ? _jsx(ChevronUp, { size: 20 }) : _jsx(ChevronDown, { size: 20 });
|
|
222
|
+
const icon = isOpen ? (_jsx(ChevronUp, { className: "dbc-muted-text", size: 20 })) : (_jsx(ChevronDown, { className: "dbc-muted-text", size: 20 }));
|
|
223
223
|
const setOverlayRef = React.useCallback((node) => {
|
|
224
224
|
assignRef(overlayRef, node);
|
|
225
225
|
}, [overlayRef]);
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { ElementType } from 'react';
|
|
2
|
+
type GapSize = 'xxs' | 'xs' | 'sm' | 'md' | 'lg';
|
|
3
|
+
type StackOwnProps = {
|
|
4
|
+
direction?: 'row' | 'column';
|
|
5
|
+
gap?: GapSize;
|
|
6
|
+
align?: 'start' | 'center' | 'end';
|
|
7
|
+
justify?: 'start' | 'center' | 'end' | 'between';
|
|
8
|
+
grow?: boolean;
|
|
9
|
+
wrap?: boolean;
|
|
10
|
+
};
|
|
11
|
+
export type StackProps<C extends ElementType = 'div'> = StackOwnProps & {
|
|
12
|
+
as?: C;
|
|
13
|
+
} & Omit<React.ComponentPropsWithRef<C>, keyof StackOwnProps | 'as'>;
|
|
14
|
+
type StackComponent = <C extends ElementType = 'div'>(props: StackProps<C>) => React.ReactElement | null;
|
|
15
|
+
export declare const Stack: StackComponent;
|
|
16
|
+
export {};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
3
|
+
import { forwardRef } from 'react';
|
|
4
|
+
export const Stack = forwardRef(function Stack({ as, direction, gap, align, justify, grow = false, wrap = false, className, ...rest }, ref) {
|
|
5
|
+
const Tag = (as !== null && as !== void 0 ? as : 'div');
|
|
6
|
+
const classes = [
|
|
7
|
+
'dbc-flex',
|
|
8
|
+
direction === 'column' ? 'dbc-flex-column' : undefined,
|
|
9
|
+
gap ? `dbc-gap-${gap}` : undefined,
|
|
10
|
+
align ? `dbc-items-${align}` : undefined,
|
|
11
|
+
justify ? `dbc-justify-${justify}` : undefined,
|
|
12
|
+
grow ? 'dbc-flex-grow' : undefined,
|
|
13
|
+
wrap ? 'dbc-flex-wrap' : undefined,
|
|
14
|
+
className,
|
|
15
|
+
]
|
|
16
|
+
.filter(Boolean)
|
|
17
|
+
.join(' ');
|
|
18
|
+
return _jsx(Tag, { ref: ref, className: classes, ...rest });
|
|
19
|
+
});
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { ReactNode } from 'react';
|
|
2
2
|
interface StatePageProps {
|
|
3
3
|
header?: string;
|
|
4
|
+
subheader?: ReactNode;
|
|
4
5
|
type: 'error' | 'empty' | 'info' | 'notfound';
|
|
5
6
|
children?: ReactNode;
|
|
6
7
|
actions?: ReactNode;
|
|
7
8
|
}
|
|
8
|
-
export declare function StatePage({ header, type, children, actions }: StatePageProps): ReactNode;
|
|
9
|
+
export declare function StatePage({ header, subheader, type, children, actions, }: StatePageProps): ReactNode;
|
|
9
10
|
export {};
|