@react-stately/combobox 3.3.2-nightly.3698 → 3.3.2-nightly.3705

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.
@@ -0,0 +1,282 @@
1
+ import {useSingleSelectListState as $k6Ppu$useSingleSelectListState, ListCollection as $k6Ppu$ListCollection} from "@react-stately/list";
2
+ import {useState as $k6Ppu$useState, useMemo as $k6Ppu$useMemo, useRef as $k6Ppu$useRef, useCallback as $k6Ppu$useCallback, useEffect as $k6Ppu$useEffect} from "react";
3
+ import {useControlledState as $k6Ppu$useControlledState} from "@react-stately/utils";
4
+ import {useMenuTriggerState as $k6Ppu$useMenuTriggerState} from "@react-stately/menu";
5
+
6
+ /*
7
+ * Copyright 2020 Adobe. All rights reserved.
8
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
9
+ * you may not use this file except in compliance with the License. You may obtain a copy
10
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software distributed under
13
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
14
+ * OF ANY KIND, either express or implied. See the License for the specific language
15
+ * governing permissions and limitations under the License.
16
+ */ /*
17
+ * Copyright 2020 Adobe. All rights reserved.
18
+ * This file is licensed to you under the Apache License, Version 2.0 (the "License");
19
+ * you may not use this file except in compliance with the License. You may obtain a copy
20
+ * of the License at http://www.apache.org/licenses/LICENSE-2.0
21
+ *
22
+ * Unless required by applicable law or agreed to in writing, software distributed under
23
+ * the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
24
+ * OF ANY KIND, either express or implied. See the License for the specific language
25
+ * governing permissions and limitations under the License.
26
+ */
27
+
28
+
29
+
30
+ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
31
+ var _collection_getItem;
32
+ let { defaultFilter: defaultFilter , menuTrigger: menuTrigger = "input" , allowsEmptyCollection: allowsEmptyCollection = false , allowsCustomValue: allowsCustomValue , shouldCloseOnBlur: shouldCloseOnBlur = true } = props;
33
+ let [showAllItems, setShowAllItems] = (0, $k6Ppu$useState)(false);
34
+ let [isFocused, setFocusedState] = (0, $k6Ppu$useState)(false);
35
+ var _props_defaultInputValue;
36
+ let [inputValue, setInputValue] = (0, $k6Ppu$useControlledState)(props.inputValue, (_props_defaultInputValue = props.defaultInputValue) !== null && _props_defaultInputValue !== void 0 ? _props_defaultInputValue : "", props.onInputChange);
37
+ let onSelectionChange = (key)=>{
38
+ if (props.onSelectionChange) props.onSelectionChange(key);
39
+ // If key is the same, reset the inputValue and close the menu
40
+ // (scenario: user clicks on already selected option)
41
+ if (key === selectedKey) {
42
+ resetInputValue();
43
+ closeMenu();
44
+ }
45
+ };
46
+ var _props_items;
47
+ let { collection: collection , selectionManager: selectionManager , selectedKey: selectedKey , setSelectedKey: setSelectedKey , selectedItem: selectedItem , disabledKeys: disabledKeys } = (0, $k6Ppu$useSingleSelectListState)({
48
+ ...props,
49
+ onSelectionChange: onSelectionChange,
50
+ items: (_props_items = props.items) !== null && _props_items !== void 0 ? _props_items : props.defaultItems
51
+ });
52
+ // Preserve original collection so we can show all items on demand
53
+ let originalCollection = collection;
54
+ let filteredCollection = (0, $k6Ppu$useMemo)(()=>// No default filter if items are controlled.
55
+ props.items != null || !defaultFilter ? collection : $a9e7382a7d111cb5$var$filterCollection(collection, inputValue, defaultFilter), [
56
+ collection,
57
+ inputValue,
58
+ defaultFilter,
59
+ props.items
60
+ ]);
61
+ let [lastCollection, setLastCollection] = (0, $k6Ppu$useState)(filteredCollection);
62
+ // Track what action is attempting to open the menu
63
+ let menuOpenTrigger = (0, $k6Ppu$useRef)("focus");
64
+ let onOpenChange = (open)=>{
65
+ if (props.onOpenChange) props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);
66
+ };
67
+ let triggerState = (0, $k6Ppu$useMenuTriggerState)({
68
+ ...props,
69
+ onOpenChange: onOpenChange,
70
+ isOpen: undefined,
71
+ defaultOpen: undefined
72
+ });
73
+ let open = (focusStrategy, trigger)=>{
74
+ let displayAllItems = trigger === "manual" || trigger === "focus" && menuTrigger === "focus";
75
+ // Prevent open operations from triggering if there is nothing to display
76
+ // Also prevent open operations from triggering if items are uncontrolled but defaultItems is empty, even if displayAllItems is true.
77
+ // 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)
78
+ if (allowsEmptyCollection || filteredCollection.size > 0 || displayAllItems && originalCollection.size > 0 || props.items) {
79
+ if (displayAllItems && !triggerState.isOpen && props.items === undefined) // Show all items if menu is manually opened. Only care about this if items are undefined
80
+ setShowAllItems(true);
81
+ menuOpenTrigger.current = trigger;
82
+ triggerState.open(focusStrategy);
83
+ }
84
+ };
85
+ let toggle = (focusStrategy, trigger)=>{
86
+ let displayAllItems = trigger === "manual" || trigger === "focus" && menuTrigger === "focus";
87
+ // If the menu is closed and there is nothing to display, early return so toggle isn't called to prevent extraneous onOpenChange
88
+ if (!(allowsEmptyCollection || filteredCollection.size > 0 || displayAllItems && originalCollection.size > 0 || props.items) && !triggerState.isOpen) return;
89
+ if (displayAllItems && !triggerState.isOpen && props.items === undefined) // Show all items if menu is toggled open. Only care about this if items are undefined
90
+ setShowAllItems(true);
91
+ // Only update the menuOpenTrigger if menu is currently closed
92
+ if (!triggerState.isOpen) menuOpenTrigger.current = trigger;
93
+ toggleMenu(focusStrategy);
94
+ };
95
+ // If menu is going to close, save the current collection so we can freeze the displayed collection when the
96
+ // user clicks outside the popover to close the menu. Prevents the menu contents from updating as the menu closes.
97
+ let toggleMenu = (0, $k6Ppu$useCallback)((focusStrategy)=>{
98
+ if (triggerState.isOpen) setLastCollection(filteredCollection);
99
+ triggerState.toggle(focusStrategy);
100
+ }, [
101
+ triggerState,
102
+ filteredCollection
103
+ ]);
104
+ let closeMenu = (0, $k6Ppu$useCallback)(()=>{
105
+ if (triggerState.isOpen) {
106
+ setLastCollection(filteredCollection);
107
+ triggerState.close();
108
+ }
109
+ }, [
110
+ triggerState,
111
+ filteredCollection
112
+ ]);
113
+ let lastValue = (0, $k6Ppu$useRef)(inputValue);
114
+ let resetInputValue = ()=>{
115
+ var _collection_getItem;
116
+ var _collection_getItem_textValue;
117
+ 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 : "";
118
+ lastValue.current = itemText;
119
+ setInputValue(itemText);
120
+ };
121
+ let isInitialRender = (0, $k6Ppu$useRef)(true);
122
+ var _props_selectedKey, _ref;
123
+ let lastSelectedKey = (0, $k6Ppu$useRef)((_ref = (_props_selectedKey = props.selectedKey) !== null && _props_selectedKey !== void 0 ? _props_selectedKey : props.defaultSelectedKey) !== null && _ref !== void 0 ? _ref : null);
124
+ var _collection_getItem_textValue;
125
+ let lastSelectedKeyText = (0, $k6Ppu$useRef)((_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 : "");
126
+ // intentional omit dependency array, want this to happen on every render
127
+ // eslint-disable-next-line react-hooks/exhaustive-deps
128
+ (0, $k6Ppu$useEffect)(()=>{
129
+ var _collection_getItem;
130
+ // Open and close menu automatically when the input value changes if the input is focused,
131
+ // and there are items in the collection or allowEmptyCollection is true.
132
+ if (isFocused && (filteredCollection.size > 0 || allowsEmptyCollection) && !triggerState.isOpen && inputValue !== lastValue.current && menuTrigger !== "manual") open(null, "input");
133
+ // Close the menu if the collection is empty. Don't close menu if filtered collection size is 0
134
+ // but we are currently showing all items via button press
135
+ if (!showAllItems && !allowsEmptyCollection && triggerState.isOpen && filteredCollection.size === 0) closeMenu();
136
+ // Close when an item is selected.
137
+ if (selectedKey != null && selectedKey !== lastSelectedKey.current) closeMenu();
138
+ // Clear focused key when input value changes and display filtered collection again.
139
+ if (inputValue !== lastValue.current) {
140
+ selectionManager.setFocusedKey(null);
141
+ setShowAllItems(false);
142
+ // Set selectedKey to null when the user clears the input.
143
+ // If controlled, this is the application developer's responsibility.
144
+ if (inputValue === "" && (props.inputValue === undefined || props.selectedKey === undefined)) setSelectedKey(null);
145
+ }
146
+ // 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
147
+ if (isInitialRender.current && props.inputValue === undefined && props.defaultInputValue === undefined) resetInputValue();
148
+ // If the selectedKey changed, update the input value.
149
+ // Do nothing if both inputValue and selectedKey are controlled.
150
+ // In this case, it's the user's responsibility to update inputValue in onSelectionChange.
151
+ if (selectedKey !== lastSelectedKey.current && (props.inputValue === undefined || props.selectedKey === undefined)) resetInputValue();
152
+ else lastValue.current = inputValue;
153
+ var _collection_getItem_textValue;
154
+ // Update the inputValue if the selected item's text changes from its last tracked value.
155
+ // 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.
156
+ // Only reset if the user isn't currently within the field so we don't erroneously modify user input.
157
+ // If inputValue is controlled, it is the user's responsibility to update the inputValue when items change.
158
+ let selectedItemText = (_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 : "";
159
+ if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {
160
+ if (lastSelectedKeyText.current !== selectedItemText) {
161
+ lastValue.current = selectedItemText;
162
+ setInputValue(selectedItemText);
163
+ }
164
+ }
165
+ isInitialRender.current = false;
166
+ lastSelectedKey.current = selectedKey;
167
+ lastSelectedKeyText.current = selectedItemText;
168
+ });
169
+ (0, $k6Ppu$useEffect)(()=>{
170
+ // Reset focused key when the menu closes
171
+ if (!triggerState.isOpen) selectionManager.setFocusedKey(null);
172
+ }, [
173
+ triggerState.isOpen,
174
+ selectionManager
175
+ ]);
176
+ // Revert input value and close menu
177
+ let revert = ()=>{
178
+ if (allowsCustomValue && selectedKey == null) commitCustomValue();
179
+ else commitSelection();
180
+ };
181
+ let commitCustomValue = ()=>{
182
+ lastSelectedKey.current = null;
183
+ setSelectedKey(null);
184
+ closeMenu();
185
+ };
186
+ let commitSelection = ()=>{
187
+ // If multiple things are controlled, call onSelectionChange
188
+ if (props.selectedKey !== undefined && props.inputValue !== undefined) {
189
+ var _collection_getItem;
190
+ props.onSelectionChange(selectedKey);
191
+ var _collection_getItem_textValue;
192
+ // Stop menu from reopening from useEffect
193
+ 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 : "";
194
+ lastValue.current = itemText;
195
+ closeMenu();
196
+ } else {
197
+ // If only a single aspect of combobox is controlled, reset input value and close menu for the user
198
+ resetInputValue();
199
+ closeMenu();
200
+ }
201
+ };
202
+ let commit = ()=>{
203
+ if (triggerState.isOpen && selectionManager.focusedKey != null) {
204
+ // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise
205
+ // fire onSelectionChange to allow the application to control the closing.
206
+ if (selectedKey === selectionManager.focusedKey) commitSelection();
207
+ else setSelectedKey(selectionManager.focusedKey);
208
+ } else if (allowsCustomValue) commitCustomValue();
209
+ else // Reset inputValue and close menu if no item is focused but user triggers a commit
210
+ commitSelection();
211
+ };
212
+ let close = ()=>{
213
+ var _collection_getItem;
214
+ var _collection_getItem_textValue;
215
+ 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 : "";
216
+ if (allowsCustomValue && inputValue !== itemText) commitCustomValue();
217
+ else commitSelection();
218
+ closeMenu();
219
+ };
220
+ let setFocused = (isFocused)=>{
221
+ if (isFocused) {
222
+ if (menuTrigger === "focus") open(null, "focus");
223
+ } else if (shouldCloseOnBlur) close();
224
+ setFocusedState(isFocused);
225
+ };
226
+ let displayedCollection = (0, $k6Ppu$useMemo)(()=>{
227
+ if (triggerState.isOpen) {
228
+ if (showAllItems) return originalCollection;
229
+ else return filteredCollection;
230
+ } else return lastCollection;
231
+ }, [
232
+ triggerState.isOpen,
233
+ originalCollection,
234
+ filteredCollection,
235
+ showAllItems,
236
+ lastCollection
237
+ ]);
238
+ return {
239
+ ...triggerState,
240
+ toggle: toggle,
241
+ open: open,
242
+ close: close,
243
+ selectionManager: selectionManager,
244
+ selectedKey: selectedKey,
245
+ setSelectedKey: setSelectedKey,
246
+ disabledKeys: disabledKeys,
247
+ isFocused: isFocused,
248
+ setFocused: setFocused,
249
+ selectedItem: selectedItem,
250
+ collection: displayedCollection,
251
+ inputValue: inputValue,
252
+ setInputValue: setInputValue,
253
+ commit: commit,
254
+ revert: revert
255
+ };
256
+ }
257
+ function $a9e7382a7d111cb5$var$filterCollection(collection, inputValue, filter) {
258
+ return new (0, $k6Ppu$ListCollection)($a9e7382a7d111cb5$var$filterNodes(collection, inputValue, filter));
259
+ }
260
+ function $a9e7382a7d111cb5$var$filterNodes(nodes, inputValue, filter) {
261
+ let filteredNode = [];
262
+ for (let node of nodes){
263
+ if (node.type === "section" && node.hasChildNodes) {
264
+ let filtered = $a9e7382a7d111cb5$var$filterNodes(node.childNodes, inputValue, filter);
265
+ if ([
266
+ ...filtered
267
+ ].length > 0) filteredNode.push({
268
+ ...node,
269
+ childNodes: filtered
270
+ });
271
+ } else if (node.type !== "section" && filter(node.textValue, inputValue)) filteredNode.push({
272
+ ...node
273
+ });
274
+ }
275
+ return filteredNode;
276
+ }
277
+
278
+
279
+
280
+
281
+ export {$a9e7382a7d111cb5$export$b453a3bfd4a5fa9e as useComboBoxState};
282
+ //# sourceMappingURL=module.js.map
package/dist/main.js CHANGED
@@ -1,6 +1,6 @@
1
1
  var $5XAuq$reactstatelylist = require("@react-stately/list");
2
- var $5XAuq$reactstatelyutils = require("@react-stately/utils");
3
2
  var $5XAuq$react = require("react");
3
+ var $5XAuq$reactstatelyutils = require("@react-stately/utils");
4
4
  var $5XAuq$reactstatelymenu = require("@react-stately/menu");
5
5
 
6
6
  function $parcel$export(e, n, v, s) {
@@ -45,7 +45,7 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
45
45
  // (scenario: user clicks on already selected option)
46
46
  if (key === selectedKey) {
47
47
  resetInputValue();
48
- triggerState.close();
48
+ closeMenu();
49
49
  }
50
50
  };
51
51
  var _props_items;
@@ -63,6 +63,7 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
63
63
  defaultFilter,
64
64
  props.items
65
65
  ]);
