@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
|
@@ -5,7 +5,7 @@ import { ErrorIllustration } from './error';
|
|
|
5
5
|
import { NotFoundIllustration } from './notFound';
|
|
6
6
|
import styles from './StatePage.module.css';
|
|
7
7
|
import { Headline } from '../headline/Headline';
|
|
8
|
-
export function StatePage({ header, type, children, actions }) {
|
|
8
|
+
export function StatePage({ header, subheader, type, children, actions, }) {
|
|
9
9
|
const illustration = useMemo(() => {
|
|
10
10
|
switch (type) {
|
|
11
11
|
case 'error':
|
|
@@ -16,5 +16,5 @@ export function StatePage({ header, type, children, actions }) {
|
|
|
16
16
|
return _jsx(NotFoundIllustration, {});
|
|
17
17
|
}
|
|
18
18
|
}, [type]);
|
|
19
|
-
return (_jsxs("div", { className: `dbc-flex dbc-flex-column dbc-gap-lg dbc-items-center dbc-justify-center ${styles.container}`, children: [_jsx("div", { className: styles.illustration, children: illustration }), _jsxs("div", { className: "dbc-flex dbc-flex-column dbc-gap-md dbc-items-center", children: [_jsx(Headline, { disableMargin: true, size: 1, children: header }), _jsx("div", { children: children }), _jsx("div", { className: "dbc-flex dbc-gap-sm dbc-justify-center", children: actions })] })] }));
|
|
19
|
+
return (_jsxs("div", { className: `dbc-flex dbc-flex-column dbc-gap-lg dbc-items-center dbc-justify-center ${styles.container}`, children: [_jsx("div", { className: styles.illustration, children: illustration }), _jsxs("div", { className: "dbc-flex dbc-flex-column dbc-gap-md dbc-items-center", children: [_jsx(Headline, { disableMargin: true, size: 1, subheader: subheader, children: header }), _jsx("div", { children: children }), _jsx("div", { className: "dbc-flex dbc-gap-sm dbc-justify-center", children: actions })] })] }));
|
|
20
20
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import type { JSX } from 'react';
|
|
2
2
|
import type { TableProps } from './Table.types';
|
|
3
|
-
export declare function Table<T extends Record<string, any>>({ data, dataKey, columns, selectedRows, selectionMode, allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant, size, viewMode, striped, fillViewport, tableWidth, tableRootRef, measuringLayout, toolbar, headerExtras, take, skip, totalItemsCount, paginationPlacement, showFirstLast, pageSizeOptions, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
|
|
3
|
+
export declare function Table<T extends Record<string, any>>({ data, dataKey, columns, selectedRows, selectionMode, allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant, size, viewMode, striped, fillViewport, fillViewportBottomOffset, tableWidth, tableRootRef, measuringLayout, toolbar, headerExtras, take, skip, totalItemsCount, paginationPlacement, showFirstLast, pageSizeOptions, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }: TableProps<T>): JSX.Element;
|
|
4
4
|
export type { ColumnItem } from './Table.types';
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
|
-
import { useCallback, useId, useMemo } from 'react';
|
|
3
|
+
import { useCallback, useId, useMemo, useRef } from 'react';
|
|
4
4
|
import { Pagination } from '../../components/pagination/Pagination';
|
|
5
|
+
import { useViewportFill } from '../../hooks/useViewportFill';
|
|
5
6
|
import { TableEmptyState } from './components/empty-state/EmptyState';
|
|
6
7
|
import { TableBody } from './components/TableBody';
|
|
7
8
|
import { TableHeader } from './components/TableHeader';
|
|
@@ -9,17 +10,34 @@ import { TableLoadingBody } from './components/TableLoadingBody';
|
|
|
9
10
|
import { cx } from './table.classes';
|
|
10
11
|
import styles from './Table.module.css';
|
|
11
12
|
import { getVisibleColumns, SELECTION_COLUMN_PX } from './table.utils';
|
|
12
|
-
export function Table({ data, dataKey, columns, selectedRows, selectionMode = 'single', allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant = 'primary', size = 'md', viewMode, striped, fillViewport = false, tableWidth, tableRootRef, measuringLayout = false, toolbar, headerExtras, take, skip, totalItemsCount, paginationPlacement = 'bottom', showFirstLast = false, pageSizeOptions, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }) {
|
|
13
|
+
export function Table({ data, dataKey, columns, selectedRows, selectionMode = 'single', allRowsSelected, sortById, sortDirection, loading, emptyConfig, variant = 'primary', size = 'md', viewMode, striped, fillViewport = false, fillViewportBottomOffset = 16, tableWidth, tableRootRef, measuringLayout = false, toolbar, headerExtras, take, skip, totalItemsCount, paginationPlacement = 'bottom', showFirstLast = false, pageSizeOptions, getRowSeverity, onRowClick, onRowMouseEnter, onRowSelect, onSelectAllRows, onSortChange, onPageChange, ...rest }) {
|
|
13
14
|
const visibleColumns = useMemo(() => getVisibleColumns(columns), [columns]);
|
|
14
15
|
const selectionInputName = useId();
|
|
16
|
+
const internalTableRootRef = useRef(null);
|
|
17
|
+
const tableRootRefWrapper = useRef(tableRootRef);
|
|
15
18
|
const hasSelection = Boolean(selectedRows && onRowSelect);
|
|
19
|
+
const hasPagination = Boolean(onPageChange && (loading || data.length > 0));
|
|
20
|
+
const paginationOffset = hasPagination ? 72 : 0;
|
|
21
|
+
const { style: viewportFillStyle } = useViewportFill(internalTableRootRef, {
|
|
22
|
+
bottomOffset: fillViewportBottomOffset + paginationOffset,
|
|
23
|
+
min: 120,
|
|
24
|
+
});
|
|
25
|
+
const setTableRootRef = useCallback((node) => {
|
|
26
|
+
internalTableRootRef.current = node;
|
|
27
|
+
if (typeof tableRootRefWrapper.current === 'function') {
|
|
28
|
+
tableRootRefWrapper.current(node);
|
|
29
|
+
}
|
|
30
|
+
else if (tableRootRefWrapper.current) {
|
|
31
|
+
tableRootRefWrapper.current.current = node;
|
|
32
|
+
}
|
|
33
|
+
}, []);
|
|
16
34
|
const handlePageChange = useCallback((e) => {
|
|
17
35
|
onPageChange === null || onPageChange === void 0 ? void 0 : onPageChange(e);
|
|
18
36
|
}, [onPageChange]);
|
|
19
37
|
const bodyContent = loading && !data.length ? (_jsx(TableLoadingBody, { rows: take !== null && take !== void 0 ? take : 5, columns: visibleColumns, hasSelection: hasSelection })) : (_jsx(TableBody, { data: data, dataKey: dataKey, columns: visibleColumns, striped: striped, selectedRows: selectedRows, hasSelection: hasSelection, selectionMode: selectionMode, selectionInputName: selectionInputName, viewMode: viewMode, getRowSeverity: getRowSeverity, onRowClick: onRowClick, onRowMouseEnter: onRowMouseEnter, onRowSelect: onRowSelect }));
|
|
20
|
-
const paginationEl =
|
|
38
|
+
const paginationEl = hasPagination ? (_jsx("div", { className: cx(styles.paginationSlot, paginationPlacement === 'top' && styles.paginationSlotTop), children: _jsx(Pagination, { itemsCount: totalItemsCount, take: take, skip: skip, onPageChange: handlePageChange, showFirstLast: showFirstLast, pageSizeOptions: pageSizeOptions }) })) : null;
|
|
21
39
|
const tableClassName = cx(styles.tableRoot, styles[variant], styles[size], measuringLayout && styles.measuringLayout, getRowSeverity && styles.severityTable);
|
|
22
|
-
const tableShell = (_jsx("div", { ...rest, className: tableClassName, children: _jsx("div", { ref:
|
|
40
|
+
const tableShell = (_jsx("div", { ...rest, className: tableClassName, children: _jsx("div", { ref: setTableRootRef, className: styles.tableScroll, style: fillViewport ? viewportFillStyle : undefined, children: !data.length && !loading ? (_jsx("div", { className: styles.emptyStateSlot, children: _jsx(TableEmptyState, { config: emptyConfig }) })) : (_jsxs("table", { className: styles.tableElement, "aria-rowcount": data.length, style: tableWidth != null ? { width: tableWidth } : undefined, children: [_jsxs("colgroup", { children: [hasSelection ? _jsx("col", { style: { width: SELECTION_COLUMN_PX } }) : null, visibleColumns.map(column => (_jsx("col", { style: column.width != null ? { width: column.width } : undefined }, column.id)))] }), _jsx(TableHeader, { columns: visibleColumns, hasSelection: hasSelection, selectionMode: selectionMode, allRowsSelected: allRowsSelected, onSelectAllRows: onSelectAllRows, sortById: sortById, sortDirection: sortDirection, onSortChange: onSortChange, headerExtras: headerExtras }), bodyContent] })) }) }));
|
|
23
41
|
if (fillViewport) {
|
|
24
42
|
return (_jsxs("div", { className: styles.fillViewportRoot, style: {
|
|
25
43
|
flexDirection: paginationPlacement === 'top' ? 'column-reverse' : 'column',
|
|
@@ -101,6 +101,10 @@
|
|
|
101
101
|
min-block-size: 0;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
.body .row:first-child .cell {
|
|
105
|
+
border-block-start: var(--spacing-xs) solid var(--table-row-bg);
|
|
106
|
+
}
|
|
107
|
+
|
|
104
108
|
.headerCell,
|
|
105
109
|
.cell {
|
|
106
110
|
position: relative;
|
|
@@ -136,6 +140,16 @@
|
|
|
136
140
|
line-height: 20px;
|
|
137
141
|
}
|
|
138
142
|
|
|
143
|
+
.md .headerCell {
|
|
144
|
+
padding-block: var(--spacing-xs);
|
|
145
|
+
padding-inline: var(--spacing-sm);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.md .cell {
|
|
149
|
+
padding-block: var(--spacing-xs);
|
|
150
|
+
padding-inline: var(--spacing-sm);
|
|
151
|
+
}
|
|
152
|
+
|
|
139
153
|
.sm .headerCell {
|
|
140
154
|
padding-block: var(--spacing-xxs);
|
|
141
155
|
padding-inline: var(--spacing-sm);
|
|
@@ -42,6 +42,7 @@ export type TableProps<T extends Record<string, any>> = Omit<HTMLAttributes<HTML
|
|
|
42
42
|
viewMode?: ViewMode;
|
|
43
43
|
striped?: boolean;
|
|
44
44
|
fillViewport?: boolean;
|
|
45
|
+
fillViewportBottomOffset?: number;
|
|
45
46
|
tableWidth?: number;
|
|
46
47
|
tableRootRef?: Ref<HTMLDivElement>;
|
|
47
48
|
measuringLayout?: boolean;
|
|
@@ -12,6 +12,7 @@ export type TabItem = {
|
|
|
12
12
|
type TabsVariant = 'filled' | 'outlined';
|
|
13
13
|
export interface TabsProps {
|
|
14
14
|
header?: string;
|
|
15
|
+
subheader?: ReactNode;
|
|
15
16
|
variant: TabsVariant;
|
|
16
17
|
panelStyle?: boolean;
|
|
17
18
|
/** Data-driven API */
|
|
@@ -22,6 +23,7 @@ export interface TabsProps {
|
|
|
22
23
|
defaultValue?: TabId;
|
|
23
24
|
onValueChange?: (id: TabId, tab: TabItem, index: number) => void;
|
|
24
25
|
addition?: ReactNode;
|
|
26
|
+
disableTopPadding?: boolean;
|
|
25
27
|
/** Composition API */
|
|
26
28
|
children?: ReactNode;
|
|
27
29
|
}
|
|
@@ -38,7 +40,7 @@ type SlotName = 'Item';
|
|
|
38
40
|
type TabsItemComponent = ((props: TabsItemProps) => JSX.Element) & {
|
|
39
41
|
__TABS_SLOT__?: SlotName;
|
|
40
42
|
};
|
|
41
|
-
export declare function Tabs({ header, variant, panelStyle, tabs, value, defaultValue, onValueChange, addition, children, }: TabsProps): JSX.Element;
|
|
43
|
+
export declare function Tabs({ header, subheader, variant, panelStyle, tabs, value, defaultValue, onValueChange, addition, disableTopPadding, children, }: TabsProps): JSX.Element;
|
|
42
44
|
export declare namespace Tabs {
|
|
43
45
|
var Item: TabsItemComponent;
|
|
44
46
|
}
|
|
@@ -33,7 +33,7 @@ function normalizeFromChildren(children) {
|
|
|
33
33
|
});
|
|
34
34
|
return items;
|
|
35
35
|
}
|
|
36
|
-
export function Tabs({ header, variant, panelStyle = false, tabs, value, defaultValue, onValueChange, addition, children, }) {
|
|
36
|
+
export function Tabs({ header, subheader, variant, panelStyle = false, tabs, value, defaultValue, onValueChange, addition, disableTopPadding, children, }) {
|
|
37
37
|
const uid = useId();
|
|
38
38
|
// Data API wins if provided; otherwise parse <Tabs.Item>
|
|
39
39
|
const sourceTabs = useMemo(() => {
|
|
@@ -113,7 +113,9 @@ export function Tabs({ header, variant, panelStyle = false, tabs, value, default
|
|
|
113
113
|
focusAndSelect(enabled.length - 1);
|
|
114
114
|
}
|
|
115
115
|
}, [uid, visibleTabs, setValue]);
|
|
116
|
-
return (_jsxs("div", { className: styles.root, children: [header ? (
|
|
116
|
+
return (_jsxs("div", { className: styles.root, children: [header ? (_jsx("div", { className: [styles.headerContainer, disableTopPadding ? styles.disableTopPadding : '']
|
|
117
|
+
.filter(Boolean)
|
|
118
|
+
.join(' '), children: _jsx(Headline, { disableMargin: true, size: 2, subheader: subheader, addition: addition, children: header }) })) : null, _jsxs("div", { className: `${styles.tabs} ${styles[variant]} ${panelStyle ? styles.panelStyle : ''}`, children: [_jsx("div", { className: styles.tabList, role: "tablist", "aria-label": header !== null && header !== void 0 ? header : 'Tabs', children: visibleTabs.map((tab, index) => {
|
|
117
119
|
const selected = index === activeIndex;
|
|
118
120
|
const tabDomId = `${uid}-tab-${String(tab.id)}`;
|
|
119
121
|
const panelDomId = `${uid}-panel-${String(tab.id)}`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import { Monitor, Moon, Palette, Sun } from 'lucide-react';
|
|
4
4
|
import { Button } from '../../components/button/Button';
|
|
5
5
|
import { Menu } from '../../components/menu/Menu';
|
|
@@ -10,6 +10,10 @@ const THEME_OPTIONS = [
|
|
|
10
10
|
{ value: 'light', label: 'Lyst', icon: _jsx(Sun, { size: 16 }) },
|
|
11
11
|
{ value: 'dark', label: 'Mørkt', icon: _jsx(Moon, { size: 16 }) },
|
|
12
12
|
];
|
|
13
|
+
export function ThemeMenuSection() {
|
|
14
|
+
const { theme, switchTheme } = useTheme();
|
|
15
|
+
return (_jsxs(_Fragment, { children: [_jsx(Menu.Header, { children: "Udseende" }), THEME_OPTIONS.map(option => (_jsx(Menu.RadioItem, { name: "theme", value: option.value, checked: theme === option.value, label: option.label, onValueChange: value => switchTheme(value) }, option.value)))] }));
|
|
16
|
+
}
|
|
13
17
|
export function ThemeButton({ size, variant = 'outlined' }) {
|
|
14
18
|
const { theme, switchTheme } = useTheme();
|
|
15
19
|
return (_jsx(Popover, { matchTriggerWidth: false, minWidth: "140px", trigger: (handleClick, chevron) => (_jsxs(Button, { variant: variant, size: size, onClick: handleClick, "aria-label": "Skift tema", "aria-haspopup": "menu", children: [_jsx(Palette, {}), chevron] })), children: close => (_jsxs(Menu, { children: [_jsx(Menu.Header, { children: "Udseende" }), THEME_OPTIONS.map(option => (_jsx(Menu.Item, { active: theme === option.value, children: _jsxs("button", { onClick: () => {
|
|
@@ -6,9 +6,10 @@ export type ToastActionConfig = {
|
|
|
6
6
|
};
|
|
7
7
|
export type ToastProps = {
|
|
8
8
|
title?: ReactNode;
|
|
9
|
+
subheader?: ReactNode;
|
|
9
10
|
message?: ReactNode;
|
|
10
11
|
severity: Severity;
|
|
11
12
|
action?: ToastActionConfig;
|
|
12
13
|
onClose?: () => void;
|
|
13
14
|
};
|
|
14
|
-
export declare function Toast({ title, message, severity, action, onClose, }: ToastProps): React.ReactNode;
|
|
15
|
+
export declare function Toast({ title, subheader, message, severity, action, onClose, }: ToastProps): React.ReactNode;
|
|
@@ -3,7 +3,7 @@ import { X } from 'lucide-react';
|
|
|
3
3
|
import styles from './Toast.module.css';
|
|
4
4
|
import { Button } from '../button/Button';
|
|
5
5
|
import { Headline } from '../headline/Headline';
|
|
6
|
-
export function Toast({ title, message, severity = 'info', action, onClose, }) {
|
|
6
|
+
export function Toast({ title, subheader, message, severity = 'info', action, onClose, }) {
|
|
7
7
|
const showHeader = Boolean(title);
|
|
8
8
|
const showMessage = Boolean(message);
|
|
9
9
|
const canClose = severity !== 'neutral';
|
|
@@ -16,5 +16,5 @@ export function Toast({ title, message, severity = 'info', action, onClose, }) {
|
|
|
16
16
|
onClose === null || onClose === void 0 ? void 0 : onClose();
|
|
17
17
|
}
|
|
18
18
|
}
|
|
19
|
-
: undefined, tabIndex: isDismissibleNeutral ? 0 : undefined, "aria-label": isDismissibleNeutral ? 'Luk notifikation' : undefined, children: [_jsxs("div", { className: styles.content, children: [showHeader && (_jsxs("div", { className: styles.row, children: [_jsx(Headline, { size: 4, severity: severity, disableMargin: true, children: title }), CloseButton] })), showMessage && (_jsxs("div", { className: styles.row, children: [_jsx("div", { className: styles.message, children: message }), !showHeader && CloseButton] }))] }), action && (_jsx("div", { className: styles.actions, children: _jsx(Button, { type: "button", variant: "primary", onClick: action.onClick, children: action.label }) }))] }));
|
|
19
|
+
: undefined, tabIndex: isDismissibleNeutral ? 0 : undefined, "aria-label": isDismissibleNeutral ? 'Luk notifikation' : undefined, children: [_jsxs("div", { className: styles.content, children: [showHeader && (_jsxs("div", { className: styles.row, children: [_jsx(Headline, { size: 4, severity: severity, disableMargin: true, subheader: subheader, children: title }), CloseButton] })), showMessage && (_jsxs("div", { className: styles.row, children: [_jsx("div", { className: styles.message, children: message }), !showHeader && CloseButton] }))] }), action && (_jsx("div", { className: styles.actions, children: _jsx(Button, { type: "button", variant: "primary", onClick: action.onClick, children: action.label }) }))] }));
|
|
20
20
|
}
|
|
@@ -1,15 +1,11 @@
|
|
|
1
|
-
import { CSSProperties, RefObject } from 'react';
|
|
1
|
+
import { type CSSProperties, type RefObject } from 'react';
|
|
2
2
|
type Options = {
|
|
3
3
|
bottomOffset?: number;
|
|
4
4
|
min?: number;
|
|
5
5
|
includeMarginTop?: boolean;
|
|
6
|
-
/**
|
|
7
|
-
* Optional element to observe in addition to the target itself.
|
|
8
|
-
* Useful when a nearby wrapper changes height and pushes the table.
|
|
9
|
-
*/
|
|
10
6
|
watchRef?: RefObject<HTMLElement | null>;
|
|
11
7
|
};
|
|
12
|
-
export declare function useViewportFill<T extends HTMLElement>(ref: RefObject<T>, { bottomOffset, min, includeMarginTop, watchRef }?: Options): {
|
|
8
|
+
export declare function useViewportFill<T extends HTMLElement>(ref: RefObject<T | null>, { bottomOffset, min, includeMarginTop, watchRef }?: Options): {
|
|
13
9
|
maxHeight: number;
|
|
14
10
|
style: CSSProperties;
|
|
15
11
|
recompute: () => void;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { useCallback, useEffect, useLayoutEffect, useRef, useState, } from 'react';
|
|
2
|
+
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, } from 'react';
|
|
3
3
|
const useIsomorphicLayoutEffect = typeof window !== 'undefined' ? useLayoutEffect : useEffect;
|
|
4
4
|
export function useViewportFill(ref, { bottomOffset = 0, min = 120, includeMarginTop = false, watchRef } = {}) {
|
|
5
5
|
const [maxHeight, setMaxHeight] = useState(min);
|
|
@@ -11,18 +11,22 @@ export function useViewportFill(ref, { bottomOffset = 0, min = 120, includeMargi
|
|
|
11
11
|
const rect = el.getBoundingClientRect();
|
|
12
12
|
let top = rect.top;
|
|
13
13
|
if (includeMarginTop) {
|
|
14
|
-
const
|
|
15
|
-
top -=
|
|
14
|
+
const marginTop = parseFloat(window.getComputedStyle(el).marginTop || '0') || 0;
|
|
15
|
+
top -= marginTop;
|
|
16
16
|
}
|
|
17
17
|
const next = Math.max(min, Math.floor(window.innerHeight - bottomOffset - top));
|
|
18
|
-
setMaxHeight(prev => (prev
|
|
18
|
+
setMaxHeight(prev => (prev === next ? prev : next));
|
|
19
19
|
}, [ref, bottomOffset, min, includeMarginTop]);
|
|
20
20
|
const scheduleMeasure = useCallback(() => {
|
|
21
21
|
if (typeof window === 'undefined')
|
|
22
22
|
return;
|
|
23
|
-
if (raf.current != null)
|
|
23
|
+
if (raf.current != null) {
|
|
24
24
|
cancelAnimationFrame(raf.current);
|
|
25
|
-
|
|
25
|
+
}
|
|
26
|
+
raf.current = window.requestAnimationFrame(() => {
|
|
27
|
+
raf.current = null;
|
|
28
|
+
measure();
|
|
29
|
+
});
|
|
26
30
|
}, [measure]);
|
|
27
31
|
useIsomorphicLayoutEffect(() => {
|
|
28
32
|
measure();
|
|
@@ -34,39 +38,40 @@ export function useViewportFill(ref, { bottomOffset = 0, min = 120, includeMargi
|
|
|
34
38
|
const target = ref.current;
|
|
35
39
|
const extra = (_a = watchRef === null || watchRef === void 0 ? void 0 : watchRef.current) !== null && _a !== void 0 ? _a : null;
|
|
36
40
|
const parent = target.parentElement;
|
|
37
|
-
const
|
|
41
|
+
const onResize = () => scheduleMeasure();
|
|
38
42
|
const onTransitionOrAnimationEnd = () => scheduleMeasure();
|
|
39
|
-
window.addEventListener('resize',
|
|
40
|
-
window.addEventListener('scroll', onResizeOrScroll, { passive: true });
|
|
41
|
-
// Cheap and often enough for collapsible filter panels.
|
|
43
|
+
window.addEventListener('resize', onResize);
|
|
42
44
|
document.addEventListener('transitionend', onTransitionOrAnimationEnd, true);
|
|
43
45
|
document.addEventListener('animationend', onTransitionOrAnimationEnd, true);
|
|
44
|
-
let
|
|
46
|
+
let resizeObserver = null;
|
|
45
47
|
if ('ResizeObserver' in window) {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (parent && parent !== target)
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
48
|
+
resizeObserver = new ResizeObserver(() => scheduleMeasure());
|
|
49
|
+
resizeObserver.observe(target);
|
|
50
|
+
if (parent && parent !== target) {
|
|
51
|
+
resizeObserver.observe(parent);
|
|
52
|
+
}
|
|
53
|
+
if (extra && extra !== target && extra !== parent) {
|
|
54
|
+
resizeObserver.observe(extra);
|
|
55
|
+
}
|
|
52
56
|
}
|
|
53
57
|
return () => {
|
|
54
|
-
window.removeEventListener('resize',
|
|
55
|
-
window.removeEventListener('scroll', onResizeOrScroll);
|
|
58
|
+
window.removeEventListener('resize', onResize);
|
|
56
59
|
document.removeEventListener('transitionend', onTransitionOrAnimationEnd, true);
|
|
57
60
|
document.removeEventListener('animationend', onTransitionOrAnimationEnd, true);
|
|
58
|
-
|
|
61
|
+
resizeObserver === null || resizeObserver === void 0 ? void 0 : resizeObserver.disconnect();
|
|
59
62
|
if (raf.current != null) {
|
|
60
63
|
cancelAnimationFrame(raf.current);
|
|
64
|
+
raf.current = null;
|
|
61
65
|
}
|
|
62
66
|
};
|
|
63
67
|
}, [ref, watchRef, scheduleMeasure]);
|
|
68
|
+
const style = useMemo(() => ({
|
|
69
|
+
maxHeight,
|
|
70
|
+
overflow: 'auto',
|
|
71
|
+
}), [maxHeight]);
|
|
64
72
|
return {
|
|
65
73
|
maxHeight,
|
|
66
|
-
style
|
|
67
|
-
maxHeight,
|
|
68
|
-
overflow: 'auto',
|
|
69
|
-
},
|
|
74
|
+
style,
|
|
70
75
|
recompute: measure,
|
|
71
76
|
};
|
|
72
77
|
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './components/stack/Stack';
|
|
1
2
|
export * from './components/button/Button';
|
|
2
3
|
export * from './components/button-select/ButtonSelect';
|
|
3
4
|
export * from './components/nav-bar/NavBar';
|
|
@@ -8,6 +9,7 @@ export * from './components/icon/Icon';
|
|
|
8
9
|
export * from './components/user-display/UserDisplay';
|
|
9
10
|
export * from './components/tabs/Tabs';
|
|
10
11
|
export * from './components/headline/Headline';
|
|
12
|
+
export * from './components/headline/CollapsibleHeadline';
|
|
11
13
|
export * from './components/page-layout/PageLayout';
|
|
12
14
|
export * from './components/page-layout/components/layout-footer/LayoutFooter';
|
|
13
15
|
export * from './components/forms/input/Input';
|
|
@@ -71,3 +73,6 @@ export * from './components/sticky-footer-layout/StickyFooterLayout';
|
|
|
71
73
|
export * from './components/forms/typeahead/Typeahead';
|
|
72
74
|
export * from './hooks/useDeviceSize';
|
|
73
75
|
export * from './components/theme-button/ThemeButton';
|
|
76
|
+
export * from './components/copy-button/CopyButton';
|
|
77
|
+
export * from './components/divider/Divider';
|
|
78
|
+
export * from './components/grid/Grid';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './components/stack/Stack';
|
|
1
2
|
export * from './components/button/Button';
|
|
2
3
|
export * from './components/button-select/ButtonSelect';
|
|
3
4
|
export * from './components/nav-bar/NavBar';
|
|
@@ -8,6 +9,7 @@ export * from './components/icon/Icon';
|
|
|
8
9
|
export * from './components/user-display/UserDisplay';
|
|
9
10
|
export * from './components/tabs/Tabs';
|
|
10
11
|
export * from './components/headline/Headline';
|
|
12
|
+
export * from './components/headline/CollapsibleHeadline';
|
|
11
13
|
export * from './components/page-layout/PageLayout';
|
|
12
14
|
export * from './components/page-layout/components/layout-footer/LayoutFooter';
|
|
13
15
|
export * from './components/forms/input/Input';
|
|
@@ -71,3 +73,6 @@ export * from './components/sticky-footer-layout/StickyFooterLayout';
|
|
|
71
73
|
export * from './components/forms/typeahead/Typeahead';
|
|
72
74
|
export * from './hooks/useDeviceSize';
|
|
73
75
|
export * from './components/theme-button/ThemeButton';
|
|
76
|
+
export * from './components/copy-button/CopyButton';
|
|
77
|
+
export * from './components/divider/Divider';
|
|
78
|
+
export * from './components/grid/Grid';
|
|
@@ -84,6 +84,18 @@
|
|
|
84
84
|
gap: var(--spacing-xl);
|
|
85
85
|
}
|
|
86
86
|
|
|
87
|
+
.dbc-gap-2xl {
|
|
88
|
+
gap: var(--spacing-2xl);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.dbc-gap-3xl {
|
|
92
|
+
gap: var(--spacing-3xl);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.dbc-gap-4xl {
|
|
96
|
+
gap: var(--spacing-4xl);
|
|
97
|
+
}
|
|
98
|
+
|
|
87
99
|
.dbc-flex-grow {
|
|
88
100
|
flex-grow: 1;
|
|
89
101
|
}
|