@react-aria/selection 3.27.0 → 3.27.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,5 @@
1
1
  var $3XJlT$react = require("react");
2
+ var $3XJlT$reactariautils = require("@react-aria/utils");
2
3
 
3
4
 
4
5
  function $parcel$export(e, n, v, s) {
@@ -17,6 +18,7 @@ $parcel$export(module.exports, "useTypeSelect", () => $a1189052f36475e8$export$e
17
18
  * OF ANY KIND, either express or implied. See the License for the specific language
18
19
  * governing permissions and limitations under the License.
19
20
  */
21
+
20
22
  /**
21
23
  * Controls how long to wait before clearing the typeahead buffer.
22
24
  */ const $a1189052f36475e8$var$TYPEAHEAD_DEBOUNCE_WAIT_MS = 1000; // 1 second
@@ -28,7 +30,7 @@ function $a1189052f36475e8$export$e32c88dfddc6e1d8(options) {
28
30
  }).current;
29
31
  let onKeyDown = (e)=>{
30
32
  let character = $a1189052f36475e8$var$getStringForKey(e.key);
31
- if (!character || e.ctrlKey || e.metaKey || !e.currentTarget.contains(e.target) || state.search.length === 0 && character === ' ') return;
33
+ if (!character || e.ctrlKey || e.metaKey || !(0, $3XJlT$reactariautils.nodeContains)(e.currentTarget, e.target) || state.search.length === 0 && character === ' ') return;
32
34
  // Do not propagate the Spacebar event if it's meant to be part of the search.
33
35
  // When we time out, the search term becomes empty, hence the check on length.
34
36
  // Trimming is to account for the case of pressing the Spacebar more than once,
@@ -1 +1 @@
1
- {"mappings":";;;;;;;;AAAA;;;;;;;;;;CAUC;AAMD;;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,mBAAK,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,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAqB,MAAM,MAAM,CAAC,MAAM,KAAK,KAAK,cAAc,KAC5I;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/selection/src/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 {KeyboardEvent, useRef} from 'react';\nimport {MultipleSelectionManager} from '@react-stately/selection';\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 || !e.currentTarget.contains(e.target 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.main.js.map"}
1
+ {"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,mBAAK,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,kCAAW,EAAE,EAAE,aAAa,EAAE,EAAE,MAAM,KAAqB,MAAM,MAAM,CAAC,MAAM,KAAK,KAAK,cAAc,KACjJ;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/selection/src/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 {KeyboardEvent, useRef} from 'react';\nimport {MultipleSelectionManager} from '@react-stately/selection';\nimport {nodeContains} from '@react-aria/utils';\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, e.target 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.main.js.map"}
@@ -1,4 +1,5 @@
1
1
  import {useRef as $dAE4Y$useRef} from "react";
2
+ import {nodeContains as $dAE4Y$nodeContains} from "@react-aria/utils";
2
3
 
3
4
  /*
4
5
  * Copyright 2020 Adobe. All rights reserved.
@@ -11,6 +12,7 @@ import {useRef as $dAE4Y$useRef} from "react";
11
12
  * OF ANY KIND, either express or implied. See the License for the specific language
12
13
  * governing permissions and limitations under the License.
13
14
  */
15
+
14
16
  /**
15
17
  * Controls how long to wait before clearing the typeahead buffer.
16
18
  */ const $fb3050f43d946246$var$TYPEAHEAD_DEBOUNCE_WAIT_MS = 1000; // 1 second
@@ -22,7 +24,7 @@ function $fb3050f43d946246$export$e32c88dfddc6e1d8(options) {
22
24
  }).current;
23
25
  let onKeyDown = (e)=>{
24
26
  let character = $fb3050f43d946246$var$getStringForKey(e.key);
25
- if (!character || e.ctrlKey || e.metaKey || !e.currentTarget.contains(e.target) || state.search.length === 0 && character === ' ') return;
27
+ if (!character || e.ctrlKey || e.metaKey || !(0, $dAE4Y$nodeContains)(e.currentTarget, e.target) || state.search.length === 0 && character === ' ') return;
26
28
  // Do not propagate the Spacebar event if it's meant to be part of the search.
27
29
  // When we time out, the search term becomes empty, hence the check on length.
28
30
  // Trimming is to account for the case of pressing the Spacebar more than once,
@@ -1,4 +1,5 @@
1
1
  import {useRef as $dAE4Y$useRef} from "react";
2
+ import {nodeContains as $dAE4Y$nodeContains} from "@react-aria/utils";
2
3
 
3
4
  /*
4
5
  * Copyright 2020 Adobe. All rights reserved.
@@ -11,6 +12,7 @@ import {useRef as $dAE4Y$useRef} from "react";
11
12
  * OF ANY KIND, either express or implied. See the License for the specific language
12
13
  * governing permissions and limitations under the License.
13
14
  */
15
+
14
16
  /**
15
17
  * Controls how long to wait before clearing the typeahead buffer.
16
18
  */ const $fb3050f43d946246$var$TYPEAHEAD_DEBOUNCE_WAIT_MS = 1000; // 1 second
@@ -22,7 +24,7 @@ function $fb3050f43d946246$export$e32c88dfddc6e1d8(options) {
22
24
  }).current;
23
25
  let onKeyDown = (e)=>{
24
26
  let character = $fb3050f43d946246$var$getStringForKey(e.key);
25
- if (!character || e.ctrlKey || e.metaKey || !e.currentTarget.contains(e.target) || state.search.length === 0 && character === ' ') return;
27
+ if (!character || e.ctrlKey || e.metaKey || !(0, $dAE4Y$nodeContains)(e.currentTarget, e.target) || state.search.length === 0 && character === ' ') return;
26
28
  // Do not propagate the Spacebar event if it's meant to be part of the search.
27
29
  // When we time out, the search term becomes empty, hence the check on length.
28
30
  // Trimming is to account for the case of pressing the Spacebar more than once,
@@ -1 +1 @@
1
- {"mappings":";;AAAA;;;;;;;;;;CAUC;AAMD;;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,EAAE,aAAa,CAAC,QAAQ,CAAC,EAAE,MAAM,KAAqB,MAAM,MAAM,CAAC,MAAM,KAAK,KAAK,cAAc,KAC5I;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/selection/src/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 {KeyboardEvent, useRef} from 'react';\nimport {MultipleSelectionManager} from '@react-stately/selection';\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 || !e.currentTarget.contains(e.target 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.module.js.map"}
1
+ {"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,mBAAW,EAAE,EAAE,aAAa,EAAE,EAAE,MAAM,KAAqB,MAAM,MAAM,CAAC,MAAM,KAAK,KAAK,cAAc,KACjJ;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/selection/src/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 {KeyboardEvent, useRef} from 'react';\nimport {MultipleSelectionManager} from '@react-stately/selection';\nimport {nodeContains} from '@react-aria/utils';\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, e.target 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.module.js.map"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@react-aria/selection",
3
- "version": "3.27.0",
3
+ "version": "3.27.1",
4
4
  "description": "Spectrum UI components in React",
5
5
  "license": "Apache-2.0",
6
6
  "main": "dist/main.js",
@@ -26,12 +26,12 @@
26
26
  "url": "https://github.com/adobe/react-spectrum"
27
27
  },
28
28
  "dependencies": {
29
- "@react-aria/focus": "^3.21.3",
30
- "@react-aria/i18n": "^3.12.14",
31
- "@react-aria/interactions": "^3.26.0",
32
- "@react-aria/utils": "^3.32.0",
33
- "@react-stately/selection": "^3.20.7",
34
- "@react-types/shared": "^3.32.1",
29
+ "@react-aria/focus": "^3.21.4",
30
+ "@react-aria/i18n": "^3.12.15",
31
+ "@react-aria/interactions": "^3.27.0",
32
+ "@react-aria/utils": "^3.33.0",
33
+ "@react-stately/selection": "^3.20.8",
34
+ "@react-types/shared": "^3.33.0",
35
35
  "@swc/helpers": "^0.5.0"
36
36
  },
37
37
  "peerDependencies": {
@@ -41,5 +41,5 @@
41
41
  "publishConfig": {
42
42
  "access": "public"
43
43
  },
44
- "gitHead": "4d838da5bfe36abb35aed166995a9ef63825370f"
44
+ "gitHead": "66e51757606b43a89ed02c574ca24517323a2ab9"
45
45
  }
@@ -10,7 +10,7 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
- import {CLEAR_FOCUS_EVENT, FOCUS_EVENT, focusWithoutScrolling, getActiveElement, isCtrlKeyPressed, isTabbable, mergeProps, scrollIntoView, scrollIntoViewport, useEvent, useRouter, useUpdateLayoutEffect} from '@react-aria/utils';
13
+ import {CLEAR_FOCUS_EVENT, FOCUS_EVENT, focusWithoutScrolling, getActiveElement, isCtrlKeyPressed, isTabbable, mergeProps, nodeContains, scrollIntoView, scrollIntoViewport, useEvent, useRouter, useUpdateLayoutEffect} from '@react-aria/utils';
14
14
  import {dispatchVirtualFocus, getFocusableTreeWalker, moveVirtualFocus} from '@react-aria/focus';
15
15
  import {DOMAttributes, FocusableElement, FocusStrategy, Key, KeyboardDelegate, RefObject} from '@react-types/shared';
16
16
  import {flushSync} from 'react-dom';
@@ -118,7 +118,6 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
118
118
  disallowTypeAhead = false,
119
119
  shouldUseVirtualFocus,
120
120
  allowsTabNavigation = false,
121
- isVirtualized,
122
121
  // If no scrollRef is provided, assume the collection ref is the scrollable region
123
122
  scrollRef = ref,
124
123
  linkBehavior = 'action'
@@ -134,7 +133,7 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
134
133
 
135
134
  // Keyboard events bubble through portals. Don't handle keyboard events
136
135
  // for elements outside the collection (e.g. menus).
137
- if (!ref.current?.contains(e.target as Element)) {
136
+ if (!ref.current || !nodeContains(ref.current, e.target as Element)) {
138
137
  return;
139
138
  }
140
139
 
@@ -315,7 +314,7 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
315
314
  // If the active element is NOT tabbable but is contained by an element that IS tabbable (aka the cell), the browser will actually move focus to
316
315
  // the containing element. We need to special case this so that tab will move focus out of the grid instead of looping between
317
316
  // focusing the containing cell and back to the non-tabbable child element
318
- if (next && (!next.contains(document.activeElement) || (document.activeElement && !isTabbable(document.activeElement)))) {
317
+ if (next && (!nodeContains(next, document.activeElement) || (document.activeElement && !isTabbable(document.activeElement)))) {
319
318
  focusWithoutScrolling(next);
320
319
  }
321
320
  }
@@ -328,7 +327,7 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
328
327
  // Store the scroll position so we can restore it later.
329
328
  /// TODO: should this happen all the time??
330
329
  let scrollPos = useRef({top: 0, left: 0});
331
- useEvent(scrollRef, 'scroll', isVirtualized ? undefined : () => {
330
+ useEvent(scrollRef, 'scroll', () => {
332
331
  scrollPos.current = {
333
332
  top: scrollRef.current?.scrollTop ?? 0,
334
333
  left: scrollRef.current?.scrollLeft ?? 0
@@ -338,7 +337,7 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
338
337
  let onFocus = (e: FocusEvent) => {
339
338
  if (manager.isFocused) {
340
339
  // If a focus event bubbled through a portal, reset focus state.
341
- if (!e.currentTarget.contains(e.target)) {
340
+ if (!nodeContains(e.currentTarget, e.target)) {
342
341
  manager.setFocused(false);
343
342
  }
344
343
 
@@ -346,7 +345,7 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
346
345
  }
347
346
 
348
347
  // Focus events can bubble through portals. Ignore these events.
349
- if (!e.currentTarget.contains(e.target)) {
348
+ if (!nodeContains(e.currentTarget, e.target)) {
350
349
  return;
351
350
  }
352
351
 
@@ -369,7 +368,7 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
369
368
  } else {
370
369
  navigateToKey(manager.firstSelectedKey ?? delegate.getFirstKey?.());
371
370
  }
372
- } else if (!isVirtualized && scrollRef.current) {
371
+ } else if (scrollRef.current) {
373
372
  // Restore the scroll position to what it was before.
374
373
  scrollRef.current.scrollTop = scrollPos.current.top;
375
374
  scrollRef.current.scrollLeft = scrollPos.current.left;
@@ -380,7 +379,7 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
380
379
  let element = getItemElement(ref, manager.focusedKey);
381
380
  if (element instanceof HTMLElement) {
382
381
  // This prevents a flash of focus on the first/last element in the collection, or the collection itself.
383
- if (!element.contains(document.activeElement) && !shouldUseVirtualFocus) {
382
+ if (!nodeContains(element, document.activeElement) && !shouldUseVirtualFocus) {
384
383
  focusWithoutScrolling(element);
385
384
  }
386
385
 
@@ -394,7 +393,7 @@ export function useSelectableCollection(options: AriaSelectableCollectionOptions
394
393
 
395
394
  let onBlur = (e) => {
396
395
  // Don't set blurred and then focused again if moving focus within the collection.
397
- if (!e.currentTarget.contains(e.relatedTarget as HTMLElement)) {
396
+ if (!nodeContains(e.currentTarget, e.relatedTarget as HTMLElement)) {
398
397
  manager.setFocused(false);
399
398
  }
400
399
  };
@@ -200,6 +200,12 @@ export function useSelectableItem(options: SelectableItemOptions): SelectableIte
200
200
  };
201
201
  }
202
202
 
203
+ useEffect(() => {
204
+ if (isDisabled && manager.focusedKey === key) {
205
+ manager.setFocusedKey(null);
206
+ }
207
+ }, [manager, isDisabled, key]);
208
+
203
209
  // With checkbox selection, onAction (i.e. navigation) becomes primary, and occurs on a single click of the row.
204
210
  // Clicking the checkbox enters selection mode, after which clicking anywhere on any row toggles selection for that row.
205
211
  // With highlight selection, onAction is secondary, and occurs on double click. Single click selects the row.
@@ -246,7 +252,7 @@ export function useSelectableItem(options: SelectableItemOptions): SelectableIte
246
252
  itemPressProps.onPressStart = (e) => {
247
253
  modality.current = e.pointerType;
248
254
  longPressEnabledOnPressStart.current = longPressEnabled;
249
- if (e.pointerType === 'keyboard' && (!hasAction || isSelectionKey())) {
255
+ if (e.pointerType === 'keyboard' && (!hasAction || isSelectionKey(e.key))) {
250
256
  onSelect(e);
251
257
  }
252
258
  };
@@ -256,7 +262,7 @@ export function useSelectableItem(options: SelectableItemOptions): SelectableIte
256
262
  if (!allowsDifferentPressOrigin) {
257
263
  itemPressProps.onPress = (e) => {
258
264
  if (hasPrimaryAction || (hasSecondaryAction && e.pointerType !== 'mouse')) {
259
- if (e.pointerType === 'keyboard' && !isActionKey()) {
265
+ if (e.pointerType === 'keyboard' && !isActionKey(e.key)) {
260
266
  return;
261
267
  }
262
268
 
@@ -290,7 +296,7 @@ export function useSelectableItem(options: SelectableItemOptions): SelectableIte
290
296
  if (
291
297
  allowsSelection && (
292
298
  (e.pointerType === 'mouse' && !hasPrimaryAction) ||
293
- (e.pointerType === 'keyboard' && (!allowsActions || isSelectionKey()))
299
+ (e.pointerType === 'keyboard' && (!allowsActions || isSelectionKey(e.key)))
294
300
  )
295
301
  ) {
296
302
  onSelect(e);
@@ -305,7 +311,7 @@ export function useSelectableItem(options: SelectableItemOptions): SelectableIte
305
311
  e.pointerType === 'touch' ||
306
312
  e.pointerType === 'pen' ||
307
313
  e.pointerType === 'virtual' ||
308
- (e.pointerType === 'keyboard' && hasAction && isActionKey()) ||
314
+ (e.pointerType === 'keyboard' && hasAction && isActionKey(e.key)) ||
309
315
  (e.pointerType === 'mouse' && hadPrimaryActionOnPressStart.current)
310
316
  ) {
311
317
  if (hasAction) {
@@ -407,12 +413,10 @@ export function useSelectableItem(options: SelectableItemOptions): SelectableIte
407
413
  };
408
414
  }
409
415
 
410
- function isActionKey() {
411
- let event = window.event as KeyboardEvent;
412
- return event?.key === 'Enter';
416
+ function isActionKey(key: string | undefined) {
417
+ return key === 'Enter';
413
418
  }
414
419
 
415
- function isSelectionKey() {
416
- let event = window.event as KeyboardEvent;
417
- return event?.key === ' ' || event?.code === 'Space';
420
+ function isSelectionKey(key: string | undefined) {
421
+ return key === ' ';
418
422
  }
@@ -13,6 +13,7 @@
13
13
  import {DOMAttributes, Key, KeyboardDelegate} from '@react-types/shared';
14
14
  import {KeyboardEvent, useRef} from 'react';
15
15
  import {MultipleSelectionManager} from '@react-stately/selection';
16
+ import {nodeContains} from '@react-aria/utils';
16
17
 
17
18
  /**
18
19
  * Controls how long to wait before clearing the typeahead buffer.
@@ -53,7 +54,7 @@ export function useTypeSelect(options: AriaTypeSelectOptions): TypeSelectAria {
53
54
 
54
55
  let onKeyDown = (e: KeyboardEvent) => {
55
56
  let character = getStringForKey(e.key);
56
- if (!character || e.ctrlKey || e.metaKey || !e.currentTarget.contains(e.target as HTMLElement) || (state.search.length === 0 && character === ' ')) {
57
+ if (!character || e.ctrlKey || e.metaKey || !nodeContains(e.currentTarget, e.target as HTMLElement) || (state.search.length === 0 && character === ' ')) {
57
58
  return;
58
59
  }
59
60