@fluentui/react-combobox 9.0.0 → 9.1.1

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.
Files changed (32) hide show
  1. package/CHANGELOG.json +72 -6
  2. package/CHANGELOG.md +31 -7
  3. package/dist/index.d.ts +8 -1
  4. package/lib/components/Combobox/useCombobox.js +2 -2
  5. package/lib/components/Combobox/useCombobox.js.map +1 -1
  6. package/lib/components/Dropdown/useDropdown.js +2 -2
  7. package/lib/components/Dropdown/useDropdown.js.map +1 -1
  8. package/lib/utils/OptionCollection.types.js.map +1 -1
  9. package/lib/utils/Selection.types.js.map +1 -1
  10. package/lib/utils/useComboboxBaseState.js +12 -5
  11. package/lib/utils/useComboboxBaseState.js.map +1 -1
  12. package/lib/utils/useOptionCollection.js +5 -1
  13. package/lib/utils/useOptionCollection.js.map +1 -1
  14. package/lib-amd/components/Combobox/useCombobox.js +2 -4
  15. package/lib-amd/components/Combobox/useCombobox.js.map +1 -1
  16. package/lib-amd/components/Dropdown/useDropdown.js +2 -2
  17. package/lib-amd/components/Dropdown/useDropdown.js.map +1 -1
  18. package/lib-amd/utils/OptionCollection.types.js.map +1 -1
  19. package/lib-amd/utils/Selection.types.js.map +1 -1
  20. package/lib-amd/utils/useComboboxBaseState.js +12 -5
  21. package/lib-amd/utils/useComboboxBaseState.js.map +1 -1
  22. package/lib-amd/utils/useOptionCollection.js +4 -0
  23. package/lib-amd/utils/useOptionCollection.js.map +1 -1
  24. package/lib-commonjs/components/Combobox/useCombobox.js +2 -2
  25. package/lib-commonjs/components/Combobox/useCombobox.js.map +1 -1
  26. package/lib-commonjs/components/Dropdown/useDropdown.js +2 -2
  27. package/lib-commonjs/components/Dropdown/useDropdown.js.map +1 -1
  28. package/lib-commonjs/utils/useComboboxBaseState.js +12 -5
  29. package/lib-commonjs/utils/useComboboxBaseState.js.map +1 -1
  30. package/lib-commonjs/utils/useOptionCollection.js +5 -1
  31. package/lib-commonjs/utils/useOptionCollection.js.map +1 -1
  32. package/package.json +6 -6
