@astryxdesign/core 0.6.1 → 0.6.2-canary.023c3e4

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 (305) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/BottomSheet/BottomSheet.d.ts +1 -1
  3. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  4. package/dist/BottomSheet/BottomSheet.js +3 -1
  5. package/dist/BottomSheet/BottomSheetPanel.d.ts +7 -5
  6. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  7. package/dist/BottomSheet/BottomSheetPanel.js +56 -19
  8. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  9. package/dist/Chat/ChatComposerInput.js +2 -2
  10. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  11. package/dist/CheckboxInput/CheckboxInput.js +12 -2
  12. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  13. package/dist/Collapsible/Collapsible.js +6 -1
  14. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  15. package/dist/CommandPalette/CommandPaletteInput.js +1 -1
  16. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  17. package/dist/ComplexSelector/ComplexSelector.js +1 -1
  18. package/dist/DateInput/DateInput.d.ts.map +1 -1
  19. package/dist/DateInput/DateInput.js +4 -4
  20. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  21. package/dist/DateInput/NativeDateField.js +16 -16
  22. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  23. package/dist/DateInput/TouchDateField.js +2 -2
  24. package/dist/DateRangeInput/DateRangeInput.d.ts +3 -0
  25. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  26. package/dist/DateRangeInput/DateRangeInput.js +20 -13
  27. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  28. package/dist/DateTimeInput/DateTimeInput.js +8 -8
  29. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  30. package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
  31. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
  32. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
  33. package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
  34. package/dist/Dialog/DialogHeader.d.ts +1 -1
  35. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  36. package/dist/Dialog/DialogHeader.js +10 -7
  37. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  38. package/dist/Field/PanelSearchInput.js +1 -1
  39. package/dist/FileInput/FileInput.d.ts.map +1 -1
  40. package/dist/FileInput/FileInput.js +16 -10
  41. package/dist/Kbd/Kbd.d.ts +5 -3
  42. package/dist/Kbd/Kbd.d.ts.map +1 -1
  43. package/dist/Kbd/Kbd.js +36 -42
  44. package/dist/Link/Link.d.ts.map +1 -1
  45. package/dist/Link/Link.js +6 -2
  46. package/dist/Markdown/Markdown.d.ts +18 -4
  47. package/dist/Markdown/Markdown.d.ts.map +1 -1
  48. package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
  49. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
  50. package/dist/Markdown/Markdown.fr23.bench.js +150 -0
  51. package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
  52. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
  53. package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
  54. package/dist/Markdown/Markdown.js +311 -114
  55. package/dist/Markdown/ast.d.ts +162 -0
  56. package/dist/Markdown/ast.d.ts.map +1 -0
  57. package/dist/Markdown/ast.js +74 -0
  58. package/dist/Markdown/index.d.ts +5 -3
  59. package/dist/Markdown/index.d.ts.map +1 -1
  60. package/dist/Markdown/index.js +3 -2
  61. package/dist/Markdown/parser/index.d.ts +10 -0
  62. package/dist/Markdown/parser/index.d.ts.map +1 -0
  63. package/dist/Markdown/parser/index.js +10 -0
  64. package/dist/Markdown/parser.d.ts +220 -38
  65. package/dist/Markdown/parser.d.ts.map +1 -1
  66. package/dist/Markdown/parser.js +1072 -188
  67. package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
  68. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
  69. package/dist/Markdown/plugins/frontmatter.js +132 -0
  70. package/dist/Markdown/plugins/index.d.ts +16 -0
  71. package/dist/Markdown/plugins/index.d.ts.map +1 -0
  72. package/dist/Markdown/plugins/index.js +13 -0
  73. package/dist/Markdown/plugins/protocol.d.ts +191 -0
  74. package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
  75. package/dist/Markdown/plugins/protocol.js +957 -0
  76. package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
  77. package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
  78. package/dist/Markdown/plugins/semanticFence.js +213 -0
  79. package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
  80. package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
  81. package/dist/Markdown/plugins/sourceDecoration.js +393 -0
  82. package/dist/Markdown/plugins/textTransform.d.ts +30 -0
  83. package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
  84. package/dist/Markdown/plugins/textTransform.js +374 -0
  85. package/dist/Markdown/remark.d.ts +196 -0
  86. package/dist/Markdown/remark.d.ts.map +1 -0
  87. package/dist/Markdown/remark.js +1062 -0
  88. package/dist/Markdown/url.d.ts +4 -0
  89. package/dist/Markdown/url.d.ts.map +1 -0
  90. package/dist/Markdown/url.js +25 -0
  91. package/dist/Markdown/utils.d.ts +4 -2
  92. package/dist/Markdown/utils.d.ts.map +1 -1
  93. package/dist/Markdown/utils.js +2 -1
  94. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  95. package/dist/NumberInput/NumberInput.js +4 -4
  96. package/dist/Outline/index.d.ts +1 -0
  97. package/dist/Outline/index.d.ts.map +1 -1
  98. package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
  99. package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
  100. package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
  101. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
  102. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  103. package/dist/Outline/useOutlineFromMarkdown.js +8 -3
  104. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  105. package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
  106. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  107. package/dist/ProgressBar/ProgressBar.js +36 -31
  108. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  109. package/dist/RadioList/RadioListItem.js +13 -1
  110. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  111. package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
  112. package/dist/Selector/Selector.d.ts.map +1 -1
  113. package/dist/Selector/Selector.js +1 -1
  114. package/dist/SideNav/SideNav.d.ts +2 -1
  115. package/dist/SideNav/SideNav.d.ts.map +1 -1
  116. package/dist/SideNav/SideNav.js +9 -3
  117. package/dist/Slider/Slider.d.ts.map +1 -1
  118. package/dist/Slider/Slider.js +19 -10
  119. package/dist/Spinner/Spinner.d.ts +1 -1
  120. package/dist/Spinner/Spinner.d.ts.map +1 -1
  121. package/dist/Spinner/Spinner.js +45 -21
  122. package/dist/Switch/Switch.d.ts.map +1 -1
  123. package/dist/Switch/Switch.js +11 -0
  124. package/dist/TabList/Tab.d.ts +1 -1
  125. package/dist/TabList/Tab.d.ts.map +1 -1
  126. package/dist/TabList/Tab.js +20 -7
  127. package/dist/TextArea/TextArea.d.ts.map +1 -1
  128. package/dist/TextArea/TextArea.js +1 -1
  129. package/dist/TextInput/TextInput.d.ts.map +1 -1
  130. package/dist/TextInput/TextInput.js +2 -2
  131. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  132. package/dist/TimeInput/TimeInput.js +4 -4
  133. package/dist/ToggleButton/ToggleButton.d.ts +2 -1
  134. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  135. package/dist/ToggleButton/ToggleButton.js +7 -1
  136. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  137. package/dist/Typeahead/BaseTypeahead.js +16 -7
  138. package/dist/astryx.css +19 -8
  139. package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
  140. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
  141. package/dist/hooks/scrollKeyboardDelegation.js +146 -0
  142. package/dist/hooks/useScrollableArea.d.ts +6 -2
  143. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  144. package/dist/hooks/useScrollableArea.js +17 -5
  145. package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
  146. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  147. package/dist/utils/interactionOverlay.stylex.js +9 -0
  148. package/locales/en.json +16 -0
  149. package/locales/pseudo.json +12 -0
  150. package/package.json +22 -5
  151. package/scripts/agent-doc-state.mjs +1 -1
  152. package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
  153. package/src/BottomSheet/BottomSheet.spec.md +46 -20
  154. package/src/BottomSheet/BottomSheet.test.tsx +6 -3
  155. package/src/BottomSheet/BottomSheet.tsx +3 -1
  156. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
  157. package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
  158. package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
  159. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
  160. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
  161. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
  162. package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
  163. package/src/Button/__tests__/Button.a11y.states.ts +9 -0
  164. package/src/Chat/ChatComposerInput.doc.mjs +3 -3
  165. package/src/Chat/ChatComposerInput.tsx +10 -2
  166. package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
  167. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  168. package/src/CheckboxInput/CheckboxInput.tsx +21 -1
  169. package/src/ClickableCard/ClickableCard.test.tsx +102 -5
  170. package/src/Collapsible/Collapsible.doc.mjs +11 -0
  171. package/src/Collapsible/Collapsible.test.tsx +21 -0
  172. package/src/Collapsible/Collapsible.tsx +5 -0
  173. package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
  174. package/src/ComplexSelector/ComplexSelector.tsx +6 -1
  175. package/src/DateInput/DateInput.tsx +6 -1
  176. package/src/DateInput/NativeDateField.tsx +24 -8
  177. package/src/DateInput/TouchDateField.tsx +6 -2
  178. package/src/DateRangeInput/DateRangeInput.doc.mjs +35 -7
  179. package/src/DateRangeInput/DateRangeInput.spec.md +203 -0
  180. package/src/DateRangeInput/DateRangeInput.test.tsx +100 -4
  181. package/src/DateRangeInput/DateRangeInput.tsx +35 -21
  182. package/src/DateTimeInput/DateTimeInput.tsx +6 -1
  183. package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
  184. package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
  185. package/src/Dialog/Dialog.doc.mjs +3 -0
  186. package/src/Dialog/Dialog.spec.md +1 -1
  187. package/src/Dialog/DialogHeader.doc.mjs +38 -0
  188. package/src/Dialog/DialogHeader.test.tsx +49 -0
  189. package/src/Dialog/DialogHeader.tsx +23 -4
  190. package/src/Dialog/modules/DialogHeader.spec.md +152 -0
  191. package/src/Field/PanelSearchInput.tsx +5 -2
  192. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
  193. package/src/FileInput/FileInput.doc.mjs +2 -0
  194. package/src/FileInput/FileInput.spec.md +199 -0
  195. package/src/FileInput/FileInput.test.tsx +14 -0
  196. package/src/FileInput/FileInput.tsx +24 -5
  197. package/src/Kbd/Kbd.doc.mjs +3 -3
  198. package/src/Kbd/Kbd.test.tsx +57 -1
  199. package/src/Kbd/Kbd.tsx +57 -37
  200. package/src/Layout/LayoutFooter.doc.mjs +17 -0
  201. package/src/Link/Link.doc.mjs +11 -0
  202. package/src/Link/Link.test.tsx +24 -0
  203. package/src/Link/Link.tsx +5 -0
  204. package/src/Markdown/Markdown.doc.mjs +439 -42
  205. package/src/Markdown/Markdown.fr23.bench.ts +174 -0
  206. package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
  207. package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
  208. package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
  209. package/src/Markdown/Markdown.public.test.ts +280 -0
  210. package/src/Markdown/Markdown.spec.md +304 -72
  211. package/src/Markdown/Markdown.test.tsx +118 -3
  212. package/src/Markdown/Markdown.tsx +489 -129
  213. package/src/Markdown/ast.test.ts +307 -0
  214. package/src/Markdown/ast.ts +337 -0
  215. package/src/Markdown/incremental.test.ts +187 -7
  216. package/src/Markdown/index.ts +43 -1
  217. package/src/Markdown/modules/remark.spec.md +269 -0
  218. package/src/Markdown/parser/index.ts +64 -0
  219. package/src/Markdown/parser.perf.test.ts +3 -1
  220. package/src/Markdown/parser.public.test.ts +103 -0
  221. package/src/Markdown/parser.test.ts +122 -0
  222. package/src/Markdown/parser.ts +1721 -248
  223. package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
  224. package/src/Markdown/plugins/frontmatter.ts +198 -0
  225. package/src/Markdown/plugins/index.ts +53 -0
  226. package/src/Markdown/plugins/protocol.test.tsx +1022 -0
  227. package/src/Markdown/plugins/protocol.ts +1618 -0
  228. package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
  229. package/src/Markdown/plugins/semanticFence.ts +424 -0
  230. package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
  231. package/src/Markdown/plugins/sourceDecoration.ts +539 -0
  232. package/src/Markdown/plugins/textTransform.test.ts +467 -0
  233. package/src/Markdown/plugins/textTransform.ts +554 -0
  234. package/src/Markdown/remark.test.tsx +1877 -0
  235. package/src/Markdown/remark.ts +1574 -0
  236. package/src/Markdown/url.ts +30 -0
  237. package/src/Markdown/utils.ts +19 -1
  238. package/src/MultiSelector/MultiSelector.test.tsx +1 -35
  239. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
  240. package/src/NumberInput/NumberInput.tsx +6 -1
  241. package/src/Outline/Outline.doc.mjs +7 -5
  242. package/src/Outline/Outline.spec.md +1 -1
  243. package/src/Outline/index.ts +1 -0
  244. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
  245. package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
  246. package/src/Outline/useOutlineFromMarkdown.ts +15 -3
  247. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  248. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
  249. package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
  250. package/src/ProgressBar/ProgressBar.test.tsx +29 -11
  251. package/src/ProgressBar/ProgressBar.tsx +59 -72
  252. package/src/RadioList/RadioList.doc.mjs +11 -0
  253. package/src/RadioList/RadioList.test.tsx +32 -0
  254. package/src/RadioList/RadioListItem.tsx +25 -1
  255. package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
  256. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  257. package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
  258. package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
  259. package/src/Selector/Selector.spec.md +12 -9
  260. package/src/Selector/Selector.tsx +6 -1
  261. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
  262. package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
  263. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
  264. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
  265. package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
  266. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
  267. package/src/SideNav/SideNav.doc.mjs +1 -1
  268. package/src/SideNav/SideNav.test.tsx +10 -0
  269. package/src/SideNav/SideNav.tsx +14 -2
  270. package/src/Slider/Slider.doc.mjs +27 -0
  271. package/src/Slider/Slider.spec.md +61 -47
  272. package/src/Slider/Slider.test.tsx +146 -0
  273. package/src/Slider/Slider.tsx +37 -13
  274. package/src/Spinner/Spinner.doc.mjs +6 -3
  275. package/src/Spinner/Spinner.test.tsx +41 -0
  276. package/src/Spinner/Spinner.tsx +62 -32
  277. package/src/Switch/Switch.doc.mjs +11 -0
  278. package/src/Switch/Switch.test.tsx +16 -0
  279. package/src/Switch/Switch.tsx +28 -0
  280. package/src/TabList/Tab.tsx +35 -7
  281. package/src/TabList/TabList.doc.mjs +11 -0
  282. package/src/TabList/TabList.test.tsx +66 -0
  283. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
  284. package/src/TextArea/TextArea.tsx +6 -1
  285. package/src/TextInput/TextInput.test.tsx +20 -1
  286. package/src/TextInput/TextInput.tsx +6 -1
  287. package/src/TimeInput/TimeInput.tsx +6 -1
  288. package/src/ToggleButton/ToggleButton.test.tsx +133 -0
  289. package/src/ToggleButton/ToggleButton.tsx +9 -2
  290. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
  291. package/src/Tokenizer/Tokenizer.spec.md +142 -75
  292. package/src/TreeList/TreeList.spec.md +123 -75
  293. package/src/Typeahead/BaseTypeahead.spec.md +4 -3
  294. package/src/Typeahead/BaseTypeahead.tsx +21 -7
  295. package/src/Typeahead/Typeahead.test.tsx +53 -0
  296. package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
  297. package/src/__tests__/pressState.ts +93 -0
  298. package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
  299. package/src/hooks/scrollKeyboardDelegation.ts +233 -0
  300. package/src/hooks/useScrollableArea.doc.mjs +15 -3
  301. package/src/hooks/useScrollableArea.test.tsx +59 -1
  302. package/src/hooks/useScrollableArea.ts +34 -10
  303. package/src/inputFontFloor.test.ts +106 -0
  304. package/src/theme/derivedVarRegistry.test.ts +6 -4
  305. package/src/utils/interactionOverlay.stylex.ts +20 -0
