@allxsmith/bestax-bulma 5.34.0 → 5.34.2
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/esm/components/Dropdown.js +8 -3
- package/dist/esm/components/Dropdown.js.map +1 -1
- package/dist/esm/components/Loading.js +5 -4
- package/dist/esm/components/Loading.js.map +1 -1
- package/dist/esm/components/Modal.js +11 -4
- package/dist/esm/components/Modal.js.map +1 -1
- package/dist/esm/components/Sidebar.js +5 -4
- package/dist/esm/components/Sidebar.js.map +1 -1
- package/dist/esm/components/Toast.js +7 -5
- package/dist/esm/components/Toast.js.map +1 -1
- package/dist/esm/form/Autocomplete.js +17 -2
- package/dist/esm/form/Autocomplete.js.map +1 -1
- package/dist/esm/form/Field.js +3 -3
- package/dist/esm/form/Field.js.map +1 -1
- package/dist/esm/form/FormContext.js +2 -1
- package/dist/esm/form/FormContext.js.map +1 -1
- package/dist/esm/form/Taginput.js +40 -6
- package/dist/esm/form/Taginput.js.map +1 -1
- package/dist/esm/form/_pickerInternals/PickerPopover.js +11 -3
- package/dist/esm/form/_pickerInternals/PickerPopover.js.map +1 -1
- package/dist/esm/form/useAutoLabelId.js.map +1 -1
- package/dist/index.cjs +107 -34
- package/dist/index.cjs.map +1 -1
- package/dist/types/components/Loading.d.ts +5 -1
- package/dist/types/components/Modal.d.ts +4 -1
- package/dist/types/components/Sidebar.d.ts +5 -1
- package/dist/types/components/Toast.d.ts +4 -1
- package/dist/types/form/Autocomplete.d.ts +13 -2
- package/dist/types/form/Field.d.ts +5 -5
- package/dist/types/form/FormContext.d.ts +2 -1
- package/dist/types/form/Taginput.d.ts +8 -3
- package/dist/types/form/useAutoLabelId.d.ts +2 -2
- package/dist/types-cjs/components/Loading.d.ts +5 -1
- package/dist/types-cjs/components/Modal.d.ts +4 -1
- package/dist/types-cjs/components/Sidebar.d.ts +5 -1
- package/dist/types-cjs/components/Toast.d.ts +4 -1
- package/dist/types-cjs/form/Autocomplete.d.ts +13 -2
- package/dist/types-cjs/form/Field.d.ts +5 -5
- package/dist/types-cjs/form/FormContext.d.ts +2 -1
- package/dist/types-cjs/form/Taginput.d.ts +8 -3
- package/dist/types-cjs/form/useAutoLabelId.d.ts +2 -2
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -2563,8 +2563,9 @@ const isBrowser$1 = (win, doc) => typeof win !== 'undefined' && typeof doc !== '
|
|
|
2563
2563
|
* the menu, so a letter typed on the trigger does nothing. Escape closes the
|
|
2564
2564
|
* menu and focuses the trigger, and Tab closes it and lets focus move on.
|
|
2565
2565
|
* Anything focusable in the menu that isn't an item, such as a field, keeps
|
|
2566
|
-
* its own keys apart from Escape and Tab
|
|
2567
|
-
*
|
|
2566
|
+
* its own keys apart from Escape and Tab, though an Escape it calls
|
|
2567
|
+
* `preventDefault()` on in its own `onKeyDown` stays its own and leaves the
|
|
2568
|
+
* menu open. For a panel built around fields, use `Popover`.
|
|
2568
2569
|
*
|
|
2569
2570
|
* @function
|
|
2570
2571
|
* @param {DropdownProps} props - Props for the Dropdown component.
|
|
@@ -2741,8 +2742,12 @@ const DropdownComponent = React.forwardRef(function DropdownComponent({ label, c
|
|
|
2741
2742
|
// Closing is Dropdown's: Escape and Tab close the menu from anywhere in
|
|
2742
2743
|
// it, a field included, and an empty or all-disabled menu too. Moving
|
|
2743
2744
|
// between the items, running them and typeahead are the hook's, which
|
|
2744
|
-
// acts only while focus is on the menu or one of its items.
|
|
2745
|
+
// acts only while focus is on the menu or one of its items. An Escape
|
|
2746
|
+
// something in the menu already used, such as a field's own list
|
|
2747
|
+
// closing on it, leaves the menu open for the next one.
|
|
2745
2748
|
if (e.key === 'Escape') {
|
|
2749
|
+
if (e.defaultPrevented)
|
|
2750
|
+
return;
|
|
2746
2751
|
e.preventDefault();
|
|
2747
2752
|
setActive(false);
|
|
2748
2753
|
onActiveChange?.(false);
|
|
@@ -4056,6 +4061,9 @@ const ModalRoot = React.forwardRef(function ModalRoot({ active, isActive, onClos
|
|
|
4056
4061
|
};
|
|
4057
4062
|
}, [isModalActive]);
|
|
4058
4063
|
// Escape closes; Tab cycles inside the modal. Both only for the topmost one.
|
|
4064
|
+
// The listener is on `window`, where a keydown arrives last, so everything
|
|
4065
|
+
// inside the modal has had the key first: React's handlers, and `document`
|
|
4066
|
+
// listeners added after this one, such as a date picker's.
|
|
4059
4067
|
React.useEffect(() => {
|
|
4060
4068
|
if (!isModalActive)
|
|
4061
4069
|
return undefined;
|
|
@@ -4065,11 +4073,15 @@ const ModalRoot = React.forwardRef(function ModalRoot({ active, isActive, onClos
|
|
|
4065
4073
|
return;
|
|
4066
4074
|
}
|
|
4067
4075
|
if (e.key === 'Escape') {
|
|
4068
|
-
|
|
4076
|
+
// Something inside already used this Escape, such as a popup that
|
|
4077
|
+
// closed on it, so the modal waits for the next one.
|
|
4078
|
+
if (closeOnEscape && !e.defaultPrevented)
|
|
4069
4079
|
onClose?.();
|
|
4070
4080
|
return;
|
|
4071
4081
|
}
|
|
4072
|
-
|
|
4082
|
+
// A trap inside the modal, such as a portaled popup's, already moved
|
|
4083
|
+
// focus on this Tab, so the modal leaves it where it went.
|
|
4084
|
+
if (e.key !== 'Tab' || !node || e.defaultPrevented)
|
|
4073
4085
|
return;
|
|
4074
4086
|
// Keep Tab within the modal — `aria-modal` hides the rest of the page
|
|
4075
4087
|
// from assistive technology, so the keyboard order has to agree.
|
|
@@ -4094,8 +4106,8 @@ const ModalRoot = React.forwardRef(function ModalRoot({ active, isActive, onClos
|
|
|
4094
4106
|
first.focus();
|
|
4095
4107
|
}
|
|
4096
4108
|
};
|
|
4097
|
-
|
|
4098
|
-
return () =>
|
|
4109
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
4110
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
4099
4111
|
}, [isModalActive, closeOnEscape, onClose]);
|
|
4100
4112
|
// Move focus into the modal on open, restore it on close
|
|
4101
4113
|
React.useEffect(() => {
|
|
@@ -5375,17 +5387,18 @@ const Loading = ({ active = false, isFullPage = false, size, color, canCancel =
|
|
|
5375
5387
|
onCancel();
|
|
5376
5388
|
}
|
|
5377
5389
|
};
|
|
5378
|
-
// Handle escape key
|
|
5390
|
+
// Handle escape key. On `window`, as in `Modal`, so a popup on the page has
|
|
5391
|
+
// had the key first, and an Escape it closed on doesn't cancel as well.
|
|
5379
5392
|
React.useEffect(() => {
|
|
5380
5393
|
if (!active || !canCancel || !onCancel)
|
|
5381
5394
|
return;
|
|
5382
5395
|
const handleKeyDown = (e) => {
|
|
5383
|
-
if (e.key === 'Escape') {
|
|
5396
|
+
if (e.key === 'Escape' && !e.defaultPrevented) {
|
|
5384
5397
|
onCancel();
|
|
5385
5398
|
}
|
|
5386
5399
|
};
|
|
5387
|
-
|
|
5388
|
-
return () =>
|
|
5400
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
5401
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
5389
5402
|
}, [active, canCancel, onCancel]);
|
|
5390
5403
|
// Prevent body scroll when full page loading is active. Ref-counted through
|
|
5391
5404
|
// the shared helper so an overlapping Modal/Dialog/Sidebar doesn't have its
|
|
@@ -7795,17 +7808,18 @@ const SidebarComponent = React.forwardRef(({ isOpen, onClose, position = 'left',
|
|
|
7795
7808
|
handleClose();
|
|
7796
7809
|
}
|
|
7797
7810
|
}, [overlayClose, handleClose]);
|
|
7798
|
-
// Handle escape key
|
|
7811
|
+
// Handle escape key. On `window`, as in `Modal`, so everything inside the
|
|
7812
|
+
// sidebar has had the key first, and an Escape it used is left to it.
|
|
7799
7813
|
React.useEffect(() => {
|
|
7800
7814
|
if (!isOpen || !escapeClose)
|
|
7801
7815
|
return;
|
|
7802
7816
|
const handleKeyDown = (e) => {
|
|
7803
|
-
if (e.key === 'Escape') {
|
|
7817
|
+
if (e.key === 'Escape' && !e.defaultPrevented) {
|
|
7804
7818
|
handleClose();
|
|
7805
7819
|
}
|
|
7806
7820
|
};
|
|
7807
|
-
|
|
7808
|
-
return () =>
|
|
7821
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
7822
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
7809
7823
|
}, [isOpen, escapeClose, handleClose]);
|
|
7810
7824
|
// Prevent body scroll when sidebar is open. Ref-counted through the shared
|
|
7811
7825
|
// helper so an overlapping Modal/Dialog/Loading doesn't unlock underneath.
|
|
@@ -8060,17 +8074,19 @@ const Toast = React.forwardRef(({ message, type = 'default', actionType, positio
|
|
|
8060
8074
|
document.removeEventListener('click', handleDocumentClick);
|
|
8061
8075
|
};
|
|
8062
8076
|
}, [dismissible, isVisible, handleClose]);
|
|
8077
|
+
// On `window`, as in `Modal`, so a popup on the page has had the key
|
|
8078
|
+
// first, and an Escape it closed on doesn't dismiss the toast as well.
|
|
8063
8079
|
React.useEffect(() => {
|
|
8064
|
-
if (!cancelable)
|
|
8080
|
+
if (!cancelable || !isVisible)
|
|
8065
8081
|
return undefined;
|
|
8066
8082
|
const handleKeyDown = (e) => {
|
|
8067
|
-
if (e.key === 'Escape') {
|
|
8083
|
+
if (e.key === 'Escape' && !e.defaultPrevented) {
|
|
8068
8084
|
handleClose();
|
|
8069
8085
|
}
|
|
8070
8086
|
};
|
|
8071
|
-
|
|
8072
|
-
return () =>
|
|
8073
|
-
}, [cancelable, handleClose]);
|
|
8087
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
8088
|
+
return () => window.removeEventListener('keydown', handleKeyDown);
|
|
8089
|
+
}, [cancelable, isVisible, handleClose]);
|
|
8074
8090
|
const containerClasses = usePrefixedClassNames('toast-container', {
|
|
8075
8091
|
[`is-${position}`]: true,
|
|
8076
8092
|
});
|
|
@@ -10694,7 +10710,8 @@ const FieldLabelForContext = React.createContext({});
|
|
|
10694
10710
|
* renders with, if it has one. An unlabeled Field passes both through
|
|
10695
10711
|
* together, so a control in the inner Field of a horizontal layout can tell
|
|
10696
10712
|
* the outer label names it, and point at that label by its id, as a range
|
|
10697
|
-
* Slider's thumbs (#981) and Autocomplete's
|
|
10713
|
+
* Slider's thumbs (#981) and Autocomplete's and Taginput's suggestion lists
|
|
10714
|
+
* (#998, #1082) do. The
|
|
10698
10715
|
* `htmlFor` is only ever compared with a control's own id, never adopted, so
|
|
10699
10716
|
* it hands out no id for a control. It keeps the generated id after the
|
|
10700
10717
|
* label drops a `for` nothing took (#1004), which no control's id matches
|
|
@@ -10949,9 +10966,9 @@ Control.displayName = 'Control';
|
|
|
10949
10966
|
* `id`, or give the horizontal `Field` a `label` prop, which renders this
|
|
10950
10967
|
* column and its `<label>` for you. A `<label>` you put here names the
|
|
10951
10968
|
* control through its `htmlFor` alone: a range `Slider`'s thumbs and an
|
|
10952
|
-
* `Autocomplete`'s suggestion list point `aria-labelledby` at
|
|
10953
|
-
* label only when its `label` prop renders it and it names the
|
|
10954
|
-
* Where it would not name the control on its own, as in an inner `Field`,
|
|
10969
|
+
* `Autocomplete`'s or `Taginput`'s suggestion list point `aria-labelledby` at
|
|
10970
|
+
* a `Field`'s label only when its `label` prop renders it and it names the
|
|
10971
|
+
* control. Where it would not name the control on its own, as in an inner `Field`,
|
|
10955
10972
|
* pass `labelProps={{ htmlFor, id }}` with a matching `id` on the control.
|
|
10956
10973
|
*
|
|
10957
10974
|
* @function
|
|
@@ -12654,6 +12671,11 @@ const nothingToAnnounce = [];
|
|
|
12654
12671
|
* />
|
|
12655
12672
|
*/
|
|
12656
12673
|
const Autocomplete = React.forwardRef(({ data = [], value: controlledValue, placeholder, field = 'label', clearable = false, openOnFocus = false, keepFirst = false, keepOpen = false, selectOnClickOutside = false, maxHeight = 200, loading = false, disabled = false, checkInfiniteScroll = false, infiniteScrollDistance = 50, color, size, onInput, onSelect, onActiveChange, onInfiniteScroll, itemTemplate, header, footer, empty, name, form, required, id,
|
|
12674
|
+
// Deprecated no-ops, taken here so they stay off the wrapper.
|
|
12675
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- deprecated no-op
|
|
12676
|
+
selected,
|
|
12677
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars -- deprecated no-op
|
|
12678
|
+
dropdown,
|
|
12657
12679
|
// Field props
|
|
12658
12680
|
label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, className, ...props }, ref) => {
|
|
12659
12681
|
const insideField = useInsideField();
|
|
@@ -12806,7 +12828,10 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
|
|
|
12806
12828
|
}
|
|
12807
12829
|
break;
|
|
12808
12830
|
case 'Escape':
|
|
12809
|
-
|
|
12831
|
+
// Only closing the dropdown claims the key. With it closed, the
|
|
12832
|
+
// key goes on to a Modal around the field.
|
|
12833
|
+
if (menuOpen)
|
|
12834
|
+
e.preventDefault();
|
|
12810
12835
|
setIsActive(false);
|
|
12811
12836
|
setHighlightedIndex(-1);
|
|
12812
12837
|
break;
|
|
@@ -12817,7 +12842,14 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
|
|
|
12817
12842
|
setIsActive(false);
|
|
12818
12843
|
break;
|
|
12819
12844
|
}
|
|
12820
|
-
}, [
|
|
12845
|
+
}, [
|
|
12846
|
+
disabled,
|
|
12847
|
+
isActive,
|
|
12848
|
+
menuOpen,
|
|
12849
|
+
highlightedIndex,
|
|
12850
|
+
filteredData,
|
|
12851
|
+
handleSelect,
|
|
12852
|
+
]);
|
|
12821
12853
|
// Handle dropdown scroll for infinite scroll
|
|
12822
12854
|
const handleDropdownScroll = React.useCallback(() => {
|
|
12823
12855
|
if (!checkInfiniteScroll || !dropdownRef.current)
|
|
@@ -12960,7 +12992,7 @@ Autocomplete.displayName = 'Autocomplete';
|
|
|
12960
12992
|
*/
|
|
12961
12993
|
const Taginput = React.forwardRef(({
|
|
12962
12994
|
// Field props
|
|
12963
|
-
label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue = [], data
|
|
12995
|
+
label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName, value: controlledValue, defaultValue = [], data: dataProp, placeholder, field = 'label', allowNew = true, allowDuplicates = false, openOnFocus = false, removeOnKeys = true, confirmKeys = ['Enter', ','], closable = true, attached = false, maxTags, maxlength, disabled = false, readonly = false, rounded = false, ellipsis = false, hasCounter = true, onPasteSeparators = [','], beforeAdding, createTag, keepFirst = false, keepOpen = true, loading = false, ariaCloseLabel, icon, iconLibrary: iconLibraryProp, iconVariant, iconFeatures, color, tagColor, size, onChange, onAdd, onRemove, onTyping, tagTemplate, name, form, id, className, ...props }, ref) => {
|
|
12964
12996
|
const insideField = useInsideField();
|
|
12965
12997
|
const insideControl = useInsideControl();
|
|
12966
12998
|
const ownField = rendersOwnField('Taginput', {
|
|
@@ -12983,17 +13015,26 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
|
|
|
12983
13015
|
const [inputValue, setInputValue] = React.useState('');
|
|
12984
13016
|
const [isActive, setIsActive] = React.useState(false);
|
|
12985
13017
|
const [highlightedIndex, setHighlightedIndex] = React.useState(-1);
|
|
13018
|
+
const listboxId = `${React.useId()}-listbox`;
|
|
13019
|
+
// With `data` the input offers suggestions, so it's a combobox, even
|
|
13020
|
+
// while none match. Without it there's never a list, so it stays a plain
|
|
13021
|
+
// text field.
|
|
13022
|
+
const hasSuggestions = dataProp !== undefined;
|
|
13023
|
+
const data = dataProp ?? [];
|
|
12986
13024
|
// Use controlled or internal tags
|
|
12987
13025
|
const tags = controlledValue !== undefined ? controlledValue : internalTags;
|
|
12988
13026
|
const isMaxReached = maxTags !== undefined && tags.length >= maxTags;
|
|
12989
13027
|
// At the tag limit the text input is not rendered, so there is nothing to
|
|
12990
|
-
// wire a label to, its own or a surrounding Field's.
|
|
12991
|
-
|
|
13028
|
+
// wire a label to, its own or a surrounding Field's. The suggestion list
|
|
13029
|
+
// points `aria-labelledby` at the label that names the input, so with
|
|
13030
|
+
// suggestions it needs that label's id.
|
|
13031
|
+
const { controlId, fieldLabelProps, labelled, labelId: listLabelId, } = useAutoLabelId({
|
|
12992
13032
|
label,
|
|
12993
13033
|
id,
|
|
12994
13034
|
labelProps,
|
|
12995
13035
|
rendersLabel: ownField && !isMaxReached,
|
|
12996
13036
|
hasInput: !isMaxReached,
|
|
13037
|
+
needsLabelId: hasSuggestions,
|
|
12997
13038
|
});
|
|
12998
13039
|
// Get display value from tag
|
|
12999
13040
|
const getDisplayValue = (tag) => {
|
|
@@ -13013,6 +13054,7 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
|
|
|
13013
13054
|
const hasInput = inputValue || (openOnFocus && isActive);
|
|
13014
13055
|
return matchesInput && notAlreadyAdded && hasInput;
|
|
13015
13056
|
});
|
|
13057
|
+
const listOpen = isActive && filteredData.length > 0;
|
|
13016
13058
|
// keepFirst: auto-highlight first item when dropdown opens
|
|
13017
13059
|
React.useEffect(() => {
|
|
13018
13060
|
if (keepFirst && isActive && filteredData.length > 0) {
|
|
@@ -13181,6 +13223,10 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
|
|
|
13181
13223
|
}
|
|
13182
13224
|
break;
|
|
13183
13225
|
case 'Escape':
|
|
13226
|
+
// Closing the suggestions claims the key, so a Modal around the
|
|
13227
|
+
// field stays open. With none showing, the key goes on to it.
|
|
13228
|
+
if (isActive && filteredData.length > 0)
|
|
13229
|
+
e.preventDefault();
|
|
13184
13230
|
setIsActive(false);
|
|
13185
13231
|
setHighlightedIndex(-1);
|
|
13186
13232
|
break;
|
|
@@ -13253,15 +13299,35 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
|
|
|
13253
13299
|
[`is-${messageColor}`]: !!messageColor,
|
|
13254
13300
|
});
|
|
13255
13301
|
const messageEl = message ? jsxRuntime.jsx("p", { className: helpClass, children: message }) : null;
|
|
13302
|
+
// The combobox controls its listbox and points at the highlighted option,
|
|
13303
|
+
// the way Autocomplete's does. The listbox takes its name from the label
|
|
13304
|
+
// that names the combobox, the one this renders or a surrounding Field's,
|
|
13305
|
+
// and keeps a fallback name when no label names it or the one that does
|
|
13306
|
+
// has no id to point at. While no suggestion matches there's no listbox,
|
|
13307
|
+
// so the combobox is collapsed and points at nothing. It skips a
|
|
13308
|
+
// highlighted suggestion that's blank once trimmed, since that one can't
|
|
13309
|
+
// become a tag, and the option it points at is the one marked selected.
|
|
13310
|
+
const optionId = (index) => `${listboxId}-${index}`;
|
|
13311
|
+
const activeOptionId = listOpen && filteredData[highlightedIndex]?.trim()
|
|
13312
|
+
? optionId(highlightedIndex)
|
|
13313
|
+
: undefined;
|
|
13314
|
+
const comboboxProps = {
|
|
13315
|
+
role: 'combobox',
|
|
13316
|
+
'aria-expanded': listOpen,
|
|
13317
|
+
'aria-controls': listOpen ? listboxId : undefined,
|
|
13318
|
+
'aria-activedescendant': activeOptionId,
|
|
13319
|
+
'aria-haspopup': 'listbox',
|
|
13320
|
+
'aria-autocomplete': 'list',
|
|
13321
|
+
};
|
|
13256
13322
|
const taginputElement = (jsxRuntime.jsxs("div", { ref: containerRef, className: combinedClasses, onClick: handleContainerClick, ...rest, children: [jsxRuntime.jsxs("div", { className: containerClasses, children: [icon && (jsxRuntime.jsx(Icon, { name: icon, library: resolvedLibrary, variant: iconVariant, features: iconFeatures, containerClassName: pcn('icon', 'is-left') })), jsxRuntime.jsxs("div", { className: tagsClasses, children: [tags.map((tag, index) => {
|
|
13257
13323
|
const displayVal = getDisplayValue(tag);
|
|
13258
13324
|
return (jsxRuntime.jsxs("span", { className: tagClasses, children: [tagTemplate ? (tagTemplate(tag)) : ellipsis ? (jsxRuntime.jsx("span", { title: displayVal, children: displayVal })) : (displayVal), closable && !disabled && !readonly && (jsxRuntime.jsx("button", { type: "button", className: pcn('delete', 'is-small'), onClick: e => {
|
|
13259
13325
|
e.stopPropagation();
|
|
13260
13326
|
removeTag(index);
|
|
13261
13327
|
}, "aria-label": ariaCloseLabel || `Remove ${displayVal}` }))] }, index));
|
|
13262
|
-
}), !isMaxReached && (jsxRuntime.jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: tags.length === 0 ? placeholder : undefined, disabled: disabled, readOnly: readonly, maxLength: maxlength, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, onPaste: handlePaste, "aria-label": labelled ? undefined : 'Add tag' }))] }), loading && (jsxRuntime.jsx("span", { className: iconRightClass, children: jsxRuntime.jsx("span", { className: loaderClass }) }))] }),
|
|
13328
|
+
}), !isMaxReached && (jsxRuntime.jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: tags.length === 0 ? placeholder : undefined, disabled: disabled, readOnly: readonly, maxLength: maxlength, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, onPaste: handlePaste, ...(hasSuggestions && comboboxProps), "aria-label": labelled ? undefined : 'Add tag' }))] }), loading && (jsxRuntime.jsx("span", { className: iconRightClass, children: jsxRuntime.jsx("span", { className: loaderClass }) }))] }), listOpen && (jsxRuntime.jsx("div", { className: dropdownMenuClasses, children: jsxRuntime.jsx("div", { ref: dropdownRef, id: listboxId, className: dropdownContentClasses, role: "listbox", "aria-labelledby": listLabelId, "aria-label": listLabelId ? undefined : 'Suggestions', children: filteredData.map((item, index) => (jsxRuntime.jsx("a", { id: optionId(index), className: pcn('dropdown-item', {
|
|
13263
13329
|
'is-active': index === highlightedIndex,
|
|
13264
|
-
}), onClick: () => addTag(item), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": index ===
|
|
13330
|
+
}), onClick: () => addTag(item), onMouseEnter: () => setHighlightedIndex(index), role: "option", "aria-selected": optionId(index) === activeOptionId, children: item }, index))) }) })), showCounter && jsxRuntime.jsx("small", { className: counterClasses, children: counterText }), name &&
|
|
13265
13331
|
tags.map((tag, i) => (jsxRuntime.jsx("input", { type: "hidden", name: name, value: getDisplayValue(tag), form: form }, `tag-input-${i}`)))] }));
|
|
13266
13332
|
if (ownField) {
|
|
13267
13333
|
return (jsxRuntime.jsxs(Field, { label: label, labelSize: labelSize, labelProps: fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [taginputElement, messageEl] }));
|
|
@@ -15022,13 +15088,20 @@ const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'botto
|
|
|
15022
15088
|
return () => document.removeEventListener('pointerdown', handler);
|
|
15023
15089
|
}, [isOpen, closeOnClickOutside, anchorRef, onClose]);
|
|
15024
15090
|
// Escape closes it, and so does Alt+ArrowUp, the combobox's key for it,
|
|
15025
|
-
// which the calendar and the time wheels inside leave to it.
|
|
15091
|
+
// which the calendar and the time wheels inside leave to it. Escape closes
|
|
15092
|
+
// it from anywhere, but the key is only the picker's when it was pressed in
|
|
15093
|
+
// the panel or the field: then it's marked used, so a Modal or Sidebar
|
|
15094
|
+
// around the picker stays open. From anywhere else, such as a dialog opened
|
|
15095
|
+
// over the picker, the key goes on to whatever has focus.
|
|
15026
15096
|
React.useEffect(() => {
|
|
15027
15097
|
if (!isOpen || !closeOnEscape || !isBrowser)
|
|
15028
15098
|
return undefined;
|
|
15029
15099
|
const handler = (e) => {
|
|
15030
15100
|
if (e.key === 'Escape') {
|
|
15031
|
-
e.
|
|
15101
|
+
if (isEventInside(e, panelRef.current) ||
|
|
15102
|
+
isEventInside(e, anchorRef.current)) {
|
|
15103
|
+
e.preventDefault();
|
|
15104
|
+
}
|
|
15032
15105
|
onClose();
|
|
15033
15106
|
}
|
|
15034
15107
|
else if (e.altKey && e.key === 'ArrowUp') {
|
|
@@ -15039,7 +15112,7 @@ const PickerPopover = ({ isOpen, onClose, anchorRef, children, position = 'botto
|
|
|
15039
15112
|
};
|
|
15040
15113
|
document.addEventListener('keydown', handler);
|
|
15041
15114
|
return () => document.removeEventListener('keydown', handler);
|
|
15042
|
-
}, [isOpen, closeOnEscape, onClose]);
|
|
15115
|
+
}, [isOpen, closeOnEscape, anchorRef, onClose]);
|
|
15043
15116
|
useFocusTrap(panelRef, {
|
|
15044
15117
|
active: isOpen && trapFocus,
|
|
15045
15118
|
initialFocusRef,
|