@@ -1 +1 @@
1
- {"version":3,"file":"useCombobox.js","sourceRoot":"","sources":["../../../../../../../../../packages/react-components/react-combobox/src/components/Combobox/useCombobox.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { ArrowLeft, ArrowRight } from '@fluentui/keyboard-keys';\nimport { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';\nimport {\n getPartitionedNativeProps,\n resolveShorthand,\n mergeCallbacks,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from '../../utils/dropdownKeyActions';\nimport { useComboboxBaseState } from '../../utils/useComboboxBaseState';\nimport { useComboboxPopup } from '../../utils/useComboboxPopup';\nimport { useTriggerListboxSlots } from '../../utils/useTriggerListboxSlots';\nimport { Listbox } from '../Listbox/Listbox';\nimport type { Slot } from '@fluentui/react-utilities';\nimport type { SelectionEvents } from '../../utils/Selection.types';\nimport type { OptionValue } from '../../utils/OptionCollection.types';\nimport type { ComboboxProps, ComboboxState } from './Combobox.types';\n\n/**\n * Create the state required to render Combobox.\n *\n * The returned state can be modified with hooks such as useComboboxStyles_unstable,\n * before being passed to renderCombobox_unstable.\n *\n * @param props - props from this instance of Combobox\n * @param ref - reference to root HTMLElement of Combobox\n */\nexport const useCombobox_unstable = (props: ComboboxProps, ref: React.Ref<HTMLInputElement>): ComboboxState => {\n const baseState = useComboboxBaseState({ ...props, editable: true });\n const {\n activeOption,\n clearSelection,\n getIndexOfId,\n getOptionsMatchingText,\n hasFocus,\n open,\n selectOption,\n selectedOptions,\n setActiveOption,\n setFocusVisible,\n setOpen,\n setValue,\n value,\n } = baseState;\n const { disabled, freeform, inlinePopup, multiselect } = props;\n const comboId = useId('combobox-');\n\n const { primary: triggerNativeProps, root: rootNativeProps } = getPartitionedNativeProps({\n props,\n primarySlotTagName: 'input',\n excludedPropNames: ['children', 'size'],\n });\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n const triggerRef = React.useRef<HTMLInputElement>(null);\n\n // NVDA and JAWS have bugs that suppress reading the input value text when aria-activedescendant is set\n // To prevent this, we clear the HTML attribute (but save the state) when a user presses left/right arrows\n // ref: https://github.com/microsoft/fluentui/issues/26359#issuecomment-1397759888\n const [hideActiveDescendant, setHideActiveDescendant] = React.useState(false);\n\n // calculate listbox width style based on trigger width\n const [popupDimensions, setPopupDimensions] = React.useState<{ width: string }>();\n React.useEffect(() => {\n // only recalculate width when opening\n if (open) {\n const width = `${rootRef.current?.clientWidth}px`;\n if (width !== popupDimensions?.width) {\n setPopupDimensions({ width });\n }\n }\n }, [open, popupDimensions]);\n\n // set active option and selection based on typing\n const getOptionFromInput = (inputValue: string): OptionValue | undefined => {\n const searchString = inputValue?.trim().toLowerCase();\n\n if (!searchString || searchString.length === 0) {\n return;\n }\n\n const matcher = (optionText: string) => optionText.toLowerCase().indexOf(searchString) === 0;\n const matches = getOptionsMatchingText(matcher);\n\n // return first matching option after the current active option, looping back to the top\n if (matches.length > 1 && activeOption) {\n const startIndex = getIndexOfId(activeOption.id);\n const nextMatch = matches.find(option => getIndexOfId(option.id) >= startIndex);\n return nextMatch ?? matches[0];\n }\n\n return matches[0] ?? undefined;\n };\n\n /* Handle typed input */\n\n // reset any typed value when an option is selected\n baseState.selectOption = (ev: SelectionEvents, option: OptionValue) => {\n setValue(undefined);\n selectOption(ev, option);\n };\n\n const onTriggerBlur = (ev: React.FocusEvent<HTMLInputElement>) => {\n // handle selection and updating value if freeform is false\n if (!baseState.open && !freeform) {\n // select matching option, if the value fully matches\n if (value && activeOption && value.trim().toLowerCase() === activeOption?.value.toLowerCase()) {\n baseState.selectOption(ev, activeOption);\n }\n\n // reset typed value when the input loses focus while collapsed, unless freeform is true\n setValue(undefined);\n }\n };\n\n baseState.setOpen = (ev, newState: boolean) => {\n if (disabled) {\n return;\n }\n\n if (!newState && !freeform) {\n setValue(undefined);\n }\n\n setOpen(ev, newState);\n };\n\n // update value and active option based on input\n const onTriggerChange = (ev: React.ChangeEvent<HTMLInputElement>) => {\n const inputValue = ev.target.value;\n // update uncontrolled value\n baseState.setValue(inputValue);\n\n // handle updating active option based on input\n const matchingOption = getOptionFromInput(inputValue);\n setActiveOption(matchingOption);\n\n setFocusVisible(true);\n\n // clear selection for single-select if the input value no longer matches the selection\n if (\n !multiselect &&\n selectedOptions.length === 1 &&\n (inputValue.length < 1 || selectedOptions[0].indexOf(inputValue) !== 0)\n ) {\n clearSelection(ev);\n }\n };\n\n // open Combobox when typing\n const onTriggerKeyDown = (ev: React.KeyboardEvent<HTMLInputElement>) => {\n if (!open && getDropdownActionFromKey(ev) === 'Type') {\n baseState.setOpen(ev, true);\n }\n\n // clear activedescendant when moving the text insertion cursor\n if (ev.key === ArrowLeft || ev.key === ArrowRight) {\n setHideActiveDescendant(true);\n } else {\n setHideActiveDescendant(false);\n }\n };\n\n // resolve input and listbox slot props\n let triggerSlot: Slot<'input'>;\n let listboxSlot: Slot<typeof Listbox> | undefined;\n\n triggerSlot = resolveShorthand(props.input, {\n required: true,\n defaultProps: {\n ref: useMergedRefs(props.input?.ref, triggerRef),\n type: 'text',\n value: value ?? '',\n ...triggerNativeProps,\n },\n });\n\n triggerSlot.onChange = mergeCallbacks(triggerSlot.onChange, onTriggerChange);\n triggerSlot.onBlur = mergeCallbacks(triggerSlot.onBlur, onTriggerBlur);\n triggerSlot.onKeyDown = mergeCallbacks(triggerSlot.onKeyDown, onTriggerKeyDown);\n\n // only resolve listbox slot if needed\n listboxSlot =\n open || hasFocus\n ? resolveShorthand(props.listbox, {\n required: true,\n defaultProps: {\n children: props.children,\n style: popupDimensions,\n },\n })\n : undefined;\n\n [triggerSlot, listboxSlot] = useComboboxPopup(props, triggerSlot, listboxSlot);\n [triggerSlot, listboxSlot] = useTriggerListboxSlots(props, baseState, ref, triggerSlot, listboxSlot);\n\n if (hideActiveDescendant) {\n triggerSlot['aria-activedescendant'] = undefined;\n }\n\n const state: ComboboxState = {\n components: {\n root: 'div',\n input: 'input',\n expandIcon: 'span',\n listbox: Listbox,\n },\n root: resolveShorthand(props.root, {\n required: true,\n defaultProps: {\n 'aria-owns': !inlinePopup ? listboxSlot?.id : undefined,\n ...rootNativeProps,\n },\n }),\n input: triggerSlot,\n listbox: listboxSlot,\n expandIcon: resolveShorthand(props.expandIcon, {\n required: true,\n defaultProps: {\n 'aria-expanded': open,\n children: <ChevronDownIcon />,\n role: 'button',\n },\n }),\n ...baseState,\n };\n\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n /* handle open/close + focus change when clicking expandIcon */\n const { onMouseDown: onIconMouseDown, onClick: onIconClick } = state.expandIcon || {};\n const onExpandIconMouseDown = useEventCallback(\n mergeCallbacks(onIconMouseDown, () => {\n // do not dismiss on blur when closing via clicking the icon\n if (open) {\n baseState.ignoreNextBlur.current = true;\n }\n }),\n );\n\n const onExpandIconClick = useEventCallback(\n mergeCallbacks(onIconClick, (event: React.MouseEvent<HTMLSpanElement>) => {\n // open and set focus\n state.setOpen(event, !state.open);\n triggerRef.current?.focus();\n\n // set focus visible=false, since this can only be done with the mouse/pointer\n setFocusVisible(false);\n }),\n );\n\n if (state.expandIcon) {\n state.expandIcon.onMouseDown = onExpandIconMouseDown;\n state.expandIcon.onClick = onExpandIconClick;\n\n // If there is no explicit aria-label, calculate default accName attribute for expandIcon button,\n // using the following steps:\n // 1. If there is an aria-label, it is \"Open [aria-label]\"\n // 2. If there is an aria-labelledby, it is \"Open [aria-labelledby target]\" (using aria-labelledby + ids)\n // 3. If there is no aria-label/ledby attr, it falls back to \"Open\"\n // We can't fall back to a label/htmlFor name because of https://github.com/w3c/accname/issues/179\n const hasExpandLabel = state.expandIcon['aria-label'] || state.expandIcon['aria-labelledby'];\n const defaultOpenString = 'Open'; // this is english-only since it is the fallback\n if (!hasExpandLabel) {\n if (props['aria-labelledby']) {\n const chevronId = state.expandIcon.id ?? `${comboId}-chevron`;\n const chevronLabelledBy = `${chevronId} ${state.input['aria-labelledby']}`;\n\n state.expandIcon['aria-label'] = defaultOpenString;\n state.expandIcon.id = chevronId;\n state.expandIcon['aria-labelledby'] = chevronLabelledBy;\n } else if (props['aria-label']) {\n state.expandIcon['aria-label'] = `${defaultOpenString} ${props['aria-label']}`;\n } else {\n state.expandIcon['aria-label'] = defaultOpenString;\n }\n }\n }\n\n return state;\n};\n"]}
1
+ {"version":3,"file":"useCombobox.js","sourceRoot":"","sources":["../../../../../../../../../packages/react-components/react-combobox/src/components/Combobox/useCombobox.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { ArrowLeft, ArrowRight } from '@fluentui/keyboard-keys';\nimport { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';\nimport {\n getPartitionedNativeProps,\n resolveShorthand,\n mergeCallbacks,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from '../../utils/dropdownKeyActions';\nimport { useComboboxBaseState } from '../../utils/useComboboxBaseState';\nimport { useComboboxPopup } from '../../utils/useComboboxPopup';\nimport { useTriggerListboxSlots } from '../../utils/useTriggerListboxSlots';\nimport { Listbox } from '../Listbox/Listbox';\nimport type { Slot } from '@fluentui/react-utilities';\nimport type { SelectionEvents } from '../../utils/Selection.types';\nimport type { OptionValue } from '../../utils/OptionCollection.types';\nimport type { ComboboxProps, ComboboxState } from './Combobox.types';\n\n/**\n * Create the state required to render Combobox.\n *\n * The returned state can be modified with hooks such as useComboboxStyles_unstable,\n * before being passed to renderCombobox_unstable.\n *\n * @param props - props from this instance of Combobox\n * @param ref - reference to root HTMLElement of Combobox\n */\nexport const useCombobox_unstable = (props: ComboboxProps, ref: React.Ref<HTMLInputElement>): ComboboxState => {\n const baseState = useComboboxBaseState({ ...props, editable: true });\n const {\n activeOption,\n clearSelection,\n getIndexOfId,\n getOptionsMatchingText,\n hasFocus,\n open,\n selectOption,\n selectedOptions,\n setActiveOption,\n setFocusVisible,\n setOpen,\n setValue,\n value,\n } = baseState;\n const { disabled, freeform, inlinePopup, multiselect } = props;\n const comboId = useId('combobox-');\n\n const { primary: triggerNativeProps, root: rootNativeProps } = getPartitionedNativeProps({\n props,\n primarySlotTagName: 'input',\n excludedPropNames: ['children', 'size'],\n });\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n const triggerRef = React.useRef<HTMLInputElement>(null);\n\n // NVDA and JAWS have bugs that suppress reading the input value text when aria-activedescendant is set\n // To prevent this, we clear the HTML attribute (but save the state) when a user presses left/right arrows\n // ref: https://github.com/microsoft/fluentui/issues/26359#issuecomment-1397759888\n const [hideActiveDescendant, setHideActiveDescendant] = React.useState(false);\n\n // calculate listbox width style based on trigger width\n const [popupDimensions, setPopupDimensions] = React.useState<{ width: string }>();\n React.useEffect(() => {\n // only recalculate width when opening\n if (open) {\n const width = `${rootRef.current?.clientWidth}px`;\n if (width !== popupDimensions?.width) {\n setPopupDimensions({ width });\n }\n }\n }, [open, popupDimensions]);\n\n // set active option and selection based on typing\n const getOptionFromInput = (inputValue: string): OptionValue | undefined => {\n const searchString = inputValue?.trim().toLowerCase();\n\n if (!searchString || searchString.length === 0) {\n return;\n }\n\n const matcher = (optionText: string) => optionText.toLowerCase().indexOf(searchString) === 0;\n const matches = getOptionsMatchingText(matcher);\n\n // return first matching option after the current active option, looping back to the top\n if (matches.length > 1 && activeOption) {\n const startIndex = getIndexOfId(activeOption.id);\n const nextMatch = matches.find(option => getIndexOfId(option.id) >= startIndex);\n return nextMatch ?? matches[0];\n }\n\n return matches[0] ?? undefined;\n };\n\n /* Handle typed input */\n\n // reset any typed value when an option is selected\n baseState.selectOption = (ev: SelectionEvents, option: OptionValue) => {\n setValue(undefined);\n selectOption(ev, option);\n };\n\n const onTriggerBlur = (ev: React.FocusEvent<HTMLInputElement>) => {\n // handle selection and updating value if freeform is false\n if (!baseState.open && !freeform) {\n // select matching option, if the value fully matches\n if (value && activeOption && value.trim().toLowerCase() === activeOption?.text.toLowerCase()) {\n baseState.selectOption(ev, activeOption);\n }\n\n // reset typed value when the input loses focus while collapsed, unless freeform is true\n setValue(undefined);\n }\n };\n\n baseState.setOpen = (ev, newState: boolean) => {\n if (disabled) {\n return;\n }\n\n if (!newState && !freeform) {\n setValue(undefined);\n }\n\n setOpen(ev, newState);\n };\n\n // update value and active option based on input\n const onTriggerChange = (ev: React.ChangeEvent<HTMLInputElement>) => {\n const inputValue = ev.target.value;\n // update uncontrolled value\n baseState.setValue(inputValue);\n\n // handle updating active option based on input\n const matchingOption = getOptionFromInput(inputValue);\n setActiveOption(matchingOption);\n\n setFocusVisible(true);\n\n // clear selection for single-select if the input value no longer matches the selection\n if (!multiselect && selectedOptions.length === 1 && (inputValue.length < 1 || !matchingOption)) {\n clearSelection(ev);\n }\n };\n\n // open Combobox when typing\n const onTriggerKeyDown = (ev: React.KeyboardEvent<HTMLInputElement>) => {\n if (!open && getDropdownActionFromKey(ev) === 'Type') {\n baseState.setOpen(ev, true);\n }\n\n // clear activedescendant when moving the text insertion cursor\n if (ev.key === ArrowLeft || ev.key === ArrowRight) {\n setHideActiveDescendant(true);\n } else {\n setHideActiveDescendant(false);\n }\n };\n\n // resolve input and listbox slot props\n let triggerSlot: Slot<'input'>;\n let listboxSlot: Slot<typeof Listbox> | undefined;\n\n triggerSlot = resolveShorthand(props.input, {\n required: true,\n defaultProps: {\n ref: useMergedRefs(props.input?.ref, triggerRef),\n type: 'text',\n value: value ?? '',\n ...triggerNativeProps,\n },\n });\n\n triggerSlot.onChange = mergeCallbacks(triggerSlot.onChange, onTriggerChange);\n triggerSlot.onBlur = mergeCallbacks(triggerSlot.onBlur, onTriggerBlur);\n triggerSlot.onKeyDown = mergeCallbacks(triggerSlot.onKeyDown, onTriggerKeyDown);\n\n // only resolve listbox slot if needed\n listboxSlot =\n open || hasFocus\n ? resolveShorthand(props.listbox, {\n required: true,\n defaultProps: {\n children: props.children,\n style: popupDimensions,\n },\n })\n : undefined;\n\n [triggerSlot, listboxSlot] = useComboboxPopup(props, triggerSlot, listboxSlot);\n [triggerSlot, listboxSlot] = useTriggerListboxSlots(props, baseState, ref, triggerSlot, listboxSlot);\n\n if (hideActiveDescendant) {\n triggerSlot['aria-activedescendant'] = undefined;\n }\n\n const state: ComboboxState = {\n components: {\n root: 'div',\n input: 'input',\n expandIcon: 'span',\n listbox: Listbox,\n },\n root: resolveShorthand(props.root, {\n required: true,\n defaultProps: {\n 'aria-owns': !inlinePopup ? listboxSlot?.id : undefined,\n ...rootNativeProps,\n },\n }),\n input: triggerSlot,\n listbox: listboxSlot,\n expandIcon: resolveShorthand(props.expandIcon, {\n required: true,\n defaultProps: {\n 'aria-expanded': open,\n children: <ChevronDownIcon />,\n role: 'button',\n },\n }),\n ...baseState,\n };\n\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n /* handle open/close + focus change when clicking expandIcon */\n const { onMouseDown: onIconMouseDown, onClick: onIconClick } = state.expandIcon || {};\n const onExpandIconMouseDown = useEventCallback(\n mergeCallbacks(onIconMouseDown, () => {\n // do not dismiss on blur when closing via clicking the icon\n if (open) {\n baseState.ignoreNextBlur.current = true;\n }\n }),\n );\n\n const onExpandIconClick = useEventCallback(\n mergeCallbacks(onIconClick, (event: React.MouseEvent<HTMLSpanElement>) => {\n // open and set focus\n state.setOpen(event, !state.open);\n triggerRef.current?.focus();\n\n // set focus visible=false, since this can only be done with the mouse/pointer\n setFocusVisible(false);\n }),\n );\n\n if (state.expandIcon) {\n state.expandIcon.onMouseDown = onExpandIconMouseDown;\n state.expandIcon.onClick = onExpandIconClick;\n\n // If there is no explicit aria-label, calculate default accName attribute for expandIcon button,\n // using the following steps:\n // 1. If there is an aria-label, it is \"Open [aria-label]\"\n // 2. If there is an aria-labelledby, it is \"Open [aria-labelledby target]\" (using aria-labelledby + ids)\n // 3. If there is no aria-label/ledby attr, it falls back to \"Open\"\n // We can't fall back to a label/htmlFor name because of https://github.com/w3c/accname/issues/179\n const hasExpandLabel = state.expandIcon['aria-label'] || state.expandIcon['aria-labelledby'];\n const defaultOpenString = 'Open'; // this is english-only since it is the fallback\n if (!hasExpandLabel) {\n if (props['aria-labelledby']) {\n const chevronId = state.expandIcon.id ?? `${comboId}-chevron`;\n const chevronLabelledBy = `${chevronId} ${state.input['aria-labelledby']}`;\n\n state.expandIcon['aria-label'] = defaultOpenString;\n state.expandIcon.id = chevronId;\n state.expandIcon['aria-labelledby'] = chevronLabelledBy;\n } else if (props['aria-label']) {\n state.expandIcon['aria-label'] = `${defaultOpenString} ${props['aria-label']}`;\n } else {\n state.expandIcon['aria-label'] = defaultOpenString;\n }\n }\n }\n\n return state;\n};\n"]}
@@ -34,7 +34,7 @@ define(["require", "exports", "tslib", "react", "@fluentui/react-icons", "@fluen
34
34
  var getNextMatchingOption = function () {
35
35
  var _a;
36
36
  // first check for matches for the full searchString
37
- var matcher = function (optionValue) { return optionValue.toLowerCase().indexOf(searchString.current) === 0; };
37
+ var matcher = function (optionText) { return optionText.toLowerCase().indexOf(searchString.current) === 0; };
38
38
  var matches = getOptionsMatchingText(matcher);
39
39
  var startIndex = activeOption ? getIndexOfId(activeOption.id) : 0;
40
40
  // if the dropdown is already open and the searchstring is a single character,
@@ -50,7 +50,7 @@ define(["require", "exports", "tslib", "react", "@fluentui/react-icons", "@fluen
50
50
  // if the search is all the same letter, cycle through options starting with that letter
51
51
  if (allSameLetter) {
52
52
  startIndex++;
53
- matcher = function (optionValue) { return optionValue.toLowerCase().indexOf(letters_1[0]) === 0; };
53
+ matcher = function (optionText) { return optionText.toLowerCase().indexOf(letters_1[0]) === 0; };
54
54
  matches = getOptionsMatchingText(matcher);
55
55
  }
56
56
  }
@@ -1 +1 @@
1
- {"version":3,"file":"useDropdown.js","sourceRoot":"","sources":["../../../../../../../../../packages/react-components/react-combobox/src/components/Dropdown/useDropdown.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';\nimport { getPartitionedNativeProps, mergeCallbacks, resolveShorthand, useTimeout } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from '../../utils/dropdownKeyActions';\nimport { useComboboxBaseState } from '../../utils/useComboboxBaseState';\nimport { useComboboxPopup } from '../../utils/useComboboxPopup';\nimport { useTriggerListboxSlots } from '../../utils/useTriggerListboxSlots';\nimport { Listbox } from '../Listbox/Listbox';\nimport type { Slot } from '@fluentui/react-utilities';\nimport type { OptionValue } from '../../utils/OptionCollection.types';\nimport type { DropdownProps, DropdownState } from './Dropdown.types';\nimport { useMergedRefs } from '@fluentui/react-utilities';\n\n/**\n * Create the state required to render Dropdown.\n *\n * The returned state can be modified with hooks such as useDropdownStyles_unstable,\n * before being passed to renderDropdown_unstable.\n *\n * @param props - props from this instance of Dropdown\n * @param ref - reference to root HTMLElement of Dropdown\n */\nexport const useDropdown_unstable = (props: DropdownProps, ref: React.Ref<HTMLButtonElement>): DropdownState => {\n const baseState = useComboboxBaseState(props);\n const {\n activeOption,\n getIndexOfId,\n getOptionsMatchingText,\n open,\n setActiveOption,\n setFocusVisible,\n setOpen,\n } = baseState;\n\n const { primary: triggerNativeProps, root: rootNativeProps } = getPartitionedNativeProps({\n props,\n primarySlotTagName: 'button',\n excludedPropNames: ['children'],\n });\n\n // set listbox popup width based off the root/trigger width\n const rootRef = React.useRef<HTMLDivElement>(null);\n const [popupWidth, setPopupWidth] = React.useState<string>();\n React.useEffect(() => {\n const width = open ? `${rootRef.current?.clientWidth}px` : undefined;\n setPopupWidth(width);\n }, [open]);\n\n // jump to matching option based on typing\n const searchString = React.useRef('');\n const [setKeyTimeout, clearKeyTimeout] = useTimeout();\n\n const getNextMatchingOption = (): OptionValue | undefined => {\n // first check for matches for the full searchString\n let matcher = (optionValue: string) => optionValue.toLowerCase().indexOf(searchString.current) === 0;\n let matches = getOptionsMatchingText(matcher);\n let startIndex = activeOption ? getIndexOfId(activeOption.id) : 0;\n\n // if the dropdown is already open and the searchstring is a single character,\n // then look after the current activeOption for letters\n // this is so slowly typing the same letter will cycle through matches\n if (open && searchString.current.length === 1) {\n startIndex++;\n }\n\n // if there are no direct matches, check if the search is all the same letter, e.g. \"aaa\"\n if (!matches.length) {\n const letters = searchString.current.split('');\n const allSameLetter = letters.length && letters.every(letter => letter === letters[0]);\n\n // if the search is all the same letter, cycle through options starting with that letter\n if (allSameLetter) {\n startIndex++;\n matcher = (optionValue: string) => optionValue.toLowerCase().indexOf(letters[0]) === 0;\n matches = getOptionsMatchingText(matcher);\n }\n }\n\n // if there is an active option and multiple matches,\n // return first matching option after the current active option, looping back to the top\n if (matches.length > 1 && activeOption) {\n const nextMatch = matches.find(option => getIndexOfId(option.id) >= startIndex);\n return nextMatch ?? matches[0];\n }\n\n return matches[0] ?? undefined;\n };\n\n const onTriggerKeyDown = (ev: React.KeyboardEvent<HTMLButtonElement>) => {\n // clear timeout, if it exists\n clearKeyTimeout();\n\n // if the key was a char key, update search string\n if (getDropdownActionFromKey(ev) === 'Type') {\n // update search string\n searchString.current += ev.key.toLowerCase();\n setKeyTimeout(() => {\n searchString.current = '';\n }, 500);\n\n // update state\n !open && setOpen(ev, true);\n\n const nextOption = getNextMatchingOption();\n setActiveOption(nextOption);\n setFocusVisible(true);\n }\n };\n\n // resolve button and listbox slot props\n let triggerSlot: Slot<'button'>;\n let listboxSlot: Slot<typeof Listbox> | undefined;\n\n triggerSlot = resolveShorthand(props.button, {\n required: true,\n defaultProps: {\n type: 'button',\n children: baseState.value || props.placeholder,\n ...triggerNativeProps,\n },\n });\n\n triggerSlot.onKeyDown = mergeCallbacks(onTriggerKeyDown, triggerSlot.onKeyDown);\n\n listboxSlot =\n baseState.open || baseState.hasFocus\n ? resolveShorthand(props.listbox, {\n required: true,\n defaultProps: {\n children: props.children,\n style: { width: popupWidth },\n },\n })\n : undefined;\n\n [triggerSlot, listboxSlot] = useComboboxPopup(props, triggerSlot, listboxSlot);\n [triggerSlot, listboxSlot] = useTriggerListboxSlots(props, baseState, ref, triggerSlot, listboxSlot);\n\n const state: DropdownState = {\n components: {\n root: 'div',\n button: 'button',\n expandIcon: 'span',\n listbox: Listbox,\n },\n root: resolveShorthand(props.root, {\n required: true,\n defaultProps: {\n 'aria-owns': !props.inlinePopup ? listboxSlot?.id : undefined,\n children: props.children,\n ...rootNativeProps,\n },\n }),\n button: triggerSlot,\n listbox: listboxSlot,\n expandIcon: resolveShorthand(props.expandIcon, {\n required: true,\n defaultProps: {\n children: <ChevronDownIcon />,\n },\n }),\n placeholderVisible: !baseState.value && !!props.placeholder,\n ...baseState,\n };\n\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n return state;\n};\n"]}
1
+ {"version":3,"file":"useDropdown.js","sourceRoot":"","sources":["../../../../../../../../../packages/react-components/react-combobox/src/components/Dropdown/useDropdown.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';\nimport { getPartitionedNativeProps, mergeCallbacks, resolveShorthand, useTimeout } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from '../../utils/dropdownKeyActions';\nimport { useComboboxBaseState } from '../../utils/useComboboxBaseState';\nimport { useComboboxPopup } from '../../utils/useComboboxPopup';\nimport { useTriggerListboxSlots } from '../../utils/useTriggerListboxSlots';\nimport { Listbox } from '../Listbox/Listbox';\nimport type { Slot } from '@fluentui/react-utilities';\nimport type { OptionValue } from '../../utils/OptionCollection.types';\nimport type { DropdownProps, DropdownState } from './Dropdown.types';\nimport { useMergedRefs } from '@fluentui/react-utilities';\n\n/**\n * Create the state required to render Dropdown.\n *\n * The returned state can be modified with hooks such as useDropdownStyles_unstable,\n * before being passed to renderDropdown_unstable.\n *\n * @param props - props from this instance of Dropdown\n * @param ref - reference to root HTMLElement of Dropdown\n */\nexport const useDropdown_unstable = (props: DropdownProps, ref: React.Ref<HTMLButtonElement>): DropdownState => {\n const baseState = useComboboxBaseState(props);\n const {\n activeOption,\n getIndexOfId,\n getOptionsMatchingText,\n open,\n setActiveOption,\n setFocusVisible,\n setOpen,\n } = baseState;\n\n const { primary: triggerNativeProps, root: rootNativeProps } = getPartitionedNativeProps({\n props,\n primarySlotTagName: 'button',\n excludedPropNames: ['children'],\n });\n\n // set listbox popup width based off the root/trigger width\n const rootRef = React.useRef<HTMLDivElement>(null);\n const [popupWidth, setPopupWidth] = React.useState<string>();\n React.useEffect(() => {\n const width = open ? `${rootRef.current?.clientWidth}px` : undefined;\n setPopupWidth(width);\n }, [open]);\n\n // jump to matching option based on typing\n const searchString = React.useRef('');\n const [setKeyTimeout, clearKeyTimeout] = useTimeout();\n\n const getNextMatchingOption = (): OptionValue | undefined => {\n // first check for matches for the full searchString\n let matcher = (optionText: string) => optionText.toLowerCase().indexOf(searchString.current) === 0;\n let matches = getOptionsMatchingText(matcher);\n let startIndex = activeOption ? getIndexOfId(activeOption.id) : 0;\n\n // if the dropdown is already open and the searchstring is a single character,\n // then look after the current activeOption for letters\n // this is so slowly typing the same letter will cycle through matches\n if (open && searchString.current.length === 1) {\n startIndex++;\n }\n\n // if there are no direct matches, check if the search is all the same letter, e.g. \"aaa\"\n if (!matches.length) {\n const letters = searchString.current.split('');\n const allSameLetter = letters.length && letters.every(letter => letter === letters[0]);\n\n // if the search is all the same letter, cycle through options starting with that letter\n if (allSameLetter) {\n startIndex++;\n matcher = (optionText: string) => optionText.toLowerCase().indexOf(letters[0]) === 0;\n matches = getOptionsMatchingText(matcher);\n }\n }\n\n // if there is an active option and multiple matches,\n // return first matching option after the current active option, looping back to the top\n if (matches.length > 1 && activeOption) {\n const nextMatch = matches.find(option => getIndexOfId(option.id) >= startIndex);\n return nextMatch ?? matches[0];\n }\n\n return matches[0] ?? undefined;\n };\n\n const onTriggerKeyDown = (ev: React.KeyboardEvent<HTMLButtonElement>) => {\n // clear timeout, if it exists\n clearKeyTimeout();\n\n // if the key was a char key, update search string\n if (getDropdownActionFromKey(ev) === 'Type') {\n // update search string\n searchString.current += ev.key.toLowerCase();\n setKeyTimeout(() => {\n searchString.current = '';\n }, 500);\n\n // update state\n !open && setOpen(ev, true);\n\n const nextOption = getNextMatchingOption();\n setActiveOption(nextOption);\n setFocusVisible(true);\n }\n };\n\n // resolve button and listbox slot props\n let triggerSlot: Slot<'button'>;\n let listboxSlot: Slot<typeof Listbox> | undefined;\n\n triggerSlot = resolveShorthand(props.button, {\n required: true,\n defaultProps: {\n type: 'button',\n children: baseState.value || props.placeholder,\n ...triggerNativeProps,\n },\n });\n\n triggerSlot.onKeyDown = mergeCallbacks(onTriggerKeyDown, triggerSlot.onKeyDown);\n\n listboxSlot =\n baseState.open || baseState.hasFocus\n ? resolveShorthand(props.listbox, {\n required: true,\n defaultProps: {\n children: props.children,\n style: { width: popupWidth },\n },\n })\n : undefined;\n\n [triggerSlot, listboxSlot] = useComboboxPopup(props, triggerSlot, listboxSlot);\n [triggerSlot, listboxSlot] = useTriggerListboxSlots(props, baseState, ref, triggerSlot, listboxSlot);\n\n const state: DropdownState = {\n components: {\n root: 'div',\n button: 'button',\n expandIcon: 'span',\n listbox: Listbox,\n },\n root: resolveShorthand(props.root, {\n required: true,\n defaultProps: {\n 'aria-owns': !props.inlinePopup ? listboxSlot?.id : undefined,\n children: props.children,\n ...rootNativeProps,\n },\n }),\n button: triggerSlot,\n listbox: listboxSlot,\n expandIcon: resolveShorthand(props.expandIcon, {\n required: true,\n defaultProps: {\n children: <ChevronDownIcon />,\n },\n }),\n placeholderVisible: !baseState.value && !!props.placeholder,\n ...baseState,\n };\n\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n return state;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"OptionCollection.types.js","sourceRoot":"","sources":["../../../../../../../../packages/react-components/react-combobox/src/utils/OptionCollection.types.ts"],"names":[],"mappings":"","sourcesContent":["export type OptionValue = {\n /** The disabled state of the option. */\n disabled?: boolean;\n\n /** The `id` attribute of the option. */\n id: string;\n\n /** The `text` string for the option. */\n text: string;\n\n /** The value string of the option. */\n value: string;\n};\n\nexport type OptionCollectionState = {\n /** The total number of options in the collection. */\n getCount: () => number;\n\n /** Returns the index of an option by key. */\n getIndexOfId(id: string): number;\n\n /** Returns the option data for the nth option. */\n getOptionAtIndex(index: number): OptionValue | undefined;\n\n /** Returns the option data by key. */\n getOptionById(id: string): OptionValue | undefined;\n\n /** Returns an array of options filtered by a value matching function against the option's text string. */\n getOptionsMatchingText(matcher: (value: string) => boolean): OptionValue[];\n\n /** The unordered option data. */\n options: OptionValue[];\n\n /* A function that child options call to register their values. Returns a function to unregister the option. */\n registerOption: (option: OptionValue, element: HTMLElement) => () => void;\n};\n"]}
1
+ {"version":3,"file":"OptionCollection.types.js","sourceRoot":"","sources":["../../../../../../../../packages/react-components/react-combobox/src/utils/OptionCollection.types.ts"],"names":[],"mappings":"","sourcesContent":["export type OptionValue = {\n /** The disabled state of the option. */\n disabled?: boolean;\n\n /** The `id` attribute of the option. */\n id: string;\n\n /** The `text` string for the option. */\n text: string;\n\n /** The value string of the option. */\n value: string;\n};\n\nexport type OptionCollectionState = {\n /** The total number of options in the collection. */\n getCount: () => number;\n\n /** Returns the index of an option by key. */\n getIndexOfId(id: string): number;\n\n /** Returns the option data for the nth option. */\n getOptionAtIndex(index: number): OptionValue | undefined;\n\n /** Returns the option data by key. */\n getOptionById(id: string): OptionValue | undefined;\n\n /** Returns an array of options filtered by a value matching function against the option's text string. */\n getOptionsMatchingText(matcher: (text: string) => boolean): OptionValue[];\n\n /** Returns an array of options filtered by a value matching function against the option's value string. */\n getOptionsMatchingValue(matcher: (value: string) => boolean): OptionValue[];\n\n /** The unordered option data. */\n options: OptionValue[];\n\n /* A function that child options call to register their values. Returns a function to unregister the option. */\n registerOption: (option: OptionValue, element: HTMLElement) => () => void;\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"Selection.types.js","sourceRoot":"","sources":["../../../../../../../../packages/react-components/react-combobox/src/utils/Selection.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { OptionValue } from './OptionCollection.types';\n\nexport type SelectionProps = {\n /* For an uncontrolled component, sets the initial selection */\n defaultSelectedOptions?: string[];\n\n /**\n * Sets the selection type to multiselect.\n * Set this to true for multiselect, even if fully controlling selection state.\n * This enables styles and accessibility properties to be set.\n * @default false\n */\n multiselect?: boolean;\n\n /* Callback when an option is selected */\n onOptionSelect?: (event: SelectionEvents, data: OptionOnSelectData) => void;\n\n /**\n * An array of selected option keys.\n * Use this with `onOptionSelect` to directly control the selected option(s)\n */\n selectedOptions?: string[];\n};\n\n/* Values returned by the useSelection hook */\nexport type SelectionState = {\n clearSelection: (event: SelectionEvents) => void;\n selectedOptions: string[];\n selectOption: (event: SelectionEvents, option: OptionValue) => void;\n};\n\n/*\n * Data for the onOptionSelect callback.\n * `optionValue` and `optionText` will be undefined if multiple options are modified at once.\n */\nexport type OptionOnSelectData = {\n optionValue: string | undefined;\n optionText: string | undefined;\n selectedOptions: string[];\n};\n\n/* Possible event types for onOptionSelect */\nexport type SelectionEvents =\n | React.ChangeEvent<HTMLElement>\n | React.KeyboardEvent<HTMLElement>\n | React.MouseEvent<HTMLElement>;\n"]}
1
+ {"version":3,"file":"Selection.types.js","sourceRoot":"","sources":["../../../../../../../../packages/react-components/react-combobox/src/utils/Selection.types.ts"],"names":[],"mappings":"","sourcesContent":["import * as React from 'react';\nimport { OptionValue } from './OptionCollection.types';\n\nexport type SelectionProps = {\n /**\n * For an uncontrolled component, sets the initial selection.\n * If this is set, the `defaultValue` prop MUST also be set.\n */\n defaultSelectedOptions?: string[];\n\n /**\n * Sets the selection type to multiselect.\n * Set this to true for multiselect, even if fully controlling selection state.\n * This enables styles and accessibility properties to be set.\n * @default false\n */\n multiselect?: boolean;\n\n /* Callback when an option is selected */\n onOptionSelect?: (event: SelectionEvents, data: OptionOnSelectData) => void;\n\n /**\n * An array of selected option keys.\n * Use this with `onOptionSelect` to directly control the selected option(s)\n * If this is set, the `value` prop MUST also be controlled.\n */\n selectedOptions?: string[];\n};\n\n/* Values returned by the useSelection hook */\nexport type SelectionState = {\n clearSelection: (event: SelectionEvents) => void;\n selectedOptions: string[];\n selectOption: (event: SelectionEvents, option: OptionValue) => void;\n};\n\n/*\n * Data for the onOptionSelect callback.\n * `optionValue` and `optionText` will be undefined if multiple options are modified at once.\n */\nexport type OptionOnSelectData = {\n optionValue: string | undefined;\n optionText: string | undefined;\n selectedOptions: string[];\n};\n\n/* Possible event types for onOptionSelect */\nexport type SelectionEvents =\n | React.ChangeEvent<HTMLElement>\n | React.KeyboardEvent<HTMLElement>\n | React.MouseEvent<HTMLElement>;\n"]}
@@ -8,7 +8,7 @@ define(["require", "exports", "tslib", "react", "@fluentui/react-utilities", "..
8
8
  var useComboboxBaseState = function (props) {
9
9
  var _a = props.appearance, appearance = _a === void 0 ? 'outline' : _a, children = props.children, _b = props.editable, editable = _b === void 0 ? false : _b, _c = props.inlinePopup, inlinePopup = _c === void 0 ? false : _c, multiselect = props.multiselect, onOpenChange = props.onOpenChange, _d = props.size, size = _d === void 0 ? 'medium' : _d;
10
10
  var optionCollection = useOptionCollection_1.useOptionCollection();
11
- var getOptionAtIndex = optionCollection.getOptionAtIndex, getOptionsMatchingText = optionCollection.getOptionsMatchingText;
11
+ var getOptionAtIndex = optionCollection.getOptionAtIndex, getOptionsMatchingValue = optionCollection.getOptionsMatchingValue;
12
12
  var _e = React.useState(), activeOption = _e[0], setActiveOption = _e[1];
13
13
  // track whether keyboard focus outline should be shown
14
14
  // tabster/keyborg doesn't work here, since the actual keyboard focus target doesn't move
@@ -33,12 +33,19 @@ define(["require", "exports", "tslib", "react", "@fluentui/react-utilities", "..
33
33
  if (isFirstMount && props.defaultValue !== undefined) {
34
34
  return props.defaultValue;
35
35
  }
36
+ var selectedOptionsText = getOptionsMatchingValue(function (optionValue) {
37
+ return selectedOptions.includes(optionValue);
38
+ }).map(function (option) { return option.text; });
36
39
  if (multiselect) {
37
40
  // editable inputs should not display multiple selected options in the input as text
38
- return editable ? '' : selectedOptions.join(', ');
41
+ return editable ? '' : selectedOptionsText.join(', ');
39
42
  }
40
- return selectedOptions[0];
41
- }, [controllableValue, editable, isFirstMount, multiselect, props.defaultValue, selectedOptions]);
43
+ return selectedOptionsText[0];
44
+ // do not change value after isFirstMount changes,
45
+ // we do not want to accidentally override defaultValue on a second render
46
+ // unless another value is intentionally set
47
+ // eslint-disable-next-line react-hooks/exhaustive-deps
48
+ }, [controllableValue, editable, getOptionsMatchingValue, multiselect, props.defaultValue, selectedOptions]);
42
49
  // Handle open state, which is shared with options in context
43
50
  var _j = react_utilities_1.useControllableState({
44
51
  state: props.open,
@@ -54,7 +61,7 @@ define(["require", "exports", "tslib", "react", "@fluentui/react-utilities", "..
54
61
  if (open && !activeOption) {
55
62
  // if it is single-select and there is a selected option, start at the selected option
56
63
  if (!multiselect && selectedOptions.length > 0) {
57
- var selectedOption = getOptionsMatchingText(function (v) { return v === selectedOptions[0]; }).pop();
64
+ var selectedOption = getOptionsMatchingValue(function (v) { return v === selectedOptions[0]; }).pop();
58
65
  selectedOption && setActiveOption(selectedOption);
59
66
  }
60
67
  // default to starting at the first option
@@ -1 +1 @@
1
- {"version":3,"file":"useComboboxBaseState.js","sourceRoot":"","sources":["../../../../../../../../packages/react-components/react-combobox/src/utils/useComboboxBaseState.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { useControllableState, useFirstMount } from '@fluentui/react-utilities';\nimport { useOptionCollection } from '../utils/useOptionCollection';\nimport { OptionValue } from '../utils/OptionCollection.types';\nimport { useSelection } from '../utils/useSelection';\nimport type { ComboboxBaseProps, ComboboxBaseOpenEvents, ComboboxBaseState } from './ComboboxBase.types';\n\n/**\n * State shared between Combobox and Dropdown components\n */\nexport const useComboboxBaseState = (\n props: ComboboxBaseProps & { children?: React.ReactNode; editable?: boolean },\n): ComboboxBaseState => {\n const {\n appearance = 'outline',\n children,\n editable = false,\n inlinePopup = false,\n multiselect,\n onOpenChange,\n size = 'medium',\n } = props;\n\n const optionCollection = useOptionCollection();\n const { getOptionAtIndex, getOptionsMatchingText } = optionCollection;\n\n const [activeOption, setActiveOption] = React.useState<OptionValue | undefined>();\n\n // track whether keyboard focus outline should be shown\n // tabster/keyborg doesn't work here, since the actual keyboard focus target doesn't move\n const [focusVisible, setFocusVisible] = React.useState(false);\n\n // track focused state to conditionally render collapsed listbox\n const [hasFocus, setHasFocus] = React.useState(false);\n\n const ignoreNextBlur = React.useRef(false);\n\n const selectionState = useSelection(props);\n const { selectedOptions } = selectionState;\n\n // calculate value based on props, internal value changes, and selected options\n const isFirstMount = useFirstMount();\n const [controllableValue, setValue] = useControllableState({\n state: props.value,\n initialState: undefined,\n });\n\n const value = React.useMemo(() => {\n // don't compute the value if it is defined through props or setValue,\n if (controllableValue !== undefined) {\n return controllableValue;\n }\n\n // handle defaultValue here, so it is overridden by selection\n if (isFirstMount && props.defaultValue !== undefined) {\n return props.defaultValue;\n }\n\n if (multiselect) {\n // editable inputs should not display multiple selected options in the input as text\n return editable ? '' : selectedOptions.join(', ');\n }\n\n return selectedOptions[0];\n }, [controllableValue, editable, isFirstMount, multiselect, props.defaultValue, selectedOptions]);\n\n // Handle open state, which is shared with options in context\n const [open, setOpenState] = useControllableState({\n state: props.open,\n defaultState: props.defaultOpen,\n initialState: false,\n });\n\n const setOpen = React.useCallback(\n (event: ComboboxBaseOpenEvents, newState: boolean) => {\n onOpenChange?.(event, { open: newState });\n setOpenState(newState);\n },\n [onOpenChange, setOpenState],\n );\n\n // update active option based on change in open state or children\n React.useEffect(() => {\n if (open && !activeOption) {\n // if it is single-select and there is a selected option, start at the selected option\n if (!multiselect && selectedOptions.length > 0) {\n const selectedOption = getOptionsMatchingText(v => v === selectedOptions[0]).pop();\n selectedOption && setActiveOption(selectedOption);\n }\n // default to starting at the first option\n else {\n setActiveOption(getOptionAtIndex(0));\n }\n } else if (!open) {\n // reset the active option when closing\n setActiveOption(undefined);\n }\n // this should only be run in response to changes in the open state or children\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, children]);\n\n return {\n ...optionCollection,\n ...selectionState,\n activeOption,\n appearance,\n focusVisible,\n hasFocus,\n ignoreNextBlur,\n inlinePopup,\n open,\n setActiveOption,\n setFocusVisible,\n setHasFocus,\n setOpen,\n setValue,\n size,\n value,\n };\n};\n"]}
1
+ {"version":3,"file":"useComboboxBaseState.js","sourceRoot":"","sources":["../../../../../../../../packages/react-components/react-combobox/src/utils/useComboboxBaseState.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport { useControllableState, useFirstMount } from '@fluentui/react-utilities';\nimport { useOptionCollection } from '../utils/useOptionCollection';\nimport { OptionValue } from '../utils/OptionCollection.types';\nimport { useSelection } from '../utils/useSelection';\nimport type { ComboboxBaseProps, ComboboxBaseOpenEvents, ComboboxBaseState } from './ComboboxBase.types';\n\n/**\n * State shared between Combobox and Dropdown components\n */\nexport const useComboboxBaseState = (\n props: ComboboxBaseProps & { children?: React.ReactNode; editable?: boolean },\n): ComboboxBaseState => {\n const {\n appearance = 'outline',\n children,\n editable = false,\n inlinePopup = false,\n multiselect,\n onOpenChange,\n size = 'medium',\n } = props;\n\n const optionCollection = useOptionCollection();\n const { getOptionAtIndex, getOptionsMatchingValue } = optionCollection;\n\n const [activeOption, setActiveOption] = React.useState<OptionValue | undefined>();\n\n // track whether keyboard focus outline should be shown\n // tabster/keyborg doesn't work here, since the actual keyboard focus target doesn't move\n const [focusVisible, setFocusVisible] = React.useState(false);\n\n // track focused state to conditionally render collapsed listbox\n const [hasFocus, setHasFocus] = React.useState(false);\n\n const ignoreNextBlur = React.useRef(false);\n\n const selectionState = useSelection(props);\n const { selectedOptions } = selectionState;\n\n // calculate value based on props, internal value changes, and selected options\n const isFirstMount = useFirstMount();\n const [controllableValue, setValue] = useControllableState({\n state: props.value,\n initialState: undefined,\n });\n\n const value = React.useMemo(() => {\n // don't compute the value if it is defined through props or setValue,\n if (controllableValue !== undefined) {\n return controllableValue;\n }\n\n // handle defaultValue here, so it is overridden by selection\n if (isFirstMount && props.defaultValue !== undefined) {\n return props.defaultValue;\n }\n\n const selectedOptionsText = getOptionsMatchingValue(optionValue => {\n return selectedOptions.includes(optionValue);\n }).map(option => option.text);\n\n if (multiselect) {\n // editable inputs should not display multiple selected options in the input as text\n return editable ? '' : selectedOptionsText.join(', ');\n }\n\n return selectedOptionsText[0];\n\n // do not change value after isFirstMount changes,\n // we do not want to accidentally override defaultValue on a second render\n // unless another value is intentionally set\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [controllableValue, editable, getOptionsMatchingValue, multiselect, props.defaultValue, selectedOptions]);\n\n // Handle open state, which is shared with options in context\n const [open, setOpenState] = useControllableState({\n state: props.open,\n defaultState: props.defaultOpen,\n initialState: false,\n });\n\n const setOpen = React.useCallback(\n (event: ComboboxBaseOpenEvents, newState: boolean) => {\n onOpenChange?.(event, { open: newState });\n setOpenState(newState);\n },\n [onOpenChange, setOpenState],\n );\n\n // update active option based on change in open state or children\n React.useEffect(() => {\n if (open && !activeOption) {\n // if it is single-select and there is a selected option, start at the selected option\n if (!multiselect && selectedOptions.length > 0) {\n const selectedOption = getOptionsMatchingValue(v => v === selectedOptions[0]).pop();\n selectedOption && setActiveOption(selectedOption);\n }\n // default to starting at the first option\n else {\n setActiveOption(getOptionAtIndex(0));\n }\n } else if (!open) {\n // reset the active option when closing\n setActiveOption(undefined);\n }\n // this should only be run in response to changes in the open state or children\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [open, children]);\n\n return {\n ...optionCollection,\n ...selectionState,\n activeOption,\n appearance,\n focusVisible,\n hasFocus,\n ignoreNextBlur,\n inlinePopup,\n open,\n setActiveOption,\n setFocusVisible,\n setHasFocus,\n setOpen,\n setValue,\n size,\n value,\n };\n};\n"]}
@@ -18,12 +18,16 @@ define(["require", "exports", "tslib", "react"], function (require, exports, tsl
18
18
  var getOptionsMatchingText = function (matcher) {
19
19
  return nodes.current.filter(function (node) { return matcher(node.option.text); }).map(function (node) { return node.option; });
20
20
  };
21
+ var getOptionsMatchingValue = function (matcher) {
22
+ return nodes.current.filter(function (node) { return matcher(node.option.value); }).map(function (node) { return node.option; });
23
+ };
21
24
  return {
22
25
  getCount: getCount,
23
26
  getOptionAtIndex: getOptionAtIndex,
24
27
  getIndexOfId: getIndexOfId,
25
28
  getOptionById: getOptionById,
26
29
  getOptionsMatchingText: getOptionsMatchingText,
30
+ getOptionsMatchingValue: getOptionsMatchingValue,
27
31
  };
28
32
  }, []);
29
33
  var registerOption = React.useCallback(function (option, element) {
@@ -1 +1 @@
1
- {"version":3,"file":"useOptionCollection.js","sourceRoot":"","sources":["../../../../../../../../packages/react-components/react-combobox/src/utils/useOptionCollection.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport type { OptionCollectionState, OptionValue } from './OptionCollection.types';\n\n/**\n * A hook for managing a collection of child Options\n */\nexport const useOptionCollection = (): OptionCollectionState => {\n const nodes = React.useRef<{ option: OptionValue; element: HTMLElement }[]>([]);\n\n const collectionAPI = React.useMemo(() => {\n const getCount = () => nodes.current.length;\n const getOptionAtIndex = (index: number) => nodes.current[index]?.option;\n const getIndexOfId = (id: string) => nodes.current.findIndex(node => node.option.id === id);\n const getOptionById = (id: string) => {\n const item = nodes.current.find(node => node.option.id === id);\n return item?.option;\n };\n const getOptionsMatchingText = (matcher: (value: string) => boolean) => {\n return nodes.current.filter(node => matcher(node.option.text)).map(node => node.option);\n };\n\n return {\n getCount,\n getOptionAtIndex,\n getIndexOfId,\n getOptionById,\n getOptionsMatchingText,\n };\n }, []);\n\n const registerOption = React.useCallback((option: OptionValue, element: HTMLElement) => {\n const index = nodes.current.findIndex(node => {\n if (!node.element || !element) {\n return false;\n }\n\n if (node.option.id === option.id) {\n return true;\n }\n\n // use the DOM method compareDocumentPosition to order the current node against registered nodes\n // eslint-disable-next-line no-bitwise\n return node.element.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_PRECEDING;\n });\n\n // do not register the option if it already exists\n if (nodes.current[index]?.option.id !== option.id) {\n const newItem = {\n element,\n option,\n };\n\n // If an index is not found we will push the element to the end.\n if (index === -1) {\n nodes.current = [...nodes.current, newItem];\n } else {\n nodes.current.splice(index, 0, newItem);\n }\n }\n\n // return the unregister function\n return () => {\n nodes.current = nodes.current.filter(node => node.option.id !== option.id);\n };\n }, []);\n\n return {\n ...collectionAPI,\n options: nodes.current.map(node => node.option),\n registerOption,\n };\n};\n"]}
1
+ {"version":3,"file":"useOptionCollection.js","sourceRoot":"","sources":["../../../../../../../../packages/react-components/react-combobox/src/utils/useOptionCollection.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react';\nimport type { OptionCollectionState, OptionValue } from './OptionCollection.types';\n\n/**\n * A hook for managing a collection of child Options\n */\nexport const useOptionCollection = (): OptionCollectionState => {\n const nodes = React.useRef<{ option: OptionValue; element: HTMLElement }[]>([]);\n\n const collectionAPI = React.useMemo(() => {\n const getCount = () => nodes.current.length;\n const getOptionAtIndex = (index: number) => nodes.current[index]?.option;\n const getIndexOfId = (id: string) => nodes.current.findIndex(node => node.option.id === id);\n const getOptionById = (id: string) => {\n const item = nodes.current.find(node => node.option.id === id);\n return item?.option;\n };\n const getOptionsMatchingText = (matcher: (text: string) => boolean) => {\n return nodes.current.filter(node => matcher(node.option.text)).map(node => node.option);\n };\n const getOptionsMatchingValue = (matcher: (value: string) => boolean) => {\n return nodes.current.filter(node => matcher(node.option.value)).map(node => node.option);\n };\n\n return {\n getCount,\n getOptionAtIndex,\n getIndexOfId,\n getOptionById,\n getOptionsMatchingText,\n getOptionsMatchingValue,\n };\n }, []);\n\n const registerOption = React.useCallback((option: OptionValue, element: HTMLElement) => {\n const index = nodes.current.findIndex(node => {\n if (!node.element || !element) {\n return false;\n }\n\n if (node.option.id === option.id) {\n return true;\n }\n\n // use the DOM method compareDocumentPosition to order the current node against registered nodes\n // eslint-disable-next-line no-bitwise\n return node.element.compareDocumentPosition(element) & Node.DOCUMENT_POSITION_PRECEDING;\n });\n\n // do not register the option if it already exists\n if (nodes.current[index]?.option.id !== option.id) {\n const newItem = {\n element,\n option,\n };\n\n // If an index is not found we will push the element to the end.\n if (index === -1) {\n nodes.current = [...nodes.current, newItem];\n } else {\n nodes.current.splice(index, 0, newItem);\n }\n }\n\n // return the unregister function\n return () => {\n nodes.current = nodes.current.filter(node => node.option.id !== option.id);\n };\n }, []);\n\n return {\n ...collectionAPI,\n options: nodes.current.map(node => node.option),\n registerOption,\n };\n};\n"]}
@@ -105,7 +105,7 @@ const useCombobox_unstable = (props, ref) => {
105
105
  // handle selection and updating value if freeform is false
106
106
  if (!baseState.open && !freeform) {
107
107
  // select matching option, if the value fully matches
108
- if (value && activeOption && value.trim().toLowerCase() === (activeOption === null || activeOption === void 0 ? void 0 : activeOption.value.toLowerCase())) {
108
+ if (value && activeOption && value.trim().toLowerCase() === (activeOption === null || activeOption === void 0 ? void 0 : activeOption.text.toLowerCase())) {
109
109
  baseState.selectOption(ev, activeOption);
110
110
  }
111
111
  // reset typed value when the input loses focus while collapsed, unless freeform is true
@@ -131,7 +131,7 @@ const useCombobox_unstable = (props, ref) => {
131
131
  setActiveOption(matchingOption);
132
132
  setFocusVisible(true);
133
133
  // clear selection for single-select if the input value no longer matches the selection
134
- if (!multiselect && selectedOptions.length === 1 && (inputValue.length < 1 || selectedOptions[0].indexOf(inputValue) !== 0)) {
134
+ if (!multiselect && selectedOptions.length === 1 && (inputValue.length < 1 || !matchingOption)) {
135
135
  clearSelection(ev);
136
136
  }
137
137
  };
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["useCombobox_unstable","props","ref","baseState","useComboboxBaseState_1","editable","activeOption","clearSelection","getIndexOfId","getOptionsMatchingText","hasFocus","open","selectOption","selectedOptions","setActiveOption","setFocusVisible","setOpen","setValue","value","disabled","freeform","inlinePopup","multiselect","comboId","react_utilities_1","primary","triggerNativeProps","root","rootNativeProps","primarySlotTagName","excludedPropNames","rootRef","React","useRef","triggerRef","hideActiveDescendant","setHideActiveDescendant","useState","popupDimensions","setPopupDimensions","useEffect","width","current","clientWidth","getOptionFromInput","inputValue","searchString","trim","toLowerCase","length","matcher","optionText","indexOf","matches","startIndex","id","nextMatch","find","option","undefined","ev","onTriggerBlur","newState","onTriggerChange","target","matchingOption","onTriggerKeyDown","dropdownKeyActions_1","key","keyboard_keys_1","triggerSlot","listboxSlot","input","required","defaultProps","type","onChange","onBlur","onKeyDown","listbox","children","style","useComboboxPopup_1","useTriggerListboxSlots_1","state","components","expandIcon","Listbox_1","react_icons_1","role","onMouseDown","onIconMouseDown","onClick","onIconClick","onExpandIconMouseDown","ignoreNextBlur","onExpandIconClick","event","focus","hasExpandLabel","defaultOpenString","chevronId","chevronLabelledBy","exports"],"sourceRoot":"../src/","sources":["packages/react-components/react-combobox/src/components/Combobox/useCombobox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { ArrowLeft, ArrowRight } from '@fluentui/keyboard-keys';\nimport { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';\nimport {\n getPartitionedNativeProps,\n resolveShorthand,\n mergeCallbacks,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from '../../utils/dropdownKeyActions';\nimport { useComboboxBaseState } from '../../utils/useComboboxBaseState';\nimport { useComboboxPopup } from '../../utils/useComboboxPopup';\nimport { useTriggerListboxSlots } from '../../utils/useTriggerListboxSlots';\nimport { Listbox } from '../Listbox/Listbox';\nimport type { Slot } from '@fluentui/react-utilities';\nimport type { SelectionEvents } from '../../utils/Selection.types';\nimport type { OptionValue } from '../../utils/OptionCollection.types';\nimport type { ComboboxProps, ComboboxState } from './Combobox.types';\n\n/**\n * Create the state required to render Combobox.\n *\n * The returned state can be modified with hooks such as useComboboxStyles_unstable,\n * before being passed to renderCombobox_unstable.\n *\n * @param props - props from this instance of Combobox\n * @param ref - reference to root HTMLElement of Combobox\n */\nexport const useCombobox_unstable = (props: ComboboxProps, ref: React.Ref<HTMLInputElement>): ComboboxState => {\n const baseState = useComboboxBaseState({ ...props, editable: true });\n const {\n activeOption,\n clearSelection,\n getIndexOfId,\n getOptionsMatchingText,\n hasFocus,\n open,\n selectOption,\n selectedOptions,\n setActiveOption,\n setFocusVisible,\n setOpen,\n setValue,\n value,\n } = baseState;\n const { disabled, freeform, inlinePopup, multiselect } = props;\n const comboId = useId('combobox-');\n\n const { primary: triggerNativeProps, root: rootNativeProps } = getPartitionedNativeProps({\n props,\n primarySlotTagName: 'input',\n excludedPropNames: ['children', 'size'],\n });\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n const triggerRef = React.useRef<HTMLInputElement>(null);\n\n // NVDA and JAWS have bugs that suppress reading the input value text when aria-activedescendant is set\n // To prevent this, we clear the HTML attribute (but save the state) when a user presses left/right arrows\n // ref: https://github.com/microsoft/fluentui/issues/26359#issuecomment-1397759888\n const [hideActiveDescendant, setHideActiveDescendant] = React.useState(false);\n\n // calculate listbox width style based on trigger width\n const [popupDimensions, setPopupDimensions] = React.useState<{ width: string }>();\n React.useEffect(() => {\n // only recalculate width when opening\n if (open) {\n const width = `${rootRef.current?.clientWidth}px`;\n if (width !== popupDimensions?.width) {\n setPopupDimensions({ width });\n }\n }\n }, [open, popupDimensions]);\n\n // set active option and selection based on typing\n const getOptionFromInput = (inputValue: string): OptionValue | undefined => {\n const searchString = inputValue?.trim().toLowerCase();\n\n if (!searchString || searchString.length === 0) {\n return;\n }\n\n const matcher = (optionText: string) => optionText.toLowerCase().indexOf(searchString) === 0;\n const matches = getOptionsMatchingText(matcher);\n\n // return first matching option after the current active option, looping back to the top\n if (matches.length > 1 && activeOption) {\n const startIndex = getIndexOfId(activeOption.id);\n const nextMatch = matches.find(option => getIndexOfId(option.id) >= startIndex);\n return nextMatch ?? matches[0];\n }\n\n return matches[0] ?? undefined;\n };\n\n /* Handle typed input */\n\n // reset any typed value when an option is selected\n baseState.selectOption = (ev: SelectionEvents, option: OptionValue) => {\n setValue(undefined);\n selectOption(ev, option);\n };\n\n const onTriggerBlur = (ev: React.FocusEvent<HTMLInputElement>) => {\n // handle selection and updating value if freeform is false\n if (!baseState.open && !freeform) {\n // select matching option, if the value fully matches\n if (value && activeOption && value.trim().toLowerCase() === activeOption?.value.toLowerCase()) {\n baseState.selectOption(ev, activeOption);\n }\n\n // reset typed value when the input loses focus while collapsed, unless freeform is true\n setValue(undefined);\n }\n };\n\n baseState.setOpen = (ev, newState: boolean) => {\n if (disabled) {\n return;\n }\n\n if (!newState && !freeform) {\n setValue(undefined);\n }\n\n setOpen(ev, newState);\n };\n\n // update value and active option based on input\n const onTriggerChange = (ev: React.ChangeEvent<HTMLInputElement>) => {\n const inputValue = ev.target.value;\n // update uncontrolled value\n baseState.setValue(inputValue);\n\n // handle updating active option based on input\n const matchingOption = getOptionFromInput(inputValue);\n setActiveOption(matchingOption);\n\n setFocusVisible(true);\n\n // clear selection for single-select if the input value no longer matches the selection\n if (\n !multiselect &&\n selectedOptions.length === 1 &&\n (inputValue.length < 1 || selectedOptions[0].indexOf(inputValue) !== 0)\n ) {\n clearSelection(ev);\n }\n };\n\n // open Combobox when typing\n const onTriggerKeyDown = (ev: React.KeyboardEvent<HTMLInputElement>) => {\n if (!open && getDropdownActionFromKey(ev) === 'Type') {\n baseState.setOpen(ev, true);\n }\n\n // clear activedescendant when moving the text insertion cursor\n if (ev.key === ArrowLeft || ev.key === ArrowRight) {\n setHideActiveDescendant(true);\n } else {\n setHideActiveDescendant(false);\n }\n };\n\n // resolve input and listbox slot props\n let triggerSlot: Slot<'input'>;\n let listboxSlot: Slot<typeof Listbox> | undefined;\n\n triggerSlot = resolveShorthand(props.input, {\n required: true,\n defaultProps: {\n ref: useMergedRefs(props.input?.ref, triggerRef),\n type: 'text',\n value: value ?? '',\n ...triggerNativeProps,\n },\n });\n\n triggerSlot.onChange = mergeCallbacks(triggerSlot.onChange, onTriggerChange);\n triggerSlot.onBlur = mergeCallbacks(triggerSlot.onBlur, onTriggerBlur);\n triggerSlot.onKeyDown = mergeCallbacks(triggerSlot.onKeyDown, onTriggerKeyDown);\n\n // only resolve listbox slot if needed\n listboxSlot =\n open || hasFocus\n ? resolveShorthand(props.listbox, {\n required: true,\n defaultProps: {\n children: props.children,\n style: popupDimensions,\n },\n })\n : undefined;\n\n [triggerSlot, listboxSlot] = useComboboxPopup(props, triggerSlot, listboxSlot);\n [triggerSlot, listboxSlot] = useTriggerListboxSlots(props, baseState, ref, triggerSlot, listboxSlot);\n\n if (hideActiveDescendant) {\n triggerSlot['aria-activedescendant'] = undefined;\n }\n\n const state: ComboboxState = {\n components: {\n root: 'div',\n input: 'input',\n expandIcon: 'span',\n listbox: Listbox,\n },\n root: resolveShorthand(props.root, {\n required: true,\n defaultProps: {\n 'aria-owns': !inlinePopup ? listboxSlot?.id : undefined,\n ...rootNativeProps,\n },\n }),\n input: triggerSlot,\n listbox: listboxSlot,\n expandIcon: resolveShorthand(props.expandIcon, {\n required: true,\n defaultProps: {\n 'aria-expanded': open,\n children: <ChevronDownIcon />,\n role: 'button',\n },\n }),\n ...baseState,\n };\n\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n /* handle open/close + focus change when clicking expandIcon */\n const { onMouseDown: onIconMouseDown, onClick: onIconClick } = state.expandIcon || {};\n const onExpandIconMouseDown = useEventCallback(\n mergeCallbacks(onIconMouseDown, () => {\n // do not dismiss on blur when closing via clicking the icon\n if (open) {\n baseState.ignoreNextBlur.current = true;\n }\n }),\n );\n\n const onExpandIconClick = useEventCallback(\n mergeCallbacks(onIconClick, (event: React.MouseEvent<HTMLSpanElement>) => {\n // open and set focus\n state.setOpen(event, !state.open);\n triggerRef.current?.focus();\n\n // set focus visible=false, since this can only be done with the mouse/pointer\n setFocusVisible(false);\n }),\n );\n\n if (state.expandIcon) {\n state.expandIcon.onMouseDown = onExpandIconMouseDown;\n state.expandIcon.onClick = onExpandIconClick;\n\n // If there is no explicit aria-label, calculate default accName attribute for expandIcon button,\n // using the following steps:\n // 1. If there is an aria-label, it is \"Open [aria-label]\"\n // 2. If there is an aria-labelledby, it is \"Open [aria-labelledby target]\" (using aria-labelledby + ids)\n // 3. If there is no aria-label/ledby attr, it falls back to \"Open\"\n // We can't fall back to a label/htmlFor name because of https://github.com/w3c/accname/issues/179\n const hasExpandLabel = state.expandIcon['aria-label'] || state.expandIcon['aria-labelledby'];\n const defaultOpenString = 'Open'; // this is english-only since it is the fallback\n if (!hasExpandLabel) {\n if (props['aria-labelledby']) {\n const chevronId = state.expandIcon.id ?? `${comboId}-chevron`;\n const chevronLabelledBy = `${chevronId} ${state.input['aria-labelledby']}`;\n\n state.expandIcon['aria-label'] = defaultOpenString;\n state.expandIcon.id = chevronId;\n state.expandIcon['aria-labelledby'] = chevronLabelledBy;\n } else if (props['aria-label']) {\n state.expandIcon['aria-label'] = `${defaultOpenString} ${props['aria-label']}`;\n } else {\n state.expandIcon['aria-label'] = defaultOpenString;\n }\n }\n }\n\n return state;\n};\n"]}
1
+ {"version":3,"mappings":"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","names":["useCombobox_unstable","props","ref","baseState","useComboboxBaseState_1","editable","activeOption","clearSelection","getIndexOfId","getOptionsMatchingText","hasFocus","open","selectOption","selectedOptions","setActiveOption","setFocusVisible","setOpen","setValue","value","disabled","freeform","inlinePopup","multiselect","comboId","react_utilities_1","primary","triggerNativeProps","root","rootNativeProps","primarySlotTagName","excludedPropNames","rootRef","React","useRef","triggerRef","hideActiveDescendant","setHideActiveDescendant","useState","popupDimensions","setPopupDimensions","useEffect","width","current","clientWidth","getOptionFromInput","inputValue","searchString","trim","toLowerCase","length","matcher","optionText","indexOf","matches","startIndex","id","nextMatch","find","option","undefined","ev","onTriggerBlur","text","newState","onTriggerChange","target","matchingOption","onTriggerKeyDown","dropdownKeyActions_1","key","keyboard_keys_1","triggerSlot","listboxSlot","input","required","defaultProps","type","onChange","onBlur","onKeyDown","listbox","children","style","useComboboxPopup_1","useTriggerListboxSlots_1","state","components","expandIcon","Listbox_1","react_icons_1","role","onMouseDown","onIconMouseDown","onClick","onIconClick","onExpandIconMouseDown","ignoreNextBlur","onExpandIconClick","event","focus","hasExpandLabel","defaultOpenString","chevronId","chevronLabelledBy","exports"],"sourceRoot":"../src/","sources":["packages/react-components/react-combobox/src/components/Combobox/useCombobox.tsx"],"sourcesContent":["import * as React from 'react';\nimport { ArrowLeft, ArrowRight } from '@fluentui/keyboard-keys';\nimport { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';\nimport {\n getPartitionedNativeProps,\n resolveShorthand,\n mergeCallbacks,\n useEventCallback,\n useId,\n useMergedRefs,\n} from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from '../../utils/dropdownKeyActions';\nimport { useComboboxBaseState } from '../../utils/useComboboxBaseState';\nimport { useComboboxPopup } from '../../utils/useComboboxPopup';\nimport { useTriggerListboxSlots } from '../../utils/useTriggerListboxSlots';\nimport { Listbox } from '../Listbox/Listbox';\nimport type { Slot } from '@fluentui/react-utilities';\nimport type { SelectionEvents } from '../../utils/Selection.types';\nimport type { OptionValue } from '../../utils/OptionCollection.types';\nimport type { ComboboxProps, ComboboxState } from './Combobox.types';\n\n/**\n * Create the state required to render Combobox.\n *\n * The returned state can be modified with hooks such as useComboboxStyles_unstable,\n * before being passed to renderCombobox_unstable.\n *\n * @param props - props from this instance of Combobox\n * @param ref - reference to root HTMLElement of Combobox\n */\nexport const useCombobox_unstable = (props: ComboboxProps, ref: React.Ref<HTMLInputElement>): ComboboxState => {\n const baseState = useComboboxBaseState({ ...props, editable: true });\n const {\n activeOption,\n clearSelection,\n getIndexOfId,\n getOptionsMatchingText,\n hasFocus,\n open,\n selectOption,\n selectedOptions,\n setActiveOption,\n setFocusVisible,\n setOpen,\n setValue,\n value,\n } = baseState;\n const { disabled, freeform, inlinePopup, multiselect } = props;\n const comboId = useId('combobox-');\n\n const { primary: triggerNativeProps, root: rootNativeProps } = getPartitionedNativeProps({\n props,\n primarySlotTagName: 'input',\n excludedPropNames: ['children', 'size'],\n });\n\n const rootRef = React.useRef<HTMLDivElement>(null);\n const triggerRef = React.useRef<HTMLInputElement>(null);\n\n // NVDA and JAWS have bugs that suppress reading the input value text when aria-activedescendant is set\n // To prevent this, we clear the HTML attribute (but save the state) when a user presses left/right arrows\n // ref: https://github.com/microsoft/fluentui/issues/26359#issuecomment-1397759888\n const [hideActiveDescendant, setHideActiveDescendant] = React.useState(false);\n\n // calculate listbox width style based on trigger width\n const [popupDimensions, setPopupDimensions] = React.useState<{ width: string }>();\n React.useEffect(() => {\n // only recalculate width when opening\n if (open) {\n const width = `${rootRef.current?.clientWidth}px`;\n if (width !== popupDimensions?.width) {\n setPopupDimensions({ width });\n }\n }\n }, [open, popupDimensions]);\n\n // set active option and selection based on typing\n const getOptionFromInput = (inputValue: string): OptionValue | undefined => {\n const searchString = inputValue?.trim().toLowerCase();\n\n if (!searchString || searchString.length === 0) {\n return;\n }\n\n const matcher = (optionText: string) => optionText.toLowerCase().indexOf(searchString) === 0;\n const matches = getOptionsMatchingText(matcher);\n\n // return first matching option after the current active option, looping back to the top\n if (matches.length > 1 && activeOption) {\n const startIndex = getIndexOfId(activeOption.id);\n const nextMatch = matches.find(option => getIndexOfId(option.id) >= startIndex);\n return nextMatch ?? matches[0];\n }\n\n return matches[0] ?? undefined;\n };\n\n /* Handle typed input */\n\n // reset any typed value when an option is selected\n baseState.selectOption = (ev: SelectionEvents, option: OptionValue) => {\n setValue(undefined);\n selectOption(ev, option);\n };\n\n const onTriggerBlur = (ev: React.FocusEvent<HTMLInputElement>) => {\n // handle selection and updating value if freeform is false\n if (!baseState.open && !freeform) {\n // select matching option, if the value fully matches\n if (value && activeOption && value.trim().toLowerCase() === activeOption?.text.toLowerCase()) {\n baseState.selectOption(ev, activeOption);\n }\n\n // reset typed value when the input loses focus while collapsed, unless freeform is true\n setValue(undefined);\n }\n };\n\n baseState.setOpen = (ev, newState: boolean) => {\n if (disabled) {\n return;\n }\n\n if (!newState && !freeform) {\n setValue(undefined);\n }\n\n setOpen(ev, newState);\n };\n\n // update value and active option based on input\n const onTriggerChange = (ev: React.ChangeEvent<HTMLInputElement>) => {\n const inputValue = ev.target.value;\n // update uncontrolled value\n baseState.setValue(inputValue);\n\n // handle updating active option based on input\n const matchingOption = getOptionFromInput(inputValue);\n setActiveOption(matchingOption);\n\n setFocusVisible(true);\n\n // clear selection for single-select if the input value no longer matches the selection\n if (!multiselect && selectedOptions.length === 1 && (inputValue.length < 1 || !matchingOption)) {\n clearSelection(ev);\n }\n };\n\n // open Combobox when typing\n const onTriggerKeyDown = (ev: React.KeyboardEvent<HTMLInputElement>) => {\n if (!open && getDropdownActionFromKey(ev) === 'Type') {\n baseState.setOpen(ev, true);\n }\n\n // clear activedescendant when moving the text insertion cursor\n if (ev.key === ArrowLeft || ev.key === ArrowRight) {\n setHideActiveDescendant(true);\n } else {\n setHideActiveDescendant(false);\n }\n };\n\n // resolve input and listbox slot props\n let triggerSlot: Slot<'input'>;\n let listboxSlot: Slot<typeof Listbox> | undefined;\n\n triggerSlot = resolveShorthand(props.input, {\n required: true,\n defaultProps: {\n ref: useMergedRefs(props.input?.ref, triggerRef),\n type: 'text',\n value: value ?? '',\n ...triggerNativeProps,\n },\n });\n\n triggerSlot.onChange = mergeCallbacks(triggerSlot.onChange, onTriggerChange);\n triggerSlot.onBlur = mergeCallbacks(triggerSlot.onBlur, onTriggerBlur);\n triggerSlot.onKeyDown = mergeCallbacks(triggerSlot.onKeyDown, onTriggerKeyDown);\n\n // only resolve listbox slot if needed\n listboxSlot =\n open || hasFocus\n ? resolveShorthand(props.listbox, {\n required: true,\n defaultProps: {\n children: props.children,\n style: popupDimensions,\n },\n })\n : undefined;\n\n [triggerSlot, listboxSlot] = useComboboxPopup(props, triggerSlot, listboxSlot);\n [triggerSlot, listboxSlot] = useTriggerListboxSlots(props, baseState, ref, triggerSlot, listboxSlot);\n\n if (hideActiveDescendant) {\n triggerSlot['aria-activedescendant'] = undefined;\n }\n\n const state: ComboboxState = {\n components: {\n root: 'div',\n input: 'input',\n expandIcon: 'span',\n listbox: Listbox,\n },\n root: resolveShorthand(props.root, {\n required: true,\n defaultProps: {\n 'aria-owns': !inlinePopup ? listboxSlot?.id : undefined,\n ...rootNativeProps,\n },\n }),\n input: triggerSlot,\n listbox: listboxSlot,\n expandIcon: resolveShorthand(props.expandIcon, {\n required: true,\n defaultProps: {\n 'aria-expanded': open,\n children: <ChevronDownIcon />,\n role: 'button',\n },\n }),\n ...baseState,\n };\n\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n /* handle open/close + focus change when clicking expandIcon */\n const { onMouseDown: onIconMouseDown, onClick: onIconClick } = state.expandIcon || {};\n const onExpandIconMouseDown = useEventCallback(\n mergeCallbacks(onIconMouseDown, () => {\n // do not dismiss on blur when closing via clicking the icon\n if (open) {\n baseState.ignoreNextBlur.current = true;\n }\n }),\n );\n\n const onExpandIconClick = useEventCallback(\n mergeCallbacks(onIconClick, (event: React.MouseEvent<HTMLSpanElement>) => {\n // open and set focus\n state.setOpen(event, !state.open);\n triggerRef.current?.focus();\n\n // set focus visible=false, since this can only be done with the mouse/pointer\n setFocusVisible(false);\n }),\n );\n\n if (state.expandIcon) {\n state.expandIcon.onMouseDown = onExpandIconMouseDown;\n state.expandIcon.onClick = onExpandIconClick;\n\n // If there is no explicit aria-label, calculate default accName attribute for expandIcon button,\n // using the following steps:\n // 1. If there is an aria-label, it is \"Open [aria-label]\"\n // 2. If there is an aria-labelledby, it is \"Open [aria-labelledby target]\" (using aria-labelledby + ids)\n // 3. If there is no aria-label/ledby attr, it falls back to \"Open\"\n // We can't fall back to a label/htmlFor name because of https://github.com/w3c/accname/issues/179\n const hasExpandLabel = state.expandIcon['aria-label'] || state.expandIcon['aria-labelledby'];\n const defaultOpenString = 'Open'; // this is english-only since it is the fallback\n if (!hasExpandLabel) {\n if (props['aria-labelledby']) {\n const chevronId = state.expandIcon.id ?? `${comboId}-chevron`;\n const chevronLabelledBy = `${chevronId} ${state.input['aria-labelledby']}`;\n\n state.expandIcon['aria-label'] = defaultOpenString;\n state.expandIcon.id = chevronId;\n state.expandIcon['aria-labelledby'] = chevronLabelledBy;\n } else if (props['aria-label']) {\n state.expandIcon['aria-label'] = `${defaultOpenString} ${props['aria-label']}`;\n } else {\n state.expandIcon['aria-label'] = defaultOpenString;\n }\n }\n }\n\n return state;\n};\n"]}
@@ -55,7 +55,7 @@ const useDropdown_unstable = (props, ref) => {
55
55
  const getNextMatchingOption = () => {
56
56
  var _a;
57
57
  // first check for matches for the full searchString
58
- let matcher = optionValue => optionValue.toLowerCase().indexOf(searchString.current) === 0;
58
+ let matcher = optionText => optionText.toLowerCase().indexOf(searchString.current) === 0;
59
59
  let matches = getOptionsMatchingText(matcher);
60
60
  let startIndex = activeOption ? getIndexOfId(activeOption.id) : 0;
61
61
  // if the dropdown is already open and the searchstring is a single character,
@@ -71,7 +71,7 @@ const useDropdown_unstable = (props, ref) => {
71
71
  // if the search is all the same letter, cycle through options starting with that letter
72
72
  if (allSameLetter) {
73
73
  startIndex++;
74
- matcher = optionValue => optionValue.toLowerCase().indexOf(letters[0]) === 0;
74
+ matcher = optionText => optionText.toLowerCase().indexOf(letters[0]) === 0;
75
75
  matches = getOptionsMatchingText(matcher);
76
76
  }
77
77
  }
@@ -1 +1 @@
1
- {"version":3,"mappings":"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","names":["useDropdown_unstable","props","ref","baseState","useComboboxBaseState_1","activeOption","getIndexOfId","getOptionsMatchingText","open","setActiveOption","setFocusVisible","setOpen","primary","triggerNativeProps","root","rootNativeProps","react_utilities_1","primarySlotTagName","excludedPropNames","rootRef","React","useRef","popupWidth","setPopupWidth","useState","useEffect","width","current","clientWidth","undefined","searchString","setKeyTimeout","clearKeyTimeout","getNextMatchingOption","matcher","optionValue","toLowerCase","indexOf","matches","startIndex","id","length","letters","split","allSameLetter","every","letter","nextMatch","find","option","onTriggerKeyDown","ev","dropdownKeyActions_1","key","nextOption","triggerSlot","listboxSlot","button","required","defaultProps","type","children","value","placeholder","onKeyDown","hasFocus","listbox","style","useComboboxPopup_1","useTriggerListboxSlots_1","state","components","expandIcon","Listbox_1","inlinePopup","react_icons_1","placeholderVisible","react_utilities_2","exports"],"sourceRoot":"../src/","sources":["packages/react-components/react-combobox/src/components/Dropdown/useDropdown.tsx"],"sourcesContent":["import * as React from 'react';\nimport { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';\nimport { getPartitionedNativeProps, mergeCallbacks, resolveShorthand, useTimeout } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from '../../utils/dropdownKeyActions';\nimport { useComboboxBaseState } from '../../utils/useComboboxBaseState';\nimport { useComboboxPopup } from '../../utils/useComboboxPopup';\nimport { useTriggerListboxSlots } from '../../utils/useTriggerListboxSlots';\nimport { Listbox } from '../Listbox/Listbox';\nimport type { Slot } from '@fluentui/react-utilities';\nimport type { OptionValue } from '../../utils/OptionCollection.types';\nimport type { DropdownProps, DropdownState } from './Dropdown.types';\nimport { useMergedRefs } from '@fluentui/react-utilities';\n\n/**\n * Create the state required to render Dropdown.\n *\n * The returned state can be modified with hooks such as useDropdownStyles_unstable,\n * before being passed to renderDropdown_unstable.\n *\n * @param props - props from this instance of Dropdown\n * @param ref - reference to root HTMLElement of Dropdown\n */\nexport const useDropdown_unstable = (props: DropdownProps, ref: React.Ref<HTMLButtonElement>): DropdownState => {\n const baseState = useComboboxBaseState(props);\n const {\n activeOption,\n getIndexOfId,\n getOptionsMatchingText,\n open,\n setActiveOption,\n setFocusVisible,\n setOpen,\n } = baseState;\n\n const { primary: triggerNativeProps, root: rootNativeProps } = getPartitionedNativeProps({\n props,\n primarySlotTagName: 'button',\n excludedPropNames: ['children'],\n });\n\n // set listbox popup width based off the root/trigger width\n const rootRef = React.useRef<HTMLDivElement>(null);\n const [popupWidth, setPopupWidth] = React.useState<string>();\n React.useEffect(() => {\n const width = open ? `${rootRef.current?.clientWidth}px` : undefined;\n setPopupWidth(width);\n }, [open]);\n\n // jump to matching option based on typing\n const searchString = React.useRef('');\n const [setKeyTimeout, clearKeyTimeout] = useTimeout();\n\n const getNextMatchingOption = (): OptionValue | undefined => {\n // first check for matches for the full searchString\n let matcher = (optionValue: string) => optionValue.toLowerCase().indexOf(searchString.current) === 0;\n let matches = getOptionsMatchingText(matcher);\n let startIndex = activeOption ? getIndexOfId(activeOption.id) : 0;\n\n // if the dropdown is already open and the searchstring is a single character,\n // then look after the current activeOption for letters\n // this is so slowly typing the same letter will cycle through matches\n if (open && searchString.current.length === 1) {\n startIndex++;\n }\n\n // if there are no direct matches, check if the search is all the same letter, e.g. \"aaa\"\n if (!matches.length) {\n const letters = searchString.current.split('');\n const allSameLetter = letters.length && letters.every(letter => letter === letters[0]);\n\n // if the search is all the same letter, cycle through options starting with that letter\n if (allSameLetter) {\n startIndex++;\n matcher = (optionValue: string) => optionValue.toLowerCase().indexOf(letters[0]) === 0;\n matches = getOptionsMatchingText(matcher);\n }\n }\n\n // if there is an active option and multiple matches,\n // return first matching option after the current active option, looping back to the top\n if (matches.length > 1 && activeOption) {\n const nextMatch = matches.find(option => getIndexOfId(option.id) >= startIndex);\n return nextMatch ?? matches[0];\n }\n\n return matches[0] ?? undefined;\n };\n\n const onTriggerKeyDown = (ev: React.KeyboardEvent<HTMLButtonElement>) => {\n // clear timeout, if it exists\n clearKeyTimeout();\n\n // if the key was a char key, update search string\n if (getDropdownActionFromKey(ev) === 'Type') {\n // update search string\n searchString.current += ev.key.toLowerCase();\n setKeyTimeout(() => {\n searchString.current = '';\n }, 500);\n\n // update state\n !open && setOpen(ev, true);\n\n const nextOption = getNextMatchingOption();\n setActiveOption(nextOption);\n setFocusVisible(true);\n }\n };\n\n // resolve button and listbox slot props\n let triggerSlot: Slot<'button'>;\n let listboxSlot: Slot<typeof Listbox> | undefined;\n\n triggerSlot = resolveShorthand(props.button, {\n required: true,\n defaultProps: {\n type: 'button',\n children: baseState.value || props.placeholder,\n ...triggerNativeProps,\n },\n });\n\n triggerSlot.onKeyDown = mergeCallbacks(onTriggerKeyDown, triggerSlot.onKeyDown);\n\n listboxSlot =\n baseState.open || baseState.hasFocus\n ? resolveShorthand(props.listbox, {\n required: true,\n defaultProps: {\n children: props.children,\n style: { width: popupWidth },\n },\n })\n : undefined;\n\n [triggerSlot, listboxSlot] = useComboboxPopup(props, triggerSlot, listboxSlot);\n [triggerSlot, listboxSlot] = useTriggerListboxSlots(props, baseState, ref, triggerSlot, listboxSlot);\n\n const state: DropdownState = {\n components: {\n root: 'div',\n button: 'button',\n expandIcon: 'span',\n listbox: Listbox,\n },\n root: resolveShorthand(props.root, {\n required: true,\n defaultProps: {\n 'aria-owns': !props.inlinePopup ? listboxSlot?.id : undefined,\n children: props.children,\n ...rootNativeProps,\n },\n }),\n button: triggerSlot,\n listbox: listboxSlot,\n expandIcon: resolveShorthand(props.expandIcon, {\n required: true,\n defaultProps: {\n children: <ChevronDownIcon />,\n },\n }),\n placeholderVisible: !baseState.value && !!props.placeholder,\n ...baseState,\n };\n\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n return state;\n};\n"]}
1
+ {"version":3,"mappings":"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","names":["useDropdown_unstable","props","ref","baseState","useComboboxBaseState_1","activeOption","getIndexOfId","getOptionsMatchingText","open","setActiveOption","setFocusVisible","setOpen","primary","triggerNativeProps","root","rootNativeProps","react_utilities_1","primarySlotTagName","excludedPropNames","rootRef","React","useRef","popupWidth","setPopupWidth","useState","useEffect","width","current","clientWidth","undefined","searchString","setKeyTimeout","clearKeyTimeout","getNextMatchingOption","matcher","optionText","toLowerCase","indexOf","matches","startIndex","id","length","letters","split","allSameLetter","every","letter","nextMatch","find","option","onTriggerKeyDown","ev","dropdownKeyActions_1","key","nextOption","triggerSlot","listboxSlot","button","required","defaultProps","type","children","value","placeholder","onKeyDown","hasFocus","listbox","style","useComboboxPopup_1","useTriggerListboxSlots_1","state","components","expandIcon","Listbox_1","inlinePopup","react_icons_1","placeholderVisible","react_utilities_2","exports"],"sourceRoot":"../src/","sources":["packages/react-components/react-combobox/src/components/Dropdown/useDropdown.tsx"],"sourcesContent":["import * as React from 'react';\nimport { ChevronDownRegular as ChevronDownIcon } from '@fluentui/react-icons';\nimport { getPartitionedNativeProps, mergeCallbacks, resolveShorthand, useTimeout } from '@fluentui/react-utilities';\nimport { getDropdownActionFromKey } from '../../utils/dropdownKeyActions';\nimport { useComboboxBaseState } from '../../utils/useComboboxBaseState';\nimport { useComboboxPopup } from '../../utils/useComboboxPopup';\nimport { useTriggerListboxSlots } from '../../utils/useTriggerListboxSlots';\nimport { Listbox } from '../Listbox/Listbox';\nimport type { Slot } from '@fluentui/react-utilities';\nimport type { OptionValue } from '../../utils/OptionCollection.types';\nimport type { DropdownProps, DropdownState } from './Dropdown.types';\nimport { useMergedRefs } from '@fluentui/react-utilities';\n\n/**\n * Create the state required to render Dropdown.\n *\n * The returned state can be modified with hooks such as useDropdownStyles_unstable,\n * before being passed to renderDropdown_unstable.\n *\n * @param props - props from this instance of Dropdown\n * @param ref - reference to root HTMLElement of Dropdown\n */\nexport const useDropdown_unstable = (props: DropdownProps, ref: React.Ref<HTMLButtonElement>): DropdownState => {\n const baseState = useComboboxBaseState(props);\n const {\n activeOption,\n getIndexOfId,\n getOptionsMatchingText,\n open,\n setActiveOption,\n setFocusVisible,\n setOpen,\n } = baseState;\n\n const { primary: triggerNativeProps, root: rootNativeProps } = getPartitionedNativeProps({\n props,\n primarySlotTagName: 'button',\n excludedPropNames: ['children'],\n });\n\n // set listbox popup width based off the root/trigger width\n const rootRef = React.useRef<HTMLDivElement>(null);\n const [popupWidth, setPopupWidth] = React.useState<string>();\n React.useEffect(() => {\n const width = open ? `${rootRef.current?.clientWidth}px` : undefined;\n setPopupWidth(width);\n }, [open]);\n\n // jump to matching option based on typing\n const searchString = React.useRef('');\n const [setKeyTimeout, clearKeyTimeout] = useTimeout();\n\n const getNextMatchingOption = (): OptionValue | undefined => {\n // first check for matches for the full searchString\n let matcher = (optionText: string) => optionText.toLowerCase().indexOf(searchString.current) === 0;\n let matches = getOptionsMatchingText(matcher);\n let startIndex = activeOption ? getIndexOfId(activeOption.id) : 0;\n\n // if the dropdown is already open and the searchstring is a single character,\n // then look after the current activeOption for letters\n // this is so slowly typing the same letter will cycle through matches\n if (open && searchString.current.length === 1) {\n startIndex++;\n }\n\n // if there are no direct matches, check if the search is all the same letter, e.g. \"aaa\"\n if (!matches.length) {\n const letters = searchString.current.split('');\n const allSameLetter = letters.length && letters.every(letter => letter === letters[0]);\n\n // if the search is all the same letter, cycle through options starting with that letter\n if (allSameLetter) {\n startIndex++;\n matcher = (optionText: string) => optionText.toLowerCase().indexOf(letters[0]) === 0;\n matches = getOptionsMatchingText(matcher);\n }\n }\n\n // if there is an active option and multiple matches,\n // return first matching option after the current active option, looping back to the top\n if (matches.length > 1 && activeOption) {\n const nextMatch = matches.find(option => getIndexOfId(option.id) >= startIndex);\n return nextMatch ?? matches[0];\n }\n\n return matches[0] ?? undefined;\n };\n\n const onTriggerKeyDown = (ev: React.KeyboardEvent<HTMLButtonElement>) => {\n // clear timeout, if it exists\n clearKeyTimeout();\n\n // if the key was a char key, update search string\n if (getDropdownActionFromKey(ev) === 'Type') {\n // update search string\n searchString.current += ev.key.toLowerCase();\n setKeyTimeout(() => {\n searchString.current = '';\n }, 500);\n\n // update state\n !open && setOpen(ev, true);\n\n const nextOption = getNextMatchingOption();\n setActiveOption(nextOption);\n setFocusVisible(true);\n }\n };\n\n // resolve button and listbox slot props\n let triggerSlot: Slot<'button'>;\n let listboxSlot: Slot<typeof Listbox> | undefined;\n\n triggerSlot = resolveShorthand(props.button, {\n required: true,\n defaultProps: {\n type: 'button',\n children: baseState.value || props.placeholder,\n ...triggerNativeProps,\n },\n });\n\n triggerSlot.onKeyDown = mergeCallbacks(onTriggerKeyDown, triggerSlot.onKeyDown);\n\n listboxSlot =\n baseState.open || baseState.hasFocus\n ? resolveShorthand(props.listbox, {\n required: true,\n defaultProps: {\n children: props.children,\n style: { width: popupWidth },\n },\n })\n : undefined;\n\n [triggerSlot, listboxSlot] = useComboboxPopup(props, triggerSlot, listboxSlot);\n [triggerSlot, listboxSlot] = useTriggerListboxSlots(props, baseState, ref, triggerSlot, listboxSlot);\n\n const state: DropdownState = {\n components: {\n root: 'div',\n button: 'button',\n expandIcon: 'span',\n listbox: Listbox,\n },\n root: resolveShorthand(props.root, {\n required: true,\n defaultProps: {\n 'aria-owns': !props.inlinePopup ? listboxSlot?.id : undefined,\n children: props.children,\n ...rootNativeProps,\n },\n }),\n button: triggerSlot,\n listbox: listboxSlot,\n expandIcon: resolveShorthand(props.expandIcon, {\n required: true,\n defaultProps: {\n children: <ChevronDownIcon />,\n },\n }),\n placeholderVisible: !baseState.value && !!props.placeholder,\n ...baseState,\n };\n\n state.root.ref = useMergedRefs(state.root.ref, rootRef);\n\n return state;\n};\n"]}
@@ -24,7 +24,7 @@ const useComboboxBaseState = props => {
24
24
  const optionCollection = useOptionCollection_1.useOptionCollection();
25
25
  const {
26
26
  getOptionAtIndex,
27
- getOptionsMatchingText
27
+ getOptionsMatchingValue
28
28
  } = optionCollection;
29
29
  const [activeOption, setActiveOption] = React.useState();
30
30
  // track whether keyboard focus outline should be shown
@@ -52,12 +52,19 @@ const useComboboxBaseState = props => {
52
52
  if (isFirstMount && props.defaultValue !== undefined) {
53
53
  return props.defaultValue;
54
54
  }
55
+ const selectedOptionsText = getOptionsMatchingValue(optionValue => {
56
+ return selectedOptions.includes(optionValue);
57
+ }).map(option => option.text);
55
58
  if (multiselect) {
56
59
  // editable inputs should not display multiple selected options in the input as text
57
- return editable ? '' : selectedOptions.join(', ');
60
+ return editable ? '' : selectedOptionsText.join(', ');
58
61
  }
59
- return selectedOptions[0];
60
- }, [controllableValue, editable, isFirstMount, multiselect, props.defaultValue, selectedOptions]);
62
+ return selectedOptionsText[0];
63
+ // do not change value after isFirstMount changes,
64
+ // we do not want to accidentally override defaultValue on a second render
65
+ // unless another value is intentionally set
66
+ // eslint-disable-next-line react-hooks/exhaustive-deps
67
+ }, [controllableValue, editable, getOptionsMatchingValue, multiselect, props.defaultValue, selectedOptions]);
61
68
  // Handle open state, which is shared with options in context
62
69
  const [open, setOpenState] = react_utilities_1.useControllableState({
63
70
  state: props.open,
@@ -75,7 +82,7 @@ const useComboboxBaseState = props => {
75
82
  if (open && !activeOption) {
76
83
  // if it is single-select and there is a selected option, start at the selected option
77
84
  if (!multiselect && selectedOptions.length > 0) {
78
- const selectedOption = getOptionsMatchingText(v => v === selectedOptions[0]).pop();
85
+ const selectedOption = getOptionsMatchingValue(v => v === selectedOptions[0]).pop();
79
86
  selectedOption && setActiveOption(selectedOption);
80
87
  }
81
88
  // default to starting at the first option