@astryxdesign/core 0.7.6-canary.d4b2d76 → 0.7.6-canary.d51f57e

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 (193) hide show
  1. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  2. package/dist/Collapsible/Collapsible.js +23 -3
  3. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  4. package/dist/DropdownMenu/DropdownMenu.js +1 -58
  5. package/dist/Grid/GridSpan.d.ts +2 -0
  6. package/dist/Grid/GridSpan.d.ts.map +1 -1
  7. package/dist/Grid/GridSpan.js +2 -0
  8. package/dist/Heading/Heading.d.ts +5 -3
  9. package/dist/Heading/Heading.d.ts.map +1 -1
  10. package/dist/Heading/Heading.js +5 -3
  11. package/dist/SegmentedControl/SegmentedControl.d.ts +7 -5
  12. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  13. package/dist/SegmentedControl/SegmentedControl.js +13 -20
  14. package/dist/SegmentedControl/SegmentedControlContext.d.ts +2 -9
  15. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  16. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  17. package/dist/SegmentedControl/SegmentedControlItem.js +4 -14
  18. package/dist/SideNav/SideNav.d.ts.map +1 -1
  19. package/dist/SideNav/SideNav.js +126 -5
  20. package/dist/SideNav/SideNavCollapseButton.d.ts.map +1 -1
  21. package/dist/SideNav/SideNavCollapseButton.js +11 -2
  22. package/dist/SideNav/SideNavFocusTargetsContext.d.ts +11 -0
  23. package/dist/SideNav/SideNavFocusTargetsContext.d.ts.map +1 -0
  24. package/dist/SideNav/SideNavFocusTargetsContext.js +16 -0
  25. package/dist/SideNav/SideNavHeading.js +6 -2
  26. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  27. package/dist/SideNav/SideNavItem.js +13 -1
  28. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  29. package/dist/TopNav/TopNavHeading.js +8 -2
  30. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  31. package/dist/hooks/useFocusTrap.js +2 -3
  32. package/dist/hooks/useListFocus.d.ts +10 -7
  33. package/dist/hooks/useListFocus.d.ts.map +1 -1
  34. package/dist/hooks/useListFocus.js +29 -17
  35. package/dist/i18n/generated-locales/af-ZA.generated.d.ts.map +1 -1
  36. package/dist/i18n/generated-locales/af-ZA.generated.js +2 -2
  37. package/dist/i18n/generated-locales/ar-SA.generated.d.ts.map +1 -1
  38. package/dist/i18n/generated-locales/ar-SA.generated.js +2 -2
  39. package/dist/i18n/generated-locales/ca-ES.generated.d.ts.map +1 -1
  40. package/dist/i18n/generated-locales/ca-ES.generated.js +2 -2
  41. package/dist/i18n/generated-locales/cs-CZ.generated.d.ts.map +1 -1
  42. package/dist/i18n/generated-locales/cs-CZ.generated.js +2 -2
  43. package/dist/i18n/generated-locales/da-DK.generated.d.ts.map +1 -1
  44. package/dist/i18n/generated-locales/da-DK.generated.js +2 -2
  45. package/dist/i18n/generated-locales/de-DE.generated.d.ts.map +1 -1
  46. package/dist/i18n/generated-locales/de-DE.generated.js +2 -2
  47. package/dist/i18n/generated-locales/el-GR.generated.d.ts.map +1 -1
  48. package/dist/i18n/generated-locales/el-GR.generated.js +2 -2
  49. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  50. package/dist/i18n/generated-locales/en.generated.js +2 -2
  51. package/dist/i18n/generated-locales/es-ES.generated.d.ts.map +1 -1
  52. package/dist/i18n/generated-locales/es-ES.generated.js +2 -2
  53. package/dist/i18n/generated-locales/fi-FI.generated.d.ts.map +1 -1
  54. package/dist/i18n/generated-locales/fi-FI.generated.js +2 -2
  55. package/dist/i18n/generated-locales/fr-FR.generated.d.ts.map +1 -1
  56. package/dist/i18n/generated-locales/fr-FR.generated.js +2 -2
  57. package/dist/i18n/generated-locales/he-IL.generated.d.ts.map +1 -1
  58. package/dist/i18n/generated-locales/he-IL.generated.js +2 -2
  59. package/dist/i18n/generated-locales/hu-HU.generated.d.ts.map +1 -1
  60. package/dist/i18n/generated-locales/hu-HU.generated.js +2 -2
  61. package/dist/i18n/generated-locales/it-IT.generated.d.ts.map +1 -1
  62. package/dist/i18n/generated-locales/it-IT.generated.js +2 -2
  63. package/dist/i18n/generated-locales/ja-JP.generated.d.ts.map +1 -1
  64. package/dist/i18n/generated-locales/ja-JP.generated.js +2 -2
  65. package/dist/i18n/generated-locales/ko-KR.generated.d.ts.map +1 -1
  66. package/dist/i18n/generated-locales/ko-KR.generated.js +2 -2
  67. package/dist/i18n/generated-locales/nl-NL.generated.d.ts.map +1 -1
  68. package/dist/i18n/generated-locales/nl-NL.generated.js +2 -2
  69. package/dist/i18n/generated-locales/no-NO.generated.d.ts.map +1 -1
  70. package/dist/i18n/generated-locales/no-NO.generated.js +2 -2
  71. package/dist/i18n/generated-locales/pl-PL.generated.d.ts.map +1 -1
  72. package/dist/i18n/generated-locales/pl-PL.generated.js +2 -2
  73. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  74. package/dist/i18n/generated-locales/pseudo.generated.js +2 -2
  75. package/dist/i18n/generated-locales/pt-BR.generated.d.ts.map +1 -1
  76. package/dist/i18n/generated-locales/pt-BR.generated.js +2 -2
  77. package/dist/i18n/generated-locales/pt-PT.generated.d.ts.map +1 -1
  78. package/dist/i18n/generated-locales/pt-PT.generated.js +2 -2
  79. package/dist/i18n/generated-locales/ro-RO.generated.d.ts.map +1 -1
  80. package/dist/i18n/generated-locales/ro-RO.generated.js +2 -2
  81. package/dist/i18n/generated-locales/ru-RU.generated.d.ts.map +1 -1
  82. package/dist/i18n/generated-locales/ru-RU.generated.js +2 -2
  83. package/dist/i18n/generated-locales/sr-SP.generated.d.ts.map +1 -1
  84. package/dist/i18n/generated-locales/sr-SP.generated.js +2 -2
  85. package/dist/i18n/generated-locales/sv-SE.generated.d.ts.map +1 -1
  86. package/dist/i18n/generated-locales/sv-SE.generated.js +2 -2
  87. package/dist/i18n/generated-locales/tr-TR.generated.d.ts.map +1 -1
  88. package/dist/i18n/generated-locales/tr-TR.generated.js +2 -2
  89. package/dist/i18n/generated-locales/uk-UA.generated.d.ts.map +1 -1
  90. package/dist/i18n/generated-locales/uk-UA.generated.js +2 -2
  91. package/dist/i18n/generated-locales/vi-VN.generated.d.ts.map +1 -1
  92. package/dist/i18n/generated-locales/vi-VN.generated.js +2 -2
  93. package/dist/i18n/generated-locales/zh-CN.generated.d.ts.map +1 -1
  94. package/dist/i18n/generated-locales/zh-CN.generated.js +2 -2
  95. package/dist/i18n/generated-locales/zh-TW.generated.d.ts.map +1 -1
  96. package/dist/i18n/generated-locales/zh-TW.generated.js +2 -2
  97. package/dist/motion/animator.d.ts.map +1 -1
  98. package/dist/motion/animator.js +69 -3
  99. package/dist/utils/accessibleName.d.ts +8 -0
  100. package/dist/utils/accessibleName.d.ts.map +1 -0
  101. package/dist/utils/accessibleName.js +72 -0
  102. package/dist/utils/focusReturn.d.ts +35 -2
  103. package/dist/utils/focusReturn.d.ts.map +1 -1
  104. package/dist/utils/focusReturn.js +53 -2
  105. package/dist/utils/useFocusLeavingChange.d.ts +13 -0
  106. package/dist/utils/useFocusLeavingChange.d.ts.map +1 -0
  107. package/dist/utils/useFocusLeavingChange.js +48 -0
  108. package/locales/af-ZA.json +2 -2
  109. package/locales/ar-SA.json +2 -2
  110. package/locales/ca-ES.json +2 -2
  111. package/locales/cs-CZ.json +2 -2
  112. package/locales/da-DK.json +2 -2
  113. package/locales/de-DE.json +2 -2
  114. package/locales/el-GR.json +2 -2
  115. package/locales/en.json +4 -4
  116. package/locales/es-ES.json +2 -2
  117. package/locales/fi-FI.json +2 -2
  118. package/locales/fr-FR.json +2 -2
  119. package/locales/he-IL.json +2 -2
  120. package/locales/hu-HU.json +2 -2
  121. package/locales/it-IT.json +2 -2
  122. package/locales/ja-JP.json +2 -2
  123. package/locales/ko-KR.json +2 -2
  124. package/locales/nl-NL.json +2 -2
  125. package/locales/no-NO.json +2 -2
  126. package/locales/pl-PL.json +2 -2
  127. package/locales/pseudo.json +2 -2
  128. package/locales/pt-BR.json +2 -2
  129. package/locales/pt-PT.json +2 -2
  130. package/locales/ro-RO.json +2 -2
  131. package/locales/ru-RU.json +2 -2
  132. package/locales/sr-SP.json +2 -2
  133. package/locales/sv-SE.json +2 -2
  134. package/locales/tr-TR.json +2 -2
  135. package/locales/uk-UA.json +2 -2
  136. package/locales/vi-VN.json +2 -2
  137. package/locales/zh-CN.json +2 -2
  138. package/locales/zh-TW.json +2 -2
  139. package/package.json +4 -4
  140. package/src/Collapsible/Collapsible.tsx +33 -4
  141. package/src/DropdownMenu/DropdownMenu.tsx +1 -71
  142. package/src/Grid/GridSpan.doc.mjs +51 -2
  143. package/src/Grid/GridSpan.tsx +2 -0
  144. package/src/Heading/Heading.tsx +5 -3
  145. package/src/SegmentedControl/SegmentedControl.doc.mjs +5 -5
  146. package/src/SegmentedControl/SegmentedControl.tsx +23 -30
  147. package/src/SegmentedControl/SegmentedControlContext.ts +2 -9
  148. package/src/SegmentedControl/SegmentedControlItem.doc.mjs +1 -1
  149. package/src/SegmentedControl/SegmentedControlItem.tsx +4 -17
  150. package/src/SideNav/SideNav.tsx +182 -6
  151. package/src/SideNav/SideNavCollapseButton.tsx +18 -2
  152. package/src/SideNav/SideNavFocusTargetsContext.ts +29 -0
  153. package/src/SideNav/SideNavHeading.tsx +2 -2
  154. package/src/SideNav/SideNavItem.tsx +19 -3
  155. package/src/Text/Heading.doc.mjs +49 -0
  156. package/src/TopNav/TopNavHeading.tsx +8 -2
  157. package/src/hooks/useFocusTrap.ts +2 -8
  158. package/src/hooks/useListFocus.ts +51 -22
  159. package/src/i18n/generated-locales/af-ZA.generated.ts +3 -2
  160. package/src/i18n/generated-locales/ar-SA.generated.ts +3 -2
  161. package/src/i18n/generated-locales/ca-ES.generated.ts +3 -2
  162. package/src/i18n/generated-locales/cs-CZ.generated.ts +3 -2
  163. package/src/i18n/generated-locales/da-DK.generated.ts +3 -2
  164. package/src/i18n/generated-locales/de-DE.generated.ts +3 -2
  165. package/src/i18n/generated-locales/el-GR.generated.ts +3 -2
  166. package/src/i18n/generated-locales/en.generated.ts +3 -2
  167. package/src/i18n/generated-locales/es-ES.generated.ts +3 -2
  168. package/src/i18n/generated-locales/fi-FI.generated.ts +3 -2
  169. package/src/i18n/generated-locales/fr-FR.generated.ts +3 -2
  170. package/src/i18n/generated-locales/he-IL.generated.ts +3 -2
  171. package/src/i18n/generated-locales/hu-HU.generated.ts +3 -2
  172. package/src/i18n/generated-locales/it-IT.generated.ts +3 -2
  173. package/src/i18n/generated-locales/ja-JP.generated.ts +3 -2
  174. package/src/i18n/generated-locales/ko-KR.generated.ts +3 -2
  175. package/src/i18n/generated-locales/nl-NL.generated.ts +3 -2
  176. package/src/i18n/generated-locales/no-NO.generated.ts +3 -2
  177. package/src/i18n/generated-locales/pl-PL.generated.ts +3 -2
  178. package/src/i18n/generated-locales/pseudo.generated.ts +3 -2
  179. package/src/i18n/generated-locales/pt-BR.generated.ts +3 -2
  180. package/src/i18n/generated-locales/pt-PT.generated.ts +3 -2
  181. package/src/i18n/generated-locales/ro-RO.generated.ts +3 -2
  182. package/src/i18n/generated-locales/ru-RU.generated.ts +3 -2
  183. package/src/i18n/generated-locales/sr-SP.generated.ts +3 -2
  184. package/src/i18n/generated-locales/sv-SE.generated.ts +3 -2
  185. package/src/i18n/generated-locales/tr-TR.generated.ts +3 -2
  186. package/src/i18n/generated-locales/uk-UA.generated.ts +3 -2
  187. package/src/i18n/generated-locales/vi-VN.generated.ts +3 -2
  188. package/src/i18n/generated-locales/zh-CN.generated.ts +3 -2
  189. package/src/i18n/generated-locales/zh-TW.generated.ts +3 -2
  190. package/src/motion/animator.ts +81 -11
  191. package/src/utils/accessibleName.ts +87 -0
  192. package/src/utils/focusReturn.ts +67 -2
  193. package/src/utils/useFocusLeavingChange.ts +53 -0
