react-aria 3.51.0 → 3.52.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.
Files changed (142) hide show
  1. package/dist/exports/index.cjs +1 -0
  2. package/dist/exports/index.cjs.map +1 -1
  3. package/dist/exports/index.js +2 -2
  4. package/dist/exports/index.js.map +1 -1
  5. package/dist/exports/index.mjs +2 -2
  6. package/dist/exports/index.mjs.map +1 -1
  7. package/dist/exports/private/utils/domHelpers.cjs +1 -0
  8. package/dist/exports/private/utils/domHelpers.cjs.map +1 -1
  9. package/dist/exports/private/utils/domHelpers.js +2 -2
  10. package/dist/exports/private/utils/domHelpers.js.map +1 -1
  11. package/dist/exports/private/utils/domHelpers.mjs +2 -2
  12. package/dist/exports/private/utils/domHelpers.mjs.map +1 -1
  13. package/dist/exports/useFocusVisible.cjs +1 -0
  14. package/dist/exports/useFocusVisible.cjs.map +1 -1
  15. package/dist/exports/useFocusVisible.js +2 -2
  16. package/dist/exports/useFocusVisible.js.map +1 -1
  17. package/dist/exports/useFocusVisible.mjs +2 -2
  18. package/dist/exports/useFocusVisible.mjs.map +1 -1
  19. package/dist/private/actiongroup/useActionGroup.cjs +3 -1
  20. package/dist/private/actiongroup/useActionGroup.cjs.map +1 -1
  21. package/dist/private/actiongroup/useActionGroup.js +3 -1
  22. package/dist/private/actiongroup/useActionGroup.js.map +1 -1
  23. package/dist/private/actiongroup/useActionGroup.mjs +3 -1
  24. package/dist/private/actiongroup/useActionGroup.mjs.map +1 -1
  25. package/dist/private/calendar/useRangeCalendar.cjs +1 -1
  26. package/dist/private/calendar/useRangeCalendar.cjs.map +1 -1
  27. package/dist/private/calendar/useRangeCalendar.js +2 -2
  28. package/dist/private/calendar/useRangeCalendar.js.map +1 -1
  29. package/dist/private/calendar/useRangeCalendar.mjs +2 -2
  30. package/dist/private/calendar/useRangeCalendar.mjs.map +1 -1
  31. package/dist/private/color/useColorField.cjs +26 -4
  32. package/dist/private/color/useColorField.cjs.map +1 -1
  33. package/dist/private/color/useColorField.js +26 -4
  34. package/dist/private/color/useColorField.js.map +1 -1
  35. package/dist/private/color/useColorField.mjs +26 -4
  36. package/dist/private/color/useColorField.mjs.map +1 -1
  37. package/dist/private/combobox/useComboBox.cjs +1 -1
  38. package/dist/private/combobox/useComboBox.cjs.map +1 -1
  39. package/dist/private/combobox/useComboBox.js +1 -1
  40. package/dist/private/combobox/useComboBox.js.map +1 -1
  41. package/dist/private/combobox/useComboBox.mjs +1 -1
  42. package/dist/private/combobox/useComboBox.mjs.map +1 -1
  43. package/dist/private/focus/FocusScope.cjs +7 -2
  44. package/dist/private/focus/FocusScope.cjs.map +1 -1
  45. package/dist/private/focus/FocusScope.js +7 -2
  46. package/dist/private/focus/FocusScope.js.map +1 -1
  47. package/dist/private/focus/FocusScope.mjs +7 -2
  48. package/dist/private/focus/FocusScope.mjs.map +1 -1
  49. package/dist/private/interactions/useFocusVisible.cjs +15 -3
  50. package/dist/private/interactions/useFocusVisible.cjs.map +1 -1
  51. package/dist/private/interactions/useFocusVisible.js +15 -3
  52. package/dist/private/interactions/useFocusVisible.js.map +1 -1
  53. package/dist/private/interactions/useFocusVisible.mjs +15 -3
  54. package/dist/private/interactions/useFocusVisible.mjs.map +1 -1
  55. package/dist/private/interactions/utils.cjs +23 -13
  56. package/dist/private/interactions/utils.cjs.map +1 -1
  57. package/dist/private/interactions/utils.js +25 -15
  58. package/dist/private/interactions/utils.js.map +1 -1
  59. package/dist/private/interactions/utils.mjs +25 -15
  60. package/dist/private/interactions/utils.mjs.map +1 -1
  61. package/dist/private/overlays/calculatePosition.cjs +3 -2
  62. package/dist/private/overlays/calculatePosition.cjs.map +1 -1
  63. package/dist/private/overlays/calculatePosition.js +5 -2
  64. package/dist/private/overlays/calculatePosition.js.map +1 -1
  65. package/dist/private/overlays/calculatePosition.mjs +3 -2
  66. package/dist/private/overlays/calculatePosition.mjs.map +1 -1
  67. package/dist/private/overlays/useOverlayPosition.cjs +5 -0
  68. package/dist/private/overlays/useOverlayPosition.cjs.map +1 -1
  69. package/dist/private/overlays/useOverlayPosition.js +6 -1
  70. package/dist/private/overlays/useOverlayPosition.js.map +1 -1
  71. package/dist/private/overlays/useOverlayPosition.mjs +6 -1
  72. package/dist/private/overlays/useOverlayPosition.mjs.map +1 -1
  73. package/dist/private/overlays/usePreventScroll.cjs +27 -35
  74. package/dist/private/overlays/usePreventScroll.cjs.map +1 -1
  75. package/dist/private/overlays/usePreventScroll.js +27 -35
  76. package/dist/private/overlays/usePreventScroll.js.map +1 -1
  77. package/dist/private/overlays/usePreventScroll.mjs +27 -35
  78. package/dist/private/overlays/usePreventScroll.mjs.map +1 -1
  79. package/dist/private/selection/useSelectableCollection.cjs +1 -0
  80. package/dist/private/selection/useSelectableCollection.cjs.map +1 -1
  81. package/dist/private/selection/useSelectableCollection.js +1 -0
  82. package/dist/private/selection/useSelectableCollection.js.map +1 -1
  83. package/dist/private/selection/useSelectableCollection.mjs +1 -0
  84. package/dist/private/selection/useSelectableCollection.mjs.map +1 -1
  85. package/dist/private/tabs/TabsKeyboardDelegate.cjs +3 -1
  86. package/dist/private/tabs/TabsKeyboardDelegate.cjs.map +1 -1
  87. package/dist/private/tabs/TabsKeyboardDelegate.js +3 -1
  88. package/dist/private/tabs/TabsKeyboardDelegate.js.map +1 -1
  89. package/dist/private/tabs/TabsKeyboardDelegate.mjs +3 -1
  90. package/dist/private/tabs/TabsKeyboardDelegate.mjs.map +1 -1
  91. package/dist/private/tokenfield/useToken.cjs +19 -4
  92. package/dist/private/tokenfield/useToken.cjs.map +1 -1
  93. package/dist/private/tokenfield/useToken.js +20 -4
  94. package/dist/private/tokenfield/useToken.js.map +1 -1
  95. package/dist/private/tokenfield/useToken.mjs +19 -4
  96. package/dist/private/tokenfield/useToken.mjs.map +1 -1
  97. package/dist/private/tokenfield/useTokenField.cjs +172 -43
  98. package/dist/private/tokenfield/useTokenField.cjs.map +1 -1
  99. package/dist/private/tokenfield/useTokenField.js +175 -45
  100. package/dist/private/tokenfield/useTokenField.js.map +1 -1
  101. package/dist/private/tokenfield/useTokenField.mjs +173 -44
  102. package/dist/private/tokenfield/useTokenField.mjs.map +1 -1
  103. package/dist/private/utils/domHelpers.cjs +21 -0
  104. package/dist/private/utils/domHelpers.cjs.map +1 -1
  105. package/dist/private/utils/domHelpers.js +20 -1
  106. package/dist/private/utils/domHelpers.js.map +1 -1
  107. package/dist/private/utils/domHelpers.mjs +20 -1
  108. package/dist/private/utils/domHelpers.mjs.map +1 -1
  109. package/dist/private/utils/getMetaValue.cjs +36 -0
  110. package/dist/private/utils/getMetaValue.cjs.map +1 -0
  111. package/dist/private/utils/getMetaValue.js +31 -0
  112. package/dist/private/utils/getMetaValue.js.map +1 -0
  113. package/dist/private/utils/getMetaValue.mjs +31 -0
  114. package/dist/private/utils/getMetaValue.mjs.map +1 -0
  115. package/dist/private/utils/getNonce.cjs +6 -10
  116. package/dist/private/utils/getNonce.cjs.map +1 -1
  117. package/dist/private/utils/getNonce.js +7 -11
  118. package/dist/private/utils/getNonce.js.map +1 -1
  119. package/dist/private/utils/getNonce.mjs +7 -11
  120. package/dist/private/utils/getNonce.mjs.map +1 -1
  121. package/dist/private/utils/scrollIntoView.cjs +6 -2
  122. package/dist/private/utils/scrollIntoView.cjs.map +1 -1
  123. package/dist/private/utils/scrollIntoView.js +6 -3
  124. package/dist/private/utils/scrollIntoView.js.map +1 -1
  125. package/dist/private/utils/scrollIntoView.mjs +6 -3
  126. package/dist/private/utils/scrollIntoView.mjs.map +1 -1
  127. package/dist/private/utils/useEvent.cjs +7 -9
  128. package/dist/private/utils/useEvent.cjs.map +1 -1
  129. package/dist/private/utils/useEvent.js +7 -9
  130. package/dist/private/utils/useEvent.js.map +1 -1
  131. package/dist/private/utils/useEvent.mjs +7 -9
  132. package/dist/private/utils/useEvent.mjs.map +1 -1
  133. package/dist/types/exports/index.d.ts +2 -2
  134. package/dist/types/exports/private/utils/domHelpers.d.ts +1 -1
  135. package/dist/types/exports/useFocusVisible.d.ts +2 -1
  136. package/dist/types/src/tokenfield/useTokenField.d.ts +3 -2
  137. package/dist/types/src/utils/domHelpers.d.ts +6 -2
  138. package/dist/types/src/utils/getMetaValue.d.ts +7 -0
  139. package/dist/types/src/utils/scrollIntoView.d.ts +1 -0
  140. package/dist/types/src/utils/useEvent.d.ts +2 -2
  141. package/dist/types/src/virtualizer/Virtualizer.d.ts +3 -3
  142. package/package.json +6 -5
