{"mappings":"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","sources":["packages/react-aria/src/combobox/useComboBox.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {announce} from '../live-announcer/LiveAnnouncer';\n\nimport {AriaButtonProps} from '../button/useButton';\nimport {ariaHideOutside} from '../overlays/ariaHideOutside';\nimport {\n  AriaLabelingProps,\n  BaseEvent,\n  DOMAttributes,\n  DOMProps,\n  InputDOMProps,\n  KeyboardDelegate,\n  LayoutDelegate,\n  PressEvent,\n  RefObject,\n  RouterOptions,\n  ValidationResult\n} from '@react-types/shared';\nimport {AriaListBoxOptions} from '../listbox/useListBox';\nimport {chain} from '../utils/chain';\nimport {ComboBoxProps, ComboBoxState, SelectionMode} from 'react-stately/useComboBoxState';\nimport {dispatchVirtualFocus} from '../focus/virtualFocus';\nimport {\n  FocusEvent,\n  InputHTMLAttributes,\n  KeyboardEvent,\n  TouchEvent,\n  useEffect,\n  useMemo,\n  useRef,\n  useState\n} from 'react';\nimport {getActiveElement, getEventTarget, nodeContains} from '../utils/shadowdom/DOMFunctions';\nimport {getChildNodes} from 'react-stately/private/collections/getChildNodes';\nimport {getItemCount} from 'react-stately/private/collections/getItemCount';\nimport {getItemId, listData} from '../listbox/utils';\nimport {getOwnerDocument} from '../utils/domHelpers';\nimport intlMessages from '../../intl/combobox/*.json';\nimport {isAppleDevice} from '../utils/platform';\nimport {ListKeyboardDelegate} from '../selection/ListKeyboardDelegate';\nimport {mergeProps} from '../utils/mergeProps';\nimport {privateValidationStateProp} from 'react-stately/private/form/useFormValidationState';\nimport {useEvent} from '../utils/useEvent';\nimport {useFormReset} from '../utils/useFormReset';\nimport {useId} from '../utils/useId';\n// @ts-ignore\nimport {useLabels} from '../utils/useLabels';\nimport {useLocalizedStringFormatter} from '../i18n/useLocalizedStringFormatter';\nimport {useMenuTrigger} from '../menu/useMenuTrigger';\nimport {useRouter} from '../utils/openLink';\nimport {useSelectableCollection} from '../selection/useSelectableCollection';\nimport {useTextField} from '../textfield/useTextField';\nimport {useUpdateEffect} from '../utils/useUpdateEffect';\n\nexport interface AriaComboBoxProps<T, M extends SelectionMode = 'single'>\n  extends ComboBoxProps<T, M>, DOMProps, InputDOMProps, AriaLabelingProps {\n  /** Whether keyboard navigation is circular. */\n  shouldFocusWrap?: boolean;\n}\n\nexport interface AriaComboBoxOptions<T, M extends SelectionMode = 'single'> extends Omit<\n  AriaComboBoxProps<T, M>,\n  'children'\n> {\n  /** The ref for the input element. */\n  inputRef: RefObject<HTMLInputElement | null>;\n  /** The ref for the list box popover. */\n  popoverRef: RefObject<Element | null>;\n  /** The ref for the list box. */\n  listBoxRef: RefObject<HTMLElement | null>;\n  /** The ref for the optional list box popup trigger button. */\n  buttonRef?: RefObject<Element | null>;\n  /** An optional keyboard delegate implementation, to override the default. */\n  keyboardDelegate?: KeyboardDelegate;\n  /**\n   * A delegate object that provides layout information for items in the collection.\n   * By default this uses the DOM, but this can be overridden to implement things like\n   * virtualized scrolling.\n   */\n  layoutDelegate?: LayoutDelegate;\n}\n\nexport interface ComboBoxAria<T> extends ValidationResult {\n  /** Props for the label element. */\n  labelProps: DOMAttributes;\n  /** Props for the combo box input element. */\n  inputProps: InputHTMLAttributes<HTMLInputElement>;\n  /** Props for the list box, to be passed to `useListBox`. */\n  listBoxProps: AriaListBoxOptions<T>;\n  /** Props for the optional trigger button, to be passed to `useButton`. */\n  buttonProps: AriaButtonProps;\n  /** Props for the element representing the selected value. */\n  valueProps: DOMAttributes;\n  /** Props for the combo box description element, if any. */\n  descriptionProps: DOMAttributes;\n  /** Props for the combo box error message element, if any. */\n  errorMessageProps: DOMAttributes;\n}\n\n/**\n * Provides the behavior and accessibility implementation for a combo box component. A combo box\n * combines a text input with a listbox, allowing users to filter a list of options to items\n * matching a query.\n *\n * @param props - Props for the combo box.\n * @param state - State for the select, as returned by `useComboBoxState`.\n */\nexport function useComboBox<T, M extends SelectionMode = 'single'>(\n  props: AriaComboBoxOptions<T, M>,\n  state: ComboBoxState<T, M>\n): ComboBoxAria<T> {\n  let {\n    buttonRef,\n    popoverRef,\n    inputRef,\n    listBoxRef,\n    keyboardDelegate,\n    layoutDelegate,\n    // completionMode = 'suggest',\n    shouldFocusWrap,\n    isReadOnly,\n    isDisabled\n  } = props;\n  let backupBtnRef = useRef(null);\n  buttonRef = buttonRef ?? backupBtnRef;\n\n  let stringFormatter = useLocalizedStringFormatter(intlMessages, '@react-aria/combobox');\n  let {menuTriggerProps, menuProps} = useMenuTrigger<T>(\n    {\n      type: 'listbox',\n      isDisabled: isDisabled || isReadOnly\n    },\n    state,\n    buttonRef\n  );\n\n  // Set listbox id so it can be used when calling getItemId later\n  listData.set(state, {id: menuProps.id});\n\n  // By default, a KeyboardDelegate is provided which uses the DOM to query layout information (e.g. for page up/page down).\n  // When virtualized, the layout object will be passed in as a prop and override this.\n  let {collection} = state;\n  let {disabledKeys} = state.selectionManager;\n  let delegate = useMemo(\n    () =>\n      keyboardDelegate ||\n      new ListKeyboardDelegate({\n        collection,\n        disabledKeys,\n        ref: listBoxRef,\n        layoutDelegate\n      }),\n    [keyboardDelegate, layoutDelegate, collection, disabledKeys, listBoxRef]\n  );\n\n  // Use useSelectableCollection to get the keyboard handlers to apply to the textfield\n  let {collectionProps} = useSelectableCollection({\n    selectionManager: state.selectionManager,\n    keyboardDelegate: delegate,\n    disallowTypeAhead: true,\n    disallowEmptySelection: true,\n    shouldFocusWrap,\n    ref: inputRef,\n    // Prevent item scroll behavior from being applied here, should be handled in the user's Popover + ListBox component\n    isVirtualized: true\n  });\n\n  let router = useRouter();\n\n  // For textfield specific keydown operations\n  let onKeyDown = (e: BaseEvent<KeyboardEvent<any>>) => {\n    if (e.nativeEvent.isComposing) {\n      return;\n    }\n    switch (e.key) {\n      case 'Enter':\n      case 'Tab':\n        // Prevent form submission if menu is open since we may be selecting a option\n        if (state.isOpen && e.key === 'Enter') {\n          e.preventDefault();\n        }\n\n        // If the focused item is a link, trigger opening it. Items that are links are not selectable.\n        if (state.isOpen && listBoxRef.current && state.selectionManager.focusedKey != null) {\n          let collectionItem = state.collection.getItem(state.selectionManager.focusedKey);\n          if (collectionItem?.props.href) {\n            let item = listBoxRef.current.querySelector(\n              `[data-key=\"${CSS.escape(state.selectionManager.focusedKey.toString())}\"]`\n            );\n            if (e.key === 'Enter' && item instanceof HTMLAnchorElement) {\n              router.open(\n                item,\n                e,\n                collectionItem.props.href,\n                collectionItem.props.routerOptions as RouterOptions\n              );\n            }\n            state.close();\n            break;\n          } else if (collectionItem?.props.onAction) {\n            collectionItem.props.onAction();\n            state.close();\n            break;\n          }\n        }\n        if (e.key === 'Enter' || state.isOpen) {\n          state.commit();\n        }\n        break;\n      case 'Escape':\n        if (!state.selectionManager.isEmpty || state.inputValue === '' || props.allowsCustomValue) {\n          e.continuePropagation();\n        }\n        state.revert();\n        break;\n      case 'ArrowDown':\n        state.open('first', 'manual');\n        break;\n      case 'ArrowUp':\n        state.open('last', 'manual');\n        break;\n      case 'ArrowLeft':\n      case 'ArrowRight':\n        state.selectionManager.setFocusedKey(null);\n        break;\n    }\n  };\n\n  let onBlur = (e: FocusEvent<HTMLInputElement>) => {\n    let blurFromButton = buttonRef?.current && buttonRef.current === e.relatedTarget;\n    let blurIntoPopover = nodeContains(popoverRef.current, e.relatedTarget);\n    // Ignore blur if focused moved to the button(if exists) or into the popover.\n    if (blurFromButton || blurIntoPopover) {\n      return;\n    }\n\n    if (props.onBlur) {\n      props.onBlur(e);\n    }\n\n    state.setFocused(false);\n  };\n\n  let onFocus = (e: FocusEvent<HTMLInputElement>) => {\n    if (state.isFocused) {\n      return;\n    }\n\n    if (props.onFocus) {\n      props.onFocus(e);\n    }\n\n    state.setFocused(true);\n  };\n\n  let valueId = useValueId([\n    state.selectionManager.selectedKeys,\n    state.selectionManager.selectionMode\n  ]);\n  let {isInvalid, validationErrors, validationDetails} = state.displayValidation;\n  let {labelProps, inputProps, descriptionProps, errorMessageProps} = useTextField(\n    {\n      ...props,\n      // In multi-select mode, only set required if the selection is empty.\n      isRequired:\n        props.selectionMode === 'multiple'\n          ? props.isRequired && state.selectionManager.isEmpty\n          : props.isRequired,\n      onChange: state.setInputValue,\n      onKeyDown: !isReadOnly\n        ? chain(state.isOpen && collectionProps.onKeyDown, onKeyDown, props.onKeyDown)\n        : props.onKeyDown,\n      onBlur,\n      value: state.inputValue,\n      defaultValue: state.defaultInputValue,\n      onFocus,\n      autoComplete: 'off',\n      validate: undefined,\n      [privateValidationStateProp]: state,\n      'aria-describedby':\n        [valueId, props['aria-describedby']].filter(Boolean).join(' ') || undefined\n    },\n    inputRef\n  );\n\n  useFormReset(inputRef, state.defaultValue, state.setValue);\n\n  // Press handlers for the ComboBox button\n  let onPress = (e: PressEvent) => {\n    if (e.pointerType === 'touch') {\n      // Focus the input field in case it isn't focused yet\n      inputRef.current?.focus();\n      state.toggle(null, 'manual');\n    }\n  };\n\n  let onPressStart = (e: PressEvent) => {\n    if (e.pointerType !== 'touch') {\n      inputRef.current?.focus();\n      state.toggle(\n        e.pointerType === 'keyboard' || e.pointerType === 'virtual' ? 'first' : null,\n        'manual'\n      );\n    }\n  };\n\n  let triggerLabelProps = useLabels({\n    id: menuTriggerProps.id,\n    'aria-label': stringFormatter.format('buttonLabel'),\n    'aria-labelledby': props['aria-labelledby'] || labelProps.id\n  });\n\n  let listBoxProps = useLabels({\n    id: menuProps.id,\n    'aria-label': stringFormatter.format('listboxLabel'),\n    'aria-labelledby': props['aria-labelledby'] || labelProps.id\n  });\n\n  // If a touch happens on direct center of ComboBox input, might be virtual click from iPad so open ComboBox menu\n  let lastEventTime = useRef(0);\n  let onTouchEnd = (e: TouchEvent) => {\n    if (isDisabled || isReadOnly) {\n      return;\n    }\n\n    // Sometimes VoiceOver on iOS fires two touchend events in quick succession. Ignore the second one.\n    if (e.timeStamp - lastEventTime.current < 500) {\n      e.preventDefault();\n      inputRef.current?.focus();\n      return;\n    }\n\n    let rect = (getEventTarget(e) as Element).getBoundingClientRect();\n    let touch = e.changedTouches[0];\n\n    let centerX = Math.ceil(rect.left + 0.5 * rect.width);\n    let centerY = Math.ceil(rect.top + 0.5 * rect.height);\n\n    if (touch.clientX === centerX && touch.clientY === centerY) {\n      e.preventDefault();\n      inputRef.current?.focus();\n      state.toggle(null, 'manual');\n\n      lastEventTime.current = e.timeStamp;\n    }\n  };\n\n  // VoiceOver has issues with announcing aria-activedescendant properly on change\n  // (especially on iOS). We use a live region announcer to announce focus changes\n  // manually. In addition, section titles are announced when navigating into a new section.\n  let focusedItem =\n    state.selectionManager.focusedKey != null && state.isOpen\n      ? state.collection.getItem(state.selectionManager.focusedKey)\n      : undefined;\n  let sectionKey = focusedItem?.parentKey ?? null;\n  let itemKey = state.selectionManager.focusedKey ?? null;\n  let lastSection = useRef(sectionKey);\n  let lastItem = useRef(itemKey);\n  useEffect(() => {\n    if (isAppleDevice() && focusedItem != null && itemKey != null && itemKey !== lastItem.current) {\n      let isSelected = state.selectionManager.isSelected(itemKey);\n      let section = sectionKey != null ? state.collection.getItem(sectionKey) : null;\n      let sectionTitle =\n        section?.['aria-label'] ||\n        (typeof section?.rendered === 'string' ? section.rendered : '') ||\n        '';\n\n      let announcement = stringFormatter.format('focusAnnouncement', {\n        isGroupChange: (section && sectionKey !== lastSection.current) ?? false,\n        groupTitle: sectionTitle,\n        groupCount: section ? [...getChildNodes(section, state.collection)].length : 0,\n        optionText: focusedItem['aria-label'] || focusedItem.textValue || '',\n        isSelected\n      });\n\n      announce(announcement);\n    }\n\n    lastSection.current = sectionKey;\n    lastItem.current = itemKey;\n  });\n\n  // Announce the number of available suggestions when it changes\n  let optionCount = getItemCount(state.collection);\n  let lastSize = useRef(optionCount);\n  let lastOpen = useRef(state.isOpen);\n  useEffect(() => {\n    // Only announce the number of options available when the menu opens if there is no\n    // focused item, otherwise screen readers will typically read e.g. \"1 of 6\".\n    // The exception is VoiceOver since this isn't included in the message above.\n    let didOpenWithoutFocusedItem =\n      state.isOpen !== lastOpen.current &&\n      (state.selectionManager.focusedKey == null || isAppleDevice());\n\n    if (state.isOpen && (didOpenWithoutFocusedItem || optionCount !== lastSize.current)) {\n      let announcement = stringFormatter.format('countAnnouncement', {optionCount});\n      announce(announcement);\n    }\n\n    lastSize.current = optionCount;\n    lastOpen.current = state.isOpen;\n  });\n\n  // Announce when a selection occurs for VoiceOver. Other screen readers typically do this automatically.\n  // TODO: do we need to do this for multi-select?\n  let lastSelectedKey = useRef(state.selectedKey);\n  useEffect(() => {\n    if (\n      isAppleDevice() &&\n      state.isFocused &&\n      state.selectedItem &&\n      state.selectedKey !== lastSelectedKey.current\n    ) {\n      let optionText = state.selectedItem['aria-label'] || state.selectedItem.textValue || '';\n      let announcement = stringFormatter.format('selectedAnnouncement', {optionText});\n      announce(announcement);\n    }\n\n    lastSelectedKey.current = state.selectedKey;\n  });\n\n  useEffect(() => {\n    if (state.isOpen) {\n      return ariaHideOutside(\n        [inputRef.current, popoverRef.current].filter(element => element != null)\n      );\n    }\n  }, [state.isOpen, inputRef, popoverRef]);\n\n  useUpdateEffect(() => {\n    // Re-show focus ring when there is no virtually focused item.\n    if (\n      !focusedItem &&\n      inputRef.current &&\n      getActiveElement(getOwnerDocument(inputRef.current)) === inputRef.current\n    ) {\n      dispatchVirtualFocus(inputRef.current, null);\n    }\n  }, [focusedItem]);\n\n  useEvent(\n    listBoxRef,\n    'react-aria-item-action',\n    state.isOpen\n      ? () => {\n          state.close();\n        }\n      : undefined\n  );\n\n  return {\n    labelProps,\n    buttonProps: {\n      ...menuTriggerProps,\n      ...triggerLabelProps,\n      excludeFromTabOrder: true,\n      preventFocusOnPress: true,\n      onPress,\n      onPressStart,\n      isDisabled: isDisabled || isReadOnly\n    },\n    inputProps: mergeProps(inputProps, {\n      role: 'combobox',\n      'aria-expanded': menuTriggerProps['aria-expanded'],\n      'aria-controls': state.isOpen ? menuProps.id : undefined,\n      // TODO: readd proper logic for completionMode = complete (aria-autocomplete: both)\n      'aria-autocomplete': 'list',\n      'aria-activedescendant': focusedItem ? getItemId(state, focusedItem.key) : undefined,\n      onTouchEnd,\n      // This disable's iOS's autocorrect suggestions, since the combo box provides its own suggestions.\n      autoCorrect: 'off',\n      // This disable's the macOS Safari spell check auto corrections.\n      spellCheck: 'false'\n    }),\n    listBoxProps: mergeProps(menuProps, listBoxProps, {\n      autoFocus: state.focusStrategy || true,\n      shouldUseVirtualFocus: true,\n      shouldSelectOnPressUp: true,\n      shouldFocusOnHover: true,\n      linkBehavior: 'selection' as const,\n      ['UNSTABLE_itemBehavior']: 'action'\n    }),\n    valueProps: {\n      id: valueId\n    },\n    descriptionProps,\n    errorMessageProps,\n    isInvalid,\n    validationErrors,\n    validationDetails\n  };\n}\n\n// This is a modified version of useSlotId that uses useEffect instead of useLayoutEffect.\n// Triggering re-renders from useLayoutEffect breaks useComboBoxState's useEffect logic in React 18.\n// These re-renders preempt async state updates in the useEffect, which ends up running multiple times\n// prior to the state being updated. This results in onSelectionChange being called multiple times.\n// TODO: refactor useComboBoxState to avoid this.\nfunction useValueId(depArray: ReadonlyArray<any> = []): string | undefined {\n  let id = useId();\n  let [exists, setExists] = useState(true);\n  let [lastDeps, setLastDeps] = useState(depArray);\n\n  // If the deps changed, set exists to true so we can test whether the element exists.\n  if (lastDeps.some((v, i) => !Object.is(v, depArray[i]))) {\n    setExists(true);\n    setLastDeps(depArray);\n  }\n\n  useEffect(() => {\n    if (exists && !document.getElementById(id)) {\n      // oxlint-disable-next-line react-hooks-js/set-state-in-effect\n      setExists(false);\n    }\n  }, [id, exists, lastDeps]);\n\n  return exists ? id : undefined;\n}\n"],"names":[],"version":3,"file":"useComboBox.mjs.map"}