@astryxdesign/core 0.6.2 → 0.6.3-canary.01fa439

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,554 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file textTransform.ts
5
+ * @input Regex selectors and replacement callbacks for eligible Markdown prose
6
+ * @output Immutable Markdown transforms with protected-context traversal
7
+ * @position Optional helper layer compiled onto the core transform protocol
8
+ */
9
+
10
+ import type {
11
+ MarkdownAstBlockContent,
12
+ MarkdownAstListItem,
13
+ MarkdownAstPhrasingContent,
14
+ MarkdownAstTableCell,
15
+ MarkdownAstTableRow,
16
+ } from '../ast';
17
+ import {
18
+ getMarkdownHelperOwnership,
19
+ adoptMarkdownHelperNode,
20
+ adoptMarkdownHelperNodes,
21
+ markMarkdownTransformClaim,
22
+ markMarkdownTransformTrusted,
23
+ type MarkdownExtensionNode,
24
+ type MarkdownHelperOwnership,
25
+ type MarkdownTransform,
26
+ } from './protocol';
27
+
28
+ /**
29
+ * Ownership for a transform invoked outside Core's pipeline. It owns no
30
+ * plugin name and no renderer, so a callback's extension node is rejected
31
+ * while ordinary phrasing still works.
32
+ */
33
+ const UNOWNED: MarkdownHelperOwnership = Object.freeze({
34
+ pluginName: '\u0000unowned',
35
+ hasRenderer: () => false,
36
+ sourceUnchanged: false,
37
+ });
38
+
39
+ export interface MarkdownTextTransformContext {
40
+ readonly parentType:
41
+ 'heading' | 'paragraph' | 'strong' | 'emphasis' | 'delete' | 'tableCell';
42
+ }
43
+
44
+ export interface MarkdownTextTransformOptions<
45
+ Node extends MarkdownExtensionNode = never,
46
+ > {
47
+ /** Global expression matched against eligible built-in prose only. */
48
+ readonly pattern: RegExp;
49
+ /**
50
+ * Literal substrings such that source containing an eligible match contains
51
+ * at least one. Core uses them to skip the transform without walking the AST
52
+ * when none are present. Omit this optimization when no conservative literal
53
+ * exists; the helper will inspect eligible prose on every run. This fast path
54
+ * is also disabled for case-insensitive patterns so JavaScript case folding
55
+ * remains exact.
56
+ */
57
+ readonly requiredSubstrings?: readonly [string, ...string[]];
58
+ /** Optionally decline or extend a regex claim. */
59
+ readonly getEndIndex?: (
60
+ text: string,
61
+ match: RegExpExecArray,
62
+ ) => number | false;
63
+ replace(
64
+ match: RegExpExecArray,
65
+ context: MarkdownTextTransformContext,
66
+ ):
67
+ | MarkdownAstPhrasingContent<Node>
68
+ | ReadonlyArray<MarkdownAstPhrasingContent<Node>>;
69
+ }
70
+
71
+ /**
72
+ * Replacement nodes already placed in a document by this helper.
73
+ *
74
+ * A callback that builds a node per match hands over a fresh object, and
75
+ * that object can go straight into the tree — copying it would allocate a
76
+ * second one for nothing, and it is validated and frozen on the way in
77
+ * either way. A callback that returns the SAME object for several matches
78
+ * is the case that needs a copy: one object cannot occupy two positions in
79
+ * a tree, and a node already frozen into an earlier position must not be
80
+ * reused for a later one. Weak, so remembering a node never keeps it alive.
81
+ */
82
+ const adoptedReplacements = new WeakSet<object>();
83
+
84
+ /** One reusable expression per transform invocation. */
85
+ interface Scanner {
86
+ readonly pattern: RegExp;
87
+ busy: boolean;
88
+ }
89
+
90
+ type AnyExtension = MarkdownExtensionNode;
91
+ type Phrasing = MarkdownAstPhrasingContent<AnyExtension>;
92
+ type Block = MarkdownAstBlockContent<AnyExtension>;
93
+
94
+ /**
95
+ * Copies a caller's node away from them. The cycle-tracking map is allocated
96
+ * only once a nested object actually appears: the overwhelmingly common
97
+ * replacement is a flat node of primitives, and this runs once per match.
98
+ */
99
+ function cloneReplacement<T>(value: T, seen?: Map<object, unknown>): T {
100
+ if (value == null || typeof value !== 'object') {
101
+ return value;
102
+ }
103
+ const cached = seen?.get(value);
104
+ if (cached != null) {
105
+ return cached as T;
106
+ }
107
+ if (Array.isArray(value)) {
108
+ const clone: unknown[] = [];
109
+ seen ??= new Map<object, unknown>();
110
+ seen.set(value, clone);
111
+ for (const item of value) {
112
+ clone.push(cloneReplacement(item, seen));
113
+ }
114
+ return clone as T;
115
+ }
116
+ if (Object.getPrototypeOf(value) !== Object.prototype) {
117
+ return value;
118
+ }
119
+ const clone: Record<string, unknown> = {};
120
+ let tracked = seen;
121
+ for (const key in value) {
122
+ const nested = (value as Record<string, unknown>)[key];
123
+ if (nested != null && typeof nested === 'object') {
124
+ if (tracked === undefined) {
125
+ tracked = new Map<object, unknown>();
126
+ tracked.set(value, clone);
127
+ }
128
+ clone[key] = cloneReplacement(nested, tracked);
129
+ } else {
130
+ clone[key] = nested;
131
+ }
132
+ }
133
+ return clone as T;
134
+ }
135
+
136
+ function advanceStringIndex(
137
+ value: string,
138
+ index: number,
139
+ unicode: boolean,
140
+ ): number {
141
+ if (!unicode || index >= value.length) {
142
+ return index + 1;
143
+ }
144
+ const first = value.charCodeAt(index);
145
+ if (first < 0xd800 || first > 0xdbff || index + 1 >= value.length) {
146
+ return index + 1;
147
+ }
148
+ const second = value.charCodeAt(index + 1);
149
+ return second >= 0xdc00 && second <= 0xdfff ? index + 2 : index + 1;
150
+ }
151
+
152
+ function replaceTextNode<Node extends MarkdownExtensionNode>(
153
+ value: string,
154
+ options: MarkdownTextTransformOptions<Node>,
155
+ parentType: MarkdownTextTransformContext['parentType'],
156
+ ownership: MarkdownHelperOwnership,
157
+ scanner: Scanner,
158
+ ): ReadonlyArray<Phrasing> | null {
159
+ // The conservative substring hint decides per text node, not just per
160
+ // document: source without one cannot contain an eligible match, so most
161
+ // prose is skipped before any scanning happens.
162
+ // Disabled for case-insensitive patterns, exactly as the document-level
163
+ // claim is, so JavaScript case folding stays the only authority.
164
+ const required = options.pattern.ignoreCase
165
+ ? undefined
166
+ : options.requiredSubstrings;
167
+ if (required != null && !required.some(hint => value.includes(hint))) {
168
+ return null;
169
+ }
170
+ // One expression per transform invocation rather than one per text node.
171
+ // A `replace` callback that re-enters this helper gets its own, so a
172
+ // nested scan can never disturb the outer one's `lastIndex`.
173
+ const pattern = scanner.busy
174
+ ? new RegExp(options.pattern.source, options.pattern.flags)
175
+ : scanner.pattern;
176
+ const reentrant = pattern !== scanner.pattern;
177
+ if (!reentrant) {
178
+ scanner.busy = true;
179
+ }
180
+ pattern.lastIndex = 0;
181
+ const output: Phrasing[] = [];
182
+ let cursor = 0;
183
+ let changed = false;
184
+ let match: RegExpExecArray | null;
185
+
186
+ while ((match = pattern.exec(value)) != null) {
187
+ const start = match.index;
188
+ const defaultEnd = start + match[0].length;
189
+ const resolvedEnd = options.getEndIndex?.(value, match) ?? defaultEnd;
190
+ if (resolvedEnd === false) {
191
+ if (match[0].length === 0) {
192
+ pattern.lastIndex = advanceStringIndex(
193
+ value,
194
+ pattern.lastIndex,
195
+ pattern.unicode || pattern.flags.includes('v'),
196
+ );
197
+ }
198
+ continue;
199
+ }
200
+ if (
201
+ !Number.isInteger(resolvedEnd) ||
202
+ resolvedEnd < defaultEnd ||
203
+ resolvedEnd < start ||
204
+ resolvedEnd > value.length
205
+ ) {
206
+ throw new TypeError(
207
+ 'Markdown text transform returned an invalid end index',
208
+ );
209
+ }
210
+ if (start < cursor) {
211
+ continue;
212
+ }
213
+ if (start > cursor) {
214
+ output.push({type: 'text', value: value.slice(cursor, start)});
215
+ }
216
+ const replacement = options.replace(match, {parentType});
217
+ // The callback's nodes are the only untrusted structure this helper can
218
+ // introduce. Each one is checked here under the same rules Core applies
219
+ // to newly-introduced nodes — representable data, no authored
220
+ // provenance, no foreign extension ownership, no cycles — and frozen,
221
+ // so the tree this transform returns needs no further checking. A node
222
+ // the callback has handed over before is copied first; a fresh one is
223
+ // adopted as it stands.
224
+ if (Array.isArray(replacement)) {
225
+ const adopted: Phrasing[] = [];
226
+ for (const replacementNode of replacement) {
227
+ adopted.push(
228
+ adoptedReplacements.has(replacementNode)
229
+ ? cloneReplacement(replacementNode)
230
+ : replacementNode,
231
+ );
232
+ }
233
+ adoptMarkdownHelperNodes(adopted, ownership);
234
+ for (const node of adopted) {
235
+ adoptedReplacements.add(node);
236
+ }
237
+ output.push(...adopted);
238
+ } else {
239
+ // One node is the overwhelmingly common reply, and it is worth its
240
+ // own path: wrapping it in an array to share the loop above would
241
+ // allocate twice per match, which on a large document is the
242
+ // helper's dominant garbage.
243
+ const single = replacement as Phrasing;
244
+ const adopted = adoptedReplacements.has(single)
245
+ ? cloneReplacement(single)
246
+ : single;
247
+ adoptMarkdownHelperNode(adopted, ownership);
248
+ adoptedReplacements.add(adopted);
249
+ output.push(adopted);
250
+ }
251
+ cursor = resolvedEnd;
252
+ pattern.lastIndex =
253
+ resolvedEnd === start
254
+ ? advanceStringIndex(
255
+ value,
256
+ pattern.lastIndex,
257
+ pattern.unicode || pattern.flags.includes('v'),
258
+ )
259
+ : Math.max(pattern.lastIndex, resolvedEnd);
260
+ changed = true;
261
+ }
262
+
263
+ if (!reentrant) {
264
+ scanner.busy = false;
265
+ }
266
+ if (!changed) {
267
+ return null;
268
+ }
269
+ if (cursor < value.length) {
270
+ output.push({type: 'text', value: value.slice(cursor)});
271
+ }
272
+ return output;
273
+ }
274
+
275
+ function transformPhrasing<Node extends MarkdownExtensionNode>(
276
+ children: ReadonlyArray<Phrasing>,
277
+ options: MarkdownTextTransformOptions<Node>,
278
+ parentType: MarkdownTextTransformContext['parentType'],
279
+ ownership: MarkdownHelperOwnership,
280
+ scanner: Scanner,
281
+ ): ReadonlyArray<Phrasing> {
282
+ // Lazy rebuild: unchanged phrasing is returned as-is, so prose with no
283
+ // match costs one walk and no allocation. Only the first change copies.
284
+ let next: Phrasing[] | undefined;
285
+ for (let index = 0; index < children.length; index++) {
286
+ const node = children[index];
287
+ if (node.type === 'text') {
288
+ const replaced = replaceTextNode(
289
+ node.value,
290
+ options,
291
+ parentType,
292
+ ownership,
293
+ scanner,
294
+ );
295
+ if (replaced == null) {
296
+ next?.push(node);
297
+ continue;
298
+ }
299
+ next ??= children.slice(0, index);
300
+ for (const replacement of replaced) {
301
+ next.push(replacement);
302
+ }
303
+ continue;
304
+ }
305
+ if (
306
+ node.type === 'strong' ||
307
+ node.type === 'emphasis' ||
308
+ node.type === 'delete'
309
+ ) {
310
+ const nested = transformPhrasing(
311
+ node.children,
312
+ options,
313
+ node.type,
314
+ ownership,
315
+ scanner,
316
+ );
317
+ if (nested === node.children) {
318
+ next?.push(node);
319
+ continue;
320
+ }
321
+ next ??= children.slice(0, index);
322
+ next.push({...node, children: nested});
323
+ continue;
324
+ }
325
+ // Links, images, code, math, citations, breaks, and accepted extension
326
+ // syntax are protected contexts owned by their existing semantics.
327
+ next?.push(node);
328
+ }
329
+ return next ?? children;
330
+ }
331
+
332
+ function blockMayContainRequiredSource<Node extends MarkdownExtensionNode>(
333
+ block: Block,
334
+ source: string | undefined,
335
+ options: MarkdownTextTransformOptions<Node>,
336
+ ): boolean {
337
+ const required = options.requiredSubstrings;
338
+ if (source === undefined || required === undefined) {
339
+ return true;
340
+ }
341
+ const start = block.position?.start.offset;
342
+ const end = block.position?.end.offset;
343
+ if (typeof start !== 'number' || typeof end !== 'number') {
344
+ return true;
345
+ }
346
+ for (const hint of required) {
347
+ const match = source.indexOf(hint, start);
348
+ if (match >= 0 && match < end) {
349
+ return true;
350
+ }
351
+ }
352
+ return false;
353
+ }
354
+
355
+ function transformBlocks<Node extends MarkdownExtensionNode>(
356
+ blocks: ReadonlyArray<Block>,
357
+ options: MarkdownTextTransformOptions<Node>,
358
+ ownership: MarkdownHelperOwnership,
359
+ scanner: Scanner,
360
+ source: string | undefined,
361
+ ): ReadonlyArray<Block> {
362
+ // Lazy rebuild, matching transformPhrasing: a block list with no match is
363
+ // returned unchanged and allocates nothing.
364
+ let next: Block[] | undefined;
365
+ for (let index = 0; index < blocks.length; index++) {
366
+ const block = blocks[index];
367
+ if (!blockMayContainRequiredSource(block, source, options)) {
368
+ next?.push(block);
369
+ continue;
370
+ }
371
+ let replacement: Block;
372
+ switch (block.type) {
373
+ case 'heading':
374
+ case 'paragraph': {
375
+ const children = transformPhrasing(
376
+ block.children,
377
+ options,
378
+ block.type,
379
+ ownership,
380
+ scanner,
381
+ );
382
+ replacement =
383
+ children === block.children ? block : {...block, children};
384
+ break;
385
+ }
386
+ case 'blockquote': {
387
+ const children = transformBlocks(
388
+ block.children,
389
+ options,
390
+ ownership,
391
+ scanner,
392
+ source,
393
+ );
394
+ replacement =
395
+ children === block.children ? block : {...block, children};
396
+ break;
397
+ }
398
+ case 'list': {
399
+ let items: MarkdownAstListItem<AnyExtension>[] | undefined;
400
+ for (
401
+ let item_index = 0;
402
+ item_index < block.children.length;
403
+ item_index++
404
+ ) {
405
+ const item = block.children[item_index];
406
+ const itemChildren = transformBlocks(
407
+ item.children,
408
+ options,
409
+ ownership,
410
+ scanner,
411
+ source,
412
+ );
413
+ if (itemChildren === item.children) {
414
+ items?.push(item);
415
+ continue;
416
+ }
417
+ items ??= block.children.slice(0, item_index);
418
+ items.push({...item, children: itemChildren});
419
+ }
420
+ replacement = items == null ? block : {...block, children: items};
421
+ break;
422
+ }
423
+ case 'table': {
424
+ let rows: MarkdownAstTableRow<AnyExtension>[] | undefined;
425
+ for (
426
+ let row_index = 0;
427
+ row_index < block.children.length;
428
+ row_index++
429
+ ) {
430
+ const row = block.children[row_index];
431
+ let cells: MarkdownAstTableCell<AnyExtension>[] | undefined;
432
+ for (
433
+ let cell_index = 0;
434
+ cell_index < row.children.length;
435
+ cell_index++
436
+ ) {
437
+ const cell = row.children[cell_index];
438
+ const cellChildren = transformPhrasing(
439
+ cell.children,
440
+ options,
441
+ 'tableCell',
442
+ ownership,
443
+ scanner,
444
+ );
445
+ if (cellChildren === cell.children) {
446
+ cells?.push(cell);
447
+ continue;
448
+ }
449
+ cells ??= row.children.slice(0, cell_index);
450
+ cells.push({...cell, children: cellChildren});
451
+ }
452
+ if (cells == null) {
453
+ rows?.push(row);
454
+ continue;
455
+ }
456
+ rows ??= block.children.slice(0, row_index);
457
+ rows.push({...row, children: cells});
458
+ }
459
+ replacement = rows == null ? block : {...block, children: rows};
460
+ break;
461
+ }
462
+ case 'code':
463
+ case 'math':
464
+ case 'image':
465
+ case 'thematicBreak':
466
+ case 'extension':
467
+ replacement = block;
468
+ break;
469
+ }
470
+ if (next === undefined && replacement !== block) {
471
+ next = blocks.slice(0, index);
472
+ }
473
+ next?.push(replacement);
474
+ }
475
+ return next ?? blocks;
476
+ }
477
+
478
+ export function createMarkdownTextTransform(
479
+ options: MarkdownTextTransformOptions<never>,
480
+ ): MarkdownTransform<never>;
481
+ export function createMarkdownTextTransform<Node extends MarkdownExtensionNode>(
482
+ options: MarkdownTextTransformOptions<Node>,
483
+ ): MarkdownTransform<Node>;
484
+ export function createMarkdownTextTransform(
485
+ options: MarkdownTextTransformOptions<MarkdownExtensionNode>,
486
+ ): MarkdownTransform<MarkdownExtensionNode> {
487
+ if (!options.pattern.global) {
488
+ throw new TypeError(
489
+ 'Markdown text transform patterns must use the global flag',
490
+ );
491
+ }
492
+ if (
493
+ options.requiredSubstrings != null &&
494
+ (!Array.isArray(options.requiredSubstrings) ||
495
+ options.requiredSubstrings.length === 0 ||
496
+ options.requiredSubstrings.some(
497
+ value => typeof value !== 'string' || value === '',
498
+ ))
499
+ ) {
500
+ throw new TypeError(
501
+ 'Markdown text transform requiredSubstrings must be non-empty strings',
502
+ );
503
+ }
504
+ const requiredSubstrings =
505
+ options.requiredSubstrings == null
506
+ ? undefined
507
+ : (Object.freeze([...options.requiredSubstrings]) as readonly [
508
+ string,
509
+ ...string[],
510
+ ]);
511
+ const normalizedOptions: MarkdownTextTransformOptions<MarkdownExtensionNode> =
512
+ Object.freeze({
513
+ pattern: new RegExp(options.pattern.source, options.pattern.flags),
514
+ requiredSubstrings,
515
+ getEndIndex: options.getEndIndex,
516
+ replace: options.replace,
517
+ });
518
+ const transform: MarkdownTransform<MarkdownExtensionNode> = (
519
+ root,
520
+ context,
521
+ ) => {
522
+ const ownership = getMarkdownHelperOwnership(context) ?? UNOWNED;
523
+ const children = transformBlocks(
524
+ root.children,
525
+ normalizedOptions,
526
+ ownership,
527
+ {
528
+ pattern: new RegExp(
529
+ normalizedOptions.pattern.source,
530
+ normalizedOptions.pattern.flags,
531
+ ),
532
+ busy: false,
533
+ },
534
+ ownership.sourceUnchanged &&
535
+ requiredSubstrings != null &&
536
+ !normalizedOptions.pattern.ignoreCase
537
+ ? context.source
538
+ : undefined,
539
+ );
540
+ return children === root.children ? root : {...root, children};
541
+ };
542
+ // Every node this helper returns is either one Core already validated or
543
+ // one `replaceTextNode` just validated against the same rules, so Core may
544
+ // run it on the trusted path.
545
+ const trusted = markMarkdownTransformTrusted(
546
+ transform as MarkdownTransform<never>,
547
+ ) as MarkdownTransform<MarkdownExtensionNode>;
548
+ if (requiredSubstrings == null || options.pattern.ignoreCase) {
549
+ return trusted;
550
+ }
551
+ return markMarkdownTransformClaim(trusted, source =>
552
+ requiredSubstrings.some(required => source.includes(required)),
553
+ );
554
+ }