@dbcdk/react-components 0.0.15 → 0.0.16
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.
|
@@ -21,6 +21,7 @@ interface ChipMultiToggleProps {
|
|
|
21
21
|
showAllOption?: boolean;
|
|
22
22
|
allLabel?: string;
|
|
23
23
|
allIcon?: React.ReactNode;
|
|
24
|
+
dataCy?: string;
|
|
24
25
|
/**
|
|
25
26
|
* If true, clicking "All" toggles between:
|
|
26
27
|
* - All (no filtering) => []
|
|
@@ -33,5 +34,5 @@ interface ChipMultiToggleProps {
|
|
|
33
34
|
*/
|
|
34
35
|
noneValue?: string;
|
|
35
36
|
}
|
|
36
|
-
export declare function ChipMultiToggle({ label, options, selectedValues, onChange, onToggle, size, selectedSeverity, unselectedSeverity, fullWidth, disabled, showAllOption, allLabel, allIcon, showSelectedIcon, allTogglesNone, noneValue, }: ChipMultiToggleProps): JSX.Element;
|
|
37
|
+
export declare function ChipMultiToggle({ label, options, selectedValues, onChange, onToggle, size, selectedSeverity, unselectedSeverity, fullWidth, disabled, showAllOption, allLabel, allIcon, showSelectedIcon, allTogglesNone, noneValue, dataCy, }: ChipMultiToggleProps): JSX.Element;
|
|
37
38
|
export {};
|
|
@@ -4,7 +4,7 @@ import { Check } from 'lucide-react';
|
|
|
4
4
|
import React from 'react';
|
|
5
5
|
import { Chip } from '../../../components/chip/Chip';
|
|
6
6
|
import styles from './ChipMultiToggle.module.css';
|
|
7
|
-
export function ChipMultiToggle({ label, options, selectedValues = [], onChange, onToggle, size = 'sm', selectedSeverity = 'info', unselectedSeverity = null, fullWidth = false, disabled = false, showAllOption = false, allLabel = 'Alle', allIcon, showSelectedIcon = false, allTogglesNone = false, noneValue = '__none__', }) {
|
|
7
|
+
export function ChipMultiToggle({ label, options, selectedValues = [], onChange, onToggle, size = 'sm', selectedSeverity = 'info', unselectedSeverity = null, fullWidth = false, disabled = false, showAllOption = false, allLabel = 'Alle', allIcon, showSelectedIcon = false, allTogglesNone = false, noneValue = '__none__', dataCy, }) {
|
|
8
8
|
const selectedSet = React.useMemo(() => new Set(selectedValues), [selectedValues]);
|
|
9
9
|
const isNoneSelected = allTogglesNone && selectedSet.has(noneValue);
|
|
10
10
|
const isAllSelected = showAllOption && !isNoneSelected && selectedSet.size === 0;
|
|
@@ -46,7 +46,7 @@ export function ChipMultiToggle({ label, options, selectedValues = [], onChange,
|
|
|
46
46
|
onChange([]);
|
|
47
47
|
}
|
|
48
48
|
};
|
|
49
|
-
return (_jsxs("div", { className: `${styles.wrapper} ${fullWidth ? styles.fullWidth : ''}`, children: [label && _jsx("span", { className: styles.label, children: label }), _jsxs("div", { className: styles.container, children: [showAllOption && (_jsx("button", { type: "button", className: styles.chipButton, onClick: toggleAll, "aria-pressed": isAllSelected || isNoneSelected, disabled: disabled, children: _jsx(Chip, { size: size, severity: (isAllSelected || isNoneSelected ? selectedSeverity : unselectedSeverity), customIcon: allIcon, type: unselectedSeverity === null ? 'outlined' : 'rounded', children: isNoneSelected ? `${allLabel} (ingen)` : allLabel }) }, "__all__")), options.map(opt => {
|
|
49
|
+
return (_jsxs("div", { className: `${styles.wrapper} ${fullWidth ? styles.fullWidth : ''}`, "data-cy": dataCy, children: [label && _jsx("span", { className: styles.label, children: label }), _jsxs("div", { className: styles.container, children: [showAllOption && (_jsx("button", { type: "button", className: styles.chipButton, onClick: toggleAll, "aria-pressed": isAllSelected || isNoneSelected, disabled: disabled, children: _jsx(Chip, { size: size, severity: (isAllSelected || isNoneSelected ? selectedSeverity : unselectedSeverity), customIcon: allIcon, type: unselectedSeverity === null ? 'outlined' : 'rounded', children: isNoneSelected ? `${allLabel} (ingen)` : allLabel }) }, "__all__")), options.map(opt => {
|
|
50
50
|
// If none-state is active, everything else should look unselected
|
|
51
51
|
const isSelected = !isNoneSelected && selectedSet.has(opt.value);
|
|
52
52
|
return (_jsx("button", { type: "button", className: styles.chipButton, onClick: () => toggleValue(opt.value), "aria-pressed": isSelected, disabled: disabled, children: _jsx(Chip, { size: size, severity: (isSelected ? selectedSeverity : unselectedSeverity), customIcon: showSelectedIcon ? isSelected ? _jsx(Check, {}) : null : opt.icon, type: unselectedSeverity === null ? 'outlined' : 'rounded', children: opt.label }) }, opt.value));
|
|
@@ -28,12 +28,24 @@ export function Table({ data, columns, selectedRows, onRowSelect, selectionMode
|
|
|
28
28
|
const nextDir = getNextSortDirection(column.sortable, active, sortDirection !== null && sortDirection !== void 0 ? sortDirection : null);
|
|
29
29
|
onSortChange(column, nextDir);
|
|
30
30
|
};
|
|
31
|
-
return (_jsx("th", { style: getColumnStyle(column.id, columnStyles, column.align, 'middle'), "aria-sort": ariaSort, className: `${styles.th}`, children: _jsxs("div", { className: styles.thInner, children: [column.sortable ? (_jsxs("button", { type: "button", className:
|
|
31
|
+
return (_jsx("th", { style: getColumnStyle(column.id, columnStyles, column.align, 'middle'), "aria-sort": ariaSort, className: `${styles.th}`, children: _jsxs("div", { className: styles.thInner, children: [column.sortable ? (_jsxs("button", { type: "button", className: [
|
|
32
|
+
styles.thButton,
|
|
33
|
+
column.align === 'right' ? styles.thButtonRight : '',
|
|
34
|
+
column.align === 'center' ? styles.thButtonCenter : '',
|
|
35
|
+
].join(' '), onClick: toggleSort, onKeyDown: e => {
|
|
32
36
|
if (shouldToggleOnKey(e.key)) {
|
|
33
37
|
e.preventDefault();
|
|
34
38
|
toggleSort();
|
|
35
39
|
}
|
|
36
|
-
}, children: [_jsx("span", { className:
|
|
40
|
+
}, children: [_jsx("span", { className: [
|
|
41
|
+
styles.thLabel,
|
|
42
|
+
column.align === 'right' ? styles.thLabelRight : '',
|
|
43
|
+
column.align === 'center' ? styles.thLabelCenter : '',
|
|
44
|
+
].join(' '), children: getHeaderLabel(column.header) }), _jsxs("span", { className: styles.sortIndicator, "aria-hidden": "true", children: [active && sortDirection === 'asc' && _jsx(ArrowUp, {}), active && sortDirection === 'desc' && (_jsx(ArrowDown, { className: styles.descending })), !active && (_jsx(ArrowDown, { className: `${styles.descending} ${styles.inActiveSort}` }))] })] })) : (_jsx("span", { className: [
|
|
45
|
+
styles.thLabel,
|
|
46
|
+
column.align === 'right' ? styles.thLabelRight : '',
|
|
47
|
+
column.align === 'center' ? styles.thLabelCenter : '',
|
|
48
|
+
].join(' '), children: getHeaderLabel(column.header) })), headerExtras ? (_jsx("div", { className: styles.thExtras, children: headerExtras({ column, index }) })) : null] }) }, column.id));
|
|
37
49
|
})] }) }), loading && !data.length ? (_jsx("tbody", { className: `${styles.tBody} ${striped ? styles.striped : ''}`, children: Array.from({ length: take !== null && take !== void 0 ? take : 5 }).map((_, rowIndex) => (_jsx("tr", { children: filteredColumns.map((column, colIndex) => (_jsx("td", { style: getColumnStyle(column.id, columnStyles, column.align, 'middle'), className: `${styles.tableCell}`, children: _jsx(SkeletonLoaderItem, { height: 20, width: "100%" }) }, `${column.id}-${colIndex}`))) }, `loading-row-${rowIndex}`))) })) : (_jsx("tbody", { className: `${styles.tBody} ${striped ? styles.striped : ''}`, children: data === null || data === void 0 ? void 0 : data.map(row => {
|
|
38
50
|
const rowSeverity = getRowSeverity === null || getRowSeverity === void 0 ? void 0 : getRowSeverity(row);
|
|
39
51
|
const rowId = row[dataKey];
|
|
@@ -78,57 +78,59 @@
|
|
|
78
78
|
inline-size: 100%;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
|
-
/*
|
|
81
|
+
/* Sort button (full width click target, but content aligns via modifiers) */
|
|
82
82
|
.thButton {
|
|
83
83
|
all: unset;
|
|
84
|
-
display:
|
|
84
|
+
display: flex;
|
|
85
85
|
align-items: center;
|
|
86
86
|
gap: var(--spacing-xxs);
|
|
87
87
|
inline-size: 100%;
|
|
88
88
|
cursor: pointer;
|
|
89
89
|
user-select: none;
|
|
90
|
-
/* make it feel like a button */
|
|
91
90
|
border-radius: var(--border-radius-default);
|
|
92
91
|
padding-block: 2px;
|
|
93
92
|
padding-inline: 2px;
|
|
93
|
+
|
|
94
|
+
/* default */
|
|
95
|
+
justify-content: flex-start;
|
|
94
96
|
}
|
|
95
97
|
|
|
96
|
-
|
|
98
|
+
/* IMPORTANT: use consistent PascalCase suffixes */
|
|
99
|
+
.thButtonRight {
|
|
97
100
|
justify-content: flex-end;
|
|
98
101
|
}
|
|
99
102
|
|
|
100
|
-
.
|
|
103
|
+
.thButtonCenter {
|
|
101
104
|
justify-content: center;
|
|
102
105
|
}
|
|
103
106
|
|
|
104
|
-
|
|
105
|
-
color: var(--color-fg-default);
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
.thButton:focus-visible {
|
|
109
|
-
outline: none;
|
|
110
|
-
box-shadow: var(--focus-ring);
|
|
111
|
-
}
|
|
112
|
-
|
|
107
|
+
/* Label should NOT grow to fill space (it breaks alignment) */
|
|
113
108
|
.thLabel {
|
|
114
109
|
overflow: hidden;
|
|
115
110
|
text-overflow: ellipsis;
|
|
116
111
|
white-space: nowrap;
|
|
112
|
+
flex: 0 1 auto;
|
|
113
|
+
min-width: 0;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/* Match label text alignment to column alignment */
|
|
117
|
+
.thLabelRight {
|
|
118
|
+
text-align: right;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.thLabelCenter {
|
|
122
|
+
text-align: center;
|
|
117
123
|
}
|
|
118
124
|
|
|
119
125
|
.thExtras {
|
|
120
|
-
margin-inline-start: auto;
|
|
121
126
|
display: inline-flex;
|
|
122
127
|
align-items: center;
|
|
123
128
|
}
|
|
124
129
|
|
|
125
|
-
.inActiveSort {
|
|
126
|
-
color: var(--color-fg-subtle);
|
|
127
|
-
opacity: 0.4;
|
|
128
|
-
}
|
|
129
|
-
|
|
130
130
|
.sortIndicator {
|
|
131
|
-
display: flex;
|
|
131
|
+
display: inline-flex;
|
|
132
|
+
flex: 0 0 auto;
|
|
133
|
+
align-items: center;
|
|
132
134
|
}
|
|
133
135
|
|
|
134
136
|
.sortIndicator svg {
|