@carbon/react 1.67.1 → 1.68.0
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/.playwright/INTERNAL_AVT_REPORT_DO_NOT_USE.json +880 -880
- package/es/components/ComboBox/ComboBox.d.ts +5 -0
- package/es/components/ComboBox/ComboBox.js +147 -45
- package/es/components/ComposedModal/ModalHeader.js +1 -1
- package/es/components/DatePicker/DatePicker.js +10 -6
- package/es/components/Dropdown/Dropdown.js +3 -2
- package/es/components/FeatureFlags/index.d.ts +56 -0
- package/es/components/FeatureFlags/index.js +2 -2
- package/es/components/FileUploader/FileUploaderDropContainer.js +1 -1
- package/es/components/FluidComboBox/FluidComboBox.Skeleton.d.ts +15 -0
- package/es/components/FluidComboBox/FluidComboBox.Skeleton.js +1 -2
- package/es/components/FluidComboBox/FluidComboBox.d.ts +102 -0
- package/es/components/FluidComboBox/FluidComboBox.js +2 -3
- package/es/components/FluidComboBox/index.d.ts +13 -0
- package/es/components/FluidDatePicker/FluidDatePicker.Skeleton.d.ts +19 -0
- package/es/components/FluidDatePicker/FluidDatePicker.Skeleton.js +2 -2
- package/es/components/FluidDatePicker/FluidDatePicker.d.ts +39 -0
- package/es/components/FluidDatePicker/FluidDatePicker.js +2 -3
- package/es/components/FluidDatePicker/index.d.ts +13 -0
- package/es/components/FluidDatePickerInput/FluidDatePickerInput.d.ts +10 -0
- package/es/components/FluidDatePickerInput/FluidDatePickerInput.js +1 -2
- package/es/components/FluidDatePickerInput/index.d.ts +9 -0
- package/es/components/FluidMultiSelect/FluidFilterableMultiSelect.d.ts +144 -0
- package/es/components/FluidMultiSelect/FluidMultiSelect.Skeleton.d.ts +15 -0
- package/es/components/FluidMultiSelect/FluidMultiSelect.Skeleton.js +1 -2
- package/es/components/FluidMultiSelect/FluidMultiSelect.d.ts +149 -0
- package/es/components/FluidMultiSelect/FluidMultiSelect.js +5 -3
- package/es/components/FluidMultiSelect/index.d.ts +13 -0
- package/es/components/FluidNumberInput/index.d.ts +2 -2
- package/es/components/FluidSearch/index.d.ts +2 -2
- package/es/components/FluidSelect/index.d.ts +2 -2
- package/es/components/FluidTimePicker/index.d.ts +2 -2
- package/es/components/Modal/Modal.js +1 -1
- package/es/components/MultiSelect/FilterableMultiSelect.d.ts +2 -2
- package/es/components/Tabs/usePressable.js +2 -0
- package/es/components/Tooltip/DefinitionTooltip.js +4 -2
- package/es/index.js +7 -7
- package/lib/components/ComboBox/ComboBox.d.ts +5 -0
- package/lib/components/ComboBox/ComboBox.js +146 -44
- package/lib/components/ComposedModal/ModalHeader.js +1 -1
- package/lib/components/DatePicker/DatePicker.js +9 -5
- package/lib/components/Dropdown/Dropdown.js +3 -2
- package/lib/components/FeatureFlags/index.d.ts +56 -0
- package/lib/components/FileUploader/FileUploaderDropContainer.js +1 -1
- package/lib/components/FluidComboBox/FluidComboBox.Skeleton.d.ts +15 -0
- package/lib/components/FluidComboBox/FluidComboBox.Skeleton.js +1 -2
- package/lib/components/FluidComboBox/FluidComboBox.d.ts +102 -0
- package/lib/components/FluidComboBox/FluidComboBox.js +2 -3
- package/lib/components/FluidComboBox/index.d.ts +13 -0
- package/lib/components/FluidDatePicker/FluidDatePicker.Skeleton.d.ts +19 -0
- package/lib/components/FluidDatePicker/FluidDatePicker.Skeleton.js +2 -2
- package/lib/components/FluidDatePicker/FluidDatePicker.d.ts +39 -0
- package/lib/components/FluidDatePicker/FluidDatePicker.js +3 -4
- package/lib/components/FluidDatePicker/index.d.ts +13 -0
- package/lib/components/FluidDatePickerInput/FluidDatePickerInput.d.ts +10 -0
- package/lib/components/FluidDatePickerInput/FluidDatePickerInput.js +1 -2
- package/lib/components/FluidDatePickerInput/index.d.ts +9 -0
- package/lib/components/FluidMultiSelect/FluidFilterableMultiSelect.d.ts +144 -0
- package/lib/components/FluidMultiSelect/FluidMultiSelect.Skeleton.d.ts +15 -0
- package/lib/components/FluidMultiSelect/FluidMultiSelect.Skeleton.js +1 -2
- package/lib/components/FluidMultiSelect/FluidMultiSelect.d.ts +149 -0
- package/lib/components/FluidMultiSelect/FluidMultiSelect.js +5 -3
- package/lib/components/FluidMultiSelect/index.d.ts +13 -0
- package/lib/components/FluidNumberInput/index.d.ts +2 -2
- package/lib/components/FluidSearch/index.d.ts +2 -2
- package/lib/components/FluidSelect/index.d.ts +2 -2
- package/lib/components/FluidTimePicker/index.d.ts +2 -2
- package/lib/components/Modal/Modal.js +1 -1
- package/lib/components/MultiSelect/FilterableMultiSelect.d.ts +2 -2
- package/lib/components/Tabs/usePressable.js +2 -0
- package/lib/components/Tooltip/DefinitionTooltip.js +4 -2
- package/lib/index.js +14 -14
- package/package.json +9 -9
|
@@ -158,6 +158,7 @@ export interface ComboBoxProps<ItemType> extends Omit<InputHTMLAttributes<HTMLIn
|
|
|
158
158
|
* Specify your own filtering logic by passing in a `shouldFilterItem`
|
|
159
159
|
* function that takes in the current input and an item and passes back
|
|
160
160
|
* whether or not the item should be filtered.
|
|
161
|
+
* this prop will be ignored if `typeahead` prop is enabled
|
|
161
162
|
*/
|
|
162
163
|
shouldFilterItem?: (input: {
|
|
163
164
|
item: ItemType;
|
|
@@ -177,6 +178,10 @@ export interface ComboBoxProps<ItemType> extends Omit<InputHTMLAttributes<HTMLIn
|
|
|
177
178
|
* combobox via ARIA attributes.
|
|
178
179
|
*/
|
|
179
180
|
titleText?: ReactNode;
|
|
181
|
+
/**
|
|
182
|
+
* **Experimental**: will enable autcomplete and typeahead for the input field
|
|
183
|
+
*/
|
|
184
|
+
typeahead?: boolean;
|
|
180
185
|
/**
|
|
181
186
|
* Specify whether the control is currently in warning state
|
|
182
187
|
*/
|
|
@@ -9,7 +9,7 @@ import { extends as _extends } from '../../_virtual/_rollupPluginBabelHelpers.js
|
|
|
9
9
|
import cx from 'classnames';
|
|
10
10
|
import { useCombobox } from 'downshift';
|
|
11
11
|
import PropTypes from 'prop-types';
|
|
12
|
-
import React__default, { forwardRef, useEffect, useContext,
|
|
12
|
+
import React__default, { forwardRef, useState, useRef, useEffect, useContext, useCallback, useMemo } from 'react';
|
|
13
13
|
import '../Text/index.js';
|
|
14
14
|
import { WarningFilled, WarningAltFilled, Checkmark } from '@carbon/icons-react';
|
|
15
15
|
import ListBox from '../ListBox/index.js';
|
|
@@ -36,8 +36,7 @@ const {
|
|
|
36
36
|
ItemMouseMove,
|
|
37
37
|
InputKeyDownArrowUp,
|
|
38
38
|
InputKeyDownArrowDown,
|
|
39
|
-
MenuMouseLeave
|
|
40
|
-
FunctionSelectItem
|
|
39
|
+
MenuMouseLeave
|
|
41
40
|
} = useCombobox.stateChangeTypes;
|
|
42
41
|
const defaultItemToString = item => {
|
|
43
42
|
if (typeof item === 'string') {
|
|
@@ -52,26 +51,42 @@ const defaultItemToString = item => {
|
|
|
52
51
|
return '';
|
|
53
52
|
};
|
|
54
53
|
const defaultShouldFilterItem = () => true;
|
|
55
|
-
const
|
|
54
|
+
const autocompleteCustomFilter = _ref => {
|
|
55
|
+
let {
|
|
56
|
+
item,
|
|
57
|
+
inputValue
|
|
58
|
+
} = _ref;
|
|
59
|
+
if (inputValue === null || inputValue === '') {
|
|
60
|
+
return true; // Show all items if there's no input
|
|
61
|
+
}
|
|
62
|
+
const lowercaseItem = item.toLowerCase();
|
|
63
|
+
const lowercaseInput = inputValue.toLowerCase();
|
|
64
|
+
return lowercaseItem.startsWith(lowercaseInput);
|
|
65
|
+
};
|
|
66
|
+
const getInputValue = _ref2 => {
|
|
56
67
|
let {
|
|
57
68
|
initialSelectedItem,
|
|
58
69
|
inputValue,
|
|
59
70
|
itemToString,
|
|
60
|
-
selectedItem
|
|
61
|
-
|
|
71
|
+
selectedItem,
|
|
72
|
+
prevSelectedItem
|
|
73
|
+
} = _ref2;
|
|
62
74
|
if (selectedItem) {
|
|
63
75
|
return itemToString(selectedItem);
|
|
64
76
|
}
|
|
65
77
|
if (initialSelectedItem) {
|
|
66
78
|
return itemToString(initialSelectedItem);
|
|
67
79
|
}
|
|
80
|
+
if (!selectedItem && prevSelectedItem) {
|
|
81
|
+
return '';
|
|
82
|
+
}
|
|
68
83
|
return inputValue || '';
|
|
69
84
|
};
|
|
70
|
-
const findHighlightedIndex = (
|
|
85
|
+
const findHighlightedIndex = (_ref3, inputValue) => {
|
|
71
86
|
let {
|
|
72
87
|
items,
|
|
73
88
|
itemToString = defaultItemToString
|
|
74
|
-
} =
|
|
89
|
+
} = _ref3;
|
|
75
90
|
if (!inputValue) {
|
|
76
91
|
return -1;
|
|
77
92
|
}
|
|
@@ -94,6 +109,9 @@ const findHighlightedIndex = (_ref2, inputValue) => {
|
|
|
94
109
|
*/
|
|
95
110
|
|
|
96
111
|
const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
112
|
+
const [cursorPosition, setCursorPosition] = useState(0);
|
|
113
|
+
const prevInputLengthRef = useRef(0);
|
|
114
|
+
const inputRef = useRef(null);
|
|
97
115
|
const {
|
|
98
116
|
['aria-label']: ariaLabel = 'Choose an item',
|
|
99
117
|
ariaLabel: deprecatedAriaLabel,
|
|
@@ -122,6 +140,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
122
140
|
size,
|
|
123
141
|
titleText,
|
|
124
142
|
translateWithId,
|
|
143
|
+
typeahead = false,
|
|
125
144
|
warn,
|
|
126
145
|
warnText,
|
|
127
146
|
allowCustomValue = false,
|
|
@@ -155,33 +174,68 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
155
174
|
}
|
|
156
175
|
}
|
|
157
176
|
}, [autoAlign, floatingStyles, refs.floating, parentWidth]);
|
|
158
|
-
const prefix = usePrefix();
|
|
159
|
-
const {
|
|
160
|
-
isFluid
|
|
161
|
-
} = useContext(FormContext);
|
|
162
|
-
const textInput = useRef(null);
|
|
163
|
-
const comboBoxInstanceId = useId();
|
|
164
177
|
const [inputValue, setInputValue] = useState(getInputValue({
|
|
165
178
|
initialSelectedItem,
|
|
166
179
|
inputValue: '',
|
|
167
180
|
itemToString,
|
|
168
181
|
selectedItem: selectedItemProp
|
|
169
182
|
}));
|
|
183
|
+
const [typeaheadText, setTypeaheadText] = useState('');
|
|
184
|
+
useEffect(() => {
|
|
185
|
+
if (typeahead) {
|
|
186
|
+
if (inputValue.length >= prevInputLengthRef.current) {
|
|
187
|
+
if (inputValue) {
|
|
188
|
+
const filteredItems = items.filter(item => autocompleteCustomFilter({
|
|
189
|
+
item: itemToString(item),
|
|
190
|
+
inputValue: inputValue
|
|
191
|
+
}));
|
|
192
|
+
if (filteredItems.length > 0) {
|
|
193
|
+
const suggestion = itemToString(filteredItems[0]);
|
|
194
|
+
setTypeaheadText(suggestion.slice(inputValue.length));
|
|
195
|
+
} else {
|
|
196
|
+
setTypeaheadText('');
|
|
197
|
+
}
|
|
198
|
+
} else {
|
|
199
|
+
setTypeaheadText('');
|
|
200
|
+
}
|
|
201
|
+
} else {
|
|
202
|
+
setTypeaheadText('');
|
|
203
|
+
}
|
|
204
|
+
prevInputLengthRef.current = inputValue.length;
|
|
205
|
+
}
|
|
206
|
+
}, [typeahead, inputValue, items, itemToString, autocompleteCustomFilter]);
|
|
207
|
+
const prefix = usePrefix();
|
|
208
|
+
const {
|
|
209
|
+
isFluid
|
|
210
|
+
} = useContext(FormContext);
|
|
211
|
+
const textInput = useRef(null);
|
|
212
|
+
const comboBoxInstanceId = useId();
|
|
170
213
|
const [isFocused, setIsFocused] = useState(false);
|
|
171
|
-
const [prevSelectedItem, setPrevSelectedItem] = useState();
|
|
172
|
-
const [doneInitialSelectedItem, setDoneInitialSelectedItem] = useState(false);
|
|
173
214
|
const savedOnInputChange = useRef(onInputChange);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
215
|
+
const prevSelectedItemProp = useRef(selectedItemProp);
|
|
216
|
+
|
|
217
|
+
// fully controlled combobox: handle changes to selectedItemProp
|
|
218
|
+
useEffect(() => {
|
|
219
|
+
if (prevSelectedItemProp.current !== selectedItemProp) {
|
|
220
|
+
const currentInputValue = getInputValue({
|
|
221
|
+
initialSelectedItem,
|
|
222
|
+
inputValue,
|
|
223
|
+
itemToString,
|
|
224
|
+
selectedItem: selectedItemProp,
|
|
225
|
+
prevSelectedItem: prevSelectedItemProp.current
|
|
226
|
+
});
|
|
227
|
+
setInputValue(currentInputValue);
|
|
228
|
+
onChange({
|
|
229
|
+
selectedItem: selectedItemProp,
|
|
230
|
+
inputValue: currentInputValue
|
|
231
|
+
});
|
|
232
|
+
prevSelectedItemProp.current = selectedItemProp;
|
|
233
|
+
}
|
|
234
|
+
}, [selectedItemProp]);
|
|
235
|
+
const filterItems = (items, itemToString, inputValue) => items.filter(item => typeahead ? autocompleteCustomFilter({
|
|
236
|
+
item: itemToString(item),
|
|
237
|
+
inputValue
|
|
238
|
+
}) : shouldFilterItem ? shouldFilterItem({
|
|
185
239
|
item,
|
|
186
240
|
itemToString,
|
|
187
241
|
inputValue
|
|
@@ -204,7 +258,7 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
204
258
|
...props,
|
|
205
259
|
items: filteredItems(inputValue)
|
|
206
260
|
}, inputValue);
|
|
207
|
-
const stateReducer =
|
|
261
|
+
const stateReducer = useCallback((state, actionAndChanges) => {
|
|
208
262
|
const {
|
|
209
263
|
type,
|
|
210
264
|
changes
|
|
@@ -240,14 +294,6 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
240
294
|
}
|
|
241
295
|
return changes;
|
|
242
296
|
}
|
|
243
|
-
case FunctionSelectItem:
|
|
244
|
-
if (onChange) {
|
|
245
|
-
onChange({
|
|
246
|
-
selectedItem: changes.selectedItem,
|
|
247
|
-
inputValue: changes.inputValue
|
|
248
|
-
});
|
|
249
|
-
}
|
|
250
|
-
return changes;
|
|
251
297
|
case InputKeyDownEnter:
|
|
252
298
|
if (allowCustomValue) {
|
|
253
299
|
setInputValue(inputValue);
|
|
@@ -304,6 +350,12 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
304
350
|
if (onToggleClick) {
|
|
305
351
|
onToggleClick(event);
|
|
306
352
|
}
|
|
353
|
+
if (readOnly) {
|
|
354
|
+
// Prevent the list from opening if readOnly is true
|
|
355
|
+
event.preventDownshiftDefault = true;
|
|
356
|
+
event?.persist?.();
|
|
357
|
+
return;
|
|
358
|
+
}
|
|
307
359
|
if (event.target === textInput.current && isOpen) {
|
|
308
360
|
event.preventDownshiftDefault = true;
|
|
309
361
|
event?.persist?.();
|
|
@@ -371,25 +423,34 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
371
423
|
itemToString: item => {
|
|
372
424
|
return itemToString(item);
|
|
373
425
|
},
|
|
374
|
-
onInputValueChange(
|
|
426
|
+
onInputValueChange(_ref4) {
|
|
375
427
|
let {
|
|
376
428
|
inputValue
|
|
377
|
-
} =
|
|
378
|
-
|
|
379
|
-
|
|
429
|
+
} = _ref4;
|
|
430
|
+
const normalizedInput = inputValue || '';
|
|
431
|
+
setInputValue(normalizedInput);
|
|
432
|
+
if (selectedItemProp && !inputValue) {
|
|
433
|
+
// ensure onChange is called when selectedItem is cleared
|
|
434
|
+
onChange({
|
|
435
|
+
selectedItem,
|
|
436
|
+
inputValue: normalizedInput
|
|
437
|
+
});
|
|
438
|
+
}
|
|
439
|
+
setHighlightedIndex(indexToHighlight(normalizedInput));
|
|
440
|
+
setCursorPosition(inputValue === null ? 0 : normalizedInput.length);
|
|
380
441
|
},
|
|
381
|
-
onSelectedItemChange(
|
|
442
|
+
onSelectedItemChange(_ref5) {
|
|
382
443
|
let {
|
|
383
444
|
selectedItem
|
|
384
|
-
} =
|
|
445
|
+
} = _ref5;
|
|
385
446
|
onChange({
|
|
386
447
|
selectedItem
|
|
387
448
|
});
|
|
388
449
|
},
|
|
389
|
-
onHighlightedIndexChange:
|
|
450
|
+
onHighlightedIndexChange: _ref6 => {
|
|
390
451
|
let {
|
|
391
452
|
highlightedIndex
|
|
392
|
-
} =
|
|
453
|
+
} = _ref6;
|
|
393
454
|
if (highlightedIndex > -1 && typeof window !== undefined) {
|
|
394
455
|
const itemArray = document.querySelectorAll(`li.${prefix}--list-box__menu-item[role="option"]`);
|
|
395
456
|
const highlightedItem = itemArray[highlightedIndex];
|
|
@@ -425,6 +486,11 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
425
486
|
};
|
|
426
487
|
}
|
|
427
488
|
}, [closeMenu, openMenu, reset, selectItem, setHighlightedIndex, downshiftSetInputValue, toggleMenu]);
|
|
489
|
+
useEffect(() => {
|
|
490
|
+
if (inputRef.current) {
|
|
491
|
+
inputRef.current.setSelectionRange(cursorPosition, cursorPosition);
|
|
492
|
+
}
|
|
493
|
+
}, [inputValue, cursorPosition]);
|
|
428
494
|
const buttonProps = getToggleButtonProps({
|
|
429
495
|
disabled: disabled || readOnly,
|
|
430
496
|
onClick: handleToggleClick(isOpen),
|
|
@@ -452,6 +518,12 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
452
518
|
if (evt.key !== 'Tab') {
|
|
453
519
|
evt.preventDefault();
|
|
454
520
|
}
|
|
521
|
+
},
|
|
522
|
+
onClick: evt => {
|
|
523
|
+
// Prevent the default behavior which would open the list
|
|
524
|
+
evt.preventDefault();
|
|
525
|
+
// Focus on the element as per readonly input behavior
|
|
526
|
+
evt.currentTarget.focus();
|
|
455
527
|
}
|
|
456
528
|
} : {};
|
|
457
529
|
|
|
@@ -465,6 +537,16 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
465
537
|
'aria-label': deprecatedAriaLabel || ariaLabel,
|
|
466
538
|
ref: autoAlign ? refs.setFloating : null
|
|
467
539
|
}), [autoAlign, deprecatedAriaLabel, ariaLabel, getMenuProps, refs.setFloating]);
|
|
540
|
+
useEffect(() => {
|
|
541
|
+
if (textInput.current) {
|
|
542
|
+
if (inputRef.current && typeaheadText) {
|
|
543
|
+
const selectionStart = inputValue.length;
|
|
544
|
+
const selectionEnd = selectionStart + typeaheadText.length;
|
|
545
|
+
inputRef.current.value = inputValue + typeaheadText;
|
|
546
|
+
inputRef.current.setSelectionRange(selectionStart, selectionEnd);
|
|
547
|
+
}
|
|
548
|
+
}
|
|
549
|
+
}, [inputValue, typeaheadText]);
|
|
468
550
|
return /*#__PURE__*/React__default.createElement("div", {
|
|
469
551
|
className: wrapperClasses
|
|
470
552
|
}, titleText && /*#__PURE__*/React__default.createElement(Text, _extends({
|
|
@@ -497,7 +579,12 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
497
579
|
}, getInputProps({
|
|
498
580
|
'aria-controls': isOpen ? undefined : menuProps.id,
|
|
499
581
|
placeholder,
|
|
500
|
-
|
|
582
|
+
value: inputValue,
|
|
583
|
+
onChange: e => {
|
|
584
|
+
const newValue = e.target.value;
|
|
585
|
+
downshiftSetInputValue(newValue);
|
|
586
|
+
},
|
|
587
|
+
ref: mergeRefs(textInput, ref, inputRef),
|
|
501
588
|
onKeyDown: event => {
|
|
502
589
|
if (match(event, Space)) {
|
|
503
590
|
event.stopPropagation();
|
|
@@ -545,6 +632,16 @@ const ComboBox = /*#__PURE__*/forwardRef((props, ref) => {
|
|
|
545
632
|
toggleMenu();
|
|
546
633
|
}
|
|
547
634
|
}
|
|
635
|
+
if (typeahead && event.key === 'Tab') {
|
|
636
|
+
// event.preventDefault();
|
|
637
|
+
const matchingItem = items.find(item => itemToString(item).toLowerCase().startsWith(inputValue.toLowerCase()));
|
|
638
|
+
if (matchingItem) {
|
|
639
|
+
const newValue = itemToString(matchingItem);
|
|
640
|
+
downshiftSetInputValue(newValue);
|
|
641
|
+
setCursorPosition(newValue.length);
|
|
642
|
+
selectItem(matchingItem);
|
|
643
|
+
}
|
|
644
|
+
}
|
|
548
645
|
}
|
|
549
646
|
}), rest, readOnlyEventHandlers, {
|
|
550
647
|
readOnly: readOnly,
|
|
@@ -737,6 +834,7 @@ ComboBox.propTypes = {
|
|
|
737
834
|
* Specify your own filtering logic by passing in a `shouldFilterItem`
|
|
738
835
|
* function that takes in the current input and an item and passes back
|
|
739
836
|
* whether or not the item should be filtered.
|
|
837
|
+
* this prop will be ignored if `typeahead` prop is enabled
|
|
740
838
|
*/
|
|
741
839
|
shouldFilterItem: PropTypes.func,
|
|
742
840
|
/**
|
|
@@ -757,6 +855,10 @@ ComboBox.propTypes = {
|
|
|
757
855
|
* and returns the localized string for the message
|
|
758
856
|
*/
|
|
759
857
|
translateWithId: PropTypes.func,
|
|
858
|
+
/**
|
|
859
|
+
* **Experimental**: will enable autcomplete and typeahead for the input field
|
|
860
|
+
*/
|
|
861
|
+
typeahead: PropTypes.bool,
|
|
760
862
|
/**
|
|
761
863
|
* Specify whether the control is currently in warning state
|
|
762
864
|
*/
|
|
@@ -44,7 +44,7 @@ const ModalHeader = /*#__PURE__*/React__default.forwardRef(function ModalHeader(
|
|
|
44
44
|
ref: ref
|
|
45
45
|
}), label && /*#__PURE__*/React__default.createElement("h2", {
|
|
46
46
|
className: labelClass
|
|
47
|
-
}, label), title && /*#__PURE__*/React__default.createElement("
|
|
47
|
+
}, label), title && /*#__PURE__*/React__default.createElement("h2", {
|
|
48
48
|
className: titleClass
|
|
49
49
|
}, title), children, /*#__PURE__*/React__default.createElement("div", {
|
|
50
50
|
className: `${prefix}--modal-close-button`
|
|
@@ -22,7 +22,7 @@ import '../FluidForm/FluidForm.js';
|
|
|
22
22
|
import { FormContext } from '../FluidForm/FormContext.js';
|
|
23
23
|
import { WarningFilled, WarningAltFilled } from '@carbon/icons-react';
|
|
24
24
|
import { match } from '../../internal/keyboard/match.js';
|
|
25
|
-
import { Escape, ArrowDown, Tab } from '../../internal/keyboard/keys.js';
|
|
25
|
+
import { Escape, ArrowDown, Enter, Tab } from '../../internal/keyboard/keys.js';
|
|
26
26
|
|
|
27
27
|
// Weekdays shorthand for english locale
|
|
28
28
|
l10n.en.weekdays.shorthand.forEach((_day, index) => {
|
|
@@ -391,9 +391,6 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
|
|
|
391
391
|
}
|
|
392
392
|
}
|
|
393
393
|
function handleOnChange(event) {
|
|
394
|
-
if (datePickerType == 'single' && closeOnSelect) {
|
|
395
|
-
calendar.calendarContainer.classList.remove('open');
|
|
396
|
-
}
|
|
397
394
|
const {
|
|
398
395
|
target
|
|
399
396
|
} = event;
|
|
@@ -409,12 +406,16 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
|
|
|
409
406
|
if (calendar.selectedDates.length === 0) {
|
|
410
407
|
return;
|
|
411
408
|
}
|
|
412
|
-
|
|
413
|
-
|
|
409
|
+
}
|
|
410
|
+
function handleKeyPress(event) {
|
|
411
|
+
if (match(event, Enter) && closeOnSelect && datePickerType == 'single') {
|
|
412
|
+
calendar.calendarContainer.classList.remove('open');
|
|
413
|
+
}
|
|
414
414
|
}
|
|
415
415
|
if (start) {
|
|
416
416
|
start.addEventListener('keydown', handleArrowDown);
|
|
417
417
|
start.addEventListener('change', handleOnChange);
|
|
418
|
+
start.addEventListener('keypress', handleKeyPress);
|
|
418
419
|
if (calendar && calendar.calendarContainer) {
|
|
419
420
|
// Flatpickr's calendar dialog is not rendered in a landmark causing an
|
|
420
421
|
// error with IBM Equal Access Accessibility Checker so we add an aria
|
|
@@ -427,6 +428,7 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
|
|
|
427
428
|
if (end) {
|
|
428
429
|
end.addEventListener('keydown', handleArrowDown);
|
|
429
430
|
end.addEventListener('change', handleOnChange);
|
|
431
|
+
end.addEventListener('keypress', handleKeyPress);
|
|
430
432
|
}
|
|
431
433
|
|
|
432
434
|
//component did unmount equivalent
|
|
@@ -450,10 +452,12 @@ const DatePicker = /*#__PURE__*/React__default.forwardRef(function DatePicker(_r
|
|
|
450
452
|
if (start) {
|
|
451
453
|
start.removeEventListener('keydown', handleArrowDown);
|
|
452
454
|
start.removeEventListener('change', handleOnChange);
|
|
455
|
+
start.removeEventListener('keypress', handleKeyPress);
|
|
453
456
|
}
|
|
454
457
|
if (end) {
|
|
455
458
|
end.removeEventListener('keydown', handleArrowDown);
|
|
456
459
|
end.removeEventListener('change', handleOnChange);
|
|
460
|
+
end.removeEventListener('change', handleKeyPress);
|
|
457
461
|
}
|
|
458
462
|
};
|
|
459
463
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
@@ -207,7 +207,9 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
207
207
|
|
|
208
208
|
// needs to be Capitalized for react to render it correctly
|
|
209
209
|
const ItemToElement = itemToElement;
|
|
210
|
-
const toggleButtonProps = getToggleButtonProps(
|
|
210
|
+
const toggleButtonProps = getToggleButtonProps({
|
|
211
|
+
'aria-label': ariaLabel || deprecatedAriaLabel
|
|
212
|
+
});
|
|
211
213
|
const helper = helperText && !isFluid ? /*#__PURE__*/React__default.createElement("div", {
|
|
212
214
|
id: helperId,
|
|
213
215
|
className: helperClasses
|
|
@@ -282,7 +284,6 @@ const Dropdown = /*#__PURE__*/React__default.forwardRef((_ref, ref) => {
|
|
|
282
284
|
}, getLabelProps()), titleText), /*#__PURE__*/React__default.createElement(ListBox, {
|
|
283
285
|
onFocus: handleFocus,
|
|
284
286
|
onBlur: handleFocus,
|
|
285
|
-
"aria-label": deprecatedAriaLabel || ariaLabel,
|
|
286
287
|
size: size$1,
|
|
287
288
|
className: className,
|
|
288
289
|
invalid: invalid,
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2015, 2023
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import PropTypes from 'prop-types';
|
|
8
|
+
import React, { ReactNode } from 'react';
|
|
9
|
+
interface FeatureFlagsProps {
|
|
10
|
+
children?: ReactNode;
|
|
11
|
+
flags?: Record<string, boolean>;
|
|
12
|
+
enableV12TileDefaultIcons?: boolean;
|
|
13
|
+
enableV12TileRadioIcons?: boolean;
|
|
14
|
+
enableV12Overflowmenu?: boolean;
|
|
15
|
+
enableTreeviewControllable?: boolean;
|
|
16
|
+
enableExperimentalFocusWrapWithoutSentinels?: boolean;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Our FeatureFlagContext is used alongside the FeatureFlags component to enable
|
|
20
|
+
* or disable feature flags in a given React tree
|
|
21
|
+
*/
|
|
22
|
+
declare const FeatureFlagContext: React.Context<any>;
|
|
23
|
+
/**
|
|
24
|
+
* Supports an object of feature flag values with the `flags` prop, merging them
|
|
25
|
+
* along with the current `FeatureFlagContext` to provide consumers to check if
|
|
26
|
+
* a feature flag is enabled or disabled in a given React tree
|
|
27
|
+
*/
|
|
28
|
+
declare function FeatureFlags({ children, flags, enableV12TileDefaultIcons, enableV12TileRadioIcons, enableV12Overflowmenu, enableTreeviewControllable, enableExperimentalFocusWrapWithoutSentinels, }: FeatureFlagsProps): JSX.Element;
|
|
29
|
+
declare namespace FeatureFlags {
|
|
30
|
+
var propTypes: {
|
|
31
|
+
children: PropTypes.Requireable<PropTypes.ReactNodeLike>;
|
|
32
|
+
/**
|
|
33
|
+
* Provide the feature flags to enabled or disabled in the current Rea,ct tree
|
|
34
|
+
*/
|
|
35
|
+
flags: (props: any, propName: any, componentName: any, ...rest: any[]) => any;
|
|
36
|
+
enableV12TileDefaultIcons: PropTypes.Requireable<boolean>;
|
|
37
|
+
enableV12TileRadioIcons: PropTypes.Requireable<boolean>;
|
|
38
|
+
enableV12Overflowmenu: PropTypes.Requireable<boolean>;
|
|
39
|
+
enableTreeviewControllable: PropTypes.Requireable<boolean>;
|
|
40
|
+
enableExperimentalFocusWrapWithoutSentinels: PropTypes.Requireable<boolean>;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Access whether a given flag is enabled or disabled in a given
|
|
45
|
+
* FeatureFlagContext
|
|
46
|
+
*
|
|
47
|
+
* @returns {boolean}
|
|
48
|
+
*/
|
|
49
|
+
declare function useFeatureFlag(flag: any): any;
|
|
50
|
+
/**
|
|
51
|
+
* Access all feature flag information for the given FeatureFlagContext
|
|
52
|
+
*
|
|
53
|
+
* @returns {FeatureFlagScope}
|
|
54
|
+
*/
|
|
55
|
+
declare function useFeatureFlags(): any;
|
|
56
|
+
export { FeatureFlags, FeatureFlagContext, useFeatureFlags, useFeatureFlag };
|
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
* LICENSE file in the root directory of this source tree.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import { FeatureFlags as FeatureFlags$1
|
|
8
|
+
import { createScope, FeatureFlags as FeatureFlags$1 } from '@carbon/feature-flags';
|
|
9
9
|
import PropTypes from 'prop-types';
|
|
10
|
-
import React__default, {
|
|
10
|
+
import React__default, { useContext, useState, useRef, useEffect, createContext } from 'react';
|
|
11
11
|
import deprecate from '../../prop-types/deprecate.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2016, 2023
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React from 'react';
|
|
8
|
+
export interface FluidComboBoxSkeletonProps {
|
|
9
|
+
/**
|
|
10
|
+
* Specify an optional className to add.
|
|
11
|
+
*/
|
|
12
|
+
className?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const FluidComboBoxSkeleton: React.FC<FluidComboBoxSkeletonProps>;
|
|
15
|
+
export default FluidComboBoxSkeleton;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copyright IBM Corp. 2022
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the Apache-2.0 license found in the
|
|
5
|
+
* LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/
|
|
7
|
+
import React, { ComponentType } from 'react';
|
|
8
|
+
import { ComboBoxProps } from '../ComboBox/ComboBox';
|
|
9
|
+
type ItemToStringHandler<ItemType> = (item: ItemType | null) => string;
|
|
10
|
+
interface OnChangeData<ItemType> {
|
|
11
|
+
selectedItem: ItemType | null | undefined;
|
|
12
|
+
inputValue?: string | null;
|
|
13
|
+
}
|
|
14
|
+
export interface FluidComboBoxProps<ItemType> extends ComboBoxProps<ItemType> {
|
|
15
|
+
/**
|
|
16
|
+
* Specify an optional className to be applied to the outer FluidForm wrapper
|
|
17
|
+
*/
|
|
18
|
+
className?: string;
|
|
19
|
+
/**
|
|
20
|
+
* Specify the direction of the dropdown. Can be either top or bottom.
|
|
21
|
+
*/
|
|
22
|
+
direction?: 'top' | 'bottom';
|
|
23
|
+
/**
|
|
24
|
+
* Specify whether the `<input>` should be disabled
|
|
25
|
+
*/
|
|
26
|
+
disabled?: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* Specify a custom `id` for the `<input>`
|
|
29
|
+
*/
|
|
30
|
+
id: string;
|
|
31
|
+
/**
|
|
32
|
+
* Allow users to pass in an arbitrary item or a string (in case their items are an array of strings)
|
|
33
|
+
* from their collection that are pre-selected
|
|
34
|
+
*/
|
|
35
|
+
initialSelectedItem?: ItemType;
|
|
36
|
+
/**
|
|
37
|
+
* Specify if the currently selected value is invalid.
|
|
38
|
+
*/
|
|
39
|
+
invalid?: boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Provide the text that is displayed when the control is in an invalid state
|
|
42
|
+
*/
|
|
43
|
+
invalidText?: React.ReactNode;
|
|
44
|
+
/**
|
|
45
|
+
* Specify if the `FluidComboBox` should render its menu items in condensed mode
|
|
46
|
+
*/
|
|
47
|
+
isCondensed?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Function to render items as custom components instead of strings.
|
|
50
|
+
* Defaults to null and is overridden by a getter
|
|
51
|
+
*/
|
|
52
|
+
itemToElement?: ComponentType<ItemType> | null;
|
|
53
|
+
/**
|
|
54
|
+
* Helper function passed to downshift that allows the library to render a
|
|
55
|
+
* given item to a string label. By default, it extracts the `label` field
|
|
56
|
+
* from a given item to serve as the item label in the list.
|
|
57
|
+
*/
|
|
58
|
+
itemToString?: ItemToStringHandler<ItemType>;
|
|
59
|
+
/**
|
|
60
|
+
* We try to stay as generic as possible here to allow individuals to pass
|
|
61
|
+
* in a collection of whatever kind of data structure they prefer
|
|
62
|
+
*/
|
|
63
|
+
items: ItemType[];
|
|
64
|
+
/**
|
|
65
|
+
* Generic `label` that will be used as the textual representation of what
|
|
66
|
+
* this field is for
|
|
67
|
+
*/
|
|
68
|
+
label: React.ReactNode;
|
|
69
|
+
/**
|
|
70
|
+
* `onChange` is a utility for this controlled component to communicate to a
|
|
71
|
+
* consuming component what kind of internal state changes are occurring.
|
|
72
|
+
*/
|
|
73
|
+
onChange: (data: OnChangeData<ItemType>) => void;
|
|
74
|
+
/**
|
|
75
|
+
* An optional callback to render the currently selected item as a react element instead of only
|
|
76
|
+
* as a string.
|
|
77
|
+
*/
|
|
78
|
+
renderSelectedItem?: (selectedItem: ItemType) => React.ReactNode;
|
|
79
|
+
/**
|
|
80
|
+
* In the case you want to control the dropdown selection entirely.
|
|
81
|
+
* */
|
|
82
|
+
selectedItem?: ItemType | null;
|
|
83
|
+
/**
|
|
84
|
+
* Provide the title text that will be read by a screen reader when
|
|
85
|
+
* visiting this control
|
|
86
|
+
*/
|
|
87
|
+
titleText?: React.ReactNode;
|
|
88
|
+
/**
|
|
89
|
+
* Callback function for translating ListBoxMenuIcon SVG title
|
|
90
|
+
*/
|
|
91
|
+
translateWithId?: (id: string) => string;
|
|
92
|
+
/**
|
|
93
|
+
* Specify whether the control is currently in warning state
|
|
94
|
+
*/
|
|
95
|
+
warn?: boolean;
|
|
96
|
+
/**
|
|
97
|
+
* Provide the text that is displayed when the control is in warning state
|
|
98
|
+
*/
|
|
99
|
+
warnText?: React.ReactNode;
|
|
100
|
+
}
|
|
101
|
+
declare const FluidComboBox: React.ForwardRefExoticComponent<FluidComboBoxProps<unknown> & React.RefAttributes<HTMLInputElement>>;
|
|
102
|
+
export default FluidComboBox;
|
|
@@ -91,7 +91,7 @@ FluidComboBox.propTypes = {
|
|
|
91
91
|
* `onChange` is a utility for this controlled component to communicate to a
|
|
92
92
|
* consuming component what kind of internal state changes are occurring.
|
|
93
93
|
*/
|
|
94
|
-
onChange: PropTypes.func,
|
|
94
|
+
onChange: PropTypes.func.isRequired,
|
|
95
95
|
/**
|
|
96
96
|
* An optional callback to render the currently selected item as a react element instead of only
|
|
97
97
|
* as a string.
|
|
@@ -119,6 +119,5 @@ FluidComboBox.propTypes = {
|
|
|
119
119
|
*/
|
|
120
120
|
warnText: PropTypes.node
|
|
121
121
|
};
|
|
122
|
-
var FluidComboBox$1 = FluidComboBox;
|
|
123
122
|
|
|
124
|
-
export { FluidComboBox
|
|
123
|
+
export { FluidComboBox as default };
|