@@ -1,3 +1,4 @@
1
+ import {isVirtualClick as $fa0ef9dfcca012a7$export$60278871457622de} from "../utils/isVirtualEvent.js";
1
2
  import {useEvent as $c3cab330536504ec$export$90fc3a17d93f704c} from "../utils/useEvent.js";
2
3
  import {useState as $bIBdX$useState, useRef as $bIBdX$useRef} from "react";
3
4
 
@@ -13,14 +14,15 @@ import {useState as $bIBdX$useState, useRef as $bIBdX$useRef} from "react";
13
14
  * governing
14
15
  */
15
16
 
17
+
16
18
  function $a06747c3f56c51df$export$31dcd79391e423fe(// Unused but matches the normal signature.
17
19
  _props, _state, ref) {
18
20
  let [isSelected, setSelected] = (0, $bIBdX$useState)(false);
19
21
  (0, $c3cab330536504ec$export$90fc3a17d93f704c)((0, $bIBdX$useRef)(typeof document !== 'undefined' ? document : null), 'selectionchange', ()=>{
20
22
  let selection = window.getSelection();
21
- if (!selection || selection.rangeCount === 0 || !ref.current) return;
22
- let range = selection.getRangeAt(0);
23
- if (!range.collapsed && range.intersectsNode(ref.current)) setSelected(true);
23
+ if (!selection || !ref.current) return;
24
+ let range = selection.rangeCount === 0 ? null : selection.getRangeAt(0);
25
+ if (!(range === null || range === void 0 ? void 0 : range.collapsed) && (range === null || range === void 0 ? void 0 : range.intersectsNode(ref.current))) setSelected(true);
24
26
  else setSelected(false);
25
27
  });
26
28
  return {
@@ -29,7 +31,21 @@ _props, _state, ref) {
29
31
  suppressContentEditableWarning: true,
30
32
  style: {
31
33
  userSelect: 'all',
32
- WebkitUserSelect: 'all'
34
+ WebkitUserSelect: 'all',
35
+ WebkitTapHighlightColor: 'transparent'
36
+ },
37
+ onClick (e) {
38
+ var _ref_current;
39
+ // Select the token when a screen reader clicks on it.
40
+ if (isSelected || !(0, $fa0ef9dfcca012a7$export$60278871457622de)(e.nativeEvent)) return;
41
+ let selection = window.getSelection();
42
+ let wrapper = (_ref_current = ref.current) === null || _ref_current === void 0 ? void 0 : _ref_current.parentElement;
43
+ if (!selection || !wrapper) return;
44
+ let range = document.createRange();
45
+ range.setStartBefore(wrapper);
46
+ range.setEndAfter(wrapper);
47
+ selection.removeAllRanges();
48
+ selection.addRange(range);
33
49
  }
34
50
  },
35
51
  isSelected: isSelected
@@ -1 +1 @@
1
- {"mappings":";;;AAAA;;;;;;;;;;CAUC;;AAkBM,SAAS,0CACd,2CAA2C;AAC3C,MAAkB,EAClB,MAAW,EACX,GAAsC;IAEtC,IAAI,CAAC,YAAY,YAAY,GAAG,CAAA,GAAA,eAAO,EAAE;IAEzC,CAAA,GAAA,yCAAO,EAAE,CAAA,GAAA,aAAK,EAAE,OAAO,aAAa,cAAc,WAAW,OAAO,mBAAmB;QACrF,IAAI,YAAY,OAAO,YAAY;QACnC,IAAI,CAAC,aAAa,UAAU,UAAU,KAAK,KAAK,CAAC,IAAI,OAAO,EAC1D;QAGF,IAAI,QAAQ,UAAU,UAAU,CAAC;QACjC,IAAI,CAAC,MAAM,SAAS,IAAI,MAAM,cAAc,CAAC,IAAI,OAAO,GACtD,YAAY;aAEZ,YAAY;IAEhB;IAEA,OAAO;QACL,YAAY;YACV,iBAAiB;YACjB,gCAAgC;YAChC,OAAO;gBACL,YAAY;gBACZ,kBAAkB;YACpB;QACF;oBACA;IACF;AACF","sources":["packages/react-aria/src/tokenfield/useToken.ts"],"sourcesContent":["/*\n * Copyright 2026 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\n */\n\nimport {HTMLAttributes, RefObject, useRef, useState} from 'react';\nimport {useEvent} from '../utils/useEvent';\n\nexport interface TokenProps {}\n\nexport interface TokenAria {\n /** Props for the token element. */\n tokenProps: HTMLAttributes<HTMLSpanElement>;\n /** Whether the token is currently selected. */\n isSelected: boolean;\n}\n\n/**\n * Provides the behavior and accessibility implementation for a token within a token field.\n * A token field allows users to enter text with inline tokens.\n */\nexport function useToken(\n // Unused but matches the normal signature.\n _props: TokenProps,\n _state: any,\n ref: RefObject<HTMLSpanElement | null>\n): TokenAria {\n let [isSelected, setSelected] = useState(false);\n\n useEvent(useRef(typeof document !== 'undefined' ? document : null), 'selectionchange', () => {\n let selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !ref.current) {\n return;\n }\n\n let range = selection.getRangeAt(0);\n if (!range.collapsed && range.intersectsNode(ref.current)) {\n setSelected(true);\n } else {\n setSelected(false);\n }\n });\n\n return {\n tokenProps: {\n contentEditable: false,\n suppressContentEditableWarning: true,\n style: {\n userSelect: 'all',\n WebkitUserSelect: 'all'\n }\n },\n isSelected\n };\n}\n"],"names":[],"version":3,"file":"useToken.js.map"}
1
+ {"mappings":";;;;AAAA;;;;;;;;;;CAUC;;;AAmBM,SAAS,0CACd,2CAA2C;AAC3C,MAAkB,EAClB,MAAW,EACX,GAAsC;IAEtC,IAAI,CAAC,YAAY,YAAY,GAAG,CAAA,GAAA,eAAO,EAAE;IAEzC,CAAA,GAAA,yCAAO,EAAE,CAAA,GAAA,aAAK,EAAE,OAAO,aAAa,cAAc,WAAW,OAAO,mBAAmB;QACrF,IAAI,YAAY,OAAO,YAAY;QACnC,IAAI,CAAC,aAAa,CAAC,IAAI,OAAO,EAC5B;QAGF,IAAI,QAAQ,UAAU,UAAU,KAAK,IAAI,OAAO,UAAU,UAAU,CAAC;QACrE,IAAI,EAAC,kBAAA,4BAAA,MAAO,SAAS,MAAI,kBAAA,4BAAA,MAAO,cAAc,CAAC,IAAI,OAAO,IACxD,YAAY;aAEZ,YAAY;IAEhB;IAEA,OAAO;QACL,YAAY;YACV,iBAAiB;YACjB,gCAAgC;YAChC,OAAO;gBACL,YAAY;gBACZ,kBAAkB;gBAClB,yBAAyB;YAC3B;YACA,SAAQ,CAAC;oBAMO;gBALd,sDAAsD;gBACtD,IAAI,cAAc,CAAC,CAAA,GAAA,yCAAa,EAAE,EAAE,WAAW,GAC7C;gBAEF,IAAI,YAAY,OAAO,YAAY;gBACnC,IAAI,WAAU,eAAA,IAAI,OAAO,cAAX,mCAAA,aAAa,aAAa;gBACxC,IAAI,CAAC,aAAa,CAAC,SACjB;gBAEF,IAAI,QAAQ,SAAS,WAAW;gBAChC,MAAM,cAAc,CAAC;gBACrB,MAAM,WAAW,CAAC;gBAClB,UAAU,eAAe;gBACzB,UAAU,QAAQ,CAAC;YACrB;QACF;oBACA;IACF;AACF","sources":["packages/react-aria/src/tokenfield/useToken.ts"],"sourcesContent":["/*\n * Copyright 2026 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\n */\n\nimport {HTMLAttributes, RefObject, useRef, useState} from 'react';\nimport {isVirtualClick} from '../utils/isVirtualEvent';\nimport {useEvent} from '../utils/useEvent';\n\nexport interface TokenProps {}\n\nexport interface TokenAria {\n /** Props for the token element. */\n tokenProps: HTMLAttributes<HTMLSpanElement>;\n /** Whether the token is currently selected. */\n isSelected: boolean;\n}\n\n/**\n * Provides the behavior and accessibility implementation for a token within a token field.\n * A token field allows users to enter text with inline tokens.\n */\nexport function useToken(\n // Unused but matches the normal signature.\n _props: TokenProps,\n _state: any,\n ref: RefObject<HTMLSpanElement | null>\n): TokenAria {\n let [isSelected, setSelected] = useState(false);\n\n useEvent(useRef(typeof document !== 'undefined' ? document : null), 'selectionchange', () => {\n let selection = window.getSelection();\n if (!selection || !ref.current) {\n return;\n }\n\n let range = selection.rangeCount === 0 ? null : selection.getRangeAt(0);\n if (!range?.collapsed && range?.intersectsNode(ref.current)) {\n setSelected(true);\n } else {\n setSelected(false);\n }\n });\n\n return {\n tokenProps: {\n contentEditable: false,\n suppressContentEditableWarning: true,\n style: {\n userSelect: 'all',\n WebkitUserSelect: 'all',\n WebkitTapHighlightColor: 'transparent'\n },\n onClick(e) {\n // Select the token when a screen reader clicks on it.\n if (isSelected || !isVirtualClick(e.nativeEvent)) {\n return;\n }\n let selection = window.getSelection();\n let wrapper = ref.current?.parentElement;\n if (!selection || !wrapper) {\n return;\n }\n let range = document.createRange();\n range.setStartBefore(wrapper);\n range.setEndAfter(wrapper);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n },\n isSelected\n };\n}\n"],"names":[],"version":3,"file":"useToken.js.map"}
@@ -1,3 +1,4 @@
1
+ import {isVirtualClick as $b5c62b033c25b96d$export$60278871457622de} from "../utils/isVirtualEvent.mjs";
1
2
  import {useEvent as $600b3cf69ae46262$export$90fc3a17d93f704c} from "../utils/useEvent.mjs";
2
3
  import {useState as $gQiz1$useState, useRef as $gQiz1$useRef} from "react";
3
4
 
@@ -13,14 +14,15 @@ import {useState as $gQiz1$useState, useRef as $gQiz1$useRef} from "react";
13
14
  * governing
14
15
  */
15
16
 
17
+
16
18
  function $d089f4b2a715a8e0$export$31dcd79391e423fe(// Unused but matches the normal signature.
17
19
  _props, _state, ref) {
18
20
  let [isSelected, setSelected] = (0, $gQiz1$useState)(false);
19
21
  (0, $600b3cf69ae46262$export$90fc3a17d93f704c)((0, $gQiz1$useRef)(typeof document !== 'undefined' ? document : null), 'selectionchange', ()=>{
20
22
  let selection = window.getSelection();
21
- if (!selection || selection.rangeCount === 0 || !ref.current) return;
22
- let range = selection.getRangeAt(0);
23
- if (!range.collapsed && range.intersectsNode(ref.current)) setSelected(true);
23
+ if (!selection || !ref.current) return;
24
+ let range = selection.rangeCount === 0 ? null : selection.getRangeAt(0);
25
+ if (!range?.collapsed && range?.intersectsNode(ref.current)) setSelected(true);
24
26
  else setSelected(false);
25
27
  });
26
28
  return {
@@ -29,7 +31,20 @@ _props, _state, ref) {
29
31
  suppressContentEditableWarning: true,
30
32
  style: {
31
33
  userSelect: 'all',
32
- WebkitUserSelect: 'all'
34
+ WebkitUserSelect: 'all',
35
+ WebkitTapHighlightColor: 'transparent'
36
+ },
37
+ onClick (e) {
38
+ // Select the token when a screen reader clicks on it.
39
+ if (isSelected || !(0, $b5c62b033c25b96d$export$60278871457622de)(e.nativeEvent)) return;
40
+ let selection = window.getSelection();
41
+ let wrapper = ref.current?.parentElement;
42
+ if (!selection || !wrapper) return;
43
+ let range = document.createRange();
44
+ range.setStartBefore(wrapper);
45
+ range.setEndAfter(wrapper);
46
+ selection.removeAllRanges();
47
+ selection.addRange(range);
33
48
  }
34
49
  },
35
50
  isSelected: isSelected
@@ -1 +1 @@
1
- {"mappings":";;;AAAA;;;;;;;;;;CAUC;;AAkBM,SAAS,0CACd,2CAA2C;AAC3C,MAAkB,EAClB,MAAW,EACX,GAAsC;IAEtC,IAAI,CAAC,YAAY,YAAY,GAAG,CAAA,GAAA,eAAO,EAAE;IAEzC,CAAA,GAAA,yCAAO,EAAE,CAAA,GAAA,aAAK,EAAE,OAAO,aAAa,cAAc,WAAW,OAAO,mBAAmB;QACrF,IAAI,YAAY,OAAO,YAAY;QACnC,IAAI,CAAC,aAAa,UAAU,UAAU,KAAK,KAAK,CAAC,IAAI,OAAO,EAC1D;QAGF,IAAI,QAAQ,UAAU,UAAU,CAAC;QACjC,IAAI,CAAC,MAAM,SAAS,IAAI,MAAM,cAAc,CAAC,IAAI,OAAO,GACtD,YAAY;aAEZ,YAAY;IAEhB;IAEA,OAAO;QACL,YAAY;YACV,iBAAiB;YACjB,gCAAgC;YAChC,OAAO;gBACL,YAAY;gBACZ,kBAAkB;YACpB;QACF;oBACA;IACF;AACF","sources":["packages/react-aria/src/tokenfield/useToken.ts"],"sourcesContent":["/*\n * Copyright 2026 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\n */\n\nimport {HTMLAttributes, RefObject, useRef, useState} from 'react';\nimport {useEvent} from '../utils/useEvent';\n\nexport interface TokenProps {}\n\nexport interface TokenAria {\n /** Props for the token element. */\n tokenProps: HTMLAttributes<HTMLSpanElement>;\n /** Whether the token is currently selected. */\n isSelected: boolean;\n}\n\n/**\n * Provides the behavior and accessibility implementation for a token within a token field.\n * A token field allows users to enter text with inline tokens.\n */\nexport function useToken(\n // Unused but matches the normal signature.\n _props: TokenProps,\n _state: any,\n ref: RefObject<HTMLSpanElement | null>\n): TokenAria {\n let [isSelected, setSelected] = useState(false);\n\n useEvent(useRef(typeof document !== 'undefined' ? document : null), 'selectionchange', () => {\n let selection = window.getSelection();\n if (!selection || selection.rangeCount === 0 || !ref.current) {\n return;\n }\n\n let range = selection.getRangeAt(0);\n if (!range.collapsed && range.intersectsNode(ref.current)) {\n setSelected(true);\n } else {\n setSelected(false);\n }\n });\n\n return {\n tokenProps: {\n contentEditable: false,\n suppressContentEditableWarning: true,\n style: {\n userSelect: 'all',\n WebkitUserSelect: 'all'\n }\n },\n isSelected\n };\n}\n"],"names":[],"version":3,"file":"useToken.mjs.map"}
1
+ {"mappings":";;;;AAAA;;;;;;;;;;CAUC;;;AAmBM,SAAS,0CACd,2CAA2C;AAC3C,MAAkB,EAClB,MAAW,EACX,GAAsC;IAEtC,IAAI,CAAC,YAAY,YAAY,GAAG,CAAA,GAAA,eAAO,EAAE;IAEzC,CAAA,GAAA,yCAAO,EAAE,CAAA,GAAA,aAAK,EAAE,OAAO,aAAa,cAAc,WAAW,OAAO,mBAAmB;QACrF,IAAI,YAAY,OAAO,YAAY;QACnC,IAAI,CAAC,aAAa,CAAC,IAAI,OAAO,EAC5B;QAGF,IAAI,QAAQ,UAAU,UAAU,KAAK,IAAI,OAAO,UAAU,UAAU,CAAC;QACrE,IAAI,CAAC,OAAO,aAAa,OAAO,eAAe,IAAI,OAAO,GACxD,YAAY;aAEZ,YAAY;IAEhB;IAEA,OAAO;QACL,YAAY;YACV,iBAAiB;YACjB,gCAAgC;YAChC,OAAO;gBACL,YAAY;gBACZ,kBAAkB;gBAClB,yBAAyB;YAC3B;YACA,SAAQ,CAAC;gBACP,sDAAsD;gBACtD,IAAI,cAAc,CAAC,CAAA,GAAA,yCAAa,EAAE,EAAE,WAAW,GAC7C;gBAEF,IAAI,YAAY,OAAO,YAAY;gBACnC,IAAI,UAAU,IAAI,OAAO,EAAE;gBAC3B,IAAI,CAAC,aAAa,CAAC,SACjB;gBAEF,IAAI,QAAQ,SAAS,WAAW;gBAChC,MAAM,cAAc,CAAC;gBACrB,MAAM,WAAW,CAAC;gBAClB,UAAU,eAAe;gBACzB,UAAU,QAAQ,CAAC;YACrB;QACF;oBACA;IACF;AACF","sources":["packages/react-aria/src/tokenfield/useToken.ts"],"sourcesContent":["/*\n * Copyright 2026 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\n */\n\nimport {HTMLAttributes, RefObject, useRef, useState} from 'react';\nimport {isVirtualClick} from '../utils/isVirtualEvent';\nimport {useEvent} from '../utils/useEvent';\n\nexport interface TokenProps {}\n\nexport interface TokenAria {\n /** Props for the token element. */\n tokenProps: HTMLAttributes<HTMLSpanElement>;\n /** Whether the token is currently selected. */\n isSelected: boolean;\n}\n\n/**\n * Provides the behavior and accessibility implementation for a token within a token field.\n * A token field allows users to enter text with inline tokens.\n */\nexport function useToken(\n // Unused but matches the normal signature.\n _props: TokenProps,\n _state: any,\n ref: RefObject<HTMLSpanElement | null>\n): TokenAria {\n let [isSelected, setSelected] = useState(false);\n\n useEvent(useRef(typeof document !== 'undefined' ? document : null), 'selectionchange', () => {\n let selection = window.getSelection();\n if (!selection || !ref.current) {\n return;\n }\n\n let range = selection.rangeCount === 0 ? null : selection.getRangeAt(0);\n if (!range?.collapsed && range?.intersectsNode(ref.current)) {\n setSelected(true);\n } else {\n setSelected(false);\n }\n });\n\n return {\n tokenProps: {\n contentEditable: false,\n suppressContentEditableWarning: true,\n style: {\n userSelect: 'all',\n WebkitUserSelect: 'all',\n WebkitTapHighlightColor: 'transparent'\n },\n onClick(e) {\n // Select the token when a screen reader clicks on it.\n if (isSelected || !isVirtualClick(e.nativeEvent)) {\n return;\n }\n let selection = window.getSelection();\n let wrapper = ref.current?.parentElement;\n if (!selection || !wrapper) {\n return;\n }\n let range = document.createRange();\n range.setStartBefore(wrapper);\n range.setEndAfter(wrapper);\n selection.removeAllRanges();\n selection.addRange(range);\n }\n },\n isSelected\n };\n}\n"],"names":[],"version":3,"file":"useToken.mjs.map"}
@@ -1,9 +1,11 @@
1
1
  var $74b2c5b1e7ea9589$exports = require("../live-announcer/LiveAnnouncer.cjs");
2
2
  var $da02ee888921bc9e$exports = require("../utils/shadowdom/DOMFunctions.cjs");
3
+ var $d0df89f3abe2c2ca$exports = require("../interactions/useFocusVisible.cjs");
3
4
  var $49582955cc364b1c$exports = require("../utils/domHelpers.cjs");
5
+ var $e2a63525475bbd9f$exports = require("../utils/getScrollParents.cjs");
4
6
  var $d0b4a781cf26e80b$exports = require("../utils/platform.cjs");
5
7
  var $89b39774f3b79dbb$exports = require("../utils/mergeProps.cjs");
6
- var $d0df89f3abe2c2ca$exports = require("../interactions/useFocusVisible.cjs");
8
+ var $9a1324d6ffd8bbb0$exports = require("../utils/scrollIntoView.cjs");
7
9
  var $6e76e65001bbcda2$exports = require("../utils/useEvent.cjs");
8
10
  var $e3486d9c44549186$exports = require("../label/useField.cjs");
9
11
  var $cfe896014413cb8c$exports = require("../interactions/useFocusable.cjs");
@@ -19,8 +21,8 @@ function $parcel$export(e, n, v, s) {
19
21
  }
20
22
 
21
23
  $parcel$export(module.exports, "useTokenField", function () { return $a3a7b013e6c801ed$export$adf3c8de3c7afc8b; });
22
- $parcel$export(module.exports, "getSelection", function () { return $a3a7b013e6c801ed$export$ca798a7e6e94638c; });
23
24
  $parcel$export(module.exports, "setTokenFieldSelection", function () { return $a3a7b013e6c801ed$export$9cafaa09e78b6e4b; });
25
+ $parcel$export(module.exports, "getSelection", function () { return $a3a7b013e6c801ed$export$ca798a7e6e94638c; });
24
26
  $parcel$export(module.exports, "tokenFieldPositionToDOMRange", function () { return $a3a7b013e6c801ed$export$30729a8cd0694a7c; });
25
27
  /*
26
28
  * Copyright 2026 Adobe. All rights reserved.
@@ -46,6 +48,8 @@ $parcel$export(module.exports, "tokenFieldPositionToDOMRange", function () { ret
46
48
 
47
49
 
48
50
 
51
+
52
+
49
53
  const $a3a7b013e6c801ed$var$CLIPBOARD_MIME_TYPE = 'application/vnd.react-aria.tokens+json';
50
54
  function $a3a7b013e6c801ed$export$adf3c8de3c7afc8b(props, state, ref) {
51
55
  let { role: role = 'textbox', allowsNewlines: multiline = false, isReadOnly: isReadOnly = false, isDisabled: isDisabled = false, 'aria-details': ariaDetails } = props;
@@ -111,21 +115,30 @@ function $a3a7b013e6c801ed$export$adf3c8de3c7afc8b(props, state, ref) {
111
115
  if (state.isComposing && value !== nextValue.current) stopComposition();
112
116
  nextValue.current = value;
113
117
  });
114
- let caretPosition = (0, $bmmaU$react.useRef)(null);
118
+ let selectedRange = (0, $bmmaU$react.useRef)(null);
115
119
  (0, $429333cab433657c$exports.useLayoutEffect)(()=>{
116
- if (ref.current && value.caretPosition && !state.isComposing && value.caretPosition !== caretPosition.current) {
120
+ if (ref.current && !state.isComposing && value.selectedRange !== selectedRange.current) {
117
121
  // Only move the caret when the field is already focused.
118
- if (ref.current === (0, $da02ee888921bc9e$exports.getActiveElement)((0, $49582955cc364b1c$exports.getOwnerDocument)(ref.current))) $a3a7b013e6c801ed$var$setCursor(ref.current, value.caretPosition);
119
- caretPosition.current = value.caretPosition;
122
+ if (ref.current === (0, $da02ee888921bc9e$exports.getActiveElement)((0, $49582955cc364b1c$exports.getOwnerDocument)(ref.current))) {
123
+ $a3a7b013e6c801ed$export$9cafaa09e78b6e4b(ref.current, value.selectedRange);
124
+ $a3a7b013e6c801ed$var$announceToken(value);
125
+ // We call preventDefault in the beforeinput handler below, which also prevents the
126
+ // browser's default behavior of scrolling the caret into view. Do it ourselves instead.
127
+ $a3a7b013e6c801ed$var$scrollCaretIntoView(ref.current);
128
+ }
129
+ selectedRange.current = value.selectedRange;
120
130
  }
121
131
  });
122
132
  // Handle text editing commands and prevent browser default behavior.
123
133
  (0, $6e76e65001bbcda2$exports.useEvent)(ref, 'beforeinput', (e)=>{
124
134
  // Android sometimes doesn't fire a compositionend event before a regular input event.
125
135
  if (state.isComposing && !e.isComposing) stopComposition();
126
- let selection = window.getSelection();
127
- if (!selection || selection.rangeCount === 0) return;
128
- let range = selection.getRangeAt(0);
136
+ let range = e.getTargetRanges()[0];
137
+ if (!range) {
138
+ let selection = window.getSelection();
139
+ if (!selection || selection.rangeCount === 0) return;
140
+ range = selection.getRangeAt(0);
141
+ }
129
142
  let [start, end] = $a3a7b013e6c801ed$var$rangeToPositions(ref.current, range);
130
143
  // https://www.w3.org/TR/input-events-2/#interface-InputEvent-Attributes
131
144
  switch(e.inputType){
@@ -179,7 +192,7 @@ function $a3a7b013e6c801ed$export$adf3c8de3c7afc8b(props, state, ref) {
179
192
  case 'deleteContent':
180
193
  case 'deleteByCut':
181
194
  case 'deleteCompositionText':
182
- if (!range.collapsed) {
195
+ if (!range.collapsed && !$a3a7b013e6c801ed$var$isSamePosition(start, end)) {
183
196
  apply((tokens)=>tokens.replaceRange(start, end, ''));
184
197
  break;
185
198
  }
@@ -251,15 +264,19 @@ function $a3a7b013e6c801ed$export$adf3c8de3c7afc8b(props, state, ref) {
251
264
  value.endCoalescing();
252
265
  // When the cursor moves next to a token, announce it.
253
266
  // Otherwise the screen reader will only announce the first/last character.
254
- if (window.getSelection()?.isCollapsed) {
255
- let [start, end] = $a3a7b013e6c801ed$export$ca798a7e6e94638c(ref.current);
256
- if (start.offset === 0) {
257
- let segment = value.segments[start.index];
258
- if (segment?.type !== 'token') segment = value.segments[start.index - 1];
259
- if (segment?.type === 'token') (0, $74b2c5b1e7ea9589$exports.announce)(segment.text, 'assertive');
260
- // Update the caret position in the value.
261
- state.setValue((value)=>value.withCaretPosition(end));
262
- }
267
+ let range = $a3a7b013e6c801ed$export$6ec3e5953919831d(ref.current);
268
+ if (!range) return;
269
+ $a3a7b013e6c801ed$var$announceToken(value, range);
270
+ // Update the selected range in the value.
271
+ state.setValue((value)=>value.withSelectedRange(range));
272
+ });
273
+ // Clear selection on blur.
274
+ (0, $6e76e65001bbcda2$exports.useEvent)(ref, 'blur', (e)=>{
275
+ if (!e.isTrusted) return;
276
+ let selection = window.getSelection();
277
+ if (ref.current && selection && selection.containsNode(ref.current, true) && !selection.isCollapsed) {
278
+ selection.removeAllRanges();
279
+ state.setValue((value)=>value.withSelectedRange(new (0, $bmmaU$reactstatelyuseTokenFieldState.TokenFieldValue).SelectedRange(value.caretPosition)));
263
280
  }
264
281
  });
265
282
  // Override the default triple click behavior to ensure that tokens get selected.
@@ -272,7 +289,7 @@ function $a3a7b013e6c801ed$export$adf3c8de3c7afc8b(props, state, ref) {
272
289
  let end = value.findLineBoundary(selection[1], (0, $bmmaU$reactstatelyuseTokenFieldState.TokenFieldValue).Direction.Forward);
273
290
  if (start && end) {
274
291
  e.preventDefault();
275
- $a3a7b013e6c801ed$export$9cafaa09e78b6e4b(ref.current, start, end, true);
292
+ $a3a7b013e6c801ed$export$9cafaa09e78b6e4b(ref.current, new (0, $bmmaU$reactstatelyuseTokenFieldState.TokenFieldValue).SelectedRange(start, end), true);
276
293
  }
277
294
  }
278
295
  });
@@ -425,15 +442,22 @@ function $a3a7b013e6c801ed$export$ca798a7e6e94638c(container) {
425
442
  let range = selection.getRangeAt(0);
426
443
  return $a3a7b013e6c801ed$var$rangeToPositions(container, range);
427
444
  }
445
+ function $a3a7b013e6c801ed$export$6ec3e5953919831d(container) {
446
+ let selection = window.getSelection();
447
+ if (!selection || !selection.anchorNode || !selection.focusNode || !(0, $da02ee888921bc9e$exports.nodeContains)(container, selection.anchorNode) || !(0, $da02ee888921bc9e$exports.nodeContains)(container, selection.focusNode)) return null;
448
+ let anchor = $a3a7b013e6c801ed$var$getPosition(container, selection.anchorNode, selection.anchorOffset, false);
449
+ let current = $a3a7b013e6c801ed$var$getPosition(container, selection.focusNode, selection.focusOffset, !selection.isCollapsed);
450
+ return new (0, $bmmaU$reactstatelyuseTokenFieldState.TokenFieldValue).SelectedRange(anchor, current);
451
+ }
428
452
  function $a3a7b013e6c801ed$var$rangeToPositions(container, range) {
429
- let start = $a3a7b013e6c801ed$var$getPosition(container, range.startContainer, range.startOffset);
430
- let end = $a3a7b013e6c801ed$var$getPosition(container, range.endContainer, range.endOffset);
453
+ let start = $a3a7b013e6c801ed$var$getPosition(container, range.startContainer, range.startOffset, false);
454
+ let end = $a3a7b013e6c801ed$var$getPosition(container, range.endContainer, range.endOffset, !range.collapsed);
431
455
  return [
432
456
  start,
433
457
  end
434
458
  ];
435
459
  }
436
- function $a3a7b013e6c801ed$var$getPosition(container, node, offset) {
460
+ function $a3a7b013e6c801ed$var$getPosition(container, node, offset, isRangeEnd = false) {
437
461
  if (node === container) return {
438
462
  index: offset,
439
463
  offset: 0
@@ -446,7 +470,7 @@ function $a3a7b013e6c801ed$var$getPosition(container, node, offset) {
446
470
  let atEnd;
447
471
  let endOffset = 0;
448
472
  if (originalNode === tokenNode) // Cursor is inside the token.
449
- atEnd = offset > 0;
473
+ atEnd = isRangeEnd || offset > 0;
450
474
  else if (originalNode === node) // Cursor is inside the wrapper element.
451
475
  atEnd = offset > 1;
452
476
  else {
@@ -474,37 +498,127 @@ function $a3a7b013e6c801ed$var$getPosition(container, node, offset) {
474
498
  }
475
499
  let $a3a7b013e6c801ed$var$isProgrammaticSelectionChange = Symbol('isProgrammaticSelectionChange');
476
500
  function $a3a7b013e6c801ed$var$setCursor(root, pos, fireEvent = false) {
477
- $a3a7b013e6c801ed$export$9cafaa09e78b6e4b(root, pos, pos, fireEvent);
501
+ $a3a7b013e6c801ed$export$9cafaa09e78b6e4b(root, new (0, $bmmaU$reactstatelyuseTokenFieldState.TokenFieldValue).SelectedRange(pos), fireEvent);
478
502
  }
479
- function $a3a7b013e6c801ed$export$9cafaa09e78b6e4b(root, start, end, fireEvent = false) {
503
+ function $a3a7b013e6c801ed$export$9cafaa09e78b6e4b(root, selectedRange, fireEvent = false) {
480
504
  let selection = window.getSelection();
481
505
  if (selection) {
482
- let range = $a3a7b013e6c801ed$var$createDOMRange(root, start, end);
506
+ // Use setBaseAndExtent to preserve the selection direction. A plain Range +
507
+ // addRange always produces a forward selection and collapses when the
508
+ // anchor comes after the current position (backward selections).
509
+ let [anchorNode, anchorOffset] = $a3a7b013e6c801ed$var$getDOMPosition(root, selectedRange.anchor);
510
+ let [focusNode, focusOffset] = $a3a7b013e6c801ed$var$getDOMPosition(root, selectedRange.current);
483
511
  root[$a3a7b013e6c801ed$var$isProgrammaticSelectionChange] = !fireEvent;
484
- selection.removeAllRanges();
485
- selection.addRange(range);
512
+ // Only set selection if it has changed, because this can clobber the browser's selection direction.
513
+ if (selection.anchorNode !== anchorNode || selection.anchorOffset !== anchorOffset || selection.focusNode !== focusNode || selection.focusOffset !== focusOffset) selection.setBaseAndExtent(anchorNode, anchorOffset, focusNode, focusOffset);
514
+ }
515
+ }
516
+ // Calling preventDefault in the beforeinput handler stops the browser from performing its
517
+ // default edit action, which also suppresses its normal behavior of scrolling the caret into
518
+ // view. Recreate that behavior by measuring the caret's position with a Range and
519
+ // scrolling each scrollable ancestor of the field so it is visible.
520
+ function $a3a7b013e6c801ed$var$scrollCaretIntoView(root) {
521
+ let selection = window.getSelection();
522
+ if ((0, $d0df89f3abe2c2ca$exports.getInteractionModality)() !== 'keyboard' || !selection || selection.rangeCount === 0 || !(0, $da02ee888921bc9e$exports.nodeContains)(root, selection.focusNode)) return;
523
+ let range = selection.getRangeAt(0);
524
+ let rect = range.getBoundingClientRect();
525
+ // A collapsed range doesn't always produce a client rect. This happens for empty lines.
526
+ if (rect.top === 0 && rect.bottom === 0 && rect.left === 0 && rect.right === 0) {
527
+ let node = range.endContainer;
528
+ if (node.nodeType === Node.TEXT_NODE && range.endOffset < node.nodeValue.length) {
529
+ // If we are not at the end of the text node, extend the range to include the next character.
530
+ range = range.cloneRange();
531
+ range.setEnd(node, range.endOffset + 1);
532
+ rect = range.getBoundingClientRect();
533
+ } else if (root.firstChild == null) // If the root has no children, use its rect.
534
+ rect = root.getBoundingClientRect();
535
+ else {
536
+ // Otherwise find the next sibling element (e.g. trailing <br>) and use its rect in this case.
537
+ let nextSibling = node.nextSibling;
538
+ while(node && node !== root && !nextSibling){
539
+ node = node.parentNode;
540
+ nextSibling = node ? node.nextSibling : null;
541
+ }
542
+ if (nextSibling?.nodeType === Node.ELEMENT_NODE) rect = nextSibling.getBoundingClientRect();
543
+ }
544
+ }
545
+ for (let element of (0, $e2a63525475bbd9f$exports.getScrollParents)(root, true)){
546
+ // scrollRectIntoView only scrolls a single scroll parent based on `rect`, which is a
547
+ // snapshot of the caret's position before any scrolling occurs. Scrolling an inner ancestor
548
+ // moves the caret within the viewport, so translate `rect` by however much we just scrolled
549
+ // before moving on to the next (outer) ancestor.
550
+ let scrollParent = element;
551
+ let beforeTop = scrollParent.scrollTop;
552
+ let beforeLeft = scrollParent.scrollLeft;
553
+ (0, $9a1324d6ffd8bbb0$exports.scrollRectIntoView)(scrollParent, root, rect, {
554
+ block: 'nearest',
555
+ inline: 'nearest'
556
+ });
557
+ let dy = scrollParent.scrollTop - beforeTop;
558
+ let dx = scrollParent.scrollLeft - beforeLeft;
559
+ if (dy !== 0 || dx !== 0) rect = new DOMRect(rect.x - dx, rect.y - dy, rect.width, rect.height);
486
560
  }
487
561
  }
488
562
  function $a3a7b013e6c801ed$export$30729a8cd0694a7c(root, pos) {
489
- return $a3a7b013e6c801ed$var$createDOMRange(root, pos, pos);
563
+ // Unlike createDOMRange (used for caret/selection placement), this range is only
564
+ // measured via getBoundingClientRect to position things like an autocomplete popover.
565
+ // Place the endpoints inside the token's zero width space wrappers so the range has a
566
+ // valid rect at the token, rather than a collapsed root-level position.
567
+ let range = document.createRange();
568
+ let [startContainer, startOffset] = $a3a7b013e6c801ed$var$getDOMRectPosition(root, pos);
569
+ range.setStart(startContainer, startOffset);
570
+ range.setEnd(startContainer, startOffset);
571
+ return range;
572
+ }
573
+ function $a3a7b013e6c801ed$var$getDOMRectPosition(root, pos) {
574
+ let child = root.childNodes[pos.index];
575
+ if (child && child.nodeType === Node.ELEMENT_NODE) {
576
+ // Place the position inside the zero width space wrappers around the token.
577
+ if (pos.offset > 0) return [
578
+ child.lastChild,
579
+ 1
580
+ ];
581
+ else return [
582
+ child.firstChild,
583
+ 0
584
+ ];
585
+ }
586
+ return $a3a7b013e6c801ed$var$getDOMPosition(root, pos);
490
587
  }
491
588
  function $a3a7b013e6c801ed$var$createDOMRange(root, start, end) {
492
589
  let range = document.createRange();
493
- let startChild = root.childNodes[start.index];
494
- if (!startChild) range.setStart(root, Math.min(root.childNodes.length, start.index));
495
- else if (startChild.nodeType === Node.ELEMENT_NODE) {
496
- // Place the cursor outside the token wrapper element.
497
- if (start.offset > 0) range.setStartAfter(startChild);
498
- else range.setStartBefore(startChild);
499
- } else range.setStart(startChild, start.offset);
500
- let endChild = root.childNodes[end.index];
501
- if (!endChild) range.setEnd(root, Math.min(root.childNodes.length, end.index));
502
- else if (endChild.nodeType === Node.ELEMENT_NODE) {
503
- if (end.offset > 0) range.setEndAfter(endChild);
504
- else range.setEndBefore(endChild);
505
- } else range.setEnd(endChild, end.offset);
590
+ let [startContainer, startOffset] = $a3a7b013e6c801ed$var$getDOMPosition(root, start);
591
+ let [endContainer, endOffset] = $a3a7b013e6c801ed$var$getDOMPosition(root, end);
592
+ range.setStart(startContainer, startOffset);
593
+ range.setEnd(endContainer, endOffset);
506
594
  return range;
507
595
  }
596
+ function $a3a7b013e6c801ed$var$getDOMPosition(root, pos) {
597
+ let index = Math.max(0, Math.min(root.childNodes.length, pos.index));
598
+ let child = root.childNodes[index];
599
+ if (!child) return [
600
+ root,
601
+ index
602
+ ];
603
+ else if (child.nodeType === Node.ELEMENT_NODE) {
604
+ // Place the cursor outside the token wrapper element.
605
+ // This is necessary for composition events.
606
+ if (pos.offset > 0) return [
607
+ root,
608
+ index + 1
609
+ ];
610
+ else return [
611
+ root,
612
+ index
613
+ ];
614
+ } else {
615
+ let offset = Math.max(0, Math.min(child.textContent?.length ?? 0, pos.offset));
616
+ return [
617
+ child,
618
+ offset
619
+ ];
620
+ }
621
+ }
508
622
  function $a3a7b013e6c801ed$var$isSamePosition(a, b) {
509
623
  return a.index === b.index && a.offset === b.offset;
510
624
  }
@@ -582,6 +696,21 @@ function $a3a7b013e6c801ed$var$trackMutations(element) {
582
696
  }
583
697
  };
584
698
  }
699
+ function $a3a7b013e6c801ed$var$announceToken(value, range = value.selectedRange) {
700
+ if (range.isCollapsed) {
701
+ // Announce adjacent tokens.
702
+ let segment = value.segments[range.current.index];
703
+ if (segment && segment.type !== 'token') {
704
+ if (range.current.offset === 0) segment = value.segments[range.current.index - 1];
705
+ else if (range.current.offset === segment.text.length) segment = value.segments[range.current.index + 1];
706
+ }
707
+ if (segment?.type === 'token') (0, $74b2c5b1e7ea9589$exports.announce)(segment.text, 'assertive');
708
+ } else {
709
+ // Announce token if it is the only thing selected.
710
+ let selected = value.slice(range.start, range.end).segments;
711
+ if (selected.length === 1 && selected[0].type === 'token') (0, $74b2c5b1e7ea9589$exports.announce)(selected[0].text, 'assertive');
712
+ }
713
+ }
585
714
 
586
715
 
587
716
  //# sourceMappingURL=useTokenField.cjs.map