@astryxdesign/core 0.6.2 → 0.6.3-canary.0949cb1

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 (384) hide show
  1. package/CHANGELOG.md +81 -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/ChatComposer.d.ts.map +1 -1
  9. package/dist/Chat/ChatComposer.js +10 -5
  10. package/dist/Chat/ChatComposerDrawer.d.ts +19 -5
  11. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  12. package/dist/Chat/ChatComposerDrawer.js +48 -23
  13. package/dist/Chat/ChatComposerInput.d.ts +11 -3
  14. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  15. package/dist/Chat/ChatComposerInput.js +63 -16
  16. package/dist/Chat/ChatDictationButton.d.ts +3 -2
  17. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  18. package/dist/Chat/ChatDictationButton.js +6 -4
  19. package/dist/Chat/ChatSendButton.js +1 -1
  20. package/dist/Chat/index.d.ts +1 -1
  21. package/dist/Chat/index.d.ts.map +1 -1
  22. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  23. package/dist/CheckboxInput/CheckboxInput.js +12 -2
  24. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  25. package/dist/Collapsible/Collapsible.js +6 -1
  26. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  27. package/dist/CommandPalette/CommandPaletteInput.js +1 -1
  28. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  29. package/dist/ComplexSelector/ComplexSelector.js +1 -1
  30. package/dist/DateInput/DateInput.d.ts.map +1 -1
  31. package/dist/DateInput/DateInput.js +4 -4
  32. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  33. package/dist/DateInput/NativeDateField.js +16 -16
  34. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  35. package/dist/DateInput/TouchDateField.js +2 -2
  36. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  37. package/dist/DateRangeInput/DateRangeInput.js +4 -4
  38. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  39. package/dist/DateTimeInput/DateTimeInput.js +8 -8
  40. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  41. package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
  42. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
  43. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
  44. package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
  45. package/dist/Dialog/DialogHeader.d.ts +8 -1
  46. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  47. package/dist/Dialog/DialogHeader.js +10 -1
  48. package/dist/Field/InputClearButton.d.ts +4 -2
  49. package/dist/Field/InputClearButton.d.ts.map +1 -1
  50. package/dist/Field/InputClearButton.js +4 -2
  51. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  52. package/dist/Field/PanelSearchInput.js +1 -1
  53. package/dist/FileInput/FileInput.d.ts.map +1 -1
  54. package/dist/FileInput/FileInput.js +7 -7
  55. package/dist/Kbd/Kbd.d.ts +5 -3
  56. package/dist/Kbd/Kbd.d.ts.map +1 -1
  57. package/dist/Kbd/Kbd.js +36 -42
  58. package/dist/Link/Link.d.ts.map +1 -1
  59. package/dist/Link/Link.js +6 -2
  60. package/dist/Markdown/Markdown.d.ts +8 -2
  61. package/dist/Markdown/Markdown.d.ts.map +1 -1
  62. package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
  63. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
  64. package/dist/Markdown/Markdown.fr23.bench.js +150 -0
  65. package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
  66. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
  67. package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
  68. package/dist/Markdown/Markdown.js +262 -109
  69. package/dist/Markdown/ast.d.ts +162 -0
  70. package/dist/Markdown/ast.d.ts.map +1 -0
  71. package/dist/Markdown/ast.js +74 -0
  72. package/dist/Markdown/index.d.ts +5 -3
  73. package/dist/Markdown/index.d.ts.map +1 -1
  74. package/dist/Markdown/index.js +3 -2
  75. package/dist/Markdown/parser/index.d.ts +10 -0
  76. package/dist/Markdown/parser/index.d.ts.map +1 -0
  77. package/dist/Markdown/parser/index.js +10 -0
  78. package/dist/Markdown/parser.d.ts +126 -58
  79. package/dist/Markdown/parser.d.ts.map +1 -1
  80. package/dist/Markdown/parser.js +716 -167
  81. package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
  82. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
  83. package/dist/Markdown/plugins/frontmatter.js +132 -0
  84. package/dist/Markdown/plugins/index.d.ts +16 -0
  85. package/dist/Markdown/plugins/index.d.ts.map +1 -0
  86. package/dist/Markdown/plugins/index.js +13 -0
  87. package/dist/Markdown/plugins/protocol.d.ts +191 -0
  88. package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
  89. package/dist/Markdown/plugins/protocol.js +957 -0
  90. package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
  91. package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
  92. package/dist/Markdown/plugins/semanticFence.js +213 -0
  93. package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
  94. package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
  95. package/dist/Markdown/plugins/sourceDecoration.js +393 -0
  96. package/dist/Markdown/plugins/textTransform.d.ts +30 -0
  97. package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
  98. package/dist/Markdown/plugins/textTransform.js +374 -0
  99. package/dist/Markdown/remark.d.ts +196 -0
  100. package/dist/Markdown/remark.d.ts.map +1 -0
  101. package/dist/Markdown/remark.js +1062 -0
  102. package/dist/Markdown/url.d.ts +4 -0
  103. package/dist/Markdown/url.d.ts.map +1 -0
  104. package/dist/Markdown/url.js +25 -0
  105. package/dist/Markdown/utils.d.ts +4 -2
  106. package/dist/Markdown/utils.d.ts.map +1 -1
  107. package/dist/Markdown/utils.js +2 -1
  108. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  109. package/dist/NumberInput/NumberInput.js +4 -4
  110. package/dist/Outline/index.d.ts +1 -0
  111. package/dist/Outline/index.d.ts.map +1 -1
  112. package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
  113. package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
  114. package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
  115. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
  116. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  117. package/dist/Outline/useOutlineFromMarkdown.js +8 -3
  118. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  119. package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
  120. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  121. package/dist/ProgressBar/ProgressBar.js +36 -31
  122. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  123. package/dist/RadioList/RadioListItem.js +13 -1
  124. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  125. package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
  126. package/dist/Selector/Selector.d.ts +9 -7
  127. package/dist/Selector/Selector.d.ts.map +1 -1
  128. package/dist/Selector/Selector.js +7 -5
  129. package/dist/SideNav/SideNav.d.ts +2 -1
  130. package/dist/SideNav/SideNav.d.ts.map +1 -1
  131. package/dist/SideNav/SideNav.js +9 -3
  132. package/dist/Slider/Slider.d.ts.map +1 -1
  133. package/dist/Slider/Slider.js +28 -12
  134. package/dist/Spinner/Spinner.d.ts.map +1 -1
  135. package/dist/Spinner/Spinner.js +23 -7
  136. package/dist/Switch/Switch.d.ts.map +1 -1
  137. package/dist/Switch/Switch.js +11 -0
  138. package/dist/TabList/Tab.d.ts +1 -1
  139. package/dist/TabList/Tab.d.ts.map +1 -1
  140. package/dist/TabList/Tab.js +20 -7
  141. package/dist/Table/Table.d.ts +1 -0
  142. package/dist/Table/Table.d.ts.map +1 -1
  143. package/dist/Table/Table.js +29 -13
  144. package/dist/TextArea/TextArea.d.ts.map +1 -1
  145. package/dist/TextArea/TextArea.js +1 -1
  146. package/dist/TextInput/TextInput.d.ts.map +1 -1
  147. package/dist/TextInput/TextInput.js +2 -2
  148. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  149. package/dist/TimeInput/TimeInput.js +4 -4
  150. package/dist/ToggleButton/ToggleButton.d.ts +9 -6
  151. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  152. package/dist/ToggleButton/ToggleButton.js +15 -27
  153. package/dist/TreeList/TreeList.d.ts.map +1 -1
  154. package/dist/TreeList/TreeList.js +3 -0
  155. package/dist/TreeList/TreeListItem.d.ts +6 -1
  156. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  157. package/dist/TreeList/TreeListItem.js +12 -2
  158. package/dist/TreeList/TreeListTypes.d.ts +8 -1
  159. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  160. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  161. package/dist/Typeahead/BaseTypeahead.js +16 -7
  162. package/dist/astryx.css +18 -7
  163. package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
  164. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
  165. package/dist/hooks/scrollKeyboardDelegation.js +146 -0
  166. package/dist/hooks/useScrollableArea.d.ts +6 -2
  167. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  168. package/dist/hooks/useScrollableArea.js +17 -5
  169. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  170. package/dist/theme/generateThemeRules.js +10 -0
  171. package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
  172. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  173. package/dist/utils/interactionOverlay.stylex.js +9 -0
  174. package/locales/af-ZA.json +530 -1
  175. package/locales/ar-SA.json +490 -1
  176. package/locales/ca-ES.json +514 -1
  177. package/locales/cs-CZ.json +498 -1
  178. package/locales/da-DK.json +522 -1
  179. package/locales/de-DE.json +522 -1
  180. package/locales/el-GR.json +498 -1
  181. package/locales/es-ES.json +510 -1
  182. package/locales/fi-FI.json +498 -1
  183. package/locales/fr-FR.json +534 -1
  184. package/locales/he-IL.json +498 -1
  185. package/locales/hu-HU.json +498 -1
  186. package/locales/it-IT.json +510 -1
  187. package/locales/ja-JP.json +490 -1
  188. package/locales/ko-KR.json +498 -1
  189. package/locales/nl-NL.json +534 -1
  190. package/locales/no-NO.json +510 -1
  191. package/locales/pl-PL.json +506 -1
  192. package/locales/pt-BR.json +506 -1
  193. package/locales/pt-PT.json +506 -1
  194. package/locales/ro-RO.json +506 -1
  195. package/locales/ru-RU.json +498 -1
  196. package/locales/sr-SP.json +498 -1
  197. package/locales/sv-SE.json +502 -1
  198. package/locales/tr-TR.json +498 -1
  199. package/locales/uk-UA.json +498 -1
  200. package/locales/vi-VN.json +502 -1
  201. package/locales/zh-CN.json +490 -1
  202. package/locales/zh-TW.json +490 -1
  203. package/package.json +19 -4
  204. package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
  205. package/src/BottomSheet/BottomSheet.spec.md +46 -20
  206. package/src/BottomSheet/BottomSheet.test.tsx +6 -3
  207. package/src/BottomSheet/BottomSheet.tsx +3 -1
  208. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
  209. package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
  210. package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
  211. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
  212. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
  213. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
  214. package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
  215. package/src/Button/__tests__/Button.a11y.states.ts +9 -0
  216. package/src/Chat/ChatComposer.doc.mjs +14 -0
  217. package/src/Chat/ChatComposer.spec.md +230 -0
  218. package/src/Chat/ChatComposer.test.tsx +57 -0
  219. package/src/Chat/ChatComposer.tsx +21 -9
  220. package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
  221. package/src/Chat/ChatComposerDrawer.spec.md +267 -0
  222. package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
  223. package/src/Chat/ChatComposerDrawer.tsx +38 -9
  224. package/src/Chat/ChatComposerInput.doc.mjs +114 -26
  225. package/src/Chat/ChatComposerInput.spec.md +185 -0
  226. package/src/Chat/ChatComposerInput.test.tsx +113 -3
  227. package/src/Chat/ChatComposerInput.tsx +78 -13
  228. package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
  229. package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
  230. package/src/Chat/ChatDictationButton.doc.mjs +3 -3
  231. package/src/Chat/ChatDictationButton.spec.md +160 -0
  232. package/src/Chat/ChatDictationButton.test.tsx +92 -27
  233. package/src/Chat/ChatDictationButton.tsx +8 -6
  234. package/src/Chat/ChatSendButton.test.tsx +1 -4
  235. package/src/Chat/ChatSendButton.tsx +1 -1
  236. package/src/Chat/index.ts +1 -0
  237. package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
  238. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  239. package/src/CheckboxInput/CheckboxInput.tsx +21 -1
  240. package/src/ClickableCard/ClickableCard.test.tsx +102 -5
  241. package/src/Collapsible/Collapsible.doc.mjs +11 -0
  242. package/src/Collapsible/Collapsible.test.tsx +21 -0
  243. package/src/Collapsible/Collapsible.tsx +5 -0
  244. package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
  245. package/src/ComplexSelector/ComplexSelector.tsx +6 -1
  246. package/src/DateInput/DateInput.tsx +6 -1
  247. package/src/DateInput/NativeDateField.tsx +24 -8
  248. package/src/DateInput/TouchDateField.tsx +6 -2
  249. package/src/DateRangeInput/DateRangeInput.tsx +6 -1
  250. package/src/DateTimeInput/DateTimeInput.tsx +6 -1
  251. package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
  252. package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
  253. package/src/Dialog/DialogHeader.doc.mjs +12 -0
  254. package/src/Dialog/DialogHeader.test.tsx +97 -0
  255. package/src/Dialog/DialogHeader.tsx +25 -3
  256. package/src/Dialog/modules/DialogHeader.spec.md +75 -38
  257. package/src/Field/InputClearButton.test.tsx +17 -3
  258. package/src/Field/InputClearButton.tsx +5 -2
  259. package/src/Field/PanelSearchInput.tsx +5 -2
  260. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
  261. package/src/FileInput/FileInput.tsx +11 -2
  262. package/src/Kbd/Kbd.doc.mjs +3 -3
  263. package/src/Kbd/Kbd.test.tsx +57 -1
  264. package/src/Kbd/Kbd.tsx +57 -37
  265. package/src/Layout/LayoutFooter.doc.mjs +17 -0
  266. package/src/Link/Link.doc.mjs +11 -0
  267. package/src/Link/Link.test.tsx +24 -0
  268. package/src/Link/Link.tsx +5 -0
  269. package/src/List/List.spec.md +200 -0
  270. package/src/Markdown/Markdown.doc.mjs +272 -0
  271. package/src/Markdown/Markdown.fr23.bench.ts +174 -0
  272. package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
  273. package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
  274. package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
  275. package/src/Markdown/Markdown.public.test.ts +126 -3
  276. package/src/Markdown/Markdown.spec.md +197 -44
  277. package/src/Markdown/Markdown.test.tsx +11 -0
  278. package/src/Markdown/Markdown.tsx +414 -135
  279. package/src/Markdown/ast.test.ts +307 -0
  280. package/src/Markdown/ast.ts +337 -0
  281. package/src/Markdown/incremental.test.ts +12 -0
  282. package/src/Markdown/index.ts +37 -1
  283. package/src/Markdown/modules/remark.spec.md +269 -0
  284. package/src/Markdown/parser/index.ts +64 -0
  285. package/src/Markdown/parser.public.test.ts +103 -0
  286. package/src/Markdown/parser.ts +1180 -235
  287. package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
  288. package/src/Markdown/plugins/frontmatter.ts +198 -0
  289. package/src/Markdown/plugins/index.ts +53 -0
  290. package/src/Markdown/plugins/protocol.test.tsx +1022 -0
  291. package/src/Markdown/plugins/protocol.ts +1618 -0
  292. package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
  293. package/src/Markdown/plugins/semanticFence.ts +424 -0
  294. package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
  295. package/src/Markdown/plugins/sourceDecoration.ts +539 -0
  296. package/src/Markdown/plugins/textTransform.test.ts +467 -0
  297. package/src/Markdown/plugins/textTransform.ts +554 -0
  298. package/src/Markdown/remark.test.tsx +1877 -0
  299. package/src/Markdown/remark.ts +1574 -0
  300. package/src/Markdown/url.ts +30 -0
  301. package/src/Markdown/utils.ts +13 -1
  302. package/src/MultiSelector/MultiSelector.test.tsx +1 -35
  303. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
  304. package/src/NumberInput/NumberInput.tsx +6 -1
  305. package/src/Outline/Outline.doc.mjs +7 -5
  306. package/src/Outline/Outline.spec.md +1 -1
  307. package/src/Outline/index.ts +1 -0
  308. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
  309. package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
  310. package/src/Outline/useOutlineFromMarkdown.ts +15 -3
  311. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  312. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
  313. package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
  314. package/src/ProgressBar/ProgressBar.test.tsx +29 -11
  315. package/src/ProgressBar/ProgressBar.tsx +59 -72
  316. package/src/RadioList/RadioList.doc.mjs +11 -0
  317. package/src/RadioList/RadioList.test.tsx +32 -0
  318. package/src/RadioList/RadioListItem.tsx +25 -1
  319. package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
  320. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  321. package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
  322. package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
  323. package/src/Selector/Selector.doc.mjs +2 -2
  324. package/src/Selector/Selector.spec.md +51 -49
  325. package/src/Selector/Selector.test.tsx +61 -55
  326. package/src/Selector/Selector.tsx +23 -14
  327. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
  328. package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
  329. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
  330. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
  331. package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
  332. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
  333. package/src/SideNav/SideNav.doc.mjs +1 -1
  334. package/src/SideNav/SideNav.test.tsx +10 -0
  335. package/src/SideNav/SideNav.tsx +14 -2
  336. package/src/Slider/Slider.doc.mjs +17 -3
  337. package/src/Slider/Slider.test.tsx +221 -0
  338. package/src/Slider/Slider.tsx +40 -9
  339. package/src/Spinner/Spinner.test.tsx +4 -0
  340. package/src/Spinner/Spinner.tsx +31 -18
  341. package/src/Switch/Switch.doc.mjs +11 -0
  342. package/src/Switch/Switch.test.tsx +16 -0
  343. package/src/Switch/Switch.tsx +28 -0
  344. package/src/TabList/Tab.tsx +35 -7
  345. package/src/TabList/TabList.doc.mjs +11 -0
  346. package/src/TabList/TabList.spec.md +204 -0
  347. package/src/TabList/TabList.test.tsx +66 -0
  348. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
  349. package/src/Table/Table.doc.mjs +1 -1
  350. package/src/Table/Table.spec.md +54 -40
  351. package/src/Table/Table.test.tsx +83 -10
  352. package/src/Table/Table.tsx +30 -22
  353. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
  354. package/src/TextArea/TextArea.tsx +6 -1
  355. package/src/TextInput/TextInput.test.tsx +20 -1
  356. package/src/TextInput/TextInput.tsx +6 -1
  357. package/src/TimeInput/TimeInput.tsx +6 -1
  358. package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
  359. package/src/ToggleButton/ToggleButton.test.tsx +299 -4
  360. package/src/ToggleButton/ToggleButton.tsx +26 -33
  361. package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
  362. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
  363. package/src/Tokenizer/Tokenizer.spec.md +142 -75
  364. package/src/TreeList/TreeList.doc.mjs +3 -3
  365. package/src/TreeList/TreeList.spec.md +123 -75
  366. package/src/TreeList/TreeList.test.tsx +29 -0
  367. package/src/TreeList/TreeList.tsx +3 -0
  368. package/src/TreeList/TreeListItem.tsx +15 -1
  369. package/src/TreeList/TreeListTypes.ts +11 -1
  370. package/src/Typeahead/BaseTypeahead.spec.md +4 -3
  371. package/src/Typeahead/BaseTypeahead.tsx +21 -7
  372. package/src/Typeahead/Typeahead.test.tsx +53 -0
  373. package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
  374. package/src/__tests__/pressState.ts +93 -0
  375. package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
  376. package/src/hooks/scrollKeyboardDelegation.ts +233 -0
  377. package/src/hooks/useScrollableArea.doc.mjs +15 -3
  378. package/src/hooks/useScrollableArea.test.tsx +59 -1
  379. package/src/hooks/useScrollableArea.ts +34 -10
  380. package/src/inputFontFloor.test.ts +106 -0
  381. package/src/tailwind-theme.css +0 -6
  382. package/src/theme/generateThemeRules.test.ts +30 -0
  383. package/src/theme/generateThemeRules.ts +10 -0
  384. package/src/utils/interactionOverlay.stylex.ts +20 -0
