@astryxdesign/core 0.7.1-canary.ff40b78 → 0.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (348) hide show
  1. package/CHANGELOG.md +116 -0
  2. package/dist/Button/Button.d.ts +1 -1
  3. package/dist/Button/Button.d.ts.map +1 -1
  4. package/dist/Button/Button.js +5 -2
  5. package/dist/Calendar/Calendar.d.ts.map +1 -1
  6. package/dist/Calendar/Calendar.js +191 -32
  7. package/dist/Chat/ChatComposerInput.d.ts +9 -0
  8. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  9. package/dist/Chat/ChatComposerInput.js +5 -0
  10. package/dist/Chat/ChatMessage.d.ts +11 -0
  11. package/dist/Chat/ChatMessage.d.ts.map +1 -1
  12. package/dist/Chat/ChatMessage.js +18 -9
  13. package/dist/Chat/useTriggerMenu.d.ts +9 -2
  14. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  15. package/dist/Chat/useTriggerMenu.js +222 -50
  16. package/dist/CodeBlock/CodeBlock.d.ts +10 -1
  17. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  18. package/dist/CodeBlock/CodeBlock.js +158 -38
  19. package/dist/CodeBlock/tokenizer.d.ts +39 -0
  20. package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
  21. package/dist/CodeBlock/tokenizer.js +108 -0
  22. package/dist/CommandPalette/CommandPalette.d.ts +9 -5
  23. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  24. package/dist/CommandPalette/CommandPalette.js +38 -20
  25. package/dist/CommandPalette/CommandPaletteEmpty.d.ts +4 -3
  26. package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
  27. package/dist/CommandPalette/CommandPaletteEmpty.js +4 -3
  28. package/dist/CommandPalette/CommandPaletteInput.d.ts +5 -4
  29. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  30. package/dist/CommandPalette/CommandPaletteInput.js +35 -18
  31. package/dist/CommandPalette/CommandPaletteItem.d.ts +11 -6
  32. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  33. package/dist/CommandPalette/CommandPaletteItem.js +8 -9
  34. package/dist/CommandPalette/CommandPaletteList.d.ts +4 -2
  35. package/dist/CommandPalette/CommandPaletteList.d.ts.map +1 -1
  36. package/dist/CommandPalette/CommandPaletteList.js +10 -5
  37. package/dist/ComplexSelector/ComplexSelector.d.ts +8 -5
  38. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  39. package/dist/ComplexSelector/ComplexSelector.js +12 -3
  40. package/dist/ContextMenu/ContextMenu.d.ts +3 -3
  41. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  42. package/dist/ContextMenu/ContextMenu.js +62 -48
  43. package/dist/DateInput/DateInput.js +1 -1
  44. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  45. package/dist/DateInput/MonthScroller.js +12 -4
  46. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  47. package/dist/DateRangeInput/DateRangeInput.js +12 -2
  48. package/dist/Dialog/Dialog.d.ts +1 -1
  49. package/dist/Dialog/Dialog.d.ts.map +1 -1
  50. package/dist/Dialog/Dialog.js +16 -5
  51. package/dist/Dialog/DialogHeader.d.ts +1 -1
  52. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  53. package/dist/Dialog/DialogHeader.js +7 -7
  54. package/dist/Divider/Divider.d.ts +1 -0
  55. package/dist/Divider/Divider.d.ts.map +1 -1
  56. package/dist/Divider/Divider.js +5 -4
  57. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  58. package/dist/DropdownMenu/DropdownMenu.js +161 -65
  59. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +7 -5
  60. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  61. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +12 -5
  62. package/dist/Field/InputClearButton.d.ts +8 -4
  63. package/dist/Field/InputClearButton.d.ts.map +1 -1
  64. package/dist/Field/InputClearButton.js +23 -7
  65. package/dist/FormLayout/FormLayout.d.ts.map +1 -1
  66. package/dist/FormLayout/FormLayout.js +1 -0
  67. package/dist/Grid/Grid.d.ts +13 -4
  68. package/dist/Grid/Grid.d.ts.map +1 -1
  69. package/dist/Grid/Grid.js +7 -1
  70. package/dist/HoverCard/useHoverCard.d.ts +1 -1
  71. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  72. package/dist/HoverCard/useHoverCard.js +67 -49
  73. package/dist/InputGroup/InputGroup.d.ts +2 -4
  74. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  75. package/dist/InputGroup/InputGroup.js +2 -4
  76. package/dist/InputGroup/groupStyles.d.ts +10 -2
  77. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  78. package/dist/InputGroup/groupStyles.js +19 -2
  79. package/dist/Layer/useLayerDismissal.d.ts +9 -9
  80. package/dist/Layer/useLayerDismissal.js +9 -9
  81. package/dist/Markdown/Markdown.d.ts.map +1 -1
  82. package/dist/Markdown/Markdown.js +25 -4
  83. package/dist/MobileNav/MobileNav.d.ts +7 -0
  84. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  85. package/dist/MobileNav/MobileNav.js +45 -2
  86. package/dist/MultiSelector/MultiSelector.d.ts +7 -4
  87. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  88. package/dist/MultiSelector/MultiSelector.js +24 -3
  89. package/dist/NumberInput/NumberInput.js +1 -1
  90. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  91. package/dist/PowerSearch/PowerSearchEditPopover.js +6 -0
  92. package/dist/Resizable/ResizeHandle.d.ts +1 -1
  93. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  94. package/dist/Resizable/ResizeHandle.js +83 -15
  95. package/dist/Resizable/useResizable.d.ts +23 -0
  96. package/dist/Resizable/useResizable.d.ts.map +1 -1
  97. package/dist/Resizable/useResizable.js +78 -0
  98. package/dist/Selector/Selector.d.ts +6 -3
  99. package/dist/Selector/Selector.d.ts.map +1 -1
  100. package/dist/Selector/Selector.js +28 -6
  101. package/dist/SideNav/SideNav.d.ts.map +1 -1
  102. package/dist/SideNav/SideNav.js +10 -2
  103. package/dist/Slider/Slider.d.ts.map +1 -1
  104. package/dist/Slider/Slider.js +18 -7
  105. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  106. package/dist/Tokenizer/Tokenizer.js +16 -4
  107. package/dist/Toolbar/Toolbar.d.ts +2 -1
  108. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  109. package/dist/Toolbar/Toolbar.js +3 -1
  110. package/dist/TreeList/TreeList.d.ts.map +1 -1
  111. package/dist/TreeList/TreeList.js +6 -3
  112. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  113. package/dist/TreeList/TreeListItem.js +7 -1
  114. package/dist/astryx.css +22 -0
  115. package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
  116. package/dist/hooks/useScrollOverflow.js +55 -12
  117. package/dist/hooks/useTreeFocus.d.ts +21 -0
  118. package/dist/hooks/useTreeFocus.d.ts.map +1 -1
  119. package/dist/hooks/useTreeFocus.js +40 -2
  120. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  121. package/dist/i18n/generated-locales/en.generated.js +3 -0
  122. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  123. package/dist/i18n/generated-locales/pseudo.generated.js +3 -0
  124. package/dist/reset.a11y.chromium.spec.js +6 -1
  125. package/dist/reset.until-found.a11y.browser.spec.d.ts +2 -0
  126. package/dist/reset.until-found.a11y.browser.spec.d.ts.map +1 -0
  127. package/dist/reset.until-found.a11y.browser.spec.js +71 -0
  128. package/dist/theme/syntax/SyntaxTheme.d.ts.map +1 -1
  129. package/dist/theme/syntax/SyntaxTheme.js +43 -2
  130. package/dist/theme/syntax/defineSyntaxTheme.d.ts +18 -5
  131. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  132. package/dist/theme/syntax/defineSyntaxTheme.js +38 -9
  133. package/dist/theme/syntax/index.d.ts +1 -1
  134. package/dist/theme/syntax/index.d.ts.map +1 -1
  135. package/dist/theme/syntax/tokens.d.ts +12 -2
  136. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  137. package/dist/theme/syntax/tokens.js +25 -4
  138. package/dist/utils/plainDate.d.ts +12 -0
  139. package/dist/utils/plainDate.d.ts.map +1 -1
  140. package/dist/utils/plainDate.js +63 -10
  141. package/locales/en.json +13 -1
  142. package/locales/pseudo.json +9 -0
  143. package/package.json +4 -4
  144. package/src/AlertDialog/AlertDialog.doc.mjs +6 -0
  145. package/src/AlertDialog/AlertDialog.spec.md +205 -0
  146. package/src/AlertDialog/AlertDialog.test.tsx +3 -14
  147. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +115 -0
  148. package/src/AlertDialog/__tests__/AlertDialog.a11y.renders.tsx +52 -0
  149. package/src/AlertDialog/__tests__/AlertDialog.a11y.states.ts +68 -0
  150. package/src/AlertDialog/__tests__/AlertDialog.a11y.test.tsx +144 -0
  151. package/src/Button/Button.test.tsx +37 -0
  152. package/src/Button/Button.tsx +5 -1
  153. package/src/Calendar/Calendar.doc.mjs +234 -60
  154. package/src/Calendar/Calendar.spec.md +209 -0
  155. package/src/Calendar/Calendar.test.tsx +559 -20
  156. package/src/Calendar/Calendar.tsx +258 -41
  157. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +126 -0
  158. package/src/Calendar/__tests__/Calendar.a11y.known-failures.ts +12 -0
  159. package/src/Calendar/__tests__/Calendar.a11y.renders.tsx +57 -0
  160. package/src/Calendar/__tests__/Calendar.a11y.states.ts +139 -0
  161. package/src/Calendar/__tests__/Calendar.a11y.test.tsx +137 -0
  162. package/src/Carousel/Carousel.test.tsx +54 -71
  163. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +192 -0
  164. package/src/Carousel/__tests__/Carousel.a11y.known-failures.ts +27 -0
  165. package/src/Carousel/__tests__/Carousel.a11y.renders.tsx +39 -0
  166. package/src/Carousel/__tests__/Carousel.a11y.states.ts +139 -0
  167. package/src/Carousel/__tests__/Carousel.a11y.test.tsx +127 -0
  168. package/src/Chat/ChatComposerInput.doc.mjs +1 -1
  169. package/src/Chat/ChatComposerInput.spec.md +94 -55
  170. package/src/Chat/ChatComposerInput.test.tsx +202 -1
  171. package/src/Chat/ChatComposerInput.tsx +13 -0
  172. package/src/Chat/ChatMessage.doc.mjs +31 -16
  173. package/src/Chat/ChatMessage.spec.md +265 -0
  174. package/src/Chat/ChatMessage.test.tsx +246 -0
  175. package/src/Chat/ChatMessage.tsx +30 -7
  176. package/src/Chat/ChatSystemMessage.spec.md +36 -37
  177. package/src/Chat/ChatSystemMessage.test.tsx +4 -4
  178. package/src/Chat/useTriggerMenu.test.tsx +994 -0
  179. package/src/Chat/useTriggerMenu.tsx +278 -46
  180. package/src/CodeBlock/CodeBlock.doc.mjs +7 -0
  181. package/src/CodeBlock/CodeBlock.spec.md +40 -41
  182. package/src/CodeBlock/CodeBlock.test.tsx +89 -9
  183. package/src/CodeBlock/CodeBlock.tsx +205 -25
  184. package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +125 -0
  185. package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +93 -0
  186. package/src/CodeBlock/tokenizer.test.ts +112 -0
  187. package/src/CodeBlock/tokenizer.ts +106 -0
  188. package/src/Collapsible/CollapsibleGroup.spec.md +17 -8
  189. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.renders.tsx +45 -0
  190. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.states.ts +139 -0
  191. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.test.tsx +135 -0
  192. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +128 -0
  193. package/src/CommandPalette/CommandPalette.doc.mjs +126 -23
  194. package/src/CommandPalette/CommandPalette.spec.md +100 -49
  195. package/src/CommandPalette/CommandPalette.test.tsx +241 -2
  196. package/src/CommandPalette/CommandPalette.tsx +47 -21
  197. package/src/CommandPalette/CommandPaletteEmpty.tsx +4 -3
  198. package/src/CommandPalette/CommandPaletteInput.doc.mjs +61 -4
  199. package/src/CommandPalette/CommandPaletteInput.spec.md +215 -0
  200. package/src/CommandPalette/CommandPaletteInput.test.tsx +375 -51
  201. package/src/CommandPalette/CommandPaletteInput.tsx +74 -21
  202. package/src/CommandPalette/CommandPaletteItem.doc.mjs +73 -22
  203. package/src/CommandPalette/CommandPaletteItem.spec.md +223 -0
  204. package/src/CommandPalette/CommandPaletteItem.test.tsx +200 -5
  205. package/src/CommandPalette/CommandPaletteItem.tsx +16 -11
  206. package/src/CommandPalette/CommandPaletteList.doc.mjs +3 -3
  207. package/src/CommandPalette/CommandPaletteList.spec.md +41 -36
  208. package/src/CommandPalette/CommandPaletteList.test.tsx +80 -0
  209. package/src/CommandPalette/CommandPaletteList.tsx +10 -5
  210. package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +599 -0
  211. package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -8
  212. package/src/ComplexSelector/ComplexSelector.spec.md +14 -9
  213. package/src/ComplexSelector/ComplexSelector.test.tsx +64 -16
  214. package/src/ComplexSelector/ComplexSelector.tsx +37 -8
  215. package/src/ContextMenu/ContextMenu.doc.mjs +6 -0
  216. package/src/ContextMenu/ContextMenu.spec.md +51 -53
  217. package/src/ContextMenu/ContextMenu.test.tsx +132 -1
  218. package/src/ContextMenu/ContextMenu.tsx +78 -48
  219. package/src/DateInput/DateInput.doc.mjs +52 -0
  220. package/src/DateInput/DateInput.spec.md +27 -15
  221. package/src/DateInput/DateInput.test.tsx +38 -0
  222. package/src/DateInput/DateInput.tsx +1 -1
  223. package/src/DateInput/DateInputTouch.test.tsx +22 -0
  224. package/src/DateInput/MonthScroller.tsx +12 -4
  225. package/src/DateRangeInput/DateRangeInput.test.tsx +49 -0
  226. package/src/DateRangeInput/DateRangeInput.tsx +20 -2
  227. package/src/Dialog/Dialog.test.tsx +27 -1
  228. package/src/Dialog/Dialog.tsx +16 -5
  229. package/src/Dialog/DialogHeader.test.tsx +27 -2
  230. package/src/Dialog/DialogHeader.tsx +7 -8
  231. package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +21 -14
  232. package/src/Divider/Divider.doc.mjs +5 -3
  233. package/src/Divider/Divider.spec.md +140 -54
  234. package/src/Divider/Divider.test.tsx +15 -0
  235. package/src/Divider/Divider.tsx +6 -4
  236. package/src/DropdownMenu/DropdownMenu.doc.mjs +2 -2
  237. package/src/DropdownMenu/DropdownMenu.spec.md +121 -45
  238. package/src/DropdownMenu/DropdownMenu.test.tsx +288 -23
  239. package/src/DropdownMenu/DropdownMenu.tsx +212 -81
  240. package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +38 -2
  241. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +32 -18
  242. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +146 -1
  243. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +136 -0
  244. package/src/DropdownMenu/__tests__/MenuButton.a11y.known-failures.ts +12 -0
  245. package/src/DropdownMenu/__tests__/MenuButton.a11y.renders.tsx +67 -0
  246. package/src/DropdownMenu/__tests__/MenuButton.a11y.states.ts +141 -0
  247. package/src/DropdownMenu/__tests__/MenuButton.a11y.test.tsx +138 -0
  248. package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +40 -5
  249. package/src/Field/InputClearButton.test.tsx +29 -4
  250. package/src/Field/InputClearButton.tsx +26 -8
  251. package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +21 -14
  252. package/src/FormLayout/FormLayout.tsx +1 -0
  253. package/src/FormLayout/__snapshots__/FormLayout.test.tsx.snap +1 -1
  254. package/src/Grid/Grid.doc.mjs +14 -11
  255. package/src/Grid/Grid.spec.md +50 -32
  256. package/src/Grid/Grid.tsx +13 -4
  257. package/src/HoverCard/HoverCard.test.tsx +46 -1
  258. package/src/HoverCard/useHoverCard.tsx +68 -48
  259. package/src/InputGroup/InputGroup.doc.mjs +11 -1
  260. package/src/InputGroup/InputGroup.tsx +2 -4
  261. package/src/InputGroup/groupStyles.ts +40 -2
  262. package/src/Layer/useLayerDismissal.ts +9 -9
  263. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +142 -0
  264. package/src/Link/__tests__/Link.a11y.renders.tsx +97 -0
  265. package/src/Link/__tests__/Link.a11y.states.ts +104 -0
  266. package/src/Link/__tests__/Link.a11y.test.tsx +127 -0
  267. package/src/Markdown/Markdown.doc.mjs +1 -1
  268. package/src/Markdown/Markdown.fr23.perf.test.ts +161 -40
  269. package/src/Markdown/Markdown.spec.md +45 -23
  270. package/src/Markdown/Markdown.test.tsx +38 -0
  271. package/src/Markdown/Markdown.tsx +24 -2
  272. package/src/Markdown/plugins/semanticFence.test.tsx +3 -2
  273. package/src/MobileNav/MobileNav.tsx +50 -2
  274. package/src/MobileNav/MobileNavFocus.test.tsx +553 -0
  275. package/src/MoreMenu/MoreMenu.spec.md +18 -7
  276. package/src/MoreMenu/MoreMenu.test.tsx +38 -0
  277. package/src/MultiSelector/MultiSelector.doc.mjs +8 -8
  278. package/src/MultiSelector/MultiSelector.spec.md +1 -1
  279. package/src/MultiSelector/MultiSelector.test.tsx +188 -21
  280. package/src/MultiSelector/MultiSelector.tsx +50 -11
  281. package/src/NumberInput/NumberInput.test.tsx +24 -0
  282. package/src/NumberInput/NumberInput.tsx +1 -1
  283. package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +22 -15
  284. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +78 -0
  285. package/src/PowerSearch/PowerSearchEditPopover.tsx +6 -0
  286. package/src/Resizable/Resizable.spec.md +41 -9
  287. package/src/Resizable/ResizeHandle.test.tsx +565 -2
  288. package/src/Resizable/ResizeHandle.tsx +126 -21
  289. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +119 -0
  290. package/src/Resizable/__tests__/ResizeHandle.a11y.known-failures.ts +39 -0
  291. package/src/Resizable/__tests__/ResizeHandle.a11y.renders.tsx +80 -0
  292. package/src/Resizable/__tests__/ResizeHandle.a11y.states.ts +197 -0
  293. package/src/Resizable/__tests__/ResizeHandle.a11y.test.tsx +123 -0
  294. package/src/Resizable/useResizable.ts +95 -0
  295. package/src/Selector/Selector.doc.mjs +7 -6
  296. package/src/Selector/Selector.spec.md +37 -24
  297. package/src/Selector/Selector.test.tsx +176 -10
  298. package/src/Selector/Selector.tsx +59 -14
  299. package/src/Selector/__tests__/Combobox.a11y.known-failures.ts +27 -0
  300. package/src/Selector/__tests__/Combobox.a11y.states.ts +145 -0
  301. package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +108 -0
  302. package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +126 -0
  303. package/src/SideNav/SideNav.test.tsx +35 -0
  304. package/src/SideNav/SideNav.tsx +16 -2
  305. package/src/Slider/Slider.spec.md +43 -17
  306. package/src/Slider/Slider.test.tsx +134 -0
  307. package/src/Slider/Slider.tsx +29 -6
  308. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +112 -0
  309. package/src/Slider/__tests__/Slider.a11y.known-failures.ts +12 -0
  310. package/src/Slider/__tests__/Slider.a11y.renders.tsx +42 -0
  311. package/src/Slider/__tests__/Slider.a11y.states.ts +106 -0
  312. package/src/Slider/__tests__/Slider.a11y.test.tsx +105 -0
  313. package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +25 -18
  314. package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +19 -12
  315. package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +21 -14
  316. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +18 -11
  317. package/src/Tokenizer/Tokenizer.test.tsx +87 -0
  318. package/src/Tokenizer/Tokenizer.tsx +31 -3
  319. package/src/Toolbar/Toolbar.test.tsx +131 -4
  320. package/src/Toolbar/Toolbar.tsx +3 -1
  321. package/src/TreeList/TreeList.spec.md +33 -8
  322. package/src/TreeList/TreeList.test.tsx +72 -0
  323. package/src/TreeList/TreeList.tsx +10 -6
  324. package/src/TreeList/TreeListItem.tsx +5 -0
  325. package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +125 -0
  326. package/src/TreeList/__tests__/TreeList.a11y.renders.tsx +44 -0
  327. package/src/TreeList/__tests__/TreeList.a11y.states.ts +164 -0
  328. package/src/TreeList/__tests__/TreeList.a11y.test.tsx +138 -0
  329. package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +82 -0
  330. package/src/hooks/useScrollOverflow.test.tsx +222 -0
  331. package/src/hooks/useScrollOverflow.ts +55 -13
  332. package/src/hooks/useTreeFocus.test.tsx +37 -0
  333. package/src/hooks/useTreeFocus.ts +55 -2
  334. package/src/i18n/generated-locales/en.generated.ts +3 -0
  335. package/src/i18n/generated-locales/pseudo.generated.ts +3 -0
  336. package/src/reset.a11y.chromium.spec.ts +9 -1
  337. package/src/reset.css +8 -3
  338. package/src/reset.until-found.a11y.browser.spec.ts +75 -0
  339. package/src/reset.until-found.test.ts +32 -0
  340. package/src/stylexValidation.source-build.test.mjs +42 -0
  341. package/src/theme/syntax/SyntaxTheme.tsx +46 -5
  342. package/src/theme/syntax/defineSyntaxTheme.diff.test.ts +91 -0
  343. package/src/theme/syntax/defineSyntaxTheme.ts +75 -15
  344. package/src/theme/syntax/index.ts +5 -1
  345. package/src/theme/syntax/tokens.ts +32 -2
  346. package/src/theme/syntax/useSyntaxTheme.diff.test.tsx +40 -0
  347. package/src/utils/plainDate.test.ts +147 -0
  348. package/src/utils/plainDate.ts +75 -10