package/dist/astryx.css CHANGED
@@ -65,7 +65,7 @@
65
65
  @keyframes xv1hr86-B{from{opacity:0;transform:translateY(calc(-1 * var(--spacing-2))) scale(.95);}to{opacity:1;transform:translateY(0) scale(1);}}
66
66
  @keyframes x1b6yrix-B{from{opacity:0;transform:translateY(var(--spacing-2));}to{opacity:1;transform:translateY(0);}}
67
67
  @keyframes xiylxmw-B{from{opacity:0;transform:translateY(calc(-1 * var(--spacing-2)));}to{opacity:1;transform:translateY(0);}}
68
- @keyframes xqng64z-B{0%{transform:rotate(0deg);}100%{transform:rotate(360deg);}}
68
+ @keyframes x1wbvqyn-B{0%{stroke-dashoffset:0;}100%{stroke-dashoffset:calc(var(--_spinner-ring-diameter) * -3.141592653589793);}}
69
69
  @keyframes x1c2q33o-B{0%{transform:translateX(100%);}100%{transform:translateX(-250%);}}
70
70
  @keyframes xr3m334-B{0%{transform:translateX(-100%);}100%{transform:translateX(250%);}}
71
71
  @keyframes x1xhkexc-B{from{width:0;margin-inline-end:0;opacity:0;}to{width:14px;margin-inline-end:var(--spacing-1);opacity:1;}}