@@ -1 +1 @@
1
- {"version":3,"file":"Collapsible.d.ts","sourceRoot":"","sources":["../../src/Collapsible/Collapsible.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAef,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAC,0BAA0B,EAAC,MAAM,2BAA2B,CAAC;AAG1E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA0J5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,OAAO,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,eAAe,CAAC,EAAE,0BAA0B,CAAC;IAE7C;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,aAAa,EACb,MAAM,EAAE,gBAAgB,EACxB,UAAkB,EAClB,YAAY,EACZ,eAAe,EACf,KAAK,EACL,cAAc,EACd,GAAG,EACH,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,gBAAgB,+BAmOlB;yBAlPe,WAAW"}
1
+ {"version":3,"file":"Collapsible.d.ts","sourceRoot":"","sources":["../../src/Collapsible/Collapsible.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAuBf,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,0BAA0B,CAAC;AAElC,OAAO,KAAK,EAAC,0BAA0B,EAAC,MAAM,2BAA2B,CAAC;AAG1E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AA0J5C,MAAM,WAAW,gBAAiB,SAAQ,SAAS;IACjD,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;OAGG;IACH,OAAO,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;IAErB;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IAExB;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;;;;;;OAQG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACzC;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAEhC;;;;;;;;;;;;OAYG;IACH,eAAe,CAAC,EAAE,0BAA0B,CAAC;IAE7C;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,aAAa,EACb,MAAM,EAAE,gBAAgB,EACxB,UAAkB,EAClB,YAAY,EACZ,eAAe,EACf,KAAK,EACL,cAAc,EACd,GAAG,EACH,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,KAAK,EACT,EAAE,gBAAgB,+BAwPlB;yBAvQe,WAAW"}
@@ -32,6 +32,10 @@ import "../theme/tokens.stylex.js";
32
32
  import { borderVars, colorVars, typographyVars, fontWeightVars, spacingVars, typeScaleVars, durationVars, easeVars } from "../theme/tokens.stylex.js";
33
33
  import { useCollapsible } from "./useCollapsible.js";
34
34
  import { LayoutChangeSnapshot } from "../motion/LayoutChangeSnapshot.js";
35
+ import { moveFocusLeftBehind, noteFocusWithin } from "../utils/focusReturn.js";
36
+ import { useInteractionModalityTracking } from "../utils/interactionModality.js";
37
+ import { useFocusLeavingChange } from "../utils/useFocusLeavingChange.js";
38
+ import { useMergedRefs } from "../hooks/useMergedRefs.js";
35
39
  import { applyLayoutChangeTransition, holdLayoutExit, playLayoutChange, releaseLayoutExit, reportLayoutChange } from "../motion/animatedLayout.js";
36
40
  import { CollapsibleGroupPresentationContext } from "./CollapsibleGroupContext.js";
37
41
  import { Icon } from "../Icon/index.js";
@@ -303,6 +307,22 @@ export function Collapsible({
303
307
  }
304
308
  }, [isOpen, isExiting]);
305
309
 
310
+ // Focus inside the content when it closes would be lost to the page once
311
+ // the content hides. It moves to the trigger that closes it (AR4); focus
312
+ // anywhere else is not moved. The shared sequence notes it in the commit
313
+ // before the DOM changes and moves it once the close has committed.
314
+ // The trigger's own document's last input decides the moved focus's ring.
315
+ const {
316
+ ref: modalityRef
317
+ } = useInteractionModalityTracking();
318
+ const mergedTriggerRef = useMergedRefs(triggerRef, modalityRef);
319
+ const noteClosingFocus = useFocusLeavingChange(isOpen, wasOpen => wasOpen ? noteFocusWithin(contentRef.current) : null, focus => moveFocusLeftBehind(focus, triggerRef.current, contentRef.current));
320
+ const beforeOpenChange = useCallback(wasOpen => {
321
+ noteClosingFocus(wasOpen);
322
+ if (animatedLayout != null) {
323
+ measureChange();
324
+ }
325
+ }, [animatedLayout, measureChange, noteClosingFocus]);
306
326
  // Activation is blocked by this guard rather than the native `disabled`
307
327
  // attribute, so the trigger keeps `aria-disabled` semantics and stays
308
328
  // discoverable. A native `disabled` button would silently swallow events
@@ -349,7 +369,7 @@ export function Collapsible({
349
369
  }), stylex.props(styles.root, isDivided && styles.divided, xstyle), className, style),