66
+ let [lastCollection, setLastCollection] = (0, $5XAuq$react.useState)(filteredCollection);
66
67
  // Track what action is attempting to open the menu
67
68
  let menuOpenTrigger = (0, $5XAuq$react.useRef)("focus");
68
69
  let onOpenChange = (open)=>{
@@ -94,8 +95,26 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
94
95
  setShowAllItems(true);
95
96
  // Only update the menuOpenTrigger if menu is currently closed
96
97
  if (!triggerState.isOpen) menuOpenTrigger.current = trigger;
97
- triggerState.toggle(focusStrategy);
98
+ toggleMenu(focusStrategy);
98
99
  };
100
+ // If menu is going to close, save the current collection so we can freeze the displayed collection when the
101
+ // user clicks outside the popover to close the menu. Prevents the menu contents from updating as the menu closes.
102
+ let toggleMenu = (0, $5XAuq$react.useCallback)((focusStrategy)=>{
103
+ if (triggerState.isOpen) setLastCollection(filteredCollection);
104
+ triggerState.toggle(focusStrategy);
105
+ }, [
106
+ triggerState,
107
+ filteredCollection
108
+ ]);
109
+ let closeMenu = (0, $5XAuq$react.useCallback)(()=>{
110
+ if (triggerState.isOpen) {
111
+ setLastCollection(filteredCollection);
112
+ triggerState.close();
113
+ }
114
+ }, [
115
+ triggerState,
116
+ filteredCollection
117
+ ]);
99
118
  let lastValue = (0, $5XAuq$react.useRef)(inputValue);
