@react-stately/combobox 3.9.2 → 3.9.3-nightly.5014

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/types.d.ts CHANGED
@@ -10,7 +10,7 @@ export interface ComboBoxState<T> extends SelectState<T>, FormValidationState {
10
10
  /** Selects the currently focused item and updates the input value. */
11
11
  commit(): void;
12
12
  /** Controls which item will be auto focused when the menu opens. */
13
- readonly focusStrategy: FocusStrategy;
13
+ readonly focusStrategy: FocusStrategy | null;
14
14
  /** Opens the menu. */
15
15
  open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void;
16
16
  /** Toggles the menu. */
@@ -1 +1 @@
1
- {"mappings":";;;;AAsBA,+BAA+B,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC,EAAE,mBAAmB;IAC3E,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,oEAAoE;IACpE,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IACtC,sBAAsB;IACtB,IAAI,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC9E,wBAAwB;IACxB,MAAM,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAChF,iGAAiG;IACjG,MAAM,IAAI,IAAI,CAAA;CACf;AAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;AAEnE,sCAAsC,CAAC,CAAE,SAAQ,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,oBAAoB,CAAC,CAAC;IACzG,kGAAkG;IAClG,aAAa,CAAC,EAAE,QAAQ,CAAC;IACzB,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;;GAIG;AACH,iCAAiC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CA4TnG","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":";;;;AAsBA,+BAA+B,CAAC,CAAE,SAAQ,YAAY,CAAC,CAAC,EAAE,mBAAmB;IAC3E,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,oEAAoE;IACpE,QAAQ,CAAC,aAAa,EAAE,aAAa,GAAG,IAAI,CAAC;IAC7C,sBAAsB;IACtB,IAAI,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC9E,wBAAwB;IACxB,MAAM,CAAC,aAAa,CAAC,EAAE,aAAa,GAAG,IAAI,EAAE,OAAO,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAChF,iGAAiG;IACjG,MAAM,IAAI,IAAI,CAAA;CACf;AAED,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,KAAK,OAAO,CAAC;AAEnE,sCAAsC,CAAC,CAAE,SAAQ,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,UAAU,CAAC,EAAE,oBAAoB,CAAC,CAAC;IACzG,kGAAkG;IAClG,aAAa,CAAC,EAAE,QAAQ,CAAC;IACzB,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,uDAAuD;IACvD,iBAAiB,CAAC,EAAE,OAAO,CAAA;CAC5B;AAED;;;;GAIG;AACH,iCAAiC,CAAC,SAAS,MAAM,EAAE,KAAK,EAAE,qBAAqB,CAAC,CAAC,GAAG,cAAc,CAAC,CAAC,CA4UnG","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"}
@@ -28,7 +28,7 @@ $parcel$export(module.exports, "useComboBoxState", () => $e563f9c9469ad14c$expor
28
28
 
29
29
 
30
30
  function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
31
- var _collection_getItem, _collection_getItem1;
31
+ var _collection_getItem;
32
32
  let { defaultFilter: defaultFilter, menuTrigger: menuTrigger = 'input', allowsEmptyCollection: allowsEmptyCollection = false, allowsCustomValue: allowsCustomValue, shouldCloseOnBlur: shouldCloseOnBlur = true } = props;
33
33
  let [showAllItems, setShowAllItems] = (0, $2KOLe$react.useState)(false);
34
34
  let [isFocused, setFocusedState] = (0, $2KOLe$react.useState)(false);
@@ -48,8 +48,14 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
48
48
  onSelectionChange: onSelectionChange,
49
49
  items: (_props_items = props.items) !== null && _props_items !== void 0 ? _props_items : props.defaultItems
50
50
  });