@@ -6,7 +6,7 @@
6
6
  * @file Selector.tsx
7
7
  * @input Uses React, StyleX, adaptive selection surfaces, theme-resolved
8
8
  * indicators, Field, and InputGroup context
9
- * @output Exports Selector with content-derived option-mark layout and token-sized single-line triggers
9
+ * @output Exports Selector with input, secondary, and ghost trigger treatments, content-derived option-mark layout, and token-sized single-line triggers
10
10
  * @position Core implementation; consumed by index.ts
11
11
  *
12
12
  * SYNC: When modified, update:
@@ -112,6 +112,17 @@ const styles = {
112
112
  k3aq6I: "x3oybdh xk4oym4 x5lqen6 x3y5scg",
113
113
  $$css: true
114
114
  },
115
+ triggerSecondary: {
116
+ kzqmXN: "x14atkfc",
117
+ kMzoRj: "xc342km",
118
+ kLWn49: "x8vohu",
119
+ kWkggS: "x17x4s8c",
120
+ kGVxlE: "x1gnnqk1 x1s17dad x15ysqaf",
121
+ k63SB2: "x1e4wzip",
122
+ k1ekBW: "xrafxwg",
123
+ k3aq6I: "x3oybdh xk4oym4 x5lqen6 x3y5scg",
124
+ $$css: true
125
+ },
115
126
  triggerGhostDisabled: {
116
127
  kKwaWg: "x18o3ruo",
117
128
  k3aq6I: "x1c071of x1pdlv7q x1ylxtyb",
@@ -386,7 +397,7 @@ export function Selector(props) {
386
397
  const emptySearchText = emptySearchTextFromProps ?? t('@astryx.selector.emptySearchResults');
387
398
  const hasClear = hasClearProp === true;
388
399
  const size = useSize(sizeProp, 'md');
389
- const effectiveStatusVariant = variant === 'ghost' && statusVariant === 'attached' ? 'detached' : statusVariant;
400
+ const effectiveStatusVariant = variant !== 'input' && statusVariant === 'attached' ? 'detached' : statusVariant;
390
401
  const isEffectivelyReadOnly = isReadOnly && !isDisabled;
391
402
 
392
403
  // Normalize null to undefined for internal use (null is the clear sentinel)
@@ -754,6 +765,14 @@ export function Selector(props) {
754
765
  const handleClear = useCallback(e => {
755
766
  e.stopPropagation(); // Don't open dropdown
756
767
  clearValue();
768
+ // A keyboard activation (detail 0) leaves focus on the clear button,
769
+ // which unmounts once the value is null and would drop focus to <body>;
770
+ // hand it to the trigger as `hasClear` documents. A pointer press never
771
+ // focuses the button, so there is no focus to repair, and moving it
772
+ // would pull it out of an open list's search input.
773
+ if (e.detail === 0) {
774
+ triggerRef.current?.focus();
775
+ }
757
776
  }, [clearValue]);
758
777
 
759
778
  // Render search input
@@ -778,7 +797,7 @@ export function Selector(props) {
778
797
  label: t('@astryx.selector.searchOptions')
779
798
  }),
780
799
  ...themeProps('selector-search'),
781
- xstyle: surface.activePresentation === 'popover' && variant !== 'ghost' && styles.searchRowInput
800
+ xstyle: surface.activePresentation === 'popover' && variant === 'input' && styles.searchRowInput
782
801
  // When hasSearch is set, focus moves into this input on open, so it —
783
802
  // not the trigger — must be the combobox that reports the highlighted
784
803
  // option via aria-activedescendant (comboboxes-4). A bare searchbox
@@ -1045,7 +1064,7 @@ export function Selector(props) {
1045
1064
  3: {
1046
1065
  className: "x9f619 xuyqlj2 x1odjw0f x1a2a7pz xu0wf1k x1hc1fzr x1ey1afo xge0x1e xish69e x2hg6jq"
1047
1066
  }
1048
- }[!!listboxHasOverflow << 1 | !!(surface.activePresentation === 'popover' && variant !== 'ghost') << 0],
1067
+ }[!!listboxHasOverflow << 1 | !!(surface.activePresentation === 'popover' && variant === 'input') << 0],
1049
1068
  children: renderOptions()
1050
1069
  })]