100
119
  let resetInputValue = ()=>{
101
120
  var _collection_getItem;
@@ -118,9 +137,9 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
118
137
  if (isFocused && (filteredCollection.size > 0 || allowsEmptyCollection) && !triggerState.isOpen && inputValue !== lastValue.current && menuTrigger !== "manual") open(null, "input");
119
138
  // Close the menu if the collection is empty. Don't close menu if filtered collection size is 0
120
139
  // but we are currently showing all items via button press
121
- if (!showAllItems && !allowsEmptyCollection && triggerState.isOpen && filteredCollection.size === 0) triggerState.close();
140
+ if (!showAllItems && !allowsEmptyCollection && triggerState.isOpen && filteredCollection.size === 0) closeMenu();
122
141
  // Close when an item is selected.
123
- if (selectedKey != null && selectedKey !== lastSelectedKey.current) triggerState.close();
142
+ if (selectedKey != null && selectedKey !== lastSelectedKey.current) closeMenu();
124
143
  // Clear focused key when input value changes and display filtered collection again.
125
144
  if (inputValue !== lastValue.current) {
126
145
  selectionManager.setFocusedKey(null);
@@ -167,7 +186,7 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
167
186
  let commitCustomValue = ()=>{
168
187
  lastSelectedKey.current = null;
169
188
  setSelectedKey(null);
170
- triggerState.close();
189
+ closeMenu();
171
190
  };
172
191
  let commitSelection = ()=>{
173
192
  // If multiple things are controlled, call onSelectionChange
@@ -178,11 +197,11 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
178
197
  // Stop menu from reopening from useEffect
179
198
  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 : "";
180
199
  lastValue.current = itemText;
181
- triggerState.close();
200
+ closeMenu();
182
201
  } else {
183
202
  // If only a single aspect of combobox is controlled, reset input value and close menu for the user
184
203
  resetInputValue();
185
- triggerState.close();
204
+ closeMenu();
186
205
  }
187
206
  };
188
207
  let commit = ()=>{
@@ -201,7 +220,7 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
201
220
  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 : "";
202
221
  if (allowsCustomValue && inputValue !== itemText) commitCustomValue();
203
222
  else commitSelection();
204
- triggerState.close();
223
+ closeMenu();
205
224
  };
206
225
  let setFocused = (isFocused)=>{
207
226
  if (isFocused) {
@@ -209,32 +228,31 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
209
228
  } else if (shouldCloseOnBlur) close();
210
229
  setFocusedState(isFocused);
211
230
  };
212
- let selectionManagerProxy = (0, $5XAuq$react.useMemo)(()=>{
213
- let proxy = new Proxy(selectionManager, {
214
- get (target, prop, receiver) {
215
- // If the menu is closed, don't update the selected key.
216
- if (prop === "replaceSelection" && !triggerState.isOpen) return ()=>{};
217
- return Reflect.get(target, prop, receiver);
218
- }
219
- });
220
- return proxy;
231
+ let displayedCollection = (0, $5XAuq$react.useMemo)(()=>{
232
+ if (triggerState.isOpen) {
233
+ if (showAllItems) return originalCollection;
234
+ else return filteredCollection;
235
+ } else return lastCollection;
221
236
  }, [
222
- selectionManager,
223
- triggerState.isOpen
237
+ triggerState.isOpen,
238
+ originalCollection,
239
+ filteredCollection,
240
+ showAllItems,
241
+ lastCollection
224
242
  ]);
225
243
  return {
226
244
  ...triggerState,
227
245
  toggle: toggle,
228
246
  open: open,
229
247
  close: close,
230
- selectionManager: selectionManagerProxy,
248
+ selectionManager: selectionManager,
231
249
  selectedKey: selectedKey,
232
250
  setSelectedKey: setSelectedKey,
233
251
  disabledKeys: disabledKeys,
234
252
  isFocused: isFocused,
235
253
  setFocused: setFocused,
236
254
  selectedItem: selectedItem,
237
- collection: showAllItems ? originalCollection : filteredCollection,
255
+ collection: displayedCollection,
238
256
  inputValue: inputValue,
239
257
  setInputValue: setInputValue,
240
258
  commit: commit,
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, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useControlledState} from '@react-stately/utils';\nimport {useEffect, useMemo, useRef, useState} from 'react';\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 ComboBoxProps<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 triggerState.close();\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\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\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 triggerState.toggle(focusStrategy);\n };\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 triggerState.close();\n }\n\n // Close when an item is selected.\n if (\n selectedKey != null &&\n selectedKey !== lastSelectedKey.current\n ) {\n triggerState.close();\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 useEffect(() => {\n // Reset focused key when the menu closes\n if (!triggerState.isOpen) {\n selectionManager.setFocusedKey(null);\n }\n }, [triggerState.isOpen, selectionManager]);\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 triggerState.close();\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 triggerState.close();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n triggerState.close();\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 triggerState.close();\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 selectionManagerProxy = useMemo(() => {\n let proxy = new Proxy(selectionManager, {\n get(target, prop, receiver) {\n // If the menu is closed, don't update the selected key.\n if (prop === 'replaceSelection' && !triggerState.isOpen) {\n return () => {};\n }\n return Reflect.get(target, prop, receiver);\n }\n });\n\n return proxy;\n }, [selectionManager, triggerState.isOpen]);\n\n return {\n ...triggerState,\n toggle,\n open,\n close,\n selectionManager: selectionManagerProxy,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: showAllItems ? originalCollection : filteredCollection,\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, inputValue, filter));\n}\n\nfunction filterNodes<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(node.childNodes, inputValue, filter);\n if ([...filtered].length > 0) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type !== 'section' && filter(node.textValue, inputValue)) {\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, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\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 ComboBoxProps<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\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 useEffect(() => {\n // Reset focused key when the menu closes\n if (!triggerState.isOpen) {\n selectionManager.setFocusedKey(null);\n }\n }, [triggerState.isOpen, selectionManager]);\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, inputValue, filter));\n}\n\nfunction filterNodes<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(node.childNodes, inputValue, filter);\n if ([...filtered].length > 0) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type !== 'section' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"main.js.map"}
package/dist/module.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import {useSingleSelectListState as $k6Ppu$useSingleSelectListState, ListCollection as $k6Ppu$ListCollection} from "@react-stately/list";
2
+ import {useState as $k6Ppu$useState, useMemo as $k6Ppu$useMemo, useRef as $k6Ppu$useRef, useCallback as $k6Ppu$useCallback, useEffect as $k6Ppu$useEffect} from "react";
2
3
  import {useControlledState as $k6Ppu$useControlledState} from "@react-stately/utils";
3
- import {useState as $k6Ppu$useState, useMemo as $k6Ppu$useMemo, useRef as $k6Ppu$useRef, useEffect as $k6Ppu$useEffect} from "react";
4
4
  import {useMenuTriggerState as $k6Ppu$useMenuTriggerState} from "@react-stately/menu";
5
5
 
6
6
  /*
@@ -40,7 +40,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
40
40
  // (scenario: user clicks on already selected option)
41
41
  if (key === selectedKey) {
42
42
  resetInputValue();
43
- triggerState.close();
43
+ closeMenu();
44
44
  }
45
45
  };
46
46
  var _props_items;
@@ -58,6 +58,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
58
58
  defaultFilter,
59
59
  props.items
60
60
  ]);
61
+ let [lastCollection, setLastCollection] = (0, $k6Ppu$useState)(filteredCollection);
61
62
  // Track what action is attempting to open the menu
62
63
  let menuOpenTrigger = (0, $k6Ppu$useRef)("focus");
63
64
  let onOpenChange = (open)=>{
@@ -89,8 +90,26 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
89
90
  setShowAllItems(true);
90
91
  // Only update the menuOpenTrigger if menu is currently closed
91
92
  if (!triggerState.isOpen) menuOpenTrigger.current = trigger;
92
- triggerState.toggle(focusStrategy);
93
+ toggleMenu(focusStrategy);
93
94
  };
95
+ // If menu is going to close, save the current collection so we can freeze the displayed collection when the
96
+ // user clicks outside the popover to close the menu. Prevents the menu contents from updating as the menu closes.
97
+ let toggleMenu = (0, $k6Ppu$useCallback)((focusStrategy)=>{
98
+ if (triggerState.isOpen) setLastCollection(filteredCollection);
99
+ triggerState.toggle(focusStrategy);
100
+ }, [
101
+ triggerState,
102
+ filteredCollection
103
+ ]);
104
+ let closeMenu = (0, $k6Ppu$useCallback)(()=>{
105
+ if (triggerState.isOpen) {
106
+ setLastCollection(filteredCollection);
107
+ triggerState.close();
108
+ }
109
+ }, [
110
+ triggerState,
111
+ filteredCollection
112
+ ]);
94
113
  let lastValue = (0, $k6Ppu$useRef)(inputValue);
95
114
  let resetInputValue = ()=>{
96
115
  var _collection_getItem;
@@ -113,9 +132,9 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
113
132
  if (isFocused && (filteredCollection.size > 0 || allowsEmptyCollection) && !triggerState.isOpen && inputValue !== lastValue.current && menuTrigger !== "manual") open(null, "input");
114
133
  // Close the menu if the collection is empty. Don't close menu if filtered collection size is 0
115
134
  // but we are currently showing all items via button press
116
- if (!showAllItems && !allowsEmptyCollection && triggerState.isOpen && filteredCollection.size === 0) triggerState.close();
135
+ if (!showAllItems && !allowsEmptyCollection && triggerState.isOpen && filteredCollection.size === 0) closeMenu();
117
136
  // Close when an item is selected.
118
- if (selectedKey != null && selectedKey !== lastSelectedKey.current) triggerState.close();
137
+ if (selectedKey != null && selectedKey !== lastSelectedKey.current) closeMenu();
119
138
  // Clear focused key when input value changes and display filtered collection again.
120
139
  if (inputValue !== lastValue.current) {
121
140
  selectionManager.setFocusedKey(null);
@@ -162,7 +181,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
162
181
  let commitCustomValue = ()=>{
163
182
  lastSelectedKey.current = null;
164
183
  setSelectedKey(null);
165
- triggerState.close();
184
+ closeMenu();
166
185
  };
167
186
  let commitSelection = ()=>{
168
187
  // If multiple things are controlled, call onSelectionChange
@@ -173,11 +192,11 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
173
192
  // Stop menu from reopening from useEffect
174
193
  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 : "";
175
194
  lastValue.current = itemText;
176
- triggerState.close();
195
+ closeMenu();
177
196
  } else {
178
197
  // If only a single aspect of combobox is controlled, reset input value and close menu for the user
179
198
  resetInputValue();
180
- triggerState.close();
199
+ closeMenu();
181
200
  }
182
201
  };
183
202
  let commit = ()=>{
@@ -196,7 +215,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
196
215
  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 : "";
197
216
  if (allowsCustomValue && inputValue !== itemText) commitCustomValue();
198
217
  else commitSelection();
199
- triggerState.close();
218
+ closeMenu();
200
219
  };
201
220
  let setFocused = (isFocused)=>{
202
221
  if (isFocused) {
@@ -204,32 +223,31 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
204
223
  } else if (shouldCloseOnBlur) close();
205
224
  setFocusedState(isFocused);
206
225
  };
207
- let selectionManagerProxy = (0, $k6Ppu$useMemo)(()=>{
208
- let proxy = new Proxy(selectionManager, {
209
- get (target, prop, receiver) {
210
- // If the menu is closed, don't update the selected key.
211
- if (prop === "replaceSelection" && !triggerState.isOpen) return ()=>{};
212
- return Reflect.get(target, prop, receiver);
213
- }
214
- });
215
- return proxy;
226
+ let displayedCollection = (0, $k6Ppu$useMemo)(()=>{
227
+ if (triggerState.isOpen) {
228
+ if (showAllItems) return originalCollection;
229
+ else return filteredCollection;
230
+ } else return lastCollection;
216
231
  }, [
217
- selectionManager,
218
- triggerState.isOpen
232
+ triggerState.isOpen,
233
+ originalCollection,
234
+ filteredCollection,
235
+ showAllItems,
236
+ lastCollection
219
237
  ]);
220
238
  return {
221
239
  ...triggerState,
222
240
  toggle: toggle,
223
241
  open: open,
224
242
  close: close,
225
- selectionManager: selectionManagerProxy,
243
+ selectionManager: selectionManager,
226
244
  selectedKey: selectedKey,
227
245
  setSelectedKey: setSelectedKey,
228
246
  disabledKeys: disabledKeys,
229
247
  isFocused: isFocused,
230
248
  setFocused: setFocused,
231
249
  selectedItem: selectedItem,
232
- collection: showAllItems ? originalCollection : filteredCollection,
250
+ collection: displayedCollection,
233
251
  inputValue: inputValue,
234
252
  setInputValue: setInputValue,
235
253
  commit: commit,
@@ -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, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useControlledState} from '@react-stately/utils';\nimport {useEffect, useMemo, useRef, useState} from 'react';\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 ComboBoxProps<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 triggerState.close();\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\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\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 triggerState.toggle(focusStrategy);\n };\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 triggerState.close();\n }\n\n // Close when an item is selected.\n if (\n selectedKey != null &&\n selectedKey !== lastSelectedKey.current\n ) {\n triggerState.close();\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 useEffect(() => {\n // Reset focused key when the menu closes\n if (!triggerState.isOpen) {\n selectionManager.setFocusedKey(null);\n }\n }, [triggerState.isOpen, selectionManager]);\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 triggerState.close();\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 triggerState.close();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n triggerState.close();\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 triggerState.close();\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 selectionManagerProxy = useMemo(() => {\n let proxy = new Proxy(selectionManager, {\n get(target, prop, receiver) {\n // If the menu is closed, don't update the selected key.\n if (prop === 'replaceSelection' && !triggerState.isOpen) {\n return () => {};\n }\n return Reflect.get(target, prop, receiver);\n }\n });\n\n return proxy;\n }, [selectionManager, triggerState.isOpen]);\n\n return {\n ...triggerState,\n toggle,\n open,\n close,\n selectionManager: selectionManagerProxy,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: showAllItems ? originalCollection : filteredCollection,\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, inputValue, filter));\n}\n\nfunction filterNodes<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(node.childNodes, inputValue, filter);\n if ([...filtered].length > 0) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type !== 'section' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"module.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, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\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 ComboBoxProps<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\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 useEffect(() => {\n // Reset focused key when the menu closes\n if (!triggerState.isOpen) {\n selectionManager.setFocusedKey(null);\n }\n }, [triggerState.isOpen, selectionManager]);\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, inputValue, filter));\n}\n\nfunction filterNodes<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(node.childNodes, inputValue, filter);\n if ([...filtered].length > 0) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type !== 'section' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"module.js.map"}
@@ -1 +1 @@
1
- {"mappings":";;;AAoBA,+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,cAAc,CAAC,CAAC;IAC/D,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,CAiSnG","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":";;;AAoBA,+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,cAAc,CAAC,CAAC;IAC/D,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,CAiTnG","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,10 +1,15 @@
1
1
  {
2
2
  "name": "@react-stately/combobox",
3
- "version": "3.3.2-nightly.3698+72ee92f6d",
3
+ "version": "3.3.2-nightly.3705+93b3c951e",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
7
7
  "module": "dist/module.js",
8
+ "exports": {
9
+ "types": "./dist/types.d.ts",
10
+ "import": "./dist/import.mjs",
11
+ "require": "./dist/main.js"
12
+ },
8
13
  "types": "dist/types.d.ts",
9
14
  "source": "src/index.ts",
10
15
  "files": [
@@ -17,12 +22,12 @@
17
22
  "url": "https://github.com/adobe/react-spectrum"
18
23
  },
19
24
  "dependencies": {
20
- "@react-stately/list": "3.6.2-nightly.3698+72ee92f6d",
21
- "@react-stately/menu": "3.4.5-nightly.3698+72ee92f6d",
22
- "@react-stately/select": "3.3.5-nightly.3698+72ee92f6d",
23
- "@react-stately/utils": "3.0.0-nightly.1998+72ee92f6d",
24
- "@react-types/combobox": "3.5.6-nightly.3698+72ee92f6d",
25
- "@react-types/shared": "3.0.0-nightly.1998+72ee92f6d",
25
+ "@react-stately/list": "3.6.2-nightly.3705+93b3c951e",
26
+ "@react-stately/menu": "3.4.5-nightly.3705+93b3c951e",
27
+ "@react-stately/select": "3.3.5-nightly.3705+93b3c951e",
28
+ "@react-stately/utils": "3.0.0-nightly.2005+93b3c951e",
29
+ "@react-types/combobox": "3.5.6-nightly.3705+93b3c951e",
30
+ "@react-types/shared": "3.0.0-nightly.2005+93b3c951e",
26
31
  "@swc/helpers": "^0.4.14"
27
32
  },
28
33
  "peerDependencies": {
@@ -31,5 +36,5 @@
31
36
  "publishConfig": {
32
37
  "access": "public"
33
38
  },
34
- "gitHead": "72ee92f6d497163468a80642ccb96576f822f365"
39
+ "gitHead": "93b3c951eb784b14183f9988f2d188b34de8f42d"
35
40
  }
@@ -14,8 +14,8 @@ import {Collection, FocusStrategy, Node} from '@react-types/shared';
14
14
  import {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';
15
15
  import {ListCollection, useSingleSelectListState} from '@react-stately/list';
16
16
  import {SelectState} from '@react-stately/select';
17
+ import {useCallback, useEffect, useMemo, useRef, useState} from 'react';
17
18
  import {useControlledState} from '@react-stately/utils';
18
- import {useEffect, useMemo, useRef, useState} from 'react';
19
19
  import {useMenuTriggerState} from '@react-stately/menu';
20
20
 
21
21
  export interface ComboBoxState<T> extends SelectState<T> {
@@ -75,7 +75,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
75
75
  // (scenario: user clicks on already selected option)
76
76
  if (key === selectedKey) {
77
77
  resetInputValue();
78
- triggerState.close();
78
+ closeMenu();
79
79
  }
80
80
  };
81
81
 
@@ -93,6 +93,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
93
93
  ? collection
94
94
  : filterCollection(collection, inputValue, defaultFilter)
95
95
  ), [collection, inputValue, defaultFilter, props.items]);
96
+ let [lastCollection, setLastCollection] = useState(filteredCollection);
96
97
 
97
98
  // Track what action is attempting to open the menu
98
99
  let menuOpenTrigger = useRef('focus' as MenuTriggerAction);
@@ -136,9 +137,26 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
136
137
  menuOpenTrigger.current = trigger;
137
138
  }
138
139
 
139
- triggerState.toggle(focusStrategy);
140
+ toggleMenu(focusStrategy);
140
141
  };
141
142
 
143
+ // If menu is going to close, save the current collection so we can freeze the displayed collection when the
144
+ // user clicks outside the popover to close the menu. Prevents the menu contents from updating as the menu closes.
145
+ let toggleMenu = useCallback((focusStrategy) => {
146
+ if (triggerState.isOpen) {
147
+ setLastCollection(filteredCollection);
148
+ }
149
+
150
+ triggerState.toggle(focusStrategy);
151
+ }, [triggerState, filteredCollection]);
152
+
153
+ let closeMenu = useCallback(() => {
154
+ if (triggerState.isOpen) {
155
+ setLastCollection(filteredCollection);
156
+ triggerState.close();
157
+ }
158
+ }, [triggerState, filteredCollection]);
159
+
142
160
  let lastValue = useRef(inputValue);
143
161
  let resetInputValue = () => {
144
162
  let itemText = collection.getItem(selectedKey)?.textValue ?? '';
@@ -172,7 +190,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
172
190
  triggerState.isOpen &&
173
191
  filteredCollection.size === 0
174
192
  ) {
175
- triggerState.close();
193
+ closeMenu();
176
194
  }
177
195
 
178
196
  // Close when an item is selected.
@@ -180,7 +198,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
180
198
  selectedKey != null &&
181
199
  selectedKey !== lastSelectedKey.current
182
200
  ) {
183
- triggerState.close();
201
+ closeMenu();
184
202
  }
185
203
 
186
204
  // Clear focused key when input value changes and display filtered collection again.
@@ -248,7 +266,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
248
266
  let commitCustomValue = () => {
249
267
  lastSelectedKey.current = null;
250
268
  setSelectedKey(null);
251
- triggerState.close();
269
+ closeMenu();
252
270
  };
253
271
 
254
272
  let commitSelection = () => {
@@ -259,11 +277,11 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
259
277
  // Stop menu from reopening from useEffect
260
278
  let itemText = collection.getItem(selectedKey)?.textValue ?? '';
261
279
  lastValue.current = itemText;
262
- triggerState.close();
280
+ closeMenu();
263
281
  } else {
264
282
  // If only a single aspect of combobox is controlled, reset input value and close menu for the user
265
283
  resetInputValue();
266
- triggerState.close();
284
+ closeMenu();
267
285
  }
268
286
  };
269
287
 
@@ -291,7 +309,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
291
309
  } else {
292
310
  commitSelection();
293
311
  }
294
- triggerState.close();
312
+ closeMenu();
295
313
  };
296
314
 
297
315
  let setFocused = (isFocused: boolean) => {
@@ -306,33 +324,31 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
306
324
  setFocusedState(isFocused);
307
325
  };
308
326
 
309
- let selectionManagerProxy = useMemo(() => {
310
- let proxy = new Proxy(selectionManager, {
311
- get(target, prop, receiver) {
312
- // If the menu is closed, don't update the selected key.
313
- if (prop === 'replaceSelection' && !triggerState.isOpen) {
314
- return () => {};
315
- }
316
- return Reflect.get(target, prop, receiver);
327
+ let displayedCollection = useMemo(() => {
328
+ if (triggerState.isOpen) {
329
+ if (showAllItems) {
330
+ return originalCollection;
331
+ } else {
332
+ return filteredCollection;
317
333
  }
318
- });
319
-
320
- return proxy;
321
- }, [selectionManager, triggerState.isOpen]);
334
+ } else {
335
+ return lastCollection;
336
+ }
337
+ }, [triggerState.isOpen, originalCollection, filteredCollection, showAllItems, lastCollection]);
322
338
 
323
339
  return {
324
340
  ...triggerState,
325
341
  toggle,
326
342
  open,
327
343
  close,
328
- selectionManager: selectionManagerProxy,
344
+ selectionManager,
329
345
  selectedKey,
330
346
  setSelectedKey,
331
347
  disabledKeys,
332
348
  isFocused,
333
349
  setFocused,
334
350
  selectedItem,
335
- collection: showAllItems ? originalCollection : filteredCollection,
351
+ collection: displayedCollection,
336
352
  inputValue,
337
353
  setInputValue,
338
354
  commit,