@dbcdk/react-components 0.0.59 → 0.0.61
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/filter-field/FilterField.d.ts +2 -1
- package/dist/components/filter-field/FilterField.js +16 -5
- package/dist/components/filter-field/FilterField.module.css +88 -37
- package/dist/components/forms/input/Input.js +8 -5
- package/dist/components/forms/input/Input.module.css +24 -3
- package/dist/components/forms/select/Select.js +3 -1
- package/dist/components/forms/typeahead/Typeahead.d.ts +3 -1
- package/dist/components/forms/typeahead/Typeahead.js +207 -56
- package/dist/components/forms/typeahead/Typeahead.module.css +31 -0
- package/dist/components/interval-select/IntervalSelect.js +3 -1
- package/dist/components/pagination/Pagination.module.css +1 -1
- package/dist/components/popover/Popover.d.ts +1 -8
- package/dist/components/popover/Popover.js +17 -13
- package/dist/components/popover/Popover.module.css +27 -2
- package/dist/components/split-pane/provider/SplitPaneContext.d.ts +1 -1
- package/dist/components/table/tanstackTable.utils.js +12 -12
- package/dist/components/toast/Toast.module.css +1 -1
- package/dist/hooks/useTimeDuration.js +8 -1
- package/package.json +18 -20
|
@@ -27,10 +27,11 @@ export interface FilterFieldProps extends Omit<React.InputHTMLAttributes<HTMLInp
|
|
|
27
27
|
minWidth?: string;
|
|
28
28
|
width?: string;
|
|
29
29
|
maxWidth?: string;
|
|
30
|
+
popoverWidth?: string;
|
|
30
31
|
debounceTime?: number;
|
|
31
32
|
}
|
|
32
33
|
export declare const NUMBER_OPERATORS: Operator[];
|
|
33
|
-
export declare function FilterField({ field, control, operator, value, onChange, operators, options, single, size, variant, label, placeholder, disabled, 'data-cy': dataCy, minWidth, width, maxWidth, debounceTime, ...inputProps }: FilterFieldProps & {
|
|
34
|
+
export declare function FilterField({ field, control, operator, value, onChange, operators, options, single, size, variant, label, placeholder, disabled, 'data-cy': dataCy, minWidth, width, maxWidth, popoverWidth, debounceTime, ...inputProps }: FilterFieldProps & {
|
|
34
35
|
'data-cy'?: string;
|
|
35
36
|
}): React.ReactElement;
|
|
36
37
|
export {};
|
|
@@ -69,14 +69,18 @@ function isFilterActive(value) {
|
|
|
69
69
|
return value.trim().length > 0;
|
|
70
70
|
return value != null;
|
|
71
71
|
}
|
|
72
|
-
export function FilterField({ field, control, operator, value, onChange, operators, options = [], single = true, size = 'md', variant = 'surface', label, placeholder = 'Type value…', disabled, 'data-cy': dataCy, minWidth, width, maxWidth, debounceTime = INPUT_DEBOUNCE_MS, ...inputProps }) {
|
|
72
|
+
export function FilterField({ field, control, operator, value, onChange, operators, options = [], single = true, size = 'md', variant = 'surface', label, placeholder = 'Type value…', disabled, 'data-cy': dataCy, minWidth, width, maxWidth, popoverWidth, debounceTime = INPUT_DEBOUNCE_MS, ...inputProps }) {
|
|
73
73
|
var _a, _b, _c, _d, _e, _f;
|
|
74
74
|
const filterFieldRef = useRef(null);
|
|
75
75
|
const ops = useMemo(() => operators !== null && operators !== void 0 ? operators : DEFAULT_TEXT_OPERATORS, [operators]);
|
|
76
|
+
const shouldAutoFitTypeahead = control === 'select' && single && !width;
|
|
76
77
|
const [selectedOperator, setSelectedOperator] = useState(operator);
|
|
77
78
|
const active = isFilterActive(value);
|
|
78
79
|
useEffect(() => {
|
|
79
80
|
if (ops.includes(operator)) {
|
|
81
|
+
// Keep the dropdown responsive to local selection immediately, but let the
|
|
82
|
+
// controlled `operator` prop take back over once parent state catches up.
|
|
83
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
80
84
|
setSelectedOperator(operator);
|
|
81
85
|
}
|
|
82
86
|
}, [operator, ops]);
|
|
@@ -149,6 +153,9 @@ export function FilterField({ field, control, operator, value, onChange, operato
|
|
|
149
153
|
return;
|
|
150
154
|
}
|
|
151
155
|
if (incoming !== localValue) {
|
|
156
|
+
// Keep the embedded input responsive while debounced updates are in flight,
|
|
157
|
+
// then resync to the controlled value once external state has settled.
|
|
158
|
+
// eslint-disable-next-line react-hooks/set-state-in-effect
|
|
152
159
|
setLocalValue(incoming);
|
|
153
160
|
}
|
|
154
161
|
}, [value, control, localValue]);
|
|
@@ -159,9 +166,13 @@ export function FilterField({ field, control, operator, value, onChange, operato
|
|
|
159
166
|
}, []);
|
|
160
167
|
return (_jsxs("div", { ref: filterFieldRef, ...(dataCy ? { 'data-cy': dataCy } : {}), className: [styles.filterField, styles[size], styles[variant], active ? styles.active : '']
|
|
161
168
|
.filter(Boolean)
|
|
162
|
-
.join(' '), children: [label ? _jsx("span", { className: `${styles.label} ${styles[size]}`, children: label }) : null, _jsx(OperatorDropdown, { value: selectedOperator, onChange: handleOperatorChange, operators: ops, size: size, disabled: disabled }), _jsx("div", { className: [
|
|
169
|
+
.join(' '), children: [label ? _jsx("span", { className: `${styles.label} ${styles[size]}`, children: label }) : null, _jsx("div", { className: styles.operatorWrapper, children: _jsx(OperatorDropdown, { value: selectedOperator, onChange: handleOperatorChange, operators: ops, size: size, disabled: disabled }) }), _jsx("div", { className: [
|
|
170
|
+
styles.valueWrapper,
|
|
171
|
+
control === 'input' ? 'dbc-flex dbc-flex-grow' : '',
|
|
172
|
+
shouldAutoFitTypeahead ? styles.autoWidth : '',
|
|
173
|
+
]
|
|
163
174
|
.filter(Boolean)
|
|
164
|
-
.join(' '), style: { width, maxWidth }, children: control === 'input' ? (_jsx(Input, { variant: "embedded", ...inputProps, fieldClassName: styles.embeddedInputField, inputClassName: styles.embeddedInputElement, value: localValue, onChange: e => {
|
|
175
|
+
.join(' '), style: shouldAutoFitTypeahead ? (maxWidth ? { maxWidth } : undefined) : { width, maxWidth }, children: control === 'input' ? (_jsx(Input, { variant: "embedded", ...inputProps, fieldClassName: styles.embeddedInputField, inputClassName: styles.embeddedInputElement, value: localValue, onChange: e => {
|
|
165
176
|
const next = e.currentTarget.value;
|
|
166
177
|
setLocalValue(next);
|
|
167
178
|
scheduleEmitValue(next);
|
|
@@ -172,9 +183,9 @@ export function FilterField({ field, control, operator, value, onChange, operato
|
|
|
172
183
|
pendingValueRef.current = '';
|
|
173
184
|
setLocalValue('');
|
|
174
185
|
emit({ value: '' });
|
|
175
|
-
} })) : (_jsx(Typeahead, { options: options, mode: single ? 'single' : 'multi', selectedValue: single ? ((_f = value) !== null && _f !== void 0 ? _f : null) : Array.isArray(value) ? value : [], onChange: v => emit({ value: v }), minWidth: minWidth, popoverAnchorRef: filterFieldRef, placeholder: placeholder, variant: "embedded", inputProps: {
|
|
186
|
+
} })) : (_jsx(Typeahead, { options: options, mode: single ? 'single' : 'multi', selectedValue: single ? ((_f = value) !== null && _f !== void 0 ? _f : null) : Array.isArray(value) ? value : [], onChange: v => emit({ value: v }), minWidth: minWidth, popoverWidth: popoverWidth, popoverAnchorRef: filterFieldRef, placeholder: placeholder, variant: "embedded", inputProps: {
|
|
176
187
|
inputSize: size,
|
|
177
188
|
fieldClassName: styles.embeddedInputField,
|
|
178
189
|
inputClassName: styles.embeddedInputElement,
|
|
179
|
-
}, onClear: () => emit({ value: single ? '' : [] }), disabled: disabled, fullWidth:
|
|
190
|
+
}, onClear: () => emit({ value: single ? '' : [] }), disabled: disabled, fullWidth: !shouldAutoFitTypeahead, fitContent: shouldAutoFitTypeahead })) })] }));
|
|
180
191
|
}
|
|
@@ -34,8 +34,14 @@
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
.filterField.surface.active {
|
|
37
|
-
|
|
37
|
+
background: color-mix(in srgb, var(--color-bg-selected) 45%, var(--color-bg-surface));
|
|
38
|
+
border-color: var(--color-border-selected);
|
|
38
39
|
box-shadow: var(--shadow-sm);
|
|
40
|
+
--filter-operator-bg: color-mix(
|
|
41
|
+
in srgb,
|
|
42
|
+
var(--color-bg-selected) 45%,
|
|
43
|
+
var(--color-bg-surface)
|
|
44
|
+
);
|
|
39
45
|
}
|
|
40
46
|
|
|
41
47
|
.filterField.outlined {
|
|
@@ -50,7 +56,14 @@
|
|
|
50
56
|
}
|
|
51
57
|
|
|
52
58
|
.filterField.outlined.active {
|
|
53
|
-
|
|
59
|
+
background: color-mix(in srgb, var(--color-bg-selected) 38%, var(--color-bg-surface));
|
|
60
|
+
border-color: var(--color-border-selected);
|
|
61
|
+
box-shadow: none;
|
|
62
|
+
--filter-operator-bg: color-mix(
|
|
63
|
+
in srgb,
|
|
64
|
+
var(--color-bg-selected) 38%,
|
|
65
|
+
var(--color-bg-surface)
|
|
66
|
+
);
|
|
54
67
|
}
|
|
55
68
|
|
|
56
69
|
.filterField.subtle {
|
|
@@ -70,34 +83,22 @@
|
|
|
70
83
|
}
|
|
71
84
|
|
|
72
85
|
.filterField.subtle.active {
|
|
73
|
-
background:
|
|
86
|
+
background: color-mix(
|
|
87
|
+
in srgb,
|
|
88
|
+
var(--color-bg-selected) 55%,
|
|
89
|
+
var(--color-bg-surface-strong)
|
|
90
|
+
);
|
|
91
|
+
border-color: var(--color-border-selected);
|
|
92
|
+
box-shadow: inset 0 0 0 1px transparent;
|
|
74
93
|
--filter-operator-bg: color-mix(
|
|
75
94
|
in srgb,
|
|
76
|
-
var(--color-
|
|
95
|
+
var(--color-bg-selected) 55%,
|
|
77
96
|
var(--color-bg-surface-strong)
|
|
78
97
|
);
|
|
79
98
|
}
|
|
80
99
|
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
========================= */
|
|
84
|
-
|
|
85
|
-
.filterField.active::before {
|
|
86
|
-
content: '';
|
|
87
|
-
position: absolute;
|
|
88
|
-
inset-inline-start: 0;
|
|
89
|
-
top: 0;
|
|
90
|
-
bottom: 0;
|
|
91
|
-
width: 3px;
|
|
92
|
-
border-top-left-radius: inherit;
|
|
93
|
-
border-bottom-left-radius: inherit;
|
|
94
|
-
background: var(--color-border-selected);
|
|
95
|
-
pointer-events: none;
|
|
96
|
-
z-index: 2;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
.filterField.outlined.active::before {
|
|
100
|
-
width: 3px;
|
|
100
|
+
.filterField.active .label {
|
|
101
|
+
color: var(--color-fg-default);
|
|
101
102
|
}
|
|
102
103
|
|
|
103
104
|
/* =========================
|
|
@@ -114,7 +115,6 @@
|
|
|
114
115
|
border-color: var(--color-border-selected);
|
|
115
116
|
}
|
|
116
117
|
|
|
117
|
-
/* subtle focus without inner outline */
|
|
118
118
|
.filterField.surface:focus-within {
|
|
119
119
|
box-shadow: var(--shadow-sm);
|
|
120
120
|
}
|
|
@@ -124,17 +124,13 @@
|
|
|
124
124
|
box-shadow: none;
|
|
125
125
|
}
|
|
126
126
|
|
|
127
|
-
/* stronger focus when filter is active */
|
|
128
|
-
|
|
129
127
|
.filterField.surface.active:focus-within {
|
|
130
|
-
box-shadow:
|
|
131
|
-
var(--shadow-sm),
|
|
132
|
-
inset 0 0 0 1px var(--color-border-selected);
|
|
128
|
+
box-shadow: var(--shadow-sm);
|
|
133
129
|
}
|
|
134
130
|
|
|
135
131
|
.filterField.outlined.active:focus-within,
|
|
136
132
|
.filterField.subtle.active:focus-within {
|
|
137
|
-
box-shadow:
|
|
133
|
+
box-shadow: none;
|
|
138
134
|
}
|
|
139
135
|
|
|
140
136
|
/* =========================
|
|
@@ -173,6 +169,13 @@
|
|
|
173
169
|
OPERATOR
|
|
174
170
|
========================= */
|
|
175
171
|
|
|
172
|
+
.filterField .operatorWrapper {
|
|
173
|
+
flex: 0 0 auto;
|
|
174
|
+
display: flex;
|
|
175
|
+
align-items: stretch;
|
|
176
|
+
min-width: 0;
|
|
177
|
+
}
|
|
178
|
+
|
|
176
179
|
.filterField .operatorTrigger {
|
|
177
180
|
display: inline-flex;
|
|
178
181
|
align-items: center;
|
|
@@ -192,10 +195,10 @@
|
|
|
192
195
|
transition:
|
|
193
196
|
background-color var(--transition-fast) var(--ease-standard),
|
|
194
197
|
color var(--transition-fast) var(--ease-standard);
|
|
198
|
+
flex: 0 0 auto;
|
|
199
|
+
white-space: nowrap;
|
|
195
200
|
}
|
|
196
201
|
|
|
197
|
-
/* inset operator background */
|
|
198
|
-
|
|
199
202
|
.filterField .operatorTrigger::after {
|
|
200
203
|
content: '';
|
|
201
204
|
position: absolute;
|
|
@@ -221,6 +224,7 @@
|
|
|
221
224
|
var(--filter-operator-bg, transparent)
|
|
222
225
|
);
|
|
223
226
|
}
|
|
227
|
+
|
|
224
228
|
/* =========================
|
|
225
229
|
SEPARATORS
|
|
226
230
|
========================= */
|
|
@@ -262,7 +266,9 @@
|
|
|
262
266
|
.operatorTrigger svg {
|
|
263
267
|
height: var(--component-size-xxs);
|
|
264
268
|
width: var(--component-size-xxs);
|
|
269
|
+
flex: 0 0 auto;
|
|
265
270
|
}
|
|
271
|
+
|
|
266
272
|
/* =========================
|
|
267
273
|
VALUE WRAPPER
|
|
268
274
|
========================= */
|
|
@@ -272,14 +278,14 @@
|
|
|
272
278
|
align-items: center;
|
|
273
279
|
padding: 0;
|
|
274
280
|
height: 100%;
|
|
275
|
-
flex: 1;
|
|
281
|
+
flex: 1 1 auto;
|
|
276
282
|
min-width: 0;
|
|
277
283
|
position: relative;
|
|
278
284
|
}
|
|
279
285
|
|
|
286
|
+
/* Base child sizing */
|
|
280
287
|
.filterField .valueWrapper > * {
|
|
281
288
|
height: 100%;
|
|
282
|
-
width: 100%;
|
|
283
289
|
min-width: 0;
|
|
284
290
|
}
|
|
285
291
|
|
|
@@ -287,10 +293,42 @@
|
|
|
287
293
|
display: flex;
|
|
288
294
|
align-items: center;
|
|
289
295
|
height: 100%;
|
|
296
|
+
min-width: 0;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/* Fill mode: regular inputs should stretch */
|
|
300
|
+
.filterField .valueWrapper:not(.autoWidth) > * {
|
|
301
|
+
width: 100%;
|
|
302
|
+
flex: 1 1 auto;
|
|
303
|
+
}
|
|
304
|
+
|
|
305
|
+
.filterField .valueWrapper:not(.autoWidth) > div {
|
|
290
306
|
width: 100%;
|
|
307
|
+
flex: 1 1 auto;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/* Auto-width mode: let Typeahead keep its measured width */
|
|
311
|
+
.filterField .valueWrapper.autoWidth {
|
|
312
|
+
flex: 1 1 auto;
|
|
313
|
+
width: auto;
|
|
291
314
|
min-width: 0;
|
|
292
315
|
}
|
|
293
316
|
|
|
317
|
+
.filterField .valueWrapper.autoWidth > * {
|
|
318
|
+
width: auto;
|
|
319
|
+
flex: 1 1 auto;
|
|
320
|
+
min-width: 0;
|
|
321
|
+
max-width: 100%;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.filterField .valueWrapper.autoWidth > div {
|
|
325
|
+
width: auto;
|
|
326
|
+
flex: 1 1 auto;
|
|
327
|
+
min-width: 0;
|
|
328
|
+
max-width: 100%;
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
/* Embedded Input internals */
|
|
294
332
|
.filterField .valueWrapper .field {
|
|
295
333
|
min-height: unset;
|
|
296
334
|
height: 100%;
|
|
@@ -298,13 +336,23 @@
|
|
|
298
336
|
box-shadow: none;
|
|
299
337
|
border: none;
|
|
300
338
|
background: transparent;
|
|
339
|
+
min-width: 0;
|
|
340
|
+
width: 100%;
|
|
341
|
+
flex: 1 1 auto;
|
|
301
342
|
}
|
|
302
343
|
|
|
344
|
+
/* Keep a small breathing space inside the filter row */
|
|
303
345
|
.embeddedInputField {
|
|
304
|
-
|
|
346
|
+
min-width: 0;
|
|
347
|
+
width: 100%;
|
|
348
|
+
flex: 1 1 auto;
|
|
305
349
|
}
|
|
306
350
|
|
|
307
351
|
.embeddedInputElement {
|
|
352
|
+
flex: 1 1 auto;
|
|
353
|
+
inline-size: 100%;
|
|
354
|
+
width: 100%;
|
|
355
|
+
min-width: 0;
|
|
308
356
|
height: 100%;
|
|
309
357
|
block-size: 100%;
|
|
310
358
|
min-height: unset;
|
|
@@ -313,12 +361,14 @@
|
|
|
313
361
|
box-shadow: none;
|
|
314
362
|
padding-block: 0;
|
|
315
363
|
padding-inline: 0;
|
|
316
|
-
padding-inline-start: 0;
|
|
317
364
|
margin: 0;
|
|
365
|
+
box-sizing: border-box;
|
|
318
366
|
}
|
|
367
|
+
|
|
319
368
|
.filterField .valueWrapper .startAdornment {
|
|
320
369
|
margin-left: 0;
|
|
321
370
|
gap: 2px;
|
|
371
|
+
min-width: 0;
|
|
322
372
|
}
|
|
323
373
|
|
|
324
374
|
/* =========================
|
|
@@ -333,6 +383,7 @@
|
|
|
333
383
|
|
|
334
384
|
.filterField input {
|
|
335
385
|
height: 100%;
|
|
386
|
+
min-width: 0;
|
|
336
387
|
}
|
|
337
388
|
|
|
338
389
|
.filterField input::placeholder {
|
|
@@ -28,8 +28,11 @@ export const Input = forwardRef(function Input({ label, error, helpText, orienta
|
|
|
28
28
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
29
29
|
}, [autoFocus]);
|
|
30
30
|
const hasButton = Boolean(onButtonClick || buttonLabel || buttonIcon);
|
|
31
|
-
const
|
|
32
|
-
const
|
|
31
|
+
const hasValue = Boolean(inputProps.value);
|
|
32
|
+
const hasVisibleClear = Boolean(onClear && hasValue);
|
|
33
|
+
const hasEndAdornment = Boolean(endAdornment);
|
|
34
|
+
const reservesInlineClearSlot = Boolean(onClear);
|
|
35
|
+
const hasInlineClear = Boolean(hasVisibleClear && hasEndAdornment);
|
|
33
36
|
const rootStyle = {
|
|
34
37
|
...(style !== null && style !== void 0 ? style : {}),
|
|
35
38
|
...(minWidth ? { ['--input-min-width']: minWidth } : null),
|
|
@@ -45,7 +48,7 @@ export const Input = forwardRef(function Input({ label, error, helpText, orienta
|
|
|
45
48
|
return (_jsx(InputContainer, { label: label, htmlFor: inputId, fullWidth: fullWidth, error: error, helpText: helpText, orientation: orientation, labelWidth: labelWidth, required: required, modified: modified, children: _jsxs("div", { style: rootStyle, className: [
|
|
46
49
|
styles.container,
|
|
47
50
|
fullWidth ? styles.fullWidth : '',
|
|
48
|
-
|
|
51
|
+
onClear ? styles.withClear : '',
|
|
49
52
|
hasInlineClear ? styles.withInlineClear : '',
|
|
50
53
|
hasButton ? styles.withButton : '',
|
|
51
54
|
className !== null && className !== void 0 ? className : '',
|
|
@@ -60,8 +63,8 @@ export const Input = forwardRef(function Input({ label, error, helpText, orienta
|
|
|
60
63
|
fieldClassName !== null && fieldClassName !== void 0 ? fieldClassName : '',
|
|
61
64
|
]
|
|
62
65
|
.filter(Boolean)
|
|
63
|
-
.join(' '), "data-forminput": "field", "data-modified": modified ? 'true' : undefined, "aria-disabled": inputProps.disabled ? 'true' : undefined, ...(tooltip ? triggerProps : {}), children: [icon && _jsx("span", { className: styles.icon, children: icon }), startAdornment && _jsx("span", { className: styles.startAdornment, children: startAdornment }), _jsx("input", { ...inputProps, id: inputId, ref: mergeRefs(inputRef, ref), className: [styles.input, inputSize ? styles[inputSize] : '', inputClassName !== null && inputClassName !== void 0 ? inputClassName : '']
|
|
66
|
+
.join(' '), "data-forminput": "field", "data-modified": modified ? 'true' : undefined, "aria-disabled": inputProps.disabled ? 'true' : undefined, ...(tooltip ? triggerProps : {}), children: [icon && (_jsx("span", { className: styles.icon, "data-input-role": "icon", children: icon })), startAdornment && (_jsx("span", { className: styles.startAdornment, "data-input-role": "start-adornment", children: startAdornment })), _jsx("input", { ...inputProps, id: inputId, ref: mergeRefs(inputRef, ref), className: [styles.input, inputSize ? styles[inputSize] : '', inputClassName !== null && inputClassName !== void 0 ? inputClassName : '']
|
|
64
67
|
.filter(Boolean)
|
|
65
|
-
.join(' ') }), (
|
|
68
|
+
.join(' ') }), (reservesInlineClearSlot || hasEndAdornment) && (_jsxs("span", { className: styles.endAdornment, "data-input-role": "end-adornment", children: [reservesInlineClearSlot ? (_jsx("span", { className: styles.clearSlot, "aria-hidden": hasVisibleClear ? undefined : 'true', children: hasVisibleClear && onClear ? _jsx(ClearButton, { onClick: onClear }) : null })) : null, endAdornment] })), hasVisibleClear && !hasEndAdornment && onClear ? (_jsx(ClearButton, { onClick: onClear, absolute: true })) : null] }), hasButton && (_jsxs(Button, { onClick: onButtonClick, className: styles.trailingButton, type: "button", variant: trailingButtonVariant, size: inputSize, children: [buttonIcon !== null && buttonIcon !== void 0 ? buttonIcon : null, buttonLabel !== null && buttonLabel !== void 0 ? buttonLabel : null] }))] }) }));
|
|
66
69
|
});
|
|
67
70
|
Input.displayName = 'Input';
|
|
@@ -73,12 +73,19 @@
|
|
|
73
73
|
border-bottom-right-radius: 0;
|
|
74
74
|
}
|
|
75
75
|
|
|
76
|
+
/*
|
|
77
|
+
When onClear exists, do not keep extra inline-end padding on the input itself.
|
|
78
|
+
The clear affordance already reserves the needed space via:
|
|
79
|
+
- the inline clearSlot inside endAdornment, or
|
|
80
|
+
- the absolute clear button path.
|
|
81
|
+
*/
|
|
76
82
|
.withClear .input {
|
|
77
|
-
padding-inline-end:
|
|
83
|
+
padding-inline-end: 0;
|
|
78
84
|
}
|
|
79
85
|
|
|
86
|
+
/* When clear is inline with other end adornments, keep the input tight as well. */
|
|
80
87
|
.withInlineClear .input {
|
|
81
|
-
padding-inline-end:
|
|
88
|
+
padding-inline-end: 0;
|
|
82
89
|
}
|
|
83
90
|
|
|
84
91
|
/* Global focus reset - variants own visible focus treatment */
|
|
@@ -308,7 +315,10 @@
|
|
|
308
315
|
.xs {
|
|
309
316
|
block-size: var(--component-size-xs);
|
|
310
317
|
font-size: var(--font-size-xs);
|
|
311
|
-
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
.input.xs {
|
|
321
|
+
padding-inline: var(--spacing-xxs);
|
|
312
322
|
}
|
|
313
323
|
|
|
314
324
|
.sm {
|
|
@@ -399,6 +409,17 @@
|
|
|
399
409
|
.endAdornment {
|
|
400
410
|
display: flex;
|
|
401
411
|
align-items: center;
|
|
412
|
+
flex: 0 0 auto;
|
|
413
|
+
gap: 2px;
|
|
414
|
+
margin-inline-start: auto;
|
|
402
415
|
margin-right: var(--spacing-xxs);
|
|
403
416
|
color: var(--color-fg-subtle);
|
|
404
417
|
}
|
|
418
|
+
|
|
419
|
+
.clearSlot {
|
|
420
|
+
display: inline-flex;
|
|
421
|
+
align-items: center;
|
|
422
|
+
justify-content: center;
|
|
423
|
+
min-inline-size: calc(16px + (var(--spacing-xxs) * 2));
|
|
424
|
+
min-block-size: calc(16px + (var(--spacing-xxs) * 2));
|
|
425
|
+
}
|
|
@@ -173,7 +173,9 @@ export function Select({ label, error, helpText, orientation = 'vertical', label
|
|
|
173
173
|
? (selectedValue === null || selectedValue === void 0 ? void 0 : selectedValue[datakey]) === opt.value[datakey]
|
|
174
174
|
: opt.value === selectedValue;
|
|
175
175
|
const isActive = index === activeIndex;
|
|
176
|
-
return (_jsx(Menu.Item, { active: isActive, itemRole: "option", "aria-selected": isSelected, children: _jsxs("button", { ref: el =>
|
|
176
|
+
return (_jsx(Menu.Item, { active: isActive, itemRole: "option", "aria-selected": isSelected, children: _jsxs("button", { ref: el => {
|
|
177
|
+
optionRefs.current[index] = el;
|
|
178
|
+
}, type: "button", tabIndex: isActive ? 0 : -1, onClick: () => {
|
|
177
179
|
var _a;
|
|
178
180
|
onChange(opt.value);
|
|
179
181
|
(_a = popoverRef.current) === null || _a === void 0 ? void 0 : _a.close();
|
|
@@ -26,11 +26,13 @@ interface TypeaheadProps<T> {
|
|
|
26
26
|
inputSize?: InputProps['inputSize'];
|
|
27
27
|
width?: InputProps['width'];
|
|
28
28
|
minWidth?: string;
|
|
29
|
+
popoverWidth?: string;
|
|
29
30
|
autoComplete?: InputProps['autoComplete'];
|
|
30
31
|
autoCorrect?: InputProps['autoCorrect'];
|
|
31
32
|
autoCapitalize?: InputProps['autoCapitalize'];
|
|
32
33
|
spellCheck?: InputProps['spellCheck'];
|
|
33
34
|
popoverAnchorRef?: React.RefObject<HTMLElement | null>;
|
|
35
|
+
fitContent?: boolean;
|
|
34
36
|
}
|
|
35
|
-
export declare function Typeahead<T extends string | number>({ options, mode, multiValueDisplayMode, multiSelectedValuesDisplayMode, multiSelectedValueChipContent, selectedValue, onChange, placeholder, variant, disabled, fullWidth, onClear, emptyMessage, filterOptions, inputProps, inputSize, width, minWidth, autoComplete, autoCorrect, autoCapitalize, spellCheck, popoverAnchorRef, }: TypeaheadProps<T>): React.ReactElement;
|
|
37
|
+
export declare function Typeahead<T extends string | number>({ options, mode, multiValueDisplayMode, multiSelectedValuesDisplayMode, multiSelectedValueChipContent, selectedValue, onChange, placeholder, variant, disabled, fullWidth, onClear, emptyMessage, filterOptions, inputProps, inputSize, width, minWidth, popoverWidth, autoComplete, autoCorrect, autoCapitalize, spellCheck, popoverAnchorRef, fitContent, }: TypeaheadProps<T>): React.ReactElement;
|
|
36
38
|
export {};
|
|
@@ -1,14 +1,93 @@
|
|
|
1
1
|
'use client';
|
|
2
2
|
import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
3
3
|
import * as React from 'react';
|
|
4
|
-
import { useEffect, useId, useMemo, useRef, useState } from 'react';
|
|
4
|
+
import { useEffect, useId, useLayoutEffect, useMemo, useRef, useState } from 'react';
|
|
5
5
|
import { Chip } from '../../../components/chip/Chip';
|
|
6
6
|
import { Input } from '../../../components/forms/input/Input';
|
|
7
7
|
import { Menu } from '../../../components/menu/Menu';
|
|
8
8
|
import { Popover } from '../../../components/popover/Popover';
|
|
9
9
|
import styles from './Typeahead.module.css';
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
function parseLengthToPx(value, referenceFontSize = 16) {
|
|
11
|
+
if (!value)
|
|
12
|
+
return 0;
|
|
13
|
+
const trimmed = value.trim();
|
|
14
|
+
if (!trimmed)
|
|
15
|
+
return 0;
|
|
16
|
+
if (trimmed.endsWith('px')) {
|
|
17
|
+
const n = Number.parseFloat(trimmed);
|
|
18
|
+
return Number.isFinite(n) ? n : 0;
|
|
19
|
+
}
|
|
20
|
+
if (trimmed.endsWith('rem')) {
|
|
21
|
+
const n = Number.parseFloat(trimmed);
|
|
22
|
+
if (!Number.isFinite(n))
|
|
23
|
+
return 0;
|
|
24
|
+
const rootFont = Number.parseFloat(getComputedStyle(document.documentElement).fontSize || '16');
|
|
25
|
+
return n * (Number.isFinite(rootFont) ? rootFont : 16);
|
|
26
|
+
}
|
|
27
|
+
if (trimmed.endsWith('em')) {
|
|
28
|
+
const n = Number.parseFloat(trimmed);
|
|
29
|
+
return Number.isFinite(n) ? n * referenceFontSize : 0;
|
|
30
|
+
}
|
|
31
|
+
const n = Number.parseFloat(trimmed);
|
|
32
|
+
return Number.isFinite(n) ? n : 0;
|
|
33
|
+
}
|
|
34
|
+
function getOuterWidthWithMargins(element) {
|
|
35
|
+
if (!(element instanceof HTMLElement))
|
|
36
|
+
return 0;
|
|
37
|
+
const rect = element.getBoundingClientRect();
|
|
38
|
+
const styles = window.getComputedStyle(element);
|
|
39
|
+
const marginLeft = Number.parseFloat(styles.marginLeft || '0');
|
|
40
|
+
const marginRight = Number.parseFloat(styles.marginRight || '0');
|
|
41
|
+
return Math.ceil(rect.width + marginLeft + marginRight);
|
|
42
|
+
}
|
|
43
|
+
function getInputFontShorthand(inputStyles) {
|
|
44
|
+
return (inputStyles.font ||
|
|
45
|
+
[
|
|
46
|
+
inputStyles.fontStyle,
|
|
47
|
+
inputStyles.fontVariant,
|
|
48
|
+
inputStyles.fontWeight,
|
|
49
|
+
inputStyles.fontStretch,
|
|
50
|
+
inputStyles.fontSize,
|
|
51
|
+
inputStyles.lineHeight !== 'normal' ? `/${inputStyles.lineHeight}` : '',
|
|
52
|
+
inputStyles.fontFamily,
|
|
53
|
+
]
|
|
54
|
+
.filter(Boolean)
|
|
55
|
+
.join(' '));
|
|
56
|
+
}
|
|
57
|
+
function measureFitContentWidth(input, text, minWidth) {
|
|
58
|
+
const field = input.closest('[data-forminput="field"]');
|
|
59
|
+
if (!field)
|
|
60
|
+
return null;
|
|
61
|
+
const inputStyles = window.getComputedStyle(input);
|
|
62
|
+
const fieldStyles = window.getComputedStyle(field);
|
|
63
|
+
const canvas = document.createElement('canvas');
|
|
64
|
+
const ctx = canvas.getContext('2d');
|
|
65
|
+
if (!ctx)
|
|
66
|
+
return null;
|
|
67
|
+
ctx.font = getInputFontShorthand(inputStyles);
|
|
68
|
+
const textWidth = Math.ceil(ctx.measureText(text).width);
|
|
69
|
+
const inputFontSize = Number.parseFloat(inputStyles.fontSize || '16');
|
|
70
|
+
const inputPaddingLeft = Number.parseFloat(inputStyles.paddingLeft || '0');
|
|
71
|
+
const inputPaddingRight = Number.parseFloat(inputStyles.paddingRight || '0');
|
|
72
|
+
const borderLeft = Number.parseFloat(fieldStyles.borderLeftWidth || '0');
|
|
73
|
+
const borderRight = Number.parseFloat(fieldStyles.borderRightWidth || '0');
|
|
74
|
+
const startAdornmentWidth = getOuterWidthWithMargins(field.querySelector('[data-input-role="start-adornment"]'));
|
|
75
|
+
const endAdornmentWidth = getOuterWidthWithMargins(field.querySelector('[data-input-role="end-adornment"]'));
|
|
76
|
+
const iconWidth = getOuterWidthWithMargins(field.querySelector('[data-input-role="icon"]'));
|
|
77
|
+
const breathingRoom = 6;
|
|
78
|
+
const nextWidth = Math.ceil(borderLeft +
|
|
79
|
+
borderRight +
|
|
80
|
+
iconWidth +
|
|
81
|
+
startAdornmentWidth +
|
|
82
|
+
inputPaddingLeft +
|
|
83
|
+
textWidth +
|
|
84
|
+
breathingRoom +
|
|
85
|
+
inputPaddingRight +
|
|
86
|
+
endAdornmentWidth);
|
|
87
|
+
return Math.max(parseLengthToPx(minWidth, inputFontSize) || 120, nextWidth);
|
|
88
|
+
}
|
|
89
|
+
export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'chips', multiSelectedValuesDisplayMode = 'hidden', multiSelectedValueChipContent = 'label', selectedValue = null, onChange, placeholder, variant = 'outlined', disabled = false, fullWidth = false, onClear, emptyMessage = 'Ingen resultater', filterOptions, inputProps, inputSize, width, minWidth, popoverWidth, autoComplete, autoCorrect, autoCapitalize, spellCheck, popoverAnchorRef, fitContent = false, }) {
|
|
90
|
+
var _a, _b;
|
|
12
91
|
const rootRef = useRef(null);
|
|
13
92
|
const inputRef = useRef(null);
|
|
14
93
|
const listboxRef = useRef(null);
|
|
@@ -43,23 +122,67 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
43
122
|
return option.label;
|
|
44
123
|
}
|
|
45
124
|
}, [multiSelectedValueChipContent]);
|
|
46
|
-
const multiSelectionAdornment = mode === 'multi' && selectedOptions.length > 0 ? (multiValueDisplayMode === 'count' ? (_jsxs("span", { className:
|
|
47
|
-
whiteSpace: 'nowrap',
|
|
48
|
-
flexShrink: 0,
|
|
49
|
-
marginRight: 'var(--spacing-xxs)',
|
|
50
|
-
}, children: ["(", selectedOptions.length, ")"] })) : ((() => {
|
|
125
|
+
const multiSelectionAdornment = mode === 'multi' && selectedOptions.length > 0 ? (multiValueDisplayMode === 'count' ? (_jsxs("span", { className: `dbc-muted-text dbc-sm-text ${styles.countAdornment}`, children: ["(", selectedOptions.length, ")"] })) : ((() => {
|
|
51
126
|
const MAX_CHIPS = 2;
|
|
52
127
|
const chipsToShow = selectedOptions.slice(0, MAX_CHIPS);
|
|
53
128
|
const extraCount = selectedOptions.length - MAX_CHIPS;
|
|
54
|
-
return (_jsxs("div", {
|
|
55
|
-
display: 'flex',
|
|
56
|
-
alignItems: 'center',
|
|
57
|
-
gap: 4,
|
|
58
|
-
flexWrap: 'nowrap',
|
|
59
|
-
overflow: 'hidden',
|
|
60
|
-
}, children: [chipsToShow.map(option => (_jsx(Chip, { size: "sm", type: "rounded", onClose: () => commitSelection(option), children: option.label }, option.value))), extraCount > 0 && (_jsxs("span", { className: "dbc-muted-text dbc-sm-text dbc-px-xxs", children: ["+", extraCount] }))] }));
|
|
129
|
+
return (_jsxs("div", { className: styles.chipRow, children: [chipsToShow.map(option => (_jsx(Chip, { size: "sm", type: "rounded", onClose: () => commitSelection(option), children: option.label }, option.value))), extraCount > 0 && (_jsxs("span", { className: "dbc-muted-text dbc-sm-text dbc-px-xxs", children: ["+", extraCount] }))] }));
|
|
61
130
|
})())) : undefined;
|
|
62
131
|
const usesCountAdornment = mode === 'multi' && multiValueDisplayMode === 'count' && selectedOptions.length > 0;
|
|
132
|
+
const resolvedInputSize = (_b = inputSize !== null && inputSize !== void 0 ? inputSize : inputProps === null || inputProps === void 0 ? void 0 : inputProps.inputSize) !== null && _b !== void 0 ? _b : 'md';
|
|
133
|
+
const shouldFitContent = fitContent && mode === 'single' && !fullWidth;
|
|
134
|
+
const [fittedWidthPx, setFittedWidthPx] = useState(null);
|
|
135
|
+
const visibleSingleValueText = useMemo(() => {
|
|
136
|
+
if (!shouldFitContent)
|
|
137
|
+
return '';
|
|
138
|
+
return inputValue || (selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) || placeholder || '';
|
|
139
|
+
}, [shouldFitContent, inputValue, selectedOption, placeholder]);
|
|
140
|
+
useLayoutEffect(() => {
|
|
141
|
+
if (!shouldFitContent)
|
|
142
|
+
return;
|
|
143
|
+
const input = inputRef.current;
|
|
144
|
+
if (!input)
|
|
145
|
+
return;
|
|
146
|
+
let cancelled = false;
|
|
147
|
+
let frameId = requestAnimationFrame(() => {
|
|
148
|
+
const nextWidth = measureFitContentWidth(input, visibleSingleValueText, minWidth);
|
|
149
|
+
if (!cancelled && nextWidth != null) {
|
|
150
|
+
setFittedWidthPx(current => (current !== nextWidth ? nextWidth : current));
|
|
151
|
+
}
|
|
152
|
+
});
|
|
153
|
+
const fonts = document.fonts;
|
|
154
|
+
if (fonts === null || fonts === void 0 ? void 0 : fonts.ready) {
|
|
155
|
+
void fonts.ready.then(() => {
|
|
156
|
+
if (cancelled)
|
|
157
|
+
return;
|
|
158
|
+
const liveInput = inputRef.current;
|
|
159
|
+
if (!liveInput)
|
|
160
|
+
return;
|
|
161
|
+
const nextWidth = measureFitContentWidth(liveInput, visibleSingleValueText, minWidth);
|
|
162
|
+
if (nextWidth != null) {
|
|
163
|
+
setFittedWidthPx(current => (current !== nextWidth ? nextWidth : current));
|
|
164
|
+
}
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
return () => {
|
|
168
|
+
cancelled = true;
|
|
169
|
+
cancelAnimationFrame(frameId);
|
|
170
|
+
};
|
|
171
|
+
}, [
|
|
172
|
+
shouldFitContent,
|
|
173
|
+
visibleSingleValueText,
|
|
174
|
+
minWidth,
|
|
175
|
+
inputPropsStartAdornment,
|
|
176
|
+
inputPropsEndAdornment,
|
|
177
|
+
]);
|
|
178
|
+
const measuredRootWidth = useMemo(() => {
|
|
179
|
+
if (!shouldFitContent)
|
|
180
|
+
return undefined;
|
|
181
|
+
if (fittedWidthPx == null)
|
|
182
|
+
return minWidth !== null && minWidth !== void 0 ? minWidth : '120px';
|
|
183
|
+
return `${fittedWidthPx}px`;
|
|
184
|
+
}, [shouldFitContent, fittedWidthPx, minWidth]);
|
|
185
|
+
const shouldStretchInput = fullWidth || shouldFitContent;
|
|
63
186
|
useEffect(() => {
|
|
64
187
|
var _a;
|
|
65
188
|
if (mode === 'multi') {
|
|
@@ -269,6 +392,65 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
269
392
|
}
|
|
270
393
|
openWithCurrentFilter();
|
|
271
394
|
}, [mode, selectedOption, prepareSingleSearchInput, openWithAllOptions, openWithCurrentFilter]);
|
|
395
|
+
const handleTriggerMouseDown = React.useCallback((e) => {
|
|
396
|
+
var _a;
|
|
397
|
+
inputPropsOnMouseDown === null || inputPropsOnMouseDown === void 0 ? void 0 : inputPropsOnMouseDown(e);
|
|
398
|
+
if (e.defaultPrevented)
|
|
399
|
+
return;
|
|
400
|
+
const isAlreadyFocused = document.activeElement === inputRef.current;
|
|
401
|
+
if (isAlreadyFocused && open) {
|
|
402
|
+
e.preventDefault();
|
|
403
|
+
setOpen(false);
|
|
404
|
+
setActiveIndex(-1);
|
|
405
|
+
if (mode === 'single') {
|
|
406
|
+
setQuery('');
|
|
407
|
+
setInputValue((_a = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _a !== void 0 ? _a : '');
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
setQuery('');
|
|
411
|
+
setInputValue('');
|
|
412
|
+
}
|
|
413
|
+
return;
|
|
414
|
+
}
|
|
415
|
+
if (isAlreadyFocused && mode === 'single' && selectedOption) {
|
|
416
|
+
prepareSingleSearchInput();
|
|
417
|
+
setOpen(true);
|
|
418
|
+
setActiveIndex(getSelectedIndex(options));
|
|
419
|
+
}
|
|
420
|
+
else if (isAlreadyFocused && !open) {
|
|
421
|
+
setOpen(true);
|
|
422
|
+
setActiveIndex(getSelectedIndex(filteredOptions));
|
|
423
|
+
}
|
|
424
|
+
}, [
|
|
425
|
+
inputPropsOnMouseDown,
|
|
426
|
+
open,
|
|
427
|
+
mode,
|
|
428
|
+
selectedOption,
|
|
429
|
+
prepareSingleSearchInput,
|
|
430
|
+
getSelectedIndex,
|
|
431
|
+
options,
|
|
432
|
+
filteredOptions,
|
|
433
|
+
]);
|
|
434
|
+
const handleChevronMouseDown = React.useCallback((e) => {
|
|
435
|
+
var _a, _b;
|
|
436
|
+
e.preventDefault();
|
|
437
|
+
e.stopPropagation();
|
|
438
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
439
|
+
if (open) {
|
|
440
|
+
setOpen(false);
|
|
441
|
+
setActiveIndex(-1);
|
|
442
|
+
if (mode === 'single') {
|
|
443
|
+
setQuery('');
|
|
444
|
+
setInputValue((_b = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _b !== void 0 ? _b : '');
|
|
445
|
+
}
|
|
446
|
+
else {
|
|
447
|
+
setQuery('');
|
|
448
|
+
setInputValue('');
|
|
449
|
+
}
|
|
450
|
+
return;
|
|
451
|
+
}
|
|
452
|
+
handleOpen();
|
|
453
|
+
}, [open, mode, selectedOption, handleOpen]);
|
|
272
454
|
const handleKeyDown = (e) => {
|
|
273
455
|
switch (e.key) {
|
|
274
456
|
case 'ArrowDown':
|
|
@@ -342,8 +524,11 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
342
524
|
selectedOptions.length > 0
|
|
343
525
|
? 8
|
|
344
526
|
: 0,
|
|
345
|
-
width: fullWidth ? '100%' : undefined,
|
|
346
|
-
|
|
527
|
+
width: shouldFitContent ? measuredRootWidth : fullWidth ? '100%' : undefined,
|
|
528
|
+
flex: fullWidth || shouldFitContent ? '1 1 auto' : undefined,
|
|
529
|
+
minWidth: 0,
|
|
530
|
+
maxWidth: shouldFitContent ? '100%' : undefined,
|
|
531
|
+
}, children: [_jsx(Popover, { open: open, minWidth: popoverWidth !== null && popoverWidth !== void 0 ? popoverWidth : minWidth, matchTriggerWidth: true, fillTrigger: true, anchorRef: popoverAnchorRef, onOpenChange: nextOpen => {
|
|
347
532
|
setOpen(nextOpen);
|
|
348
533
|
if (nextOpen) {
|
|
349
534
|
if (mode === 'single' && selectedOption) {
|
|
@@ -358,43 +543,14 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
358
543
|
setActiveIndex(-1);
|
|
359
544
|
}
|
|
360
545
|
}, fullWidth: fullWidth, autoFocusContent: false, returnFocus: false, overlayRef: popoverContentRef, trigger: (openPopover, icon) => {
|
|
361
|
-
var _a, _b, _c, _d
|
|
362
|
-
return (_jsx(Input, { ...passthroughInputProps, ref: inputRef, value: inputValue, startAdornment: multiSelectionAdornment || inputPropsStartAdornment ? (_jsxs(_Fragment, { children: [multiSelectionAdornment, inputPropsStartAdornment] })) : undefined, endAdornment: inputPropsEndAdornment || icon ? (_jsxs(_Fragment, { children: [inputPropsEndAdornment, icon] })) : undefined, onFocus: e => {
|
|
546
|
+
var _a, _b, _c, _d;
|
|
547
|
+
return (_jsx(Input, { ...passthroughInputProps, ref: inputRef, value: inputValue, startAdornment: multiSelectionAdornment || inputPropsStartAdornment ? (_jsxs(_Fragment, { children: [multiSelectionAdornment, inputPropsStartAdornment] })) : undefined, endAdornment: inputPropsEndAdornment || icon ? (_jsxs(_Fragment, { children: [inputPropsEndAdornment, icon ? (_jsx("span", { className: styles.chevronButton, onMouseDown: handleChevronMouseDown, children: icon })) : null] })) : undefined, onFocus: e => {
|
|
363
548
|
inputPropsOnFocus === null || inputPropsOnFocus === void 0 ? void 0 : inputPropsOnFocus(e);
|
|
364
549
|
if (e.defaultPrevented)
|
|
365
550
|
return;
|
|
366
551
|
handleOpen();
|
|
367
552
|
openPopover(e);
|
|
368
|
-
}, onMouseDown: e => {
|
|
369
|
-
var _a;
|
|
370
|
-
inputPropsOnMouseDown === null || inputPropsOnMouseDown === void 0 ? void 0 : inputPropsOnMouseDown(e);
|
|
371
|
-
if (e.defaultPrevented)
|
|
372
|
-
return;
|
|
373
|
-
const isAlreadyFocused = document.activeElement === inputRef.current;
|
|
374
|
-
if (isAlreadyFocused && open) {
|
|
375
|
-
e.preventDefault();
|
|
376
|
-
setOpen(false);
|
|
377
|
-
setActiveIndex(-1);
|
|
378
|
-
if (mode === 'single') {
|
|
379
|
-
setQuery('');
|
|
380
|
-
setInputValue((_a = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _a !== void 0 ? _a : '');
|
|
381
|
-
}
|
|
382
|
-
else {
|
|
383
|
-
setQuery('');
|
|
384
|
-
setInputValue('');
|
|
385
|
-
}
|
|
386
|
-
return;
|
|
387
|
-
}
|
|
388
|
-
if (isAlreadyFocused && mode === 'single' && selectedOption) {
|
|
389
|
-
prepareSingleSearchInput();
|
|
390
|
-
setOpen(true);
|
|
391
|
-
setActiveIndex(getSelectedIndex(options));
|
|
392
|
-
}
|
|
393
|
-
else if (isAlreadyFocused && !open) {
|
|
394
|
-
setOpen(true);
|
|
395
|
-
setActiveIndex(getSelectedIndex(filteredOptions));
|
|
396
|
-
}
|
|
397
|
-
}, onChange: e => handleInputChange(e.currentTarget.value), onBlur: e => {
|
|
553
|
+
}, onMouseDown: handleTriggerMouseDown, onChange: e => handleInputChange(e.currentTarget.value), onBlur: e => {
|
|
398
554
|
inputPropsOnBlur === null || inputPropsOnBlur === void 0 ? void 0 : inputPropsOnBlur(e);
|
|
399
555
|
if (e.defaultPrevented)
|
|
400
556
|
return;
|
|
@@ -407,7 +563,7 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
407
563
|
if (e.defaultPrevented)
|
|
408
564
|
return;
|
|
409
565
|
handleKeyDown(e);
|
|
410
|
-
}, placeholder: placeholder, variant: variant, inputSize:
|
|
566
|
+
}, placeholder: placeholder, variant: variant, inputSize: resolvedInputSize, width: shouldFitContent ? undefined : (width !== null && width !== void 0 ? width : inputProps === null || inputProps === void 0 ? void 0 : inputProps.width), autoComplete: (_a = autoComplete !== null && autoComplete !== void 0 ? autoComplete : inputProps === null || inputProps === void 0 ? void 0 : inputProps.autoComplete) !== null && _a !== void 0 ? _a : 'off', autoCorrect: (_b = autoCorrect !== null && autoCorrect !== void 0 ? autoCorrect : inputProps === null || inputProps === void 0 ? void 0 : inputProps.autoCorrect) !== null && _b !== void 0 ? _b : 'off', autoCapitalize: (_c = autoCapitalize !== null && autoCapitalize !== void 0 ? autoCapitalize : inputProps === null || inputProps === void 0 ? void 0 : inputProps.autoCapitalize) !== null && _c !== void 0 ? _c : 'none', spellCheck: (_d = spellCheck !== null && spellCheck !== void 0 ? spellCheck : inputProps === null || inputProps === void 0 ? void 0 : inputProps.spellCheck) !== null && _d !== void 0 ? _d : false, disabled: disabled, fullWidth: shouldStretchInput, inputClassName: [
|
|
411
567
|
inputProps === null || inputProps === void 0 ? void 0 : inputProps.inputClassName,
|
|
412
568
|
usesCountAdornment ? styles.inputWithoutStartPadding : '',
|
|
413
569
|
]
|
|
@@ -447,10 +603,5 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
447
603
|
}, onKeyDown: e => handleTabKeyDown(e), onClick: () => commitSelection(option), children: _jsx("span", { children: option.label }) }) }, option.value));
|
|
448
604
|
})) : (_jsx(Menu.Item, { disabled: true, children: emptyMessage })) }) }), mode === 'multi' &&
|
|
449
605
|
multiSelectedValuesDisplayMode === 'below-input' &&
|
|
450
|
-
selectedOptions.length > 0 && (_jsx("div", {
|
|
451
|
-
display: 'flex',
|
|
452
|
-
flexWrap: 'wrap',
|
|
453
|
-
gap: 8,
|
|
454
|
-
alignItems: 'flex-start',
|
|
455
|
-
}, children: selectedOptions.map(option => (_jsx(Chip, { size: "sm", type: "default", severity: "neutral", onClose: () => commitSelection(option), children: getSelectedValueChipLabel(option) }, option.value))) }))] }));
|
|
606
|
+
selectedOptions.length > 0 && (_jsx("div", { className: styles.selectedValues, children: selectedOptions.map(option => (_jsx(Chip, { size: "sm", type: "default", severity: "neutral", onClose: () => commitSelection(option), children: getSelectedValueChipLabel(option) }, option.value))) }))] }));
|
|
456
607
|
}
|
|
@@ -1,3 +1,34 @@
|
|
|
1
|
+
.countAdornment {
|
|
2
|
+
white-space: nowrap;
|
|
3
|
+
flex-shrink: 0;
|
|
4
|
+
margin-right: var(--spacing-xxs);
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
.chipRow {
|
|
8
|
+
display: flex;
|
|
9
|
+
align-items: center;
|
|
10
|
+
gap: 4px;
|
|
11
|
+
flex-wrap: nowrap;
|
|
12
|
+
overflow: hidden;
|
|
13
|
+
min-width: 0;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.chevronButton {
|
|
17
|
+
display: inline-flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
justify-content: center;
|
|
20
|
+
height: 100%;
|
|
21
|
+
flex-shrink: 0;
|
|
22
|
+
cursor: pointer;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.selectedValues {
|
|
26
|
+
display: flex;
|
|
27
|
+
flex-wrap: wrap;
|
|
28
|
+
gap: 8px;
|
|
29
|
+
align-items: flex-start;
|
|
30
|
+
}
|
|
31
|
+
|
|
1
32
|
.inputWithoutStartPadding {
|
|
2
33
|
padding-inline-start: 0;
|
|
3
34
|
}
|
|
@@ -92,6 +92,8 @@ id, options, selectedValue, onChange, baseDate, placeholder = 'Vælg interval',
|
|
|
92
92
|
const isActive = index === activeIndex;
|
|
93
93
|
return (_jsx(Menu.Item, { active: isActive, selected: isSelected,
|
|
94
94
|
// IMPORTANT: listbox uses role="option"
|
|
95
|
-
itemRole: "option", children: _jsxs("button", { ref: el =>
|
|
95
|
+
itemRole: "option", children: _jsxs("button", { ref: el => {
|
|
96
|
+
optionRefs.current[index] = el;
|
|
97
|
+
}, type: "button", tabIndex: isActive ? 0 : -1, "aria-selected": isSelected, onClick: () => handleCommit(opt), onFocus: () => setActiveIndex(index), style: { display: 'flex', alignItems: 'center', width: '100%' }, children: [_jsx("span", { style: { width: 16, display: 'inline-flex', justifyContent: 'center' }, children: isSelected ? _jsx(Check, {}) : null }), opt.label] }) }, opt.minutesAgo));
|
|
96
98
|
}) }) }), (error || helpText) && (_jsx("span", { id: describedById, style: { display: 'none' }, children: error !== null && error !== void 0 ? error : helpText }))] }));
|
|
97
99
|
}
|
|
@@ -6,20 +6,13 @@ export interface PopoverProps {
|
|
|
6
6
|
defaultOpen?: boolean;
|
|
7
7
|
onOpenChange?: (open: boolean) => void;
|
|
8
8
|
contentId?: string;
|
|
9
|
-
/**
|
|
10
|
-
* CSS length, recommended "NNpx" for predictability.
|
|
11
|
-
* Used as a minimum, not as a forced width unless matchTriggerWidth=true.
|
|
12
|
-
*/
|
|
13
9
|
minWidth?: string;
|
|
14
|
-
/**
|
|
15
|
-
* If true, force the overlay width to at least the trigger width.
|
|
16
|
-
* If false, overlay width is content-driven (calendar-friendly).
|
|
17
|
-
*/
|
|
18
10
|
matchTriggerWidth?: boolean;
|
|
19
11
|
viewportPadding?: number;
|
|
20
12
|
edgeBuffer?: number;
|
|
21
13
|
dataCy?: string;
|
|
22
14
|
fullWidth?: boolean;
|
|
15
|
+
fillTrigger?: boolean;
|
|
23
16
|
autoFocusContent?: boolean;
|
|
24
17
|
returnFocus?: boolean;
|
|
25
18
|
anchorRef?: React.RefObject<HTMLElement | null>;
|
|
@@ -38,7 +38,7 @@ function parseMinWidthPx(minWidth, elForEm) {
|
|
|
38
38
|
}
|
|
39
39
|
return 0;
|
|
40
40
|
}
|
|
41
|
-
export const Popover = forwardRef(function Popover({ trigger: Trigger, children, open, defaultOpen = false, onOpenChange, contentId, minWidth = '200px', matchTriggerWidth = true, viewportPadding = 8, edgeBuffer = 100, dataCy, fullWidth = false, autoFocusContent = false, returnFocus = true, anchorRef, overlayRef, }, ref) {
|
|
41
|
+
export const Popover = forwardRef(function Popover({ trigger: Trigger, children, open, defaultOpen = false, onOpenChange, contentId, minWidth = '200px', matchTriggerWidth = true, viewportPadding = 8, edgeBuffer = 100, dataCy, fullWidth = false, fillTrigger = false, autoFocusContent = false, returnFocus = true, anchorRef, overlayRef, }, ref) {
|
|
42
42
|
const internalId = useId();
|
|
43
43
|
const resolvedContentId = contentId !== null && contentId !== void 0 ? contentId : `popover-${internalId}`;
|
|
44
44
|
const isControlled = open !== undefined;
|
|
@@ -74,7 +74,7 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
74
74
|
closePopover('trigger');
|
|
75
75
|
else
|
|
76
76
|
openPopover();
|
|
77
|
-
}, [isOpen, closePopover, openPopover]);
|
|
77
|
+
}, [isOpen, closePopover, openPopover, anchorRef]);
|
|
78
78
|
useImperativeHandle(ref, () => ({
|
|
79
79
|
close: () => closePopover('api'),
|
|
80
80
|
open: openPopover,
|
|
@@ -90,19 +90,15 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
90
90
|
return;
|
|
91
91
|
const triggerRect = triggerEl.getBoundingClientRect();
|
|
92
92
|
const overlayWidthBuffer = 8;
|
|
93
|
-
// Only compute a forced width when requested.
|
|
94
93
|
let forcedWidthPx = null;
|
|
95
94
|
if (matchTriggerWidth) {
|
|
96
95
|
const minWidthPx = parseMinWidthPx(minWidth, triggerEl);
|
|
97
|
-
// Make the overlay slightly wider than the trigger so it reads as a
|
|
98
|
-
// floating layer instead of blending into adjacent form fields.
|
|
99
96
|
forcedWidthPx = Math.max(triggerRect.width + overlayWidthBuffer, minWidthPx || 0);
|
|
100
97
|
setTriggerWidth(forcedWidthPx);
|
|
101
98
|
}
|
|
102
99
|
else {
|
|
103
100
|
setTriggerWidth(null);
|
|
104
101
|
}
|
|
105
|
-
// Measure height/width for collision using a temporary sizing that reflects our final sizing:
|
|
106
102
|
const prevHidden = content.hidden;
|
|
107
103
|
const prevVis = content.style.visibility;
|
|
108
104
|
const prevDisp = content.style.display;
|
|
@@ -115,12 +111,10 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
115
111
|
content.style.display = 'block';
|
|
116
112
|
content.style.top = '0px';
|
|
117
113
|
content.style.left = '0px';
|
|
118
|
-
// Apply minWidth always; apply width only if matchTriggerWidth.
|
|
119
114
|
content.style.minWidth = minWidth;
|
|
120
115
|
content.style.width = forcedWidthPx != null ? `${forcedWidthPx}px` : 'auto';
|
|
121
116
|
const contentWidth = content.offsetWidth;
|
|
122
117
|
const contentHeight = content.offsetHeight;
|
|
123
|
-
// Restore
|
|
124
118
|
content.hidden = prevHidden;
|
|
125
119
|
content.style.visibility = prevVis;
|
|
126
120
|
content.style.display = prevDisp;
|
|
@@ -152,13 +146,12 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
152
146
|
const clampedTop = Math.max(viewportPadding, Math.min(rawTop, vh - contentHeight - viewportPadding));
|
|
153
147
|
setPos({ top: clampedTop, left: clampedLeft });
|
|
154
148
|
setPositioned(true);
|
|
155
|
-
}, [edgeBuffer, viewportPadding, minWidth, matchTriggerWidth]);
|
|
149
|
+
}, [anchorRef, edgeBuffer, viewportPadding, minWidth, matchTriggerWidth]);
|
|
156
150
|
useLayoutEffect(() => {
|
|
157
151
|
if (!isOpen)
|
|
158
152
|
return;
|
|
159
153
|
computeAndSetPosition();
|
|
160
|
-
|
|
161
|
-
}, [isOpen]);
|
|
154
|
+
}, [isOpen, computeAndSetPosition]);
|
|
162
155
|
useEffect(() => {
|
|
163
156
|
var _a, _b, _c;
|
|
164
157
|
if (!isOpen)
|
|
@@ -227,7 +220,19 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
227
220
|
const mutableRef = overlayRef;
|
|
228
221
|
mutableRef.current = node;
|
|
229
222
|
}, [overlayRef]);
|
|
230
|
-
return (_jsxs("div", { className: [
|
|
223
|
+
return (_jsxs("div", { className: [
|
|
224
|
+
styles.container,
|
|
225
|
+
fullWidth ? styles.fullWidth : '',
|
|
226
|
+
fillTrigger ? styles.fillTrigger : '',
|
|
227
|
+
]
|
|
228
|
+
.filter(Boolean)
|
|
229
|
+
.join(' '), ref: containerRef, children: [_jsx("div", { className: [
|
|
230
|
+
styles.triggerSlot,
|
|
231
|
+
fullWidth ? styles.fullWidth : '',
|
|
232
|
+
fillTrigger ? styles.fillTrigger : '',
|
|
233
|
+
]
|
|
234
|
+
.filter(Boolean)
|
|
235
|
+
.join(' '), children: Trigger(togglePopover, icon, isOpen) }), mounted &&
|
|
231
236
|
isOpen &&
|
|
232
237
|
createPortal(_jsx("div", { id: resolvedContentId, ref: node => {
|
|
233
238
|
const mutableContentRef = contentRef;
|
|
@@ -236,7 +241,6 @@ export const Popover = forwardRef(function Popover({ trigger: Trigger, children,
|
|
|
236
241
|
}, className: styles.content, style: {
|
|
237
242
|
top: pos.top,
|
|
238
243
|
left: pos.left,
|
|
239
|
-
// Content-driven sizing by default.
|
|
240
244
|
minWidth,
|
|
241
245
|
width: triggerWidth != null ? `${triggerWidth}px` : undefined,
|
|
242
246
|
maxWidth: `calc(100vw - ${viewportPadding * 2}px)`,
|
|
@@ -1,14 +1,39 @@
|
|
|
1
1
|
.container {
|
|
2
2
|
position: relative;
|
|
3
|
-
display:
|
|
3
|
+
display: flex;
|
|
4
4
|
align-items: stretch;
|
|
5
5
|
height: 100%;
|
|
6
6
|
min-width: 0;
|
|
7
|
+
width: auto;
|
|
8
|
+
flex: 0 0 auto;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
.container > * {
|
|
12
|
+
min-width: 0;
|
|
7
13
|
}
|
|
8
14
|
|
|
9
|
-
.
|
|
15
|
+
.triggerSlot {
|
|
10
16
|
display: flex;
|
|
17
|
+
align-items: stretch;
|
|
18
|
+
min-width: 0;
|
|
19
|
+
width: auto;
|
|
20
|
+
flex: 0 0 auto;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.triggerSlot > * {
|
|
24
|
+
min-width: 0;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
.fullWidth,
|
|
28
|
+
.fillTrigger {
|
|
11
29
|
width: 100%;
|
|
30
|
+
flex: 1 1 auto;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.fullWidth > *,
|
|
34
|
+
.fillTrigger > * {
|
|
35
|
+
width: 100%;
|
|
36
|
+
min-width: 0;
|
|
12
37
|
}
|
|
13
38
|
|
|
14
39
|
.content {
|
|
@@ -6,7 +6,7 @@ export interface SplitPaneContextValue {
|
|
|
6
6
|
setPrimarySize: (newSize: number) => void;
|
|
7
7
|
minPrimarySize: number;
|
|
8
8
|
minSecondarySize: number;
|
|
9
|
-
containerRef: React.RefObject<HTMLDivElement>;
|
|
9
|
+
containerRef: React.RefObject<HTMLDivElement | null>;
|
|
10
10
|
storageKey?: string;
|
|
11
11
|
resetDefault: () => void;
|
|
12
12
|
}
|
|
@@ -20,12 +20,12 @@ export function buildColumnVisibilityFromVisibleIds(defs, visibleColumnIds) {
|
|
|
20
20
|
}
|
|
21
21
|
export function mapDefsToColumnItems(defs, columnVisibility, resolvedLayout = {}) {
|
|
22
22
|
return defs.map((def, index) => {
|
|
23
|
-
var _a, _b, _c, _d, _e, _f, _g
|
|
23
|
+
var _a, _b, _c, _d, _e, _f, _g;
|
|
24
24
|
const id = getColumnId(def, index);
|
|
25
25
|
const accessorKey = def.accessorKey;
|
|
26
26
|
const accessorFn = def.accessorFn;
|
|
27
27
|
const cell = def.cell;
|
|
28
|
-
const meta = (
|
|
28
|
+
const meta = ((_a = def.meta) !== null && _a !== void 0 ? _a : {});
|
|
29
29
|
let render;
|
|
30
30
|
if (typeof cell === 'function') {
|
|
31
31
|
render = (row) => cell({
|
|
@@ -46,22 +46,22 @@ export function mapDefsToColumnItems(defs, columnVisibility, resolvedLayout = {}
|
|
|
46
46
|
else {
|
|
47
47
|
render = () => null;
|
|
48
48
|
}
|
|
49
|
-
const isVisible = (
|
|
49
|
+
const isVisible = (_b = columnVisibility[id]) !== null && _b !== void 0 ? _b : true;
|
|
50
50
|
return {
|
|
51
51
|
id,
|
|
52
52
|
header: def.header,
|
|
53
53
|
accessor: accessorKey,
|
|
54
|
-
sortable: (
|
|
54
|
+
sortable: (_c = def.enableSorting) !== null && _c !== void 0 ? _c : !!accessorKey,
|
|
55
55
|
render,
|
|
56
56
|
hidden: !isVisible,
|
|
57
|
-
width: (
|
|
57
|
+
width: (_d = resolvedLayout[id]) === null || _d === void 0 ? void 0 : _d.width,
|
|
58
58
|
align: meta.align,
|
|
59
59
|
verticalAlign: meta.verticalAlign,
|
|
60
|
-
emptyPlaceholder: (
|
|
61
|
-
allowWrap: (
|
|
60
|
+
emptyPlaceholder: (_e = meta.emptyPlaceholder) !== null && _e !== void 0 ? _e : '-',
|
|
61
|
+
allowWrap: (_f = meta.allowWrap) !== null && _f !== void 0 ? _f : false,
|
|
62
62
|
severity: meta.severity,
|
|
63
63
|
divider: meta.divider,
|
|
64
|
-
allowOverflow: (
|
|
64
|
+
allowOverflow: (_g = meta.allowOverflow) !== null && _g !== void 0 ? _g : false,
|
|
65
65
|
};
|
|
66
66
|
});
|
|
67
67
|
}
|
|
@@ -111,10 +111,10 @@ export function buildDistributedColumnWidths(args) {
|
|
|
111
111
|
const leaf = table.getVisibleLeafColumns();
|
|
112
112
|
const selectionWidth = hasSelection ? SELECTION_COLUMN_PX : 0;
|
|
113
113
|
const tracks = leaf.map((c) => {
|
|
114
|
-
var _a, _b, _c, _d
|
|
114
|
+
var _a, _b, _c, _d;
|
|
115
115
|
const def = c.columnDef;
|
|
116
|
-
const meta = ((
|
|
117
|
-
const min = Math.max(1, Number((
|
|
116
|
+
const meta = ((_a = def.meta) !== null && _a !== void 0 ? _a : {});
|
|
117
|
+
const min = Math.max(1, Number((_b = def.minSize) !== null && _b !== void 0 ? _b : defaultMinPx));
|
|
118
118
|
const max = def.maxSize != null ? Math.max(min, Number(def.maxSize)) : undefined;
|
|
119
119
|
const resizedPxRaw = columnSizing[c.id];
|
|
120
120
|
const resizedPx = resizedPxRaw != null ? Math.round(clamp(Number(resizedPxRaw), min, max)) : undefined;
|
|
@@ -127,7 +127,7 @@ export function buildDistributedColumnWidths(args) {
|
|
|
127
127
|
fixed: true,
|
|
128
128
|
};
|
|
129
129
|
}
|
|
130
|
-
const rawWeight = Number((
|
|
130
|
+
const rawWeight = Number((_d = (_c = meta.weight) !== null && _c !== void 0 ? _c : def.size) !== null && _d !== void 0 ? _d : DEFAULT_COLUMN_PX);
|
|
131
131
|
const weight = Number.isFinite(rawWeight) && rawWeight > 0 ? rawWeight : DEFAULT_COLUMN_PX;
|
|
132
132
|
return {
|
|
133
133
|
id: c.id,
|
|
@@ -14,7 +14,14 @@ function defaultDuration(ms) {
|
|
|
14
14
|
}
|
|
15
15
|
return `${sec}s`;
|
|
16
16
|
}
|
|
17
|
-
export function useTimeDuration({ start, end, dateFormat = {
|
|
17
|
+
export function useTimeDuration({ start, end, dateFormat = {
|
|
18
|
+
year: '2-digit',
|
|
19
|
+
month: '2-digit',
|
|
20
|
+
day: '2-digit',
|
|
21
|
+
hour: '2-digit',
|
|
22
|
+
minute: '2-digit',
|
|
23
|
+
second: '2-digit',
|
|
24
|
+
}, fallback = '—', liveUpdate = false, formatDuration = defaultDuration, }) {
|
|
18
25
|
const [hydrated, setHydrated] = useState(false);
|
|
19
26
|
const [tick, setTick] = useState(0);
|
|
20
27
|
useEffect(() => setHydrated(true), []);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dbcdk/react-components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.61",
|
|
4
4
|
"description": "Reusable React components for DBC projects",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "",
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
},
|
|
62
62
|
"peerDependencies": {
|
|
63
63
|
"@tanstack/react-table": "^8.21.3",
|
|
64
|
-
"lucide-react": ">=0.543.0 <
|
|
64
|
+
"lucide-react": ">=0.543.0 <2",
|
|
65
65
|
"react": "^19.0.0",
|
|
66
66
|
"react-dom": "^19.0.0"
|
|
67
67
|
},
|
|
@@ -73,47 +73,45 @@
|
|
|
73
73
|
"devDependencies": {
|
|
74
74
|
"@changesets/cli": "^2.29.6",
|
|
75
75
|
"@mdx-js/react": "^3.1.1",
|
|
76
|
-
"@storybook/addon-a11y": "^
|
|
77
|
-
"@storybook/addon-docs": "^
|
|
78
|
-
"@storybook/
|
|
79
|
-
"@storybook/react-vite": "^9.1.3",
|
|
76
|
+
"@storybook/addon-a11y": "^10.3.5",
|
|
77
|
+
"@storybook/addon-docs": "^10.3.5",
|
|
78
|
+
"@storybook/react-vite": "^10.3.5",
|
|
80
79
|
"@swc/core": "^1.15.11",
|
|
81
80
|
"@swc/jest": "^0.2.39",
|
|
82
81
|
"@tanstack/react-table": "^8.20.0",
|
|
83
82
|
"@testing-library/jest-dom": "^6.9.1",
|
|
84
83
|
"@testing-library/react": "^16.3.2",
|
|
85
84
|
"@types/jest": "^30.0.0",
|
|
86
|
-
"@types/react": "^
|
|
87
|
-
"@types/react-dom": "^
|
|
85
|
+
"@types/react": "^19.2.14",
|
|
86
|
+
"@types/react-dom": "^19.2.3",
|
|
88
87
|
"@typescript-eslint/eslint-plugin": "^8.41.0",
|
|
89
88
|
"@typescript-eslint/parser": "^8.41.0",
|
|
90
|
-
"@vitejs/plugin-react": "^
|
|
91
|
-
"cpy-cli": "^
|
|
89
|
+
"@vitejs/plugin-react": "^6.0.1",
|
|
90
|
+
"cpy-cli": "^7.0.0",
|
|
92
91
|
"esbuild-css-modules-plugin": "^3.1.5",
|
|
93
|
-
"
|
|
94
|
-
"eslint": "^9.34.0",
|
|
92
|
+
"eslint": "^9.39.4",
|
|
95
93
|
"eslint-config-prettier": "^10.1.8",
|
|
96
94
|
"eslint-import-resolver-typescript": "^4.4.4",
|
|
97
95
|
"eslint-plugin-import": "^2.32.0",
|
|
98
96
|
"eslint-plugin-prettier": "^5.5.5",
|
|
99
97
|
"eslint-plugin-react": "^7.37.5",
|
|
100
|
-
"eslint-plugin-react-hooks": "^
|
|
98
|
+
"eslint-plugin-react-hooks": "^7.0.1",
|
|
101
99
|
"globals": "^17.3.0",
|
|
102
100
|
"identity-obj-proxy": "^3.0.0",
|
|
103
101
|
"jest": "^30.2.0",
|
|
104
102
|
"jest-environment-jsdom": "^30.2.0",
|
|
105
|
-
"jsdom": "^
|
|
103
|
+
"jsdom": "^29.0.2",
|
|
106
104
|
"prettier": "^3.2.4",
|
|
107
|
-
"react": "
|
|
108
|
-
"react-dom": "
|
|
105
|
+
"react": "19.2.4",
|
|
106
|
+
"react-dom": "19.2.4",
|
|
109
107
|
"rimraf": "^6.1.2",
|
|
110
|
-
"storybook": "^
|
|
108
|
+
"storybook": "^10.3.5",
|
|
111
109
|
"tsc-alias": "^1.8.16",
|
|
112
110
|
"tsup": "^8.5.0",
|
|
113
|
-
"typescript": "^
|
|
114
|
-
"vite": "^
|
|
111
|
+
"typescript": "^6.0.2",
|
|
112
|
+
"vite": "^8.0.7",
|
|
115
113
|
"vite-tsconfig-paths": "^6.0.5",
|
|
116
|
-
"vitest": "^
|
|
114
|
+
"vitest": "^4.1.3"
|
|
117
115
|
},
|
|
118
116
|
"engines": {
|
|
119
117
|
"node": ">=18.17"
|