@astryxdesign/core 0.6.2 → 0.6.3-canary.0788c49

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 (558) 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/Button/Button.d.ts.map +1 -1
  9. package/dist/Button/Button.js +13 -28
  10. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  11. package/dist/Chat/ChatComposer.js +10 -5
  12. package/dist/Chat/ChatComposerDrawer.d.ts +19 -5
  13. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  14. package/dist/Chat/ChatComposerDrawer.js +48 -23
  15. package/dist/Chat/ChatComposerInput.d.ts +11 -3
  16. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  17. package/dist/Chat/ChatComposerInput.js +63 -16
  18. package/dist/Chat/ChatDictationButton.d.ts +3 -2
  19. package/dist/Chat/ChatDictationButton.d.ts.map +1 -1
  20. package/dist/Chat/ChatDictationButton.js +6 -4
  21. package/dist/Chat/ChatLayout.d.ts +19 -0
  22. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  23. package/dist/Chat/ChatLayout.js +19 -0
  24. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  25. package/dist/Chat/ChatLayoutScrollButton.js +44 -34
  26. package/dist/Chat/ChatMessageBubble.d.ts +2 -0
  27. package/dist/Chat/ChatMessageBubble.d.ts.map +1 -1
  28. package/dist/Chat/ChatMessageBubble.js +5 -3
  29. package/dist/Chat/ChatMessageList.d.ts +2 -1
  30. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  31. package/dist/Chat/ChatMessageList.js +4 -3
  32. package/dist/Chat/ChatMessageMetadata.d.ts +5 -4
  33. package/dist/Chat/ChatMessageMetadata.d.ts.map +1 -1
  34. package/dist/Chat/ChatMessageMetadata.js +12 -9
  35. package/dist/Chat/ChatSendButton.d.ts +2 -1
  36. package/dist/Chat/ChatSendButton.d.ts.map +1 -1
  37. package/dist/Chat/ChatSendButton.js +6 -4
  38. package/dist/Chat/index.d.ts +1 -1
  39. package/dist/Chat/index.d.ts.map +1 -1
  40. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  41. package/dist/CheckboxInput/CheckboxInput.js +12 -2
  42. package/dist/Citation/Citation.d.ts +1 -1
  43. package/dist/Citation/Citation.d.ts.map +1 -1
  44. package/dist/Citation/Citation.js +3 -2
  45. package/dist/CodeBlock/highlightRanges.d.ts.map +1 -1
  46. package/dist/CodeBlock/highlightRanges.js +14 -3
  47. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  48. package/dist/Collapsible/Collapsible.js +6 -1
  49. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  50. package/dist/CommandPalette/CommandPaletteInput.js +1 -1
  51. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  52. package/dist/ComplexSelector/ComplexSelector.js +1 -1
  53. package/dist/DateInput/DateInput.d.ts.map +1 -1
  54. package/dist/DateInput/DateInput.js +4 -4
  55. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  56. package/dist/DateInput/NativeDateField.js +16 -16
  57. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  58. package/dist/DateInput/TouchDateField.js +2 -2
  59. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  60. package/dist/DateRangeInput/DateRangeInput.js +4 -4
  61. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  62. package/dist/DateTimeInput/DateTimeInput.js +8 -8
  63. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  64. package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
  65. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
  66. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
  67. package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
  68. package/dist/Dialog/DialogHeader.d.ts +8 -1
  69. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  70. package/dist/Dialog/DialogHeader.js +13 -4
  71. package/dist/Field/InputClearButton.d.ts +4 -2
  72. package/dist/Field/InputClearButton.d.ts.map +1 -1
  73. package/dist/Field/InputClearButton.js +4 -2
  74. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  75. package/dist/Field/PanelSearchInput.js +1 -1
  76. package/dist/FileInput/FileInput.d.ts.map +1 -1
  77. package/dist/FileInput/FileInput.js +7 -7
  78. package/dist/Icon/Icon.d.ts +6 -31
  79. package/dist/Icon/Icon.d.ts.map +1 -1
  80. package/dist/Icon/Icon.js +8 -71
  81. package/dist/Icon/IconDefaultSizeContext.d.ts +4 -0
  82. package/dist/Icon/IconDefaultSizeContext.d.ts.map +1 -0
  83. package/dist/Icon/IconDefaultSizeContext.js +18 -0
  84. package/dist/Icon/IconSize.stylex.d.ts +65 -0
  85. package/dist/Icon/IconSize.stylex.d.ts.map +1 -0
  86. package/dist/Icon/IconSize.stylex.js +75 -0
  87. package/dist/Item/Item.d.ts +1 -1
  88. package/dist/Item/Item.d.ts.map +1 -1
  89. package/dist/Item/Item.js +4 -3
  90. package/dist/Kbd/Kbd.d.ts +5 -3
  91. package/dist/Kbd/Kbd.d.ts.map +1 -1
  92. package/dist/Kbd/Kbd.js +36 -42
  93. package/dist/Link/Link.d.ts.map +1 -1
  94. package/dist/Link/Link.js +6 -2
  95. package/dist/Link/useLinkComponent.d.ts +5 -15
  96. package/dist/Link/useLinkComponent.d.ts.map +1 -1
  97. package/dist/Link/useLinkComponent.js +34 -51
  98. package/dist/List/List.d.ts +19 -1
  99. package/dist/List/List.d.ts.map +1 -1
  100. package/dist/List/List.js +9 -2
  101. package/dist/List/ListContext.d.ts +1 -0
  102. package/dist/List/ListContext.d.ts.map +1 -1
  103. package/dist/List/ListContext.js +2 -1
  104. package/dist/List/ListItem.d.ts +1 -1
  105. package/dist/List/ListItem.d.ts.map +1 -1
  106. package/dist/List/ListItem.js +9 -2
  107. package/dist/Markdown/Markdown.d.ts +8 -2
  108. package/dist/Markdown/Markdown.d.ts.map +1 -1
  109. package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
  110. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
  111. package/dist/Markdown/Markdown.fr23.bench.js +150 -0
  112. package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
  113. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
  114. package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
  115. package/dist/Markdown/Markdown.js +262 -109
  116. package/dist/Markdown/ast.d.ts +162 -0
  117. package/dist/Markdown/ast.d.ts.map +1 -0
  118. package/dist/Markdown/ast.js +74 -0
  119. package/dist/Markdown/index.d.ts +5 -3
  120. package/dist/Markdown/index.d.ts.map +1 -1
  121. package/dist/Markdown/index.js +3 -2
  122. package/dist/Markdown/parser/index.d.ts +10 -0
  123. package/dist/Markdown/parser/index.d.ts.map +1 -0
  124. package/dist/Markdown/parser/index.js +10 -0
  125. package/dist/Markdown/parser.d.ts +126 -58
  126. package/dist/Markdown/parser.d.ts.map +1 -1
  127. package/dist/Markdown/parser.js +726 -177
  128. package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
  129. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
  130. package/dist/Markdown/plugins/frontmatter.js +132 -0
  131. package/dist/Markdown/plugins/index.d.ts +17 -0
  132. package/dist/Markdown/plugins/index.d.ts.map +1 -0
  133. package/dist/Markdown/plugins/index.js +14 -0
  134. package/dist/Markdown/plugins/protocol.d.ts +191 -0
  135. package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
  136. package/dist/Markdown/plugins/protocol.js +957 -0
  137. package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
  138. package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
  139. package/dist/Markdown/plugins/semanticFence.js +213 -0
  140. package/dist/Markdown/plugins/softBreaks.d.ts +3 -0
  141. package/dist/Markdown/plugins/softBreaks.d.ts.map +1 -0
  142. package/dist/Markdown/plugins/softBreaks.js +172 -0
  143. package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
  144. package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
  145. package/dist/Markdown/plugins/sourceDecoration.js +393 -0
  146. package/dist/Markdown/plugins/textTransform.d.ts +30 -0
  147. package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
  148. package/dist/Markdown/plugins/textTransform.js +374 -0
  149. package/dist/Markdown/remark.d.ts +196 -0
  150. package/dist/Markdown/remark.d.ts.map +1 -0
  151. package/dist/Markdown/remark.js +1062 -0
  152. package/dist/Markdown/url.d.ts +6 -0
  153. package/dist/Markdown/url.d.ts.map +1 -0
  154. package/dist/Markdown/url.js +31 -0
  155. package/dist/Markdown/utils.d.ts +4 -2
  156. package/dist/Markdown/utils.d.ts.map +1 -1
  157. package/dist/Markdown/utils.js +2 -1
  158. package/dist/MetadataList/MetadataList.js +3 -3
  159. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  160. package/dist/NumberInput/NumberInput.js +4 -4
  161. package/dist/Outline/index.d.ts +1 -0
  162. package/dist/Outline/index.d.ts.map +1 -1
  163. package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
  164. package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
  165. package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
  166. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
  167. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  168. package/dist/Outline/useOutlineFromMarkdown.js +8 -3
  169. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  170. package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
  171. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  172. package/dist/PowerSearch/PowerSearchValueEditor.js +5 -0
  173. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  174. package/dist/ProgressBar/ProgressBar.js +36 -31
  175. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  176. package/dist/RadioList/RadioListItem.js +13 -1
  177. package/dist/ScrollableArea/ScrollableArea.d.ts +1 -0
  178. package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
  179. package/dist/ScrollableArea/ScrollableArea.js +1 -0
  180. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  181. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  182. package/dist/SegmentedControl/SegmentedControl.js +1 -0
  183. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  184. package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
  185. package/dist/Selector/Selector.d.ts +9 -7
  186. package/dist/Selector/Selector.d.ts.map +1 -1
  187. package/dist/Selector/Selector.js +16 -7
  188. package/dist/SideNav/SideNav.d.ts +2 -1
  189. package/dist/SideNav/SideNav.d.ts.map +1 -1
  190. package/dist/SideNav/SideNav.js +9 -3
  191. package/dist/Slider/Slider.d.ts.map +1 -1
  192. package/dist/Slider/Slider.js +28 -12
  193. package/dist/Spinner/Spinner.d.ts.map +1 -1
  194. package/dist/Spinner/Spinner.js +23 -7
  195. package/dist/Switch/Switch.d.ts.map +1 -1
  196. package/dist/Switch/Switch.js +11 -0
  197. package/dist/TabList/Tab.d.ts +1 -1
  198. package/dist/TabList/Tab.d.ts.map +1 -1
  199. package/dist/TabList/Tab.js +20 -7
  200. package/dist/Table/Table.d.ts +1 -0
  201. package/dist/Table/Table.d.ts.map +1 -1
  202. package/dist/Table/Table.js +29 -13
  203. package/dist/TextArea/TextArea.d.ts.map +1 -1
  204. package/dist/TextArea/TextArea.js +1 -1
  205. package/dist/TextInput/TextInput.d.ts.map +1 -1
  206. package/dist/TextInput/TextInput.js +2 -2
  207. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  208. package/dist/TimeInput/TimeInput.js +4 -4
  209. package/dist/Timer/Timer.d.ts +49 -0
  210. package/dist/Timer/Timer.d.ts.map +1 -0
  211. package/dist/Timer/Timer.js +158 -0
  212. package/dist/Timer/index.d.ts +9 -0
  213. package/dist/Timer/index.d.ts.map +1 -0
  214. package/dist/Timer/index.js +10 -0
  215. package/dist/ToggleButton/ToggleButton.d.ts +9 -6
  216. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  217. package/dist/ToggleButton/ToggleButton.js +15 -27
  218. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  219. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  220. package/dist/TopNav/TopNavMenu.js +3 -2
  221. package/dist/TreeList/TreeList.d.ts.map +1 -1
  222. package/dist/TreeList/TreeList.js +3 -0
  223. package/dist/TreeList/TreeListItem.d.ts +6 -1
  224. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  225. package/dist/TreeList/TreeListItem.js +12 -2
  226. package/dist/TreeList/TreeListTypes.d.ts +8 -1
  227. package/dist/TreeList/TreeListTypes.d.ts.map +1 -1
  228. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  229. package/dist/Typeahead/BaseTypeahead.js +16 -7
  230. package/dist/astryx.css +27 -11
  231. package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
  232. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
  233. package/dist/hooks/scrollKeyboardDelegation.js +146 -0
  234. package/dist/hooks/useClickableContainer.d.ts +10 -1
  235. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  236. package/dist/hooks/useClickableContainer.js +15 -4
  237. package/dist/hooks/useScrollableArea.d.ts +6 -2
  238. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  239. package/dist/hooks/useScrollableArea.js +17 -5
  240. package/dist/index.d.ts +1 -0
  241. package/dist/index.d.ts.map +1 -1
  242. package/dist/index.js +3 -0
  243. package/dist/theme/declarationBoundary.d.ts +17 -0
  244. package/dist/theme/declarationBoundary.d.ts.map +1 -0
  245. package/dist/theme/declarationBoundary.js +343 -0
  246. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  247. package/dist/theme/derivedVarRegistry.js +4 -0
  248. package/dist/theme/generateThemeRules.d.ts +13 -7
  249. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  250. package/dist/theme/generateThemeRules.js +140 -34
  251. package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
  252. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  253. package/dist/utils/interactionOverlay.stylex.js +9 -0
  254. package/dist/utils/safeUrl.d.ts +11 -0
  255. package/dist/utils/safeUrl.d.ts.map +1 -0
  256. package/dist/utils/safeUrl.js +78 -0
  257. package/locales/af-ZA.json +530 -1
  258. package/locales/ar-SA.json +490 -1
  259. package/locales/ca-ES.json +514 -1
  260. package/locales/cs-CZ.json +498 -1
  261. package/locales/da-DK.json +522 -1
  262. package/locales/de-DE.json +522 -1
  263. package/locales/el-GR.json +498 -1
  264. package/locales/es-ES.json +510 -1
  265. package/locales/fi-FI.json +498 -1
  266. package/locales/fr-FR.json +534 -1
  267. package/locales/he-IL.json +498 -1
  268. package/locales/hu-HU.json +498 -1
  269. package/locales/it-IT.json +510 -1
  270. package/locales/ja-JP.json +490 -1
  271. package/locales/ko-KR.json +498 -1
  272. package/locales/nl-NL.json +534 -1
  273. package/locales/no-NO.json +510 -1
  274. package/locales/pl-PL.json +506 -1
  275. package/locales/pt-BR.json +506 -1
  276. package/locales/pt-PT.json +506 -1
  277. package/locales/ro-RO.json +506 -1
  278. package/locales/ru-RU.json +498 -1
  279. package/locales/sr-SP.json +498 -1
  280. package/locales/sv-SE.json +502 -1
  281. package/locales/tr-TR.json +498 -1
  282. package/locales/uk-UA.json +498 -1
  283. package/locales/vi-VN.json +502 -1
  284. package/locales/zh-CN.json +490 -1
  285. package/locales/zh-TW.json +490 -1
  286. package/package.json +24 -4
  287. package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
  288. package/src/BottomSheet/BottomSheet.spec.md +46 -20
  289. package/src/BottomSheet/BottomSheet.test.tsx +6 -3
  290. package/src/BottomSheet/BottomSheet.tsx +3 -1
  291. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
  292. package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
  293. package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
  294. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
  295. package/src/Button/Button.doc.mjs +5 -5
  296. package/src/Button/Button.tsx +15 -13
  297. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
  298. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
  299. package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
  300. package/src/Button/__tests__/Button.a11y.states.ts +9 -0
  301. package/src/Chat/ChatComposer.doc.mjs +14 -0
  302. package/src/Chat/ChatComposer.spec.md +230 -0
  303. package/src/Chat/ChatComposer.test.tsx +57 -0
  304. package/src/Chat/ChatComposer.tsx +21 -9
  305. package/src/Chat/ChatComposerDrawer.doc.mjs +63 -5
  306. package/src/Chat/ChatComposerDrawer.spec.md +267 -0
  307. package/src/Chat/ChatComposerDrawer.test.tsx +81 -12
  308. package/src/Chat/ChatComposerDrawer.tsx +38 -9
  309. package/src/Chat/ChatComposerInput.doc.mjs +114 -26
  310. package/src/Chat/ChatComposerInput.spec.md +185 -0
  311. package/src/Chat/ChatComposerInput.test.tsx +113 -3
  312. package/src/Chat/ChatComposerInput.tsx +78 -13
  313. package/src/Chat/ChatComposerTokenElement.spec.md +152 -0
  314. package/src/Chat/ChatComposerTokenElement.test.tsx +85 -0
  315. package/src/Chat/ChatDictationButton.doc.mjs +3 -3
  316. package/src/Chat/ChatDictationButton.spec.md +160 -0
  317. package/src/Chat/ChatDictationButton.test.tsx +92 -27
  318. package/src/Chat/ChatDictationButton.tsx +8 -6
  319. package/src/Chat/ChatLayout.doc.mjs +12 -4
  320. package/src/Chat/ChatLayout.spec.md +271 -0
  321. package/src/Chat/ChatLayout.test.tsx +28 -0
  322. package/src/Chat/ChatLayout.tsx +19 -0
  323. package/src/Chat/ChatLayoutScrollButton.spec.md +338 -0
  324. package/src/Chat/ChatLayoutScrollButton.test.tsx +31 -0
  325. package/src/Chat/ChatLayoutScrollButton.tsx +31 -14
  326. package/src/Chat/ChatMessageBubble.doc.mjs +28 -15
  327. package/src/Chat/ChatMessageBubble.spec.md +263 -0
  328. package/src/Chat/ChatMessageBubble.test.tsx +93 -0
  329. package/src/Chat/ChatMessageBubble.tsx +8 -3
  330. package/src/Chat/ChatMessageList.spec.md +222 -0
  331. package/src/Chat/ChatMessageList.test.tsx +64 -2
  332. package/src/Chat/ChatMessageList.tsx +4 -3
  333. package/src/Chat/ChatMessageMetadata.doc.mjs +57 -3
  334. package/src/Chat/ChatMessageMetadata.spec.md +220 -0
  335. package/src/Chat/ChatMessageMetadata.test.tsx +34 -0
  336. package/src/Chat/ChatMessageMetadata.tsx +13 -13
  337. package/src/Chat/ChatSendButton.doc.mjs +32 -0
  338. package/src/Chat/ChatSendButton.spec.md +227 -0
  339. package/src/Chat/ChatSendButton.test.tsx +128 -8
  340. package/src/Chat/ChatSendButton.tsx +6 -4
  341. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +514 -0
  342. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +740 -0
  343. package/src/Chat/__tests__/ChatMessageBubble.a11y.chromium.spec.ts +457 -0
  344. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.test.ts +91 -0
  345. package/src/Chat/__tests__/ChatMessageBubble.auditProvenance.ts +91 -0
  346. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +456 -0
  347. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +413 -0
  348. package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1522 -0
  349. package/src/Chat/index.ts +1 -0
  350. package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
  351. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  352. package/src/CheckboxInput/CheckboxInput.tsx +21 -1
  353. package/src/Citation/Citation.doc.mjs +2 -2
  354. package/src/Citation/Citation.test.tsx +17 -0
  355. package/src/Citation/Citation.tsx +4 -2
  356. package/src/ClickableCard/ClickableCard.doc.mjs +2 -2
  357. package/src/ClickableCard/ClickableCard.test.tsx +102 -5
  358. package/src/CodeBlock/highlightRanges.test.ts +143 -1
  359. package/src/CodeBlock/highlightRanges.ts +15 -5
  360. package/src/Collapsible/Collapsible.doc.mjs +11 -0
  361. package/src/Collapsible/Collapsible.test.tsx +21 -0
  362. package/src/Collapsible/Collapsible.tsx +5 -0
  363. package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
  364. package/src/ComplexSelector/ComplexSelector.tsx +6 -1
  365. package/src/DateInput/DateInput.tsx +6 -1
  366. package/src/DateInput/NativeDateField.tsx +24 -8
  367. package/src/DateInput/TouchDateField.tsx +6 -2
  368. package/src/DateRangeInput/DateRangeInput.tsx +6 -1
  369. package/src/DateTimeInput/DateTimeInput.tsx +6 -1
  370. package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
  371. package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
  372. package/src/Dialog/Dialog.doc.mjs +2 -0
  373. package/src/Dialog/DialogHeader.doc.mjs +22 -0
  374. package/src/Dialog/DialogHeader.test.tsx +167 -3
  375. package/src/Dialog/DialogHeader.tsx +37 -6
  376. package/src/Dialog/modules/DialogHeader.spec.md +101 -42
  377. package/src/DropdownMenu/DropdownMenu.test.tsx +5 -2
  378. package/src/Field/InputClearButton.test.tsx +17 -3
  379. package/src/Field/InputClearButton.tsx +5 -2
  380. package/src/Field/PanelSearchInput.tsx +5 -2
  381. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
  382. package/src/FileInput/FileInput.tsx +11 -2
  383. package/src/Icon/Icon.doc.mjs +7 -5
  384. package/src/Icon/Icon.spec.md +81 -40
  385. package/src/Icon/Icon.test.tsx +6 -3
  386. package/src/Icon/Icon.tsx +20 -68
  387. package/src/Icon/IconDefaultSizeContext.ts +23 -0
  388. package/src/Icon/IconSize.stylex.ts +70 -0
  389. package/src/IconButton/IconButton.doc.mjs +3 -3
  390. package/src/IconButton/IconButton.test.tsx +40 -0
  391. package/src/Item/Item.doc.mjs +6 -2
  392. package/src/Item/Item.tsx +9 -3
  393. package/src/Kbd/Kbd.doc.mjs +3 -3
  394. package/src/Kbd/Kbd.test.tsx +57 -1
  395. package/src/Kbd/Kbd.tsx +57 -37
  396. package/src/Layout/LayoutFooter.doc.mjs +17 -0
  397. package/src/Link/Link.doc.mjs +17 -4
  398. package/src/Link/Link.test.tsx +24 -0
  399. package/src/Link/Link.tsx +5 -0
  400. package/src/Link/LinkProvider.doc.mjs +2 -2
  401. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +261 -0
  402. package/src/Link/useLinkComponent.test.tsx +333 -0
  403. package/src/Link/useLinkComponent.ts +29 -57
  404. package/src/List/List.doc.mjs +6 -0
  405. package/src/List/List.spec.md +200 -0
  406. package/src/List/List.test.tsx +117 -1
  407. package/src/List/List.tsx +22 -2
  408. package/src/List/ListContext.tsx +3 -1
  409. package/src/List/ListItem.doc.mjs +2 -2
  410. package/src/List/ListItem.source-build.test.mjs +41 -0
  411. package/src/List/ListItem.tsx +26 -2
  412. package/src/Markdown/Markdown.doc.mjs +300 -2
  413. package/src/Markdown/Markdown.fr23.bench.ts +174 -0
  414. package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
  415. package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
  416. package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
  417. package/src/Markdown/Markdown.public.test.ts +130 -3
  418. package/src/Markdown/Markdown.renderBoundary.test.tsx +72 -0
  419. package/src/Markdown/Markdown.spec.md +210 -45
  420. package/src/Markdown/Markdown.test.tsx +87 -3
  421. package/src/Markdown/Markdown.tsx +414 -135
  422. package/src/Markdown/ast.test.ts +307 -0
  423. package/src/Markdown/ast.ts +337 -0
  424. package/src/Markdown/incremental.test.ts +43 -0
  425. package/src/Markdown/index.ts +37 -1
  426. package/src/Markdown/modules/remark.spec.md +269 -0
  427. package/src/Markdown/modules/softBreaks.spec.md +137 -0
  428. package/src/Markdown/parser/index.ts +64 -0
  429. package/src/Markdown/parser.public.test.ts +103 -0
  430. package/src/Markdown/parser.test.ts +38 -6
  431. package/src/Markdown/parser.ts +1221 -242
  432. package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
  433. package/src/Markdown/plugins/frontmatter.ts +198 -0
  434. package/src/Markdown/plugins/index.ts +54 -0
  435. package/src/Markdown/plugins/protocol.test.tsx +1022 -0
  436. package/src/Markdown/plugins/protocol.ts +1618 -0
  437. package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
  438. package/src/Markdown/plugins/semanticFence.ts +424 -0
  439. package/src/Markdown/plugins/softBreaks.test.tsx +172 -0
  440. package/src/Markdown/plugins/softBreaks.ts +169 -0
  441. package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
  442. package/src/Markdown/plugins/sourceDecoration.ts +539 -0
  443. package/src/Markdown/plugins/textTransform.test.ts +467 -0
  444. package/src/Markdown/plugins/textTransform.ts +554 -0
  445. package/src/Markdown/remark.test.tsx +1877 -0
  446. package/src/Markdown/remark.ts +1574 -0
  447. package/src/Markdown/url.ts +36 -0
  448. package/src/Markdown/utils.ts +13 -1
  449. package/src/MetadataList/MetadataList.test.tsx +4 -2
  450. package/src/MetadataList/MetadataList.tsx +3 -3
  451. package/src/MultiSelector/MultiSelector.test.tsx +1 -35
  452. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
  453. package/src/NumberInput/NumberInput.tsx +6 -1
  454. package/src/Outline/Outline.doc.mjs +7 -5
  455. package/src/Outline/Outline.spec.md +1 -1
  456. package/src/Outline/index.ts +1 -0
  457. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
  458. package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
  459. package/src/Outline/useOutlineFromMarkdown.ts +15 -3
  460. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  461. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
  462. package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
  463. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +51 -0
  464. package/src/PowerSearch/PowerSearchValueEditor.tsx +4 -0
  465. package/src/ProgressBar/ProgressBar.test.tsx +29 -11
  466. package/src/ProgressBar/ProgressBar.tsx +59 -72
  467. package/src/RadioList/RadioList.doc.mjs +11 -0
  468. package/src/RadioList/RadioList.test.tsx +32 -0
  469. package/src/RadioList/RadioListItem.tsx +25 -1
  470. package/src/ScrollableArea/ScrollableArea.tsx +1 -0
  471. package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
  472. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  473. package/src/SegmentedControl/SegmentedControl.test.tsx +61 -0
  474. package/src/SegmentedControl/SegmentedControl.tsx +2 -1
  475. package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
  476. package/src/Selector/Selector.doc.mjs +3 -3
  477. package/src/Selector/Selector.spec.md +51 -49
  478. package/src/Selector/Selector.test.tsx +61 -55
  479. package/src/Selector/Selector.tsx +34 -15
  480. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
  481. package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
  482. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
  483. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
  484. package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
  485. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +45 -0
  486. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
  487. package/src/SideNav/SideNav.doc.mjs +1 -1
  488. package/src/SideNav/SideNav.test.tsx +10 -0
  489. package/src/SideNav/SideNav.tsx +14 -2
  490. package/src/Slider/Slider.doc.mjs +17 -3
  491. package/src/Slider/Slider.test.tsx +221 -0
  492. package/src/Slider/Slider.tsx +40 -9
  493. package/src/Spinner/Spinner.test.tsx +4 -0
  494. package/src/Spinner/Spinner.tsx +31 -18
  495. package/src/Switch/Switch.doc.mjs +11 -0
  496. package/src/Switch/Switch.test.tsx +16 -0
  497. package/src/Switch/Switch.tsx +28 -0
  498. package/src/TabList/Tab.tsx +35 -7
  499. package/src/TabList/TabList.doc.mjs +11 -0
  500. package/src/TabList/TabList.spec.md +204 -0
  501. package/src/TabList/TabList.test.tsx +66 -0
  502. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
  503. package/src/Table/Table.doc.mjs +1 -1
  504. package/src/Table/Table.spec.md +54 -40
  505. package/src/Table/Table.test.tsx +83 -10
  506. package/src/Table/Table.tsx +30 -22
  507. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +137 -0
  508. package/src/TextArea/TextArea.tsx +6 -1
  509. package/src/TextInput/TextInput.test.tsx +20 -1
  510. package/src/TextInput/TextInput.tsx +6 -1
  511. package/src/TimeInput/TimeInput.tsx +6 -1
  512. package/src/Timer/Timer.doc.mjs +183 -0
  513. package/src/Timer/Timer.spec.md +215 -0
  514. package/src/Timer/Timer.test.tsx +302 -0
  515. package/src/Timer/Timer.tsx +258 -0
  516. package/src/Timer/index.ts +11 -0
  517. package/src/ToggleButton/ToggleButton.doc.mjs +3 -3
  518. package/src/ToggleButton/ToggleButton.test.tsx +299 -4
  519. package/src/ToggleButton/ToggleButton.tsx +26 -33
  520. package/src/ToggleButton/ToggleButtonGroup.doc.mjs +3 -3
  521. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
  522. package/src/Token/Token.doc.mjs +2 -2
  523. package/src/Tokenizer/Tokenizer.spec.md +142 -75
  524. package/src/TopNav/TopNavMenu.doc.mjs +2 -2
  525. package/src/TopNav/TopNavMenu.test.tsx +30 -0
  526. package/src/TopNav/TopNavMenu.tsx +7 -2
  527. package/src/TreeList/TreeList.doc.mjs +3 -3
  528. package/src/TreeList/TreeList.spec.md +123 -75
  529. package/src/TreeList/TreeList.test.tsx +29 -0
  530. package/src/TreeList/TreeList.tsx +3 -0
  531. package/src/TreeList/TreeListItem.tsx +15 -1
  532. package/src/TreeList/TreeListTypes.ts +11 -1
  533. package/src/Typeahead/BaseTypeahead.spec.md +4 -3
  534. package/src/Typeahead/BaseTypeahead.tsx +21 -7
  535. package/src/Typeahead/Typeahead.test.tsx +53 -0
  536. package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
  537. package/src/__tests__/pressState.ts +93 -0
  538. package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
  539. package/src/hooks/scrollKeyboardDelegation.ts +233 -0
  540. package/src/hooks/useClickableContainer.test.tsx +236 -0
  541. package/src/hooks/useClickableContainer.ts +20 -4
  542. package/src/hooks/useScrollableArea.doc.mjs +15 -3
  543. package/src/hooks/useScrollableArea.test.tsx +59 -1
  544. package/src/hooks/useScrollableArea.ts +34 -10
  545. package/src/index.ts +3 -0
  546. package/src/inputFontFloor.test.ts +106 -0
  547. package/src/tailwind-theme.css +0 -6
  548. package/src/theme/Theme.test.tsx +32 -0
  549. package/src/theme/declarationBoundary.test.ts +126 -0
  550. package/src/theme/declarationBoundary.ts +347 -0
  551. package/src/theme/derivedVarRegistry.test.ts +7 -0
  552. package/src/theme/derivedVarRegistry.ts +1 -0
  553. package/src/theme/generateThemeRules.test.ts +526 -1
  554. package/src/theme/generateThemeRules.ts +228 -50
  555. package/src/theme/tokenValueCompat.test.ts +4 -1
  556. package/src/utils/interactionOverlay.stylex.ts +20 -0
  557. package/src/utils/safeUrl.test.ts +88 -0
  558. package/src/utils/safeUrl.ts +85 -0
