@allxsmith/bestax-bulma 5.34.2 → 5.34.3

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.
@@ -14,6 +14,18 @@ import { spokenText, StatusRegion } from '../helpers/statusRegion.js';
14
14
  // it's handed while that content is on screen because of the user's typing.
15
15
  const typedNoMatches = [{ id: 'empty' }];
16
16
  const nothingToAnnounce = [];
17
+ // A press on an option would take focus from the field, since an option
18
+ // can't hold it, and nothing would put it back. Cancelling the press keeps
19
+ // it there, as the ARIA Authoring Practices' combobox does, and the click
20
+ // still picks the option.
21
+ const keepFocus = (e) => e.preventDefault();
22
+ // An IME that's composing owns every key: Enter confirms what it composed,
23
+ // and the arrows move through its candidates. Safari can say so with
24
+ // `keyCode` 229 rather than `isComposing`.
25
+ const isComposing = (e) => e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229;
26
+ // Whether an option can be picked. The arrows still reach a disabled one, so
27
+ // a screen reader user finds it.
28
+ const isEnabled = (item) => typeof item === 'string' || !item.disabled;
17
29
  /**
18
30
  * The `Autocomplete` component provides an input field with dropdown suggestions that filter based on user input.
19
31
  *
@@ -173,13 +185,17 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
173
185
  }, [keepFirst, isActive, filteredData.length, inputValue]);
174
186
  // Handle keyboard navigation
175
187
  const handleKeyDown = useCallback((e) => {
176
- if (disabled)
188
+ if (disabled || isComposing(e))
177
189
  return;
178
190
  switch (e.key) {
179
191
  case 'ArrowDown':
180
192
  e.preventDefault();
181
193
  if (!isActive) {
194
+ // A closed list opens on its first enabled option, as the ARIA
195
+ // Authoring Practices' combobox does. Alt+Down Arrow opens it
196
+ // without a highlight.
182
197
  setIsActive(true);
198
+ setHighlightedIndex(e.altKey ? -1 : filteredData.map(isEnabled).indexOf(true));
183
199
  }
184
200
  else {
185
201
  setHighlightedIndex(prev => prev < filteredData.length - 1 ? prev + 1 : prev);
@@ -187,13 +203,30 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
187
203
  break;
188
204
  case 'ArrowUp':
189
205
  e.preventDefault();
190
- setHighlightedIndex(prev => (prev > 0 ? prev - 1 : prev));
206
+ if (!isActive) {
207
+ // And Up Arrow opens it on its last enabled option.
208
+ setIsActive(true);
209
+ setHighlightedIndex(filteredData.map(isEnabled).lastIndexOf(true));
210
+ }
211
+ else {
212
+ setHighlightedIndex(prev => (prev > 0 ? prev - 1 : prev));
213
+ }
191
214
  break;
192
215
  case 'Enter':
193
- e.preventDefault();
194
- if (highlightedIndex >= 0 && filteredData[highlightedIndex]) {
216
+ // With the list open on a highlighted option it can pick, Enter
217
+ // is that option's. Otherwise it closes the list and goes on, so
218
+ // a form around the field submits, as it would from any text
219
+ // field.
220
+ if (isActive &&
221
+ highlightedIndex >= 0 &&
222
+ filteredData[highlightedIndex] &&
223
+ isEnabled(filteredData[highlightedIndex])) {
224
+ e.preventDefault();
195
225
  handleSelect(filteredData[highlightedIndex]);
196
226
  }
227
+ else {
228
+ setIsActive(false);
229
+ }
197
230
  break;
198
231
  case 'Escape':
199
232
  // Only closing the dropdown claims the key. With it closed, the
@@ -204,7 +237,9 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
204
237
  setHighlightedIndex(-1);
205
238
  break;
206
239
  case 'Tab':
207
- if (highlightedIndex >= 0 && filteredData[highlightedIndex]) {
240
+ if (isActive &&
241
+ highlightedIndex >= 0 &&
242
+ filteredData[highlightedIndex]) {
208
243
  handleSelect(filteredData[highlightedIndex]);
209
244
  }
210
245
  setIsActive(false);
@@ -317,17 +352,17 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
317
352
  return null;
318
353
  return spokenText(node);
319
354
  }, []);
320
- const autocompleteElement = (jsxs("div", { ref: containerRef, className: combinedClasses, ...rest, children: [jsxs("div", { className: controlClasses, children: [jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: placeholder, disabled: disabled, name: name, form: form, required: required, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, role: "combobox", "aria-expanded": listOpen, "aria-controls": listOpen ? listboxId : undefined, "aria-activedescendant": activeOptionId, "aria-haspopup": "listbox", "aria-autocomplete": "list", autoComplete: "off" }), showClear && (jsx("button", { type: "button", className: iconRightClickableClass, onClick: handleClear, "aria-label": "Clear", children: jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", "aria-hidden": "true", children: [jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })), loading && (jsx("span", { className: iconRightClass, children: jsx("span", { className: loaderClass }) }))] }), menuOpen && (jsx("div", { className: dropdownMenuClasses, children: jsxs("div", { ref: dropdownRef, className: dropdownContentClass, style: { maxHeight: `${maxHeight}px`, overflowY: 'auto' }, onScroll: handleDropdownScroll, children: [header && jsx("div", { className: dropdownHeaderClass, children: header }), listOpen ? (jsx("div", { id: listboxId, role: "listbox", "aria-labelledby": listLabelId, "aria-label": listLabelId ? undefined : 'Suggestions', children: filteredData.map((item, index) => {
355
+ const autocompleteElement = (jsxs("div", { ref: containerRef, className: combinedClasses, ...rest, children: [jsxs("div", { className: controlClasses, children: [jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: placeholder, disabled: disabled, name: name, form: form, required: required, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, role: "combobox", "aria-expanded": listOpen, "aria-controls": listOpen ? listboxId : undefined, "aria-activedescendant": activeOptionId, "aria-haspopup": "listbox", "aria-autocomplete": "list", autoComplete: "off" }), showClear && (jsx("button", { type: "button", className: iconRightClickableClass, onClick: handleClear, "aria-label": "Clear", children: jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", "aria-hidden": "true", children: [jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })), loading && (jsx("span", { className: iconRightClass, children: jsx("span", { className: loaderClass }) }))] }), menuOpen && (jsx("div", { className: dropdownMenuClasses, children: jsxs("div", { ref: dropdownRef, className: dropdownContentClass, style: { maxHeight: `${maxHeight}px`, overflowY: 'auto' }, onScroll: handleDropdownScroll, children: [header && jsx("div", { className: dropdownHeaderClass, children: header }), listOpen ? (jsx("div", { id: listboxId, role: "listbox", "aria-labelledby": listLabelId, "aria-label": listLabelId ? undefined : 'Suggestions', onMouseDown: keepFocus, children: filteredData.map((item, index) => {
321
356
  const isDisabled = typeof item !== 'string' && item.disabled;
322
357
  const isHighlighted = index === highlightedIndex;
323
358
  const itemClasses = prefixedClassNames(classPrefix, 'dropdown-item', {
324
359
  'is-active': isHighlighted,
325
360
  'is-disabled': isDisabled,
326
361
  });
327
- return (jsx("a", { id: `${listboxId}-${index}`, "data-index": index, className: itemClasses, onClick: () => !isDisabled && handleSelect(item), onMouseEnter: () => !isDisabled && setHighlightedIndex(index), role: "option", "aria-selected": isHighlighted, "aria-disabled": isDisabled, children: itemTemplate
362
+ return (jsx("a", { id: `${listboxId}-${index}`, "data-index": index, className: itemClasses, onClick: () => !isDisabled && handleSelect(item), onMouseEnter: () => !isDisabled && setHighlightedIndex(index), role: "option", "aria-selected": isHighlighted && !isDisabled, "aria-disabled": isDisabled, children: itemTemplate
328
363
  ? itemTemplate(item)
329
364
  : getDisplayValue(item) }, index));
330
- }) })) : (jsx("div", { ref: emptyRef, className: emptyItemClasses, children: empty })), footer && jsx("div", { className: dropdownFooterClass, children: footer })] }) })), jsx(StatusRegion, { items: emptyItems, describe: describeEmpty })] }));
365
+ }) })) : (jsx("div", { ref: emptyRef, className: emptyItemClasses, onMouseDown: keepFocus, children: empty })), footer && jsx("div", { className: dropdownFooterClass, children: footer })] }) })), jsx(StatusRegion, { items: emptyItems, describe: describeEmpty })] }));
331
366
  if (!insideField) {
332
367
  return (jsxs(Field, { label: label, labelSize: labelSize, labelProps: fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [autocompleteElement, messageEl] }));
333
368
  }
@@ -1 +1 @@
1
- {"version":3,"file":"Autocomplete.js","sources":["../../../src/form/Autocomplete.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useState,\n useRef,\n useEffect,\n useCallback,\n useId,\n} from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { useConfig } from '../helpers/Config';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useInsideField } from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\nimport { useControlLoading } from './controlLoading';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\n\n/**\n * An item in the Autocomplete dropdown list.\n */\nexport interface AutocompleteItem {\n /** The value used for filtering and selection. */\n value: string;\n /** Display label (optional). */\n label?: string;\n /** Whether the item is disabled and unselectable. */\n disabled?: boolean;\n [key: string]: unknown;\n}\n\n// What the status region announces: the `empty` content, as the one item\n// it's handed while that content is on screen because of the user's typing.\nconst typedNoMatches = [{ id: 'empty' }];\nconst nothingToAnnounce: Array<{ id: string }> = [];\n\n/**\n * Props for the Autocomplete component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the input element.\n */\nexport interface AutocompleteProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect' | 'onInput'>,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** Field label, associated with the text input via `htmlFor`: through your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose label names the input instead when it points at it. The `Field` points its label there itself when the Autocomplete has no `id` and no inner `Field` sits between them (and the `Field` is not `grouped` or `hasAddons`); a label you wire by hand with `labelProps.htmlFor` points at the input with that `id`. The label naming the input also names the open suggestion list, through `aria-labelledby`, when it has an id: this label always does, and an outer `Field`'s does unless you wired it by hand without an `id` in its `labelProps`. Otherwise the list is named \"Suggestions\". */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (the input then gets no generated id). While the label names the input, the suggestion list's `aria-labelledby` points at it, through an `id` here when you give one and a generated one otherwise. */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Applied to the inner text input (the labellable control), not the wrapper div. */\n id?: string;\n /** The options data to display (required). */\n data: AutocompleteItem[] | string[];\n /** The current input value (controlled). */\n value?: string;\n /**\n * Does nothing: Autocomplete doesn't read it.\n *\n * @deprecated Nothing reads it, and `onSelect` is what reports a pick. It\n * will be removed in the next major version.\n */\n selected?: AutocompleteItem | string | null;\n /** Placeholder text for the input. */\n placeholder?: string;\n /** Object property to use as the display field. */\n field?: string;\n /**\n * Whether to show a clear button while the input holds a value.\n * It hides while the input is disabled, and gives way to a loading\n * spinner at the same right edge: the one `loading` draws, or that of a\n * `Control` with `isLoading` around the Autocomplete.\n */\n clearable?: boolean;\n /** Open dropdown when input is focused. */\n openOnFocus?: boolean;\n /** Keep first option highlighted. */\n keepFirst?: boolean;\n /** Keep dropdown open after selection. */\n keepOpen?: boolean;\n /** Select highlighted item on click outside. */\n selectOnClickOutside?: boolean;\n /** Maximum dropdown height in pixels. */\n maxHeight?: number;\n /**\n * Does nothing: Autocomplete doesn't read it, and always shows its\n * suggestions in a dropdown.\n *\n * @deprecated It will be removed in the next major version, with nothing\n * in its place.\n */\n dropdown?: boolean;\n /**\n * Show a loading spinner in the input.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n */\n loading?: boolean;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Enables infinite scroll detection in the dropdown. */\n checkInfiniteScroll?: boolean;\n /** Distance in pixels from the bottom to trigger `onInfiniteScroll`. */\n infiniteScrollDistance?: number;\n /** Input color variant. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Size variant. */\n size?: 'small' | 'medium' | 'large';\n /** Form field name. Forwarded to the inner `<input>`. */\n name?: string;\n /** Optional id of the form the input belongs to. */\n form?: string;\n /** Marks the field as required for native HTML form validation. */\n required?: boolean;\n /** Callback when input value changes. */\n onInput?: (value: string) => void;\n /** Callback when item is selected. */\n onSelect?: (item: AutocompleteItem | string | null) => void;\n /** Callback when dropdown active state changes. */\n onActiveChange?: (active: boolean) => void;\n /** Callback when scrolled to bottom (infinite scroll). */\n onInfiniteScroll?: () => void;\n /** Custom render for items. */\n itemTemplate?: (item: AutocompleteItem | string) => React.ReactNode;\n /** Custom header at the top of the dropdown. It sits above the list of options rather than in it, so assistive technology doesn't count it as one. */\n header?: React.ReactNode;\n /** Custom footer at the bottom of the dropdown. It sits below the list of options rather than in it, so assistive technology doesn't count it as one. */\n footer?: React.ReactNode;\n /**\n * A message the dropdown shows in place of the options when nothing\n * matches. Keep it to text: `Tab` closes the list, so a keyboard user\n * can't reach a link or button in it. It sits beside the list of options\n * rather than in it, so the input's `aria-expanded` stays false while it\n * shows. When the user's typing leaves nothing that matches, a polite\n * status region announces its text: once each time the matches run out.\n * The text is read when they first run out, and isn't read again as it\n * changes while they stay out, so a message that names the query is heard\n * for that first query only. Keep it static.\n * Opening the list without typing, or emptying the field, announces\n * nothing. While `loading`, or a `Control` with `isLoading` around the\n * Autocomplete, is on, it waits, and it's announced once loading ends\n * with nothing matching. Without `empty`, the dropdown closes when nothing\n * matches and nothing is announced.\n */\n empty?: React.ReactNode;\n}\n\n/**\n * The `Autocomplete` component provides an input field with dropdown suggestions that filter based on user input.\n *\n * @function\n * @param {AutocompleteProps} props - Props for the Autocomplete component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the input element.\n * @returns {JSX.Element} The rendered autocomplete component.\n *\n * @example\n * // Basic usage with string array\n * <Autocomplete\n * data={['Apple', 'Banana', 'Cherry']}\n * placeholder=\"Search fruit...\"\n * onSelect={(item) => console.log(item)}\n * />\n *\n * @example\n * // With object data\n * <Autocomplete\n * data={[{ value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }]}\n * field=\"label\"\n * onSelect={(item) => console.log(item)}\n * />\n */\nexport const Autocomplete = forwardRef<HTMLInputElement, AutocompleteProps>(\n (\n {\n data = [],\n value: controlledValue,\n placeholder,\n field = 'label',\n clearable = false,\n openOnFocus = false,\n keepFirst = false,\n keepOpen = false,\n selectOnClickOutside = false,\n maxHeight = 200,\n loading = false,\n disabled = false,\n checkInfiniteScroll = false,\n infiniteScrollDistance = 50,\n color,\n size,\n onInput,\n onSelect,\n onActiveChange,\n onInfiniteScroll,\n itemTemplate,\n header,\n footer,\n empty,\n name,\n form,\n required,\n id,\n // Deprecated no-ops, taken here so they stay off the wrapper.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- deprecated no-op\n selected,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- deprecated no-op\n dropdown,\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n // The suggestion list points `aria-labelledby` at the label that names\n // the input, so it needs that label's id.\n const {\n controlId,\n fieldLabelProps,\n labelId: listLabelId,\n } = useAutoLabelId({\n label,\n id,\n labelProps,\n rendersLabel: !insideField,\n needsLabelId: true,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const { classPrefix } = useConfig();\n const containerRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const [internalValue, setInternalValue] = useState('');\n const [isActive, setIsActive] = useState(false);\n // Whether the user has typed since the list opened, since only typing\n // gets the `empty` content announced. Closing the list resets it (during\n // render, React's pattern for adjusting state when other state changes),\n // so opening the list again without typing stays quiet.\n const [typed, setTyped] = useState(false);\n if (typed && !isActive) setTyped(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const listboxId = `${useId()}-listbox`;\n\n // Use controlled or internal value\n const inputValue =\n controlledValue !== undefined ? controlledValue : internalValue;\n\n // Get display value from item\n const getDisplayValue = (item: AutocompleteItem | string): string => {\n if (typeof item === 'string') return item;\n const fieldValue = item[field];\n if (typeof fieldValue === 'string') return fieldValue;\n return item.value || '';\n };\n\n // Filter data based on input\n const filteredData = data.filter(item => {\n const displayValue = getDisplayValue(item);\n return displayValue.toLowerCase().includes(inputValue.toLowerCase());\n });\n\n // The dropdown shows the options or, when nothing matches, the `empty`\n // content. The listbox holds only options, so it's on screen only while\n // there are some.\n const menuOpen = isActive && (filteredData.length > 0 || !!empty);\n const listOpen = isActive && filteredData.length > 0;\n\n // Handle input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n if (controlledValue === undefined) {\n setInternalValue(newValue);\n }\n onInput?.(newValue);\n setTyped(true);\n if (!isActive && newValue) {\n setIsActive(true);\n }\n },\n [controlledValue, isActive, onInput]\n );\n\n // Handle item selection\n const handleSelect = useCallback(\n (item: AutocompleteItem | string) => {\n if (typeof item !== 'string' && item.disabled) return;\n\n const displayValue = getDisplayValue(item);\n if (controlledValue === undefined) {\n setInternalValue(displayValue);\n }\n onInput?.(displayValue);\n onSelect?.(item);\n\n if (!keepOpen) {\n setIsActive(false);\n }\n setHighlightedIndex(-1);\n },\n [controlledValue, field, keepOpen, onInput, onSelect]\n );\n\n // Handle clear\n const handleClear = useCallback(() => {\n if (controlledValue === undefined) {\n setInternalValue('');\n }\n onInput?.('');\n onSelect?.(null);\n inputRef.current?.focus();\n }, [controlledValue, onInput, onSelect]);\n\n // Handle focus\n const handleFocus = useCallback(() => {\n if (openOnFocus && !disabled) {\n setIsActive(true);\n }\n }, [openOnFocus, disabled]);\n\n // Handle blur (click outside)\n useEffect(() => {\n if (!isActive) return undefined;\n\n const handleClickOutside = (e: MouseEvent) => {\n if (!containerRef.current) return;\n\n // Use composedPath() to correctly detect clicks inside Shadow DOM\n const path = e.composedPath();\n const isInside = path.includes(containerRef.current);\n\n if (!isInside) {\n if (selectOnClickOutside && highlightedIndex >= 0) {\n handleSelect(filteredData[highlightedIndex]);\n }\n setIsActive(false);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () =>\n document.removeEventListener('mousedown', handleClickOutside);\n }, [\n isActive,\n selectOnClickOutside,\n highlightedIndex,\n filteredData,\n handleSelect,\n ]);\n\n // Notify active state change\n useEffect(() => {\n onActiveChange?.(isActive);\n }, [isActive, onActiveChange]);\n\n // Keep first highlighted\n useEffect(() => {\n if (keepFirst && isActive && filteredData.length > 0) {\n setHighlightedIndex(0);\n }\n }, [keepFirst, isActive, filteredData.length, inputValue]);\n\n // Handle keyboard navigation\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (disabled) return;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!isActive) {\n setIsActive(true);\n } else {\n setHighlightedIndex(prev =>\n prev < filteredData.length - 1 ? prev + 1 : prev\n );\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n setHighlightedIndex(prev => (prev > 0 ? prev - 1 : prev));\n break;\n case 'Enter':\n e.preventDefault();\n if (highlightedIndex >= 0 && filteredData[highlightedIndex]) {\n handleSelect(filteredData[highlightedIndex]);\n }\n break;\n case 'Escape':\n // Only closing the dropdown claims the key. With it closed, the\n // key goes on to a Modal around the field.\n if (menuOpen) e.preventDefault();\n setIsActive(false);\n setHighlightedIndex(-1);\n break;\n case 'Tab':\n if (highlightedIndex >= 0 && filteredData[highlightedIndex]) {\n handleSelect(filteredData[highlightedIndex]);\n }\n setIsActive(false);\n break;\n }\n },\n [\n disabled,\n isActive,\n menuOpen,\n highlightedIndex,\n filteredData,\n handleSelect,\n ]\n );\n\n // Handle dropdown scroll for infinite scroll\n const handleDropdownScroll = useCallback(() => {\n if (!checkInfiniteScroll || !dropdownRef.current) return;\n\n const { scrollTop, scrollHeight, clientHeight } = dropdownRef.current;\n if (scrollHeight - scrollTop - clientHeight <= infiniteScrollDistance) {\n onInfiniteScroll?.();\n }\n }, [checkInfiniteScroll, infiniteScrollDistance, onInfiniteScroll]);\n\n // Scroll highlighted item into view\n useEffect(() => {\n if (highlightedIndex >= 0 && dropdownRef.current) {\n const highlightedEl = dropdownRef.current.querySelector(\n `[data-index=\"${highlightedIndex}\"]`\n );\n if (\n highlightedEl &&\n typeof highlightedEl.scrollIntoView === 'function'\n ) {\n highlightedEl.scrollIntoView({ block: 'nearest' });\n }\n }\n }, [highlightedIndex]);\n\n // Combined ref\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n }\n },\n [ref]\n );\n\n // Generate classes\n const autocompleteClasses = usePrefixedClassNames('autocomplete', {\n 'is-active': isActive,\n [`is-${size}`]: !!size,\n });\n\n const inputClasses = usePrefixedClassNames('input', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-loading': loading,\n });\n\n const controlClasses = usePrefixedClassNames(\n 'control',\n 'is-expanded',\n 'has-icons-right'\n );\n\n const dropdownMenuClasses = usePrefixedClassNames('dropdown-menu', {\n 'is-active': menuOpen,\n });\n\n const dropdownContentClass = usePrefixedClassNames('dropdown-content');\n const dropdownHeaderClass = usePrefixedClassNames('dropdown-header');\n const dropdownFooterClass = usePrefixedClassNames('dropdown-footer');\n const emptyItemClasses = usePrefixedClassNames(\n 'dropdown-item',\n 'has-text-grey'\n );\n\n const iconRightClickableClass = usePrefixedClassNames(\n 'icon',\n 'is-right',\n 'is-clickable'\n );\n const iconRightClass = usePrefixedClassNames('icon', 'is-right');\n const loaderClass = usePrefixedClassNames('loader', 'is-loading');\n\n const combinedClasses = classNames(\n autocompleteClasses,\n bulmaHelperClasses,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // The clear button gives way to a spinner at its spot: the `loading` one,\n // or that of a loading Control this sits in.\n const controlLoading = useControlLoading();\n const showClear =\n clearable && !!inputValue && !disabled && !loading && !controlLoading;\n\n // The combobox controls its listbox and points at the highlighted option.\n // The listbox takes its name from the label that names the combobox, the\n // one this renders or a surrounding Field's, so the two say the same\n // thing. When no label names the combobox, or the one that does has no\n // id to point at, the list keeps a fallback name. While the dropdown\n // shows only the `empty` content there's no listbox, so the combobox is\n // collapsed and points at nothing.\n const activeOptionId =\n listOpen &&\n highlightedIndex >= 0 &&\n highlightedIndex < filteredData.length\n ? `${listboxId}-${highlightedIndex}`\n : undefined;\n\n // A polite status region, in the page from the start so it's there\n // before anything is written into it, announces the `empty` content\n // when the user's typing leaves nothing that matches what's in the\n // field. It follows what's on screen, so results that come in after the\n // typing count too. It's said once each time that happens, not again on\n // each keystroke while nothing matches. An empty field isn't a search,\n // so it stays quiet then, even with no data. While `loading`, or a\n // loading Control around it, says results are on their way, it waits,\n // and it's said once loading ends with nothing matching.\n const emptyItems =\n typed &&\n menuOpen &&\n !listOpen &&\n !!inputValue &&\n !loading &&\n !controlLoading\n ? typedNoMatches\n : nothingToAnnounce;\n // The region reads the text on screen, whatever `empty` renders.\n const emptyRef = useRef<HTMLDivElement>(null);\n const describeEmpty = useCallback(() => {\n const node = emptyRef.current;\n /* istanbul ignore if: it's only announced while it's on screen */\n if (!node) return null;\n return spokenText(node);\n }, []);\n\n const autocompleteElement = (\n <div ref={containerRef} className={combinedClasses} {...rest}>\n <div className={controlClasses}>\n <input\n ref={combinedRef}\n type=\"text\"\n className={inputClasses}\n id={controlId}\n value={inputValue}\n placeholder={placeholder}\n disabled={disabled}\n name={name}\n form={form}\n required={required}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n role=\"combobox\"\n aria-expanded={listOpen}\n aria-controls={listOpen ? listboxId : undefined}\n aria-activedescendant={activeOptionId}\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n autoComplete=\"off\"\n />\n {showClear && (\n <button\n type=\"button\"\n className={iconRightClickableClass}\n onClick={handleClear}\n aria-label=\"Clear\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n )}\n {loading && (\n <span className={iconRightClass}>\n <span className={loaderClass} />\n </span>\n )}\n </div>\n\n {menuOpen && (\n <div className={dropdownMenuClasses}>\n <div\n ref={dropdownRef}\n className={dropdownContentClass}\n style={{ maxHeight: `${maxHeight}px`, overflowY: 'auto' }}\n onScroll={handleDropdownScroll}\n >\n {header && <div className={dropdownHeaderClass}>{header}</div>}\n\n {listOpen ? (\n <div\n id={listboxId}\n role=\"listbox\"\n aria-labelledby={listLabelId}\n aria-label={listLabelId ? undefined : 'Suggestions'}\n >\n {filteredData.map((item, index) => {\n const isDisabled =\n typeof item !== 'string' && item.disabled;\n const isHighlighted = index === highlightedIndex;\n\n const itemClasses = prefixedClassNames(\n classPrefix,\n 'dropdown-item',\n {\n 'is-active': isHighlighted,\n 'is-disabled': isDisabled,\n }\n );\n\n return (\n <a\n key={index}\n id={`${listboxId}-${index}`}\n data-index={index}\n className={itemClasses}\n onClick={() => !isDisabled && handleSelect(item)}\n onMouseEnter={() =>\n !isDisabled && setHighlightedIndex(index)\n }\n role=\"option\"\n aria-selected={isHighlighted}\n aria-disabled={isDisabled}\n >\n {itemTemplate\n ? itemTemplate(item)\n : getDisplayValue(item)}\n </a>\n );\n })}\n </div>\n ) : (\n <div ref={emptyRef} className={emptyItemClasses}>\n {empty}\n </div>\n )}\n\n {footer && <div className={dropdownFooterClass}>{footer}</div>}\n </div>\n </div>\n )}\n\n <StatusRegion items={emptyItems} describe={describeEmpty} />\n </div>\n );\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {autocompleteElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {autocompleteElement}\n {messageEl}\n </>\n );\n }\n);\n\nAutocomplete.displayName = 'Autocomplete';\n\nexport default Autocomplete;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":";;;;;;;;;;;;AAmCA;AACA;AACA,MAAM,cAAc,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC;AACxC,MAAM,iBAAiB,GAA0B,EAAE;AAmHnD;;;;;;;;;;;;;;;;;;;;;;;AAuBG;AACI,MAAM,YAAY,GAAG,UAAU,CACpC,CACE,EACE,IAAI,GAAG,EAAE,EACT,KAAK,EAAE,eAAe,EACtB,WAAW,EACX,KAAK,GAAG,OAAO,EACf,SAAS,GAAG,KAAK,EACjB,WAAW,GAAG,KAAK,EACnB,SAAS,GAAG,KAAK,EACjB,QAAQ,GAAG,KAAK,EAChB,oBAAoB,GAAG,KAAK,EAC5B,SAAS,GAAG,GAAG,EACf,OAAO,GAAG,KAAK,EACf,QAAQ,GAAG,KAAK,EAChB,mBAAmB,GAAG,KAAK,EAC3B,sBAAsB,GAAG,EAAE,EAC3B,KAAK,EACL,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,MAAM,EACN,MAAM,EACN,KAAK,EACL,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,EAAE;AACF;AACA;AACA,QAAQ;AACR;AACA,QAAQ;AACR;AACA,KAAK,EACL,SAAS,EACT,UAAU,EACV,UAAU,EACV,OAAO,EACP,YAAY,EACZ,cAAc,EACd,SAAS,EACT,GAAG,KAAK,EACT,EACD,GAAG,KACD;AACF,IAAA,MAAM,WAAW,GAAG,cAAc,EAAE;;;IAGpC,MAAM,EACJ,SAAS,EACT,eAAe,EACf,OAAO,EAAE,WAAW,GACrB,GAAG,cAAc,CAAC;QACjB,KAAK;QACL,EAAE;QACF,UAAU;QACV,YAAY,EAAE,CAAC,WAAW;AAC1B,QAAA,YAAY,EAAE,IAAI;AACnB,KAAA,CAAC;IACF,MAAM,EAAE,kBAAkB,EAAE,IAAI,EAAE,GAAG,eAAe,CAAC,KAAK,CAAC;AAC3D,IAAA,MAAM,EAAE,WAAW,EAAE,GAAG,SAAS,EAAE;AACnC,IAAA,MAAM,YAAY,GAAG,MAAM,CAAiB,IAAI,CAAC;AACjD,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAmB,IAAI,CAAC;AAC/C,IAAA,MAAM,WAAW,GAAG,MAAM,CAAiB,IAAI,CAAC;IAEhD,MAAM,CAAC,aAAa,EAAE,gBAAgB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC;IACtD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;;;;;IAK/C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC;IACzC,IAAI,KAAK,IAAI,CAAC,QAAQ;QAAE,QAAQ,CAAC,KAAK,CAAC;IACvC,MAAM,CAAC,gBAAgB,EAAE,mBAAmB,CAAC,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC5D,IAAA,MAAM,SAAS,GAAG,CAAA,EAAG,KAAK,EAAE,UAAU;;AAGtC,IAAA,MAAM,UAAU,GACd,eAAe,KAAK,SAAS,GAAG,eAAe,GAAG,aAAa;;AAGjE,IAAA,MAAM,eAAe,GAAG,CAAC,IAA+B,KAAY;QAClE,IAAI,OAAO,IAAI,KAAK,QAAQ;AAAE,YAAA,OAAO,IAAI;AACzC,QAAA,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC;QAC9B,IAAI,OAAO,UAAU,KAAK,QAAQ;AAAE,YAAA,OAAO,UAAU;AACrD,QAAA,OAAO,IAAI,CAAC,KAAK,IAAI,EAAE;AACzB,IAAA,CAAC;;IAGD,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,IAAI,IAAG;AACtC,QAAA,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,CAAC;AAC1C,QAAA,OAAO,YAAY,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,WAAW,EAAE,CAAC;AACtE,IAAA,CAAC,CAAC;;;;AAKF,IAAA,MAAM,QAAQ,GAAG,QAAQ,KAAK,YAAY,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC;IACjE,MAAM,QAAQ,GAAG,QAAQ,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC;;AAGpD,IAAA,MAAM,iBAAiB,GAAG,WAAW,CACnC,CAAC,CAAsC,KAAI;AACzC,QAAA,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,CAAC,KAAK;AAC/B,QAAA,IAAI,eAAe,KAAK,SAAS,EAAE;YACjC,gBAAgB,CAAC,QAAQ,CAAC;QAC5B;AACA,QAAA,OAAO,GAAG,QAAQ,CAAC;QACnB,QAAQ,CAAC,IAAI,CAAC;AACd,QAAA,IAAI,CAAC,QAAQ,IAAI,QAAQ,EAAE;YACzB,WAAW,CAAC,IAAI,CAAC;QACnB;IACF,CAAC,EACD,CAAC,eAAe,EAAE,QAAQ,EAAE,OAAO,CAAC,CACrC;;AAGD,IAAA,MAAM,YAAY,GAAG,WAAW,CAC9B,CAAC,IAA+B,KAAI;AAClC,QAAA,IAAI,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ;YAAE;AAE/C,QAAA,MAAM,YAAY,GAAG,eAAe,CAAC,IAAI,CAAC;AAC1C,QAAA,IAAI,eAAe,KAAK,SAAS,EAAE;YACjC,gBAAgB,CAAC,YAAY,CAAC;QAChC;AACA,QAAA,OAAO,GAAG,YAAY,CAAC;AACvB,QAAA,QAAQ,GAAG,IAAI,CAAC;QAEhB,IAAI,CAAC,QAAQ,EAAE;YACb,WAAW,CAAC,KAAK,CAAC;QACpB;AACA,QAAA,mBAAmB,CAAC,EAAE,CAAC;AACzB,IAAA,CAAC,EACD,CAAC,eAAe,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,QAAQ,CAAC,CACtD;;AAGD,IAAA,MAAM,WAAW,GAAG,WAAW,CAAC,MAAK;AACnC,QAAA,IAAI,eAAe,KAAK,SAAS,EAAE;YACjC,gBAAgB,CAAC,EAAE,CAAC;QACtB;AACA,QAAA,OAAO,GAAG,EAAE,CAAC;AACb,QAAA,QAAQ,GAAG,IAAI,CAAC;AAChB,QAAA,QAAQ,CAAC,OAAO,EAAE,KAAK,EAAE;IAC3B,CAAC,EAAE,CAAC,eAAe,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;;AAGxC,IAAA,MAAM,WAAW,GAAG,WAAW,CAAC,MAAK;AACnC,QAAA,IAAI,WAAW,IAAI,CAAC,QAAQ,EAAE;YAC5B,WAAW,CAAC,IAAI,CAAC;QACnB;AACF,IAAA,CAAC,EAAE,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC;;IAG3B,SAAS,CAAC,MAAK;AACb,QAAA,IAAI,CAAC,QAAQ;AAAE,YAAA,OAAO,SAAS;AAE/B,QAAA,MAAM,kBAAkB,GAAG,CAAC,CAAa,KAAI;YAC3C,IAAI,CAAC,YAAY,CAAC,OAAO;gBAAE;;AAG3B,YAAA,MAAM,IAAI,GAAG,CAAC,CAAC,YAAY,EAAE;YAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,OAAO,CAAC;YAEpD,IAAI,CAAC,QAAQ,EAAE;AACb,gBAAA,IAAI,oBAAoB,IAAI,gBAAgB,IAAI,CAAC,EAAE;AACjD,oBAAA,YAAY,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;gBAC9C;gBACA,WAAW,CAAC,KAAK,CAAC;YACpB;AACF,QAAA,CAAC;AAED,QAAA,QAAQ,CAAC,gBAAgB,CAAC,WAAW,EAAE,kBAAkB,CAAC;QAC1D,OAAO,MACL,QAAQ,CAAC,mBAAmB,CAAC,WAAW,EAAE,kBAAkB,CAAC;AACjE,IAAA,CAAC,EAAE;QACD,QAAQ;QACR,oBAAoB;QACpB,gBAAgB;QAChB,YAAY;QACZ,YAAY;AACb,KAAA,CAAC;;IAGF,SAAS,CAAC,MAAK;AACb,QAAA,cAAc,GAAG,QAAQ,CAAC;AAC5B,IAAA,CAAC,EAAE,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;;IAG9B,SAAS,CAAC,MAAK;QACb,IAAI,SAAS,IAAI,QAAQ,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE;YACpD,mBAAmB,CAAC,CAAC,CAAC;QACxB;AACF,IAAA,CAAC,EAAE,CAAC,SAAS,EAAE,QAAQ,EAAE,YAAY,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;;AAG1D,IAAA,MAAM,aAAa,GAAG,WAAW,CAC/B,CAAC,CAAsB,KAAI;AACzB,QAAA,IAAI,QAAQ;YAAE;AAEd,QAAA,QAAQ,CAAC,CAAC,GAAG;AACX,YAAA,KAAK,WAAW;gBACd,CAAC,CAAC,cAAc,EAAE;gBAClB,IAAI,CAAC,QAAQ,EAAE;oBACb,WAAW,CAAC,IAAI,CAAC;gBACnB;qBAAO;oBACL,mBAAmB,CAAC,IAAI,IACtB,IAAI,GAAG,YAAY,CAAC,MAAM,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CACjD;gBACH;gBACA;AACF,YAAA,KAAK,SAAS;gBACZ,CAAC,CAAC,cAAc,EAAE;gBAClB,mBAAmB,CAAC,IAAI,KAAK,IAAI,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;gBACzD;AACF,YAAA,KAAK,OAAO;gBACV,CAAC,CAAC,cAAc,EAAE;gBAClB,IAAI,gBAAgB,IAAI,CAAC,IAAI,YAAY,CAAC,gBAAgB,CAAC,EAAE;AAC3D,oBAAA,YAAY,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;gBAC9C;gBACA;AACF,YAAA,KAAK,QAAQ;;;AAGX,gBAAA,IAAI,QAAQ;oBAAE,CAAC,CAAC,cAAc,EAAE;gBAChC,WAAW,CAAC,KAAK,CAAC;AAClB,gBAAA,mBAAmB,CAAC,EAAE,CAAC;gBACvB;AACF,YAAA,KAAK,KAAK;gBACR,IAAI,gBAAgB,IAAI,CAAC,IAAI,YAAY,CAAC,gBAAgB,CAAC,EAAE;AAC3D,oBAAA,YAAY,CAAC,YAAY,CAAC,gBAAgB,CAAC,CAAC;gBAC9C;gBACA,WAAW,CAAC,KAAK,CAAC;gBAClB;;AAEN,IAAA,CAAC,EACD;QACE,QAAQ;QACR,QAAQ;QACR,QAAQ;QACR,gBAAgB;QAChB,YAAY;QACZ,YAAY;AACb,KAAA,CACF;;AAGD,IAAA,MAAM,oBAAoB,GAAG,WAAW,CAAC,MAAK;AAC5C,QAAA,IAAI,CAAC,mBAAmB,IAAI,CAAC,WAAW,CAAC,OAAO;YAAE;QAElD,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,GAAG,WAAW,CAAC,OAAO;QACrE,IAAI,YAAY,GAAG,SAAS,GAAG,YAAY,IAAI,sBAAsB,EAAE;YACrE,gBAAgB,IAAI;QACtB;IACF,CAAC,EAAE,CAAC,mBAAmB,EAAE,sBAAsB,EAAE,gBAAgB,CAAC,CAAC;;IAGnE,SAAS,CAAC,MAAK;QACb,IAAI,gBAAgB,IAAI,CAAC,IAAI,WAAW,CAAC,OAAO,EAAE;AAChD,YAAA,MAAM,aAAa,GAAG,WAAW,CAAC,OAAO,CAAC,aAAa,CACrD,CAAA,aAAA,EAAgB,gBAAgB,CAAA,EAAA,CAAI,CACrC;AACD,YAAA,IACE,aAAa;AACb,gBAAA,OAAO,aAAa,CAAC,cAAc,KAAK,UAAU,EAClD;gBACA,aAAa,CAAC,cAAc,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC;YACpD;QACF;AACF,IAAA,CAAC,EAAE,CAAC,gBAAgB,CAAC,CAAC;;AAGtB,IAAA,MAAM,WAAW,GAAG,WAAW,CAC7B,CAAC,IAA6B,KAAI;AAC/B,QAAA,QAA4D,CAAC,OAAO;AACnE,YAAA,IAAI;AACN,QAAA,IAAI,OAAO,GAAG,KAAK,UAAU,EAAE;YAC7B,GAAG,CAAC,IAAI,CAAC;QACX;aAAO,IAAI,GAAG,EAAE;AACb,YAAA,GAAuD,CAAC,OAAO;AAC9D,gBAAA,IAAI;QACR;AACF,IAAA,CAAC,EACD,CAAC,GAAG,CAAC,CACN;;AAGD,IAAA,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,cAAc,EAAE;AAChE,QAAA,WAAW,EAAE,QAAQ;AACrB,QAAA,CAAC,MAAM,IAAI,CAAA,CAAE,GAAG,CAAC,CAAC,IAAI;AACvB,KAAA,CAAC;AAEF,IAAA,MAAM,YAAY,GAAG,qBAAqB,CAAC,OAAO,EAAE;AAClD,QAAA,CAAC,MAAM,KAAK,CAAA,CAAE,GAAG,CAAC,CAAC,KAAK;AACxB,QAAA,CAAC,MAAM,IAAI,CAAA,CAAE,GAAG,CAAC,CAAC,IAAI;AACtB,QAAA,YAAY,EAAE,OAAO;AACtB,KAAA,CAAC;IAEF,MAAM,cAAc,GAAG,qBAAqB,CAC1C,SAAS,EACT,aAAa,EACb,iBAAiB,CAClB;AAED,IAAA,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,eAAe,EAAE;AACjE,QAAA,WAAW,EAAE,QAAQ;AACtB,KAAA,CAAC;AAEF,IAAA,MAAM,oBAAoB,GAAG,qBAAqB,CAAC,kBAAkB,CAAC;AACtE,IAAA,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,iBAAiB,CAAC;AACpE,IAAA,MAAM,mBAAmB,GAAG,qBAAqB,CAAC,iBAAiB,CAAC;IACpE,MAAM,gBAAgB,GAAG,qBAAqB,CAC5C,eAAe,EACf,eAAe,CAChB;IAED,MAAM,uBAAuB,GAAG,qBAAqB,CACnD,MAAM,EACN,UAAU,EACV,cAAc,CACf;IACD,MAAM,cAAc,GAAG,qBAAqB,CAAC,MAAM,EAAE,UAAU,CAAC;IAChE,MAAM,WAAW,GAAG,qBAAqB,CAAC,QAAQ,EAAE,YAAY,CAAC;IAEjE,MAAM,eAAe,GAAG,UAAU,CAChC,mBAAmB,EACnB,kBAAkB,EAClB,SAAS,CACV;AAED,IAAA,MAAM,SAAS,GAAG,qBAAqB,CAAC,MAAM,EAAE;AAC9C,QAAA,CAAC,MAAM,YAAY,CAAA,CAAE,GAAG,CAAC,CAAC,YAAY;AACvC,KAAA,CAAC;AACF,IAAA,MAAM,SAAS,GAAG,OAAO,GAAGA,GAAA,CAAA,GAAA,EAAA,EAAG,SAAS,EAAE,SAAS,YAAG,OAAO,EAAA,CAAK,GAAG,IAAI;;;AAIzE,IAAA,MAAM,cAAc,GAAG,iBAAiB,EAAE;AAC1C,IAAA,MAAM,SAAS,GACb,SAAS,IAAI,CAAC,CAAC,UAAU,IAAI,CAAC,QAAQ,IAAI,CAAC,OAAO,IAAI,CAAC,cAAc;;;;;;;;IASvE,MAAM,cAAc,GAClB,QAAQ;AACR,QAAA,gBAAgB,IAAI,CAAC;QACrB,gBAAgB,GAAG,YAAY,CAAC;AAC9B,UAAE,CAAA,EAAG,SAAS,CAAA,CAAA,EAAI,gBAAgB,CAAA;UAChC,SAAS;;;;;;;;;;IAWf,MAAM,UAAU,GACd,KAAK;QACL,QAAQ;AACR,QAAA,CAAC,QAAQ;AACT,QAAA,CAAC,CAAC,UAAU;AACZ,QAAA,CAAC,OAAO;AACR,QAAA,CAAC;AACC,UAAE;UACA,iBAAiB;;AAEvB,IAAA,MAAM,QAAQ,GAAG,MAAM,CAAiB,IAAI,CAAC;AAC7C,IAAA,MAAM,aAAa,GAAG,WAAW,CAAC,MAAK;AACrC,QAAA,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO;;AAE7B,QAAA,IAAI,CAAC,IAAI;AAAE,YAAA,OAAO,IAAI;AACtB,QAAA,OAAO,UAAU,CAAC,IAAI,CAAC;IACzB,CAAC,EAAE,EAAE,CAAC;AAEN,IAAA,MAAM,mBAAmB,IACvBC,IAAA,CAAA,KAAA,EAAA,EAAK,GAAG,EAAE,YAAY,EAAE,SAAS,EAAE,eAAe,EAAA,GAAM,IAAI,aAC1DA,IAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,cAAc,EAAA,QAAA,EAAA,CAC5BD,GAAA,CAAA,OAAA,EAAA,EACE,GAAG,EAAE,WAAW,EAChB,IAAI,EAAC,MAAM,EACX,SAAS,EAAE,YAAY,EACvB,EAAE,EAAE,SAAS,EACb,KAAK,EAAE,UAAU,EACjB,WAAW,EAAE,WAAW,EACxB,QAAQ,EAAE,QAAQ,EAClB,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,iBAAiB,EAC3B,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,IAAI,EAAC,UAAU,EAAA,eAAA,EACA,QAAQ,EAAA,eAAA,EACR,QAAQ,GAAG,SAAS,GAAG,SAAS,EAAA,uBAAA,EACxB,cAAc,EAAA,eAAA,EACvB,SAAS,EAAA,mBAAA,EACL,MAAM,EACxB,YAAY,EAAC,KAAK,EAAA,CAClB,EACD,SAAS,KACRA,GAAA,CAAA,QAAA,EAAA,EACE,IAAI,EAAC,QAAQ,EACb,SAAS,EAAE,uBAAuB,EAClC,OAAO,EAAE,WAAW,EAAA,YAAA,EACT,OAAO,EAAA,QAAA,EAElBC,IAAA,CAAA,KAAA,EAAA,EACE,KAAK,EAAC,4BAA4B,EAClC,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,GAAG,EACf,KAAK,EAAC,IAAI,EACV,MAAM,EAAC,IAAI,EAAA,aAAA,EACC,MAAM,EAAA,QAAA,EAAA,CAElBD,cAAM,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,EACtCA,cAAM,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,IAAI,EAAC,EAAE,EAAC,IAAI,EAAA,CAAG,CAAA,EAAA,CAClC,GACC,CACV,EACA,OAAO,KACNA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,cAAc,EAAA,QAAA,EAC7BA,GAAA,CAAA,MAAA,EAAA,EAAM,SAAS,EAAE,WAAW,EAAA,CAAI,EAAA,CAC3B,CACR,IACG,EAEL,QAAQ,KACPA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,mBAAmB,YACjCC,IAAA,CAAA,KAAA,EAAA,EACE,GAAG,EAAE,WAAW,EAChB,SAAS,EAAE,oBAAoB,EAC/B,KAAK,EAAE,EAAE,SAAS,EAAE,CAAA,EAAG,SAAS,CAAA,EAAA,CAAI,EAAE,SAAS,EAAE,MAAM,EAAE,EACzD,QAAQ,EAAE,oBAAoB,aAE7B,MAAM,IAAID,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,mBAAmB,EAAA,QAAA,EAAG,MAAM,GAAO,EAE7D,QAAQ,IACPA,GAAA,CAAA,KAAA,EAAA,EACE,EAAE,EAAE,SAAS,EACb,IAAI,EAAC,SAAS,EAAA,iBAAA,EACG,WAAW,EAAA,YAAA,EAChB,WAAW,GAAG,SAAS,GAAG,aAAa,YAElD,YAAY,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,KAAI;gCAChC,MAAM,UAAU,GACd,OAAO,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,QAAQ;AAC3C,gCAAA,MAAM,aAAa,GAAG,KAAK,KAAK,gBAAgB;AAEhD,gCAAA,MAAM,WAAW,GAAG,kBAAkB,CACpC,WAAW,EACX,eAAe,EACf;AACE,oCAAA,WAAW,EAAE,aAAa;AAC1B,oCAAA,aAAa,EAAE,UAAU;AAC1B,iCAAA,CACF;gCAED,QACEA,WAEE,EAAE,EAAE,GAAG,SAAS,CAAA,CAAA,EAAI,KAAK,CAAA,CAAE,EAAA,YAAA,EACf,KAAK,EACjB,SAAS,EAAE,WAAW,EACtB,OAAO,EAAE,MAAM,CAAC,UAAU,IAAI,YAAY,CAAC,IAAI,CAAC,EAChD,YAAY,EAAE,MACZ,CAAC,UAAU,IAAI,mBAAmB,CAAC,KAAK,CAAC,EAE3C,IAAI,EAAC,QAAQ,mBACE,aAAa,EAAA,eAAA,EACb,UAAU,EAAA,QAAA,EAExB;AACC,0CAAE,YAAY,CAAC,IAAI;0CACjB,eAAe,CAAC,IAAI,CAAC,EAAA,EAdpB,KAAK,CAeR;4BAER,CAAC,CAAC,GACE,KAENA,aAAK,GAAG,EAAE,QAAQ,EAAE,SAAS,EAAE,gBAAgB,EAAA,QAAA,EAC5C,KAAK,EAAA,CACF,CACP,EAEA,MAAM,IAAIA,GAAA,CAAA,KAAA,EAAA,EAAK,SAAS,EAAE,mBAAmB,YAAG,MAAM,EAAA,CAAO,IAC1D,EAAA,CACF,CACP,EAEDA,GAAA,CAAC,YAAY,IAAC,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,aAAa,EAAA,CAAI,CAAA,EAAA,CACxD,CACP;IAED,IAAI,CAAC,WAAW,EAAE;AAChB,QAAA,QACEC,IAAA,CAAC,KAAK,EAAA,EACJ,KAAK,EAAE,KAAK,EACZ,SAAS,EAAE,SAAS,EACpB,UAAU,EAAE,eAAe,EAC3B,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,cAAc,EAAA,QAAA,EAAA,CAExB,mBAAmB,EACnB,SAAS,CAAA,EAAA,CACJ;IAEZ;AAEA,IAAA,QACEA,IAAA,CAAAC,QAAA,EAAA,EAAA,QAAA,EAAA,CACG,mBAAmB,EACnB,SAAS,CAAA,EAAA,CACT;AAEP,CAAC;AAGH,YAAY,CAAC,WAAW,GAAG,cAAc;;"}
1
+ {"version":3,"file":"Autocomplete.js","sources":["../../../src/form/Autocomplete.tsx"],"sourcesContent":["import React, {\n forwardRef,\n useState,\n useRef,\n useEffect,\n useCallback,\n useId,\n} from 'react';\nimport {\n classNames,\n usePrefixedClassNames,\n prefixedClassNames,\n} from '../helpers/classNames';\nimport { useConfig } from '../helpers/Config';\nimport { useBulmaClasses, BulmaClassesProps } from '../helpers/useBulmaClasses';\nimport { useInsideField } from './FormContext';\nimport { Field } from './Field';\nimport { FormFieldProps } from './fieldProps';\nimport { useAutoLabelId } from './useAutoLabelId';\nimport { useControlLoading } from './controlLoading';\nimport { StatusRegion, spokenText } from '../helpers/statusRegion';\n\n/**\n * An item in the Autocomplete dropdown list.\n */\nexport interface AutocompleteItem {\n /** The value used for filtering and selection. */\n value: string;\n /** Display label (optional). */\n label?: string;\n /** Whether the item is disabled and unselectable. */\n disabled?: boolean;\n [key: string]: unknown;\n}\n\n// What the status region announces: the `empty` content, as the one item\n// it's handed while that content is on screen because of the user's typing.\nconst typedNoMatches = [{ id: 'empty' }];\nconst nothingToAnnounce: Array<{ id: string }> = [];\n\n// A press on an option would take focus from the field, since an option\n// can't hold it, and nothing would put it back. Cancelling the press keeps\n// it there, as the ARIA Authoring Practices' combobox does, and the click\n// still picks the option.\nconst keepFocus = (e: React.MouseEvent) => e.preventDefault();\n\n// An IME that's composing owns every key: Enter confirms what it composed,\n// and the arrows move through its candidates. Safari can say so with\n// `keyCode` 229 rather than `isComposing`.\nconst isComposing = (e: React.KeyboardEvent): boolean =>\n e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229;\n\n// Whether an option can be picked. The arrows still reach a disabled one, so\n// a screen reader user finds it.\nconst isEnabled = (item: AutocompleteItem | string): boolean =>\n typeof item === 'string' || !item.disabled;\n\n/**\n * Props for the Autocomplete component.\n * @extraProp {string} [className] - Additional CSS classes.\n * @extraProp {React.Ref<HTMLInputElement>} [ref] - Ref forwarded to the input element.\n */\nexport interface AutocompleteProps\n extends\n Omit<React.HTMLAttributes<HTMLDivElement>, 'onSelect' | 'onInput'>,\n Omit<BulmaClassesProps, 'color'>,\n FormFieldProps {\n /** Field label, associated with the text input via `htmlFor`: through your `id` when provided, otherwise a generated one. Dropped inside an outer `Field`, whose label names the input instead when it points at it. The `Field` points its label there itself when the Autocomplete has no `id` and no inner `Field` sits between them (and the `Field` is not `grouped` or `hasAddons`); a label you wire by hand with `labelProps.htmlFor` points at the input with that `id`. The label naming the input also names the open suggestion list, through `aria-labelledby`, when it has an id: this label always does, and an outer `Field`'s does unless you wired it by hand without an `id` in its `labelProps`. Otherwise the list is named \"Suggestions\". */\n label?: React.ReactNode;\n /** Props for the label element. An explicit `htmlFor` here overrides the automatic association (the input then gets no generated id). While the label names the input, the suggestion list's `aria-labelledby` points at it, through an `id` here when you give one and a generated one otherwise. */\n labelProps?: React.LabelHTMLAttributes<HTMLLabelElement> & {\n [key: string]: unknown;\n };\n /** Applied to the inner text input (the labellable control), not the wrapper div. */\n id?: string;\n /** The options data to display (required). */\n data: AutocompleteItem[] | string[];\n /** The current input value (controlled). */\n value?: string;\n /**\n * Does nothing: Autocomplete doesn't read it.\n *\n * @deprecated Nothing reads it, and `onSelect` is what reports a pick. It\n * will be removed in the next major version.\n */\n selected?: AutocompleteItem | string | null;\n /** Placeholder text for the input. */\n placeholder?: string;\n /** Object property to use as the display field. */\n field?: string;\n /**\n * Whether to show a clear button while the input holds a value.\n * It hides while the input is disabled, and gives way to a loading\n * spinner at the same right edge: the one `loading` draws, or that of a\n * `Control` with `isLoading` around the Autocomplete.\n */\n clearable?: boolean;\n /** Open dropdown when input is focused. */\n openOnFocus?: boolean;\n /**\n * Keep the first option highlighted whenever the list opens, Up Arrow and\n * Alt+Down Arrow included, and whenever the text in the field changes.\n * While the list is open on a highlighted option that isn't disabled, Enter\n * picks it rather than submitting a form around the field.\n */\n keepFirst?: boolean;\n /** Keep dropdown open after selection. */\n keepOpen?: boolean;\n /** Select highlighted item on click outside. */\n selectOnClickOutside?: boolean;\n /** Maximum dropdown height in pixels. */\n maxHeight?: number;\n /**\n * Does nothing: Autocomplete doesn't read it, and always shows its\n * suggestions in a dropdown.\n *\n * @deprecated It will be removed in the next major version, with nothing\n * in its place.\n */\n dropdown?: boolean;\n /**\n * Show a loading spinner in the input.\n * Under `prefers-reduced-motion: reduce` the spinner stops and stays\n * drawn (with bestax's CSS loaded).\n */\n loading?: boolean;\n /** Whether the input is disabled. */\n disabled?: boolean;\n /** Enables infinite scroll detection in the dropdown. */\n checkInfiniteScroll?: boolean;\n /** Distance in pixels from the bottom to trigger `onInfiniteScroll`. */\n infiniteScrollDistance?: number;\n /** Input color variant. */\n color?: 'primary' | 'link' | 'info' | 'success' | 'warning' | 'danger';\n /** Size variant. */\n size?: 'small' | 'medium' | 'large';\n /** Form field name. Forwarded to the inner `<input>`. */\n name?: string;\n /** Optional id of the form the input belongs to. */\n form?: string;\n /** Marks the field as required for native HTML form validation. */\n required?: boolean;\n /** Callback when input value changes. */\n onInput?: (value: string) => void;\n /** Callback when item is selected. */\n onSelect?: (item: AutocompleteItem | string | null) => void;\n /** Callback when dropdown active state changes. */\n onActiveChange?: (active: boolean) => void;\n /** Callback when scrolled to bottom (infinite scroll). */\n onInfiniteScroll?: () => void;\n /** Custom render for items. */\n itemTemplate?: (item: AutocompleteItem | string) => React.ReactNode;\n /** Custom header at the top of the dropdown. It sits above the list of options rather than in it, so assistive technology doesn't count it as one. */\n header?: React.ReactNode;\n /** Custom footer at the bottom of the dropdown. It sits below the list of options rather than in it, so assistive technology doesn't count it as one. */\n footer?: React.ReactNode;\n /**\n * A message the dropdown shows in place of the options when nothing\n * matches. Keep it to text: `Tab` closes the list, so a keyboard user\n * can't reach a link or button in it. It sits beside the list of options\n * rather than in it, so the input's `aria-expanded` stays false while it\n * shows. When the user's typing leaves nothing that matches, a polite\n * status region announces its text: once each time the matches run out.\n * The text is read when they first run out, and isn't read again as it\n * changes while they stay out, so a message that names the query is heard\n * for that first query only. Keep it static.\n * Opening the list without typing, or emptying the field, announces\n * nothing. While `loading`, or a `Control` with `isLoading` around the\n * Autocomplete, is on, it waits, and it's announced once loading ends\n * with nothing matching. Without `empty`, the dropdown closes when nothing\n * matches and nothing is announced.\n */\n empty?: React.ReactNode;\n}\n\n/**\n * The `Autocomplete` component provides an input field with dropdown suggestions that filter based on user input.\n *\n * @function\n * @param {AutocompleteProps} props - Props for the Autocomplete component.\n * @param {React.Ref<HTMLInputElement>} ref - Forwarded ref to the input element.\n * @returns {JSX.Element} The rendered autocomplete component.\n *\n * @example\n * // Basic usage with string array\n * <Autocomplete\n * data={['Apple', 'Banana', 'Cherry']}\n * placeholder=\"Search fruit...\"\n * onSelect={(item) => console.log(item)}\n * />\n *\n * @example\n * // With object data\n * <Autocomplete\n * data={[{ value: '1', label: 'Option 1' }, { value: '2', label: 'Option 2' }]}\n * field=\"label\"\n * onSelect={(item) => console.log(item)}\n * />\n */\nexport const Autocomplete = forwardRef<HTMLInputElement, AutocompleteProps>(\n (\n {\n data = [],\n value: controlledValue,\n placeholder,\n field = 'label',\n clearable = false,\n openOnFocus = false,\n keepFirst = false,\n keepOpen = false,\n selectOnClickOutside = false,\n maxHeight = 200,\n loading = false,\n disabled = false,\n checkInfiniteScroll = false,\n infiniteScrollDistance = 50,\n color,\n size,\n onInput,\n onSelect,\n onActiveChange,\n onInfiniteScroll,\n itemTemplate,\n header,\n footer,\n empty,\n name,\n form,\n required,\n id,\n // Deprecated no-ops, taken here so they stay off the wrapper.\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- deprecated no-op\n selected,\n // eslint-disable-next-line @typescript-eslint/no-unused-vars -- deprecated no-op\n dropdown,\n // Field props\n label,\n labelSize,\n labelProps,\n horizontal,\n message,\n messageColor,\n fieldClassName,\n className,\n ...props\n },\n ref\n ) => {\n const insideField = useInsideField();\n // The suggestion list points `aria-labelledby` at the label that names\n // the input, so it needs that label's id.\n const {\n controlId,\n fieldLabelProps,\n labelId: listLabelId,\n } = useAutoLabelId({\n label,\n id,\n labelProps,\n rendersLabel: !insideField,\n needsLabelId: true,\n });\n const { bulmaHelperClasses, rest } = useBulmaClasses(props);\n const { classPrefix } = useConfig();\n const containerRef = useRef<HTMLDivElement>(null);\n const inputRef = useRef<HTMLInputElement>(null);\n const dropdownRef = useRef<HTMLDivElement>(null);\n\n const [internalValue, setInternalValue] = useState('');\n const [isActive, setIsActive] = useState(false);\n // Whether the user has typed since the list opened, since only typing\n // gets the `empty` content announced. Closing the list resets it (during\n // render, React's pattern for adjusting state when other state changes),\n // so opening the list again without typing stays quiet.\n const [typed, setTyped] = useState(false);\n if (typed && !isActive) setTyped(false);\n const [highlightedIndex, setHighlightedIndex] = useState(-1);\n const listboxId = `${useId()}-listbox`;\n\n // Use controlled or internal value\n const inputValue =\n controlledValue !== undefined ? controlledValue : internalValue;\n\n // Get display value from item\n const getDisplayValue = (item: AutocompleteItem | string): string => {\n if (typeof item === 'string') return item;\n const fieldValue = item[field];\n if (typeof fieldValue === 'string') return fieldValue;\n return item.value || '';\n };\n\n // Filter data based on input\n const filteredData = data.filter(item => {\n const displayValue = getDisplayValue(item);\n return displayValue.toLowerCase().includes(inputValue.toLowerCase());\n });\n\n // The dropdown shows the options or, when nothing matches, the `empty`\n // content. The listbox holds only options, so it's on screen only while\n // there are some.\n const menuOpen = isActive && (filteredData.length > 0 || !!empty);\n const listOpen = isActive && filteredData.length > 0;\n\n // Handle input change\n const handleInputChange = useCallback(\n (e: React.ChangeEvent<HTMLInputElement>) => {\n const newValue = e.target.value;\n if (controlledValue === undefined) {\n setInternalValue(newValue);\n }\n onInput?.(newValue);\n setTyped(true);\n if (!isActive && newValue) {\n setIsActive(true);\n }\n },\n [controlledValue, isActive, onInput]\n );\n\n // Handle item selection\n const handleSelect = useCallback(\n (item: AutocompleteItem | string) => {\n if (typeof item !== 'string' && item.disabled) return;\n\n const displayValue = getDisplayValue(item);\n if (controlledValue === undefined) {\n setInternalValue(displayValue);\n }\n onInput?.(displayValue);\n onSelect?.(item);\n\n if (!keepOpen) {\n setIsActive(false);\n }\n setHighlightedIndex(-1);\n },\n [controlledValue, field, keepOpen, onInput, onSelect]\n );\n\n // Handle clear\n const handleClear = useCallback(() => {\n if (controlledValue === undefined) {\n setInternalValue('');\n }\n onInput?.('');\n onSelect?.(null);\n inputRef.current?.focus();\n }, [controlledValue, onInput, onSelect]);\n\n // Handle focus\n const handleFocus = useCallback(() => {\n if (openOnFocus && !disabled) {\n setIsActive(true);\n }\n }, [openOnFocus, disabled]);\n\n // Handle blur (click outside)\n useEffect(() => {\n if (!isActive) return undefined;\n\n const handleClickOutside = (e: MouseEvent) => {\n if (!containerRef.current) return;\n\n // Use composedPath() to correctly detect clicks inside Shadow DOM\n const path = e.composedPath();\n const isInside = path.includes(containerRef.current);\n\n if (!isInside) {\n if (selectOnClickOutside && highlightedIndex >= 0) {\n handleSelect(filteredData[highlightedIndex]);\n }\n setIsActive(false);\n }\n };\n\n document.addEventListener('mousedown', handleClickOutside);\n return () =>\n document.removeEventListener('mousedown', handleClickOutside);\n }, [\n isActive,\n selectOnClickOutside,\n highlightedIndex,\n filteredData,\n handleSelect,\n ]);\n\n // Notify active state change\n useEffect(() => {\n onActiveChange?.(isActive);\n }, [isActive, onActiveChange]);\n\n // Keep first highlighted\n useEffect(() => {\n if (keepFirst && isActive && filteredData.length > 0) {\n setHighlightedIndex(0);\n }\n }, [keepFirst, isActive, filteredData.length, inputValue]);\n\n // Handle keyboard navigation\n const handleKeyDown = useCallback(\n (e: React.KeyboardEvent) => {\n if (disabled || isComposing(e)) return;\n\n switch (e.key) {\n case 'ArrowDown':\n e.preventDefault();\n if (!isActive) {\n // A closed list opens on its first enabled option, as the ARIA\n // Authoring Practices' combobox does. Alt+Down Arrow opens it\n // without a highlight.\n setIsActive(true);\n setHighlightedIndex(\n e.altKey ? -1 : filteredData.map(isEnabled).indexOf(true)\n );\n } else {\n setHighlightedIndex(prev =>\n prev < filteredData.length - 1 ? prev + 1 : prev\n );\n }\n break;\n case 'ArrowUp':\n e.preventDefault();\n if (!isActive) {\n // And Up Arrow opens it on its last enabled option.\n setIsActive(true);\n setHighlightedIndex(\n filteredData.map(isEnabled).lastIndexOf(true)\n );\n } else {\n setHighlightedIndex(prev => (prev > 0 ? prev - 1 : prev));\n }\n break;\n case 'Enter':\n // With the list open on a highlighted option it can pick, Enter\n // is that option's. Otherwise it closes the list and goes on, so\n // a form around the field submits, as it would from any text\n // field.\n if (\n isActive &&\n highlightedIndex >= 0 &&\n filteredData[highlightedIndex] &&\n isEnabled(filteredData[highlightedIndex])\n ) {\n e.preventDefault();\n handleSelect(filteredData[highlightedIndex]);\n } else {\n setIsActive(false);\n }\n break;\n case 'Escape':\n // Only closing the dropdown claims the key. With it closed, the\n // key goes on to a Modal around the field.\n if (menuOpen) e.preventDefault();\n setIsActive(false);\n setHighlightedIndex(-1);\n break;\n case 'Tab':\n if (\n isActive &&\n highlightedIndex >= 0 &&\n filteredData[highlightedIndex]\n ) {\n handleSelect(filteredData[highlightedIndex]);\n }\n setIsActive(false);\n break;\n }\n },\n [\n disabled,\n isActive,\n menuOpen,\n highlightedIndex,\n filteredData,\n handleSelect,\n ]\n );\n\n // Handle dropdown scroll for infinite scroll\n const handleDropdownScroll = useCallback(() => {\n if (!checkInfiniteScroll || !dropdownRef.current) return;\n\n const { scrollTop, scrollHeight, clientHeight } = dropdownRef.current;\n if (scrollHeight - scrollTop - clientHeight <= infiniteScrollDistance) {\n onInfiniteScroll?.();\n }\n }, [checkInfiniteScroll, infiniteScrollDistance, onInfiniteScroll]);\n\n // Scroll highlighted item into view\n useEffect(() => {\n if (highlightedIndex >= 0 && dropdownRef.current) {\n const highlightedEl = dropdownRef.current.querySelector(\n `[data-index=\"${highlightedIndex}\"]`\n );\n if (\n highlightedEl &&\n typeof highlightedEl.scrollIntoView === 'function'\n ) {\n highlightedEl.scrollIntoView({ block: 'nearest' });\n }\n }\n }, [highlightedIndex]);\n\n // Combined ref\n const combinedRef = useCallback(\n (node: HTMLInputElement | null) => {\n (inputRef as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n if (typeof ref === 'function') {\n ref(node);\n } else if (ref) {\n (ref as React.MutableRefObject<HTMLInputElement | null>).current =\n node;\n }\n },\n [ref]\n );\n\n // Generate classes\n const autocompleteClasses = usePrefixedClassNames('autocomplete', {\n 'is-active': isActive,\n [`is-${size}`]: !!size,\n });\n\n const inputClasses = usePrefixedClassNames('input', {\n [`is-${color}`]: !!color,\n [`is-${size}`]: !!size,\n 'is-loading': loading,\n });\n\n const controlClasses = usePrefixedClassNames(\n 'control',\n 'is-expanded',\n 'has-icons-right'\n );\n\n const dropdownMenuClasses = usePrefixedClassNames('dropdown-menu', {\n 'is-active': menuOpen,\n });\n\n const dropdownContentClass = usePrefixedClassNames('dropdown-content');\n const dropdownHeaderClass = usePrefixedClassNames('dropdown-header');\n const dropdownFooterClass = usePrefixedClassNames('dropdown-footer');\n const emptyItemClasses = usePrefixedClassNames(\n 'dropdown-item',\n 'has-text-grey'\n );\n\n const iconRightClickableClass = usePrefixedClassNames(\n 'icon',\n 'is-right',\n 'is-clickable'\n );\n const iconRightClass = usePrefixedClassNames('icon', 'is-right');\n const loaderClass = usePrefixedClassNames('loader', 'is-loading');\n\n const combinedClasses = classNames(\n autocompleteClasses,\n bulmaHelperClasses,\n className\n );\n\n const helpClass = usePrefixedClassNames('help', {\n [`is-${messageColor}`]: !!messageColor,\n });\n const messageEl = message ? <p className={helpClass}>{message}</p> : null;\n\n // The clear button gives way to a spinner at its spot: the `loading` one,\n // or that of a loading Control this sits in.\n const controlLoading = useControlLoading();\n const showClear =\n clearable && !!inputValue && !disabled && !loading && !controlLoading;\n\n // The combobox controls its listbox and points at the highlighted option.\n // The listbox takes its name from the label that names the combobox, the\n // one this renders or a surrounding Field's, so the two say the same\n // thing. When no label names the combobox, or the one that does has no\n // id to point at, the list keeps a fallback name. While the dropdown\n // shows only the `empty` content there's no listbox, so the combobox is\n // collapsed and points at nothing.\n const activeOptionId =\n listOpen &&\n highlightedIndex >= 0 &&\n highlightedIndex < filteredData.length\n ? `${listboxId}-${highlightedIndex}`\n : undefined;\n\n // A polite status region, in the page from the start so it's there\n // before anything is written into it, announces the `empty` content\n // when the user's typing leaves nothing that matches what's in the\n // field. It follows what's on screen, so results that come in after the\n // typing count too. It's said once each time that happens, not again on\n // each keystroke while nothing matches. An empty field isn't a search,\n // so it stays quiet then, even with no data. While `loading`, or a\n // loading Control around it, says results are on their way, it waits,\n // and it's said once loading ends with nothing matching.\n const emptyItems =\n typed &&\n menuOpen &&\n !listOpen &&\n !!inputValue &&\n !loading &&\n !controlLoading\n ? typedNoMatches\n : nothingToAnnounce;\n // The region reads the text on screen, whatever `empty` renders.\n const emptyRef = useRef<HTMLDivElement>(null);\n const describeEmpty = useCallback(() => {\n const node = emptyRef.current;\n /* istanbul ignore if: it's only announced while it's on screen */\n if (!node) return null;\n return spokenText(node);\n }, []);\n\n const autocompleteElement = (\n <div ref={containerRef} className={combinedClasses} {...rest}>\n <div className={controlClasses}>\n <input\n ref={combinedRef}\n type=\"text\"\n className={inputClasses}\n id={controlId}\n value={inputValue}\n placeholder={placeholder}\n disabled={disabled}\n name={name}\n form={form}\n required={required}\n onChange={handleInputChange}\n onFocus={handleFocus}\n onKeyDown={handleKeyDown}\n role=\"combobox\"\n aria-expanded={listOpen}\n aria-controls={listOpen ? listboxId : undefined}\n aria-activedescendant={activeOptionId}\n aria-haspopup=\"listbox\"\n aria-autocomplete=\"list\"\n autoComplete=\"off\"\n />\n {showClear && (\n <button\n type=\"button\"\n className={iconRightClickableClass}\n onClick={handleClear}\n aria-label=\"Clear\"\n >\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n width=\"16\"\n height=\"16\"\n aria-hidden=\"true\"\n >\n <line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\" />\n <line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\" />\n </svg>\n </button>\n )}\n {loading && (\n <span className={iconRightClass}>\n <span className={loaderClass} />\n </span>\n )}\n </div>\n\n {menuOpen && (\n <div className={dropdownMenuClasses}>\n <div\n ref={dropdownRef}\n className={dropdownContentClass}\n style={{ maxHeight: `${maxHeight}px`, overflowY: 'auto' }}\n onScroll={handleDropdownScroll}\n >\n {header && <div className={dropdownHeaderClass}>{header}</div>}\n\n {listOpen ? (\n <div\n id={listboxId}\n role=\"listbox\"\n aria-labelledby={listLabelId}\n aria-label={listLabelId ? undefined : 'Suggestions'}\n onMouseDown={keepFocus}\n >\n {filteredData.map((item, index) => {\n const isDisabled =\n typeof item !== 'string' && item.disabled;\n const isHighlighted = index === highlightedIndex;\n\n const itemClasses = prefixedClassNames(\n classPrefix,\n 'dropdown-item',\n {\n 'is-active': isHighlighted,\n 'is-disabled': isDisabled,\n }\n );\n\n return (\n <a\n key={index}\n id={`${listboxId}-${index}`}\n data-index={index}\n className={itemClasses}\n onClick={() => !isDisabled && handleSelect(item)}\n onMouseEnter={() =>\n !isDisabled && setHighlightedIndex(index)\n }\n role=\"option\"\n aria-selected={isHighlighted && !isDisabled}\n aria-disabled={isDisabled}\n >\n {itemTemplate\n ? itemTemplate(item)\n : getDisplayValue(item)}\n </a>\n );\n })}\n </div>\n ) : (\n <div\n ref={emptyRef}\n className={emptyItemClasses}\n onMouseDown={keepFocus}\n >\n {empty}\n </div>\n )}\n\n {footer && <div className={dropdownFooterClass}>{footer}</div>}\n </div>\n </div>\n )}\n\n <StatusRegion items={emptyItems} describe={describeEmpty} />\n </div>\n );\n\n if (!insideField) {\n return (\n <Field\n label={label}\n labelSize={labelSize}\n labelProps={fieldLabelProps}\n horizontal={horizontal}\n className={fieldClassName}\n >\n {autocompleteElement}\n {messageEl}\n </Field>\n );\n }\n\n return (\n <>\n {autocompleteElement}\n {messageEl}\n </>\n );\n }\n);\n\nAutocomplete.displayName = 'Autocomplete';\n\nexport default Autocomplete;\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
package/dist/index.cjs CHANGED
@@ -12646,6 +12646,18 @@ Rate.displayName = 'Rate';
12646
12646
  // it's handed while that content is on screen because of the user's typing.
12647
12647
  const typedNoMatches = [{ id: 'empty' }];
12648
12648
  const nothingToAnnounce = [];
12649
+ // A press on an option would take focus from the field, since an option
12650
+ // can't hold it, and nothing would put it back. Cancelling the press keeps
12651
+ // it there, as the ARIA Authoring Practices' combobox does, and the click
12652
+ // still picks the option.
12653
+ const keepFocus = (e) => e.preventDefault();
12654
+ // An IME that's composing owns every key: Enter confirms what it composed,
12655
+ // and the arrows move through its candidates. Safari can say so with
12656
+ // `keyCode` 229 rather than `isComposing`.
12657
+ const isComposing = (e) => e.nativeEvent.isComposing || e.nativeEvent.keyCode === 229;
12658
+ // Whether an option can be picked. The arrows still reach a disabled one, so
12659
+ // a screen reader user finds it.
12660
+ const isEnabled = (item) => typeof item === 'string' || !item.disabled;
12649
12661
  /**
12650
12662
  * The `Autocomplete` component provides an input field with dropdown suggestions that filter based on user input.
12651
12663
  *
@@ -12805,13 +12817,17 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
12805
12817
  }, [keepFirst, isActive, filteredData.length, inputValue]);
12806
12818
  // Handle keyboard navigation
12807
12819
  const handleKeyDown = React.useCallback((e) => {
12808
- if (disabled)
12820
+ if (disabled || isComposing(e))
12809
12821
  return;
12810
12822
  switch (e.key) {
12811
12823
  case 'ArrowDown':
12812
12824
  e.preventDefault();
12813
12825
  if (!isActive) {
12826
+ // A closed list opens on its first enabled option, as the ARIA
12827
+ // Authoring Practices' combobox does. Alt+Down Arrow opens it
12828
+ // without a highlight.
12814
12829
  setIsActive(true);
12830
+ setHighlightedIndex(e.altKey ? -1 : filteredData.map(isEnabled).indexOf(true));
12815
12831
  }
12816
12832
  else {
12817
12833
  setHighlightedIndex(prev => prev < filteredData.length - 1 ? prev + 1 : prev);
@@ -12819,13 +12835,30 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
12819
12835
  break;
12820
12836
  case 'ArrowUp':
12821
12837
  e.preventDefault();
12822
- setHighlightedIndex(prev => (prev > 0 ? prev - 1 : prev));
12838
+ if (!isActive) {
12839
+ // And Up Arrow opens it on its last enabled option.
12840
+ setIsActive(true);
12841
+ setHighlightedIndex(filteredData.map(isEnabled).lastIndexOf(true));
12842
+ }
12843
+ else {
12844
+ setHighlightedIndex(prev => (prev > 0 ? prev - 1 : prev));
12845
+ }
12823
12846
  break;
12824
12847
  case 'Enter':
12825
- e.preventDefault();
12826
- if (highlightedIndex >= 0 && filteredData[highlightedIndex]) {
12848
+ // With the list open on a highlighted option it can pick, Enter
12849
+ // is that option's. Otherwise it closes the list and goes on, so
12850
+ // a form around the field submits, as it would from any text
12851
+ // field.
12852
+ if (isActive &&
12853
+ highlightedIndex >= 0 &&
12854
+ filteredData[highlightedIndex] &&
12855
+ isEnabled(filteredData[highlightedIndex])) {
12856
+ e.preventDefault();
12827
12857
  handleSelect(filteredData[highlightedIndex]);
12828
12858
  }
12859
+ else {
12860
+ setIsActive(false);
12861
+ }
12829
12862
  break;
12830
12863
  case 'Escape':
12831
12864
  // Only closing the dropdown claims the key. With it closed, the
@@ -12836,7 +12869,9 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
12836
12869
  setHighlightedIndex(-1);
12837
12870
  break;
12838
12871
  case 'Tab':
12839
- if (highlightedIndex >= 0 && filteredData[highlightedIndex]) {
12872
+ if (isActive &&
12873
+ highlightedIndex >= 0 &&
12874
+ filteredData[highlightedIndex]) {
12840
12875
  handleSelect(filteredData[highlightedIndex]);
12841
12876
  }
12842
12877
  setIsActive(false);
@@ -12949,17 +12984,17 @@ label, labelSize, labelProps, horizontal, message, messageColor, fieldClassName,
12949
12984
  return null;
12950
12985
  return spokenText(node);
12951
12986
  }, []);
12952
- const autocompleteElement = (jsxRuntime.jsxs("div", { ref: containerRef, className: combinedClasses, ...rest, children: [jsxRuntime.jsxs("div", { className: controlClasses, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: placeholder, disabled: disabled, name: name, form: form, required: required, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, role: "combobox", "aria-expanded": listOpen, "aria-controls": listOpen ? listboxId : undefined, "aria-activedescendant": activeOptionId, "aria-haspopup": "listbox", "aria-autocomplete": "list", autoComplete: "off" }), showClear && (jsxRuntime.jsx("button", { type: "button", className: iconRightClickableClass, onClick: handleClear, "aria-label": "Clear", children: jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", "aria-hidden": "true", children: [jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })), loading && (jsxRuntime.jsx("span", { className: iconRightClass, children: jsxRuntime.jsx("span", { className: loaderClass }) }))] }), menuOpen && (jsxRuntime.jsx("div", { className: dropdownMenuClasses, children: jsxRuntime.jsxs("div", { ref: dropdownRef, className: dropdownContentClass, style: { maxHeight: `${maxHeight}px`, overflowY: 'auto' }, onScroll: handleDropdownScroll, children: [header && jsxRuntime.jsx("div", { className: dropdownHeaderClass, children: header }), listOpen ? (jsxRuntime.jsx("div", { id: listboxId, role: "listbox", "aria-labelledby": listLabelId, "aria-label": listLabelId ? undefined : 'Suggestions', children: filteredData.map((item, index) => {
12987
+ const autocompleteElement = (jsxRuntime.jsxs("div", { ref: containerRef, className: combinedClasses, ...rest, children: [jsxRuntime.jsxs("div", { className: controlClasses, children: [jsxRuntime.jsx("input", { ref: combinedRef, type: "text", className: inputClasses, id: controlId, value: inputValue, placeholder: placeholder, disabled: disabled, name: name, form: form, required: required, onChange: handleInputChange, onFocus: handleFocus, onKeyDown: handleKeyDown, role: "combobox", "aria-expanded": listOpen, "aria-controls": listOpen ? listboxId : undefined, "aria-activedescendant": activeOptionId, "aria-haspopup": "listbox", "aria-autocomplete": "list", autoComplete: "off" }), showClear && (jsxRuntime.jsx("button", { type: "button", className: iconRightClickableClass, onClick: handleClear, "aria-label": "Clear", children: jsxRuntime.jsxs("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", width: "16", height: "16", "aria-hidden": "true", children: [jsxRuntime.jsx("line", { x1: "18", y1: "6", x2: "6", y2: "18" }), jsxRuntime.jsx("line", { x1: "6", y1: "6", x2: "18", y2: "18" })] }) })), loading && (jsxRuntime.jsx("span", { className: iconRightClass, children: jsxRuntime.jsx("span", { className: loaderClass }) }))] }), menuOpen && (jsxRuntime.jsx("div", { className: dropdownMenuClasses, children: jsxRuntime.jsxs("div", { ref: dropdownRef, className: dropdownContentClass, style: { maxHeight: `${maxHeight}px`, overflowY: 'auto' }, onScroll: handleDropdownScroll, children: [header && jsxRuntime.jsx("div", { className: dropdownHeaderClass, children: header }), listOpen ? (jsxRuntime.jsx("div", { id: listboxId, role: "listbox", "aria-labelledby": listLabelId, "aria-label": listLabelId ? undefined : 'Suggestions', onMouseDown: keepFocus, children: filteredData.map((item, index) => {
12953
12988
  const isDisabled = typeof item !== 'string' && item.disabled;
12954
12989
  const isHighlighted = index === highlightedIndex;
12955
12990
  const itemClasses = prefixedClassNames(classPrefix, 'dropdown-item', {
12956
12991
  'is-active': isHighlighted,
12957
12992
  'is-disabled': isDisabled,
12958
12993
  });
12959
- return (jsxRuntime.jsx("a", { id: `${listboxId}-${index}`, "data-index": index, className: itemClasses, onClick: () => !isDisabled && handleSelect(item), onMouseEnter: () => !isDisabled && setHighlightedIndex(index), role: "option", "aria-selected": isHighlighted, "aria-disabled": isDisabled, children: itemTemplate
12994
+ return (jsxRuntime.jsx("a", { id: `${listboxId}-${index}`, "data-index": index, className: itemClasses, onClick: () => !isDisabled && handleSelect(item), onMouseEnter: () => !isDisabled && setHighlightedIndex(index), role: "option", "aria-selected": isHighlighted && !isDisabled, "aria-disabled": isDisabled, children: itemTemplate
12960
12995
  ? itemTemplate(item)
12961
12996
  : getDisplayValue(item) }, index));
12962
- }) })) : (jsxRuntime.jsx("div", { ref: emptyRef, className: emptyItemClasses, children: empty })), footer && jsxRuntime.jsx("div", { className: dropdownFooterClass, children: footer })] }) })), jsxRuntime.jsx(StatusRegion, { items: emptyItems, describe: describeEmpty })] }));
12997
+ }) })) : (jsxRuntime.jsx("div", { ref: emptyRef, className: emptyItemClasses, onMouseDown: keepFocus, children: empty })), footer && jsxRuntime.jsx("div", { className: dropdownFooterClass, children: footer })] }) })), jsxRuntime.jsx(StatusRegion, { items: emptyItems, describe: describeEmpty })] }));
12963
12998
  if (!insideField) {
12964
12999
  return (jsxRuntime.jsxs(Field, { label: label, labelSize: labelSize, labelProps: fieldLabelProps, horizontal: horizontal, className: fieldClassName, children: [autocompleteElement, messageEl] }));
12965
13000
  }