@react-stately/combobox 3.5.3-nightly.4042 → 3.5.3-nightly.4044

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/import.mjs CHANGED
@@ -196,28 +196,27 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
196
196
  closeMenu();
197
197
  }
198
198
  };
199
+ const commitValue = ()=>{
200
+ if (allowsCustomValue) {
201
+ var _collection_getItem;
202
+ var _collection_getItem_textValue;
203
+ const itemText = (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : "";
204
+ inputValue === itemText ? commitSelection() : commitCustomValue();
205
+ } else // Reset inputValue and close menu
206
+ commitSelection();
207
+ };
199
208
  let commit = ()=>{
200
209
  if (triggerState.isOpen && selectionManager.focusedKey != null) {
201
210
  // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise
202
211
  // fire onSelectionChange to allow the application to control the closing.
203
212
  if (selectedKey === selectionManager.focusedKey) commitSelection();
204
213
  else setSelectedKey(selectionManager.focusedKey);
205
- } else if (allowsCustomValue) commitCustomValue();
206
- else // Reset inputValue and close menu if no item is focused but user triggers a commit
207
- commitSelection();
208
- };
209
- let close = ()=>{
210
- var _collection_getItem;
211
- var _collection_getItem_textValue;
212
- let itemText = (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : "";
213
- if (allowsCustomValue && inputValue !== itemText) commitCustomValue();
214
- else commitSelection();
215
- closeMenu();
214
+ } else commitValue();
216
215
  };
217
216
  let setFocused = (isFocused)=>{
218
217
  if (isFocused) {
219
218
  if (menuTrigger === "focus") open(null, "focus");
220
- } else if (shouldCloseOnBlur) close();
219
+ } else if (shouldCloseOnBlur) commitValue();
221
220
  setFocusedState(isFocused);
222
221
  };
223
222
  let displayedCollection = (0, $k6Ppu$useMemo)(()=>{
@@ -236,7 +235,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
236
235
  ...triggerState,
237
236
  toggle: toggle,
238
237
  open: open,
239
- close: close,
238
+ close: commitValue,
240
239
  selectionManager: selectionManager,
241
240
  selectedKey: selectedKey,
242
241
  setSelectedKey: setSelectedKey,
package/dist/main.js CHANGED
@@ -201,28 +201,27 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
201
201
  closeMenu();
202
202
  }
203
203
  };
204
+ const commitValue = ()=>{
205
+ if (allowsCustomValue) {
206
+ var _collection_getItem;
207
+ var _collection_getItem_textValue;
208
+ const itemText = (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : "";
209
+ inputValue === itemText ? commitSelection() : commitCustomValue();
210
+ } else // Reset inputValue and close menu
211
+ commitSelection();
212
+ };
204
213
  let commit = ()=>{
205
214
  if (triggerState.isOpen && selectionManager.focusedKey != null) {
206
215
  // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise
207
216
  // fire onSelectionChange to allow the application to control the closing.
208
217
  if (selectedKey === selectionManager.focusedKey) commitSelection();
209
218
  else setSelectedKey(selectionManager.focusedKey);
210
- } else if (allowsCustomValue) commitCustomValue();
211
- else // Reset inputValue and close menu if no item is focused but user triggers a commit
212
- commitSelection();
213
- };
214
- let close = ()=>{
215
- var _collection_getItem;
216
- var _collection_getItem_textValue;
217
- let itemText = (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : "";
218
- if (allowsCustomValue && inputValue !== itemText) commitCustomValue();
219
- else commitSelection();
220
- closeMenu();
219
+ } else commitValue();
221
220
  };
222
221
  let setFocused = (isFocused)=>{
223
222
  if (isFocused) {
224
223
  if (menuTrigger === "focus") open(null, "focus");
225
- } else if (shouldCloseOnBlur) close();
224
+ } else if (shouldCloseOnBlur) commitValue();
226
225
  setFocusedState(isFocused);
227
226
  };