@@ -0,0 +1,539 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file sourceDecoration.ts
5
+ * @input Caller-supplied UTF-16 source ranges and non-semantic decoration payloads
6
+ * @output Immutable Markdown transforms that annotate Core-authored source-backed nodes
7
+ * @position Optional helper layer compiled onto the core transform protocol
8
+ */
9
+
10
+ import type {
11
+ MarkdownAstDataValue,
12
+ MarkdownAstNodeBase,
13
+ MarkdownAstPosition,
14
+ MarkdownAstRoot,
15
+ } from '../ast';
16
+ import {
17
+ isMarkdownPluginData,
18
+ markMarkdownTransformClaim,
19
+ markMarkdownTransformTrusted,
20
+ type MarkdownExtensionNode,
21
+ type MarkdownPluginData,
22
+ type MarkdownTransform,
23
+ } from './protocol';
24
+
25
+ /**
26
+ * Reserved node-data key and brand of the Core-owned decoration envelope.
27
+ * Decorations are only ever read from, and merged into, a value carrying all
28
+ * three: an arbitrary payload that happens to sit at this key is foreign data
29
+ * and is left untouched.
30
+ */
31
+ const ENVELOPE_KEY = 'astryx:sourceDecorations';
32
+ const ENVELOPE_BRAND = 'astryx.markdown.sourceDecorations';
33
+ const ENVELOPE_VERSION = 1;
34
+
35
+ /** One decoration recorded on an annotated node. */
36
+ export interface MarkdownSourceDecoration {
37
+ /** Stable decoration name supplied by the helper's caller. */
38
+ readonly name: string;
39
+ /** Optional finite JSON-like payload copied from the matching range. */
40
+ readonly data?: MarkdownPluginData;
41
+ }
42
+
43
+ export interface MarkdownSourceDecorationRange {
44
+ /** Inclusive UTF-16 offset into the parsed source. */
45
+ readonly start: number;
46
+ /** Exclusive UTF-16 offset into the parsed source. */
47
+ readonly end: number;
48
+ /** Optional finite JSON-like payload recorded with this range. */
49
+ readonly data?: MarkdownPluginData;
50
+ }
51
+
52
+ export interface MarkdownSourceDecorationOptions {
53
+ /** Stable decoration name identifying every entry this helper records. */
54
+ readonly name: string;
55
+ /**
56
+ * Source ranges to decorate, as UTF-16 offsets into the same string the
57
+ * parser received. Order does not matter: entries are recorded in a fixed
58
+ * start, end, payload order so overlapping and duplicate ranges resolve the
59
+ * same way on every run. An empty list is a valid no-op.
60
+ */
61
+ readonly ranges: ReadonlyArray<MarkdownSourceDecorationRange>;
62
+ }
63
+
64
+ /** A decoration entry as stored: plain, frozen, JSON-like node data. */
65
+ type DecorationEntry = {readonly [key: string]: MarkdownAstDataValue};
66
+
67
+ interface NormalizedRange {
68
+ readonly start: number;
69
+ readonly end: number;
70
+ readonly entry: DecorationEntry;
71
+ }
72
+
73
+ /**
74
+ * Every AST node shares an optional `position` and `data`; decoration is node
75
+ * kind agnostic, so the walk below reads only those two fields plus children.
76
+ */
77
+ type DecoratableNode = MarkdownAstNodeBase & {
78
+ readonly type: string;
79
+ readonly children?: ReadonlyArray<DecoratableNode>;
80
+ };
81
+
82
+ interface RunState {
83
+ readonly report: (message: string) => void;
84
+ hasReported: boolean;
85
+ }
86
+
87
+ const NO_DECORATIONS: ReadonlyArray<MarkdownSourceDecoration> = Object.freeze(
88
+ [],
89
+ );
90
+
91
+ function isPlainObject(
92
+ value: MarkdownAstDataValue | undefined,
93
+ ): value is {readonly [key: string]: MarkdownAstDataValue} {
94
+ return value != null && typeof value === 'object' && !Array.isArray(value);
95
+ }
96
+
97
+ function cloneDecorationData<Data extends MarkdownPluginData>(
98
+ value: Data,
99
+ ): Data {
100
+ if (value == null || typeof value !== 'object') {
101
+ return value;
102
+ }
103
+ if (Array.isArray(value)) {
104
+ return Object.freeze(value.map(cloneDecorationData)) as Data;
105
+ }
106
+ const clone: Record<string, MarkdownAstDataValue> = {};
107
+ for (const [key, nested] of Object.entries(value)) {
108
+ clone[key] = cloneDecorationData(nested);
109
+ }
110
+ return Object.freeze(clone) as Data;
111
+ }
112
+
113
+ function fail(message: string): never {
114
+ throw new TypeError(`Markdown source decoration: ${message}`);
115
+ }
116
+
117
+ function normalizeRanges(
118
+ name: string,
119
+ ranges: ReadonlyArray<MarkdownSourceDecorationRange>,
120
+ ): ReadonlyArray<NormalizedRange> {
121
+ const normalized: (NormalizedRange & {readonly key: string})[] = [];
122
+ const seen = new Set<string>();
123
+ for (const range of ranges) {
124
+ if (
125
+ !Number.isInteger(range.start) ||
126
+ !Number.isInteger(range.end) ||
127
+ range.start < 0 ||
128
+ range.end <= range.start
129
+ ) {
130
+ fail('ranges must be ordered, non-empty, non-negative UTF-16 offsets');
131
+ }
132
+ if (range.data !== undefined && !isMarkdownPluginData(range.data)) {
133
+ fail('range data must be finite JSON-like plugin data');
134
+ }
135
+ const data =
136
+ range.data === undefined ? undefined : cloneDecorationData(range.data);
137
+ const key = `${range.start}\u0000${range.end}\u0000${
138
+ data === undefined ? '' : JSON.stringify(data)
139
+ }`;
140
+ if (seen.has(key)) {
141
+ continue;
142
+ }
143
+ seen.add(key);
144
+ normalized.push({
145
+ start: range.start,
146
+ end: range.end,
147
+ entry: Object.freeze(
148
+ data === undefined ? {name} : {name, data},
149
+ ) as DecorationEntry,
150
+ key,
151
+ });
152
+ }
153
+ // Sorted by start, then end, then payload: the sweep below needs start
154
+ // order, and the tail of the comparison makes overlapping and duplicate
155
+ // ranges resolve identically on every run.
156
+ normalized.sort(
157
+ (left, right) =>
158
+ left.start - right.start ||
159
+ left.end - right.end ||
160
+ (left.key < right.key ? -1 : left.key > right.key ? 1 : 0),
161
+ );
162
+ return Object.freeze(
163
+ normalized.map(({start, end, entry}) => Object.freeze({start, end, entry})),
164
+ );
165
+ }
166
+
167
+ /**
168
+ * A node's Core-authored span, or `undefined` when it has no usable one.
169
+ * Read into two numbers rather than an object: this runs once per node of
170
+ * every decorated document.
171
+ */
172
+ function spanStart(position: MarkdownAstPosition | undefined): number {
173
+ if (position === undefined) {
174
+ return -1;
175
+ }
176
+ const start = position.start.offset;
177
+ const end = position.end.offset;
178
+ return typeof start === 'number' &&
179
+ typeof end === 'number' &&
180
+ start >= 0 &&
181
+ end >= start
182
+ ? start
183
+ : -1;
184
+ }
185
+
186
+ /**
187
+ * Reads the decoration entries already on a node. `null` means the node
188
+ * carries data this helper does not own, so it must be left alone.
189
+ */
190
+ function existingEntries(
191
+ data: MarkdownAstDataValue | undefined,
192
+ ): ReadonlyArray<MarkdownAstDataValue> | undefined | null {
193
+ if (data === undefined) {
194
+ return undefined;
195
+ }
196
+ if (!isPlainObject(data)) {
197
+ return null;
198
+ }
199
+ const envelope = data[ENVELOPE_KEY];
200
+ if (envelope === undefined) {
201
+ return undefined;
202
+ }
203
+ if (
204
+ !isPlainObject(envelope) ||
205
+ envelope.kind !== ENVELOPE_BRAND ||
206
+ envelope.version !== ENVELOPE_VERSION ||
207
+ !Array.isArray(envelope.entries) ||
208
+ !envelope.entries.every(isDecorationEntry)
209
+ ) {
210
+ return null;
211
+ }
212
+ return envelope.entries;
213
+ }
214
+
215
+ function isDecorationEntry(value: MarkdownAstDataValue): boolean {
216
+ return isPlainObject(value) && typeof value.name === 'string';
217
+ }
218
+
219
+ function envelope(
220
+ entries: ReadonlyArray<MarkdownAstDataValue>,
221
+ ): MarkdownAstDataValue {
222
+ return {
223
+ kind: ENVELOPE_BRAND,
224
+ version: ENVELOPE_VERSION,
225
+ entries,
226
+ };
227
+ }
228
+
229
+ function reportSkip(state: RunState): void {
230
+ if (state.hasReported) {
231
+ return;
232
+ }
233
+ state.hasReported = true;
234
+ state.report(
235
+ 'skipped a node whose data is not a Core-owned source-decoration envelope',
236
+ );
237
+ }
238
+
239
+ /**
240
+ * Records `entries` in the node's decoration envelope, or returns `undefined`
241
+ * when the node carries data this helper does not own. Skipping keeps a
242
+ * foreign payload intact instead of overwriting or extending it.
243
+ */
244
+ function mergeDecorations(
245
+ node: DecoratableNode,
246
+ entries: ReadonlyArray<DecorationEntry>,
247
+ state: RunState,
248
+ ): MarkdownAstDataValue | undefined {
249
+ const current = existingEntries(node.data);
250
+ if (current === null) {
251
+ reportSkip(state);
252
+ return undefined;
253
+ }
254
+ const merged = envelope(
255
+ current === undefined ? entries : [...current, ...entries],
256
+ );
257
+ return node.data === undefined
258
+ ? {[ENVELOPE_KEY]: merged}
259
+ : {...(node.data as object), [ENVELOPE_KEY]: merged};
260
+ }
261
+
262
+ /**
263
+ * Whether the positioned children already sit in ascending span order, and
264
+ * the span-ordered index list when they do not. An earlier transform may
265
+ * reorder, drop, or interleave blocks, so document order is never assumed —
266
+ * but the ordinary case is detected in one pass and needs no index list at
267
+ * all.
268
+ */
269
+ function spanOrder(
270
+ children: ReadonlyArray<DecoratableNode>,
271
+ ): ReadonlyArray<number> | undefined {
272
+ let previous = -1;
273
+ for (let index = 0; index < children.length; index++) {
274
+ const start = spanStart(children[index].position);
275
+ if (start < 0) {
276
+ continue;
277
+ }
278
+ if (start < previous) {
279
+ const indices: number[] = [];
280
+ for (let scan = 0; scan < children.length; scan++) {
281
+ if (spanStart(children[scan].position) >= 0) {
282
+ indices.push(scan);
283
+ }
284
+ }
285
+ indices.sort(
286
+ (left, right) =>
287
+ spanStart(children[left].position) -
288
+ spanStart(children[right].position) || left - right,
289
+ );
290
+ return indices;
291
+ }
292
+ previous = start;
293
+ }
294
+ return undefined;
295
+ }
296
+
297
+ /**
298
+ * The first slot whose node can overlap `offset` — that is, the first one
299
+ * ending after it. Spans ascend, so the blocks a range touches are one
300
+ * contiguous run and a search finds its start without walking the document.
301
+ * Decorating a known range therefore costs the blocks it actually covers,
302
+ * not the length of the document it sits in.
303
+ */
304
+ function firstSlotEndingAfter(
305
+ children: ReadonlyArray<DecoratableNode>,
306
+ order: ReadonlyArray<number> | undefined,
307
+ length: number,
308
+ offset: number,
309
+ ): number {
310
+ let low = 0;
311
+ let high = length;
312
+ while (low < high) {
313
+ const middle = (low + high) >>> 1;
314
+ const node = children[order?.[middle] ?? middle];
315
+ const end = node.position?.end.offset;
316
+ if (typeof end === 'number' && end <= offset) {
317
+ low = middle + 1;
318
+ } else {
319
+ high = middle;
320
+ }
321
+ }
322
+ return low;
323
+ }
324
+
325
+ /**
326
+ * Sweeps the start-sorted ranges across the span-ordered children, keeping
327
+ * the ranges that can still overlap in an active window. Each range is
328
+ * admitted and retired at most once, so the pass costs the blocks the ranges
329
+ * reach plus the matches — never the whole document per range.
330
+ */
331
+ function decorateChildren(
332
+ children: ReadonlyArray<DecoratableNode>,
333
+ ranges: ReadonlyArray<NormalizedRange>,
334
+ state: RunState,
335
+ ): ReadonlyArray<DecoratableNode> {
336
+ const order = spanOrder(children);
337
+ const length = order?.length ?? children.length;
338
+ let next: DecoratableNode[] | undefined;
339
+ let cursor = 0;
340
+ const active: NormalizedRange[] = [];
341
+
342
+ // Skip straight to the first block the earliest range can reach. Unordered
343
+ // trees fall back to a full sweep, since a sorted index list makes the
344
+ // search valid only over positioned nodes.
345
+ let slot =
346
+ order === undefined
347
+ ? firstSlotEndingAfter(children, order, length, ranges[0].start)
348
+ : 0;
349
+
350
+ for (; slot < length; slot++) {
351
+ // Once every range has been admitted and retired, no later span can
352
+ // match: the rest of the document is left untouched.
353
+ if (cursor >= ranges.length && active.length === 0) {
354
+ break;
355
+ }
356
+ const index = order?.[slot] ?? slot;
357
+ const child = children[index];
358
+ const start = spanStart(child.position);
359
+ if (start < 0) {
360
+ continue;
361
+ }
362
+ const end = child.position?.end.offset as number;
363
+ while (cursor < ranges.length && ranges[cursor].start < end) {
364
+ active.push(ranges[cursor++]);
365
+ }
366
+ // Retire in place: spans are visited in ascending start order, so a range
367
+ // that ended before this one starts cannot match any later span either.
368
+ let kept = 0;
369
+ for (let active_slot = 0; active_slot < active.length; active_slot++) {
370
+ if (active[active_slot].end > start) {
371
+ active[kept++] = active[active_slot];
372
+ }
373
+ }
374
+ active.length = kept;
375
+ if (kept === 0) {
376
+ // No range reaches this block. When the next range starts beyond this
377
+ // block, jump to the first block it can reach rather than walking the
378
+ // gap between; when it starts inside this one the next block is
379
+ // already the answer and searching for it would cost more than
380
+ // stepping to it.
381
+ if (
382
+ order === undefined &&
383
+ cursor < ranges.length &&
384
+ ranges[cursor].start > end
385
+ ) {
386
+ const jump = firstSlotEndingAfter(
387
+ children,
388
+ order,
389
+ length,
390
+ ranges[cursor].start,
391
+ );
392
+ if (jump > slot) {
393
+ slot = jump - 1;
394
+ }
395
+ }
396
+ continue;
397
+ }
398
+ const decorated = decorateNode(child, active, state);
399
+ if (decorated === child) {
400
+ continue;
401
+ }
402
+ next ??= children.slice();
403
+ next[index] = decorated;
404
+ }
405
+ return next ?? children;
406
+ }
407
+
408
+ /**
409
+ * Decorates one node every range in `ranges` already overlaps. Decoration
410
+ * stops at the outermost positioned node, so a range never records itself
411
+ * twice down one branch.
412
+ */
413
+ function decorateNode(
414
+ node: DecoratableNode,
415
+ ranges: ReadonlyArray<NormalizedRange>,
416
+ state: RunState,
417
+ ): DecoratableNode {
418
+ // Extension nodes belong to the plugin that produced them; their data is
419
+ // part of their identity, so decoration never touches them.
420
+ if (node.type === 'extension') {
421
+ return node;
422
+ }
423
+ const data = mergeDecorations(
424
+ node,
425
+ ranges.map(range => range.entry),
426
+ state,
427
+ );
428
+ return data === undefined ? node : {...node, data};
429
+ }
430
+
431
+ /**
432
+ * Compiles validated source ranges into an immutable transform that records
433
+ * non-semantic presentation metadata on the Core-authored nodes those ranges
434
+ * overlap.
435
+ *
436
+ * A node is decorated only when the parser authored its source position and
437
+ * the range overlaps its span, so the helper never changes AST meaning,
438
+ * rendered output, copyable text, accessible names, focus order, navigation,
439
+ * or source provenance. Core authors positions on top-level blocks, so a
440
+ * range decorates every block it touches, whatever order those blocks sit in
441
+ * after earlier transforms.
442
+ *
443
+ * Decorations describe settled source, so they appear on the final snapshot
444
+ * of a streaming document rather than on its partial chunks: a partial
445
+ * block's extent is still changing, and exposing decorations from it would
446
+ * let one appear and then vanish. Exposure is therefore monotone — never
447
+ * present, then absent.
448
+ *
449
+ * Decorations are stored in one Core-owned versioned envelope and read back
450
+ * with `getMarkdownSourceDecorations`; data the helper does not own is never
451
+ * merged into or overwritten.
452
+ *
453
+ * @example
454
+ * ```
455
+ * const reviewHits = createMarkdownPlugin({
456
+ * name: 'review-hits',
457
+ * apiVersion: 1,
458
+ * transform: createMarkdownSourceDecoration({
459
+ * name: 'review-hit',
460
+ * ranges: [{start: 0, end: 12, data: {reviewer: 'ada'}}],
461
+ * }),
462
+ * });
463
+ * ```
464
+ */
465
+ export function createMarkdownSourceDecoration(
466
+ options: MarkdownSourceDecorationOptions,
467
+ ): MarkdownTransform<never> {
468
+ if (typeof options.name !== 'string' || options.name.trim() === '') {
469
+ fail('name must be a non-empty string');
470
+ }
471
+ if (!Array.isArray(options.ranges)) {
472
+ fail('ranges must be an array');
473
+ }
474
+ const ranges = normalizeRanges(options.name, options.ranges);
475
+ const smallestStart = ranges.length === 0 ? -1 : ranges[0].start;
476
+
477
+ const transform: MarkdownTransform<never> = (document, context) => {
478
+ // Decorations describe settled source. While a document streams, the
479
+ // block a range falls in can still be re-parsed, re-split, merged into a
480
+ // table or list, or withheld entirely, so a range's covering block is not
481
+ // stable and a decoration computed from it could appear, vanish, and
482
+ // reappear across chunks. Waiting for the settled snapshot makes exposure
483
+ // monotone by construction: absent while the source can still change,
484
+ // then present once it cannot.
485
+ if (!context.isFinal || ranges.length === 0) {
486
+ return document;
487
+ }
488
+ // A range starting at or past the end of the source overlaps nothing.
489
+ const usable =
490
+ ranges[ranges.length - 1].start < context.source.length
491
+ ? ranges
492
+ : ranges.filter(range => range.start < context.source.length);
493
+ if (usable.length === 0) {
494
+ return document;
495
+ }
496
+ const root = document as unknown as DecoratableNode;
497
+ if (root.children == null) {
498
+ return document;
499
+ }
500
+ const state: RunState = {
501
+ report: message => context.report(message),
502
+ hasReported: false,
503
+ };
504
+ const children = decorateChildren(root.children, usable, state);
505
+ return children === root.children
506
+ ? document
507
+ : ({
508
+ ...document,
509
+ children,
510
+ } as unknown as MarkdownAstRoot<MarkdownExtensionNode>);
511
+ };
512
+
513
+ // Every node this helper emits is built here, from ranges validated above:
514
+ // it inserts no caller-supplied node and changes no existing node's meaning,
515
+ // provenance, or ownership. Core may therefore skip the validation and
516
+ // freezing it applies to plugin-authored output.
517
+ return markMarkdownTransformTrusted(
518
+ markMarkdownTransformClaim(
519
+ transform,
520
+ source => smallestStart >= 0 && source.length > smallestStart,
521
+ ),
522
+ );
523
+ }
524
+
525
+ /**
526
+ * Reads the decorations a source-decoration helper recorded on a node.
527
+ * Returns an empty list for undecorated nodes and for any value that is not
528
+ * a current Core-owned decoration envelope.
529
+ */
530
+ export function getMarkdownSourceDecorations(
531
+ node: MarkdownAstNodeBase,
532
+ ): ReadonlyArray<MarkdownSourceDecoration> {
533
+ const entries = existingEntries(node.data);
534
+ // `existingEntries` returns entries only from a branded envelope whose
535
+ // every member passed `isDecorationEntry`, so each one has a string name.
536
+ return entries == null || entries.length === 0
537
+ ? NO_DECORATIONS
538
+ : (entries as unknown as ReadonlyArray<MarkdownSourceDecoration>);
539
+ }