350
370
  ...props,
351
371
  children: [/*#__PURE__*/_jsxs("button", {
352
- ref: triggerRef,
372
+ ref: mergedTriggerRef,
353
373
  type: "button",
354
374
  onClick: handleToggle,
355
375
  "aria-disabled": isDisabled || undefined,
@@ -379,9 +399,9 @@ export function Collapsible({
379
399
  },
380
400
  children: trigger
381
401
  }), !isChevronAtStart && chevron]
382
- }), animatedLayout != null && /*#__PURE__*/_jsx(LayoutChangeSnapshot, {
402
+ }), /*#__PURE__*/_jsx(LayoutChangeSnapshot, {
383
403
  value: isOpen,
384
- onBeforeChange: measureChange
404
+ onBeforeChange: beforeOpenChange
385
405
  }), /*#__PURE__*/_jsx("div", {
386
406
  ref: contentRef,
387
407
  id: contentId,
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"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"}
@@ -35,6 +35,7 @@
35
35
  * - /packages/cli/assets/templates/blocks/components/DropdownMenu/ (showcase blocks)
36
36
  */
37
37
  import React, { useCallback, useEffect, useId, useMemo, useRef, useState } from 'react';
38
+ import { readAccessibleName } from "../utils/accessibleName.js";
38
39
  import * as stylex from '@stylexjs/stylex';
39
40
  import { usePopover } from "../Popover/usePopover.js";
40
41
  import { Button } from "../Button/index.js";
@@ -276,64 +277,6 @@ function holdInvokerThroughPress(control, popoverId) {
276
277
  doc.addEventListener('pointerup', onPressEnd, true);
277
278
  doc.addEventListener('pointercancel', onPressEnd, true);
278
279
  }
279
-
280
- /** Text an assistive technology reads from `element`, `aria-hidden` left out. */
281
- function visibleText(element) {
282
- const copy = element.cloneNode(true);
283
- for (const hidden of copy.querySelectorAll('[aria-hidden="true"]')) {
284
- hidden.remove();
285
- }
286
- // An icon-only control is named by its image's alt, an inner aria-label, or
287
- // an svg title rather than by text, so those count as its contents too.
288
- for (const named of copy.querySelectorAll('img[alt], [aria-label]')) {
289
- const name = named.getAttribute(named.tagName === 'IMG' ? 'alt' : 'aria-label') ?? '';
290
- named.replaceWith(copy.ownerDocument.createTextNode(` ${name} `));
291
- }
292
- for (const svg of copy.querySelectorAll('svg')) {
293
- const title = svg.querySelector('title')?.textContent ?? '';
294
- svg.replaceWith(copy.ownerDocument.createTextNode(` ${title} `));
295
- }
296
- return (copy.textContent ?? '').replace(/\s+/g, ' ').trim();
297
- }
298
-
299
- /**
300
- * The name a custom trigger gives the menu it labels (`aria-labelledby` on
301
- * the menu points at it): its own `aria-labelledby` targets, its
302
- * `aria-label`, its text, or its `title`, in that order.
303
- */
304
- function readAccessibleName(element) {
305
- if (element == null) {
306
- return undefined;
307
- }
308
- const labelledBy = element.getAttribute('aria-labelledby');
309
- if (labelledBy != null && labelledBy.trim() !== '') {
310
- const text = labelledBy.split(/\s+/).map(id => element.ownerDocument.getElementById(id)).filter(node => node != null).map(visibleText).join(' ').trim();
311
- if (text !== '') {
312
- return text;
313
- }
314
- }
315
- const label = element.getAttribute('aria-label')?.trim();
316
- if (label) {
317
- return label;
318
- }
319
- // A form control is named by its own <label>s; an input button by its value.
320
- const labels = 'labels' in element ? Array.from(element.labels ?? []) : [];
321
- const labelText = labels.map(visibleText).join(' ').trim();
322
- if (labelText !== '') {
323
- return labelText;
324
- }
325
- if (element instanceof HTMLInputElement && ['button', 'submit', 'reset'].includes(element.getAttribute('type') ?? '')) {
326
- const value = element.value.trim();
327
- if (value !== '') {
328
- return value;
329
- }
330
- }
331
- const text = visibleText(element);
332
- if (text !== '') {
333
- return text;
334
- }
335
- return element.getAttribute('title')?.trim() || undefined;
336
- }
337
280
  function DropdownMenuBottomSheet({
338
281
  button: buttonFromProps,
339
282
  renderTrigger,
@@ -5,8 +5,10 @@
5
5
  * @position Grid span component; controls grid item span
6
6
  *
7
7
  * SYNC: When modified, update these files to stay in sync:
8
+ * - /packages/core/src/Grid/GridSpan.doc.mjs
8
9
  * - /packages/core/src/Grid/Grid.doc.mjs
9
10
  * - /packages/core/src/Grid/Grid.test.tsx
11
+ * - /apps/storybook/stories/GridSpan.stories.tsx
10
12
  * - /apps/storybook/stories/Grid.stories.tsx
11
13
  * - /packages/cli/assets/templates/blocks/components/Grid/ (showcase blocks)
12
14
  */
@@ -1 +1 @@
1
- {"version":3,"file":"GridSpan.d.ts","sourceRoot":"","sources":["../../src/Grid/GridSpan.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAK5C,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAeD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,IAAI,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,KAAK,EACT,EAAE,aAAa,+BAwBf;yBAjCe,QAAQ"}
1
+ {"version":3,"file":"GridSpan.d.ts","sourceRoot":"","sources":["../../src/Grid/GridSpan.tsx"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAK5C,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;;;OAIG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAE1B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAeD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,QAAQ,CAAC,EACvB,OAAO,EACP,IAAI,EACJ,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,KAAK,EACT,EAAE,aAAa,+BAwBf;yBAjCe,QAAQ"}
@@ -7,8 +7,10 @@
7
7
  * @position Grid span component; controls grid item span
8
8
  *
9
9
  * SYNC: When modified, update these files to stay in sync:
10
+ * - /packages/core/src/Grid/GridSpan.doc.mjs
10
11
  * - /packages/core/src/Grid/Grid.doc.mjs
11
12
  * - /packages/core/src/Grid/Grid.test.tsx
13
+ * - /apps/storybook/stories/GridSpan.stories.tsx
12
14
  * - /apps/storybook/stories/Grid.stories.tsx
13
15
  * - /packages/cli/assets/templates/blocks/components/Grid/ (showcase blocks)
14
16
  */
@@ -5,10 +5,12 @@
5
5
  * @position Core implementation; lives in own Heading/ dir, re-exported by Text/
6
6
  *
7
7
  * SYNC: When modified, update these files to stay in sync:
8
- * - /packages/core/src/Text/Text.doc.mjs (props table, features, implementation notes)
8
+ * - /packages/core/src/Text/Heading.doc.mjs (props table, theming target)
9
+ * - /packages/core/src/Text/Text.doc.mjs (shared truncation and tooltip guidance)
9
10
  * - /packages/core/src/Heading/Heading.test.tsx (tests for new/changed behavior)
10
- * - /packages/core/src/Text/index.ts (exports if types change)
11
- * - /apps/storybook/stories/Text.stories.tsx (storybook stories)
11
+ * - /packages/core/src/Heading/index.ts (exports if types change)
12
+ * - /packages/core/src/Text/index.ts (re-exports if types change)
13
+ * - /apps/storybook/stories/Heading.stories.tsx (storybook stories)
12
14
  * - /packages/cli/assets/templates/blocks/components/Heading/ (showcase blocks)
13
15
  * - /packages/cli/assets/templates/blocks/components/Text/ (showcase blocks)
14
16
  */
@@ -1 +1 @@
1
- {"version":3,"file":"Heading.d.ts","sourceRoot":"","sources":["../../src/Heading/Heading.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAyB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAE7D,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,SAAS,EACT,QAAQ,EACR,UAAU,EACX,MAAM,gBAAgB,CAAC;AAkBxB,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAG7C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAM5C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC;AAQ/C,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,SAAS,CAAC,kBAAkB,CAAC,EAC7B,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACpC;;;OAGG;IACH,KAAK,EAAE,YAAY,CAAC;IAEpB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAElC;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC;IAE9C;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,IAAI,EACJ,MAAM,EACN,kBAAkB,EAClB,KAAiB,EACjB,OAAiB,EACjB,QAAY,EACZ,kBAAyB,EACzB,SAAS,EACT,QAAQ,EACR,OAAiB,EACjB,UAAkB,EAClB,gBAAwB,EACxB,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,KAAK,EACT,EAAE,YAAY,+BAsGd;yBA1He,OAAO"}
1
+ {"version":3,"file":"Heading.d.ts","sourceRoot":"","sources":["../../src/Heading/Heading.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAyB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAE7D,OAAO,KAAK,EACV,SAAS,EACT,WAAW,EACX,WAAW,EACX,SAAS,EACT,QAAQ,EACR,UAAU,EACX,MAAM,gBAAgB,CAAC;AAkBxB,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,UAAU,CAAC;AAG7C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,SAAS,CAAC;AAM5C;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,MAAM,cAAc,CAAC;AAQ/C,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,SAAS,CAAC,kBAAkB,CAAC,EAC7B,UAAU,CACX;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC;IACpC;;;OAGG;IACH,KAAK,EAAE,YAAY,CAAC;IAEpB;;;;;;;;;;;;;OAaG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB;;;;;;;;;;;OAWG;IACH,kBAAkB,CAAC,EAAE,YAAY,CAAC;IAElC;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAElB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB;;;;;;OAMG;IACH,kBAAkB,CAAC,EAAE,OAAO,GAAG,cAAc,CAAC;IAE9C;;;OAGG;IACH,SAAS,CAAC,EAAE,SAAS,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,EAAE,QAAQ,CAAC;IAEpB;;;;OAIG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;;OAIG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAE3B;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AAWD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,KAAK,EACL,IAAI,EACJ,MAAM,EACN,kBAAkB,EAClB,KAAiB,EACjB,OAAiB,EACjB,QAAY,EACZ,kBAAyB,EACzB,SAAS,EACT,QAAQ,EACR,OAAiB,EACjB,UAAkB,EAClB,gBAAwB,EACxB,MAAM,EACN,SAAS,EACT,KAAK,EACL,QAAQ,EACR,GAAG,EACH,GAAG,KAAK,EACT,EAAE,YAAY,+BAsGd;yBA1He,OAAO"}
@@ -9,10 +9,12 @@
9
9
  * @position Core implementation; lives in own Heading/ dir, re-exported by Text/
10
10
  *
11
11
  * SYNC: When modified, update these files to stay in sync:
12
- * - /packages/core/src/Text/Text.doc.mjs (props table, features, implementation notes)
12
+ * - /packages/core/src/Text/Heading.doc.mjs (props table, theming target)
13
+ * - /packages/core/src/Text/Text.doc.mjs (shared truncation and tooltip guidance)
13
14
  * - /packages/core/src/Heading/Heading.test.tsx (tests for new/changed behavior)
14
- * - /packages/core/src/Text/index.ts (exports if types change)
15
- * - /apps/storybook/stories/Text.stories.tsx (storybook stories)
15
+ * - /packages/core/src/Heading/index.ts (exports if types change)
16
+ * - /packages/core/src/Text/index.ts (re-exports if types change)
17
+ * - /apps/storybook/stories/Heading.stories.tsx (storybook stories)
16
18
  * - /packages/cli/assets/templates/blocks/components/Heading/ (showcase blocks)
17
19
  * - /packages/cli/assets/templates/blocks/components/Text/ (showcase blocks)
18
20
  */
@@ -41,7 +41,9 @@ export interface SegmentedControlProps extends Omit<BaseProps<HTMLDivElement>, '
41
41
  */
42
42
  layout?: SegmentedControlLayout;
43
43
  /**
44
- * Whether the entire control is disabled.
44
+ * Whether the entire control is disabled. The selected segment keeps the
45
+ * control's Tab stop, announced as disabled (`aria-disabled`), and nothing
46
+ * can be selected.
45
47
  * @default false
46
48
  */
47
49
  isDisabled?: boolean;
@@ -49,11 +51,11 @@ export interface SegmentedControlProps extends Omit<BaseProps<HTMLDivElement>, '
49
51
  * Explains why the control is disabled. Applies to the whole-group disabled
50
52
  * state (`isDisabled`), not individual segments. When set together with
51
53
  * `isDisabled`, the control shows a tooltip with this text on hover and
52
- * keyboard focus, and stays focusable (via `aria-disabled`) so the reason is
53
- * discoverable by keyboard and assistive technology. Selection stays blocked.
54
+ * keyboard focus, and the reason describes each segment for assistive
55
+ * technology. Selection stays blocked.
54
56
  *
55
- * Use this instead of wrapping a disabled control in `Tooltip` — disabled
56
- * controls don't emit the pointer events an external tooltip needs.
57
+ * Use this instead of wrapping a disabled control in `Tooltip`, so the
58
+ * reason is attached to the control itself.
57
59
  */
58
60
  disabledMessage?: string;
59
61
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControl.d.ts","sourceRoot":"","sources":["../../src/SegmentedControl/SegmentedControl.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAAuB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAQlE,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,2BAA2B,CAAC;AAInC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AA8DD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,KAAK,EACL,QAAQ,EACR,KAAK,EACL,IAAI,EAAE,QAAQ,EACd,MAAc,EACd,UAAkB,EAClB,eAAe,EACf,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,kBAAkB,EAAE,mBAAmB,EACvC,GAAG,IAAI,EACR,EAAE,qBAAqB,qBAyJvB;yBA3Ke,gBAAgB"}
1
+ {"version":3,"file":"SegmentedControl.d.ts","sourceRoot":"","sources":["../../src/SegmentedControl/SegmentedControl.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAAuB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAQlE,OAAO,KAAK,EACV,oBAAoB,EACpB,sBAAsB,EACvB,MAAM,2BAA2B,CAAC;AAInC,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAI5C,MAAM,WAAW,qBAAsB,SAAQ,IAAI,CACjD,SAAS,CAAC,cAAc,CAAC,EACzB,UAAU,CACX;IACC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;OAEG;IACH,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,IAAI,CAAC,EAAE,oBAAoB,CAAC;IAC5B;;;;;;OAMG;IACH,MAAM,CAAC,EAAE,sBAAsB,CAAC;IAChC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;OASG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;CACrB;AA0DD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,GAAG,EACH,KAAK,EACL,QAAQ,EACR,KAAK,EACL,IAAI,EAAE,QAAQ,EACd,MAAc,EACd,UAAkB,EAClB,eAAe,EACf,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,kBAAkB,EAAE,mBAAmB,EACvC,GAAG,IAAI,EACR,EAAE,qBAAqB,qBAoJvB;yBAtKe,gBAAgB"}
@@ -52,11 +52,6 @@ const styles = {
52
52
  $$css: true
53
53
  },
54
54
  disabled: {
55
- kSiTet: "xbyyjgo",
56
- kfzvcC: "x47corl",
57
- $$css: true
58
- },
59
- disabledWithMessage: {
60
55
  kSiTet: "xbyyjgo",
61
56
  $$css: true
62
57
  }
@@ -113,11 +108,10 @@ export function SegmentedControl({
113
108
  }) {
114
109
  const size = useSize(sizeProp, 'md');
115
110
 
116
- // Disabled-reason tooltip. Applies to the whole-group disabled state. Disabled
117
- // controls swallow pointer events, so the tooltip listeners attach to the
118
- // radiogroup container (and the container keeps pointer events on in this
119
- // mode) while the radios stay perceivable via aria-disabled. Selection is
120
- // blocked by the isDisabled guards in the click/focus handlers.
111
+ // Disabled-reason tooltip. Applies to the whole-group disabled state. The
112
+ // tooltip listeners attach to the radiogroup container, which keeps pointer
113
+ // events while disabled; the radios stay perceivable via aria-disabled.
114
+ // Selection is blocked by the isDisabled guards in the click/focus handlers.
121
115
  const showsDisabledMessage = isDisabled && !!disabledMessage;
122
116
  const disabledMessageTooltip = useTooltip({
123
117
  placement: 'above',
@@ -139,10 +133,10 @@ export function SegmentedControl({
139
133
  } = useInternalListFocus({
140
134
  itemSelector: '[role="radio"]:not([aria-disabled="true"])',
141
135
  hasRovingTabIndex: true,
142
- // Disabled with a reason, the control keeps one Tab stop so the reason is
143
- // reachable (FR2, FR7): the selected segment, else the first segment not
144
- // disabled by its own isDisabled, else the first.
145
- disabledTabStop: showsDisabledMessage ? orderDisabledTabStop : undefined,
136
+ // One Tab stop, placed by the control (FR2, FR7): the selected segment,
137
+ // enabled or not and in a disabled control too, else the first segment
138
+ // not disabled by its own isDisabled, else the first.
139
+ tabStopOrder: orderTabStop,
146
140
  wrap: true,
147
141
  orientation: 'horizontal'
148
142
  });
@@ -200,7 +194,6 @@ export function SegmentedControl({
200
194
  size,
201
195
  layout,
202
196
  isDisabled,
203
- hasDisabledMessage: showsDisabledMessage,
204
197
  disabledReasonID: showsDisabledMessage ? disabledMessageTooltip.describedBy : undefined
205
198
  }), [value, onChange, size, layout, isDisabled, showsDisabledMessage, disabledMessageTooltip.describedBy]);
206
199
  return /*#__PURE__*/_jsxs(SegmentedControlContext, {
@@ -219,7 +212,7 @@ export function SegmentedControl({
219
212
  onBlur: composeEventHandlers(onBlurProp, hint.onBlur),
220
213
  ...mergeProps(themeProps('segmented-control', {
221
214
  size
222
- }), stylex.props(styles.container, sizeStyles[size], layout === 'fill' && styles.fill, isDisabled && (showsDisabledMessage ? styles.disabledWithMessage : styles.disabled), xstyle), className, style),
215
+ }), stylex.props(styles.container, sizeStyles[size], layout === 'fill' && styles.fill, isDisabled && styles.disabled, xstyle), className, style),
223
216
  children: [children, hint.hintElement]
224
217
  }), showsDisabledMessage && disabledMessageTooltip.renderTooltip(disabledMessage)]
225
218
  });
@@ -227,11 +220,11 @@ export function SegmentedControl({
227
220
  SegmentedControl.displayName = 'SegmentedControl';
228
221
 
229
222
  /**
230
- * The segments of a control disabled with a reason, its Tab stop first: the
231
- * selected segment, else the first segment not disabled by its own
232
- * isDisabled, else the first (FR2, FR7).
223
+ * The control's segments, its Tab stop first: the selected segment, enabled
224
+ * or not, else the first segment not disabled by its own isDisabled, else the
225
+ * first (FR2, FR7).
233
226
  */
234
- function orderDisabledTabStop(list) {
227
+ function orderTabStop(list) {
235
228
  const segments = Array.from(list.querySelectorAll('[role="radio"]'));
236
229
  const stop = segments.find(segment => segment.getAttribute('aria-checked') === 'true') ?? segments.find(segment => !isSegmentDisabledOnItsOwn(segment)) ?? segments[0];
237
230
  return stop == null ? [] : [stop, ...segments.filter(segment => segment !== stop)];
@@ -7,15 +7,8 @@ export interface SegmentedControlContextValue {
7
7
  layout: SegmentedControlLayout;
8
8
  isDisabled: boolean;
9
9
  /**
10
- * True when the whole control is disabled *and* a `disabledMessage` is set.
11
- * In that mode the selected segment stays focusable (via `aria-disabled`
12
- * rather than being dropped from the tab order) so the group's disabled-reason
13
- * tooltip is keyboard-discoverable; selection is still blocked.
14
- */
15
- hasDisabledMessage?: boolean;
16
- /**
17
- * The id of the group's disabled-reason tooltip while `hasDisabledMessage`
18
- * is true. It also describes each segment, so the segment that has focus is
10
+ * The id of the group's disabled-reason tooltip while the group is disabled
11
+ * with a `disabledMessage`. It also describes each segment, so the segment that has focus is
19
12
  * described by the reason (spec:AST-085 FR5).
20
13
  */
21
14
  disabledReasonID?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControlContext.d.ts","sourceRoot":"","sources":["../../src/SegmentedControl/SegmentedControlContext.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACtD,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,uBAAuB,8DACsB,CAAC;AAG3D,wBAAgB,0BAA0B,IAAI,4BAA4B,CASzE"}
1
+ {"version":3,"file":"SegmentedControlContext.d.ts","sourceRoot":"","sources":["../../src/SegmentedControl/SegmentedControlContext.ts"],"names":[],"mappings":"AAgBA,MAAM,MAAM,oBAAoB,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AACtD,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,MAAM,CAAC;AAEpD,MAAM,WAAW,4BAA4B;IAC3C,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,IAAI,EAAE,oBAAoB,CAAC;IAC3B,MAAM,EAAE,sBAAsB,CAAC;IAC/B,UAAU,EAAE,OAAO,CAAC;IACpB;;;;OAIG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,eAAO,MAAM,uBAAuB,8DACsB,CAAC;AAG3D,wBAAgB,0BAA0B,IAAI,4BAA4B,CASzE"}
@@ -1 +1 @@
1
- {"version":3,"file":"SegmentedControlItem.d.ts","sourceRoot":"","sources":["../../src/SegmentedControl/SegmentedControlItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAiB5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAM5C,MAAM,WAAW,yBAA0B,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC7E,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAgHD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,GAAG,EACH,KAAK,EACL,KAAK,EACL,aAAqB,EACrB,IAAI,EACJ,UAAkB,EAClB,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,kBAAkB,EAAE,mBAAmB,EACvC,GAAG,IAAI,EACR,EAAE,yBAAyB,qBAwF3B;yBAnGe,oBAAoB"}
1
+ {"version":3,"file":"SegmentedControlItem.d.ts","sourceRoot":"","sources":["../../src/SegmentedControl/SegmentedControlItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAiB5C,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAM5C,MAAM,WAAW,yBAA0B,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC7E,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB;;OAEG;IACH,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAgHD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,EACnC,GAAG,EACH,KAAK,EACL,KAAK,EACL,aAAqB,EACrB,IAAI,EACJ,UAAkB,EAClB,OAAO,EAAE,WAAW,EACpB,MAAM,EACN,kBAAkB,EAAE,mBAAmB,EACvC,GAAG,IAAI,EACR,EAAE,yBAAyB,qBA2E3B;yBAtFe,oBAAoB"}
@@ -151,14 +151,6 @@ export function SegmentedControlItem({
151
151
  const ctx = useSegmentedControlContext();
152
152
  const isSelected = ctx.value === value;
153
153
  const isItemDisabled = isDisabled || ctx.isDisabled;
154
- // When the whole group is disabled with a disabledMessage, keep the selected
155
- // segment focusable so the group's reason tooltip is keyboard-discoverable.
156
- // Per-item disabling (`isDisabled` on the item) always drops out of the tab
157
- // order. Activation stays blocked by the isItemDisabled guard in handleClick.
158
- // Disabled with a reason, the selected segment keeps the Tab stop even when
159
- // it is itself disabled (FR4); with no selected segment, the group places
160
- // the stop (SegmentedControl FR2).
161
- const keepsSelectedFocusable = isSelected && (ctx.hasDisabledMessage ?? false);
162
154
  const size = ctx.size;
163
155
  const isFill = ctx.layout === 'fill';
164
156
 
@@ -193,12 +185,10 @@ export function SegmentedControlItem({
193
185
  ,
194
186
  ...segmentDisabledProps(isDisabled),
195
187
  ...(!isSelected && !isItemDisabled ? pressable : undefined),
196
- // Disabled items (including when the whole group is disabled) are not tab
197
- // stops — otherwise the selected segment stays keyboard-focusable but is
198
- // silently dead (arrows and activation are no-ops) (navigation-13). The
199
- // exception is a whole-group disabledMessage, where the selected segment
200
- // stays focusable so the reason tooltip is keyboard-discoverable.
201
- tabIndex: isSelected && !isItemDisabled || keepsSelectedFocusable ? 0 : -1,
188
+ // The selected segment holds the Tab stop, disabled or not (spec:AST-085
189
+ // FR1); activation stays blocked by the isItemDisabled guard. With no
190
+ // selected segment, the group places the stop (SegmentedControl FR2).
191
+ tabIndex: isSelected ? 0 : -1,
202
192
  onClick: handleClick,
203
193
  ...mergeProps(themeProps('segmented-control-item', {
204
194
  size,
@@ -1 +1 @@
1
- {"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../src/SideNav/SideNav.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,EACrC,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AA+P/D,MAAM,WAAW,YAAa,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC1D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE7B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAEvD;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IAEtC;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,wBAAwB,CAAC;CAClD;AAMD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,EACtB,MAAM,EACN,UAAU,EACV,QAAQ,EACR,MAAM,EACN,WAAW,EACX,WAAmB,EACnB,SAAiB,EACjB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,SAAS,EACT,GAAG,KAAK,EACT,EAAE,YAAY,+BA2Vd;yBA1We,OAAO"}
1
+ {"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../src/SideNav/SideNav.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAQL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AACf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAGnD,OAAO,EAGL,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,EACrC,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAC,eAAe,EAAC,MAAM,2BAA2B,CAAC;AA4Q/D,MAAM,WAAW,YAAa,SAAQ,SAAS,CAAC,WAAW,CAAC;IAC1D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;IAE7B;;;;;;;OAOG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,+BAA+B,CAAC,CAAC;IAEvD;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;OAEG;IACH,QAAQ,EAAE,SAAS,CAAC;IACpB;;OAEG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB;;OAEG;IACH,WAAW,CAAC,EAAE,SAAS,CAAC;IACxB;;;;;;;;;OASG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;IACtB;;;OAGG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IAEvB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,SAAS,CAAC,EAAE,OAAO,GAAG,eAAe,CAAC;IAEtC;;;;;;;;;;;;;OAaG;IACH,WAAW,CAAC,EAAE,OAAO,GAAG,wBAAwB,CAAC;CAClD;AAmBD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,OAAO,CAAC,EACtB,MAAM,EACN,UAAU,EACV,QAAQ,EACR,MAAM,EACN,WAAW,EACX,WAAmB,EACnB,SAAiB,EACjB,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,GAAG,EACH,SAAS,EACT,GAAG,KAAK,EACT,EAAE,YAAY,+BAmdd;yBAlee,OAAO"}
@@ -38,6 +38,12 @@ import { useDevWarning } from "../hooks/useDevWarning.js";
38
38
  import { useTranslator } from "../i18n/index.js";
39
39
  import { useMergedRefs } from "../hooks/useMergedRefs.js";
40
40
  import { LayoutChangeSnapshot } from "../motion/LayoutChangeSnapshot.js";
41
+ import { getFocusableElements } from "../hooks/useFocusTrap.js";
42
+ import { useFocusLeavingChange } from "../utils/useFocusLeavingChange.js";
43
+ import { readAccessibleName } from "../utils/accessibleName.js";
44
+ import { moveFocusLeftBehind, noteFocusWithin } from "../utils/focusReturn.js";
45
+ import { useInteractionModalityTracking } from "../utils/interactionModality.js";
46
+ import { SideNavFocusTargetsContext } from "./SideNavFocusTargetsContext.js";
41
47
  import { createRailLayout, playRail, snapshotRail, SideNavShellContext } from "./railMotion.js";
42
48
  // =============================================================================
43
49
  // Constants
@@ -136,6 +142,8 @@ const FOOTER_ICON_SIZE = 'sm';
136
142
  // Component
137
143
  // =============================================================================
138
144
 
145
+ /** Where focus was before a collapse, as the move after it needs it. */
146
+
139
147
  /**
140
148
  * Sidebar navigation container for application pages.
141
149
  *
@@ -189,7 +197,12 @@ export function SideNav({
189
197
  // nav needs an id; a consumer's own id wins.
190
198
  const generatedNavId = useId();
191
199
  const navId = props.id ?? generatedNavId;
192
- const mergedNavRef = useMergedRefs(ref, navRef);
200
+ // The nav's own document's last input decides the moved focus's ring
201
+ // (AR3), so a SideNav in a second document tracks input there.
202
+ const {
203
+ ref: modalityRef
204
+ } = useInteractionModalityTracking();
205
+ const mergedNavRef = useMergedRefs(ref, navRef, modalityRef);
193
206
  const collapseStateRef = useRef({
194
207
  isCollapsed: false,
195
208
  toggle: () => {},
@@ -257,6 +270,92 @@ export function SideNav({
257
270
  motionRef.current?.rail.end();
258
271
  motionRef.current?.endContent();
259
272
  }, []);
273
+
274
+ // Focus on something the collapsed rail does not render would fall to the
275
+ // page when the rail collapses (`component:SideNav` AR3). On a row the rail
276
+ // keeps (its link replaced, its expand toggle or row actions gone), focus
277
+ // stays on that row's control; from a row the rail drops (no icon, or
278
+ // nested), it moves to the rail's collapse toggle, or, with none, to the
279
+ // nearest row the rail keeps. Rows and the toggle register through their
280
+ // callback refs. Rows are matched across the commit by their place among
281
+ // the rows the rail keeps, not by element: a resizable SideNav remounts its
282
+ // nav when it collapses. Focus on a header or footer control that a
283
+ // resizable collapse remounts goes back to the control with the same
284
+ // accessible name. From one the collapse removes or renames, or the resize
285
+ // handle, focus goes to the toggle, or, with none, to the first kept row.
286
+ // Focus moves only if the collapse lost it.
287
+ const rowsRef = useRef(new Map());
288
+ const togglesRef = useRef(new Set());
289
+ const focusTargets = useMemo(() => ({
290
+ registerRow: (element, isKeptInRail) => {
291
+ rowsRef.current.set(element, isKeptInRail);
292
+ return () => {
293
+ rowsRef.current.delete(element);
294
+ };
295
+ },
296
+ registerToggle: element => {
297
+ togglesRef.current.add(element);
298
+ return () => {
299
+ togglesRef.current.delete(element);
300
+ };
301
+ }
302
+ }), []);
303
+ const resizeWrapperRef = useRef(null);
304
+ const noteRailFocus = useFocusLeavingChange(collapsed, wasCollapsed => {
305
+ const nav = navRef.current;
306
+ // The resize handle sits beside the nav, in the resize wrapper, and goes
307
+ // with a collapse its Enter starts.
308
+ const focus = wasCollapsed ? null : noteFocusWithin(nav) ?? noteFocusWithin(resizeWrapperRef.current);
309
+ if (focus == null || nav == null) {
310
+ return null;
311
+ }
312
+ const rows = railRows(nav, rowsRef.current);
313
+ // The innermost row holding focus, the last in document order: a nested
314
+ // row's parent holds it too.
315
+ let index = -1;
316
+ rows.forEach((row, at) => {
317
+ if (row.contains(focus.element)) {
318
+ index = at;
319
+ }
320
+ });
321
+ let outside = null;
322
+ if (index < 0) {
323
+ const controls = controlsOutsideRows(nav, rows);
324
+ const at = controls.findIndex(control => control.contains(focus.element));
325
+ outside = at < 0 ? null : {
326
+ name: controlName(controls[at])
327
+ };
328
+ }
329
+ return {
330
+ focus,
331
+ outside,
332
+ wasOnToggle: [...togglesRef.current].some(toggle => toggle.contains(focus.element)),
333
+ isRowKept: index >= 0 && rowsRef.current.get(rows[index]) === true,
334
+ keptBefore: rows.slice(0, Math.max(index, 0)).filter(row => rowsRef.current.get(row) === true).length
335
+ };
336
+ }, (pending, isCollapsed) => {
337
+ const nav = navRef.current;
338
+ if (!isCollapsed || nav == null) {
339
+ return;
340
+ }
341
+ // Collapsed, every row the nav renders is one the rail keeps, in order.
342
+ const kept = railRows(nav, rowsRef.current);
343
+ const controlOf = row => row == null ? undefined : getFocusableElements(row)[0];
344
+ const toggle = [...togglesRef.current].find(element => nav.contains(element));
345
+ let sameOutside;
346
+ if (pending.wasOnToggle) {
347
+ sameOutside = toggle;
348
+ } else if (pending.outside != null) {
349
+ const controls = controlsOutsideRows(nav, kept);
350
+ sameOutside = controls.find(control => controlName(control) === pending.outside?.name);
351
+ }
352
+ const target = pending.isRowKept ? controlOf(kept[pending.keptBefore]) : sameOutside ?? toggle ?? controlOf(kept[pending.keptBefore - 1]) ?? controlOf(kept[pending.keptBefore]);
353
+ moveFocusLeftBehind(pending.focus, target);
354
+ });
355
+ const beforeRailChange = useCallback(wasCollapsed => {
356
+ noteRailFocus(wasCollapsed);
357
+ measureRail(wasCollapsed);
358
+ }, [noteRailFocus, measureRail]);
260
359
  const toggle = useCallback(() => {
261
360
  const next = !collapsed;
262
361
 
@@ -459,6 +558,7 @@ export function SideNav({
459
558
  // Uses ResizeHandle in overlay mode so the handle sits inside
460
559
  // the panel's overflow: clip bounds.
461
560
  const rail = showResizeHandle ? /*#__PURE__*/_jsxs("div", {
561
+ ref: resizeWrapperRef,
462
562
  ...{
463
563
  className: "x1n2onr6 x78zum5 x2lah0s x5yr21d x7giv3"
464
564
  },
@@ -479,15 +579,36 @@ export function SideNav({
479
579
  const content = /*#__PURE__*/_jsxs(_Fragment, {
480
580
  children: [/*#__PURE__*/_jsx(LayoutChangeSnapshot, {
481
581
  value: collapsed,
482
- onBeforeChange: measureRail
582
+ onBeforeChange: beforeRailChange
483
583
  }), rail]
484
584
  });
485
585
  if (isCollapsible) {
486
- return /*#__PURE__*/_jsx(SideNavCollapseContext, {
487
- value: collapseContext,
488
- children: content
586
+ return /*#__PURE__*/_jsx(SideNavFocusTargetsContext, {
587
+ value: focusTargets,
588
+ children: /*#__PURE__*/_jsx(SideNavCollapseContext, {
589
+ value: collapseContext,
590
+ children: content
591
+ })
489
592
  });
490
593
  }
491
594
  return content;
492
595
  }
596
+
597
+ /** The focusable controls in `nav` outside every row: header and footer. */
598
+ function controlsOutsideRows(nav, rows) {
599
+ return getFocusableElements(nav).filter(control => !rows.some(row => row.contains(control)));
600
+ }
601
+
602
+ /** A control's accessible name, so a re-rendered control is found again. */
603
+ function controlName(control) {
604
+ return readAccessibleName(control) ?? '';
605
+ }
606
+
607
+ /**
608
+ * The registered rows inside `nav`, in document order, leaving out rows in a
609
+ * collapsed item's flyout, which is a layer of its own.
610
+ */
611
+ function railRows(nav, rows) {
612
+ return [...rows.keys()].filter(row => nav.contains(row) && row.closest('[popover]') == null).sort((a, b) => a.compareDocumentPosition(b) & Node.DOCUMENT_POSITION_FOLLOWING ? -1 : 1);
613
+ }
493
614
  SideNav.displayName = 'SideNav';
@@ -1 +1 @@
1
- {"version":3,"file":"SideNavCollapseButton.d.ts","sourceRoot":"","sources":["../../src/SideNav/SideNavCollapseButton.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAAc,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAKzD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,EAGL,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACrC,MAAM,0BAA0B,CAAC;AAGlC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAC;AAkC5D,MAAM,WAAW,0BAA2B,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC9E,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;;;OAIG;IACH,WAAW,CAAC,EAAE,4BAA4B,CAAC;IAE3C;;;;OAIG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,+BAA+B,GAAG,IAAI,CAAC,CAAC;IAEpE;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,GAAG,EACH,WAAW,EACX,SAAS,EACT,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,GAAG,KAAK,EACT,EAAE,0BAA0B,4BAiD5B;yBA1De,qBAAqB"}
1
+ {"version":3,"file":"SideNavCollapseButton.d.ts","sourceRoot":"","sources":["../../src/SideNav/SideNavCollapseButton.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,EAAmB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAK9D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,EAGL,KAAK,4BAA4B,EACjC,KAAK,+BAA+B,EACrC,MAAM,0BAA0B,CAAC;AAKlC,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAC;AAkC5D,MAAM,WAAW,0BAA2B,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC9E,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;;;OAIG;IACH,WAAW,CAAC,EAAE,4BAA4B,CAAC;IAE3C;;;;OAIG;IACH,SAAS,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,+BAA+B,GAAG,IAAI,CAAC,CAAC;IAEpE;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IAEf;;;;OAIG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAMD;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,GAAG,EACH,WAAW,EACX,SAAS,EACT,KAAK,EACL,IAAI,EACJ,QAAQ,EACR,OAAO,EAAE,WAAW,EACpB,GAAG,KAAK,EACT,EAAE,0BAA0B,4BA+D5B;yBAxEe,qBAAqB"}