@@ -4,11 +4,11 @@
4
4
 
5
5
  /**
6
6
  * @file Markdown.tsx
7
- * @input Markdown string, parser AST types, optional custom renderers
7
+ * @input Markdown string, canonical AST, optional plugins and custom renderers
8
8
  * @output Exports Markdown component, MarkdownProps, and renderer contracts
9
9
  * @position Core implementation; renders markdown as Astryx components
10
10
  */
11
- import { useMemo, useRef } from 'react';
11
+ import { Component, Suspense, useMemo, useRef } from 'react';
12
12
  import { Fragment } from 'react';
13
13
  import * as stylex from '@stylexjs/stylex';
14
14
  import "../theme/tokens.stylex.js";
@@ -31,7 +31,11 @@ import { computeBoundaries, computeSegments } from "./streaming.js";
31
31
  import { useTheme } from "../theme/useTheme.js";
32
32
  import { Citation } from "../Citation/Citation.js";
33
33
  import { useLinkComponent } from "../Link/useLinkComponent.js";
34
- import { parseInline, parseMarkdown, parseMarkdownIncremental, createIncrementalState, trimStreamingArtifacts, inlineText, slugify, uniqueSlug } from "./parser.js";
34
+ import { parseInlineAst, parseMarkdownAst, parseMarkdownAstIncremental, createIncrementalState, trimStreamingArtifacts, slugify, uniqueSlug } from "./parser.js";
35
+ import { getMarkdownAstLegacyCodeLanguage, markdownAstText } from "./ast.js";
36
+ import { applyMarkdownTransforms, getMarkdownExtensionRenderer, markdownExtensionText, prepareMarkdownPlugins, reportMarkdownPluginFailure } from "./plugins/protocol.js";
37
+ import { getMarkdownFenceProposal } from "./plugins/semanticFence.js";
38
+ import { sanitizeMarkdownLinkUrl, sanitizeMarkdownUrl } from "./url.js";
35
39
  import { themeProps } from "../utils/themeProps.js";