51
- var _props_defaultInputValue, _ref;
52
- let [inputValue, setInputValue] = (0, $2KOLe$reactstatelyutils.useControlledState)(props.inputValue, (_ref = (_props_defaultInputValue = props.defaultInputValue) !== null && _props_defaultInputValue !== void 0 ? _props_defaultInputValue : (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _ref !== void 0 ? _ref : '', props.onInputChange);
51
+ let defaultInputValue = props.defaultInputValue;
52
+ if (defaultInputValue == null) {
53
+ var _collection_getItem1;
54
+ var _collection_getItem_textValue;
55
+ if (selectedKey == null) defaultInputValue = '';
56
+ else defaultInputValue = (_collection_getItem_textValue = (_collection_getItem1 = collection.getItem(selectedKey)) === null || _collection_getItem1 === void 0 ? void 0 : _collection_getItem1.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '';
57
+ }
58
+ let [inputValue, setInputValue] = (0, $2KOLe$reactstatelyutils.useControlledState)(props.inputValue, defaultInputValue, props.onInputChange);
53
59
  // Preserve original collection so we can show all items on demand
54
60
  let originalCollection = collection;
55
61
  let filteredCollection = (0, $2KOLe$react.useMemo)(()=>// No default filter if items are controlled.
@@ -126,14 +132,14 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
126
132
  let resetInputValue = ()=>{
127
133
  var _collection_getItem;
128
134
  var _collection_getItem_textValue;
129
- 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 : '';
135
+ let itemText = selectedKey != null ? (_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 : '' : '';
130
136
  setLastValue(itemText);
131
137
  setInputValue(itemText);
132
138
  };
133
- var _props_selectedKey, _ref1;
134
- let lastSelectedKey = (0, $2KOLe$react.useRef)((_ref1 = (_props_selectedKey = props.selectedKey) !== null && _props_selectedKey !== void 0 ? _props_selectedKey : props.defaultSelectedKey) !== null && _ref1 !== void 0 ? _ref1 : null);
135
- var _collection_getItem_textValue;
136
- let lastSelectedKeyText = (0, $2KOLe$react.useRef)((_collection_getItem_textValue = (_collection_getItem1 = collection.getItem(selectedKey)) === null || _collection_getItem1 === void 0 ? void 0 : _collection_getItem1.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '');
139
+ var _props_selectedKey, _ref;
140
+ let lastSelectedKey = (0, $2KOLe$react.useRef)((_ref = (_props_selectedKey = props.selectedKey) !== null && _props_selectedKey !== void 0 ? _props_selectedKey : props.defaultSelectedKey) !== null && _ref !== void 0 ? _ref : null);
141
+ var _collection_getItem_textValue1;
142
+ let lastSelectedKeyText = (0, $2KOLe$react.useRef)(selectedKey != null ? (_collection_getItem_textValue1 = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue1 !== void 0 ? _collection_getItem_textValue1 : '' : '');
137
143
  // intentional omit dependency array, want this to happen on every render
138
144
  // eslint-disable-next-line react-hooks/exhaustive-deps
139
145
  (0, $2KOLe$react.useEffect)(()=>{
@@ -164,7 +170,7 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
164
170
  // 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.
165
171
  // Only reset if the user isn't currently within the field so we don't erroneously modify user input.
166
172
  // If inputValue is controlled, it is the user's responsibility to update the inputValue when items change.
167
- 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 : '';
173
+ let selectedItemText = selectedKey != null ? (_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 : '' : '';
168
174
  if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {
169
175
  if (lastSelectedKeyText.current !== selectedItemText) {
170
176
  setLastValue(selectedItemText);
@@ -197,11 +203,11 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
197
203
  let commitSelection = ()=>{
198
204
  // If multiple things are controlled, call onSelectionChange
199
205
  if (props.selectedKey !== undefined && props.inputValue !== undefined) {
200
- var _collection_getItem;
201
- props.onSelectionChange(selectedKey);
206
+ var _props_onSelectionChange, _collection_getItem;
207
+ (_props_onSelectionChange = props.onSelectionChange) === null || _props_onSelectionChange === void 0 ? void 0 : _props_onSelectionChange.call(props, selectedKey);
202
208
  var _collection_getItem_textValue;
203
209
  // Stop menu from reopening from useEffect
204
- 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 : '';
210
+ let itemText = selectedKey != null ? (_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 : '' : '';
205
211
  setLastValue(itemText);
206
212
  closeMenu();
207
213
  } else {
@@ -214,7 +220,7 @@ function $e563f9c9469ad14c$export$b453a3bfd4a5fa9e(props) {
214
220
  if (allowsCustomValue) {
215
221
  var _collection_getItem;
216
222
  var _collection_getItem_textValue;
217
- const itemText = (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '';
223
+ const itemText = selectedKey != null ? (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '' : '';
218
224
  inputValue === itemText ? commitSelection() : commitCustomValue();
219
225
  } else // Reset inputValue and close menu
220
226
  commitSelection();
@@ -1 +1 @@
1
- {"mappings":";;;;;;;;;;;;;AAAA;;;;;;;;;;CAUC;;;;;;AA6CM,SAAS,0CAAmC,KAA8B;QAkClD,qBA+FI;IAhIjC,IAAI,iBACF,aAAa,eACb,cAAc,gCACd,wBAAwB,0BACxB,iBAAiB,qBACjB,oBAAoB,MACrB,GAAG;IAEJ,IAAI,CAAC,cAAc,gBAAgB,GAAG,CAAA,GAAA,qBAAO,EAAE;IAC/C,IAAI,CAAC,WAAW,gBAAgB,GAAG,CAAA,GAAA,qBAAO,EAAE;IAC5C,IAAI,CAAC,eAAe,iBAAiB,GAAG,CAAA,GAAA,qBAAO,EAAiB;IAEhE,IAAI,oBAAoB,CAAC;QACvB,IAAI,MAAM,iBAAiB,EACzB,MAAM,iBAAiB,CAAC;QAG1B,8DAA8D;QAC9D,qDAAqD;QACrD,IAAI,QAAQ,aAAa;YACvB;YACA;QACF;IACF;QAKS;IAHT,IAAI,cAAC,UAAU,oBAAE,gBAAgB,eAAE,WAAW,kBAAE,cAAc,gBAAE,YAAY,gBAAE,YAAY,EAAC,GAAG,CAAA,GAAA,gDAAuB,EAAE;QACrH,GAAG,KAAK;2BACR;QACA,OAAO,CAAA,eAAA,MAAM,KAAK,cAAX,0BAAA,eAAe,MAAM,YAAY;IAC1C;QAIE,0BAAA;IAFF,IAAI,CAAC,YAAY,cAAc,GAAG,CAAA,GAAA,2CAAiB,EACjD,MAAM,UAAU,EAChB,CAAA,OAAA,CAAA,2BAAA,MAAM,iBAAiB,cAAvB,sCAAA,4BAA2B,sBAAA,WAAW,OAAO,CAAC,0BAAnB,0CAAA,oBAAiC,SAAS,cAArE,kBAAA,OAAyE,IACzE,MAAM,aAAa;IAGrB,kEAAkE;IAClE,IAAI,qBAAqB;IACzB,IAAI,qBAAqB,CAAA,GAAA,oBAAM,EAAE,IAC/B,6CAA6C;QAC7C,MAAM,KAAK,IAAI,QAAQ,CAAC,gBACpB,aACA,uCAAiB,YAAY,YAAY,gBAC5C;QAAC;QAAY;QAAY;QAAe,MAAM,KAAK;KAAC;IACvD,IAAI,CAAC,gBAAgB,kBAAkB,GAAG,CAAA,GAAA,qBAAO,EAAE;IAEnD,mDAAmD;IACnD,IAAI,kBAAkB,CAAA,GAAA,mBAAK,EAAE;IAC7B,IAAI,eAAe,CAAC;QAClB,IAAI,MAAM,YAAY,EACpB,MAAM,YAAY,CAAC,MAAM,OAAO,gBAAgB,OAAO,GAAG;QAG5D,iBAAiB,UAAU,CAAC;QAC5B,IAAI,CAAC,MACH,iBAAiB,aAAa,CAAC;IAEnC;IAEA,IAAI,eAAe,CAAA,GAAA,kDAAqB,EAAE;QAAC,GAAG,KAAK;sBAAE;QAAc,QAAQ;QAAW,aAAa;IAAS;IAC5G,IAAI,OAAO,CAAC,gBAA+B,IAAI,EAAE;QAC/C,IAAI,kBAAmB,YAAY,YAAa,YAAY,WAAW,gBAAgB;QACvF,yEAAyE;QACzE,qIAAqI;QACrI,2QAA2Q;QAC3Q,IAAI,yBAAyB,mBAAmB,IAAI,GAAG,KAAM,mBAAmB,mBAAmB,IAAI,GAAG,KAAM,MAAM,KAAK,EAAE;YAC3H,IAAI,mBAAmB,CAAC,aAAa,MAAM,IAAI,MAAM,KAAK,KAAK,WAC7D,yFAAyF;YACzF,gBAAgB;YAGlB,gBAAgB,OAAO,GAAG;YAC1B,iBAAiB;YACjB,aAAa,IAAI;QACnB;IACF;IAEA,IAAI,SAAS,CAAC,gBAA+B,IAAI,EAAE;QACjD,IAAI,kBAAmB,YAAY,YAAa,YAAY,WAAW,gBAAgB;QACvF,gIAAgI;QAChI,IAAI,CAAE,CAAA,yBAAyB,mBAAmB,IAAI,GAAG,KAAM,mBAAmB,mBAAmB,IAAI,GAAG,KAAM,MAAM,KAAK,AAAD,KAAM,CAAC,aAAa,MAAM,EACpJ;QAGF,IAAI,mBAAmB,CAAC,aAAa,MAAM,IAAI,MAAM,KAAK,KAAK,WAC7D,sFAAsF;QACtF,gBAAgB;QAGlB,8DAA8D;QAC9D,IAAI,CAAC,aAAa,MAAM,EACtB,gBAAgB,OAAO,GAAG;QAG5B,WAAW;IACb;IAEA,IAAI,uBAAuB,CAAA,GAAA,wBAAU,EAAE;QACrC,kBAAkB,eAAe,qBAAqB;IACxD,GAAG;QAAC;QAAc;QAAoB;KAAmB;IAEzD,4GAA4G;IAC5G,kHAAkH;IAClH,IAAI,aAAa,CAAA,GAAA,wBAAU,EAAE,CAAC,gBAA+B,IAAI;QAC/D,IAAI,aAAa,MAAM,EACrB;QAGF,iBAAiB;QACjB,aAAa,MAAM;IACrB,GAAG;QAAC;QAAc;KAAqB;IAEvC,IAAI,YAAY,CAAA,GAAA,wBAAU,EAAE;QAC1B,IAAI,aAAa,MAAM,EAAE;YACvB;YACA,aAAa,KAAK;QACpB;IACF,GAAG;QAAC;QAAc;KAAqB;IAEvC,IAAI,CAAC,WAAW,aAAa,GAAG,CAAA,GAAA,qBAAO,EAAE;IACzC,IAAI,kBAAkB;YACL;YAAA;QAAf,IAAI,WAAW,CAAA,iCAAA,sBAAA,WAAW,OAAO,CAAC,0BAAnB,0CAAA,oBAAiC,SAAS,cAA1C,2CAAA,gCAA8C;QAC7D,aAAa;QACb,cAAc;IAChB;QAE6B,oBAAA;IAA7B,IAAI,kBAAkB,CAAA,GAAA,mBAAK,EAAE,CAAA,QAAA,CAAA,qBAAA,MAAM,WAAW,cAAjB,gCAAA,qBAAqB,MAAM,kBAAkB,cAA7C,mBAAA,QAAiD;QAC7C;IAAjC,IAAI,sBAAsB,CAAA,GAAA,mBAAK,EAAE,CAAA,iCAAA,uBAAA,WAAW,OAAO,CAAC,0BAAnB,2CAAA,qBAAiC,SAAS,cAA1C,2CAAA,gCAA8C;IAC/E,yEAAyE;IACzE,uDAAuD;IACvD,CAAA,GAAA,sBAAQ,EAAE;YA4De;QA3DvB,0FAA0F;QAC1F,yEAAyE;QACzE,IACE,aACC,CAAA,mBAAmB,IAAI,GAAG,KAAK,qBAAoB,KACpD,CAAC,aAAa,MAAM,IACpB,eAAe,aACf,gBAAgB,UAEhB,KAAK,MAAM;QAGb,+FAA+F;QAC/F,0DAA0D;QAC1D,IACE,CAAC,gBACD,CAAC,yBACD,aAAa,MAAM,IACnB,mBAAmB,IAAI,KAAK,GAE5B;QAGF,kCAAkC;QAClC,IACE,eAAe,QACf,gBAAgB,gBAAgB,OAAO,EAEvC;QAGF,oFAAoF;QACpF,IAAI,eAAe,WAAW;YAC5B,iBAAiB,aAAa,CAAC;YAC/B,gBAAgB;YAEhB,0DAA0D;YAC1D,qEAAqE;YACrE,IAAI,eAAe,MAAO,CAAA,MAAM,UAAU,KAAK,aAAa,MAAM,WAAW,KAAK,SAAQ,GACxF,eAAe;QAEnB;QAEA,sDAAsD;QACtD,gEAAgE;QAChE,0FAA0F;QAC1F,IACE,gBAAgB,gBAAgB,OAAO,IACtC,CAAA,MAAM,UAAU,KAAK,aAAa,MAAM,WAAW,KAAK,SAAQ,GAEjE;aACK,IAAI,cAAc,YACvB,aAAa;YAOQ;QAJvB,yFAAyF;QACzF,qJAAqJ;QACrJ,qGAAqG;QACrG,2GAA2G;QAC3G,IAAI,mBAAmB,CAAA,iCAAA,sBAAA,WAAW,OAAO,CAAC,0BAAnB,0CAAA,oBAAiC,SAAS,cAA1C,2CAAA,gCAA8C;QACrE,IAAI,CAAC,aAAa,eAAe,QAAQ,MAAM,UAAU,KAAK,aAAa,gBAAgB,gBAAgB,OAAO,EAChH;YAAA,IAAI,oBAAoB,OAAO,KAAK,kBAAkB;gBACpD,aAAa;gBACb,cAAc;YAChB;QAAA;QAGF,gBAAgB,OAAO,GAAG;QAC1B,oBAAoB,OAAO,GAAG;IAChC;IAEA,IAAI,aAAa,CAAA,GAAA,8CAAqB,EAAE;QACtC,GAAG,KAAK;QACR,OAAO,CAAA,GAAA,oBAAM,EAAE,IAAO,CAAA;4BAAC;6BAAY;YAAW,CAAA,GAAI;YAAC;YAAY;SAAY;IAC7E;IAEA,oCAAoC;IACpC,IAAI,SAAS;QACX,IAAI,qBAAqB,eAAe,MACtC;aAEA;IAEJ;IAEA,IAAI,oBAAoB;QACtB,gBAAgB,OAAO,GAAG;QAC1B,eAAe;QACf;IACF;IAEA,IAAI,kBAAkB;QACpB,4DAA4D;QAC5D,IAAI,MAAM,WAAW,KAAK,aAAa,MAAM,UAAU,KAAK,WAAW;gBAItD;YAHf,MAAM,iBAAiB,CAAC;gBAGT;YADf,0CAA0C;YAC1C,IAAI,WAAW,CAAA,iCAAA,sBAAA,WAAW,OAAO,CAAC,0BAAnB,0CAAA,oBAAiC,SAAS,cAA1C,2CAAA,gCAA8C;YAC7D,aAAa;YACb;QACF,OAAO;YACL,mGAAmG;YACnG;YACA;QACF;IACF;IAEA,MAAM,cAAc;QAClB,IAAI,mBAAmB;gBACJ;gBAAA;YAAjB,MAAM,WAAW,CAAA,iCAAA,sBAAA,WAAW,OAAO,CAAC,0BAAnB,0CAAA,oBAAiC,SAAS,cAA1C,2CAAA,gCAA8C;YAC9D,eAAe,WAAY,oBAAoB;QAClD,OACE,kCAAkC;QAClC;IAEJ;IAEA,IAAI,SAAS;QACX,IAAI,aAAa,MAAM,IAAI,iBAAiB,UAAU,IAAI;YACxD,iGAAiG;YACjG,0EAA0E;YAC1E,IAAI,gBAAgB,iBAAiB,UAAU,EAC7C;iBAEA,eAAe,iBAAiB,UAAU;eAG5C;IAEJ;IAEA,IAAI,eAAe,CAAA,GAAA,mBAAK,EAAE;IAC1B,IAAI,aAAa,CAAC;QAChB,IAAI,WAAW;YACb,aAAa,OAAO,GAAG;YACvB,IAAI,gBAAgB,WAAW,CAAC,MAAM,UAAU,EAC9C,KAAK,MAAM;QAEf,OAAO;YACL,IAAI,mBACF;YAGF,IAAI,eAAe,aAAa,OAAO,EACrC,WAAW,gBAAgB;QAE/B;QAEA,gBAAgB;IAClB;IAEA,IAAI,sBAAsB,CAAA,GAAA,oBAAM,EAAE;QAChC,IAAI,aAAa,MAAM,EAAE;YACvB,IAAI,cACF,OAAO;iBAEP,OAAO;QAEX,OACE,OAAO;IAEX,GAAG;QAAC,aAAa,MAAM;QAAE;QAAoB;QAAoB;QAAc;KAAe;IAE9F,OAAO;QACL,GAAG,UAAU;QACb,GAAG,YAAY;uBACf;gBACA;cACA;QACA,OAAO;0BACP;qBACA;wBACA;sBACA;mBACA;oBACA;sBACA;QACA,YAAY;oBACZ;uBACA;gBACA;gBACA;IACF;AACF;AAEA,SAAS,uCAAmC,UAA+B,EAAE,UAAkB,EAAE,MAAgB;IAC/G,OAAO,IAAI,CAAA,GAAA,sCAAa,EAAE,kCAAY,YAAY,YAAY,YAAY;AAC5E;AAEA,SAAS,kCAAe,UAA+B,EAAE,KAAwB,EAAE,UAAkB,EAAE,MAAgB;IACrH,IAAI,eAAe,EAAE;IACrB,KAAK,IAAI,QAAQ,MAAO;QACtB,IAAI,KAAK,IAAI,KAAK,aAAa,KAAK,aAAa,EAAE;YACjD,IAAI,WAAW,kCAAY,YAAY,CAAA,GAAA,4CAAY,EAAE,MAAM,aAAa,YAAY;YACpF,IAAI;mBAAI;aAAS,CAAC,IAAI,CAAC,CAAA,OAAQ,KAAK,IAAI,KAAK,SAC3C,aAAa,IAAI,CAAC;gBAAC,GAAG,IAAI;gBAAE,YAAY;YAAQ;QAEpD,OAAO,IAAI,KAAK,IAAI,KAAK,UAAU,OAAO,KAAK,SAAS,EAAE,aACxD,aAAa,IAAI,CAAC;YAAC,GAAG,IAAI;QAAA;aACrB,IAAI,KAAK,IAAI,KAAK,QACvB,aAAa,IAAI,CAAC;YAAC,GAAG,IAAI;QAAA;IAE9B;IACA,OAAO;AACT","sources":["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\nimport {Collection, CollectionStateBase, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {FormValidationState, useFormValidationState} from '@react-stately/form';\nimport {getChildNodes} from '@react-stately/collections';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useControlledState} from '@react-stately/utils';\nimport {useOverlayTriggerState} from '@react-stately/overlays';\n\nexport interface ComboBoxState<T> extends SelectState<T>, FormValidationState{\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 /** Controls which item will be auto focused when the menu opens. */\n readonly focusStrategy: FocusStrategy,\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Resets the input value to the previously selected item's text if any and closes the menu. */\n revert(): void\n}\n\ntype FilterFn = (textValue: string, inputValue: string) => boolean;\n\nexport interface ComboBoxStateOptions<T> extends Omit<ComboBoxProps<T>, 'children'>, CollectionStateBase<T> {\n /** The filter function used to determine if a option should be included in the combo box list. */\n defaultFilter?: FilterFn,\n /** Whether the combo box allows the menu to be open when the collection is empty. */\n allowsEmptyCollection?: boolean,\n /** Whether the combo box menu should close on blur. */\n shouldCloseOnBlur?: boolean\n}\n\n/**\n * Provides state management for a combo box component. Handles building a collection\n * of items from props and manages the option selection state of the combo box. In addition, it tracks the input value,\n * focus state, and other properties of the combo box.\n */\nexport function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T>): ComboBoxState<T> {\n let {\n defaultFilter,\n menuTrigger = 'input',\n allowsEmptyCollection = false,\n allowsCustomValue,\n shouldCloseOnBlur = true\n } = props;\n\n let [showAllItems, setShowAllItems] = useState(false);\n let [isFocused, setFocusedState] = useState(false);\n let [focusStrategy, setFocusStrategy] = useState<FocusStrategy>(null);\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 let [inputValue, setInputValue] = useControlledState(\n props.inputValue,\n props.defaultInputValue ?? collection.getItem(selectedKey)?.textValue ?? '',\n props.onInputChange\n );\n\n // Preserve original collection so we can show all items on demand\n let originalCollection = collection;\n let filteredCollection = useMemo(() => (\n // No default filter if items are controlled.\n props.items != null || !defaultFilter\n ? collection\n : filterCollection(collection, inputValue, defaultFilter)\n ), [collection, inputValue, defaultFilter, props.items]);\n let [lastCollection, setLastCollection] = useState(filteredCollection);\n\n // Track what action is attempting to open the menu\n let menuOpenTrigger = useRef('focus' as MenuTriggerAction);\n let onOpenChange = (open: boolean) => {\n if (props.onOpenChange) {\n props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);\n }\n\n selectionManager.setFocused(open);\n if (!open) {\n selectionManager.setFocusedKey(null);\n }\n };\n\n let triggerState = useOverlayTriggerState({...props, onOpenChange, isOpen: undefined, defaultOpen: undefined});\n let open = (focusStrategy: FocusStrategy = null, 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 setFocusStrategy(focusStrategy);\n triggerState.open();\n }\n };\n\n let toggle = (focusStrategy: FocusStrategy = null, 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 let updateLastCollection = useCallback(() => {\n setLastCollection(showAllItems ? originalCollection : filteredCollection);\n }, [showAllItems, originalCollection, filteredCollection]);\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: FocusStrategy = null) => {\n if (triggerState.isOpen) {\n updateLastCollection();\n }\n\n setFocusStrategy(focusStrategy);\n triggerState.toggle();\n }, [triggerState, updateLastCollection]);\n\n let closeMenu = useCallback(() => {\n if (triggerState.isOpen) {\n updateLastCollection();\n triggerState.close();\n }\n }, [triggerState, updateLastCollection]);\n\n let [lastValue, setLastValue] = useState(inputValue);\n let resetInputValue = () => {\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n setLastValue(itemText);\n setInputValue(itemText);\n };\n\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 &&\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) {\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 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 if (lastValue !== inputValue) {\n setLastValue(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 setLastValue(selectedItemText);\n setInputValue(selectedItemText);\n }\n }\n\n lastSelectedKey.current = selectedKey;\n lastSelectedKeyText.current = selectedItemText;\n });\n\n let validation = useFormValidationState({\n ...props,\n value: useMemo(() => ({inputValue, selectedKey}), [inputValue, selectedKey])\n });\n\n // Revert input value and close menu\n let revert = () => {\n if (allowsCustomValue && selectedKey == null) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n };\n\n let commitCustomValue = () => {\n lastSelectedKey.current = null;\n setSelectedKey(null);\n closeMenu();\n };\n\n let commitSelection = () => {\n // If multiple things are controlled, call onSelectionChange\n if (props.selectedKey !== undefined && props.inputValue !== undefined) {\n props.onSelectionChange(selectedKey);\n\n // Stop menu from reopening from useEffect\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n setLastValue(itemText);\n closeMenu();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n closeMenu();\n }\n };\n\n const commitValue = () => {\n if (allowsCustomValue) {\n const itemText = collection.getItem(selectedKey)?.textValue ?? '';\n (inputValue === itemText) ? commitSelection() : commitCustomValue();\n } else {\n // Reset inputValue and close menu\n commitSelection();\n }\n };\n\n let commit = () => {\n if (triggerState.isOpen && selectionManager.focusedKey != null) {\n // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise\n // fire onSelectionChange to allow the application to control the closing.\n if (selectedKey === selectionManager.focusedKey) {\n commitSelection();\n } else {\n setSelectedKey(selectionManager.focusedKey);\n }\n } else {\n commitValue();\n }\n };\n\n let valueOnFocus = useRef(inputValue);\n let setFocused = (isFocused: boolean) => {\n if (isFocused) {\n valueOnFocus.current = inputValue;\n if (menuTrigger === 'focus' && !props.isReadOnly) {\n open(null, 'focus');\n }\n } else {\n if (shouldCloseOnBlur) {\n commitValue();\n }\n\n if (inputValue !== valueOnFocus.current) {\n validation.commitValidation();\n }\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 ...validation,\n ...triggerState,\n focusStrategy,\n toggle,\n open,\n close: commitValue,\n selectionManager,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: displayedCollection,\n inputValue,\n setInputValue,\n commit,\n revert\n };\n}\n\nfunction filterCollection<T extends object>(collection: Collection<Node<T>>, inputValue: string, filter: FilterFn): Collection<Node<T>> {\n return new ListCollection(filterNodes(collection, collection, inputValue, filter));\n}\n\nfunction filterNodes<T>(collection: Collection<Node<T>>, nodes: Iterable<Node<T>>, inputValue: string, filter: FilterFn): Iterable<Node<T>> {\n let filteredNode = [];\n for (let node of nodes) {\n if (node.type === 'section' && node.hasChildNodes) {\n let filtered = filterNodes(collection, getChildNodes(node, collection), inputValue, filter);\n if ([...filtered].some(node => node.type === 'item')) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type === 'item' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n } else if (node.type !== 'item') {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"useComboBoxState.main.js.map"}
1
+ {"mappings":"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","sources":["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\nimport {Collection, CollectionStateBase, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {FormValidationState, useFormValidationState} from '@react-stately/form';\nimport {getChildNodes} from '@react-stately/collections';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useControlledState} from '@react-stately/utils';\nimport {useOverlayTriggerState} from '@react-stately/overlays';\n\nexport interface ComboBoxState<T> extends SelectState<T>, FormValidationState{\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 /** Controls which item will be auto focused when the menu opens. */\n readonly focusStrategy: FocusStrategy | null,\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Resets the input value to the previously selected item's text if any and closes the menu. */\n revert(): void\n}\n\ntype FilterFn = (textValue: string, inputValue: string) => boolean;\n\nexport interface ComboBoxStateOptions<T> extends Omit<ComboBoxProps<T>, 'children'>, CollectionStateBase<T> {\n /** The filter function used to determine if a option should be included in the combo box list. */\n defaultFilter?: FilterFn,\n /** Whether the combo box allows the menu to be open when the collection is empty. */\n allowsEmptyCollection?: boolean,\n /** Whether the combo box menu should close on blur. */\n shouldCloseOnBlur?: boolean\n}\n\n/**\n * Provides state management for a combo box component. Handles building a collection\n * of items from props and manages the option selection state of the combo box. In addition, it tracks the input value,\n * focus state, and other properties of the combo box.\n */\nexport function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T>): ComboBoxState<T> {\n let {\n defaultFilter,\n menuTrigger = 'input',\n allowsEmptyCollection = false,\n allowsCustomValue,\n shouldCloseOnBlur = true\n } = props;\n\n let [showAllItems, setShowAllItems] = useState(false);\n let [isFocused, setFocusedState] = useState(false);\n let [focusStrategy, setFocusStrategy] = useState<FocusStrategy | null>(null);\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,\n selectionManager,\n selectedKey,\n setSelectedKey,\n selectedItem,\n disabledKeys\n } = useSingleSelectListState({\n ...props,\n onSelectionChange,\n items: props.items ?? props.defaultItems\n });\n let defaultInputValue: string | null | undefined = props.defaultInputValue;\n if (defaultInputValue == null) {\n if (selectedKey == null) {\n defaultInputValue = '';\n } else {\n defaultInputValue = collection.getItem(selectedKey)?.textValue ?? '';\n }\n }\n\n let [inputValue, setInputValue] = useControlledState(\n props.inputValue,\n defaultInputValue!,\n props.onInputChange\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<MenuTriggerAction | undefined>('focus');\n let onOpenChange = (open: boolean) => {\n if (props.onOpenChange) {\n props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);\n }\n\n selectionManager.setFocused(open);\n if (!open) {\n selectionManager.setFocusedKey(null);\n }\n };\n\n let triggerState = useOverlayTriggerState({...props, onOpenChange, isOpen: undefined, defaultOpen: undefined});\n let open = (focusStrategy: FocusStrategy | null = null, 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 setFocusStrategy(focusStrategy);\n triggerState.open();\n }\n };\n\n let toggle = (focusStrategy: FocusStrategy | null = null, 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 let updateLastCollection = useCallback(() => {\n setLastCollection(showAllItems ? originalCollection : filteredCollection);\n }, [showAllItems, originalCollection, filteredCollection]);\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: FocusStrategy | null = null) => {\n if (triggerState.isOpen) {\n updateLastCollection();\n }\n\n setFocusStrategy(focusStrategy);\n triggerState.toggle();\n }, [triggerState, updateLastCollection]);\n\n let closeMenu = useCallback(() => {\n if (triggerState.isOpen) {\n updateLastCollection();\n triggerState.close();\n }\n }, [triggerState, updateLastCollection]);\n\n let [lastValue, setLastValue] = useState(inputValue);\n let resetInputValue = () => {\n let itemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';\n setLastValue(itemText);\n setInputValue(itemText);\n };\n\n let lastSelectedKey = useRef(props.selectedKey ?? props.defaultSelectedKey ?? null);\n let lastSelectedKeyText = useRef(\n selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : ''\n );\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 &&\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) {\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 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 if (lastValue !== inputValue) {\n setLastValue(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 = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';\n if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {\n if (lastSelectedKeyText.current !== selectedItemText) {\n setLastValue(selectedItemText);\n setInputValue(selectedItemText);\n }\n }\n\n lastSelectedKey.current = selectedKey;\n lastSelectedKeyText.current = selectedItemText;\n });\n\n let validation = useFormValidationState({\n ...props,\n value: useMemo(() => ({inputValue, selectedKey}), [inputValue, selectedKey])\n });\n\n // Revert input value and close menu\n let revert = () => {\n if (allowsCustomValue && selectedKey == null) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n };\n\n let commitCustomValue = () => {\n lastSelectedKey.current = null;\n setSelectedKey(null);\n closeMenu();\n };\n\n let commitSelection = () => {\n // If multiple things are controlled, call onSelectionChange\n if (props.selectedKey !== undefined && props.inputValue !== undefined) {\n props.onSelectionChange?.(selectedKey);\n\n // Stop menu from reopening from useEffect\n let itemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';\n setLastValue(itemText);\n closeMenu();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n closeMenu();\n }\n };\n\n const commitValue = () => {\n if (allowsCustomValue) {\n const itemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';\n (inputValue === itemText) ? commitSelection() : commitCustomValue();\n } else {\n // Reset inputValue and close menu\n commitSelection();\n }\n };\n\n let commit = () => {\n if (triggerState.isOpen && selectionManager.focusedKey != null) {\n // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise\n // fire onSelectionChange to allow the application to control the closing.\n if (selectedKey === selectionManager.focusedKey) {\n commitSelection();\n } else {\n setSelectedKey(selectionManager.focusedKey);\n }\n } else {\n commitValue();\n }\n };\n\n let valueOnFocus = useRef(inputValue);\n let setFocused = (isFocused: boolean) => {\n if (isFocused) {\n valueOnFocus.current = inputValue;\n if (menuTrigger === 'focus' && !props.isReadOnly) {\n open(null, 'focus');\n }\n } else {\n if (shouldCloseOnBlur) {\n commitValue();\n }\n\n if (inputValue !== valueOnFocus.current) {\n validation.commitValidation();\n }\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 ...validation,\n ...triggerState,\n focusStrategy,\n toggle,\n open,\n close: commitValue,\n selectionManager,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: displayedCollection,\n inputValue,\n setInputValue,\n commit,\n revert\n };\n}\n\nfunction filterCollection<T extends object>(collection: Collection<Node<T>>, inputValue: string, filter: FilterFn): Collection<Node<T>> {\n return new ListCollection(filterNodes(collection, collection, inputValue, filter));\n}\n\nfunction filterNodes<T>(collection: Collection<Node<T>>, nodes: Iterable<Node<T>>, inputValue: string, filter: FilterFn): Iterable<Node<T>> {\n let filteredNode: Node<T>[] = [];\n for (let node of nodes) {\n if (node.type === 'section' && node.hasChildNodes) {\n let filtered = filterNodes(collection, getChildNodes(node, collection), inputValue, filter);\n if ([...filtered].some(node => node.type === 'item')) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type === 'item' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n } else if (node.type !== 'item') {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"useComboBoxState.main.js.map"}
@@ -22,7 +22,7 @@ import {useOverlayTriggerState as $49BJP$useOverlayTriggerState} from "@react-st
22
22
 
23
23
 
24
24
  function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
25
- var _collection_getItem, _collection_getItem1;
25
+ var _collection_getItem;
26
26
  let { defaultFilter: defaultFilter, menuTrigger: menuTrigger = 'input', allowsEmptyCollection: allowsEmptyCollection = false, allowsCustomValue: allowsCustomValue, shouldCloseOnBlur: shouldCloseOnBlur = true } = props;
27
27
  let [showAllItems, setShowAllItems] = (0, $49BJP$useState)(false);
28
28
  let [isFocused, setFocusedState] = (0, $49BJP$useState)(false);
@@ -42,8 +42,14 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
42
42
  onSelectionChange: onSelectionChange,
43
43
  items: (_props_items = props.items) !== null && _props_items !== void 0 ? _props_items : props.defaultItems
44
44
  });
45
- var _props_defaultInputValue, _ref;
46
- let [inputValue, setInputValue] = (0, $49BJP$useControlledState)(props.inputValue, (_ref = (_props_defaultInputValue = props.defaultInputValue) !== null && _props_defaultInputValue !== void 0 ? _props_defaultInputValue : (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _ref !== void 0 ? _ref : '', props.onInputChange);
45
+ let defaultInputValue = props.defaultInputValue;
46
+ if (defaultInputValue == null) {
47
+ var _collection_getItem1;
48
+ var _collection_getItem_textValue;
49
+ if (selectedKey == null) defaultInputValue = '';
50
+ else defaultInputValue = (_collection_getItem_textValue = (_collection_getItem1 = collection.getItem(selectedKey)) === null || _collection_getItem1 === void 0 ? void 0 : _collection_getItem1.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '';
51
+ }
52
+ let [inputValue, setInputValue] = (0, $49BJP$useControlledState)(props.inputValue, defaultInputValue, props.onInputChange);
47
53
  // Preserve original collection so we can show all items on demand
48
54
  let originalCollection = collection;
49
55
  let filteredCollection = (0, $49BJP$useMemo)(()=>// No default filter if items are controlled.
@@ -120,14 +126,14 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
120
126
  let resetInputValue = ()=>{
121
127
  var _collection_getItem;
122
128
  var _collection_getItem_textValue;
123
- 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 : '';
129
+ let itemText = selectedKey != null ? (_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 : '' : '';
124
130
  setLastValue(itemText);
125
131
  setInputValue(itemText);
126
132
  };
127
- var _props_selectedKey, _ref1;
128
- let lastSelectedKey = (0, $49BJP$useRef)((_ref1 = (_props_selectedKey = props.selectedKey) !== null && _props_selectedKey !== void 0 ? _props_selectedKey : props.defaultSelectedKey) !== null && _ref1 !== void 0 ? _ref1 : null);
129
- var _collection_getItem_textValue;
130
- let lastSelectedKeyText = (0, $49BJP$useRef)((_collection_getItem_textValue = (_collection_getItem1 = collection.getItem(selectedKey)) === null || _collection_getItem1 === void 0 ? void 0 : _collection_getItem1.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '');
133
+ var _props_selectedKey, _ref;
134
+ let lastSelectedKey = (0, $49BJP$useRef)((_ref = (_props_selectedKey = props.selectedKey) !== null && _props_selectedKey !== void 0 ? _props_selectedKey : props.defaultSelectedKey) !== null && _ref !== void 0 ? _ref : null);
135
+ var _collection_getItem_textValue1;
136
+ let lastSelectedKeyText = (0, $49BJP$useRef)(selectedKey != null ? (_collection_getItem_textValue1 = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue1 !== void 0 ? _collection_getItem_textValue1 : '' : '');
131
137
  // intentional omit dependency array, want this to happen on every render
132
138
  // eslint-disable-next-line react-hooks/exhaustive-deps
133
139
  (0, $49BJP$useEffect)(()=>{
@@ -158,7 +164,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
158
164
  // 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.
159
165
  // Only reset if the user isn't currently within the field so we don't erroneously modify user input.
160
166
  // If inputValue is controlled, it is the user's responsibility to update the inputValue when items change.
161
- 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 : '';
167
+ let selectedItemText = selectedKey != null ? (_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 : '' : '';
162
168
  if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {
163
169
  if (lastSelectedKeyText.current !== selectedItemText) {
164
170
  setLastValue(selectedItemText);
@@ -191,11 +197,11 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
191
197
  let commitSelection = ()=>{
192
198
  // If multiple things are controlled, call onSelectionChange
193
199
  if (props.selectedKey !== undefined && props.inputValue !== undefined) {
194
- var _collection_getItem;
195
- props.onSelectionChange(selectedKey);
200
+ var _props_onSelectionChange, _collection_getItem;
201
+ (_props_onSelectionChange = props.onSelectionChange) === null || _props_onSelectionChange === void 0 ? void 0 : _props_onSelectionChange.call(props, selectedKey);
196
202
  var _collection_getItem_textValue;
197
203
  // Stop menu from reopening from useEffect
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 : '';
204
+ let itemText = selectedKey != null ? (_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 : '' : '';
199
205
  setLastValue(itemText);
200
206
  closeMenu();
201
207
  } else {
@@ -208,7 +214,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
208
214
  if (allowsCustomValue) {
209
215
  var _collection_getItem;
210
216
  var _collection_getItem_textValue;
211
- const itemText = (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '';
217
+ const itemText = selectedKey != null ? (_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 : '' : '';
212
218
  inputValue === itemText ? commitSelection() : commitCustomValue();
213
219
  } else // Reset inputValue and close menu
214
220
  commitSelection();
@@ -22,7 +22,7 @@ import {useOverlayTriggerState as $49BJP$useOverlayTriggerState} from "@react-st
22
22
 
23
23
 
24
24
  function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
25
- var _collection_getItem, _collection_getItem1;
25
+ var _collection_getItem;
26
26
  let { defaultFilter: defaultFilter, menuTrigger: menuTrigger = 'input', allowsEmptyCollection: allowsEmptyCollection = false, allowsCustomValue: allowsCustomValue, shouldCloseOnBlur: shouldCloseOnBlur = true } = props;
27
27
  let [showAllItems, setShowAllItems] = (0, $49BJP$useState)(false);
28
28
  let [isFocused, setFocusedState] = (0, $49BJP$useState)(false);
@@ -42,8 +42,14 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
42
42
  onSelectionChange: onSelectionChange,
43
43
  items: (_props_items = props.items) !== null && _props_items !== void 0 ? _props_items : props.defaultItems
44
44
  });
45
- var _props_defaultInputValue, _ref;
46
- let [inputValue, setInputValue] = (0, $49BJP$useControlledState)(props.inputValue, (_ref = (_props_defaultInputValue = props.defaultInputValue) !== null && _props_defaultInputValue !== void 0 ? _props_defaultInputValue : (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _ref !== void 0 ? _ref : '', props.onInputChange);
45
+ let defaultInputValue = props.defaultInputValue;
46
+ if (defaultInputValue == null) {
47
+ var _collection_getItem1;
48
+ var _collection_getItem_textValue;
49
+ if (selectedKey == null) defaultInputValue = '';
50
+ else defaultInputValue = (_collection_getItem_textValue = (_collection_getItem1 = collection.getItem(selectedKey)) === null || _collection_getItem1 === void 0 ? void 0 : _collection_getItem1.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '';
51
+ }
52
+ let [inputValue, setInputValue] = (0, $49BJP$useControlledState)(props.inputValue, defaultInputValue, props.onInputChange);
47
53
  // Preserve original collection so we can show all items on demand
48
54
  let originalCollection = collection;
49
55
  let filteredCollection = (0, $49BJP$useMemo)(()=>// No default filter if items are controlled.
@@ -120,14 +126,14 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
120
126
  let resetInputValue = ()=>{
121
127
  var _collection_getItem;
122
128
  var _collection_getItem_textValue;
123
- 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 : '';
129
+ let itemText = selectedKey != null ? (_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 : '' : '';
124
130
  setLastValue(itemText);
125
131
  setInputValue(itemText);
126
132
  };
127
- var _props_selectedKey, _ref1;
128
- let lastSelectedKey = (0, $49BJP$useRef)((_ref1 = (_props_selectedKey = props.selectedKey) !== null && _props_selectedKey !== void 0 ? _props_selectedKey : props.defaultSelectedKey) !== null && _ref1 !== void 0 ? _ref1 : null);
129
- var _collection_getItem_textValue;
130
- let lastSelectedKeyText = (0, $49BJP$useRef)((_collection_getItem_textValue = (_collection_getItem1 = collection.getItem(selectedKey)) === null || _collection_getItem1 === void 0 ? void 0 : _collection_getItem1.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '');
133
+ var _props_selectedKey, _ref;
134
+ let lastSelectedKey = (0, $49BJP$useRef)((_ref = (_props_selectedKey = props.selectedKey) !== null && _props_selectedKey !== void 0 ? _props_selectedKey : props.defaultSelectedKey) !== null && _ref !== void 0 ? _ref : null);
135
+ var _collection_getItem_textValue1;
136
+ let lastSelectedKeyText = (0, $49BJP$useRef)(selectedKey != null ? (_collection_getItem_textValue1 = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue1 !== void 0 ? _collection_getItem_textValue1 : '' : '');
131
137
  // intentional omit dependency array, want this to happen on every render
132
138
  // eslint-disable-next-line react-hooks/exhaustive-deps
133
139
  (0, $49BJP$useEffect)(()=>{
@@ -158,7 +164,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
158
164
  // 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.
159
165
  // Only reset if the user isn't currently within the field so we don't erroneously modify user input.
160
166
  // If inputValue is controlled, it is the user's responsibility to update the inputValue when items change.
161
- 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 : '';
167
+ let selectedItemText = selectedKey != null ? (_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 : '' : '';
162
168
  if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {
163
169
  if (lastSelectedKeyText.current !== selectedItemText) {
164
170
  setLastValue(selectedItemText);
@@ -191,11 +197,11 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
191
197
  let commitSelection = ()=>{
192
198
  // If multiple things are controlled, call onSelectionChange
193
199
  if (props.selectedKey !== undefined && props.inputValue !== undefined) {
194
- var _collection_getItem;
195
- props.onSelectionChange(selectedKey);
200
+ var _props_onSelectionChange, _collection_getItem;
201
+ (_props_onSelectionChange = props.onSelectionChange) === null || _props_onSelectionChange === void 0 ? void 0 : _props_onSelectionChange.call(props, selectedKey);
196
202
  var _collection_getItem_textValue;
197
203
  // Stop menu from reopening from useEffect
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 : '';
204
+ let itemText = selectedKey != null ? (_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 : '' : '';
199
205
  setLastValue(itemText);
200
206
  closeMenu();
201
207
  } else {
@@ -208,7 +214,7 @@ function $a9e7382a7d111cb5$export$b453a3bfd4a5fa9e(props) {
208
214
  if (allowsCustomValue) {
209
215
  var _collection_getItem;
210
216
  var _collection_getItem_textValue;
211
- const itemText = (_collection_getItem_textValue = (_collection_getItem = collection.getItem(selectedKey)) === null || _collection_getItem === void 0 ? void 0 : _collection_getItem.textValue) !== null && _collection_getItem_textValue !== void 0 ? _collection_getItem_textValue : '';
217
+ const itemText = selectedKey != null ? (_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 : '' : '';
212
218
  inputValue === itemText ? commitSelection() : commitCustomValue();
213
219
  } else // Reset inputValue and close menu
214
220
  commitSelection();
@@ -1 +1 @@
1
- {"mappings":"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","sources":["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\nimport {Collection, CollectionStateBase, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {FormValidationState, useFormValidationState} from '@react-stately/form';\nimport {getChildNodes} from '@react-stately/collections';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useControlledState} from '@react-stately/utils';\nimport {useOverlayTriggerState} from '@react-stately/overlays';\n\nexport interface ComboBoxState<T> extends SelectState<T>, FormValidationState{\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 /** Controls which item will be auto focused when the menu opens. */\n readonly focusStrategy: FocusStrategy,\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Resets the input value to the previously selected item's text if any and closes the menu. */\n revert(): void\n}\n\ntype FilterFn = (textValue: string, inputValue: string) => boolean;\n\nexport interface ComboBoxStateOptions<T> extends Omit<ComboBoxProps<T>, 'children'>, CollectionStateBase<T> {\n /** The filter function used to determine if a option should be included in the combo box list. */\n defaultFilter?: FilterFn,\n /** Whether the combo box allows the menu to be open when the collection is empty. */\n allowsEmptyCollection?: boolean,\n /** Whether the combo box menu should close on blur. */\n shouldCloseOnBlur?: boolean\n}\n\n/**\n * Provides state management for a combo box component. Handles building a collection\n * of items from props and manages the option selection state of the combo box. In addition, it tracks the input value,\n * focus state, and other properties of the combo box.\n */\nexport function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T>): ComboBoxState<T> {\n let {\n defaultFilter,\n menuTrigger = 'input',\n allowsEmptyCollection = false,\n allowsCustomValue,\n shouldCloseOnBlur = true\n } = props;\n\n let [showAllItems, setShowAllItems] = useState(false);\n let [isFocused, setFocusedState] = useState(false);\n let [focusStrategy, setFocusStrategy] = useState<FocusStrategy>(null);\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 let [inputValue, setInputValue] = useControlledState(\n props.inputValue,\n props.defaultInputValue ?? collection.getItem(selectedKey)?.textValue ?? '',\n props.onInputChange\n );\n\n // Preserve original collection so we can show all items on demand\n let originalCollection = collection;\n let filteredCollection = useMemo(() => (\n // No default filter if items are controlled.\n props.items != null || !defaultFilter\n ? collection\n : filterCollection(collection, inputValue, defaultFilter)\n ), [collection, inputValue, defaultFilter, props.items]);\n let [lastCollection, setLastCollection] = useState(filteredCollection);\n\n // Track what action is attempting to open the menu\n let menuOpenTrigger = useRef('focus' as MenuTriggerAction);\n let onOpenChange = (open: boolean) => {\n if (props.onOpenChange) {\n props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);\n }\n\n selectionManager.setFocused(open);\n if (!open) {\n selectionManager.setFocusedKey(null);\n }\n };\n\n let triggerState = useOverlayTriggerState({...props, onOpenChange, isOpen: undefined, defaultOpen: undefined});\n let open = (focusStrategy: FocusStrategy = null, 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 setFocusStrategy(focusStrategy);\n triggerState.open();\n }\n };\n\n let toggle = (focusStrategy: FocusStrategy = null, 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 let updateLastCollection = useCallback(() => {\n setLastCollection(showAllItems ? originalCollection : filteredCollection);\n }, [showAllItems, originalCollection, filteredCollection]);\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: FocusStrategy = null) => {\n if (triggerState.isOpen) {\n updateLastCollection();\n }\n\n setFocusStrategy(focusStrategy);\n triggerState.toggle();\n }, [triggerState, updateLastCollection]);\n\n let closeMenu = useCallback(() => {\n if (triggerState.isOpen) {\n updateLastCollection();\n triggerState.close();\n }\n }, [triggerState, updateLastCollection]);\n\n let [lastValue, setLastValue] = useState(inputValue);\n let resetInputValue = () => {\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n setLastValue(itemText);\n setInputValue(itemText);\n };\n\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 &&\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) {\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 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 if (lastValue !== inputValue) {\n setLastValue(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 setLastValue(selectedItemText);\n setInputValue(selectedItemText);\n }\n }\n\n lastSelectedKey.current = selectedKey;\n lastSelectedKeyText.current = selectedItemText;\n });\n\n let validation = useFormValidationState({\n ...props,\n value: useMemo(() => ({inputValue, selectedKey}), [inputValue, selectedKey])\n });\n\n // Revert input value and close menu\n let revert = () => {\n if (allowsCustomValue && selectedKey == null) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n };\n\n let commitCustomValue = () => {\n lastSelectedKey.current = null;\n setSelectedKey(null);\n closeMenu();\n };\n\n let commitSelection = () => {\n // If multiple things are controlled, call onSelectionChange\n if (props.selectedKey !== undefined && props.inputValue !== undefined) {\n props.onSelectionChange(selectedKey);\n\n // Stop menu from reopening from useEffect\n let itemText = collection.getItem(selectedKey)?.textValue ?? '';\n setLastValue(itemText);\n closeMenu();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n closeMenu();\n }\n };\n\n const commitValue = () => {\n if (allowsCustomValue) {\n const itemText = collection.getItem(selectedKey)?.textValue ?? '';\n (inputValue === itemText) ? commitSelection() : commitCustomValue();\n } else {\n // Reset inputValue and close menu\n commitSelection();\n }\n };\n\n let commit = () => {\n if (triggerState.isOpen && selectionManager.focusedKey != null) {\n // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise\n // fire onSelectionChange to allow the application to control the closing.\n if (selectedKey === selectionManager.focusedKey) {\n commitSelection();\n } else {\n setSelectedKey(selectionManager.focusedKey);\n }\n } else {\n commitValue();\n }\n };\n\n let valueOnFocus = useRef(inputValue);\n let setFocused = (isFocused: boolean) => {\n if (isFocused) {\n valueOnFocus.current = inputValue;\n if (menuTrigger === 'focus' && !props.isReadOnly) {\n open(null, 'focus');\n }\n } else {\n if (shouldCloseOnBlur) {\n commitValue();\n }\n\n if (inputValue !== valueOnFocus.current) {\n validation.commitValidation();\n }\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 ...validation,\n ...triggerState,\n focusStrategy,\n toggle,\n open,\n close: commitValue,\n selectionManager,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: displayedCollection,\n inputValue,\n setInputValue,\n commit,\n revert\n };\n}\n\nfunction filterCollection<T extends object>(collection: Collection<Node<T>>, inputValue: string, filter: FilterFn): Collection<Node<T>> {\n return new ListCollection(filterNodes(collection, collection, inputValue, filter));\n}\n\nfunction filterNodes<T>(collection: Collection<Node<T>>, nodes: Iterable<Node<T>>, inputValue: string, filter: FilterFn): Iterable<Node<T>> {\n let filteredNode = [];\n for (let node of nodes) {\n if (node.type === 'section' && node.hasChildNodes) {\n let filtered = filterNodes(collection, getChildNodes(node, collection), inputValue, filter);\n if ([...filtered].some(node => node.type === 'item')) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type === 'item' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n } else if (node.type !== 'item') {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"useComboBoxState.module.js.map"}
1
+ {"mappings":"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","sources":["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\nimport {Collection, CollectionStateBase, FocusStrategy, Node} from '@react-types/shared';\nimport {ComboBoxProps, MenuTriggerAction} from '@react-types/combobox';\nimport {FormValidationState, useFormValidationState} from '@react-stately/form';\nimport {getChildNodes} from '@react-stately/collections';\nimport {ListCollection, useSingleSelectListState} from '@react-stately/list';\nimport {SelectState} from '@react-stately/select';\nimport {useCallback, useEffect, useMemo, useRef, useState} from 'react';\nimport {useControlledState} from '@react-stately/utils';\nimport {useOverlayTriggerState} from '@react-stately/overlays';\n\nexport interface ComboBoxState<T> extends SelectState<T>, FormValidationState{\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 /** Controls which item will be auto focused when the menu opens. */\n readonly focusStrategy: FocusStrategy | null,\n /** Opens the menu. */\n open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Toggles the menu. */\n toggle(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,\n /** Resets the input value to the previously selected item's text if any and closes the menu. */\n revert(): void\n}\n\ntype FilterFn = (textValue: string, inputValue: string) => boolean;\n\nexport interface ComboBoxStateOptions<T> extends Omit<ComboBoxProps<T>, 'children'>, CollectionStateBase<T> {\n /** The filter function used to determine if a option should be included in the combo box list. */\n defaultFilter?: FilterFn,\n /** Whether the combo box allows the menu to be open when the collection is empty. */\n allowsEmptyCollection?: boolean,\n /** Whether the combo box menu should close on blur. */\n shouldCloseOnBlur?: boolean\n}\n\n/**\n * Provides state management for a combo box component. Handles building a collection\n * of items from props and manages the option selection state of the combo box. In addition, it tracks the input value,\n * focus state, and other properties of the combo box.\n */\nexport function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T>): ComboBoxState<T> {\n let {\n defaultFilter,\n menuTrigger = 'input',\n allowsEmptyCollection = false,\n allowsCustomValue,\n shouldCloseOnBlur = true\n } = props;\n\n let [showAllItems, setShowAllItems] = useState(false);\n let [isFocused, setFocusedState] = useState(false);\n let [focusStrategy, setFocusStrategy] = useState<FocusStrategy | null>(null);\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,\n selectionManager,\n selectedKey,\n setSelectedKey,\n selectedItem,\n disabledKeys\n } = useSingleSelectListState({\n ...props,\n onSelectionChange,\n items: props.items ?? props.defaultItems\n });\n let defaultInputValue: string | null | undefined = props.defaultInputValue;\n if (defaultInputValue == null) {\n if (selectedKey == null) {\n defaultInputValue = '';\n } else {\n defaultInputValue = collection.getItem(selectedKey)?.textValue ?? '';\n }\n }\n\n let [inputValue, setInputValue] = useControlledState(\n props.inputValue,\n defaultInputValue!,\n props.onInputChange\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<MenuTriggerAction | undefined>('focus');\n let onOpenChange = (open: boolean) => {\n if (props.onOpenChange) {\n props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);\n }\n\n selectionManager.setFocused(open);\n if (!open) {\n selectionManager.setFocusedKey(null);\n }\n };\n\n let triggerState = useOverlayTriggerState({...props, onOpenChange, isOpen: undefined, defaultOpen: undefined});\n let open = (focusStrategy: FocusStrategy | null = null, 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 setFocusStrategy(focusStrategy);\n triggerState.open();\n }\n };\n\n let toggle = (focusStrategy: FocusStrategy | null = null, 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 let updateLastCollection = useCallback(() => {\n setLastCollection(showAllItems ? originalCollection : filteredCollection);\n }, [showAllItems, originalCollection, filteredCollection]);\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: FocusStrategy | null = null) => {\n if (triggerState.isOpen) {\n updateLastCollection();\n }\n\n setFocusStrategy(focusStrategy);\n triggerState.toggle();\n }, [triggerState, updateLastCollection]);\n\n let closeMenu = useCallback(() => {\n if (triggerState.isOpen) {\n updateLastCollection();\n triggerState.close();\n }\n }, [triggerState, updateLastCollection]);\n\n let [lastValue, setLastValue] = useState(inputValue);\n let resetInputValue = () => {\n let itemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';\n setLastValue(itemText);\n setInputValue(itemText);\n };\n\n let lastSelectedKey = useRef(props.selectedKey ?? props.defaultSelectedKey ?? null);\n let lastSelectedKeyText = useRef(\n selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : ''\n );\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 &&\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) {\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 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 if (lastValue !== inputValue) {\n setLastValue(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 = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';\n if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {\n if (lastSelectedKeyText.current !== selectedItemText) {\n setLastValue(selectedItemText);\n setInputValue(selectedItemText);\n }\n }\n\n lastSelectedKey.current = selectedKey;\n lastSelectedKeyText.current = selectedItemText;\n });\n\n let validation = useFormValidationState({\n ...props,\n value: useMemo(() => ({inputValue, selectedKey}), [inputValue, selectedKey])\n });\n\n // Revert input value and close menu\n let revert = () => {\n if (allowsCustomValue && selectedKey == null) {\n commitCustomValue();\n } else {\n commitSelection();\n }\n };\n\n let commitCustomValue = () => {\n lastSelectedKey.current = null;\n setSelectedKey(null);\n closeMenu();\n };\n\n let commitSelection = () => {\n // If multiple things are controlled, call onSelectionChange\n if (props.selectedKey !== undefined && props.inputValue !== undefined) {\n props.onSelectionChange?.(selectedKey);\n\n // Stop menu from reopening from useEffect\n let itemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';\n setLastValue(itemText);\n closeMenu();\n } else {\n // If only a single aspect of combobox is controlled, reset input value and close menu for the user\n resetInputValue();\n closeMenu();\n }\n };\n\n const commitValue = () => {\n if (allowsCustomValue) {\n const itemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';\n (inputValue === itemText) ? commitSelection() : commitCustomValue();\n } else {\n // Reset inputValue and close menu\n commitSelection();\n }\n };\n\n let commit = () => {\n if (triggerState.isOpen && selectionManager.focusedKey != null) {\n // Reset inputValue and close menu here if the selected key is already the focused key. Otherwise\n // fire onSelectionChange to allow the application to control the closing.\n if (selectedKey === selectionManager.focusedKey) {\n commitSelection();\n } else {\n setSelectedKey(selectionManager.focusedKey);\n }\n } else {\n commitValue();\n }\n };\n\n let valueOnFocus = useRef(inputValue);\n let setFocused = (isFocused: boolean) => {\n if (isFocused) {\n valueOnFocus.current = inputValue;\n if (menuTrigger === 'focus' && !props.isReadOnly) {\n open(null, 'focus');\n }\n } else {\n if (shouldCloseOnBlur) {\n commitValue();\n }\n\n if (inputValue !== valueOnFocus.current) {\n validation.commitValidation();\n }\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 ...validation,\n ...triggerState,\n focusStrategy,\n toggle,\n open,\n close: commitValue,\n selectionManager,\n selectedKey,\n setSelectedKey,\n disabledKeys,\n isFocused,\n setFocused,\n selectedItem,\n collection: displayedCollection,\n inputValue,\n setInputValue,\n commit,\n revert\n };\n}\n\nfunction filterCollection<T extends object>(collection: Collection<Node<T>>, inputValue: string, filter: FilterFn): Collection<Node<T>> {\n return new ListCollection(filterNodes(collection, collection, inputValue, filter));\n}\n\nfunction filterNodes<T>(collection: Collection<Node<T>>, nodes: Iterable<Node<T>>, inputValue: string, filter: FilterFn): Iterable<Node<T>> {\n let filteredNode: Node<T>[] = [];\n for (let node of nodes) {\n if (node.type === 'section' && node.hasChildNodes) {\n let filtered = filterNodes(collection, getChildNodes(node, collection), inputValue, filter);\n if ([...filtered].some(node => node.type === 'item')) {\n filteredNode.push({...node, childNodes: filtered});\n }\n } else if (node.type === 'item' && filter(node.textValue, inputValue)) {\n filteredNode.push({...node});\n } else if (node.type !== 'item') {\n filteredNode.push({...node});\n }\n }\n return filteredNode;\n}\n"],"names":[],"version":3,"file":"useComboBoxState.module.js.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-stately/combobox",
3
- "version": "3.9.2",
3
+ "version": "3.9.3-nightly.5014+8f3c0ea09",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
@@ -22,14 +22,14 @@
22
22
  "url": "https://github.com/adobe/react-spectrum"
23
23
  },
24
24
  "dependencies": {
25
- "@react-stately/collections": "^3.10.9",
26
- "@react-stately/form": "^3.0.5",
27
- "@react-stately/list": "^3.10.8",
28
- "@react-stately/overlays": "^3.6.10",
29
- "@react-stately/select": "^3.6.7",
30
- "@react-stately/utils": "^3.10.3",
31
- "@react-types/combobox": "^3.12.1",
32
- "@react-types/shared": "^3.24.1",
25
+ "@react-stately/collections": "3.0.0-nightly.3086+8f3c0ea09",
26
+ "@react-stately/form": "3.0.6-nightly.5014+8f3c0ea09",
27
+ "@react-stately/list": "3.10.9-nightly.5014+8f3c0ea09",
28
+ "@react-stately/overlays": "3.6.11-nightly.5014+8f3c0ea09",
29
+ "@react-stately/select": "3.6.8-nightly.5014+8f3c0ea09",
30
+ "@react-stately/utils": "3.0.0-nightly.3086+8f3c0ea09",
31
+ "@react-types/combobox": "3.12.2-nightly.5014+8f3c0ea09",
32
+ "@react-types/shared": "3.0.0-nightly.3086+8f3c0ea09",
33
33
  "@swc/helpers": "^0.5.0"
34
34
  },
35
35
  "peerDependencies": {
@@ -38,5 +38,5 @@
38
38
  "publishConfig": {
39
39
  "access": "public"
40
40
  },
41
- "gitHead": "faf0e18467231422cb7a06eb92a74d04e271f1e8"
41
+ "gitHead": "8f3c0ea0931107eceba0127fb524b79b46eb838b"
42
42
  }
@@ -28,7 +28,7 @@ export interface ComboBoxState<T> extends SelectState<T>, FormValidationState{
28
28
  /** Selects the currently focused item and updates the input value. */
29
29
  commit(): void,
30
30
  /** Controls which item will be auto focused when the menu opens. */
31
- readonly focusStrategy: FocusStrategy,
31
+ readonly focusStrategy: FocusStrategy | null,
32
32
  /** Opens the menu. */
33
33
  open(focusStrategy?: FocusStrategy | null, trigger?: MenuTriggerAction): void,
34
34
  /** Toggles the menu. */
@@ -64,7 +64,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
64
64
 
65
65
  let [showAllItems, setShowAllItems] = useState(false);
66
66
  let [isFocused, setFocusedState] = useState(false);
67
- let [focusStrategy, setFocusStrategy] = useState<FocusStrategy>(null);
67
+ let [focusStrategy, setFocusStrategy] = useState<FocusStrategy | null>(null);
68
68
 
69
69
  let onSelectionChange = (key) => {
70
70
  if (props.onSelectionChange) {
@@ -79,15 +79,29 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
79
79
  }
80
80
  };
81
81
 
82
- let {collection, selectionManager, selectedKey, setSelectedKey, selectedItem, disabledKeys} = useSingleSelectListState({
82
+ let {collection,
83
+ selectionManager,
84
+ selectedKey,
85
+ setSelectedKey,
86
+ selectedItem,
87
+ disabledKeys
88
+ } = useSingleSelectListState({
83
89
  ...props,
84
90
  onSelectionChange,
85
91
  items: props.items ?? props.defaultItems
86
92
  });
93
+ let defaultInputValue: string | null | undefined = props.defaultInputValue;
94
+ if (defaultInputValue == null) {
95
+ if (selectedKey == null) {
96
+ defaultInputValue = '';
97
+ } else {
98
+ defaultInputValue = collection.getItem(selectedKey)?.textValue ?? '';
99
+ }
100
+ }
87
101
 
88
102
  let [inputValue, setInputValue] = useControlledState(
89
103
  props.inputValue,
90
- props.defaultInputValue ?? collection.getItem(selectedKey)?.textValue ?? '',
104
+ defaultInputValue!,
91
105
  props.onInputChange
92
106
  );
93
107
 
@@ -102,7 +116,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
102
116
  let [lastCollection, setLastCollection] = useState(filteredCollection);
103
117
 
104
118
  // Track what action is attempting to open the menu
105
- let menuOpenTrigger = useRef('focus' as MenuTriggerAction);
119
+ let menuOpenTrigger = useRef<MenuTriggerAction | undefined>('focus');
106
120
  let onOpenChange = (open: boolean) => {
107
121
  if (props.onOpenChange) {
108
122
  props.onOpenChange(open, open ? menuOpenTrigger.current : undefined);
@@ -115,7 +129,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
115
129
  };
116
130
 
117
131
  let triggerState = useOverlayTriggerState({...props, onOpenChange, isOpen: undefined, defaultOpen: undefined});
118
- let open = (focusStrategy: FocusStrategy = null, trigger?: MenuTriggerAction) => {
132
+ let open = (focusStrategy: FocusStrategy | null = null, trigger?: MenuTriggerAction) => {
119
133
  let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));
120
134
  // Prevent open operations from triggering if there is nothing to display
121
135
  // Also prevent open operations from triggering if items are uncontrolled but defaultItems is empty, even if displayAllItems is true.
@@ -132,7 +146,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
132
146
  }
133
147
  };
134
148
 
135
- let toggle = (focusStrategy: FocusStrategy = null, trigger?: MenuTriggerAction) => {
149
+ let toggle = (focusStrategy: FocusStrategy | null = null, trigger?: MenuTriggerAction) => {
136
150
  let displayAllItems = (trigger === 'manual' || (trigger === 'focus' && menuTrigger === 'focus'));
137
151
  // If the menu is closed and there is nothing to display, early return so toggle isn't called to prevent extraneous onOpenChange
138
152
  if (!(allowsEmptyCollection || filteredCollection.size > 0 || (displayAllItems && originalCollection.size > 0) || props.items) && !triggerState.isOpen) {
@@ -158,7 +172,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
158
172
 
159
173
  // If menu is going to close, save the current collection so we can freeze the displayed collection when the
160
174
  // user clicks outside the popover to close the menu. Prevents the menu contents from updating as the menu closes.
161
- let toggleMenu = useCallback((focusStrategy: FocusStrategy = null) => {
175
+ let toggleMenu = useCallback((focusStrategy: FocusStrategy | null = null) => {
162
176
  if (triggerState.isOpen) {
163
177
  updateLastCollection();
164
178
  }
@@ -176,13 +190,15 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
176
190
 
177
191
  let [lastValue, setLastValue] = useState(inputValue);
178
192
  let resetInputValue = () => {
179
- let itemText = collection.getItem(selectedKey)?.textValue ?? '';
193
+ let itemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';
180
194
  setLastValue(itemText);
181
195
  setInputValue(itemText);
182
196
  };
183
197
 
184
198
  let lastSelectedKey = useRef(props.selectedKey ?? props.defaultSelectedKey ?? null);
185
- let lastSelectedKeyText = useRef(collection.getItem(selectedKey)?.textValue ?? '');
199
+ let lastSelectedKeyText = useRef(
200
+ selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : ''
201
+ );
186
202
  // intentional omit dependency array, want this to happen on every render
187
203
  // eslint-disable-next-line react-hooks/exhaustive-deps
188
204
  useEffect(() => {
@@ -245,7 +261,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
245
261
  // 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.
246
262
  // Only reset if the user isn't currently within the field so we don't erroneously modify user input.
247
263
  // If inputValue is controlled, it is the user's responsibility to update the inputValue when items change.
248
- let selectedItemText = collection.getItem(selectedKey)?.textValue ?? '';
264
+ let selectedItemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';
249
265
  if (!isFocused && selectedKey != null && props.inputValue === undefined && selectedKey === lastSelectedKey.current) {
250
266
  if (lastSelectedKeyText.current !== selectedItemText) {
251
267
  setLastValue(selectedItemText);
@@ -280,10 +296,10 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
280
296
  let commitSelection = () => {
281
297
  // If multiple things are controlled, call onSelectionChange
282
298
  if (props.selectedKey !== undefined && props.inputValue !== undefined) {
283
- props.onSelectionChange(selectedKey);
299
+ props.onSelectionChange?.(selectedKey);
284
300
 
285
301
  // Stop menu from reopening from useEffect
286
- let itemText = collection.getItem(selectedKey)?.textValue ?? '';
302
+ let itemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';
287
303
  setLastValue(itemText);
288
304
  closeMenu();
289
305
  } else {
@@ -295,7 +311,7 @@ export function useComboBoxState<T extends object>(props: ComboBoxStateOptions<T
295
311
 
296
312
  const commitValue = () => {
297
313
  if (allowsCustomValue) {
298
- const itemText = collection.getItem(selectedKey)?.textValue ?? '';
314
+ const itemText = selectedKey != null ? collection.getItem(selectedKey)?.textValue ?? '' : '';
299
315
  (inputValue === itemText) ? commitSelection() : commitCustomValue();
300
316
  } else {
301
317
  // Reset inputValue and close menu
@@ -376,7 +392,7 @@ function filterCollection<T extends object>(collection: Collection<Node<T>>, inp
376
392
  }
377
393
 
378
394
  function filterNodes<T>(collection: Collection<Node<T>>, nodes: Iterable<Node<T>>, inputValue: string, filter: FilterFn): Iterable<Node<T>> {
379
- let filteredNode = [];
395
+ let filteredNode: Node<T>[] = [];
380
396
  for (let node of nodes) {
381
397
  if (node.type === 'section' && node.hasChildNodes) {
382
398
  let filtered = filterNodes(collection, getChildNodes(node, collection), inputValue, filter);