228
227
  let displayedCollection = (0, $5XAuq$react.useMemo)(()=>{
@@ -241,7 +240,7 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
241
240
  ...triggerState,
242
241
  toggle: toggle,
243
242
  open: open,
244
- close: close,
243
+ close: commitValue,
245
244
  selectionManager: selectionManager,
246
245
  selectedKey: selectedKey,
247
246
  setSelectedKey: setSelectedKey,
package/dist/main.js.map CHANGED
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-stately/combobox/src/index.ts","packages/@react-stately/combobox/src/useComboBoxState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useComboBoxState} from './useComboBoxState';\n\nexport type {ComboBoxStateOptions, ComboBoxState} from './useComboBoxState';\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionStateBase, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {getChildNodes} from '@react-stately/collections';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useControlledState} from '@react-stately/utils';\nimport {useMenuTriggerState} from '@react-stately/menu';\n\nexport interface ComboBoxState<T> extends SelectState<T> {\n /** The current value of the combo box input. */\n inputValue: string,\n /** Sets the value of the combo box input. */\n setInputValue(value: string): void,\n /** Selects the currently focused item and updates the input value. */\n commit(): void,\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Resets the input value to the previously selected item's text if any and closes the menu. */\n revert(): void\n}\n\ntype FilterFn = (textValue: string, inputValue: string) => boolean;\n\nexport interface ComboBoxStateOptions<T> extends Omit<ComboBoxProps<T>, 'children'>, CollectionStateBase<T> {\n /** The filter function used to determine if a option should be included in the combo box list. */\n defaultFilter?: FilterFn,\n /** Whether the combo box allows the menu to be open when the collection is empty. */\n allowsEmptyCollection?: boolean,\n /** Whether the combo box menu should close on blur. */\n shouldCloseOnBlur?: boolean\n}\n\n/**\n * Provides state management for a combo box component. Handles building a collection\n * of items from props and manages the option selection state of the combo box. In addition, it tracks the input value,\n * focus state, and other properties of the combo box.\n */\nexport function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T>): ComboBoxState<T> {\n let {\n defaultFilter,\n menuTrigger = 'input',\n allowsEmptyCollection = false,\n allowsCustomValue,\n shouldCloseOnBlur = true\n } = props;\n\n let [showAllItems, setShowAllItems] = useState(false);\n let [isFocused, setFocusedState] = useState(false);\n let [inputValue, setInputValue] = useControlledState(\n props.inputValue,\n props.defaultInputValue ?? '',\n props.onInputChange\n );\n\n let onSelectionChange = (key) => {\n if (props.onSelectionChange) {\n props.onSelectionChange(key);\n }\n\n // If key is the same, reset the inputValue and close the menu\n // (scenario: user clicks on already selected option)\n if (key === selectedKey) {\n resetInputValue();\n closeMenu();\n }\n };\n\n let {collection, selectionManager, selectedKey, setSelectedKey, selectedItem, disabledKeys} = useSingleSelectListState({\n ...props,\n onSelectionChange,\n items: props.items ?? props.defaultItems\n });\n\n // Preserve original collection so we can show all items on demand\n let originalCollection = collection;\n let filteredCollection = useMemo(() => (\n // No default filter if items are controlled.\n props.items != null || !defaultFilter\n ? collection\n : filterCollection(collection, inputValue, defaultFilter)\n ), [collection, inputValue, defaultFilter, props.items]);\n let [lastCollection, setLastCollection] = useState(filteredCollection);\n\n // Track what action is attempting to open the menu\n let menuOpenTrigger = useRef('focus' as MenuTriggerAction);\n let onOpenChange = (open: boolean) => {\n if (props.onOpenChange) {\n props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);\n }\n\n selectionManager.setFocused(open);\n if (!open) {\n selectionManager.setFocusedKey(null);\n }\n };\n\n let triggerState = useMenuTriggerState({...props, onOpenChange, isOpen: undefined, defaultOpen: undefined});\n let open = (focusStrategy?: FocusStrategy, trigger?: MenuTriggerAction) => {\n let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));\n // Prevent open operations from triggering if there is nothing to display\n // Also prevent open operations from triggering if items are uncontrolled but defaultItems is empty, even if displayAllItems is true.\n // This is to prevent comboboxes with empty defaultItems from opening but allow controlled items comboboxes to open even if the inital list is empty (assumption is user will provide swap the empty list with a base list via onOpenChange returning `menuTrigger` manual)\n if (allowsEmptyCollection || filteredCollection.size > 0 || (displayAllItems && originalCollection.size > 0) || props.items) {\n if (displayAllItems && !triggerState.isOpen && props.items === undefined) {\n // Show all items if menu is manually opened. Only care about this if items are undefined\n setShowAllItems(true);\n }\n\n menuOpenTrigger.current = trigger;\n triggerState.open(focusStrategy);\n }\n };\n\n let toggle = (focusStrategy?: FocusStrategy, trigger?: MenuTriggerAction) => {\n let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));\n // If the menu is closed and there is nothing to display, early return so toggle isn't called to prevent extraneous onOpenChange\n if (!(allowsEmptyCollection || filteredCollection.size > 0 || (displayAllItems && originalCollection.size > 0) || props.items) && !triggerState.isOpen) {\n return;\n }\n\n if (displayAllItems && !triggerState.isOpen && props.items === undefined) {\n // Show all items if menu is toggled open. Only care about this if items are undefined\n setShowAllItems(true);\n }\n\n // Only update the menuOpenTrigger if menu is currently closed\n if (!triggerState.isOpen) {\n menuOpenTrigger.current = trigger;\n }\n\n toggleMenu(focusStrategy);\n };\n\n // If menu is going to close, save the current collection so we can freeze the displayed collection when the\n // user clicks outside the popover to close the menu. Prevents the menu contents from updating as the menu closes.\n let toggleMenu = useCallback((focusStrategy) => {\n if (triggerState.isOpen) {\n setLastCollection(filteredCollection);\n }\n\n triggerState.toggle(focusStrategy);\n }, [triggerState, filteredCollection]);\n\n let closeMenu = useCallback(() => {\n if (triggerState.isOpen) {\n setLastCollection(filteredCollection);\n triggerState.close();\n }\n }, [triggerState, filteredCollection]);\n\n let lastValue = useRef(inputValue);\n let resetInputValue = () => {\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n lastValue.current = itemText;\n setInputValue(itemText);\n };\n\n let isInitialRender = useRef(true);\n let lastSelectedKey = useRef(props.selectedKey ?? props.defaultSelectedKey ?? null);\n let lastSelectedKeyText = useRef(collection.getItem(selectedKey)?.textValue ?? '');\n // intentional omit dependency array, want this to happen on every render\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => {\n // Open and close menu automatically when the input value changes if the input is focused,\n // and there are items in the collection or allowEmptyCollection is true.\n if (\n isFocused &&\n (filteredCollection.size > 0 || allowsEmptyCollection) &&\n !triggerState.isOpen &&\n inputValue !== lastValue.current &&\n menuTrigger !== 'manual'\n ) {\n open(null, 'input');\n }\n\n // Close the menu if the collection is empty. Don't close menu if filtered collection size is 0\n // but we are currently showing all items via button press\n if (\n !showAllItems &&\n !allowsEmptyCollection &&\n triggerState.isOpen &&\n filteredCollection.size === 0\n ) {\n closeMenu();\n }\n\n // Close when an item is selected.\n if (\n selectedKey != null &&\n selectedKey !== lastSelectedKey.current\n ) {\n closeMenu();\n }\n\n // Clear focused key when input value changes and display filtered collection again.\n if (inputValue !== lastValue.current) {\n selectionManager.setFocusedKey(null);\n setShowAllItems(false);\n\n // Set selectedKey to null when the user clears the input.\n // If controlled, this is the application developer's responsibility.\n if (inputValue === '' && (props.inputValue === undefined || props.selectedKey === undefined)) {\n setSelectedKey(null);\n }\n }\n\n // If it is the intial render and inputValue isn't controlled nor has an intial value, set input to match current selected key if any\n if (isInitialRender.current && (props.inputValue === undefined && props.defaultInputValue === undefined)) {\n resetInputValue();\n }\n\n // If the selectedKey changed, update the input value.\n // Do nothing if both inputValue and selectedKey are controlled.\n // In this case, it's the user's responsibility to update inputValue in onSelectionChange.\n if (\n selectedKey !== lastSelectedKey.current &&\n (props.inputValue === undefined || props.selectedKey === undefined)\n ) {\n resetInputValue();\n } else {\n lastValue.current = inputValue;\n }\n\n // Update the inputValue if the selected item's text changes from its last tracked value.\n // This is to handle cases where a selectedKey is specified but the items aren't available (async loading) or the selected item's text value updates.\n // Only reset if the user isn't currently within the field so we don't erroneously modify user input.\n // If inputValue is controlled, it is the user's responsibility to update the inputValue when items change.\n let selectedItemText = collection.getItem(selectedKey)?.textValue ?? '';\n if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {\n if (lastSelectedKeyText.current !== selectedItemText) {\n lastValue.current = selectedItemText;\n setInputValue(selectedItemText);\n }\n }\n\n isInitialRender.current = false;\n lastSelectedKey.current = selectedKey;\n lastSelectedKeyText.current = selectedItemText;\n });\n\n // Revert input value and close menu\n let revert = () => {\n if (allowsCustomValue && selectedKey == null) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n };\n\n let commitCustomValue = () => {\n lastSelectedKey.current = null;\n setSelectedKey(null);\n closeMenu();\n };\n\n let commitSelection = () => {\n // If multiple things are controlled, call onSelectionChange\n if (props.selectedKey !== undefined && props.inputValue !== undefined) {\n props.onSelectionChange(selectedKey);\n\n // Stop menu from reopening from useEffect\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n lastValue.current = itemText;\n closeMenu();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n closeMenu();\n }\n };\n\n let commit = () => {\n if (triggerState.isOpen && selectionManager.focusedKey != null) {\n // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise\n // fire onSelectionChange to allow the application to control the closing.\n if (selectedKey === selectionManager.focusedKey) {\n commitSelection();\n } else {\n setSelectedKey(selectionManager.focusedKey);\n }\n } else if (allowsCustomValue) {\n commitCustomValue();\n } else {\n // Reset inputValue and close menu if no item is focused but user triggers a commit\n commitSelection();\n }\n };\n\n let close = () => {\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n if (allowsCustomValue && inputValue !== itemText) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n closeMenu();\n };\n\n let setFocused = (isFocused: boolean) => {\n if (isFocused) {\n if (menuTrigger === 'focus') {\n open(null, 'focus');\n }\n } else if (shouldCloseOnBlur) {\n close();\n }\n\n setFocusedState(isFocused);\n };\n\n let displayedCollection = useMemo(() => {\n if (triggerState.isOpen) {\n if (showAllItems) {\n return originalCollection;\n } else {\n return filteredCollection;\n }\n } else {\n return lastCollection;\n }\n }, [triggerState.isOpen, originalCollection, filteredCollection, showAllItems, lastCollection]);\n\n return {\n ...triggerState,\n toggle,\n open,\n close,\n selectionManager,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: displayedCollection,\n inputValue,\n setInputValue,\n commit,\n revert\n };\n}\n\nfunction filterCollection<T extends object>(collection: Collection<Node<T>>, inputValue: string, filter: FilterFn): Collection<Node<T>> {\n return new ListCollection(filterNodes(collection, collection, inputValue, filter));\n}\n\nfunction filterNodes<T>(collection: Collection<Node<T>>, nodes: Iterable<Node<T>>, inputValue: string, filter: FilterFn): Iterable<Node<T>> {\n let filteredNode = [];\n for (let node of nodes) {\n if (node.type === 'section' && node.hasChildNodes) {\n let filtered = filterNodes(collection, getChildNodes(node, collection), inputValue, filter);\n if ([...filtered].some(node => node.type === 'item')) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type === 'item' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n } else if (node.type !== 'item') {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"main.js.map"}
1
+ {"mappings":"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","sources":["packages/@react-stately/combobox/src/index.ts","packages/@react-stately/combobox/src/useComboBoxState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useComboBoxState} from './useComboBoxState';\n\nexport type {ComboBoxStateOptions, ComboBoxState} from './useComboBoxState';\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionStateBase, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {getChildNodes} from '@react-stately/collections';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useControlledState} from '@react-stately/utils';\nimport {useMenuTriggerState} from '@react-stately/menu';\n\nexport interface ComboBoxState<T> extends SelectState<T> {\n /** The current value of the combo box input. */\n inputValue: string,\n /** Sets the value of the combo box input. */\n setInputValue(value: string): void,\n /** Selects the currently focused item and updates the input value. */\n commit(): void,\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Resets the input value to the previously selected item's text if any and closes the menu. */\n revert(): void\n}\n\ntype FilterFn = (textValue: string, inputValue: string) => boolean;\n\nexport interface ComboBoxStateOptions<T> extends Omit<ComboBoxProps<T>, 'children'>, CollectionStateBase<T> {\n /** The filter function used to determine if a option should be included in the combo box list. */\n defaultFilter?: FilterFn,\n /** Whether the combo box allows the menu to be open when the collection is empty. */\n allowsEmptyCollection?: boolean,\n /** Whether the combo box menu should close on blur. */\n shouldCloseOnBlur?: boolean\n}\n\n/**\n * Provides state management for a combo box component. Handles building a collection\n * of items from props and manages the option selection state of the combo box. In addition, it tracks the input value,\n * focus state, and other properties of the combo box.\n */\nexport function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T>): ComboBoxState<T> {\n let {\n defaultFilter,\n menuTrigger = 'input',\n allowsEmptyCollection = false,\n allowsCustomValue,\n shouldCloseOnBlur = true\n } = props;\n\n let [showAllItems, setShowAllItems] = useState(false);\n let [isFocused, setFocusedState] = useState(false);\n let [inputValue, setInputValue] = useControlledState(\n props.inputValue,\n props.defaultInputValue ?? '',\n props.onInputChange\n );\n\n let onSelectionChange = (key) => {\n if (props.onSelectionChange) {\n props.onSelectionChange(key);\n }\n\n // If key is the same, reset the inputValue and close the menu\n // (scenario: user clicks on already selected option)\n if (key === selectedKey) {\n resetInputValue();\n closeMenu();\n }\n };\n\n let {collection, selectionManager, selectedKey, setSelectedKey, selectedItem, disabledKeys} = useSingleSelectListState({\n ...props,\n onSelectionChange,\n items: props.items ?? props.defaultItems\n });\n\n // Preserve original collection so we can show all items on demand\n let originalCollection = collection;\n let filteredCollection = useMemo(() => (\n // No default filter if items are controlled.\n props.items != null || !defaultFilter\n ? collection\n : filterCollection(collection, inputValue, defaultFilter)\n ), [collection, inputValue, defaultFilter, props.items]);\n let [lastCollection, setLastCollection] = useState(filteredCollection);\n\n // Track what action is attempting to open the menu\n let menuOpenTrigger = useRef('focus' as MenuTriggerAction);\n let onOpenChange = (open: boolean) => {\n if (props.onOpenChange) {\n props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);\n }\n\n selectionManager.setFocused(open);\n if (!open) {\n selectionManager.setFocusedKey(null);\n }\n };\n\n let triggerState = useMenuTriggerState({...props, onOpenChange, isOpen: undefined, defaultOpen: undefined});\n let open = (focusStrategy?: FocusStrategy, trigger?: MenuTriggerAction) => {\n let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));\n // Prevent open operations from triggering if there is nothing to display\n // Also prevent open operations from triggering if items are uncontrolled but defaultItems is empty, even if displayAllItems is true.\n // This is to prevent comboboxes with empty defaultItems from opening but allow controlled items comboboxes to open even if the inital list is empty (assumption is user will provide swap the empty list with a base list via onOpenChange returning `menuTrigger` manual)\n if (allowsEmptyCollection || filteredCollection.size > 0 || (displayAllItems && originalCollection.size > 0) || props.items) {\n if (displayAllItems && !triggerState.isOpen && props.items === undefined) {\n // Show all items if menu is manually opened. Only care about this if items are undefined\n setShowAllItems(true);\n }\n\n menuOpenTrigger.current = trigger;\n triggerState.open(focusStrategy);\n }\n };\n\n let toggle = (focusStrategy?: FocusStrategy, trigger?: MenuTriggerAction) => {\n let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));\n // If the menu is closed and there is nothing to display, early return so toggle isn't called to prevent extraneous onOpenChange\n if (!(allowsEmptyCollection || filteredCollection.size > 0 || (displayAllItems && originalCollection.size > 0) || props.items) && !triggerState.isOpen) {\n return;\n }\n\n if (displayAllItems && !triggerState.isOpen && props.items === undefined) {\n // Show all items if menu is toggled open. Only care about this if items are undefined\n setShowAllItems(true);\n }\n\n // Only update the menuOpenTrigger if menu is currently closed\n if (!triggerState.isOpen) {\n menuOpenTrigger.current = trigger;\n }\n\n toggleMenu(focusStrategy);\n };\n\n // If menu is going to close, save the current collection so we can freeze the displayed collection when the\n // user clicks outside the popover to close the menu. Prevents the menu contents from updating as the menu closes.\n let toggleMenu = useCallback((focusStrategy) => {\n if (triggerState.isOpen) {\n setLastCollection(filteredCollection);\n }\n\n triggerState.toggle(focusStrategy);\n }, [triggerState, filteredCollection]);\n\n let closeMenu = useCallback(() => {\n if (triggerState.isOpen) {\n setLastCollection(filteredCollection);\n triggerState.close();\n }\n }, [triggerState, filteredCollection]);\n\n let lastValue = useRef(inputValue);\n let resetInputValue = () => {\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n lastValue.current = itemText;\n setInputValue(itemText);\n };\n\n let isInitialRender = useRef(true);\n let lastSelectedKey = useRef(props.selectedKey ?? props.defaultSelectedKey ?? null);\n let lastSelectedKeyText = useRef(collection.getItem(selectedKey)?.textValue ?? '');\n // intentional omit dependency array, want this to happen on every render\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => {\n // Open and close menu automatically when the input value changes if the input is focused,\n // and there are items in the collection or allowEmptyCollection is true.\n if (\n isFocused &&\n (filteredCollection.size > 0 || allowsEmptyCollection) &&\n !triggerState.isOpen &&\n inputValue !== lastValue.current &&\n menuTrigger !== 'manual'\n ) {\n open(null, 'input');\n }\n\n // Close the menu if the collection is empty. Don't close menu if filtered collection size is 0\n // but we are currently showing all items via button press\n if (\n !showAllItems &&\n !allowsEmptyCollection &&\n triggerState.isOpen &&\n filteredCollection.size === 0\n ) {\n closeMenu();\n }\n\n // Close when an item is selected.\n if (\n selectedKey != null &&\n selectedKey !== lastSelectedKey.current\n ) {\n closeMenu();\n }\n\n // Clear focused key when input value changes and display filtered collection again.\n if (inputValue !== lastValue.current) {\n selectionManager.setFocusedKey(null);\n setShowAllItems(false);\n\n // Set selectedKey to null when the user clears the input.\n // If controlled, this is the application developer's responsibility.\n if (inputValue === '' && (props.inputValue === undefined || props.selectedKey === undefined)) {\n setSelectedKey(null);\n }\n }\n\n // If it is the intial render and inputValue isn't controlled nor has an intial value, set input to match current selected key if any\n if (isInitialRender.current && (props.inputValue === undefined && props.defaultInputValue === undefined)) {\n resetInputValue();\n }\n\n // If the selectedKey changed, update the input value.\n // Do nothing if both inputValue and selectedKey are controlled.\n // In this case, it's the user's responsibility to update inputValue in onSelectionChange.\n if (\n selectedKey !== lastSelectedKey.current &&\n (props.inputValue === undefined || props.selectedKey === undefined)\n ) {\n resetInputValue();\n } else {\n lastValue.current = inputValue;\n }\n\n // Update the inputValue if the selected item's text changes from its last tracked value.\n // This is to handle cases where a selectedKey is specified but the items aren't available (async loading) or the selected item's text value updates.\n // Only reset if the user isn't currently within the field so we don't erroneously modify user input.\n // If inputValue is controlled, it is the user's responsibility to update the inputValue when items change.\n let selectedItemText = collection.getItem(selectedKey)?.textValue ?? '';\n if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {\n if (lastSelectedKeyText.current !== selectedItemText) {\n lastValue.current = selectedItemText;\n setInputValue(selectedItemText);\n }\n }\n\n isInitialRender.current = false;\n lastSelectedKey.current = selectedKey;\n lastSelectedKeyText.current = selectedItemText;\n });\n\n // Revert input value and close menu\n let revert = () => {\n if (allowsCustomValue && selectedKey == null) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n };\n\n let commitCustomValue = () => {\n lastSelectedKey.current = null;\n setSelectedKey(null);\n closeMenu();\n };\n\n let commitSelection = () => {\n // If multiple things are controlled, call onSelectionChange\n if (props.selectedKey !== undefined && props.inputValue !== undefined) {\n props.onSelectionChange(selectedKey);\n\n // Stop menu from reopening from useEffect\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n lastValue.current = itemText;\n closeMenu();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n closeMenu();\n }\n };\n\n const commitValue = () => {\n if (allowsCustomValue) {\n const itemText = collection.getItem(selectedKey)?.textValue ?? '';\n (inputValue === itemText) ? commitSelection() : commitCustomValue();\n } else {\n // Reset inputValue and close menu\n commitSelection();\n }\n };\n\n let commit = () => {\n if (triggerState.isOpen && selectionManager.focusedKey != null) {\n // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise\n // fire onSelectionChange to allow the application to control the closing.\n if (selectedKey === selectionManager.focusedKey) {\n commitSelection();\n } else {\n setSelectedKey(selectionManager.focusedKey);\n }\n } else {\n commitValue();\n }\n };\n\n let setFocused = (isFocused: boolean) => {\n if (isFocused) {\n if (menuTrigger === 'focus') {\n open(null, 'focus');\n }\n } else if (shouldCloseOnBlur) {\n commitValue();\n }\n\n setFocusedState(isFocused);\n };\n\n let displayedCollection = useMemo(() => {\n if (triggerState.isOpen) {\n if (showAllItems) {\n return originalCollection;\n } else {\n return filteredCollection;\n }\n } else {\n return lastCollection;\n }\n }, [triggerState.isOpen, originalCollection, filteredCollection, showAllItems, lastCollection]);\n\n return {\n ...triggerState,\n toggle,\n open,\n close: commitValue,\n selectionManager,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: displayedCollection,\n inputValue,\n setInputValue,\n commit,\n revert\n };\n}\n\nfunction filterCollection<T extends object>(collection: Collection<Node<T>>, inputValue: string, filter: FilterFn): Collection<Node<T>> {\n return new ListCollection(filterNodes(collection, collection, inputValue, filter));\n}\n\nfunction filterNodes<T>(collection: Collection<Node<T>>, nodes: Iterable<Node<T>>, inputValue: string, filter: FilterFn): Iterable<Node<T>> {\n let filteredNode = [];\n for (let node of nodes) {\n if (node.type === 'section' && node.hasChildNodes) {\n let filtered = filterNodes(collection, getChildNodes(node, collection), inputValue, filter);\n if ([...filtered].some(node => node.type === 'item')) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type === 'item' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n } else if (node.type !== 'item') {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"main.js.map"}
package/dist/module.js CHANGED
@@ -196,28 +196,27 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
196
196
  closeMenu();
197
197
  }
198
198
  };
199
+ const commitValue = ()=>{
200
+ if (allowsCustomValue) {
201
+ var _collection_getItem;
202
+ var _collection_getItem_textValue;
203
+ const itemText = (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : "";
204
+ inputValue === itemText ? commitSelection() : commitCustomValue();
205
+ } else // Reset inputValue and close menu
206
+ commitSelection();
207
+ };
199
208
  let commit = ()=>{
200
209
  if (triggerState.isOpen && selectionManager.focusedKey != null) {
201
210
  // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise
202
211
  // fire onSelectionChange to allow the application to control the closing.
203
212
  if (selectedKey === selectionManager.focusedKey) commitSelection();
204
213
  else setSelectedKey(selectionManager.focusedKey);
205
- } else if (allowsCustomValue) commitCustomValue();
206
- else // Reset inputValue and close menu if no item is focused but user triggers a commit
207
- commitSelection();
208
- };
209
- let close = ()=>{
210
- var _collection_getItem;
211
- var _collection_getItem_textValue;
212
- let itemText = (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : "";
213
- if (allowsCustomValue && inputValue !== itemText) commitCustomValue();
214
- else commitSelection();
215
- closeMenu();
214
+ } else commitValue();
216
215
  };
217
216
  let setFocused = (isFocused)=>{
218
217
  if (isFocused) {
219
218
  if (menuTrigger === "focus") open(null, "focus");
220
- } else if (shouldCloseOnBlur) close();
219
+ } else if (shouldCloseOnBlur) commitValue();
221
220
  setFocusedState(isFocused);
222
221
  };
223
222
  let displayedCollection = (0, $k6Ppu$useMemo)(()=>{
@@ -236,7 +235,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
236
235
  ...triggerState,
237
236
  toggle: toggle,
238
237
  open: open,
239
- close: close,
238
+ close: commitValue,
240
239
  selectionManager: selectionManager,
241
240
  selectedKey: selectedKey,
242
241
  setSelectedKey: setSelectedKey,
@@ -1 +1 @@
1
- {"mappings":"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","sources":["packages/@react-stately/combobox/src/index.ts","packages/@react-stately/combobox/src/useComboBoxState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useComboBoxState} from './useComboBoxState';\n\nexport type {ComboBoxStateOptions, ComboBoxState} from './useComboBoxState';\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionStateBase, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {getChildNodes} from '@react-stately/collections';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useControlledState} from '@react-stately/utils';\nimport {useMenuTriggerState} from '@react-stately/menu';\n\nexport interface ComboBoxState<T> extends SelectState<T> {\n /** The current value of the combo box input. */\n inputValue: string,\n /** Sets the value of the combo box input. */\n setInputValue(value: string): void,\n /** Selects the currently focused item and updates the input value. */\n commit(): void,\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Resets the input value to the previously selected item's text if any and closes the menu. */\n revert(): void\n}\n\ntype FilterFn = (textValue: string, inputValue: string) => boolean;\n\nexport interface ComboBoxStateOptions<T> extends Omit<ComboBoxProps<T>, 'children'>, CollectionStateBase<T> {\n /** The filter function used to determine if a option should be included in the combo box list. */\n defaultFilter?: FilterFn,\n /** Whether the combo box allows the menu to be open when the collection is empty. */\n allowsEmptyCollection?: boolean,\n /** Whether the combo box menu should close on blur. */\n shouldCloseOnBlur?: boolean\n}\n\n/**\n * Provides state management for a combo box component. Handles building a collection\n * of items from props and manages the option selection state of the combo box. In addition, it tracks the input value,\n * focus state, and other properties of the combo box.\n */\nexport function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T>): ComboBoxState<T> {\n let {\n defaultFilter,\n menuTrigger = 'input',\n allowsEmptyCollection = false,\n allowsCustomValue,\n shouldCloseOnBlur = true\n } = props;\n\n let [showAllItems, setShowAllItems] = useState(false);\n let [isFocused, setFocusedState] = useState(false);\n let [inputValue, setInputValue] = useControlledState(\n props.inputValue,\n props.defaultInputValue ?? '',\n props.onInputChange\n );\n\n let onSelectionChange = (key) => {\n if (props.onSelectionChange) {\n props.onSelectionChange(key);\n }\n\n // If key is the same, reset the inputValue and close the menu\n // (scenario: user clicks on already selected option)\n if (key === selectedKey) {\n resetInputValue();\n closeMenu();\n }\n };\n\n let {collection, selectionManager, selectedKey, setSelectedKey, selectedItem, disabledKeys} = useSingleSelectListState({\n ...props,\n onSelectionChange,\n items: props.items ?? props.defaultItems\n });\n\n // Preserve original collection so we can show all items on demand\n let originalCollection = collection;\n let filteredCollection = useMemo(() => (\n // No default filter if items are controlled.\n props.items != null || !defaultFilter\n ? collection\n : filterCollection(collection, inputValue, defaultFilter)\n ), [collection, inputValue, defaultFilter, props.items]);\n let [lastCollection, setLastCollection] = useState(filteredCollection);\n\n // Track what action is attempting to open the menu\n let menuOpenTrigger = useRef('focus' as MenuTriggerAction);\n let onOpenChange = (open: boolean) => {\n if (props.onOpenChange) {\n props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);\n }\n\n selectionManager.setFocused(open);\n if (!open) {\n selectionManager.setFocusedKey(null);\n }\n };\n\n let triggerState = useMenuTriggerState({...props, onOpenChange, isOpen: undefined, defaultOpen: undefined});\n let open = (focusStrategy?: FocusStrategy, trigger?: MenuTriggerAction) => {\n let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));\n // Prevent open operations from triggering if there is nothing to display\n // Also prevent open operations from triggering if items are uncontrolled but defaultItems is empty, even if displayAllItems is true.\n // This is to prevent comboboxes with empty defaultItems from opening but allow controlled items comboboxes to open even if the inital list is empty (assumption is user will provide swap the empty list with a base list via onOpenChange returning `menuTrigger` manual)\n if (allowsEmptyCollection || filteredCollection.size > 0 || (displayAllItems && originalCollection.size > 0) || props.items) {\n if (displayAllItems && !triggerState.isOpen && props.items === undefined) {\n // Show all items if menu is manually opened. Only care about this if items are undefined\n setShowAllItems(true);\n }\n\n menuOpenTrigger.current = trigger;\n triggerState.open(focusStrategy);\n }\n };\n\n let toggle = (focusStrategy?: FocusStrategy, trigger?: MenuTriggerAction) => {\n let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));\n // If the menu is closed and there is nothing to display, early return so toggle isn't called to prevent extraneous onOpenChange\n if (!(allowsEmptyCollection || filteredCollection.size > 0 || (displayAllItems && originalCollection.size > 0) || props.items) && !triggerState.isOpen) {\n return;\n }\n\n if (displayAllItems && !triggerState.isOpen && props.items === undefined) {\n // Show all items if menu is toggled open. Only care about this if items are undefined\n setShowAllItems(true);\n }\n\n // Only update the menuOpenTrigger if menu is currently closed\n if (!triggerState.isOpen) {\n menuOpenTrigger.current = trigger;\n }\n\n toggleMenu(focusStrategy);\n };\n\n // If menu is going to close, save the current collection so we can freeze the displayed collection when the\n // user clicks outside the popover to close the menu. Prevents the menu contents from updating as the menu closes.\n let toggleMenu = useCallback((focusStrategy) => {\n if (triggerState.isOpen) {\n setLastCollection(filteredCollection);\n }\n\n triggerState.toggle(focusStrategy);\n }, [triggerState, filteredCollection]);\n\n let closeMenu = useCallback(() => {\n if (triggerState.isOpen) {\n setLastCollection(filteredCollection);\n triggerState.close();\n }\n }, [triggerState, filteredCollection]);\n\n let lastValue = useRef(inputValue);\n let resetInputValue = () => {\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n lastValue.current = itemText;\n setInputValue(itemText);\n };\n\n let isInitialRender = useRef(true);\n let lastSelectedKey = useRef(props.selectedKey ?? props.defaultSelectedKey ?? null);\n let lastSelectedKeyText = useRef(collection.getItem(selectedKey)?.textValue ?? '');\n // intentional omit dependency array, want this to happen on every render\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => {\n // Open and close menu automatically when the input value changes if the input is focused,\n // and there are items in the collection or allowEmptyCollection is true.\n if (\n isFocused &&\n (filteredCollection.size > 0 || allowsEmptyCollection) &&\n !triggerState.isOpen &&\n inputValue !== lastValue.current &&\n menuTrigger !== 'manual'\n ) {\n open(null, 'input');\n }\n\n // Close the menu if the collection is empty. Don't close menu if filtered collection size is 0\n // but we are currently showing all items via button press\n if (\n !showAllItems &&\n !allowsEmptyCollection &&\n triggerState.isOpen &&\n filteredCollection.size === 0\n ) {\n closeMenu();\n }\n\n // Close when an item is selected.\n if (\n selectedKey != null &&\n selectedKey !== lastSelectedKey.current\n ) {\n closeMenu();\n }\n\n // Clear focused key when input value changes and display filtered collection again.\n if (inputValue !== lastValue.current) {\n selectionManager.setFocusedKey(null);\n setShowAllItems(false);\n\n // Set selectedKey to null when the user clears the input.\n // If controlled, this is the application developer's responsibility.\n if (inputValue === '' && (props.inputValue === undefined || props.selectedKey === undefined)) {\n setSelectedKey(null);\n }\n }\n\n // If it is the intial render and inputValue isn't controlled nor has an intial value, set input to match current selected key if any\n if (isInitialRender.current && (props.inputValue === undefined && props.defaultInputValue === undefined)) {\n resetInputValue();\n }\n\n // If the selectedKey changed, update the input value.\n // Do nothing if both inputValue and selectedKey are controlled.\n // In this case, it's the user's responsibility to update inputValue in onSelectionChange.\n if (\n selectedKey !== lastSelectedKey.current &&\n (props.inputValue === undefined || props.selectedKey === undefined)\n ) {\n resetInputValue();\n } else {\n lastValue.current = inputValue;\n }\n\n // Update the inputValue if the selected item's text changes from its last tracked value.\n // This is to handle cases where a selectedKey is specified but the items aren't available (async loading) or the selected item's text value updates.\n // Only reset if the user isn't currently within the field so we don't erroneously modify user input.\n // If inputValue is controlled, it is the user's responsibility to update the inputValue when items change.\n let selectedItemText = collection.getItem(selectedKey)?.textValue ?? '';\n if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {\n if (lastSelectedKeyText.current !== selectedItemText) {\n lastValue.current = selectedItemText;\n setInputValue(selectedItemText);\n }\n }\n\n isInitialRender.current = false;\n lastSelectedKey.current = selectedKey;\n lastSelectedKeyText.current = selectedItemText;\n });\n\n // Revert input value and close menu\n let revert = () => {\n if (allowsCustomValue && selectedKey == null) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n };\n\n let commitCustomValue = () => {\n lastSelectedKey.current = null;\n setSelectedKey(null);\n closeMenu();\n };\n\n let commitSelection = () => {\n // If multiple things are controlled, call onSelectionChange\n if (props.selectedKey !== undefined && props.inputValue !== undefined) {\n props.onSelectionChange(selectedKey);\n\n // Stop menu from reopening from useEffect\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n lastValue.current = itemText;\n closeMenu();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n closeMenu();\n }\n };\n\n let commit = () => {\n if (triggerState.isOpen && selectionManager.focusedKey != null) {\n // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise\n // fire onSelectionChange to allow the application to control the closing.\n if (selectedKey === selectionManager.focusedKey) {\n commitSelection();\n } else {\n setSelectedKey(selectionManager.focusedKey);\n }\n } else if (allowsCustomValue) {\n commitCustomValue();\n } else {\n // Reset inputValue and close menu if no item is focused but user triggers a commit\n commitSelection();\n }\n };\n\n let close = () => {\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n if (allowsCustomValue && inputValue !== itemText) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n closeMenu();\n };\n\n let setFocused = (isFocused: boolean) => {\n if (isFocused) {\n if (menuTrigger === 'focus') {\n open(null, 'focus');\n }\n } else if (shouldCloseOnBlur) {\n close();\n }\n\n setFocusedState(isFocused);\n };\n\n let displayedCollection = useMemo(() => {\n if (triggerState.isOpen) {\n if (showAllItems) {\n return originalCollection;\n } else {\n return filteredCollection;\n }\n } else {\n return lastCollection;\n }\n }, [triggerState.isOpen, originalCollection, filteredCollection, showAllItems, lastCollection]);\n\n return {\n ...triggerState,\n toggle,\n open,\n close,\n selectionManager,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: displayedCollection,\n inputValue,\n setInputValue,\n commit,\n revert\n };\n}\n\nfunction filterCollection<T extends object>(collection: Collection<Node<T>>, inputValue: string, filter: FilterFn): Collection<Node<T>> {\n return new ListCollection(filterNodes(collection, collection, inputValue, filter));\n}\n\nfunction filterNodes<T>(collection: Collection<Node<T>>, nodes: Iterable<Node<T>>, inputValue: string, filter: FilterFn): Iterable<Node<T>> {\n let filteredNode = [];\n for (let node of nodes) {\n if (node.type === 'section' && node.hasChildNodes) {\n let filtered = filterNodes(collection, getChildNodes(node, collection), inputValue, filter);\n if ([...filtered].some(node => node.type === 'item')) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type === 'item' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n } else if (node.type !== 'item') {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"module.js.map"}
1
+ {"mappings":";;;;;;AAAA;;;;;;;;;;ACAA;;;;;;;;;;CAUC;;;;;AA0CM,SAAS,0CAAmC,KAA8B;QA0H9C;IAzHjC,IAAI,iBACF,cAAa,eACb,cAAc,iCACd,wBAAwB,2BACxB,kBAAiB,qBACjB,oBAAoB,OACrB,GAAG;IAEJ,IAAI,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,eAAO,EAAE;IAC/C,IAAI,CAAC,WAAW,gBAAgB,GAAG,CAAA,GAAA,eAAO,EAAE;QAG1C;IAFF,IAAI,CAAC,YAAY,cAAc,GAAG,CAAA,GAAA,yBAAiB,EACjD,MAAM,YACN,CAAA,2BAAA,MAAM,+BAAN,sCAAA,2BAA2B,IAC3B,MAAM;IAGR,IAAI,oBAAoB,CAAC;QACvB,IAAI,MAAM,mBACR,MAAM,kBAAkB;QAG1B,8DAA8D;QAC9D,qDAAqD;QACrD,IAAI,QAAQ,aAAa;YACvB;YACA;QACF;IACF;QAKS;IAHT,IAAI,cAAC,WAAU,oBAAE,iBAAgB,eAAE,YAAW,kBAAE,eAAc,gBAAE,aAAY,gBAAE,aAAY,EAAC,GAAG,CAAA,GAAA,+BAAuB,EAAE;QACrH,GAAG,KAAK;2BACR;QACA,OAAO,CAAA,eAAA,MAAM,mBAAN,0BAAA,eAAe,MAAM;IAC9B;IAEA,kEAAkE;IAClE,IAAI,qBAAqB;IACzB,IAAI,qBAAqB,CAAA,GAAA,cAAM,EAAE,IAC/B,6CAA6C;QAC7C,MAAM,SAAS,QAAQ,CAAC,gBACpB,aACA,uCAAiB,YAAY,YAAY,gBAC5C;QAAC;QAAY;QAAY;QAAe,MAAM;KAAM;IACvD,IAAI,CAAC,gBAAgB,kBAAkB,GAAG,CAAA,GAAA,eAAO,EAAE;IAEnD,mDAAmD;IACnD,IAAI,kBAAkB,CAAA,GAAA,aAAK,EAAE;IAC7B,IAAI,eAAe,CAAC;QAClB,IAAI,MAAM,cACR,MAAM,aAAa,MAAM,OAAO,gBAAgB,UAAU;QAG5D,iBAAiB,WAAW;QAC5B,IAAI,CAAC,MACH,iBAAiB,cAAc;IAEnC;IAEA,IAAI,eAAe,CAAA,GAAA,0BAAkB,EAAE;QAAC,GAAG,KAAK;sBAAE;QAAc,QAAQ;QAAW,aAAa;IAAS;IACzG,IAAI,OAAO,CAAC,eAA+B;QACzC,IAAI,kBAAmB,YAAY,YAAa,YAAY,WAAW,gBAAgB;QACvF,yEAAyE;QACzE,qIAAqI;QACrI,2QAA2Q;QAC3Q,IAAI,yBAAyB,mBAAmB,OAAO,KAAM,mBAAmB,mBAAmB,OAAO,KAAM,MAAM,OAAO;YAC3H,IAAI,mBAAmB,CAAC,aAAa,UAAU,MAAM,UAAU,WAC7D,yFAAyF;YACzF,gBAAgB;YAGlB,gBAAgB,UAAU;YAC1B,aAAa,KAAK;QACpB;IACF;IAEA,IAAI,SAAS,CAAC,eAA+B;QAC3C,IAAI,kBAAmB,YAAY,YAAa,YAAY,WAAW,gBAAgB;QACvF,gIAAgI;QAChI,IAAI,CAAE,CAAA,yBAAyB,mBAAmB,OAAO,KAAM,mBAAmB,mBAAmB,OAAO,KAAM,MAAM,KAAI,KAAM,CAAC,aAAa,QAC9I;QAGF,IAAI,mBAAmB,CAAC,aAAa,UAAU,MAAM,UAAU,WAC7D,sFAAsF;QACtF,gBAAgB;QAGlB,8DAA8D;QAC9D,IAAI,CAAC,aAAa,QAChB,gBAAgB,UAAU;QAG5B,WAAW;IACb;IAEA,4GAA4G;IAC5G,kHAAkH;IAClH,IAAI,aAAa,CAAA,GAAA,kBAAU,EAAE,CAAC;QAC5B,IAAI,aAAa,QACf,kBAAkB;QAGpB,aAAa,OAAO;IACtB,GAAG;QAAC;QAAc;KAAmB;IAErC,IAAI,YAAY,CAAA,GAAA,kBAAU,EAAE;QAC1B,IAAI,aAAa,QAAQ;YACvB,kBAAkB;YAClB,aAAa;QACf;IACF,GAAG;QAAC;QAAc;KAAmB;IAErC,IAAI,YAAY,CAAA,GAAA,aAAK,EAAE;IACvB,IAAI,kBAAkB;YACL;YAAA;QAAf,IAAI,WAAW,CAAA,gCAAA,CAAA,sBAAA,WAAW,QAAQ,0BAAnB,iCAAA,KAAA,IAAA,oBAAiC,uBAAjC,2CAAA,gCAA8C;QAC7D,UAAU,UAAU;QACpB,cAAc;IAChB;IAEA,IAAI,kBAAkB,CAAA,GAAA,aAAK,EAAE;QACA,oBAAA;IAA7B,IAAI,kBAAkB,CAAA,GAAA,aAAK,EAAE,CAAA,OAAA,CAAA,qBAAA,MAAM,yBAAN,gCAAA,qBAAqB,MAAM,gCAA3B,kBAAA,OAAiD;QAC7C;IAAjC,IAAI,sBAAsB,CAAA,GAAA,aAAK,EAAE,CAAA,gCAAA,CAAA,sBAAA,WAAW,QAAQ,0BAAnB,iCAAA,KAAA,IAAA,oBAAiC,uBAAjC,2CAAA,gCAA8C;IAC/E,yEAAyE;IACzE,uDAAuD;IACvD,CAAA,GAAA,gBAAQ,EAAE;YAiEe;QAhEvB,0FAA0F;QAC1F,yEAAyE;QACzE,IACE,aACC,CAAA,mBAAmB,OAAO,KAAK,qBAAoB,KACpD,CAAC,aAAa,UACd,eAAe,UAAU,WACzB,gBAAgB,UAEhB,KAAK,MAAM;QAGb,+FAA+F;QAC/F,0DAA0D;QAC1D,IACE,CAAC,gBACD,CAAC,yBACD,aAAa,UACb,mBAAmB,SAAS,GAE5B;QAGF,kCAAkC;QAClC,IACE,eAAe,QACf,gBAAgB,gBAAgB,SAEhC;QAGF,oFAAoF;QACpF,IAAI,eAAe,UAAU,SAAS;YACpC,iBAAiB,cAAc;YAC/B,gBAAgB;YAEhB,0DAA0D;YAC1D,qEAAqE;YACrE,IAAI,eAAe,MAAO,CAAA,MAAM,eAAe,aAAa,MAAM,gBAAgB,SAAQ,GACxF,eAAe;QAEnB;QAEA,qIAAqI;QACrI,IAAI,gBAAgB,WAAY,MAAM,eAAe,aAAa,MAAM,sBAAsB,WAC5F;QAGF,sDAAsD;QACtD,gEAAgE;QAChE,0FAA0F;QAC1F,IACE,gBAAgB,gBAAgB,WAC/B,CAAA,MAAM,eAAe,aAAa,MAAM,gBAAgB,SAAQ,GAEjE;aAEA,UAAU,UAAU;YAOC;QAJvB,yFAAyF;QACzF,qJAAqJ;QACrJ,qGAAqG;QACrG,2GAA2G;QAC3G,IAAI,mBAAmB,CAAA,gCAAA,CAAA,sBAAA,WAAW,QAAQ,0BAAnB,iCAAA,KAAA,IAAA,oBAAiC,uBAAjC,2CAAA,gCAA8C;QACrE,IAAI,CAAC,aAAa,eAAe,QAAQ,MAAM,eAAe,aAAa,gBAAgB,gBAAgB,SACzG;YAAA,IAAI,oBAAoB,YAAY,kBAAkB;gBACpD,UAAU,UAAU;gBACpB,cAAc;YAChB;QAAA;QAGF,gBAAgB,UAAU;QAC1B,gBAAgB,UAAU;QAC1B,oBAAoB,UAAU;IAChC;IAEA,oCAAoC;IACpC,IAAI,SAAS;QACX,IAAI,qBAAqB,eAAe,MACtC;aAEA;IAEJ;IAEA,IAAI,oBAAoB;QACtB,gBAAgB,UAAU;QAC1B,eAAe;QACf;IACF;IAEA,IAAI,kBAAkB;QACpB,4DAA4D;QAC5D,IAAI,MAAM,gBAAgB,aAAa,MAAM,eAAe,WAAW;gBAItD;YAHf,MAAM,kBAAkB;gBAGT;YADf,0CAA0C;YAC1C,IAAI,WAAW,CAAA,gCAAA,CAAA,sBAAA,WAAW,QAAQ,0BAAnB,iCAAA,KAAA,IAAA,oBAAiC,uBAAjC,2CAAA,gCAA8C;YAC7D,UAAU,UAAU;YACpB;QACF,OAAO;YACL,mGAAmG;YACnG;YACA;QACF;IACF;IAEA,MAAM,cAAc;QAClB,IAAI,mBAAmB;gBACJ;gBAAA;YAAjB,MAAM,WAAW,CAAA,gCAAA,CAAA,sBAAA,WAAW,QAAQ,0BAAnB,iCAAA,KAAA,IAAA,oBAAiC,uBAAjC,2CAAA,gCAA8C;YAC9D,eAAe,WAAY,oBAAoB;QAClD,OACE,kCAAkC;QAClC;IAEJ;IAEA,IAAI,SAAS;QACX,IAAI,aAAa,UAAU,iBAAiB,cAAc;YACxD,iGAAiG;YACjG,0EAA0E;YAC1E,IAAI,gBAAgB,iBAAiB,YACnC;iBAEA,eAAe,iBAAiB;eAGlC;IAEJ;IAEA,IAAI,aAAa,CAAC;QAChB,IAAI,WACF;YAAA,IAAI,gBAAgB,SAClB,KAAK,MAAM;QACb,OACK,IAAI,mBACT;QAGF,gBAAgB;IAClB;IAEA,IAAI,sBAAsB,CAAA,GAAA,cAAM,EAAE;QAChC,IAAI,aAAa,QAAQ;YACvB,IAAI,cACF,OAAO;iBAEP,OAAO;QAEX,OACE,OAAO;IAEX,GAAG;QAAC,aAAa;QAAQ;QAAoB;QAAoB;QAAc;KAAe;IAE9F,OAAO;QACL,GAAG,YAAY;gBACf;cACA;QACA,OAAO;0BACP;qBACA;wBACA;sBACA;mBACA;oBACA;sBACA;QACA,YAAY;oBACZ;uBACA;gBACA;gBACA;IACF;AACF;AAEA,SAAS,uCAAmC,UAA+B,EAAE,UAAkB,EAAE,MAAgB;IAC/G,OAAO,IAAI,CAAA,GAAA,qBAAa,EAAE,kCAAY,YAAY,YAAY,YAAY;AAC5E;AAEA,SAAS,kCAAe,UAA+B,EAAE,KAAwB,EAAE,UAAkB,EAAE,MAAgB;IACrH,IAAI,eAAe,EAAE;IACrB,KAAK,IAAI,QAAQ,MAAO;QACtB,IAAI,KAAK,SAAS,aAAa,KAAK,eAAe;YACjD,IAAI,WAAW,kCAAY,YAAY,CAAA,GAAA,oBAAY,EAAE,MAAM,aAAa,YAAY;YACpF,IAAI;mBAAI;aAAS,CAAC,KAAK,CAAA,OAAQ,KAAK,SAAS,SAC3C,aAAa,KAAK;gBAAC,GAAG,IAAI;gBAAE,YAAY;YAAQ;QAEpD,OAAO,IAAI,KAAK,SAAS,UAAU,OAAO,KAAK,WAAW,aACxD,aAAa,KAAK;YAAC,GAAG,IAAI;QAAA;aACrB,IAAI,KAAK,SAAS,QACvB,aAAa,KAAK;YAAC,GAAG,IAAI;QAAA;IAE9B;IACA,OAAO;AACT;;CD3WC","sources":["packages/@react-stately/combobox/src/index.ts","packages/@react-stately/combobox/src/useComboBoxState.ts"],"sourcesContent":["/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useComboBoxState} from './useComboBoxState';\n\nexport type {ComboBoxStateOptions, ComboBoxState} from './useComboBoxState';\n","/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {Collection, CollectionStateBase, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {getChildNodes} from '@react-stately/collections';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useControlledState} from '@react-stately/utils';\nimport {useMenuTriggerState} from '@react-stately/menu';\n\nexport interface ComboBoxState<T> extends SelectState<T> {\n /** The current value of the combo box input. */\n inputValue: string,\n /** Sets the value of the combo box input. */\n setInputValue(value: string): void,\n /** Selects the currently focused item and updates the input value. */\n commit(): void,\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Resets the input value to the previously selected item's text if any and closes the menu. */\n revert(): void\n}\n\ntype FilterFn = (textValue: string, inputValue: string) => boolean;\n\nexport interface ComboBoxStateOptions<T> extends Omit<ComboBoxProps<T>, 'children'>, CollectionStateBase<T> {\n /** The filter function used to determine if a option should be included in the combo box list. */\n defaultFilter?: FilterFn,\n /** Whether the combo box allows the menu to be open when the collection is empty. */\n allowsEmptyCollection?: boolean,\n /** Whether the combo box menu should close on blur. */\n shouldCloseOnBlur?: boolean\n}\n\n/**\n * Provides state management for a combo box component. Handles building a collection\n * of items from props and manages the option selection state of the combo box. In addition, it tracks the input value,\n * focus state, and other properties of the combo box.\n */\nexport function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T>): ComboBoxState<T> {\n let {\n defaultFilter,\n menuTrigger = 'input',\n allowsEmptyCollection = false,\n allowsCustomValue,\n shouldCloseOnBlur = true\n } = props;\n\n let [showAllItems, setShowAllItems] = useState(false);\n let [isFocused, setFocusedState] = useState(false);\n let [inputValue, setInputValue] = useControlledState(\n props.inputValue,\n props.defaultInputValue ?? '',\n props.onInputChange\n );\n\n let onSelectionChange = (key) => {\n if (props.onSelectionChange) {\n props.onSelectionChange(key);\n }\n\n // If key is the same, reset the inputValue and close the menu\n // (scenario: user clicks on already selected option)\n if (key === selectedKey) {\n resetInputValue();\n closeMenu();\n }\n };\n\n let {collection, selectionManager, selectedKey, setSelectedKey, selectedItem, disabledKeys} = useSingleSelectListState({\n ...props,\n onSelectionChange,\n items: props.items ?? props.defaultItems\n });\n\n // Preserve original collection so we can show all items on demand\n let originalCollection = collection;\n let filteredCollection = useMemo(() => (\n // No default filter if items are controlled.\n props.items != null || !defaultFilter\n ? collection\n : filterCollection(collection, inputValue, defaultFilter)\n ), [collection, inputValue, defaultFilter, props.items]);\n let [lastCollection, setLastCollection] = useState(filteredCollection);\n\n // Track what action is attempting to open the menu\n let menuOpenTrigger = useRef('focus' as MenuTriggerAction);\n let onOpenChange = (open: boolean) => {\n if (props.onOpenChange) {\n props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);\n }\n\n selectionManager.setFocused(open);\n if (!open) {\n selectionManager.setFocusedKey(null);\n }\n };\n\n let triggerState = useMenuTriggerState({...props, onOpenChange, isOpen: undefined, defaultOpen: undefined});\n let open = (focusStrategy?: FocusStrategy, trigger?: MenuTriggerAction) => {\n let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));\n // Prevent open operations from triggering if there is nothing to display\n // Also prevent open operations from triggering if items are uncontrolled but defaultItems is empty, even if displayAllItems is true.\n // This is to prevent comboboxes with empty defaultItems from opening but allow controlled items comboboxes to open even if the inital list is empty (assumption is user will provide swap the empty list with a base list via onOpenChange returning `menuTrigger` manual)\n if (allowsEmptyCollection || filteredCollection.size > 0 || (displayAllItems && originalCollection.size > 0) || props.items) {\n if (displayAllItems && !triggerState.isOpen && props.items === undefined) {\n // Show all items if menu is manually opened. Only care about this if items are undefined\n setShowAllItems(true);\n }\n\n menuOpenTrigger.current = trigger;\n triggerState.open(focusStrategy);\n }\n };\n\n let toggle = (focusStrategy?: FocusStrategy, trigger?: MenuTriggerAction) => {\n let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));\n // If the menu is closed and there is nothing to display, early return so toggle isn't called to prevent extraneous onOpenChange\n if (!(allowsEmptyCollection || filteredCollection.size > 0 || (displayAllItems && originalCollection.size > 0) || props.items) && !triggerState.isOpen) {\n return;\n }\n\n if (displayAllItems && !triggerState.isOpen && props.items === undefined) {\n // Show all items if menu is toggled open. Only care about this if items are undefined\n setShowAllItems(true);\n }\n\n // Only update the menuOpenTrigger if menu is currently closed\n if (!triggerState.isOpen) {\n menuOpenTrigger.current = trigger;\n }\n\n toggleMenu(focusStrategy);\n };\n\n // If menu is going to close, save the current collection so we can freeze the displayed collection when the\n // user clicks outside the popover to close the menu. Prevents the menu contents from updating as the menu closes.\n let toggleMenu = useCallback((focusStrategy) => {\n if (triggerState.isOpen) {\n setLastCollection(filteredCollection);\n }\n\n triggerState.toggle(focusStrategy);\n }, [triggerState, filteredCollection]);\n\n let closeMenu = useCallback(() => {\n if (triggerState.isOpen) {\n setLastCollection(filteredCollection);\n triggerState.close();\n }\n }, [triggerState, filteredCollection]);\n\n let lastValue = useRef(inputValue);\n let resetInputValue = () => {\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n lastValue.current = itemText;\n setInputValue(itemText);\n };\n\n let isInitialRender = useRef(true);\n let lastSelectedKey = useRef(props.selectedKey ?? props.defaultSelectedKey ?? null);\n let lastSelectedKeyText = useRef(collection.getItem(selectedKey)?.textValue ?? '');\n // intentional omit dependency array, want this to happen on every render\n // eslint-disable-next-line react-hooks/exhaustive-deps\n useEffect(() => {\n // Open and close menu automatically when the input value changes if the input is focused,\n // and there are items in the collection or allowEmptyCollection is true.\n if (\n isFocused &&\n (filteredCollection.size > 0 || allowsEmptyCollection) &&\n !triggerState.isOpen &&\n inputValue !== lastValue.current &&\n menuTrigger !== 'manual'\n ) {\n open(null, 'input');\n }\n\n // Close the menu if the collection is empty. Don't close menu if filtered collection size is 0\n // but we are currently showing all items via button press\n if (\n !showAllItems &&\n !allowsEmptyCollection &&\n triggerState.isOpen &&\n filteredCollection.size === 0\n ) {\n closeMenu();\n }\n\n // Close when an item is selected.\n if (\n selectedKey != null &&\n selectedKey !== lastSelectedKey.current\n ) {\n closeMenu();\n }\n\n // Clear focused key when input value changes and display filtered collection again.\n if (inputValue !== lastValue.current) {\n selectionManager.setFocusedKey(null);\n setShowAllItems(false);\n\n // Set selectedKey to null when the user clears the input.\n // If controlled, this is the application developer's responsibility.\n if (inputValue === '' && (props.inputValue === undefined || props.selectedKey === undefined)) {\n setSelectedKey(null);\n }\n }\n\n // If it is the intial render and inputValue isn't controlled nor has an intial value, set input to match current selected key if any\n if (isInitialRender.current && (props.inputValue === undefined && props.defaultInputValue === undefined)) {\n resetInputValue();\n }\n\n // If the selectedKey changed, update the input value.\n // Do nothing if both inputValue and selectedKey are controlled.\n // In this case, it's the user's responsibility to update inputValue in onSelectionChange.\n if (\n selectedKey !== lastSelectedKey.current &&\n (props.inputValue === undefined || props.selectedKey === undefined)\n ) {\n resetInputValue();\n } else {\n lastValue.current = inputValue;\n }\n\n // Update the inputValue if the selected item's text changes from its last tracked value.\n // This is to handle cases where a selectedKey is specified but the items aren't available (async loading) or the selected item's text value updates.\n // Only reset if the user isn't currently within the field so we don't erroneously modify user input.\n // If inputValue is controlled, it is the user's responsibility to update the inputValue when items change.\n let selectedItemText = collection.getItem(selectedKey)?.textValue ?? '';\n if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {\n if (lastSelectedKeyText.current !== selectedItemText) {\n lastValue.current = selectedItemText;\n setInputValue(selectedItemText);\n }\n }\n\n isInitialRender.current = false;\n lastSelectedKey.current = selectedKey;\n lastSelectedKeyText.current = selectedItemText;\n });\n\n // Revert input value and close menu\n let revert = () => {\n if (allowsCustomValue && selectedKey == null) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n };\n\n let commitCustomValue = () => {\n lastSelectedKey.current = null;\n setSelectedKey(null);\n closeMenu();\n };\n\n let commitSelection = () => {\n // If multiple things are controlled, call onSelectionChange\n if (props.selectedKey !== undefined && props.inputValue !== undefined) {\n props.onSelectionChange(selectedKey);\n\n // Stop menu from reopening from useEffect\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n lastValue.current = itemText;\n closeMenu();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n closeMenu();\n }\n };\n\n const commitValue = () => {\n if (allowsCustomValue) {\n const itemText = collection.getItem(selectedKey)?.textValue ?? '';\n (inputValue === itemText) ? commitSelection() : commitCustomValue();\n } else {\n // Reset inputValue and close menu\n commitSelection();\n }\n };\n\n let commit = () => {\n if (triggerState.isOpen && selectionManager.focusedKey != null) {\n // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise\n // fire onSelectionChange to allow the application to control the closing.\n if (selectedKey === selectionManager.focusedKey) {\n commitSelection();\n } else {\n setSelectedKey(selectionManager.focusedKey);\n }\n } else {\n commitValue();\n }\n };\n\n let setFocused = (isFocused: boolean) => {\n if (isFocused) {\n if (menuTrigger === 'focus') {\n open(null, 'focus');\n }\n } else if (shouldCloseOnBlur) {\n commitValue();\n }\n\n setFocusedState(isFocused);\n };\n\n let displayedCollection = useMemo(() => {\n if (triggerState.isOpen) {\n if (showAllItems) {\n return originalCollection;\n } else {\n return filteredCollection;\n }\n } else {\n return lastCollection;\n }\n }, [triggerState.isOpen, originalCollection, filteredCollection, showAllItems, lastCollection]);\n\n return {\n ...triggerState,\n toggle,\n open,\n close: commitValue,\n selectionManager,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: displayedCollection,\n inputValue,\n setInputValue,\n commit,\n revert\n };\n}\n\nfunction filterCollection<T extends object>(collection: Collection<Node<T>>, inputValue: string, filter: FilterFn): Collection<Node<T>> {\n return new ListCollection(filterNodes(collection, collection, inputValue, filter));\n}\n\nfunction filterNodes<T>(collection: Collection<Node<T>>, nodes: Iterable<Node<T>>, inputValue: string, filter: FilterFn): Iterable<Node<T>> {\n let filteredNode = [];\n for (let node of nodes) {\n if (node.type === 'section' && node.hasChildNodes) {\n let filtered = filterNodes(collection, getChildNodes(node, collection), inputValue, filter);\n if ([...filtered].some(node => node.type === 'item')) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type === 'item' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n } else if (node.type !== 'item') {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"module.js.map"}
@@ -1 +1 @@
1
- {"mappings":";;;AAqBA,+BAA+B,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC;IACtD,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,sEAAsE;IACtE,MAAM,IAAI,IAAI,CAAC;IACf,sBAAsB;IACtB,IAAI,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC9E,wBAAwB;IACxB,MAAM,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAChF,iGAAiG;IACjG,MAAM,IAAI,IAAI,CAAA;CACf;AAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;AAEnE,sCAAsC,CAAC,CAAE,SAAQ,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,oBAAoB,CAAC,CAAC;IACzG,kGAAkG;IAClG,aAAa,CAAC,EAAE,QAAQ,CAAC;IACzB,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;;GAIG;AACH,iCAAiC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CA+SnG","sources":["packages/@react-stately/combobox/src/packages/@react-stately/combobox/src/useComboBoxState.ts","packages/@react-stately/combobox/src/packages/@react-stately/combobox/src/index.ts","packages/@react-stately/combobox/src/index.ts"],"sourcesContent":[null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useComboBoxState} from './useComboBoxState';\n\nexport type {ComboBoxStateOptions, ComboBoxState} from './useComboBoxState';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
1
+ {"mappings":";;;AAqBA,+BAA+B,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC;IACtD,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC;IACnB,6CAA6C;IAC7C,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,sEAAsE;IACtE,MAAM,IAAI,IAAI,CAAC;IACf,sBAAsB;IACtB,IAAI,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC9E,wBAAwB;IACxB,MAAM,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAChF,iGAAiG;IACjG,MAAM,IAAI,IAAI,CAAA;CACf;AAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;AAEnE,sCAAsC,CAAC,CAAE,SAAQ,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,oBAAoB,CAAC,CAAC;IACzG,kGAAkG;IAClG,aAAa,CAAC,EAAE,QAAQ,CAAC;IACzB,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;;GAIG;AACH,iCAAiC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CA4SnG","sources":["packages/@react-stately/combobox/src/packages/@react-stately/combobox/src/useComboBoxState.ts","packages/@react-stately/combobox/src/packages/@react-stately/combobox/src/index.ts","packages/@react-stately/combobox/src/index.ts"],"sourcesContent":[null,null,"/*\n * Copyright 2020 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n * \n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nexport {useComboBoxState} from './useComboBoxState';\n\nexport type {ComboBoxStateOptions, ComboBoxState} from './useComboBoxState';\n"],"names":[],"version":3,"file":"types.d.ts.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-stately/combobox",
3
- "version": "3.5.3-nightly.4042+da38fa0da",
3
+ "version": "3.5.3-nightly.4044+9f1540281",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
@@ -22,13 +22,13 @@
22
22
  "url": "https://github.com/adobe/react-spectrum"
23
23
  },
24
24
  "dependencies": {
25
- "@react-stately/collections": "3.0.0-nightly.2337+da38fa0da",
26
- "@react-stately/list": "3.9.1-nightly.4042+da38fa0da",
27
- "@react-stately/menu": "3.5.4-nightly.4042+da38fa0da",
28
- "@react-stately/select": "3.5.3-nightly.4042+da38fa0da",
29
- "@react-stately/utils": "3.0.0-nightly.2337+da38fa0da",
30
- "@react-types/combobox": "3.6.3-nightly.4042+da38fa0da",
31
- "@react-types/shared": "3.0.0-nightly.2337+da38fa0da",
25
+ "@react-stately/collections": "3.0.0-nightly.2339+9f1540281",
26
+ "@react-stately/list": "3.9.1-nightly.4044+9f1540281",
27
+ "@react-stately/menu": "3.5.4-nightly.4044+9f1540281",
28
+ "@react-stately/select": "3.5.3-nightly.4044+9f1540281",
29
+ "@react-stately/utils": "3.0.0-nightly.2339+9f1540281",
30
+ "@react-types/combobox": "3.6.3-nightly.4044+9f1540281",
31
+ "@react-types/shared": "3.0.0-nightly.2339+9f1540281",
32
32
  "@swc/helpers": "^0.5.0"
33
33
  },
34
34
  "peerDependencies": {
@@ -37,5 +37,5 @@
37
37
  "publishConfig": {
38
38
  "access": "public"
39
39
  },
40
- "gitHead": "da38fa0da7da175032209fccb4556c0d580d0274"
40
+ "gitHead": "9f154028102aa8085f366226fe7a027556c8a3ac"
41
41
  }
@@ -284,6 +284,16 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
284
284
  }
285
285
  };
286
286
 
287
+ const commitValue = () => {
288
+ if (allowsCustomValue) {
289
+ const itemText = collection.getItem(selectedKey)?.textValue ?? '';
290
+ (inputValue === itemText) ? commitSelection() : commitCustomValue();
291
+ } else {
292
+ // Reset inputValue and close menu
293
+ commitSelection();
294
+ }
295
+ };
296
+
287
297
  let commit = () => {
288
298
  if (triggerState.isOpen && selectionManager.focusedKey != null) {
289
299
  // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise
@@ -293,31 +303,18 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
293
303
  } else {
294
304
  setSelectedKey(selectionManager.focusedKey);
295
305
  }
296
- } else if (allowsCustomValue) {
297
- commitCustomValue();
298
306
  } else {
299
- // Reset inputValue and close menu if no item is focused but user triggers a commit
300
- commitSelection();
307
+ commitValue();
301
308
  }
302
309
  };
303
310
 
304
- let close = () => {
305
- let itemText = collection.getItem(selectedKey)?.textValue ?? '';
306
- if (allowsCustomValue && inputValue !== itemText) {
307
- commitCustomValue();
308
- } else {
309
- commitSelection();
310
- }
311
- closeMenu();
312
- };
313
-
314
311
  let setFocused = (isFocused: boolean) => {
315
312
  if (isFocused) {
316
313
  if (menuTrigger === 'focus') {
317
314
  open(null, 'focus');
318
315
  }
319
316
  } else if (shouldCloseOnBlur) {
320
- close();
317
+ commitValue();
321
318
  }
322
319
 
323
320
  setFocusedState(isFocused);
@@ -339,7 +336,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
339
336
  ...triggerState,
340
337
  toggle,
341
338
  open,
342
- close,
339
+ close: commitValue,
343
340
  selectionManager,
344
341
  selectedKey,
345
342
  setSelectedKey,