@@ -333,6 +333,7 @@
333
333
  .xnpej1e{--radius-element:var(--radius-full)}
334
334
  .x11rj6l1{--selectable-card-ring-color:var(--color-accent)}
335
335
  .xkce8z9{--separator-display:flex}
336
+ .x7o5821{--spinner-arc-fraction:.375}
336
337
  .x1uzk0gl{--spinner-color:currentColor}
337
338
  .xt1b8mc{--spinner-color:var(--color-accent)}
338
339
  .x13u6jys{--spinner-color:var(--color-on-dark)}
@@ -515,7 +516,6 @@
515
516
  .xb3r6kr:not(#\#):not(#\#){overflow:hidden}
516
517
  .x1rea2x4:not(#\#):not(#\#){overflow:visible}
517
518
  .xish69e:not(#\#):not(#\#){overscroll-behavior:contain}
518
- .x8du1vd:not(#\#):not(#\#){overscroll-behavior:none}
519
519
  .xt970qd:not(#\#):not(#\#){padding-block:0}
520
520
  .x1vn5h1t:not(#\#):not(#\#){padding-block:calc((var(--size-element-lg) - var(--spacing-5) - 2 * var(--border-width)) / 2)}
521
521
  .x1ioay2v:not(#\#):not(#\#){padding-block:calc((var(--size-element-md) - var(--spacing-5) - 2 * var(--border-width)) / 2)}
@@ -650,10 +650,10 @@
650
650
  .x3psbcj:not(#\#):not(#\#):not(#\#){animation-name:x1ahk7ht-B}
651
651
  .x1dvww92:not(#\#):not(#\#):not(#\#){animation-name:x1b6yrix-B}
652
652
  .x97zbip:not(#\#):not(#\#):not(#\#){animation-name:x1k48ry3-B}
653
+ .x1nlxm0d:not(#\#):not(#\#):not(#\#){animation-name:x1wbvqyn-B}
653
654
  .x1gbn2au:not(#\#):not(#\#):not(#\#){animation-name:x1xhkexc-B}
654
655
  .xeuoslp:not(#\#):not(#\#):not(#\#){animation-name:xgnty7z-B}
655
656
  .x1srr2gu:not(#\#):not(#\#):not(#\#){animation-name:xiylxmw-B}
656
- .x1ka1v4i:not(#\#):not(#\#):not(#\#){animation-name:xqng64z-B}
657
657
  .xozk8ic:not(#\#):not(#\#):not(#\#){animation-name:xr3m334-B}
658
658
  .x1mta51n:not(#\#):not(#\#):not(#\#){animation-name:xtut5q7-B}
659
659
  .xck01x9:not(#\#):not(#\#):not(#\#){animation-name:xu7jd1z-B}
@@ -866,6 +866,7 @@
866
866
  .x1lliihq:not(#\#):not(#\#):not(#\#){display:block}
867
867
  .xjp7ctv:not(#\#):not(#\#):not(#\#){display:contents}
868
868
  .x78zum5:not(#\#):not(#\#):not(#\#){display:flex}
869
+ .xufnvkl:not(#\#):not(#\#):not(#\#){display:flow-root}
869
870
  .xrvj5dj:not(#\#):not(#\#):not(#\#){display:grid}
870
871
  .x1rg5ohu:not(#\#):not(#\#):not(#\#){display:inline-block}
871
872
  .x3nfvp2:not(#\#):not(#\#):not(#\#){display:inline-flex}
@@ -1173,7 +1174,7 @@
1173
1174
  .x24f09q:not(#\#):not(#\#):not(#\#){scrollbar-gutter:auto}
1174
1175
  .xosa0jh:not(#\#):not(#\#):not(#\#){scrollbar-width:auto}
1175
1176
  .x1rohswg:not(#\#):not(#\#):not(#\#){scrollbar-width:none}
1176
- .x1vy8frr:not(#\#):not(#\#):not(#\#){stroke-dasharray:calc(var(--_spinner-ring-diameter) * 1.1780972450961724) calc(var(--_spinner-ring-diameter) * 1.9634954084936207)}
1177
+ .xdv9ggb:not(#\#):not(#\#):not(#\#){stroke-dasharray:calc(var(--_spinner-ring-diameter) * 3.141592653589793 * var(--spinner-arc-fraction)) calc(var(--_spinner-ring-diameter) * 3.141592653589793 * (1 - var(--spinner-arc-fraction)))}
1177
1178
  .x1owpc8m:not(#\#):not(#\#):not(#\#){stroke-linecap:round}
1178
1179
  .x7bo2k:not(#\#):not(#\#):not(#\#){stroke-opacity:.3}
1179
1180
  .x1smxkh6:not(#\#):not(#\#):not(#\#){stroke-opacity:.302}
@@ -1312,7 +1313,6 @@
1312
1313
  .x126k92a:not(#\#):not(#\#):not(#\#){white-space:pre-wrap}
1313
1314
  .x1sdyfia:not(#\#):not(#\#):not(#\#){white-space:pre}
1314
1315
  .x1q1rmc8:not(#\#):not(#\#):not(#\#){will-change:transform,opacity}
1315
- .x1so62im:not(#\#):not(#\#):not(#\#){will-change:transform}
1316
1316
  .x1yn0g08:not(#\#):not(#\#):not(#\#){word-break:break-all}
1317
1317
  .x13faqbe:not(#\#):not(#\#):not(#\#){word-break:break-word}
1318
1318
  .x1lldw8n:not(#\#):not(#\#):not(#\#){word-break:normal}
@@ -1330,6 +1330,7 @@
1330
1330
  .x7v6acp.x7v6acp:where(.x84s7jz:focus-within *):not(#\#):not(#\#):not(#\#){visibility:visible}
1331
1331
  .x5um2zc.x5um2zc:where(.x1twag4g:first-child *):not(#\#):not(#\#):not(#\#){visibility:hidden}
1332
1332
  .x1se5z8o.x1se5z8o:where(.x1twag4g:last-child *):not(#\#):not(#\#):not(#\#){visibility:hidden}
1333
+ .x6ipy2d.x6ipy2d:where(.x1u3b27q:active *):not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-pressed)}
1333
1334
  @supports (animation-timeline: view()){.x1iu2jvn.x1iu2jvn:not(#\#):not(#\#):not(#\#){animation-name:x1tut0r7-B}}
1334
1335
  @supports (container-type: scroll-state){.xafyuhj.xafyuhj:not(#\#):not(#\#):not(#\#){container-type:scroll-state}}
1335
1336
  .xfd3fxj:is([dir="rtl"] *):not(#\#):not(#\#):not(#\#){animation-name:x1c2q33o-B}
@@ -1362,6 +1363,8 @@
1362
1363
  .x1e0x2sz:focus-visible:not(#\#):not(#\#):not(#\#){outline-color:var(--color-error)}
1363
1364
  .xx47ajj:focus-visible:not(#\#):not(#\#):not(#\#){outline-color:var(--focus-outline-color)}
1364
1365
  .x7s97pk:focus-visible:not(#\#):not(#\#):not(#\#){outline-offset:2px}
1366
+ .x1nw7mhf:focus-visible:not(#\#):not(#\#):not(#\#){outline-offset:calc(-1 * var(--focus-outline-width))}
1367
+ .x1l5jwag:focus-visible:not(#\#):not(#\#):not(#\#){outline-offset:calc(0px - var(--focus-outline-width))}
1365
1368
  .x13aywxo:focus-visible:not(#\#):not(#\#):not(#\#){outline-offset:var(--button-focus-offset)}
1366
1369
  .x1vwwbsn:focus-visible:not(#\#):not(#\#):not(#\#){outline-offset:var(--focus-outline-offset)}
1367
1370
  .xwz5zln.xwz5zln:where(.x1iwu4tg:has(:focus-visible) *):not(#\#):not(#\#):not(#\#){outline-offset:var(--focus-outline-offset)}
@@ -1447,8 +1450,6 @@
1447
1450
  @media (max-width: 480px){.xedohl4.xedohl4:not(#\#):not(#\#):not(#\#){display:flex}}
1448
1451
  @media (pointer: coarse){.xhj50sb.xhj50sb:not(#\#):not(#\#):not(#\#){display:none}}
1449
1452
  @media (max-width: 480px){.x1rpgqan.x1rpgqan:not(#\#):not(#\#):not(#\#){flex-direction:column}}
1450
- @media (pointer: coarse){.x6pjikd.x6pjikd:not(#\#):not(#\#):not(#\#){font-size:max(1rem,var(--text-body-size))}}
1451
- @media (pointer: coarse){.xdk3u5w.xdk3u5w:not(#\#):not(#\#):not(#\#){font-size:max(1rem,var(--text-label-size))}}
1452
1453
  @media (pointer: coarse){.x1jymrmb.x1jymrmb:not(#\#):not(#\#):not(#\#){margin-inline-start:auto}}
1453
1454
  @media (forced-colors: active){.x1tbh5bv.x1tbh5bv:not(#\#):not(#\#):not(#\#){opacity:1}}
1454
1455
  @media (pointer: coarse){.xozvky.xozvky:not(#\#):not(#\#):not(#\#){order:1}}
@@ -1477,7 +1478,11 @@
1477
1478
  @media (hover: hover){.x8ydxbz.x8ydxbz.x8ydxbz:where(.x84s7jz:hover *):not(#\#):not(#\#):not(#\#){pointer-events:auto}}
1478
1479
  @media (hover: hover){.x17hxqr7.x17hxqr7.x17hxqr7:where(.x84s7jz:hover *):not(#\#):not(#\#):not(#\#){transform:translateY(0)}}
1479
1480
  @media (hover: hover){.xneequu.xneequu.xneequu:where(.x84s7jz:hover *):not(#\#):not(#\#):not(#\#){visibility:visible}}
1481
+ @media (hover: hover){.x74x3iv.x74x3iv.x74x3iv:where(.x1u3b27q:active *):not(#\#):not(#\#):not(#\#){background-color:var(--color-overlay-pressed)}}
1482
+ @media (forced-colors: none){.x1xm682w.x1xm682w.x1xm682w:where(.x1iwu4tg:active *):not(#\#):not(#\#):not(#\#){background-image:linear-gradient(var(--color-overlay-pressed),var(--color-overlay-pressed))}}
1480
1483
  @supports (animation-timeline: view()){@media (prefers-reduced-motion: reduce){.xk3h8ob.xk3h8ob.xk3h8ob:not(#\#):not(#\#):not(#\#){animation-name:xuvekqa-B}}}
1484
+ @supports (-webkit-touch-callout: none){@media (pointer: coarse){.xf9zqsd.xf9zqsd.xf9zqsd:not(#\#):not(#\#):not(#\#){font-size:max(1rem,var(--text-body-size))}}}
1485
+ @supports (-webkit-touch-callout: none){@media (pointer: coarse){.x1w61h2b.x1w61h2b.x1w61h2b:not(#\#):not(#\#):not(#\#){font-size:max(1rem,var(--text-label-size))}}}
1481
1486
  @media (hover: hover){.xvxo0qp.xvxo0qp.xvxo0qp:hover:where(:not(:disabled,[aria-disabled="true"])):not(#\#):not(#\#):not(#\#){background-color:color-mix(in srgb,var(--color-accent),var(--color-tint-hover) 15%)}}
1482
1487
  @media (hover: hover){.x1pfkqlk.x1pfkqlk.x1pfkqlk:hover:where(:not(:disabled,[aria-disabled="true"])):not(#\#):not(#\#):not(#\#){background-color:transparent}}
1483
1488
  @media (hover: hover){.xcu6dpe.xcu6dpe.xcu6dpe:hover:where(:not(:disabled,[aria-disabled="true"])):not(#\#):not(#\#):not(#\#){background-color:var(--color-neutral)}}
@@ -1558,7 +1563,6 @@
1558
1563
  .xs02d24:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(100% + 1px)}
1559
1564
  .x12qplqi:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(100% + var(--container-padding-block-start,0px) + var(--container-padding-block-end,0px))}
1560
1565
  .xpa73km:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(100dvh - var(--_app-shell-header-height,0px))}
1561
- .x1oglpa6:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(max(1rem,var(--text-body-size)) * var(--text-body-leading));height:1lh}
1562
1566
  .x1tpcejd:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--_sheet-budget) + 48px)}
1563
1567
  .x1uiybsj:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-lg) - 4px)}
1564
1568
  .x102lyln:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-lg) - 8px)}
@@ -1567,6 +1571,7 @@
1567
1571
  .x1u5rhrp:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-md) + var(--spacing-1))}
1568
1572
  .xzj98nu:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-sm) - 4px)}
1569
1573
  .xzydfjl:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--size-element-sm) - 8px)}
1574
+ .x1mutkkf:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--text-body-size) * var(--text-body-leading));height:1lh}
1570
1575
  .x1q370uo:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--text-body-size) * var(--text-body-leading))}
1571
1576
  .x14o5nre:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(var(--text-supporting-size) * var(--text-supporting-leading))}
1572
1577
  .xw1wawg:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(44px - 8px)}
@@ -1675,6 +1680,7 @@
1675
1680
  .xjwf9q1:not(#\#):not(#\#):not(#\#):not(#\#){min-height:24px}
1676
1681
  .xe0p6wg:not(#\#):not(#\#):not(#\#):not(#\#){min-height:28px}
1677
1682
  .x21xpn4:not(#\#):not(#\#):not(#\#):not(#\#){min-height:32px}
1683
+ .x121v3j4:not(#\#):not(#\#):not(#\#):not(#\#){min-height:min-content}
1678
1684
  .x1xf4nls:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--size-element-lg)}
1679
1685
  .x1uogy3y:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--size-element-md)}
1680
1686
  .x1gdqauq:not(#\#):not(#\#):not(#\#):not(#\#){min-height:var(--size-element-sm)}
@@ -1865,6 +1871,7 @@
1865
1871
  @media (pointer: coarse){.xkagaj0.xkagaj0:not(#\#):not(#\#):not(#\#):not(#\#){min-width:24px}}
1866
1872
  @media (pointer: coarse){.x1xrq5m.x1xrq5m:not(#\#):not(#\#):not(#\#):not(#\#){min-width:44px}}
1867
1873
  @media (pointer: coarse){.xngvp7v.xngvp7v:not(#\#):not(#\#):not(#\#):not(#\#){min-width:44px}}
1874
+ @supports (-webkit-touch-callout: none){@media (pointer: coarse){.x9w4715.x9w4715.x9w4715:not(#\#):not(#\#):not(#\#):not(#\#){height:calc(max(1rem,var(--text-body-size)) * var(--text-body-leading));height:1lh}}}
1868
1875
  @starting-style{.x1sopeo2.x1sopeo2:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){grid-template-rows:0fr}}
1869
1876
  .x1xsm0q9:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{inset:-14px}
1870
1877
  .xarstr8:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{inset:0}
@@ -1882,6 +1889,8 @@
1882
1889
  @starting-style{.x14gflnl.x14gflnl:is([dir="rtl"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#){transform:translateX(100%)}}
1883
1890
  .x1k48kgn:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{border-radius:inherit}
1884
1891
  .xxyica1:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{border-radius:inherit}
1892
+ .xq94oqs:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{border-radius:var(--radius-full)}
1893
+ .xtb6wbx:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{border-radius:var(--radius-inner)}
1885
1894
  .x17gn2l9:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{grid-column:1}
1886
1895
  .xd54j2p:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{inset-block:0}
1887
1896
  .xpsyfx0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::-webkit-date-and-time-value{margin-block:0}
@@ -1961,6 +1970,8 @@
1961
1970
  .xa5v58t:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{transition-timing-function:var(--ease-standard)}
1962
1971
  .x1rbqspl:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{user-select:none}
1963
1972
  .xy5mcqj:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{z-index:-1}
1973
+ .xzywxsk.xzywxsk:where(.x1odsvnm:active *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{background-color:var(--color-overlay-pressed)}
1974
+ .x2kv6q6.x2kv6q6:where(.x1odsvnm:active:not(:has(a:active,button:active,[role="button"]:active,[role="link"]:active)) *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{background-color:var(--color-overlay-pressed)}
1964
1975
  .xk7vujl:is([dir="rtl"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{background-image:linear-gradient(to left,var(--color-shadow),transparent)}
1965
1976
  .xlptwl5:is([dir="rtl"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{background-image:linear-gradient(to right,var(--color-shadow),transparent)}
1966
1977
  .xdq8fwl:is([dir="rtl"] *):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{transform-origin:right center}
@@ -0,0 +1,3 @@
1
+ /** Attach only while automatic ownership has an effective scroll axis. */
2
+ export declare function attachScrollKeyboardDelegation(viewport: HTMLElement, content: HTMLElement): () => void;
3
+ //# sourceMappingURL=scrollKeyboardDelegation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrollKeyboardDelegation.d.ts","sourceRoot":"","sources":["../../src/hooks/scrollKeyboardDelegation.ts"],"names":[],"mappings":"AAkIA,0EAA0E;AAC1E,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,WAAW,EACrB,OAAO,EAAE,WAAW,GACnB,MAAM,IAAI,CAkGZ"}
@@ -0,0 +1,146 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file scrollKeyboardDelegation.ts
5
+ * @input A named, overflowing viewport and its real content box
6
+ * @output Focus-time delegation with native forward and reverse Tab traversal
7
+ * @position Private useScrollableArea keyboard behavior; no DOM observers or scrolling
8
+ */
9
+
10
+ import { FOCUSABLE_SELECTOR } from "./focusableSelector.js";
11
+ import { getRegisteredScrollOwnerState } from "./scrollOwnerRegistry.js";
12
+
13
+ // Structural roles may contain ordinary links/buttons. Unknown or interactive
14
+ // roles are deliberately excluded until their navigation contract is proven.
15
+ const PASSIVE_ROLES = new Set(['article', 'banner', 'complementary', 'contentinfo', 'definition', 'directory', 'document', 'figure', 'form', 'generic', 'group', 'heading', 'list', 'listitem', 'main', 'navigation', 'none', 'note', 'paragraph', 'presentation', 'region', 'section', 'status', 'table', 'term']);
16
+ function isSequential(element) {
17
+ if (element.tabIndex < 0 || element.matches(':disabled') || element.closest('[inert], [hidden]') != null || element.getClientRects().length === 0) {
18
+ return false;
19
+ }
20
+ const visibility = getComputedStyle(element).visibility;
21
+ return visibility !== 'hidden' && visibility !== 'collapse';
22
+ }
23
+ function firstDelegationTarget(viewport, content) {
24
+ const candidates = content.querySelectorAll(FOCUSABLE_SELECTOR);
25
+ let first = content.matches(FOCUSABLE_SELECTOR) && isSequential(content) ? content : null;
26
+ for (const candidate of candidates) {
27
+ // After finding the first target, only positive tabindex can precede it.
28
+ // Ordinary trailing controls need no visibility or layout reads.
29
+ if (first != null && candidate.tabIndex <= 0) {
30
+ continue;
31
+ }
32
+ if (!isSequential(candidate)) {
33
+ continue;
34
+ }
35
+ // Positive tabindex participates before the zero-index viewport. Do not
36
+ // revisit it or skip its ordering by delegating to a later zero-index child.
37
+ if (candidate.tabIndex > 0) {
38
+ return null;
39
+ }
40
+ first ??= candidate;
41
+ }
42
+ if (first == null || first.tabIndex !== 0 || !first.matches('a[href], button') || first.closest('[aria-hidden="true"]') != null || first.matches('[aria-disabled="true"], [aria-haspopup]:not([aria-haspopup="false"])')) {
43
+ return null;
44
+ }
45
+ let ancestor = first;
46
+ while (ancestor != null && ancestor !== viewport) {
47
+ const role = ancestor.getAttribute('role')?.trim().toLowerCase();
48
+ const nativeRole = ancestor === first && (role === 'button' && first.localName === 'button' || role === 'link' && first.localName === 'a');
49
+ if (role != null && role !== '' && !nativeRole && !PASSIVE_ROLES.has(role) || ancestor === first && role != null && role !== '' && !nativeRole || ancestor.hasAttribute('aria-activedescendant') || ancestor.isContentEditable || ancestor.matches('[contenteditable]:not([contenteditable="false"])') || getRegisteredScrollOwnerState(ancestor) != null) {
50
+ return null;
51
+ }
52
+ // Also respect native scroll owners that have not adopted the shared hook.
53
+ const style = getComputedStyle(ancestor);
54
+ if (/^(auto|scroll|overlay)$/.test(style.overflowX) && ancestor.scrollWidth > ancestor.clientWidth + 1 || /^(auto|scroll|overlay)$/.test(style.overflowY) && ancestor.scrollHeight > ancestor.clientHeight + 1) {
55
+ return null;
56
+ }
57
+ ancestor = ancestor.parentElement;
58
+ }
59
+ return ancestor === viewport ? first : null;
60
+ }
61
+
62
+ /** Attach only while automatic ownership has an effective scroll axis. */
63
+ export function attachScrollKeyboardDelegation(viewport, content) {
64
+ const document = viewport.ownerDocument;
65
+ const window = document.defaultView;
66
+ if (window == null) {
67
+ return () => {};
68
+ }
69
+ let entry = null;
70
+ let origin = null;
71
+ let delegated = null;
72
+ let timer;
73
+ let restoreTabStop;
74
+ const reset = () => {
75
+ entry = null;
76
+ origin = null;
77
+ window.clearTimeout(timer);
78
+ restoreTabStop?.();
79
+ restoreTabStop = undefined;
80
+ };
81
+ const onKeyDown = event => {
82
+ reset();
83
+ if (event.key !== 'Tab' || event.ctrlKey || event.metaKey) {
84
+ return;
85
+ }
86
+ // Keep the actual event: focus() during keydown is programmatic (nonzero
87
+ // eventPhase), whereas native Tab focus follows completed event dispatch.
88
+ entry = event;
89
+ origin = event.target;
90
+ if (event.shiftKey && delegated != null && document.activeElement === delegated && viewport.contains(delegated)) {
91
+ const tabIndex = viewport.getAttribute('tabindex');
92
+ viewport.tabIndex = -1;
93
+ restoreTabStop = () => {
94
+ if (viewport.getAttribute('tabindex') === '-1') {
95
+ if (tabIndex == null) {
96
+ viewport.removeAttribute('tabindex');
97
+ } else {
98
+ viewport.setAttribute('tabindex', tabIndex);
99
+ }
100
+ }
101
+ };
102
+ }
103
+ // A canceled Tab, focus leaving the document, or a held key must not leave
104
+ // stale keyboard intent for a later pointer/programmatic focus operation.
105
+ timer = window.setTimeout(reset, 0);
106
+ };
107
+ const onFocusIn = event => {
108
+ const keyboardEntry = entry;
109
+ const previous = origin;
110
+ reset();
111
+ if (event.target !== viewport) {
112
+ if (!viewport.contains(event.target)) {
113
+ delegated = null;
114
+ }
115
+ return;
116
+ }
117
+ delegated = null;
118
+ if (keyboardEntry == null || keyboardEntry.shiftKey || keyboardEntry.defaultPrevented || keyboardEntry.eventPhase !== 0 || event.relatedTarget != null && event.relatedTarget !== previous) {
119
+ return;
120
+ }
121
+ const target = firstDelegationTarget(viewport, content);
122
+ if (target == null) {
123
+ return;
124
+ }
125
+ delegated = target;
126
+ // Let native focus reveal the action. Arrow/Page scrolling remains entirely
127
+ // browser-owned, including scroll chaining and the full viewport range.
128
+ target.focus();
129
+ if (document.activeElement !== target) {
130
+ delegated = null;
131
+ }
132
+ };
133
+ document.addEventListener('keydown', onKeyDown, true);
134
+ document.addEventListener('keyup', reset, true);
135
+ document.addEventListener('pointerdown', reset, true);
136
+ document.addEventListener('focusin', onFocusIn, true);
137
+ window.addEventListener('blur', reset);
138
+ return () => {
139
+ reset();
140
+ document.removeEventListener('keydown', onKeyDown, true);
141
+ document.removeEventListener('keyup', reset, true);
142
+ document.removeEventListener('pointerdown', reset, true);
143
+ document.removeEventListener('focusin', onFocusIn, true);
144
+ window.removeEventListener('blur', reset);
145
+ };
146
+ }
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @file useScrollableArea.ts
3
- * @input Logical scroll intent, keyboard ownership, caller-owned viewport/content props
4
- * @output Safe prop getters and stable per-axis effective scroll state
3
+ * @input Logical scroll intent, focus-time keyboard delegation, caller-owned viewport/content props
4
+ * @output Safe prop getters, native keyboard entry, and stable per-axis effective scroll state
5
5
  * @position Canonical behavior core for ScrollableArea and structure-owning adopters
6
6
  *
7
7
  * SYNC: When modified, update:
@@ -20,6 +20,10 @@ export type ScrollKeyboardAccess = {
20
20
  owner: 'viewport';
21
21
  label: string;
22
22
  role?: 'group' | 'region';
23
+ } | {
24
+ owner: 'contentOrViewport';
25
+ label: string;
26
+ role?: 'group' | 'region';
23
27
  };
24
28
  export interface ScrollAxisState {
25
29
  isScrollable: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollableArea.d.ts","sourceRoot":"","sources":["../../src/hooks/useScrollableArea.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAOL,KAAK,aAAa,EAEnB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAiB5C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AACrD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;AACnD,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AAElE,MAAM,MAAM,oBAAoB,GAC5B;IAAC,KAAK,EAAE,SAAS,CAAA;CAAC,GAClB;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;CAAC,CAAC;AAElE,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,cAAc,EAAE,oBAAoB,CAAC;IACrC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;CAC7C;AAED,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,WAAW,IAAI,SAAS,CAAC,CAAC,CAAC,GACtE,aAAa,CAAC,CAAC,CAAC,CAAC;AAEnB,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,CAAC,CAAC,SAAS,WAAW,EACpC,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAChC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC7B,eAAe,CAAC,CAAC,SAAS,WAAW,EACnC,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAChC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC7B,KAAK,EAAE,mBAAmB,CAAC;CAC5B;AAiGD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,cAAc,EACd,UAAoB,EACpB,iBAAoC,GACrC,EAAE,wBAAwB,GAAG,uBAAuB,CAwRpD"}
1
+ {"version":3,"file":"useScrollableArea.d.ts","sourceRoot":"","sources":["../../src/hooks/useScrollableArea.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAOL,KAAK,aAAa,EAEnB,MAAM,OAAO,CAAC;AAEf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAkB5C,MAAM,MAAM,UAAU,GAAG,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAC;AACrD,MAAM,MAAM,gBAAgB,GAAG,OAAO,GAAG,SAAS,CAAC;AACnD,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,GAAG,QAAQ,CAAC;AAElE,MAAM,MAAM,oBAAoB,GAC5B;IAAC,KAAK,EAAE,SAAS,CAAA;CAAC,GAClB;IAAC,KAAK,EAAE,UAAU,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAA;CAAC,GAC7D;IACE,KAAK,EAAE,mBAAmB,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,GAAG,QAAQ,CAAC;CAC3B,CAAC;AAEN,MAAM,WAAW,eAAe;IAC9B,YAAY,EAAE,OAAO,CAAC;IACtB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,OAAO,CAAC;CAChB;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,EAAE,eAAe,CAAC;IACxB,KAAK,EAAE,eAAe,CAAC;CACxB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,UAAU,CAAC;IACjB,cAAc,EAAE,oBAAoB,CAAC;IACrC,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,iBAAiB,CAAC,EAAE,uBAAuB,CAAC;CAC7C;AAED,MAAM,MAAM,sBAAsB,CAAC,CAAC,SAAS,WAAW,IAAI,SAAS,CAAC,CAAC,CAAC,GACtE,aAAa,CAAC,CAAC,CAAC,CAAC;AAEnB,MAAM,WAAW,uBAAuB;IACtC,gBAAgB,CAAC,CAAC,SAAS,WAAW,EACpC,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAChC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC7B,eAAe,CAAC,CAAC,SAAS,WAAW,EACnC,KAAK,CAAC,EAAE,sBAAsB,CAAC,CAAC,CAAC,GAChC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAC7B,KAAK,EAAE,mBAAmB,CAAC;CAC5B;AAiGD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAAC,EAChC,IAAI,EACJ,cAAc,EACd,UAAoB,EACpB,iBAAoC,GACrC,EAAE,wBAAwB,GAAG,uBAAuB,CA0SpD"}
@@ -4,8 +4,8 @@
4
4
 
5
5
  /**
6
6
  * @file useScrollableArea.ts
7
- * @input Logical scroll intent, keyboard ownership, caller-owned viewport/content props
8
- * @output Safe prop getters and stable per-axis effective scroll state
7
+ * @input Logical scroll intent, focus-time keyboard delegation, caller-owned viewport/content props
8
+ * @output Safe prop getters, native keyboard entry, and stable per-axis effective scroll state
9
9
  * @position Canonical behavior core for ScrollableArea and structure-owning adopters
10
10
  *
11
11
  * SYNC: When modified, update:
@@ -15,6 +15,7 @@
15
15
  */
16
16
  import { useCallback, useMemo, useRef, useState } from 'react';
17
17
  import * as stylex from '@stylexjs/stylex';
18
+ import { attachScrollKeyboardDelegation } from "./scrollKeyboardDelegation.js";
18
19
  import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
19
20
  import { mergeProps } from "../utils/mergeProps.js";
20
21
  import { mergeRefs } from "../utils/mergeRefs.js";
@@ -172,6 +173,9 @@ export function useScrollableArea({
172
173
  viewport.addEventListener('animationend', scheduleMeasure);
173
174
  content.addEventListener('transitionend', scheduleMeasure);
174
175
  content.addEventListener('animationend', scheduleMeasure);
176
+
177
+ // Geometry invalidation is independent of keyboard eligibility. The latter
178
+ // is inspected only on native keyboard entry, never by these observers.
175
179
  const mutationObserver = typeof MutationObserver === 'undefined' ? null : new MutationObserver(scheduleMeasure);
176
180
  mutationObserver?.observe(viewport, {
177
181
  attributes: true,
@@ -219,6 +223,13 @@ export function useScrollableArea({
219
223
  inline: axisIsRequested(axis, 'inline') ? measured.inline : INACTIVE_AXIS_STATE,
220
224
  block: axisIsRequested(axis, 'block') ? measured.block : INACTIVE_AXIS_STATE
221
225
  }), [axis, measured]);
226
+ const hasEffectiveAxis = state.inline.isScrollable || state.block.isScrollable;
227
+ useIsomorphicLayoutEffect(() => {
228
+ if (keyboardAccess.owner !== 'contentOrViewport' || !hasEffectiveAxis || viewport == null || content == null) {
229
+ return;
230
+ }
231
+ return attachScrollKeyboardDelegation(viewport, content);
232
+ }, [content, hasEffectiveAxis, keyboardAccess.owner, viewport]);
222
233
  const getViewportProps = useCallback((props = {}) => {
223
234
  const hasEffectiveAxis = state.inline.isScrollable || state.block.isScrollable;
224
235
  const requestedX = axisIsRequested(axis, 'inline') && mapping.inline === 'x' || axisIsRequested(axis, 'block') && mapping.block === 'x';
@@ -237,7 +248,8 @@ export function useScrollableArea({
237
248
  style: withoutOwnedOverflow(domProps.style)
238
249
  };
239
250
  const styledProps = mergeProps(callerProps, stylex.props(xstyle, styles.overflow(containsSticky ? scrollsOnX ? 'auto' : 'hidden' : 'clip', containsSticky ? scrollsOnY ? 'auto' : 'hidden' : 'clip')));
240
- const keepsProgrammaticFocus = !hasEffectiveAxis && viewport != null && typeof document !== 'undefined' && document.activeElement === viewport;
251
+ const viewportIsKeyboardOwner = keyboardAccess.owner !== 'content';
252
+ const keepsProgrammaticFocus = (!viewportIsKeyboardOwner || !hasEffectiveAxis) && viewport != null && typeof document !== 'undefined' && document.activeElement === viewport;
241
253
  const behaviorStyle = {
242
254
  ...styledProps.style
243
255
  };
@@ -251,10 +263,10 @@ export function useScrollableArea({
251
263
  if (axisIsRequested(axis, 'block')) {
252
264
  behaviorStyle[blockPhysical === 'x' ? 'overscrollBehaviorX' : 'overscrollBehaviorY'] = containBlock ? 'contain' : 'auto';
253
265
  }
254
- const keyboardProps = keyboardAccess.owner === 'viewport' ? {
266
+ const keyboardProps = keyboardAccess.owner !== 'content' ? {
255
267
  role: keyboardAccess.role ?? 'group',
256
268
  'aria-label': keyboardAccess.label,
257
- tabIndex: hasEffectiveAxis ? 0 : keepsProgrammaticFocus ? -1 : undefined
269
+ tabIndex: viewportIsKeyboardOwner && hasEffectiveAxis ? 0 : keepsProgrammaticFocus ? -1 : undefined
258
270
  } : {};
259
271
  const result = {
260
272
  ...styledProps,
@@ -4,6 +4,11 @@
4
4
  * @output Exports reusable background-color and background-image state styles
5
5
  * @position Internal styling utility for interactive core surfaces
6
6
  *
7
+ * Every surface that paints a press composes one of these (or carries its own
8
+ * `:active` rule), so a change to how the system answers a press is made here
9
+ * once. `pressedBackgroundColor` is the press without the hover, for controls
10
+ * whose hover is a colour or nothing.
11
+ *
7
12
  * Keep the enabled guard outside the individual states. StyleX assigns an
8
13
  * extra priority bucket (and generated selector specificity) to media-nested
9
14
  * rules. Repeating `:active` inside the hover-capable branch gives hover and
@@ -22,5 +27,8 @@ export declare const interactionOverlayStyles: Readonly<{
22
27
  readonly backgroundImageOnNeutral: Readonly<{
23
28
  readonly backgroundImage: stylex.StyleXClassNameFor<"backgroundImage", string | null>;
24
29
  }>;
30
+ readonly pressedBackgroundColor: Readonly<{
31
+ readonly backgroundColor: stylex.StyleXClassNameFor<"backgroundColor", "light-dark(#05365919, #FFFFFF19)" | null>;
32
+ }>;
25
33
  }>;
26
34
  //# sourceMappingURL=interactionOverlay.stylex.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"interactionOverlay.stylex.d.ts","sourceRoot":"","sources":["../../src/utils/interactionOverlay.stylex.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;GAYG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAU3C,eAAO,MAAM,wBAAwB;;;;;;;;;;EA2CnC,CAAC"}
1
+ {"version":3,"file":"interactionOverlay.stylex.d.ts","sourceRoot":"","sources":["../../src/utils/interactionOverlay.stylex.ts"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAU3C,eAAO,MAAM,wBAAwB;;;;;;;;;;;;;EA0DnC,CAAC"}
@@ -10,6 +10,11 @@
10
10
  * @output Exports reusable background-color and background-image state styles
11
11
  * @position Internal styling utility for interactive core surfaces
12
12
  *
13
+ * Every surface that paints a press composes one of these (or carries its own
14
+ * `:active` rule), so a change to how the system answers a press is made here
15
+ * once. `pressedBackgroundColor` is the press without the hover, for controls
16
+ * whose hover is a colour or nothing.
17
+ *
13
18
  * Keep the enabled guard outside the individual states. StyleX assigns an
14
19
  * extra priority bucket (and generated selector specificity) to media-nested
15
20
  * rules. Repeating `:active` inside the hover-capable branch gives hover and
@@ -38,5 +43,9 @@ export const interactionOverlayStyles = {
38
43
  backgroundImageOnNeutral: {
39
44
  kKwaWg: "x14bno8m xzmimnh x1otsd3y xo3fi6e",
40
45
  $$css: true
46
+ },
47
+ pressedBackgroundColor: {
48
+ kWkggS: "x1anq1lc",
49
+ $$css: true
41
50
  }
42
51
  };
package/locales/en.json CHANGED
@@ -447,6 +447,18 @@
447
447
  "defaultMessage": "Next",
448
448
  "description": "Screen-reader-only label on the right-arrow button in a Lightbox (navigates to next media item). Pairs with `lightbox.previous`."
449
449
  },
450
+ "@astryx.chatTypingIndicator.one": {
451
+ "defaultMessage": "{name} is typing…",
452
+ "description": "Politely announced status naming the single person currently typing in a chat. `name` is a display name supplied by the app. Present-progressive form; the trailing ellipsis is the single … character."
453
+ },
454
+ "@astryx.chatTypingIndicator.many": {
455
+ "defaultMessage": "{names} are typing…",
456
+ "description": "Politely announced status when more than one person is typing in a chat. `names` is already joined for the locale by Intl.ListFormat, so translations must not add their own conjunction — place `{names}` where the joined list belongs."
457
+ },
458
+ "@astryx.chatTypingIndicator.others": {
459
+ "defaultMessage": "{count, number} {count, plural, one {other} other {others}}",
460
+ "description": "Overflow element for the chat typing status when three or more people type: the first name is shown and the rest collapse into this phrase, which is then joined to the name by Intl.ListFormat. Renders as the last list item, e.g. \"Ana and 2 others\"."
461
+ },
450
462
  "@astryx.listInput.emptyTitle": {
451
463
  "defaultMessage": "No {itemName}s yet",
452
464
  "description": "EmptyState title shown inside a lab ListInput when its collection has no records. `{itemName}` is the consumer's singular noun for one record (e.g. \"guest\"); the source appends a literal \"s\" to pluralize it, which only works for regular English plurals. If your language cannot pluralize an interpolated noun this way, rephrase around `{itemName}` instead (e.g. \"No {itemName} added yet\")."
@@ -935,6 +947,10 @@
935
947
  "defaultMessage": "Loading",
936
948
  "description": "Screen-reader-only live-region announcement while a Button is in its loading state (spinner shown, action in flight). Progressive sense (\"work in progress\"), not a noun. Kept separate from `typeahead.loading` — translations may diverge."
937
949
  },
950
+ "@astryx.spinner.loading": {
951
+ "defaultMessage": "Loading",
952
+ "description": "Screen-reader-only default name for a standalone Spinner's role=\"status\" element, used when the consumer supplies neither `aria-label` nor a visible string label. Present-progressive form. Kept separate from `button.loading` and `typeahead.loading` — translations may diverge."
953
+ },
938
954
  "@astryx.chatComposerDrawer.expand": {
939
955
  "defaultMessage": "Expand {label}",
940
956
  "description": "Screen-reader-only label on the ChatComposerDrawer toggle when the drawer is collapsed. `{label}` is the drawer's visible name — example: `Expand Attachments`. Pairs with `collapse`."
@@ -335,6 +335,15 @@
335
335
  "@astryx.lightbox.next": {
336
336
  "defaultMessage": "⟦Ñéẋţ⟧"
337
337
  },
338
+ "@astryx.chatTypingIndicator.one": {
339
+ "defaultMessage": "⟦{name} íš ţýþíñĝ…⟧"
340
+ },
341
+ "@astryx.chatTypingIndicator.many": {
342
+ "defaultMessage": "⟦{names} àřé ţýþíñĝ…⟧"
343
+ },
344
+ "@astryx.chatTypingIndicator.others": {
345
+ "defaultMessage": "⟦{count, number} {count, plural, one {other} other {others}}⟧"
346
+ },
338
347
  "@astryx.listInput.emptyTitle": {
339
348
  "defaultMessage": "⟦Ñó {itemName}š ýéţ⟧"
340
349
  },
@@ -701,6 +710,9 @@
701
710
  "@astryx.button.loading": {
702
711
  "defaultMessage": "⟦Łóàðíñĝ⟧"
703
712
  },
713
+ "@astryx.spinner.loading": {
714
+ "defaultMessage": "⟦Łóàðíñĝ⟧"
715
+ },
704
716
  "@astryx.chatComposerDrawer.expand": {
705
717
  "defaultMessage": "⟦Éẋþàñð {label}⟧"
706
718
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/core",
3
- "version": "0.6.1",
3
+ "version": "0.6.2-canary.023c3e4",
4
4
  "displayName": "Astryx Core",
5
5
  "description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
6
6
  "author": "Meta Open Source",
@@ -619,6 +619,16 @@
619
619
  "types": "./dist/utils/index.d.ts",
620
620
  "default": "./dist/utils/index.js"
621
621
  },
622
+ "./Markdown/plugins": {
623
+ "source": "./src/Markdown/plugins/index.ts",
624
+ "types": "./dist/Markdown/plugins/index.d.ts",
625
+ "default": "./dist/Markdown/plugins/index.js"
626
+ },
627
+ "./Markdown/parser": {
628
+ "source": "./src/Markdown/parser/index.ts",
629
+ "types": "./dist/Markdown/parser/index.d.ts",
630
+ "default": "./dist/Markdown/parser/index.js"
631
+ },
622
632
  "./Calendar/utils": {
623
633
  "source": "./src/Calendar/utils.ts",
624
634
  "types": "./dist/Calendar/utils.d.ts",
@@ -653,6 +663,11 @@
653
663
  "source": "./src/Typeahead/utils.ts",
654
664
  "types": "./dist/Typeahead/utils.d.ts",
655
665
  "default": "./dist/Typeahead/utils.js"
666
+ },
667
+ "./Markdown/remark": {
668
+ "source": "./src/Markdown/remark.ts",
669
+ "types": "./dist/Markdown/remark.d.ts",
670
+ "default": "./dist/Markdown/remark.js"
656
671
  }
657
672
  },
658
673
  "files": [
@@ -672,16 +687,18 @@
672
687
  "react-dom": ">=19.0.0"
673
688
  },
674
689
  "devDependencies": {
675
- "@babel/cli": "^8.0.4",
690
+ "@astryxdesign/a11y-spec": "0.6.2-canary.023c3e4",
691
+ "@astryxdesign/cli": "0.6.2-canary.023c3e4",
692
+ "@babel/cli": "^7.29.7",
676
693
  "@babel/core": "^7.29.7",
677
- "@babel/preset-react": "^8.0.1",
694
+ "@babel/preset-react": "^7.29.7",
678
695
  "@babel/preset-typescript": "^7.29.7",
696
+ "@heroicons/react": "^2.2.0",
679
697
  "@stylexjs/babel-plugin": "^0.19.0",
680
698
  "@testing-library/dom": "^10.0.0",
681
699
  "@testing-library/jest-dom": "^6.6.0",
682
700
  "@testing-library/react": "^16.3.2",
683
- "@astryxdesign/a11y-spec": "0.0.0",
684
- "@astryxdesign/cli": "0.6.1"
701
+ "@types/babel__core": "^7.20.5"
685
702
  },
686
703
  "dependencies": {
687
704
  "intl-messageformat": "^11.2.9"
@@ -57,7 +57,7 @@ export const LEGACY_MARKER_END = '<!-- XDS:END -->';
57
57
  * targets are user-chosen and not enumerable here.)
58
58
  */
59
59
  export const AGENT_DOC_PATHS = [
60
- AGENTS_MD, // Codex / ChatGPT / generic
60
+ AGENTS_MD, // Codex / ChatGPT / Muse / generic
61
61
  CLAUDE_MD, // Claude Code (root)
62
62
  CLAUDE_DIR_MD, // Claude Code (.claude/CLAUDE.md)
63
63
  CURSOR_RULES, // Cursor
@@ -1,5 +1,12 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
+ /**
4
+ * @file BottomSheet.doc.mjs
5
+ * @input BottomSheet props, sheet anatomy, and focus-time keyboard scrolling behavior
6
+ * @output Consumer documentation and examples for BottomSheet
7
+ * @position CLI and rendered component documentation
8
+ */
9
+
3
10
  /** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
4
11
  const anatomy = [
5
12
  {
@@ -130,7 +137,7 @@ export const docs = {
130
137
  name: 'children',
131
138
  type: 'ReactNode',
132
139
  description:
133
- "Sheet content, rendered below the grab handle in a scrollable area. If it includes a text-entry control that can bring up the mobile keyboard, use height='tall' and keep the sheet fully expanded while editing.",
140
+ "Sheet content in a scrollable area. The named body is keyboard reachable while overflowing. Forward Tab entry may move directly to the first native link or button; input controls, composite widgets, and nested scroll areas retain the body stop. Shift+Tab from a delegated first child skips the body. Fitting content adds no body stop. The internal observed content box preserves block flow and percentage heights. If it includes a text-entry control that can bring up the mobile keyboard, use height='tall' and keep the sheet fully expanded while editing.",
134
141
  required: true,
135
142
  },
136
143
  {