1051
1070
  }) : /*#__PURE__*/_jsx("div", {
@@ -1088,7 +1107,7 @@ export function Selector(props) {
1088
1107
  7: {
1089
1108
  className: "x9f619 xuyqlj2 x1odjw0f x1a2a7pz xu0wf1k xge0x1e xish69e x2hg6jq xg01cxk xq2gx43"
1090
1109
  }
1091
- }[!!listboxHasOverflow << 2 | !!(surface.activePresentation === 'popover' && variant !== 'ghost') << 1 | !!(surface.activePresentation === 'popover' && !isPositioned) << 0],
1110
+ }[!!listboxHasOverflow << 2 | !!(surface.activePresentation === 'popover' && variant === 'input') << 1 | !!(surface.activePresentation === 'popover' && !isPositioned) << 0],
1092
1111
  children: renderOptions()
1093
1112
  });
1094
1113
  let selectionSurface = null;
@@ -1167,7 +1186,10 @@ export function Selector(props) {
1167
1186
  status: status?.type ?? null,
1168
1187
  disabled: isDisabled ? 'disabled' : null,
1169
1188
  readonly: isEffectivelyReadOnly ? 'readonly' : null
1170
- }), stylex.props(inputWrapperStyles.base, styles.triggerContainer, sizeStyles[size], variant === 'ghost' && styles.triggerGhost, variant === 'ghost' && interactionOverlayStyles.backgroundImage, variant === 'ghost' && focusOutlineStyles.focusWithin, surface.isTriggerFocusRingSuppressed && selectorPresentationStyles.pointerRestoredFocus, isDisabled && inputWrapperStyles.disabled, isEffectivelyReadOnly && styles.triggerReadOnly, variant === 'ghost' && isDisabled && styles.triggerGhostDisabled, variant === 'ghost' && isEffectivelyReadOnly && styles.triggerGhostReadOnly, !selectedItem && styles.triggerPlaceholder, variant !== 'ghost' && status && inputStatusBorderStyles[status.type], variant !== 'ghost' && status && !isDisabled && inputStatusHoverShadowStyles[status.type], variant !== 'ghost' && inputGroup && groupStyles.inGroup, inputGroup && styles.triggerInGroup, controlXstyle), controlClassName, controlStyle),
1189
+ }), stylex.props(inputWrapperStyles.base, styles.triggerContainer, sizeStyles[size], variant === 'ghost' && styles.triggerGhost, variant === 'secondary' && styles.triggerSecondary, variant !== 'input' && interactionOverlayStyles.backgroundImage, variant !== 'input' && focusOutlineStyles.focusWithin, surface.isTriggerFocusRingSuppressed && selectorPresentationStyles.pointerRestoredFocus, isDisabled && inputWrapperStyles.disabled, isEffectivelyReadOnly && styles.triggerReadOnly, variant !== 'input' && isDisabled && styles.triggerGhostDisabled, variant !== 'input' && isEffectivelyReadOnly && styles.triggerGhostReadOnly, !selectedItem && styles.triggerPlaceholder, variant === 'input' && status && inputStatusBorderStyles[status.type], variant === 'input' && status && !isDisabled && inputStatusHoverShadowStyles[status.type],
1190
+ // Grouped secondary triggers keep their neutral fill but take the
1191
+ // group's row height, connected edge radii, and focus stacking.
1192
+ variant !== 'ghost' && inputGroup && groupStyles.inGroup, inputGroup && styles.triggerInGroup, controlXstyle), controlClassName, controlStyle),
1171
1193
  children: [startIcon && renderIconSlot(startIcon, {
1172
1194
  size: 'sm',
1173
1195
  color: 'secondary'
@@ -1 +1 @@
1
- {"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../src/SideNav/SideNav.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAA2C,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAC/E,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;AAsP/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,+BA2Qd;yBA1Re,OAAO"}
1
+ {"version":3,"file":"SideNav.d.ts","sourceRoot":"","sources":["../../src/SideNav/SideNav.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAKL,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;AAsP/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,+BAmRd;yBAlSe,OAAO"}
@@ -21,7 +21,7 @@
21
21
  * - /apps/storybook/stories/SideNav.stories.tsx
22
22
  * - /packages/cli/assets/templates/blocks/components/SideNav/ (showcase blocks)
23
23
  */
24
- import { useCallback, useImperativeHandle, useRef } from 'react';
24
+ import { useCallback, useId, useImperativeHandle, useRef } from 'react';
25
25
  import * as stylex from '@stylexjs/stylex';
26
26
  import "../theme/tokens.stylex.js";
27
27
  import { focusVars, spacingVars } from "../theme/tokens.stylex.js";
@@ -183,6 +183,10 @@ export function SideNav({
183
183
  } = collapseConfig;
184
184
  useDevWarning('SideNav', collapseConfig.conflict ?? '', collapseConfig.conflict != null);
185
185
  const navRef = useRef(null);
186
+ // The resize handle names the pane it resizes (APG window splitter), so the
187
+ // nav needs an id; a consumer's own id wins.
188
+ const generatedNavId = useId();
189
+ const navId = props.id ?? generatedNavId;
186
190
  const mergedNavRef = useMergedRefs(ref, navRef);
187
191
  const collapseStateRef = useRef({
188
192
  isCollapsed: false,
@@ -333,6 +337,9 @@ export function SideNav({
333
337
  "data-testid": testId,
334
338
  ...mergeProps(themeProps('side-nav'), stylex.props(styles.root, collapsed && styles.rootCollapsed, xstyle), className, resizableNavStyle),
335
339
  ...props,
340
+ // After the spread: a wrapper forwarding `id={undefined}` must not erase
341
+ // the id the resize handle's aria-controls points at.
342
+ id: navId,
336
343
  children: [hasStickyTop && /*#__PURE__*/_jsxs("div", {
337
344
  ...{
338
345
  0: {
@@ -415,7 +422,8 @@ export function SideNav({
415
422
  isAlwaysVisible: false,
416
423
  xstyle: styles.resizableHandle,
417
424
  resizable: resizableHook.props,
418
- label: t('@astryx.sideNav.resizeSidebar')
425
+ label: t('@astryx.sideNav.resizeSidebar'),
426
+ "aria-controls": navId
419
427
  })]
420
428
  }) : navElement;
421
429
  if (isCollapsible) {
@@ -1 +1 @@
1
- {"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../src/Slider/Slider.tsx"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAQhD,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAQ9C,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,mBAAmB,CAAC,cAAc,CAAC,EACnC,UAAU,CACX;IACC,mDAAmD;IACnD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAC3C,8DAA8D;IAC9D,KAAK,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,8CAA8C;IAC9C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC7C,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAChD,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAmT/D;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,EAAE,WAAW,+BAovBlD;yBApvBe,MAAM"}
1
+ {"version":3,"file":"Slider.d.ts","sourceRoot":"","sources":["../../src/Slider/Slider.tsx"],"names":[],"mappings":"AA0CA,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAQhD,OAAO,EACL,KAAK,mBAAmB,EAEzB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,gBAAgB,CAAC;AAQ9C,MAAM,WAAW,eAAgB,SAAQ,IAAI,CAC3C,mBAAmB,CAAC,cAAc,CAAC,EACnC,UAAU,CACX;IACC,mDAAmD;IACnD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAC;IACd,8FAA8F;IAC9F,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,kDAAkD;IAClD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qDAAqD;IACrD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB;;;;;;;;;;;;;;;;;;;OAmBG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,uCAAuC;IACvC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;OAIG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB,uEAAuE;IACvE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,gCAAgC;IAChC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,kCAAkC;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uDAAuD;IACvD,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC,uEAAuE;IACvE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,CAAC;IACxC,6DAA6D;IAC7D,YAAY,CAAC,EAAE,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAC3C,8DAA8D;IAC9D,KAAK,CAAC,EAAE;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAC1C;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,yCAAyC;IACzC,KAAK,EAAE,MAAM,CAAC;IACd,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,8CAA8C;IAC9C,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAC7C,iEAAiE;IACjE,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;IAChD,8CAA8C;IAC9C,qBAAqB,CAAC,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,MAAM,WAAW,GAAG,iBAAiB,GAAG,gBAAgB,CAAC;AAmT/D;;;;;;;;GAQG;AACH,wBAAgB,MAAM,CAAC,EAAC,GAAG,EAAE,GAAG,KAAK,EAAC,EAAE,WAAW,+BA2wBlD;yBA3wBe,MAAM"}
@@ -413,11 +413,14 @@ export function Slider({
413
413
  // Prefer the lower thumb if equidistant
414
414
  return d0 <= d1 ? 0 : 1;
415
415
  }, [isRange, values]);
416
- const updateValue = useCallback((thumbIndex, newVal) => {
416
+ const updateValue = useCallback((thumbIndex, newVal, snap = true) => {
417
417
  if (isDisabled) {
418
418
  return;
419
419
  }
420
- const clamped = clamp(snapToStep(newVal, min, step), min, max);
420
+ // Home and End pass the bound itself (`snap: false`). The step grid is
421
+ // anchored at `min`, so Home always landed there; `max` may lie off the
422
+ // grid (max 100 with step 3 snapped End to 99, not 100).
423
+ const clamped = clamp(snap ? snapToStep(newVal, min, step) : newVal, min, max);
421
424
  if (isRange) {
422
425
  const currentValues = [...values];
423
426
  currentValues[thumbIndex] = clamped;
@@ -514,12 +517,19 @@ export function Slider({
514
517
  }
515
518
  const currentVal = values[thumbIndex];
516
519
  let newVal;
520
+
521
+ // On a horizontal track the keyboard follows the track's direction:
522
+ // under RTL the value grows toward the left, so ArrowLeft increases and
523
+ // ArrowRight decreases (APG Slider). Up/Down and a vertical track are
524
+ // direction-free.
525
+ const towardMax = isHorizontal && isRtlElement(trackRef.current) ? 'ArrowLeft' : 'ArrowRight';
526
+ const towardMin = towardMax === 'ArrowLeft' ? 'ArrowRight' : 'ArrowLeft';
517
527
  switch (e.key) {
518
- case 'ArrowRight':
528
+ case towardMax:
519
529
  case 'ArrowUp':
520
530
  newVal = currentVal + step;
521
531
  break;
522
- case 'ArrowLeft':
532
+ case towardMin:
523
533
  case 'ArrowDown':
524
534
  newVal = currentVal - step;
525
535
  break;
@@ -539,8 +549,9 @@ export function Slider({
539
549
  return;
540
550
  }
541
551
  e.preventDefault();
542
- const clamped = clamp(snapToStep(newVal, min, step), min, max);
543
- updateValue(thumbIndex, newVal);
552
+ const toBound = e.key === 'Home' || e.key === 'End';
553
+ const clamped = clamp(toBound ? newVal : snapToStep(newVal, min, step), min, max);
554
+ updateValue(thumbIndex, newVal, !toBound);
544
555
 
545
556
  // Compute exact post-update values so onChangeEnd reports the correct
546
557
  // value even before React batches the state update.
@@ -559,7 +570,7 @@ export function Slider({
559
570
  } else {
560
571
  fireChangeEnd([clamped]);
561
572
  }
562
- }, [isDisabled, isRange, values, step, min, max, minStepsBetweenThumbs, updateValue, fireChangeEnd]);
573
+ }, [isDisabled, isHorizontal, isRange, values, step, min, max, minStepsBetweenThumbs, updateValue, fireChangeEnd]);
563
574
 
564
575
  // Format display value
565
576
  const displayValue = val => {
@@ -1 +1 @@
1
- {"version":3,"file":"Tokenizer.d.ts","sourceRoot":"","sources":["../../src/Tokenizer/Tokenizer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"Tokenizer.d.ts","sourceRoot":"","sources":["../../src/Tokenizer/Tokenizer.tsx"],"names":[],"mappings":"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"}
@@ -462,6 +462,15 @@ export function Tokenizer({
462
462
 
463
463
  // Filter out already-selected items from search results
464
464
  const selectedIds = useMemo(() => new Set(value.map(item => item.id)), [value]);
465
+
466
+ // Selected labels, lowercased, for the Create entry's duplicate check. The
467
+ // typed text is a label, not an id: real selections usually carry an opaque
468
+ // id (`usr_123` under the label "Alice"), so comparing the text against ids
469
+ // alone misses an already-tokenized label — and the search results cannot
470
+ // catch it either, because filteredSource has already removed the selected
471
+ // item from them. The result was a "Create Alice" entry that, when picked,
472
+ // added a second "Alice" token under a different id.
473
+ const selectedLabels = useMemo(() => new Set(value.map(item => item.label.toLowerCase())), [value]);
465
474
  const filteredSource = useMemo(() => ({
466
475
  search: async query => {
467
476
  const results = await searchSource.search(query);
@@ -486,7 +495,7 @@ export function Tokenizer({
486
495
  if (!hasCreate || trimmed === '') {
487
496
  return [];
488
497
  }
489
- const alreadyExists = selectedIds.has(trimmed) || results.some(item => item.label.toLowerCase() === trimmed.toLowerCase());
498
+ const alreadyExists = selectedIds.has(trimmed) || selectedLabels.has(trimmed.toLowerCase()) || results.some(item => item.label.toLowerCase() === trimmed.toLowerCase());
490
499
  if (alreadyExists) {
491
500
  return [];
492
501
  }
@@ -497,7 +506,7 @@ export function Tokenizer({
497
506
  __createdValue: trimmed
498
507
  }
499
508
  }];
500
- }, [hasCreate, selectedIds]);
509
+ }, [hasCreate, selectedIds, selectedLabels]);
501
510
  const emptySource = useMemo(() => ({
502
511
  search: async () => [],
503
512
  bootstrap: async () => []
@@ -521,7 +530,10 @@ export function Tokenizer({
521
530
  // Detect "Create: X" synthetic items from the creatable source
522
531
  if (hasCreate && typeof item.id === 'string' && item.id.startsWith(CREATABLE_ID_PREFIX)) {
523
532
  const createdValue = item.id.slice(CREATABLE_ID_PREFIX.length);
524
- if (selectedIds.has(createdValue)) {
533
+ // Same domain fix as createEntries: the created value names itself by
534
+ // label, so a selection carrying an opaque id with that label is also a
535
+ // duplicate, not just one whose id happens to equal the text.
536
+ if (selectedIds.has(createdValue) || selectedLabels.has(createdValue.toLowerCase())) {
525
537
  return;
526
538
  }
527
539
  const base = {
@@ -550,7 +562,7 @@ export function Tokenizer({
550
562
  announce(t('@astryx.tokenizer.tokenAdded', {
551
563
  label: item.label
552
564
  }));
553
- }, [value, onChange, isAtMax, selectedIds, hasCreate, announce, t]);
565
+ }, [value, onChange, isAtMax, selectedIds, selectedLabels, hasCreate, announce, t]);
554
566
 
555
567
  // Handle removing an item. Single removal path: both Backspace on an empty
556
568
  // input and the per-token remove buttons route through here, so the
@@ -2,7 +2,8 @@
2
2
  * @file Toolbar.tsx
3
3
  * @input Uses Section, SizeContext, useListFocus, useKeyboardHint, StyleX, spacingVars, sizeVars
4
4
  * @output Exports Toolbar component and ToolbarProps
5
- * @position Core implementation; consumed by index.ts
5
+ * @position Core implementation; consumed by index.ts. Owns toolbar focus and
6
+ * keyboard navigation, excluding nested toolbars and popover contents.
6
7
  *
7
8
  * SYNC: When modified, update these files to stay in sync:
8
9
  * - /packages/core/src/Toolbar/Toolbar.doc.mjs
@@ -1 +1 @@
1
- {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/Toolbar/Toolbar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAAc,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAC;AAwH5D,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC;AAEtC,MAAM,WAAW,YAAa,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC7D,gDAAgD;IAChD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;OAGG;IACH,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;CACnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,YAAY,EACZ,aAAa,EACb,UAAU,EACV,KAAK,EACL,IAAW,EACX,GAAO,EACP,WAA0B,EAC1B,OAAuB,EACvB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,KAAK,EACX,YAAY,EAAE,UAAU,EACxB,kBAAkB,EAAE,gBAAgB,EACpC,GAAG,KAAK,EACT,EAAE,YAAY,+BAsJd;yBA3Ke,OAAO"}
1
+ {"version":3,"file":"Toolbar.d.ts","sourceRoot":"","sources":["../../src/Toolbar/Toolbar.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAc,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAClD,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAC5C,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,oBAAoB,CAAC;AACvD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,gBAAgB,CAAC;AAChD,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,4BAA4B,CAAC;AAwH5D,MAAM,MAAM,WAAW,GAAG,WAAW,CAAC;AAEtC,MAAM,WAAW,YAAa,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC7D,gDAAgD;IAChD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAChC;;OAEG;IACH,YAAY,CAAC,EAAE,SAAS,CAAC;IACzB;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,CAAC;IAC1B;;OAEG;IACH,UAAU,CAAC,EAAE,SAAS,CAAC;IACvB;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IACd;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB;;;OAGG;IACH,GAAG,CAAC,EAAE,WAAW,CAAC;IAClB;;;;OAIG;IACH,WAAW,CAAC,EAAE,YAAY,GAAG,UAAU,CAAC;IACxC;;;OAGG;IACH,OAAO,CAAC,EAAE,cAAc,CAAC;IAEzB;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,CAAC,KAAK,GAAG,QAAQ,GAAG,OAAO,GAAG,KAAK,CAAC,EAAE,CAAC;CACnD;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,OAAO,CAAC,EACtB,YAAY,EACZ,aAAa,EACb,UAAU,EACV,KAAK,EACL,IAAW,EACX,GAAO,EACP,WAA0B,EAC1B,OAAuB,EACvB,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,WAAW,EACpB,MAAM,EAAE,UAAU,EAClB,IAAI,EAAE,KAAK,EACX,YAAY,EAAE,UAAU,EACxB,kBAAkB,EAAE,gBAAgB,EACpC,GAAG,KAAK,EACT,EAAE,YAAY,+BAuJd;yBA5Ke,OAAO"}
@@ -6,7 +6,8 @@
6
6
  * @file Toolbar.tsx
7
7
  * @input Uses Section, SizeContext, useListFocus, useKeyboardHint, StyleX, spacingVars, sizeVars
8
8
  * @output Exports Toolbar component and ToolbarProps
9
- * @position Core implementation; consumed by index.ts
9
+ * @position Core implementation; consumed by index.ts. Owns toolbar focus and
10
+ * keyboard navigation, excluding nested toolbars and popover contents.
10
11
  *
11
12
  * SYNC: When modified, update these files to stay in sync:
12
13
  * - /packages/core/src/Toolbar/Toolbar.doc.mjs
@@ -187,6 +188,7 @@ export function Toolbar({
187
188
  handleFocus
188
189
  } = useListFocus({
189
190
  itemSelector: 'button, input, [tabindex]',
191
+ boundarySelector: '[role="toolbar"], [popover]',
190
192
  orientation,
191
193
  hasRovingTabIndex: true,
192
194
  hasCaretGuard: true
@@ -1 +1 @@
1
- {"version":3,"file":"TreeList.d.ts","sourceRoot":"","sources":["../../src/TreeList/TreeList.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAwC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAI5E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EAAC,KAAK,eAAe,EAAE,KAAK,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAE3E,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;;OAGG;IACH,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAE1B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAE1B;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAE1B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmFD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,OAAoB,EACpB,OAAsB,EACtB,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,GAAG,EACH,SAAS,EAAE,aAAa,EACxB,GAAG,SAAS,EACb,EAAE,aAAa,+BA0Lf;yBAxMe,QAAQ"}
1
+ {"version":3,"file":"TreeList.d.ts","sourceRoot":"","sources":["../../src/TreeList/TreeList.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAwC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAI5E,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EACV,gBAAgB,EAChB,eAAe,EACf,eAAe,EAChB,MAAM,iBAAiB,CAAC;AAQzB,OAAO,EAAC,KAAK,eAAe,EAAE,KAAK,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAE3E,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,cAAc,CAAC;IAC9D,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IAEhC;;;OAGG;IACH,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAE1B;;;;;;OAMG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAE1B;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAE1B;;;OAGG;IACH,MAAM,CAAC,EAAE,SAAS,CAAC;IAEnB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAmFD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,QAAQ,CAAC,EACvB,KAAK,EACL,OAAoB,EACpB,OAAsB,EACtB,MAAM,EACN,MAAM,EACN,SAAS,EACT,KAAK,EACL,aAAa,EAAE,MAAM,EACrB,YAAY,EAAE,SAAS,EACvB,iBAAiB,EAAE,cAAc,EACjC,GAAG,EACH,SAAS,EAAE,aAAa,EACxB,GAAG,SAAS,EACb,EAAE,aAAa,+BA8Lf;yBA5Me,QAAQ"}
@@ -21,7 +21,7 @@ import { spacingVars } from "../theme/tokens.stylex.js";
21
21
  import { mergeProps } from "../utils/index.js";
22
22
  import { TreeListItem } from "./TreeListItem.js";
23
23
  import { themeProps } from "../utils/themeProps.js";
24
- import { useTreeFocus } from "../hooks/useTreeFocus.js";
24
+ import { useTreeFocusInternal } from "../hooks/useTreeFocus.js";
25
25
 
26
26
  // =============================================================================
27
27
  // Types
@@ -176,10 +176,13 @@ export function TreeList({
176
176
  treeRef,
177
177
  handleKeyDown,
178
178
  handleFocus
179
- } = useTreeFocus({
179
+ } = useTreeFocusInternal({
180
180
  onToggleExpand: handleToggle,
181
181
  onActivate: activateItem,
182
- hasRovingTabIndex: true
182
+ hasRovingTabIndex: true,
183
+ // Rows are named by their label (AR1); typeahead matches that label, not
184
+ // the chevron toggle, start content or description.
185
+ matchLabelledBy: true
183
186
  });
184
187
  const handleRootKeyDown = useCallback(e => {
185
188
  onKeyDownProp?.(e);
@@ -1 +1 @@
1
- {"version":3,"file":"TreeListItem.d.ts","sourceRoot":"","sources":["../../src/TreeList/TreeListItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAiB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAgB3C,OAAO,KAAK,EAAC,eAAe,EAAE,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAyPtE,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;;;;OAQG;IACH,kBAAkB,EAAE,OAAO,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB;;;;OAIG;IACH,OAAO,EAAE,eAAe,CAAC;IACzB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAMD,wBAAgB,YAAY,CAAC,EAC3B,EAAE,EACF,KAAK,EACL,WAAW,EACX,YAAY,EACZ,UAAU,EACV,MAAM,EACN,SAAS,EACT,KAAK,EACL,OAAO,EACP,IAAI,EACJ,MAAM,EACN,UAAkB,EAClB,UAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,MAAM,EACN,eAAe,EACf,UAAU,EACV,QAAQ,EACR,OAAO,EACP,OAAO,EACP,gBAAgB,EAChB,QAAQ,EACR,OAAO,EACP,UAAU,GACX,EAAE,yBAAyB,+BAuQ3B;yBAlSe,YAAY"}
1
+ {"version":3,"file":"TreeListItem.d.ts","sourceRoot":"","sources":["../../src/TreeList/TreeListItem.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AAEH,OAAO,EAAiB,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AACrD,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAgB3C,OAAO,KAAK,EAAC,eAAe,EAAE,eAAe,EAAC,MAAM,iBAAiB,CAAC;AAyPtE,MAAM,WAAW,yBAAyB;IACxC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,KAAK,CAAC,SAAS,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC/B,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC7B,OAAO,CAAC,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IACxC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,mEAAmE;IACnE,MAAM,CAAC,EAAE,MAAM,CAAC,YAAY,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAC;IAC5B,WAAW,EAAE,OAAO,CAAC;IACrB;;;;;;;;OAQG;IACH,kBAAkB,EAAE,OAAO,CAAC;IAC5B,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,OAAO,CAAC;IAChB,eAAe,EAAE,aAAa,CAAC,OAAO,CAAC,CAAC;IACxC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,OAAO,EAAE,eAAe,CAAC;IACzB;;;;OAIG;IACH,OAAO,EAAE,eAAe,CAAC;IACzB,uEAAuE;IACvE,gBAAgB,CAAC,EAAE,SAAS,CAAC;IAC7B,wEAAwE;IACxE,QAAQ,EAAE,MAAM,CAAC;IACjB,uDAAuD;IACvD,OAAO,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;CACrB;AAMD,wBAAgB,YAAY,CAAC,EAC3B,EAAE,EACF,KAAK,EACL,WAAW,EACX,YAAY,EACZ,UAAU,EACV,MAAM,EACN,SAAS,EACT,KAAK,EACL,OAAO,EACP,IAAI,EACJ,MAAM,EACN,UAAkB,EAClB,UAAkB,EAClB,WAAW,EACX,kBAAkB,EAClB,WAAW,EACX,MAAM,EACN,eAAe,EACf,UAAU,EACV,QAAQ,EACR,OAAO,EACP,OAAO,EACP,gBAAgB,EAChB,QAAQ,EACR,OAAO,EACP,UAAU,GACX,EAAE,yBAAyB,+BA4Q3B;yBAvSe,YAAY"}
@@ -348,7 +348,13 @@ export function TreeListItem({
348
348
  })]
349
349
  });
350
350
  return /*#__PURE__*/_jsxs("li", {
351
- role: "treeitem",
351
+ role: "treeitem"
352
+ // The row is named by its label alone and described by its description
353
+ // (APG tree view): without these the name would be the row's whole text,
354
+ // chevron button label and description included.
355
+ ,
356
+ "aria-labelledby": labelId,
357
+ "aria-describedby": description != null ? descriptionId : undefined,
352
358
  "aria-expanded": hasChildren ? isExpanded : undefined,
353
359
  "aria-selected": isSelected || undefined,
354
360
  "aria-disabled": isDisabled || undefined,
package/dist/astryx.css CHANGED
@@ -1,6 +1,8 @@
1
1
  /* Astryx Pre-compiled StyleX CSS — all components */
2
2
  /* Auto-generated. Do not edit manually. */
3
3
 
4
+ @layer reset, astryx-base, astryx-theme;
5
+
4
6
  @layer astryx-base {
5
7
  @property --x---_avatar-group-overlap { syntax: "*"; inherits: false;}
6
8
  @property --x---_codeblock-gutter-width { syntax: "*"; inherits: false;}
@@ -772,7 +774,10 @@
772
774
  .xprdx6m:not(#\#):not(#\#):not(#\#){background-color:var(--color-skeleton)}
773
775
  .xu13z74:not(#\#):not(#\#):not(#\#){background-color:var(--color-success-muted)}
774
776
  .xdsz4j9:not(#\#):not(#\#):not(#\#){background-color:var(--color-success)}
777
+ .xjqijk9:not(#\#):not(#\#):not(#\#){background-color:var(--color-syntax-added)}
775
778
  .xzyc27v:not(#\#):not(#\#):not(#\#){background-color:var(--color-syntax-background)}
779
+ .x11ds9ch:not(#\#):not(#\#):not(#\#){background-color:var(--color-syntax-diff-header)}
780
+ .xv48ua2:not(#\#):not(#\#):not(#\#){background-color:var(--color-syntax-removed)}
776
781
  .x16fr6go:not(#\#):not(#\#):not(#\#){background-color:var(--color-text-disabled)}
777
782
  .x19aspcf:not(#\#):not(#\#):not(#\#){background-color:var(--color-text-primary)}
778
783
  .xdomwnj:not(#\#):not(#\#):not(#\#){background-color:var(--color-text-secondary)}
@@ -877,7 +882,10 @@
877
882
  .xri61p4:not(#\#):not(#\#):not(#\#){color:var(--color-on-success)}
878
883
  .xrebv38:not(#\#):not(#\#):not(#\#){color:var(--color-on-warning)}
879
884
  .xtjic6:not(#\#):not(#\#):not(#\#){color:var(--color-success)}
885
+ .x1wxerb0:not(#\#):not(#\#):not(#\#){color:var(--color-syntax-added-marker)}
880
886
  .x1mjzq1q:not(#\#):not(#\#):not(#\#){color:var(--color-syntax-comment)}
887
+ .xt5rlkq:not(#\#):not(#\#):not(#\#){color:var(--color-syntax-punctuation)}
888
+ .x103bwea:not(#\#):not(#\#):not(#\#){color:var(--color-syntax-removed-marker)}
881
889
  .xdfisg:not(#\#):not(#\#):not(#\#){color:var(--color-syntax-variable)}
882
890
  .xjse4m1:not(#\#):not(#\#):not(#\#){color:var(--color-text-accent)}
883
891
  .x1vvqiwl:not(#\#):not(#\#):not(#\#){color:var(--color-text-blue)}
@@ -895,6 +903,7 @@
895
903
  .xdhq94a:not(#\#):not(#\#):not(#\#){color:var(--color-text-yellow)}
896
904
  .xs3pv69:not(#\#):not(#\#):not(#\#){color:var(--color-warning)}
897
905
  .x14rh7hd:not(#\#):not(#\#):not(#\#){color:var(--x-color)}
906
+ .x1o1pmfc:not(#\#):not(#\#):not(#\#){column-gap:0}
898
907
  .xf5zn4v:not(#\#):not(#\#):not(#\#){column-gap:calc(var(--spacing-3) + var(--border-width) + var(--spacing-4))}
899
908
  .x1kihgfc:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-0-5)}
900
909
  .x1o57wo1:not(#\#):not(#\#):not(#\#){column-gap:var(--spacing-0)}
@@ -1023,6 +1032,7 @@
1023
1032
  .xhij9v2:not(#\#):not(#\#):not(#\#){grid-auto-rows:var(--x-gridAutoRows)}
1024
1033
  .xcrlgei:not(#\#):not(#\#):not(#\#){grid-column-start:1}
1025
1034
  .x1agbcgv:not(#\#):not(#\#):not(#\#){grid-row-start:1}
1035
+ .xrnahuw:not(#\#):not(#\#):not(#\#){grid-template-columns:1ch 1fr}
1026
1036
  .x134kloy:not(#\#):not(#\#):not(#\#){grid-template-columns:1fr auto 1fr}
1027
1037
  .x52fmzj:not(#\#):not(#\#):not(#\#){grid-template-columns:1fr auto}
1028
1038
  .x1y6fwsi:not(#\#):not(#\#):not(#\#){grid-template-columns:1fr}
@@ -1033,6 +1043,7 @@
1033
1043
  .x1mzazjb:not(#\#):not(#\#):not(#\#){grid-template-columns:repeat(7,1fr)}
1034
1044
  .x189bvgu:not(#\#):not(#\#):not(#\#){grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}
1035
1045
  .x1xx4m37:not(#\#):not(#\#):not(#\#){grid-template-columns:var(--_codeblock-gutter-width) 1fr}
1046
+ .x1v9b7p9:not(#\#):not(#\#):not(#\#){grid-template-columns:var(--_codeblock-gutter-width) auto 1fr}
1036
1047
  .xqketvx:not(#\#):not(#\#):not(#\#){grid-template-columns:var(--x-gridTemplateColumns)}
1037
1048
  .xihq33y:not(#\#):not(#\#):not(#\#){grid-template-rows:0fr}
1038
1049
  .x1tu4anv:not(#\#):not(#\#):not(#\#){grid-template-rows:1fr}
@@ -1121,6 +1132,7 @@
1121
1132
  .xs69w1r:not(#\#):not(#\#):not(#\#){margin-inline-start:calc((40px - min(var(--spacing-6),40px)) / 2 - var(--spacing-3))}
1122
1133
  .x1idpjx9:not(#\#):not(#\#):not(#\#){margin-inline-start:calc((40px - min(var(--spacing-6),40px)) / 2 - var(--spacing-4))}
1123
1134
  .x1xrm450:not(#\#):not(#\#):not(#\#){margin-inline-start:calc(var(--spacing-2) - var(--spacing-1) + 1px)}
1135
+ .x6w1cxl:not(#\#):not(#\#):not(#\#){margin-inline-start:calc(var(--spacing-3) + var(--border-width) + var(--spacing-4))}
1124
1136
  .x13hpdyo:not(#\#):not(#\#):not(#\#){margin-inline-start:var(--_avatar-group-overlap)}
1125
1137
  .x12vn87o:not(#\#):not(#\#):not(#\#){margin-inline-start:var(--_tree-indent,0px)}
1126
1138
  .xladpz9:not(#\#):not(#\#):not(#\#){margin-inline-start:var(--spacing-0-5)}
@@ -1443,9 +1455,13 @@
1443
1455
  .x1vxsm5i:is([dir="rtl"] *):not(#\#):not(#\#):not(#\#){animation-name:xu7jd1z-B}
1444
1456
  .x18lne9g:is([dir="rtl"] *):not(#\#):not(#\#):not(#\#){animation-name:xwmkjkf-B}
1445
1457
  .x1spg45b.x1spg45b:hover:where(:not(:disabled,[aria-disabled="true"])):not(#\#):not(#\#):not(#\#){background-color:var(--color-accent)}
1458
+ .x1tgb0ru.x1tgb0ru:where(.astryx-input-group > *):has(~ *:not([popover]):not(template):not(dialog)):not(#\#):not(#\#):not(#\#){border-end-end-radius:0}
1446
1459
  .x1ursds5:not(:has(~ *:not([popover]):not(template):not(dialog))):not(#\#):not(#\#):not(#\#){border-end-end-radius:var(--radius-element)}
1460
+ .xf2wquc.xf2wquc:where(.astryx-input-group > *):not(:first-child):not(#\#):not(#\#):not(#\#){border-end-start-radius:0}
1447
1461
  .xy2bsav:not(:has(~ *:not([popover]):not(template):not(dialog))):not(#\#):not(#\#):not(#\#){border-end-start-radius:var(--radius-element)}
1462
+ .x2dar1b.x2dar1b:where(.astryx-input-group > *):has(~ *:not([popover]):not(template):not(dialog)):not(#\#):not(#\#):not(#\#){border-start-end-radius:0}
1448
1463
  .x149bkfe:not(:has(~ *:not([popover]):not(template):not(dialog))):not(#\#):not(#\#):not(#\#){border-start-end-radius:var(--radius-element)}
1464
+ .x1epqg88.x1epqg88:where(.astryx-input-group > *):not(:first-child):not(#\#):not(#\#):not(#\#){border-start-start-radius:0}
1449
1465
  .xuihb5h:focus-within:not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px var(--color-accent-muted)}
1450
1466
  .x15ysqaf:focus-within:not(#\#):not(#\#):not(#\#){box-shadow:none}
1451
1467
  .xyavpck:focus-within:not(#\#):not(#\#):not(#\#){box-shadow:var(--shadow-med)}
@@ -1497,6 +1513,7 @@
1497
1513
  .x9cjr8z:popover-open:not(#\#):not(#\#):not(#\#){transform:translateY(0)}
1498
1514
  .x75qhwu:is([dir="rtl"] *):not(#\#):not(#\#):not(#\#){transform:var(--x-sj6hyi)}
1499
1515
  .x1rm9qnc:focus-within:not(#\#):not(#\#):not(#\#){z-index:1}
1516
+ .x1qf1n5z.x1qf1n5z:where(.astryx-input-group > *):focus-visible:not(#\#):not(#\#):not(#\#){z-index:2}
1500
1517
  .x1s2lk0z.x1s2lk0z:where(:not(:disabled,[aria-disabled="true"]))[data-astryx-press="fading"]:not(#\#):not(#\#):not(#\#){--_press-overlay:var(--_press-paint)}
1501
1518
  .x1sad4of.x1sad4of:where(:not(:disabled,[aria-disabled="true"]))[data-astryx-press="on"]:not(#\#):not(#\#):not(#\#){--_press-overlay:var(--_press-paint)}
1502
1519
  .x1btxeh5:has(input:focus-visible):not(#\#):not(#\#):not(#\#){box-shadow:inset 0 0 0 2px var(--color-accent)}
@@ -1547,6 +1564,7 @@
1547
1564
  .xuqm82a:active:not(#\#):not(#\#):not(#\#){background-image:none}
1548
1565
  .x1pdlv7q:active:not(#\#):not(#\#):not(#\#){transform:none}
1549
1566
  .xk4oym4:active:not(#\#):not(#\#):not(#\#){transform:scale(.98)}
1567
+ @media (max-width: 480px){.x1q32nj3.x1q32nj3:not(#\#):not(#\#):not(#\#){align-items:stretch}}
1550
1568
  @media (prefers-reduced-motion: reduce){.x14q22ui.x14q22ui:not(#\#):not(#\#):not(#\#){animation-delay:0s}}
1551
1569
  @media (prefers-reduced-motion: reduce){.xnh0sag.xnh0sag:not(#\#):not(#\#):not(#\#){animation-duration:3s}}
1552
1570
  @media (prefers-reduced-motion: reduce){.x1aquc0h.x1aquc0h:not(#\#):not(#\#):not(#\#){animation-name:none}}
@@ -1844,6 +1862,7 @@
1844
1862
  .x15x72sd:not(#\#):not(#\#):not(#\#):not(#\#){min-width:auto}
1845
1863
  .x8wyhu6:not(#\#):not(#\#):not(#\#):not(#\#){min-width:calc(anchor-size(width) + 16px)}
1846
1864
  .x1pshirs:not(#\#):not(#\#):not(#\#):not(#\#){min-width:fit-content}
1865
+ .xk8lq53:not(#\#):not(#\#):not(#\#):not(#\#){min-width:max-content}
1847
1866
  .xg3bzn3:not(#\#):not(#\#):not(#\#):not(#\#){min-width:min(400px,calc(100vw - var(--spacing-4) - var(--spacing-4) - var(--astryx-layer-inset-inline-start, 0px) - var(--astryx-layer-inset-inline-end, 0px)));min-width:min(400px,calc(100vi - calc(max(var(--spacing-4), env(safe-area-inset-left, 0px)) + var(--astryx-layer-inset-inline-start, 0px)) - calc(max(var(--spacing-4), env(safe-area-inset-right, 0px)) + var(--astryx-layer-inset-inline-end, 0px))))}
1848
1867
  .x17ydmr0:not(#\#):not(#\#):not(#\#):not(#\#){min-width:var(--size-element-md)}
1849
1868
  .x1nkkqge:not(#\#):not(#\#):not(#\#):not(#\#){min-width:var(--size-element-sm)}
@@ -1987,6 +2006,7 @@
1987
2006
  .x1uyokj7:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--x-inlineSize)}
1988
2007
  .x5lhr3w:not(#\#):not(#\#):not(#\#):not(#\#){width:var(--x-width)}
1989
2008
  .x1wp2rvj.x1wp2rvj:where(.x139im0d:last-child *):not(#\#):not(#\#):not(#\#):not(#\#){border-bottom-width:0}
2009
+ .x1vonza8.x1vonza8:where(.astryx-input-group > *):not(#\#):not(#\#):not(#\#):not(#\#){height:100%}
1990
2010
  .x132qfvm:focus-within:not(#\#):not(#\#):not(#\#):not(#\#){height:auto}
1991
2011
  .xsg11nj.xsg11nj:where(.x-default-marker:has(> .astryx-layout-footer:not([data-divider])) *):not(#\#):not(#\#):not(#\#):not(#\#){padding-bottom:0}
1992
2012
  .x1ioh5az.x1ioh5az:where(.x-default-marker:has(> .astryx-layout-header:not([data-divider])) *):not(#\#):not(#\#):not(#\#):not(#\#){padding-top:0}
@@ -2082,7 +2102,9 @@
2082
2102
  .xnnzo76:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{border-inline-start-color:var(--color-border)}
2083
2103
  .xvsnedh:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{border-inline-start-style:solid}
2084
2104
  .x1p96cux:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::after{border-inline-start-width:var(--border-width)}
2105
+ .x147exv5:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{color:var(--color-syntax-added-marker)}
2085
2106
  .xtkarl4:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{color:var(--color-syntax-punctuation)}
2107
+ .x16hy5kr:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{color:var(--color-syntax-removed-marker)}
2086
2108
  .xnf3u0:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::placeholder{color:var(--color-text-disabled)}
2087
2109
  .xeyghm5:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::placeholder{color:var(--color-text-secondary)}
2088
2110
  .x1cpjm7i:not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#):not(#\#)::before{content:""}
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollOverflow.d.ts","sourceRoot":"","sources":["../../src/hooks/useScrollOverflow.ts"],"names":[],"mappings":"AAoBA,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,aAAa,EAAE,OAAO,CAAC;IACvB,4DAA4D;IAC5D,WAAW,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,WAAW,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB;IApB/B,8DAA8D;mBAC/C,OAAO;IACtB,4DAA4D;iBAC/C,OAAO;IACpB,oDAAoD;iBACvC,OAAO;oBAoDb,WAAW,GAAG,IAAI;EA+B1B"}
1
+ {"version":3,"file":"useScrollOverflow.d.ts","sourceRoot":"","sources":["../../src/hooks/useScrollOverflow.ts"],"names":[],"mappings":"AAgCA,MAAM,WAAW,mBAAmB;IAClC,8DAA8D;IAC9D,aAAa,EAAE,OAAO,CAAC;IACvB,4DAA4D;IAC5D,WAAW,EAAE,OAAO,CAAC;IACrB,oDAAoD;IACpD,WAAW,EAAE,OAAO,CAAC;CACtB;AAeD;;;;;;;;;;;GAWG;AACH,wBAAgB,iBAAiB;IAjC/B,8DAA8D;mBAC/C,OAAO;IACtB,4DAA4D;iBAC/C,OAAO;IACpB,oDAAoD;iBACvC,OAAO;oBAkFb,WAAW,GAAG,IAAI;EA+B1B"}
@@ -6,16 +6,41 @@
6
6
  * @file useScrollOverflow.ts
7
7
  * @input Uses React useRef, useState, useCallback, useEffect
8
8
  * @output Exports useScrollOverflow hook for tracking scroll position edges
9
- * @position Core hook; used by Carousel for fade-edge and button state
9
+ * @position Core hook; used by Carousel and TabList for fade-edge and button
10
+ * state
10
11
  *
11
12
  * Observes a scroll container and reports whether content overflows at the
12
- * start, end, or both edges. Updates on scroll and resize.
13
+ * start, end, or both edges. Updates on every scroll, and on a resize while
14
+ * the container is rendered: a layout read on an element the browser is not
15
+ * rendering (an ancestor with `display: none`, or a `content-visibility:
16
+ * hidden` subtree) either answers zeros or makes the browser lay out that
17
+ * whole hidden subtree for the answer, so a resize observation delivered for
18
+ * a hidden container, and the measurement at registration inside one, are
19
+ * skipped; the hook keeps its last state until the resize observation that
20
+ * follows the reveal (one frame after it paints). A scroll is measured
21
+ * whether or not the container is rendered: a scroll of a hidden container
22
+ * is script's (a selected tab revealed under a hidden panel), its layout is
23
+ * already the scroll's, and a reveal at the same size brings no resize to
24
+ * measure it with.
13
25
  *
14
26
  * SYNC: When modified, update:
15
27
  * - /packages/core/src/hooks/index.ts
16
28
  */
17
29
  import { useState, useCallback, useEffect, useRef } from 'react';
18
30
  import { observeResize } from "../utils/sharedResizeObserver.js";
31
+ /**
32
+ * Whether the browser is rendering `el`, so a layout read on it answers for a
33
+ * real box. `checkVisibility()` is false under a `display: none` ancestor and
34
+ * inside a `content-visibility: hidden` subtree, and it answers without
35
+ * rendering that subtree. Not `contentVisibilityAuto`: a freshly inserted,
36
+ * on-screen `content-visibility: auto` section counts as skipped until the
37
+ * next rendering update, and a strip mounted into one would paint its first
38
+ * frame unmeasured. A browser without `checkVisibility` measures as before.
39
+ */
40
+ function isRendered(el) {
41
+ return typeof el.checkVisibility !== 'function' || el.checkVisibility();
42
+ }
43
+
19
44
  /**
20
45
  * Tracks scroll overflow state for a horizontally scrollable container.
21
46
  *
@@ -36,11 +61,7 @@ export function useScrollOverflow() {
36
61
  overflowEnd: false,
37
62
  hasOverflow: false
38
63
  });
39
- const measure = useCallback(() => {
40
- const el = elRef.current;
41
- if (!el) {
42
- return;
43
- }
64
+ const measureNow = useCallback(el => {
44
65
  const tolerance = 1;
45
66
  const {
46
67
  scrollLeft,
@@ -62,29 +83,51 @@ export function useScrollOverflow() {
62
83
  };
63
84
  });
64
85
  }, []);
86
+
87
+ // Registration and resize: only a rendered container. A hidden one has no
88
+ // edges to report, and reading its layout would make the browser render
89
+ // the hidden subtree it sits in; the resize observation that follows the
90
+ // reveal measures again.
91
+ const measure = useCallback(() => {
92
+ const el = elRef.current;
93
+ if (el && isRendered(el)) {
94
+ measureNow(el);
95
+ }
96
+ }, [measureNow]);
97
+
98
+ // A scroll: measured hidden or not. Script scrolled the hidden container
99
+ // (its layout is already the scroll's), and a reveal at the same size
100
+ // brings no resize observation, so this is the read that keeps the edges
101
+ // right for it.
102
+ const measureOnScroll = useCallback(() => {
103
+ const el = elRef.current;
104
+ if (el) {
105
+ measureNow(el);
106
+ }
107
+ }, [measureNow]);
65
108
  const scrollRef = useCallback(el => {
66
109
  if (elRef.current) {
67
110
  unobserveRef.current?.();
68
111
  unobserveRef.current = null;
69
- elRef.current.removeEventListener('scroll', measure);
112
+ elRef.current.removeEventListener('scroll', measureOnScroll);
70
113
  }
71
114
  elRef.current = el;
72
115
  if (el) {
73
- el.addEventListener('scroll', measure, {
116
+ el.addEventListener('scroll', measureOnScroll, {
74
117
  passive: true
75
118
  });
76
119
  unobserveRef.current = observeResize(el, measure);
77
120
  }
78
- }, [measure]);
121
+ }, [measure, measureOnScroll]);
79
122
  useEffect(() => {
80
123
  return () => {
81
124
  if (elRef.current) {
82
125
  unobserveRef.current?.();
83
126
  unobserveRef.current = null;
84
- elRef.current.removeEventListener('scroll', measure);
127
+ elRef.current.removeEventListener('scroll', measureOnScroll);
85
128
  }
86
129
  };
87
- }, [measure]);
130
+ }, [measureOnScroll]);
88
131
  return {
89
132
  scrollRef,
90
133
  ...state