36
40
  import { useTranslator } from "../i18n/index.js";
37
41
 
@@ -331,20 +335,20 @@ function countInlineTextLength(nodes) {
331
335
  for (const node of nodes) {
332
336
  switch (node.type) {
333
337
  case 'text':
334
- len += node.content.length;
338
+ len += node.value.length;
335
339
  break;
336
- case 'code':
337
- len += node.content.length;
340
+ case 'inlineCode':
341
+ len += node.value.length;
338
342
  break;
339
- case 'math':
343
+ case 'inlineMath':
340
344
  len += node.value.length;
341
345
  break;
342
346
  case 'image':
343
347
  len += node.alt.length;
344
348
  break;
345
- case 'bold':
346
- case 'italic':
347
- case 'strikethrough':
349
+ case 'strong':
350
+ case 'emphasis':
351
+ case 'delete':
348
352
  case 'link':
349
353
  len += countInlineTextLength(node.children);
350
354
  break;
@@ -354,6 +358,9 @@ function countInlineTextLength(nodes) {
354
358
  case 'citation':
355
359
  len += 1;
356
360
  break;
361
+ case 'extension':
362
+ len += node.source?.length ?? 0;
363
+ break;
357
364
  }
358
365
  }
359
366
  return len;
@@ -370,8 +377,8 @@ function countBlockTextLength(nodes) {
370
377
  case 'paragraph':
371
378
  len += countInlineTextLength(node.children);
372
379
  break;
373
- case 'codeblock':
374
- len += node.content.length;
380
+ case 'code':
381
+ len += node.value.length;
375
382
  break;
376
383
  case 'math':
377
384
  len += node.value.length;
@@ -380,21 +387,21 @@ function countBlockTextLength(nodes) {
380
387
  len += countBlockTextLength(node.children);
381
388
  break;
382
389
  case 'list':
383
- for (const item of node.items) {
390
+ for (const item of node.children) {
384
391
  len += countBlockTextLength(item.children);
385
392
  }
386
393
  break;
387
394
  case 'table':
388
- for (const h of node.headers) {
389
- len += countInlineTextLength(h.children);
390
- }
391
- for (const row of node.rows) {
392
- for (const cell of row) {
395
+ for (const row of node.children) {
396
+ for (const cell of row.children) {
393
397
  len += countInlineTextLength(cell.children);
394
398
  }
395
399
  }
396
400
  break;
397
- case 'hr':
401
+ case 'extension':
402
+ len += node.source?.length ?? 0;
403
+ break;
404
+ case 'thematicBreak':
398
405
  break;
399
406
  case 'image':
400
407
  len += node.alt.length;
@@ -413,26 +420,6 @@ const headingStyles = {
413
420
  };
414
421
 
415
422
  // ---------------------------------------------------------------------------
416
- // URL sanitization — block dangerous protocols
417
- // ---------------------------------------------------------------------------
418
-
419
- const DANGEROUS_URL_PATTERN = /^(javascript|data|vbscript):/i;
420
- function sanitizeUrl(url) {
421
- // Strip control characters before testing, the same normalization the
422
- // parser's isSafeUrl applies — the anchored pattern must see the URL the
423
- // way a browser will. Return the normalized value so the stripped
424
- // characters don't ride along into an attribute or component override.
425
- // eslint-disable-next-line no-control-regex -- control chars are the bypass
426
- const normalized = url.replace(/[\x00-\x1f\x7f]/g, '').trim();
427
- if (normalized.length === 0) {
428
- return null;
429
- }
430
- if (DANGEROUS_URL_PATTERN.test(normalized)) {
431
- return null;
432
- }
433
- return normalized;
434
- }
435
-
436
423
  // ---------------------------------------------------------------------------
437
424
  // Inline plugin matching
438
425
  // ---------------------------------------------------------------------------
@@ -524,6 +511,42 @@ function applyInlinePlugins(text, plugins) {
524
511
  }
525
512
  return segments;
526
513
  }
514
+ class MarkdownPluginBoundary extends Component {
515
+ state = {
516
+ failed: false,
517
+ resetKey: this.props.resetKey,
518
+ resetRenderer: this.props.resetRenderer
519
+ };
520
+ static getDerivedStateFromError() {
521
+ return {
522
+ failed: true
523
+ };
524
+ }
525
+ static getDerivedStateFromProps(props, state) {
526
+ return props.resetKey === state.resetKey && props.resetRenderer === state.resetRenderer ? null : {
527
+ failed: false,
528
+ resetKey: props.resetKey,
529
+ resetRenderer: props.resetRenderer
530
+ };
531
+ }
532
+ componentDidCatch(error) {
533
+ reportMarkdownPluginFailure(this.props.pluginName, 'render', error);
534
+ }
535
+ render() {
536
+ return this.state.failed ? this.props.fallback : this.props.children;
537
+ }
538
+ }
539
+ function useStableMarkdownSyntaxEntries(plugins) {
540
+ const identity = plugins?.syntaxIdentity ?? '';
541
+ const syntaxEntriesRef = useRef(undefined);
542
+ if (syntaxEntriesRef.current == null || syntaxEntriesRef.current.identity !== identity) {
543
+ syntaxEntriesRef.current = {
544
+ identity,
545
+ entries: plugins == null || identity === '' ? undefined : plugins.syntaxEntries
546
+ };
547
+ }
548
+ return syntaxEntriesRef.current.entries;
549
+ }
527
550
 
528
551
  // ---------------------------------------------------------------------------
529
552
  // Inline renderer
@@ -571,12 +594,12 @@ function getCitationNumber(ctx, sourceId) {
571
594
  }
572
595
  return num;
573
596
  }
574
- function renderInline(node, index, onLinkClick, cursor, citationCtx, linkComponent = 'a', inlinePlugins, components) {
597
+ function renderInline(node, index, onLinkClick, cursor, citationCtx, linkComponent = 'a', inlinePlugins, components, preparedPlugins) {
575
598
  switch (node.type) {
576
599
  case 'text':
577
600
  {
578
601
  if (inlinePlugins && inlinePlugins.length > 0) {
579
- const segments = applyInlinePlugins(node.content, inlinePlugins);
602
+ const segments = applyInlinePlugins(node.value, inlinePlugins);
580
603
  // If no plugin matched, fall through to the normal path
581
604
  // O(1) guard: applyInlinePlugins returns a single text segment when
582
605
  // nothing matched — skip the plugin path entirely in that case.
@@ -599,39 +622,39 @@ function renderInline(node, index, onLinkClick, cursor, citationCtx, linkCompone
599
622
  }, index);
600
623
  }
601
624
  }
602
- return wrapTextWithFade(node.content, cursor, index);
625
+ return wrapTextWithFade(node.value, cursor, index);
603
626
  }
604
- case 'bold':
627
+ case 'strong':
605
628
  return /*#__PURE__*/_jsx("strong", {
606
629
  ...{
607
630
  className: "x2mo6ok"
608
631
  },
609
- children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
632
+ children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
610
633
  }, index);
611
- case 'italic':
634
+ case 'emphasis':
612
635
  return /*#__PURE__*/_jsx("em", {
613
- children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
636
+ children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
614
637
  }, index);
615
- case 'strikethrough':
638
+ case 'delete':
616
639
  return /*#__PURE__*/_jsx("del", {
617
640
  ...{
618
641
  className: "xv1l7n4"
619
642
  },
620
- children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
643
+ children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
621
644
  }, index);
622
- case 'code':
645
+ case 'inlineCode':
623
646
  {
624
647
  // Track code content length for cursor but don't split inside code
625
- cursor.offset += node.content.length;
648
+ cursor.offset += node.value.length;
626
649
  const InlineCodeComp = components?.inlineCode;
627
650
  const codeEl = InlineCodeComp ? /*#__PURE__*/_jsx(InlineCodeComp, {
628
- children: node.content
651
+ children: node.value
629
652
  }, index) : /*#__PURE__*/_jsx(Code, {
630
- children: node.content
653
+ children: node.value
631
654
  }, index);
632
655
  return codeEl;
633
656
  }
634
- case 'math':
657
+ case 'inlineMath':
635
658
  {
636
659
  const MathComp = components?.math;
637
660
  if (MathComp == null) {
@@ -645,18 +668,18 @@ function renderInline(node, index, onLinkClick, cursor, citationCtx, linkCompone
645
668
  }
646
669
  case 'link':
647
670
  {
648
- const safeHref = sanitizeUrl(node.href);
671
+ const safeHref = sanitizeMarkdownLinkUrl(node.url);
649
672
  if (safeHref == null) {
650
673
  // Unsafe URL — render as plain text
651
674
  return /*#__PURE__*/_jsx("span", {
652
- children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
675
+ children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
653
676
  }, index);
654
677
  }
655
678
  const LinkComp = components?.link;
656
679
  if (LinkComp) {
657
680
  return /*#__PURE__*/_jsx(LinkComp, {
658
681
  href: safeHref,
659
- children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
682
+ children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
660
683
  }, index);
661
684
  }
662
685
  const isExternal = safeHref.startsWith('https://') || safeHref.startsWith('http://');
@@ -680,12 +703,12 @@ function renderInline(node, index, onLinkClick, cursor, citationCtx, linkCompone
680
703
  ...{
681
704
  className: "xjse4m1 x1bvjpef"
682
705
  },
683
- children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
706
+ children: node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
684
707
  }, index);
685
708
  }
686
709
  case 'image':
687
710
  {
688
- const safeSrc = sanitizeUrl(node.src);
711
+ const safeSrc = sanitizeMarkdownUrl(node.url);
689
712
  if (safeSrc == null) {
690
713
  return /*#__PURE__*/_jsxs("span", {
691
714
  children: ["[", node.alt, "]"]
@@ -706,6 +729,33 @@ function renderInline(node, index, onLinkClick, cursor, citationCtx, linkCompone
706
729
  }
707
730
  }, index);
708
731
  }
732
+ case 'extension':
733
+ {
734
+ const renderer = getMarkdownExtensionRenderer(preparedPlugins, node);
735
+ const fallback = wrapTextWithFade(node.source ?? markdownExtensionText(preparedPlugins, node), cursor, index);
736
+ if (renderer == null) {
737
+ return fallback;
738
+ }
739
+ let rendered;
740
+ try {
741
+ rendered = renderer.render({
742
+ node
743
+ });
744
+ } catch (error) {
745
+ reportMarkdownPluginFailure(node.plugin, 'render', error);
746
+ return fallback;
747
+ }
748
+ return /*#__PURE__*/_jsx(MarkdownPluginBoundary, {
749
+ pluginName: node.plugin,
750
+ resetKey: node,
751
+ resetRenderer: renderer.render,
752
+ fallback: fallback,
753
+ children: /*#__PURE__*/_jsx(Suspense, {
754
+ fallback: fallback,
755
+ children: rendered
756
+ })
757
+ }, index);
758
+ }
709
759
  case 'break':
710
760
  cursor.offset += 1;
711
761
  return /*#__PURE__*/_jsx("br", {}, index);
@@ -746,10 +796,10 @@ function getElementSpacing(node, density) {
746
796
  const compact = density === 'compact';
747
797
  switch (node.type) {
748
798
  case 'heading':
749
- return node.level <= 3 ? compact ? styles.spacingHeadingMajorCompact : styles.spacingHeadingMajorDefault : compact ? styles.spacingHeadingMinorCompact : styles.spacingHeadingMinorDefault;
799
+ return node.depth <= 3 ? compact ? styles.spacingHeadingMajorCompact : styles.spacingHeadingMajorDefault : compact ? styles.spacingHeadingMinorCompact : styles.spacingHeadingMinorDefault;
750
800
  case 'paragraph':
751
801
  return compact ? styles.spacingParagraphCompact : styles.spacingParagraphDefault;
752
- case 'codeblock':
802
+ case 'code':
753
803
  case 'math':
754
804
  return compact ? styles.spacingCodeblockCompact : styles.spacingCodeblockDefault;
755
805
  case 'blockquote':
@@ -758,7 +808,9 @@ function getElementSpacing(node, density) {
758
808
  return compact ? styles.spacingListCompact : styles.spacingListDefault;
759
809
  case 'table':
760
810
  return compact ? styles.spacingTableCompact : styles.spacingTableDefault;
761
- case 'hr':
811
+ case 'extension':
812
+ return compact ? styles.spacingParagraphCompact : styles.spacingParagraphDefault;
813
+ case 'thematicBreak':
762
814
  return compact ? styles.spacingHrCompact : styles.spacingHrDefault;
763
815
  case 'image':
764
816
  return compact ? styles.spacingImageCompact : styles.spacingImageDefault;
@@ -774,11 +826,16 @@ function getElementSpacing(node, density) {
774
826
  * Buckets: ≤6 chars → 60px, 7–15 → 80px, >15 → 120px.
775
827
  */
776
828
  function computeTableColumnMinWidths(node) {
777
- return node.headers.map((h, colIdx) => {
778
- let maxLen = countInlineTextLength(h.children);
779
- for (const row of node.rows) {
780
- if (row[colIdx]) {
781
- const len = countInlineTextLength(row[colIdx].children);
829
+ const [header, ...rows] = node.children;
830
+ if (header == null) {
831
+ return [];
832
+ }
833
+ return header.children.map((cell, colIdx) => {
834
+ let maxLen = countInlineTextLength(cell.children);
835
+ for (const row of rows) {
836
+ const rowCell = row.children[colIdx];
837
+ if (rowCell != null) {
838
+ const len = countInlineTextLength(rowCell.children);
782
839
  if (len > maxLen) {
783
840
  maxLen = len;
784
841
  }
@@ -787,7 +844,7 @@ function computeTableColumnMinWidths(node) {
787
844
  return maxLen <= 6 ? 60 : maxLen <= 15 ? 80 : 120;
788
845
  });
789
846
  }
790
- function renderBlock(node, index, blockCount, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent = 'a', inlinePlugins, components, t, headingIdMap) {
847
+ function renderBlock(node, index, blockCount, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent = 'a', inlinePlugins, components, preparedPlugins, t, headingIdMap) {
791
848
  const blockAlignMargin = BLOCK_ALIGN_MARGIN[contentAlign];
792
849
  const blockAlignStyle = blockAlignMargin != null ? dynamicStyles.blockAlign(blockAlignMargin) : null;
793
850
  const spacing = getElementSpacing(node, density);
@@ -796,8 +853,8 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
796
853
  switch (node.type) {
797
854
  case 'heading':
798
855
  {
799
- const level = Math.min(node.level + headingLevelStart - 1, 6);
800
- const headingChildren = node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components));
856
+ const level = Math.min(node.depth + headingLevelStart - 1, 6);
857
+ const headingChildren = node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins));
801
858
  // Only top-level headings get an id: the map is built from the same
802
859
  // traversal parseOutlineFromMarkdown uses (which skips headings nested
803
860
  // in blockquotes / list items), so rendered ids and outline ids stay
@@ -823,7 +880,7 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
823
880
  }
824
881
  case 'paragraph':
825
882
  {
826
- const paraChildren = node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components));
883
+ const paraChildren = node.children.map((c, i) => renderInline(c, i, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins));
827
884
  const ParagraphComp = components?.paragraph;
828
885
  if (ParagraphComp) {
829
886
  return /*#__PURE__*/_jsx(ParagraphComp, {
@@ -847,28 +904,58 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
847
904
  children: paraChildren
848
905
  }, index);
849
906
  }
850
- case 'codeblock':
907
+ case 'code':
851
908
  {
852
909
  // Track codeblock content in cursor for accurate character counting
853
- cursor.offset += node.content.length;
910
+ cursor.offset += node.value.length;
911
+ const language = getMarkdownAstLegacyCodeLanguage(node) ?? 'plaintext';
854
912
  const CodeBlockComp = components?.code;
855
913
  if (CodeBlockComp) {
856
914
  return /*#__PURE__*/_jsx(CodeBlockComp, {
857
- code: node.content,
858
- language: node.language
915
+ code: node.value,
916
+ language: language
859
917
  }, index);
860
918
  }
861
- return /*#__PURE__*/_jsx("div", {
919
+ const fallback = /*#__PURE__*/_jsx("div", {
862
920
  ...mergeProps(themeProps('markdown-codeblock', {
863
921
  density
864
922
  }), stylex.props(spacing, styles.codeBlockWrapper, isFirst && styles.noMarginBlockStart, isLast && styles.noMarginBlockEnd)),
865
923
  children: /*#__PURE__*/_jsx(CodeBlock, {
866
- code: node.content,
867
- language: node.language,
924
+ code: node.value,
925
+ language: language,
868
926
  isCollapsible: true,
869
927
  xstyle: [contentWidthValue != null ? dynamicStyles.blockWidth(contentWidthValue) : undefined, blockAlignStyle]
870
928
  })
871
929
  }, index);
930
+ const proposal = getMarkdownFenceProposal(node);
931
+ if (proposal == null) {
932
+ return fallback;
933
+ }
934
+ const renderer = getMarkdownExtensionRenderer(preparedPlugins, proposal.node);
935
+ if (renderer == null) {
936
+ return fallback;
937
+ }
938
+ try {
939
+ const rendered = renderer.render({
940
+ node: proposal.node
941
+ });
942
+ if (rendered == null || typeof rendered === 'boolean') {
943
+ return fallback;
944
+ }
945
+ return /*#__PURE__*/_jsx(MarkdownPluginBoundary, {
946
+ pluginName: proposal.node.plugin,
947
+ resetKey: proposal.node,
948
+ resetRenderer: renderer.render,
949
+ fallback: fallback,
950
+ children: /*#__PURE__*/_jsx(Suspense, {
951
+ fallback: fallback,
952
+ children: rendered
953
+ })
954
+ }, index);
955
+ } catch (error) {
956
+ reportMarkdownPluginFailure(proposal.node.plugin, 'render', error);
957
+ return fallback;
958
+ }
872
959
  }
873
960
  case 'math':
874
961
  {
@@ -889,7 +976,7 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
889
976
  {
890
977
  const BlockquoteComp = components?.blockquote;
891
978
  if (BlockquoteComp) {
892
- const bqC = node.children.map((c, i) => renderBlock(c, i, node.children.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent, inlinePlugins, components, t));
979
+ const bqC = node.children.map((c, i) => renderBlock(c, i, node.children.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent, inlinePlugins, components, preparedPlugins, t));
893
980
  return /*#__PURE__*/_jsx(BlockquoteComp, {
894
981
  children: bqC
895
982
  }, index);
@@ -899,16 +986,16 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
899
986
  density
900
987
  }),
901
988
  xstyle: [spacing, contentWidthValue != null ? dynamicStyles.proseWidth(contentWidthValue) : undefined, contentAlign !== 'start' ? dynamicStyles.proseAlign(ALIGN_MARGIN[contentAlign]) : undefined, isFirst && styles.noMarginBlockStart, isLast && styles.noMarginBlockEnd],
902
- children: node.children.map((c, i) => renderBlock(c, i, node.children.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent, inlinePlugins, components, t))
989
+ children: node.children.map((c, i) => renderBlock(c, i, node.children.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent, inlinePlugins, components, preparedPlugins, t))
903
990
  }, index);
904
991
  }
905
992
  case 'list':
906
993
  {
907
994
  // Detect task lists: all items have a checked state
908
- const isTaskList = node.items.length > 0 && node.items.every(item => item.checked != null);
995
+ const isTaskList = node.children.length > 0 && node.children.every(item => item.checked != null);
909
996
  if (isTaskList) {
910
997
  // Extract labels from task items — render as rich inline content
911
- const checkedValues = node.items.map((item, i) => ({
998
+ const checkedValues = node.children.map((item, i) => ({
912
999
  item,
913
1000
  key: `task-${i}`
914
1001
  })).filter(({
@@ -927,13 +1014,13 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
927
1014
  xstyle: styles.blockIndent,
928
1015
  isReadOnly: true,
929
1016
  density: "compact",
930
- children: node.items.map((item, i) => {
1017
+ children: node.children.map((item, i) => {
931
1018
  const firstChild = item.children[0];
932
1019
  const isInline = item.children.length === 1 && firstChild?.type === 'paragraph';
933
1020
  const label = isInline ? /*#__PURE__*/_jsx(_Fragment, {
934
- children: firstChild.children.map((c, j) => renderInline(c, j, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
1021
+ children: firstChild.children.map((c, j) => renderInline(c, j, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
935
1022
  }) : /*#__PURE__*/_jsx(_Fragment, {
936
- children: item.children.map((c, j) => renderBlock(c, j, item.children.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent, inlinePlugins, components, t))
1023
+ children: item.children.map((c, j) => renderBlock(c, j, item.children.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent, inlinePlugins, components, preparedPlugins, t))
937
1024
  });
938
1025
  return /*#__PURE__*/_jsx(CheckboxListItem
939
1026
  // eslint-disable-next-line @eslint-react/no-array-index-key -- markdown task items are rendered from positional AST nodes
@@ -954,7 +1041,7 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
954
1041
  density: "compact",
955
1042
  start: node.ordered ? node.start : undefined,
956
1043
  xstyle: styles.blockIndent,
957
- children: node.items.map((item, i) => {
1044
+ children: node.children.map((item, i) => {
958
1045
  const firstChild = item.children[0];
959
1046
  const isInline = item.children.length === 1 && firstChild?.type === 'paragraph';
960
1047
 
@@ -962,9 +1049,9 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
962
1049
  // whole item as a block instead of fading individual text spans.
963
1050
 
964
1051
  const label = isInline ? /*#__PURE__*/_jsx(_Fragment, {
965
- children: firstChild.children.map((c, j) => renderInline(c, j, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
1052
+ children: firstChild.children.map((c, j) => renderInline(c, j, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
966
1053
  }) : /*#__PURE__*/_jsx(_Fragment, {
967
- children: item.children.map((c, j) => renderBlock(c, j, item.children.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent, inlinePlugins, components, t))
1054
+ children: item.children.map((c, j) => renderBlock(c, j, item.children.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidthValue, contentAlign, linkComponent, inlinePlugins, components, preparedPlugins, t))
968
1055
  });
969
1056
  return /*#__PURE__*/_jsx(ListItem
970
1057
  // eslint-disable-next-line @eslint-react/no-array-index-key -- markdown list items are rendered from positional AST nodes
@@ -978,6 +1065,7 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
978
1065
  case 'table':
979
1066
  {
980
1067
  const colMinWidths = computeTableColumnMinWidths(node);
1068
+ const [header, ...rows] = node.children;
981
1069
  return /*#__PURE__*/_jsx("div", {
982
1070
  // Keyboard-focusable so keyboard users can scroll a horizontally
983
1071
  // overflowing GFM table. Uses role="group" (not "region") so
@@ -994,20 +1082,20 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
994
1082
  textOverflow: "wrap",
995
1083
  children: [/*#__PURE__*/_jsx(TableHeader, {
996
1084
  children: /*#__PURE__*/_jsx(TableRow, {
997
- children: node.headers.map((h, i) => /*#__PURE__*/_jsx(TableHeaderCell
1085
+ children: header?.children.map((h, i) => /*#__PURE__*/_jsx(TableHeaderCell
998
1086
  // eslint-disable-next-line @eslint-react/no-array-index-key -- markdown table columns are positional by definition
999
1087
  , {
1000
- xstyle: [dynamicStyles.cellMinWidth(`${colMinWidths[i]}px`), node.alignments[i] === 'center' && cellAlignStyles.center, node.alignments[i] === 'right' && cellAlignStyles.end],
1001
- children: h.children.map((c, j) => renderInline(c, j, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
1088
+ xstyle: [dynamicStyles.cellMinWidth(`${colMinWidths[i]}px`), node.align[i] === 'center' && cellAlignStyles.center, node.align[i] === 'right' && cellAlignStyles.end],
1089
+ children: h.children.map((c, j) => renderInline(c, j, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
1002
1090
  }, i))
1003
1091
  })
1004
1092
  }), /*#__PURE__*/_jsx(TableBody, {
1005
- children: node.rows.map((row, i) => {
1006
- const cells = row.map((cell, j) => /*#__PURE__*/_jsx(TableCell
1093
+ children: rows.map((row, i) => {
1094
+ const cells = row.children.map((cell, j) => /*#__PURE__*/_jsx(TableCell
1007
1095
  // eslint-disable-next-line @eslint-react/no-array-index-key -- markdown table cells are positional by row and column
1008
1096
  , {
1009
- xstyle: [node.alignments[j] === 'center' && cellAlignStyles.center, node.alignments[j] === 'right' && cellAlignStyles.end],
1010
- children: cell.children.map((c, k) => renderInline(c, k, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components))
1097
+ xstyle: [node.align[j] === 'center' && cellAlignStyles.center, node.align[j] === 'right' && cellAlignStyles.end],
1098
+ children: cell.children.map((c, k) => renderInline(c, k, onLinkClick, cursor, citationCtx, linkComponent, inlinePlugins, components, preparedPlugins))
1011
1099
  }, j));
1012
1100
  return /*#__PURE__*/_jsx(TableRow
1013
1101
  // eslint-disable-next-line @eslint-react/no-array-index-key -- markdown table rows are rendered from positional AST nodes
@@ -1019,7 +1107,37 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
1019
1107
  })
1020
1108
  }, index);
1021
1109
  }
1022
- case 'hr':
1110
+ case 'extension':
1111
+ {
1112
+ const renderer = getMarkdownExtensionRenderer(preparedPlugins, node);
1113
+ const fallbackText = node.source ?? markdownExtensionText(preparedPlugins, node);
1114
+ const fallback = wrapTextWithFade(fallbackText, cursor, index);
1115
+ let content = fallback;
1116
+ if (renderer != null) {
1117
+ try {
1118
+ const rendered = renderer.render({
1119
+ node
1120
+ });
1121
+ content = /*#__PURE__*/_jsx(MarkdownPluginBoundary, {
1122
+ pluginName: node.plugin,
1123
+ resetKey: node,
1124
+ resetRenderer: renderer.render,
1125
+ fallback: fallback,
1126
+ children: /*#__PURE__*/_jsx(Suspense, {
1127
+ fallback: fallback,
1128
+ children: rendered
1129
+ })
1130
+ });
1131
+ } catch (error) {
1132
+ reportMarkdownPluginFailure(node.plugin, 'render', error);
1133
+ }
1134
+ }
1135
+ return /*#__PURE__*/_jsx("div", {
1136
+ ...stylex.props(spacing, contentWidthValue != null ? dynamicStyles.proseWidth(contentWidthValue) : null, contentAlign !== 'start' ? dynamicStyles.proseAlign(ALIGN_MARGIN[contentAlign]) : null, isFirst && styles.noMarginBlockStart, isLast && styles.noMarginBlockEnd),
1137
+ children: content
1138
+ }, index);
1139
+ }
1140
+ case 'thematicBreak':
1023
1141
  {
1024
1142
  const HrComp = components?.hr;
1025
1143
  if (HrComp) {
@@ -1033,7 +1151,7 @@ function renderBlock(node, index, blockCount, density, headingLevelStart, onLink
1033
1151
  }
1034
1152
  case 'image':
1035
1153
  {
1036
- const safeSrc = sanitizeUrl(node.src);
1154
+ const safeSrc = sanitizeMarkdownUrl(node.url);
1037
1155
  if (safeSrc == null) {
1038
1156
  return /*#__PURE__*/_jsxs("div", {
1039
1157
  ...mergeProps(themeProps('markdown-image', {
@@ -1093,6 +1211,7 @@ export function Markdown({
1093
1211
  contentWidth = 680,
1094
1212
  contentAlign = 'start',
1095
1213
  components,
1214
+ plugins,
1096
1215
  inlinePlugins,
1097
1216
  autolink,
1098
1217
  xstyle,
@@ -1105,16 +1224,30 @@ export function Markdown({
1105
1224
  const LinkComponent = useLinkComponent();
1106
1225
  // Derive the set of source IDs for the parser (stable across renders when sources don't change)
1107
1226
  const sourceIds = useMemo(() => sources ? new Set(Object.keys(sources)) : undefined, [sources]);
1227
+ const preparedPlugins = useMemo(() => {
1228
+ if (plugins == null) {
1229
+ return undefined;
1230
+ }
1231
+ try {
1232
+ return prepareMarkdownPlugins(plugins);
1233
+ } catch (error) {
1234
+ reportMarkdownPluginFailure('configuration', 'transform', error);
1235
+ return undefined;
1236
+ }
1237
+ }, [plugins]);
1238
+ const syntaxPlugins = useStableMarkdownSyntaxEntries(preparedPlugins);
1108
1239
  const hasMathRenderer = components?.math != null;
1109
1240
  const legacyParseOptions = useMemo(() => ({
1110
1241
  sourceIds,
1111
- autolink
1112
- }), [sourceIds, autolink]);
1242
+ autolink,
1243
+ plugins: syntaxPlugins
1244
+ }), [sourceIds, autolink, syntaxPlugins]);
1113
1245
  const mathParseOptions = useMemo(() => ({
1114
1246
  sourceIds,
1115
1247
  autolink,
1116
- math: true
1117
- }), [sourceIds, autolink]);
1248
+ math: true,
1249
+ plugins: syntaxPlugins
1250
+ }), [sourceIds, autolink, syntaxPlugins]);
1118
1251
 
1119
1252
  // Smooth bursty streamed chunks into a steady character-by-character reveal.
1120
1253
  // When not streaming, the hook returns children unchanged (no-op).
@@ -1129,7 +1262,7 @@ export function Markdown({
1129
1262
  prevAutolinkRef.current = autolink;
1130
1263
  prevMathRef.current = hasMathRenderer;
1131
1264
  }
1132
- const blocks = useMemo(() => {
1265
+ const parsedBlocks = useMemo(() => {
1133
1266
  if (display === 'inline') {
1134
1267
  return [];
1135
1268
  }
@@ -1140,10 +1273,15 @@ export function Markdown({
1140
1273
  }
1141
1274
  const options = hasMathRenderer ? mathParseOptions : legacyParseOptions;
1142
1275
  const input = trimStreamingArtifacts(smoothedText, options);
1143
- return hasMathRenderer ? parseMarkdownIncremental(input, incrementalStateRef.current, mathParseOptions) : parseMarkdownIncremental(input, incrementalStateRef.current, legacyParseOptions);
1276
+ return (hasMathRenderer ? parseMarkdownAstIncremental(input, incrementalStateRef.current, mathParseOptions) : parseMarkdownAstIncremental(input, incrementalStateRef.current, legacyParseOptions)).children;
1144
1277
  }
1145
- return hasMathRenderer ? parseMarkdown(children, mathParseOptions) : parseMarkdown(children, legacyParseOptions);
1278
+ return (hasMathRenderer ? parseMarkdownAst(children, mathParseOptions) : parseMarkdownAst(children, legacyParseOptions)).children;
1146
1279
  }, [display, smoothedText, children, isStreaming, hasMathRenderer, mathParseOptions, legacyParseOptions]);
1280
+ const transformSource = isStreaming ? trimStreamingArtifacts(smoothedText, hasMathRenderer ? mathParseOptions : legacyParseOptions) : children;
1281
+ const blocks = useMemo(() => applyMarkdownTransforms({
1282
+ type: 'root',
1283
+ children: parsedBlocks
1284
+ }, preparedPlugins, transformSource, !isStreaming, 'block').children, [parsedBlocks, preparedPlugins, transformSource, isStreaming]);
1147
1285
 
1148
1286
  // Assign each top-level heading the slug that parseOutlineFromMarkdown
1149
1287
  // would derive for it, so Outline hash links built from the same source
@@ -1159,20 +1297,35 @@ export function Markdown({
1159
1297
  const counts = new Map();
1160
1298
  for (const block of blocks) {
1161
1299
  if (block.type === 'heading') {
1162
- const label = inlineText(block.children).trim();
1300
+ const label = markdownAstText(block.children, node => markdownExtensionText(preparedPlugins, node)).trim();
1163
1301
  map.set(block, uniqueSlug(slugify(label), counts));
1164
1302
  }
1165
1303
  }
1166
1304
  return map;
1167
- }, [display, blocks]);
1168
- const inlineNodes = useMemo(() => {
1305
+ }, [display, blocks, preparedPlugins]);
1306
+ const parsedInlineNodes = useMemo(() => {
1169
1307
  if (display !== 'inline') {
1170
1308
  return [];
1171
1309
  }
1172
1310
  const options = hasMathRenderer ? mathParseOptions : legacyParseOptions;
1173
1311
  const input = isStreaming ? trimStreamingArtifacts(smoothedText, options) : children;
1174
- return hasMathRenderer ? parseInline(input, mathParseOptions) : parseInline(input, legacyParseOptions);
1312
+ return hasMathRenderer ? parseInlineAst(input, mathParseOptions) : parseInlineAst(input, legacyParseOptions);
1175
1313
  }, [display, smoothedText, children, isStreaming, hasMathRenderer, mathParseOptions, legacyParseOptions]);
1314
+ const inlineTransformSource = isStreaming ? trimStreamingArtifacts(smoothedText, hasMathRenderer ? mathParseOptions : legacyParseOptions) : children;
1315
+ const inlineNodes = useMemo(() => {
1316
+ if (display !== 'inline') {
1317
+ return [];
1318
+ }
1319
+ const transformed = applyMarkdownTransforms({
1320
+ type: 'root',
1321
+ children: [{
1322
+ type: 'paragraph',
1323
+ children: parsedInlineNodes
1324
+ }]
1325
+ }, preparedPlugins, inlineTransformSource, !isStreaming, 'inline');
1326
+ const paragraph = transformed.children[0];
1327
+ return paragraph?.type === 'paragraph' ? [...paragraph.children] : parsedInlineNodes;
1328
+ }, [display, parsedInlineNodes, preparedPlugins, inlineTransformSource, isStreaming]);
1176
1329
 
1177
1330
  // Track recent boundaries for stacked fade-in animation.
1178
1331
  // The number of spans needed = ceil(animationDuration / tickInterval).
@@ -1224,7 +1377,7 @@ export function Markdown({
1224
1377
  ...mergeProps(themeProps('markdown', {
1225
1378
  density
1226
1379
  }), stylex.props(styles.root, styles.inlineRoot, xstyle), className, style),
1227
- children: inlineNodes.map((node, i) => renderInline(node, i, onLinkClick, cursor, citationCtx, LinkComponent, inlinePlugins, components))
1380
+ children: inlineNodes.map((node, i) => renderInline(node, i, onLinkClick, cursor, citationCtx, LinkComponent, inlinePlugins, components, preparedPlugins))
1228
1381
  });
1229
1382
 
1230
1383
  // Store current inline nodes for next render's boundary calculation.
@@ -1243,7 +1396,7 @@ export function Markdown({
1243
1396
  ...mergeProps(themeProps('markdown', {
1244
1397
  density
1245
1398
  }), stylex.props(styles.root, xstyle), className, style),
1246
- children: blocks.map((block, i) => renderBlock(block, i, blocks.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidth ? typeof contentWidth === 'number' ? `${contentWidth}px` : contentWidth : null, contentAlign, LinkComponent, inlinePlugins, components, t, headingIdMap))
1399
+ children: blocks.map((block, i) => renderBlock(block, i, blocks.length, density, headingLevelStart, onLinkClick, cursor, citationCtx, contentWidth ? typeof contentWidth === 'number' ? `${contentWidth}px` : contentWidth : null, contentAlign, LinkComponent, inlinePlugins, components, preparedPlugins, t, headingIdMap))
1247
1400
  });
1248
1401
 
1249
1402
  // Store current blocks for next render's boundary calculation.