{"mappings":";;;AAAA;;;;;;;;;;CAUC;;AAOD;;CAEC,GACD,MAAM,mDAA6B,MAAM,WAAW;AA2B7C,SAAS,0CAAc,OAA8B;IAC1D,IAAI,oBAAC,gBAAgB,oBAAE,gBAAgB,gBAAE,YAAY,EAAC,GAAG;IACzD,IAAI,QAAQ,CAAA,GAAA,aAAK,EAAwE;QACvF,QAAQ;QACR,SAAS;IACX,GAAG,OAAO;IAEV,IAAI,YAAY,CAAC;QACf,IAAI,YAAY,sCAAgB,EAAE,GAAG;QACrC,IAAI,CAAC,aAAa,EAAE,OAAO,IAAI,EAAE,OAAO,IAAI,CAAC,CAAA,GAAA,yCAAW,EAAE,EAAE,aAAa,EAAE,CAAA,GAAA,yCAAa,EAAE,OAAuB,MAAM,MAAM,CAAC,MAAM,KAAK,KAAK,cAAc,KAC1J;QAGF,8EAA8E;QAC9E,8EAA8E;QAC9E,+EAA+E;QAC/E,4EAA4E;QAC5E,IAAI,cAAc,OAAO,MAAM,MAAM,CAAC,IAAI,GAAG,MAAM,GAAG,GAAG;YACvD,EAAE,cAAc;YAChB,IAAI,CAAE,CAAA,yBAAyB,CAAA,GAC7B,EAAE,eAAe;QAErB;QAEA,MAAM,MAAM,IAAI;QAEhB,IAAI,iBAAiB,eAAe,IAAI,MAAM;YAC5C,2CAA2C;YAC3C,+FAA+F;YAC/F,IAAI,MAAM,iBAAiB,eAAe,CAAC,MAAM,MAAM,EAAE,iBAAiB,UAAU;YAEpF,wCAAwC;YACxC,IAAI,OAAO,MACT,MAAM,iBAAiB,eAAe,CAAC,MAAM,MAAM;YAGrD,IAAI,OAAO,MAAM;gBACf,iBAAiB,aAAa,CAAC;gBAC/B,IAAI,cACF,aAAa;YAEjB;QACF;QAEA,aAAa,MAAM,OAAO;QAC1B,MAAM,OAAO,GAAG,WAAW;YACzB,MAAM,MAAM,GAAG;QACjB,GAAG;IACL;IAEA,OAAO;QACL,iBAAiB;YACf,+DAA+D;YAC/D,qDAAqD;YACrD,kBAAkB,iBAAiB,eAAe,GAAG,YAAY;QACnE;IACF;AACF;AAEA,SAAS,sCAAgB,GAAW;IAClC,mDAAmD;IACnD,+DAA+D;IAC/D,6BAA6B;IAC7B,0CAA0C;IAC1C,IAAI,IAAI,MAAM,KAAK,KAAK,CAAC,UAAU,IAAI,CAAC,MACtC,OAAO;IAGT,OAAO;AACT","sources":["packages/react-aria/src/selection/useTypeSelect.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 {DOMAttributes, Key, KeyboardDelegate} from '@react-types/shared';\nimport {getEventTarget, nodeContains} from '../utils/shadowdom/DOMFunctions';\nimport {KeyboardEvent, useRef} from 'react';\nimport {MultipleSelectionManager} from 'react-stately/useMultipleSelectionState';\n\n/**\n * Controls how long to wait before clearing the typeahead buffer.\n */\nconst TYPEAHEAD_DEBOUNCE_WAIT_MS = 1000; // 1 second\n\nexport interface AriaTypeSelectOptions {\n  /**\n   * A delegate that returns collection item keys with respect to visual layout.\n   */\n  keyboardDelegate: KeyboardDelegate,\n  /**\n   * An interface for reading and updating multiple selection state.\n   */\n  selectionManager: MultipleSelectionManager,\n  /**\n   * Called when an item is focused by typing.\n   */\n  onTypeSelect?: (key: Key) => void\n}\n\nexport interface TypeSelectAria {\n  /**\n   * Props to be spread on the owner of the options.\n   */\n  typeSelectProps: DOMAttributes\n}\n\n/**\n * Handles typeahead interactions with collections.\n */\nexport function useTypeSelect(options: AriaTypeSelectOptions): TypeSelectAria {\n  let {keyboardDelegate, selectionManager, onTypeSelect} = options;\n  let state = useRef<{search: string, timeout: ReturnType<typeof setTimeout> | undefined}>({\n    search: '',\n    timeout: undefined\n  }).current;\n\n  let onKeyDown = (e: KeyboardEvent) => {\n    let character = getStringForKey(e.key);\n    if (!character || e.ctrlKey || e.metaKey || !nodeContains(e.currentTarget, getEventTarget(e) as HTMLElement) || (state.search.length === 0 && character === ' ')) {\n      return;\n    }\n\n    // Do not propagate the Spacebar event if it's meant to be part of the search.\n    // When we time out, the search term becomes empty, hence the check on length.\n    // Trimming is to account for the case of pressing the Spacebar more than once,\n    // which should cycle through the selection/deselection of the focused item.\n    if (character === ' ' && state.search.trim().length > 0) {\n      e.preventDefault();\n      if (!('continuePropagation' in e)) {\n        e.stopPropagation();\n      }\n    }\n\n    state.search += character;\n\n    if (keyboardDelegate.getKeyForSearch != null) {\n      // Use the delegate to find a key to focus.\n      // Prioritize items after the currently focused item, falling back to searching the whole list.\n      let key = keyboardDelegate.getKeyForSearch(state.search, selectionManager.focusedKey);\n\n      // If no key found, search from the top.\n      if (key == null) {\n        key = keyboardDelegate.getKeyForSearch(state.search);\n      }\n\n      if (key != null) {\n        selectionManager.setFocusedKey(key);\n        if (onTypeSelect) {\n          onTypeSelect(key);\n        }\n      }\n    }\n\n    clearTimeout(state.timeout);\n    state.timeout = setTimeout(() => {\n      state.search = '';\n    }, TYPEAHEAD_DEBOUNCE_WAIT_MS);\n  };\n\n  return {\n    typeSelectProps: {\n      // Using a capturing listener to catch the keydown event before\n      // other hooks in order to handle the Spacebar event.\n      onKeyDownCapture: keyboardDelegate.getKeyForSearch ? onKeyDown : undefined\n    }\n  };\n}\n\nfunction getStringForKey(key: string) {\n  // If the key is of length 1, it is an ASCII value.\n  // Otherwise, if there are no ASCII characters in the key name,\n  // it is a Unicode character.\n  // See https://www.w3.org/TR/uievents-key/\n  if (key.length === 1 || !/^[A-Z]/i.test(key)) {\n    return key;\n  }\n\n  return '';\n}\n"],"names":[],"version":3,"file":"useTypeSelect.mjs.map"}