@dbcdk/react-components 0.0.87 → 0.0.89
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/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 +85 -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 +21 -0
- package/dist/components/grid/Grid.js +21 -0
- package/dist/components/grid/Grid.module.css +20 -0
- package/dist/components/headline/Headline.d.ts +3 -3
- package/dist/components/headline/Headline.js +6 -6
- package/dist/components/headline/Headline.module.css +25 -6
- 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 +3 -3
- 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 +4 -0
- package/dist/index.js +4 -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
|
@@ -86,14 +86,15 @@ function measureFitContentWidth(input, text, minWidth) {
|
|
|
86
86
|
endAdornmentWidth);
|
|
87
87
|
return Math.max(parseLengthToPx(minWidth, inputFontSize) || 120, nextWidth);
|
|
88
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, }) {
|
|
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, enableHotkey = false, }) {
|
|
90
90
|
var _a, _b;
|
|
91
91
|
const rootRef = useRef(null);
|
|
92
|
+
const triggerWrapperRef = useRef(null);
|
|
92
93
|
const inputRef = useRef(null);
|
|
93
|
-
const listboxRef = useRef(null);
|
|
94
94
|
const popoverContentRef = useRef(null);
|
|
95
|
-
const optionRefs = useRef([]);
|
|
96
95
|
const interactingWithOptionsRef = useRef(false);
|
|
96
|
+
const justClearedRef = useRef(false);
|
|
97
|
+
const locallyClearedRef = useRef(false);
|
|
97
98
|
const listboxId = useId();
|
|
98
99
|
const { onFocus: inputPropsOnFocus, onBlur: inputPropsOnBlur, onKeyDown: inputPropsOnKeyDown, onMouseDown: inputPropsOnMouseDown, onClear: inputPropsOnClear, startAdornment: inputPropsStartAdornment, endAdornment: inputPropsEndAdornment, ...passthroughInputProps } = inputProps !== null && inputProps !== void 0 ? inputProps : {};
|
|
99
100
|
const selectedOption = useMemo(() => {
|
|
@@ -111,6 +112,12 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
111
112
|
const [inputValue, setInputValue] = useState(mode === 'multi' ? '' : ((_a = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _a !== void 0 ? _a : ''));
|
|
112
113
|
const [query, setQuery] = useState('');
|
|
113
114
|
const [activeIndex, setActiveIndex] = useState(-1);
|
|
115
|
+
const [hideSelectedHighlight, setHideSelectedHighlight] = useState(false);
|
|
116
|
+
const clearJustClearedAfterEventCycle = React.useCallback(() => {
|
|
117
|
+
requestAnimationFrame(() => {
|
|
118
|
+
justClearedRef.current = false;
|
|
119
|
+
});
|
|
120
|
+
}, []);
|
|
114
121
|
const getSelectedValueChipLabel = React.useCallback((option) => {
|
|
115
122
|
switch (multiSelectedValueChipContent) {
|
|
116
123
|
case 'value':
|
|
@@ -122,6 +129,48 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
122
129
|
return option.label;
|
|
123
130
|
}
|
|
124
131
|
}, [multiSelectedValueChipContent]);
|
|
132
|
+
let filteredOptions;
|
|
133
|
+
if (filterOptions) {
|
|
134
|
+
filteredOptions = filterOptions(options, query);
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
const normalizedQuery = query.trim().toLocaleLowerCase();
|
|
138
|
+
if (!normalizedQuery) {
|
|
139
|
+
filteredOptions = options;
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
filteredOptions = options.filter(option => option.label.toLocaleLowerCase().includes(normalizedQuery));
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
const commitSelection = React.useCallback((option) => {
|
|
146
|
+
var _a, _b;
|
|
147
|
+
locallyClearedRef.current = false;
|
|
148
|
+
setHideSelectedHighlight(false);
|
|
149
|
+
if (mode === 'multi') {
|
|
150
|
+
if (!option)
|
|
151
|
+
return;
|
|
152
|
+
const nextValues = Array.isArray(selectedValue) ? [...selectedValue] : [];
|
|
153
|
+
const idx = nextValues.indexOf(option.value);
|
|
154
|
+
if (idx > -1) {
|
|
155
|
+
nextValues.splice(idx, 1);
|
|
156
|
+
}
|
|
157
|
+
else {
|
|
158
|
+
nextValues.push(option.value);
|
|
159
|
+
}
|
|
160
|
+
onChange(nextValues);
|
|
161
|
+
if (filteredOptions.length > 1) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
setInputValue('');
|
|
165
|
+
setQuery('');
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
onChange((_a = option === null || option === void 0 ? void 0 : option.value) !== null && _a !== void 0 ? _a : null);
|
|
169
|
+
setInputValue((_b = option === null || option === void 0 ? void 0 : option.label) !== null && _b !== void 0 ? _b : '');
|
|
170
|
+
setQuery('');
|
|
171
|
+
setOpen(false);
|
|
172
|
+
setActiveIndex(-1);
|
|
173
|
+
}, [mode, selectedValue, onChange, filteredOptions.length]);
|
|
125
174
|
const multiSelectionAdornment = mode === 'multi' && selectedOptions.length > 0 ? (multiValueDisplayMode === 'count' ? (_jsxs("span", { className: `dbc-muted-text dbc-sm-text ${styles.countAdornment}`, children: ["(", selectedOptions.length, ")"] })) : ((() => {
|
|
126
175
|
const MAX_CHIPS = 2;
|
|
127
176
|
const chipsToShow = selectedOptions.slice(0, MAX_CHIPS);
|
|
@@ -130,7 +179,7 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
130
179
|
})())) : undefined;
|
|
131
180
|
const usesCountAdornment = mode === 'multi' && multiValueDisplayMode === 'count' && selectedOptions.length > 0;
|
|
132
181
|
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'
|
|
182
|
+
const shouldFitContent = fitContent && mode === 'single';
|
|
134
183
|
const [fittedWidthPx, setFittedWidthPx] = useState(null);
|
|
135
184
|
const visibleSingleValueText = useMemo(() => {
|
|
136
185
|
if (!shouldFitContent)
|
|
@@ -144,7 +193,7 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
144
193
|
if (!input)
|
|
145
194
|
return;
|
|
146
195
|
let cancelled = false;
|
|
147
|
-
|
|
196
|
+
const frameId = requestAnimationFrame(() => {
|
|
148
197
|
const nextWidth = measureFitContentWidth(input, visibleSingleValueText, minWidth);
|
|
149
198
|
if (!cancelled && nextWidth != null) {
|
|
150
199
|
setFittedWidthPx(current => (current !== nextWidth ? nextWidth : current));
|
|
@@ -183,28 +232,36 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
183
232
|
return `${fittedWidthPx}px`;
|
|
184
233
|
}, [shouldFitContent, fittedWidthPx, minWidth]);
|
|
185
234
|
const shouldStretchInput = fullWidth || shouldFitContent;
|
|
235
|
+
useEffect(() => {
|
|
236
|
+
if (!enableHotkey)
|
|
237
|
+
return;
|
|
238
|
+
function handleKeyDown(event) {
|
|
239
|
+
var _a;
|
|
240
|
+
if (event.key === 'k' && (event.metaKey || event.ctrlKey)) {
|
|
241
|
+
event.preventDefault();
|
|
242
|
+
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
246
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
247
|
+
}, [enableHotkey]);
|
|
186
248
|
useEffect(() => {
|
|
187
249
|
var _a;
|
|
250
|
+
if (justClearedRef.current || locallyClearedRef.current)
|
|
251
|
+
return;
|
|
188
252
|
if (mode === 'multi') {
|
|
189
253
|
setInputValue('');
|
|
190
254
|
setQuery('');
|
|
191
255
|
}
|
|
192
256
|
else {
|
|
193
|
-
|
|
194
|
-
setInputValue(nextLabel);
|
|
257
|
+
setInputValue((_a = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _a !== void 0 ? _a : '');
|
|
195
258
|
}
|
|
196
259
|
}, [selectedOption, mode]);
|
|
197
|
-
const filteredOptions = useMemo(() => {
|
|
198
|
-
if (filterOptions)
|
|
199
|
-
return filterOptions(options, query);
|
|
200
|
-
const normalizedQuery = query.trim().toLocaleLowerCase();
|
|
201
|
-
if (!normalizedQuery)
|
|
202
|
-
return options;
|
|
203
|
-
return options.filter(option => option.label.toLocaleLowerCase().includes(normalizedQuery));
|
|
204
|
-
}, [filterOptions, query, options]);
|
|
205
260
|
const getSelectedIndex = React.useCallback((items) => {
|
|
206
261
|
if (items.length === 0)
|
|
207
262
|
return -1;
|
|
263
|
+
if (locallyClearedRef.current)
|
|
264
|
+
return 0;
|
|
208
265
|
if (mode === 'multi') {
|
|
209
266
|
if (!Array.isArray(selectedValue) || selectedValue.length === 0)
|
|
210
267
|
return 0;
|
|
@@ -218,18 +275,21 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
218
275
|
setActiveIndex(current => {
|
|
219
276
|
if (filteredOptions.length === 0)
|
|
220
277
|
return -1;
|
|
278
|
+
if (locallyClearedRef.current)
|
|
279
|
+
return 0;
|
|
221
280
|
if (current < 0)
|
|
222
281
|
return getSelectedIndex(filteredOptions);
|
|
223
282
|
return Math.min(current, filteredOptions.length - 1);
|
|
224
283
|
});
|
|
225
284
|
}, [filteredOptions, getSelectedIndex]);
|
|
226
285
|
useEffect(() => {
|
|
227
|
-
var _a;
|
|
286
|
+
var _a, _b;
|
|
228
287
|
if (!open || activeIndex < 0)
|
|
229
288
|
return;
|
|
230
|
-
const activeEl =
|
|
231
|
-
|
|
232
|
-
|
|
289
|
+
const activeEl = (_a = document
|
|
290
|
+
.getElementById(listboxId)) === null || _a === void 0 ? void 0 : _a.querySelector(`#${CSS.escape(`${listboxId}-option-${activeIndex}`)}`);
|
|
291
|
+
(_b = activeEl === null || activeEl === void 0 ? void 0 : activeEl.scrollIntoView) === null || _b === void 0 ? void 0 : _b.call(activeEl, { block: 'nearest' });
|
|
292
|
+
}, [open, activeIndex, filteredOptions, listboxId]);
|
|
233
293
|
const getFocusableElements = React.useCallback(() => {
|
|
234
294
|
const selector = [
|
|
235
295
|
'a[href]',
|
|
@@ -279,8 +339,6 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
279
339
|
? eventTarget
|
|
280
340
|
: ((_a = document.activeElement) !== null && _a !== void 0 ? _a : null);
|
|
281
341
|
const activeIndexInScope = activeElement ? focusables.indexOf(activeElement) : -1;
|
|
282
|
-
const boundaryIndex = event.shiftKey ? 0 : focusables.length - 1;
|
|
283
|
-
const boundaryElement = focusables[boundaryIndex];
|
|
284
342
|
if (mode === 'multi') {
|
|
285
343
|
if (activeIndexInScope === -1) {
|
|
286
344
|
event.preventDefault();
|
|
@@ -294,38 +352,14 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
294
352
|
(_c = focusables[nextIndex]) === null || _c === void 0 ? void 0 : _c.focus();
|
|
295
353
|
return;
|
|
296
354
|
}
|
|
297
|
-
// single mode: Tab always closes the dropdown and lets focus move naturally
|
|
298
355
|
setOpen(false);
|
|
299
356
|
setActiveIndex(-1);
|
|
300
357
|
}, [open, getFocusableElements, mode]);
|
|
301
|
-
const commitSelection = (option) => {
|
|
302
|
-
var _a, _b;
|
|
303
|
-
if (mode === 'multi') {
|
|
304
|
-
if (!option)
|
|
305
|
-
return;
|
|
306
|
-
const nextValues = Array.isArray(selectedValue) ? [...selectedValue] : [];
|
|
307
|
-
const idx = nextValues.indexOf(option.value);
|
|
308
|
-
if (idx > -1) {
|
|
309
|
-
nextValues.splice(idx, 1);
|
|
310
|
-
}
|
|
311
|
-
else {
|
|
312
|
-
nextValues.push(option.value);
|
|
313
|
-
}
|
|
314
|
-
onChange(nextValues);
|
|
315
|
-
if (filteredOptions.length > 1) {
|
|
316
|
-
return;
|
|
317
|
-
}
|
|
318
|
-
setInputValue('');
|
|
319
|
-
setQuery('');
|
|
320
|
-
return;
|
|
321
|
-
}
|
|
322
|
-
onChange((_a = option === null || option === void 0 ? void 0 : option.value) !== null && _a !== void 0 ? _a : null);
|
|
323
|
-
setInputValue((_b = option === null || option === void 0 ? void 0 : option.label) !== null && _b !== void 0 ? _b : '');
|
|
324
|
-
setQuery('');
|
|
325
|
-
setOpen(false);
|
|
326
|
-
setActiveIndex(-1);
|
|
327
|
-
};
|
|
328
358
|
const handleInputChange = (nextValue) => {
|
|
359
|
+
if (justClearedRef.current)
|
|
360
|
+
return;
|
|
361
|
+
locallyClearedRef.current = false;
|
|
362
|
+
setHideSelectedHighlight(false);
|
|
329
363
|
setInputValue(nextValue);
|
|
330
364
|
setQuery(nextValue);
|
|
331
365
|
if (!open)
|
|
@@ -338,6 +372,13 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
338
372
|
}
|
|
339
373
|
};
|
|
340
374
|
const handleBlur = (nextFocusedTarget) => {
|
|
375
|
+
if (justClearedRef.current || locallyClearedRef.current) {
|
|
376
|
+
setInputValue('');
|
|
377
|
+
setQuery('');
|
|
378
|
+
setOpen(false);
|
|
379
|
+
setActiveIndex(-1);
|
|
380
|
+
return;
|
|
381
|
+
}
|
|
341
382
|
if (isFocusWithinTypeahead(nextFocusedTarget))
|
|
342
383
|
return;
|
|
343
384
|
if (mode === 'multi') {
|
|
@@ -369,22 +410,28 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
369
410
|
setActiveIndex(-1);
|
|
370
411
|
};
|
|
371
412
|
const openWithAllOptions = React.useCallback(() => {
|
|
413
|
+
if (justClearedRef.current)
|
|
414
|
+
return;
|
|
372
415
|
setQuery('');
|
|
373
416
|
setOpen(true);
|
|
374
417
|
setActiveIndex(getSelectedIndex(options));
|
|
375
418
|
}, [getSelectedIndex, options]);
|
|
376
419
|
const openWithCurrentFilter = React.useCallback(() => {
|
|
420
|
+
if (justClearedRef.current)
|
|
421
|
+
return;
|
|
377
422
|
setOpen(true);
|
|
378
423
|
setActiveIndex(getSelectedIndex(filteredOptions));
|
|
379
424
|
}, [getSelectedIndex, filteredOptions]);
|
|
380
425
|
const prepareSingleSearchInput = React.useCallback(() => {
|
|
381
|
-
if (mode !== 'single' || !selectedOption)
|
|
426
|
+
if (mode !== 'single' || !selectedOption || justClearedRef.current)
|
|
382
427
|
return;
|
|
383
428
|
setInputValue('');
|
|
384
429
|
setQuery('');
|
|
385
430
|
}, [mode, selectedOption]);
|
|
386
431
|
const handleOpen = React.useCallback(() => {
|
|
387
|
-
if (
|
|
432
|
+
if (justClearedRef.current)
|
|
433
|
+
return;
|
|
434
|
+
if (mode === 'single' && selectedOption && !locallyClearedRef.current) {
|
|
388
435
|
prepareSingleSearchInput();
|
|
389
436
|
openWithAllOptions();
|
|
390
437
|
return;
|
|
@@ -396,22 +443,21 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
396
443
|
inputPropsOnMouseDown === null || inputPropsOnMouseDown === void 0 ? void 0 : inputPropsOnMouseDown(e);
|
|
397
444
|
if (e.defaultPrevented)
|
|
398
445
|
return;
|
|
446
|
+
if (justClearedRef.current) {
|
|
447
|
+
e.preventDefault();
|
|
448
|
+
e.stopPropagation();
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
399
451
|
const isAlreadyFocused = document.activeElement === inputRef.current;
|
|
400
452
|
if (isAlreadyFocused && open) {
|
|
401
453
|
e.preventDefault();
|
|
402
454
|
setOpen(false);
|
|
403
455
|
setActiveIndex(-1);
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
setInputValue((_a = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _a !== void 0 ? _a : '');
|
|
407
|
-
}
|
|
408
|
-
else {
|
|
409
|
-
setQuery('');
|
|
410
|
-
setInputValue('');
|
|
411
|
-
}
|
|
456
|
+
setQuery('');
|
|
457
|
+
setInputValue(mode === 'single' && !locallyClearedRef.current ? ((_a = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _a !== void 0 ? _a : '') : '');
|
|
412
458
|
return;
|
|
413
459
|
}
|
|
414
|
-
if (isAlreadyFocused && mode === 'single' && selectedOption) {
|
|
460
|
+
if (isAlreadyFocused && mode === 'single' && selectedOption && !locallyClearedRef.current) {
|
|
415
461
|
prepareSingleSearchInput();
|
|
416
462
|
setOpen(true);
|
|
417
463
|
setActiveIndex(getSelectedIndex(options));
|
|
@@ -434,18 +480,14 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
434
480
|
var _a, _b;
|
|
435
481
|
e.preventDefault();
|
|
436
482
|
e.stopPropagation();
|
|
483
|
+
if (justClearedRef.current)
|
|
484
|
+
return;
|
|
437
485
|
(_a = inputRef.current) === null || _a === void 0 ? void 0 : _a.focus();
|
|
438
486
|
if (open) {
|
|
439
487
|
setOpen(false);
|
|
440
488
|
setActiveIndex(-1);
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
setInputValue((_b = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _b !== void 0 ? _b : '');
|
|
444
|
-
}
|
|
445
|
-
else {
|
|
446
|
-
setQuery('');
|
|
447
|
-
setInputValue('');
|
|
448
|
-
}
|
|
489
|
+
setQuery('');
|
|
490
|
+
setInputValue(mode === 'single' && !locallyClearedRef.current ? ((_b = selectedOption === null || selectedOption === void 0 ? void 0 : selectedOption.label) !== null && _b !== void 0 ? _b : '') : '');
|
|
449
491
|
return;
|
|
450
492
|
}
|
|
451
493
|
handleOpen();
|
|
@@ -506,12 +548,9 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
506
548
|
setOpen(false);
|
|
507
549
|
setActiveIndex(-1);
|
|
508
550
|
setQuery('');
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
else {
|
|
513
|
-
setInputValue('');
|
|
514
|
-
}
|
|
551
|
+
setInputValue(mode === 'single' && selectedOption && !locallyClearedRef.current
|
|
552
|
+
? selectedOption.label
|
|
553
|
+
: '');
|
|
515
554
|
return;
|
|
516
555
|
}
|
|
517
556
|
};
|
|
@@ -523,14 +562,19 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
523
562
|
selectedOptions.length > 0
|
|
524
563
|
? 8
|
|
525
564
|
: 0,
|
|
526
|
-
width:
|
|
565
|
+
width: fullWidth ? '100%' : shouldFitContent ? measuredRootWidth : undefined,
|
|
527
566
|
flex: fullWidth || shouldFitContent ? '1 1 auto' : undefined,
|
|
528
|
-
minWidth: 0,
|
|
567
|
+
minWidth: shouldFitContent ? measuredRootWidth : 0,
|
|
529
568
|
maxWidth: shouldFitContent ? '100%' : undefined,
|
|
530
|
-
}, children: [_jsx(Popover, { open: open, minWidth: popoverWidth !== null && popoverWidth !== void 0 ? popoverWidth : minWidth, matchTriggerWidth: true, fillTrigger: true, anchorRef: popoverAnchorRef, onOpenChange: nextOpen => {
|
|
569
|
+
}, children: [_jsx(Popover, { open: open, minWidth: popoverWidth !== null && popoverWidth !== void 0 ? popoverWidth : minWidth, matchTriggerWidth: true, fillTrigger: true, anchorRef: popoverAnchorRef !== null && popoverAnchorRef !== void 0 ? popoverAnchorRef : triggerWrapperRef, onOpenChange: nextOpen => {
|
|
570
|
+
if (justClearedRef.current) {
|
|
571
|
+
setOpen(false);
|
|
572
|
+
setActiveIndex(-1);
|
|
573
|
+
return;
|
|
574
|
+
}
|
|
531
575
|
setOpen(nextOpen);
|
|
532
576
|
if (nextOpen) {
|
|
533
|
-
if (mode === 'single' && selectedOption) {
|
|
577
|
+
if (mode === 'single' && selectedOption && !locallyClearedRef.current) {
|
|
534
578
|
setQuery('');
|
|
535
579
|
setActiveIndex(getSelectedIndex(options));
|
|
536
580
|
}
|
|
@@ -543,50 +587,70 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
543
587
|
}
|
|
544
588
|
}, fullWidth: fullWidth, autoFocusContent: false, returnFocus: false, overlayRef: popoverContentRef, trigger: (openPopover, icon) => {
|
|
545
589
|
var _a, _b, _c, _d;
|
|
546
|
-
return (_jsx(
|
|
547
|
-
|
|
548
|
-
if (
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
openPopover(e);
|
|
552
|
-
}, onMouseDown: handleTriggerMouseDown, onChange: e => handleInputChange(e.currentTarget.value), onBlur: e => {
|
|
553
|
-
inputPropsOnBlur === null || inputPropsOnBlur === void 0 ? void 0 : inputPropsOnBlur(e);
|
|
554
|
-
if (e.defaultPrevented)
|
|
555
|
-
return;
|
|
556
|
-
handleBlur(e.relatedTarget);
|
|
557
|
-
}, onKeyDown: e => {
|
|
558
|
-
inputPropsOnKeyDown === null || inputPropsOnKeyDown === void 0 ? void 0 : inputPropsOnKeyDown(e);
|
|
559
|
-
if (e.defaultPrevented)
|
|
590
|
+
return (_jsx("div", { ref: triggerWrapperRef, onMouseDown: e => {
|
|
591
|
+
const target = e.target;
|
|
592
|
+
if (justClearedRef.current) {
|
|
593
|
+
e.preventDefault();
|
|
594
|
+
e.stopPropagation();
|
|
560
595
|
return;
|
|
561
|
-
|
|
562
|
-
if (
|
|
596
|
+
}
|
|
597
|
+
if (target.closest('input, button, [data-input-role="clear"]'))
|
|
563
598
|
return;
|
|
564
|
-
|
|
565
|
-
},
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
599
|
+
handleChevronMouseDown(e);
|
|
600
|
+
}, children: _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 => {
|
|
601
|
+
inputPropsOnFocus === null || inputPropsOnFocus === void 0 ? void 0 : inputPropsOnFocus(e);
|
|
602
|
+
if (e.defaultPrevented)
|
|
603
|
+
return;
|
|
604
|
+
if (justClearedRef.current)
|
|
605
|
+
return;
|
|
606
|
+
handleOpen();
|
|
607
|
+
openPopover(e);
|
|
608
|
+
}, onMouseDown: handleTriggerMouseDown, onChange: e => handleInputChange(e.currentTarget.value), onBlur: e => {
|
|
609
|
+
inputPropsOnBlur === null || inputPropsOnBlur === void 0 ? void 0 : inputPropsOnBlur(e);
|
|
610
|
+
if (e.defaultPrevented)
|
|
611
|
+
return;
|
|
612
|
+
handleBlur(e.relatedTarget);
|
|
613
|
+
}, onKeyDown: e => {
|
|
614
|
+
inputPropsOnKeyDown === null || inputPropsOnKeyDown === void 0 ? void 0 : inputPropsOnKeyDown(e);
|
|
615
|
+
if (e.defaultPrevented)
|
|
616
|
+
return;
|
|
617
|
+
handleTabKeyDown(e);
|
|
618
|
+
if (e.defaultPrevented)
|
|
619
|
+
return;
|
|
620
|
+
handleKeyDown(e);
|
|
621
|
+
}, 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: [
|
|
622
|
+
inputProps === null || inputProps === void 0 ? void 0 : inputProps.inputClassName,
|
|
623
|
+
styles.typeaheadInput,
|
|
624
|
+
usesCountAdornment ? styles.inputWithoutStartPadding : '',
|
|
625
|
+
]
|
|
626
|
+
.filter(Boolean)
|
|
627
|
+
.join(' '), onClear: (event) => {
|
|
628
|
+
var _a, _b;
|
|
629
|
+
(_a = event === null || event === void 0 ? void 0 : event.preventDefault) === null || _a === void 0 ? void 0 : _a.call(event);
|
|
630
|
+
(_b = event === null || event === void 0 ? void 0 : event.stopPropagation) === null || _b === void 0 ? void 0 : _b.call(event);
|
|
631
|
+
justClearedRef.current = true;
|
|
632
|
+
locallyClearedRef.current = true;
|
|
633
|
+
setHideSelectedHighlight(true);
|
|
578
634
|
setOpen(false);
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
635
|
+
setInputValue('');
|
|
636
|
+
setQuery('');
|
|
637
|
+
setActiveIndex(-1);
|
|
638
|
+
inputPropsOnClear === null || inputPropsOnClear === void 0 ? void 0 : inputPropsOnClear();
|
|
639
|
+
if (onClear) {
|
|
640
|
+
onClear();
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
onChange(mode === 'multi' ? [] : null);
|
|
644
|
+
}
|
|
645
|
+
clearJustClearedAfterEventCycle();
|
|
646
|
+
}, role: "combobox", "aria-expanded": open, "aria-controls": listboxId, "aria-autocomplete": "list", "aria-activedescendant": open && activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : undefined }) }));
|
|
647
|
+
}, children: _jsx(Menu, { role: "listbox", id: listboxId, children: filteredOptions.length > 0 ? (filteredOptions.map((option, index) => {
|
|
582
648
|
const isActive = index === activeIndex;
|
|
583
649
|
const isSelected = mode === 'multi'
|
|
584
650
|
? Array.isArray(selectedValue) && selectedValue.includes(option.value)
|
|
585
|
-
: option.value === selectedValue;
|
|
651
|
+
: option.value === selectedValue && !hideSelectedHighlight;
|
|
586
652
|
const optionId = `${listboxId}-option-${index}`;
|
|
587
|
-
return mode === 'multi' ? (_jsx(Menu.CheckItem, { checked: isSelected, active: isActive,
|
|
588
|
-
optionRefs.current[index] = node;
|
|
589
|
-
}, interactiveProps: {
|
|
653
|
+
return mode === 'multi' ? (_jsx(Menu.CheckItem, { checked: isSelected, active: isActive, interactiveProps: {
|
|
590
654
|
id: optionId,
|
|
591
655
|
role: 'option',
|
|
592
656
|
onMouseEnter: () => setActiveIndex(index),
|
|
@@ -595,9 +659,7 @@ export function Typeahead({ options, mode = 'single', multiValueDisplayMode = 'c
|
|
|
595
659
|
e.preventDefault();
|
|
596
660
|
},
|
|
597
661
|
onKeyDown: e => handleTabKeyDown(e),
|
|
598
|
-
}, label: _jsx("span", { children: option.label }), onCheckedChange: () => commitSelection(option) }, option.value)) : (_jsx(Menu.Item, { active: isActive, selected: isSelected, children: _jsx("button", {
|
|
599
|
-
optionRefs.current[index] = node;
|
|
600
|
-
}, id: optionId, type: "button", role: "option", "aria-selected": isSelected, onMouseEnter: () => setActiveIndex(index), onMouseDown: e => {
|
|
662
|
+
}, label: _jsx("span", { children: option.label }), onCheckedChange: () => commitSelection(option) }, option.value)) : (_jsx(Menu.Item, { active: isActive, selected: isSelected, children: _jsx("button", { id: optionId, type: "button", role: "option", "aria-selected": isSelected, onMouseEnter: () => setActiveIndex(index), onMouseDown: e => {
|
|
601
663
|
e.preventDefault();
|
|
602
664
|
}, onKeyDown: e => handleTabKeyDown(e), onClick: () => commitSelection(option), children: _jsx("span", { children: option.label }) }) }, option.value));
|
|
603
665
|
})) : (_jsx(Menu.Item, { disabled: true, children: emptyMessage })) }) }), mode === 'multi' &&
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
export type GridGap = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
3
|
+
export interface GridProps {
|
|
4
|
+
children?: ReactNode;
|
|
5
|
+
gap?: GridGap;
|
|
6
|
+
className?: string;
|
|
7
|
+
style?: CSSProperties;
|
|
8
|
+
}
|
|
9
|
+
export declare function Grid({ children, gap, className, style }: GridProps): import("react/jsx-runtime").JSX.Element;
|
|
10
|
+
export interface GridItemProps {
|
|
11
|
+
children?: ReactNode;
|
|
12
|
+
/** Default span (mobile-first, 1–12) */
|
|
13
|
+
base?: number;
|
|
14
|
+
/** Override at ≥768px */
|
|
15
|
+
md?: number;
|
|
16
|
+
/** Override at ≥1024px */
|
|
17
|
+
lg?: number;
|
|
18
|
+
className?: string;
|
|
19
|
+
style?: CSSProperties;
|
|
20
|
+
}
|
|
21
|
+
export declare function GridItem({ children, base, md, lg, className, style }: GridItemProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import styles from './Grid.module.css';
|
|
3
|
+
const GAP_TOKEN = {
|
|
4
|
+
none: '0',
|
|
5
|
+
xs: 'var(--spacing-xs)',
|
|
6
|
+
sm: 'var(--spacing-sm)',
|
|
7
|
+
md: 'var(--spacing-md)',
|
|
8
|
+
lg: 'var(--spacing-lg)',
|
|
9
|
+
xl: 'var(--spacing-xl)',
|
|
10
|
+
};
|
|
11
|
+
export function Grid({ children, gap = 'md', className, style }) {
|
|
12
|
+
return (_jsx("div", { className: [styles.grid, className].filter(Boolean).join(' '), style: { gap: GAP_TOKEN[gap], ...style }, children: children }));
|
|
13
|
+
}
|
|
14
|
+
export function GridItem({ children, base = 12, md, lg, className, style }) {
|
|
15
|
+
return (_jsx("div", { className: [styles.item, className].filter(Boolean).join(' '), style: {
|
|
16
|
+
'--span-base': base,
|
|
17
|
+
...(md != null ? { '--span-md': md } : {}),
|
|
18
|
+
...(lg != null ? { '--span-lg': lg } : {}),
|
|
19
|
+
...style,
|
|
20
|
+
}, children: children }));
|
|
21
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
.grid {
|
|
2
|
+
display: grid;
|
|
3
|
+
grid-template-columns: repeat(12, minmax(0, 1fr));
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.item {
|
|
7
|
+
grid-column: span var(--span-base, 12);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
@media (min-width: 768px) {
|
|
11
|
+
.item {
|
|
12
|
+
grid-column: span var(--span-md, var(--span-base, 12));
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
@media (min-width: 1024px) {
|
|
17
|
+
.item {
|
|
18
|
+
grid-column: span var(--span-lg, var(--span-md, var(--span-base, 12)));
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, { PropsWithChildren } from 'react';
|
|
2
2
|
import { Severity } from '../../constants/severity.types';
|
|
3
3
|
type HeadlineTone = 'dark' | 'light';
|
|
4
4
|
interface HeadlineProps extends React.AriaAttributes {
|
|
@@ -7,11 +7,11 @@ interface HeadlineProps extends React.AriaAttributes {
|
|
|
7
7
|
disableMargin?: boolean;
|
|
8
8
|
severity?: Severity;
|
|
9
9
|
weight?: 500 | 600 | 700;
|
|
10
|
-
|
|
10
|
+
subheader?: React.ReactNode;
|
|
11
11
|
addition?: React.ReactNode;
|
|
12
12
|
icon?: React.ReactNode;
|
|
13
13
|
allowWrap?: boolean;
|
|
14
14
|
tone?: HeadlineTone;
|
|
15
15
|
}
|
|
16
|
-
export declare function Headline({ size, marker, disableMargin, children, severity, weight,
|
|
16
|
+
export declare function Headline({ size, marker, disableMargin, children, severity, weight, subheader, addition, icon, tone, allowWrap, }: PropsWithChildren<HeadlineProps>): React.JSX.Element;
|
|
17
17
|
export {};
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
'use client';
|
|
2
|
-
import { jsx as _jsx, jsxs as _jsxs
|
|
2
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
3
3
|
import styles from './Headline.module.css';
|
|
4
4
|
import { SeverityBgColor } from '../../constants/severity';
|
|
5
5
|
import { Icon } from '../icon/Icon';
|
|
6
|
-
export function Headline({ size = 2, marker, disableMargin, children, severity, weight = 600,
|
|
6
|
+
export function Headline({ size = 2, marker, disableMargin, children, severity, weight = 600, subheader, addition, icon, tone, allowWrap = true, }) {
|
|
7
7
|
const Tag = `h${size}`;
|
|
8
8
|
const containerClassName = [styles.headlineContainer, tone ? styles[`tone-${tone}`] : '']
|
|
9
9
|
.filter(Boolean)
|
|
@@ -18,8 +18,8 @@ export function Headline({ size = 2, marker, disableMargin, children, severity,
|
|
|
18
18
|
const textClassName = [styles.text, allowWrap ? styles.wrap : styles.truncate]
|
|
19
19
|
.filter(Boolean)
|
|
20
20
|
.join(' ');
|
|
21
|
-
return (_jsxs(
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
21
|
+
return (_jsx("div", { className: containerClassName, children: _jsxs("div", { className: styles.headlineBlock, children: [_jsxs("div", { className: styles.headlineRow, children: [_jsxs(Tag, { style: {
|
|
22
|
+
'--font-weight': weight,
|
|
23
|
+
'--marker-color': severity ? SeverityBgColor[severity] : undefined,
|
|
24
|
+
}, className: headlineClassName, children: [icon || (severity && !marker) ? (_jsx("span", { className: styles.icon, children: _jsx(Icon, { customIcon: icon, severity: severity }) })) : null, _jsx("span", { className: textClassName, children: children })] }), addition ? _jsx("div", { className: styles.addition, children: addition }) : null] }), subheader ? _jsx("div", { className: styles.subheader, children: subheader }) : null] }) }));
|
|
25
25
|
}
|