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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (305) hide show
  1. package/CHANGELOG.md +33 -0
  2. package/dist/BottomSheet/BottomSheet.d.ts +1 -1
  3. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  4. package/dist/BottomSheet/BottomSheet.js +3 -1
  5. package/dist/BottomSheet/BottomSheetPanel.d.ts +7 -5
  6. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  7. package/dist/BottomSheet/BottomSheetPanel.js +56 -19
  8. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  9. package/dist/Chat/ChatComposerInput.js +2 -2
  10. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  11. package/dist/CheckboxInput/CheckboxInput.js +12 -2
  12. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  13. package/dist/Collapsible/Collapsible.js +6 -1
  14. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  15. package/dist/CommandPalette/CommandPaletteInput.js +1 -1
  16. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  17. package/dist/ComplexSelector/ComplexSelector.js +1 -1
  18. package/dist/DateInput/DateInput.d.ts.map +1 -1
  19. package/dist/DateInput/DateInput.js +4 -4
  20. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  21. package/dist/DateInput/NativeDateField.js +16 -16
  22. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  23. package/dist/DateInput/TouchDateField.js +2 -2
  24. package/dist/DateRangeInput/DateRangeInput.d.ts +3 -0
  25. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  26. package/dist/DateRangeInput/DateRangeInput.js +20 -13
  27. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  28. package/dist/DateTimeInput/DateTimeInput.js +8 -8
  29. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  30. package/dist/DateTimeInput/TouchDateTimeField.js +4 -4
  31. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +9 -3
  32. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -1
  33. package/dist/DateTimeInput/nativePickerSegmentStyles.js +3 -3
  34. package/dist/Dialog/DialogHeader.d.ts +1 -1
  35. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  36. package/dist/Dialog/DialogHeader.js +10 -7
  37. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  38. package/dist/Field/PanelSearchInput.js +1 -1
  39. package/dist/FileInput/FileInput.d.ts.map +1 -1
  40. package/dist/FileInput/FileInput.js +16 -10
  41. package/dist/Kbd/Kbd.d.ts +5 -3
  42. package/dist/Kbd/Kbd.d.ts.map +1 -1
  43. package/dist/Kbd/Kbd.js +36 -42
  44. package/dist/Link/Link.d.ts.map +1 -1
  45. package/dist/Link/Link.js +6 -2
  46. package/dist/Markdown/Markdown.d.ts +18 -4
  47. package/dist/Markdown/Markdown.d.ts.map +1 -1
  48. package/dist/Markdown/Markdown.fr23.bench.d.ts +2 -0
  49. package/dist/Markdown/Markdown.fr23.bench.d.ts.map +1 -0
  50. package/dist/Markdown/Markdown.fr23.bench.js +150 -0
  51. package/dist/Markdown/Markdown.fr23.sampling.d.ts +2 -0
  52. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -0
  53. package/dist/Markdown/Markdown.fr23.sampling.js +43 -0
  54. package/dist/Markdown/Markdown.js +311 -114
  55. package/dist/Markdown/ast.d.ts +162 -0
  56. package/dist/Markdown/ast.d.ts.map +1 -0
  57. package/dist/Markdown/ast.js +74 -0
  58. package/dist/Markdown/index.d.ts +5 -3
  59. package/dist/Markdown/index.d.ts.map +1 -1
  60. package/dist/Markdown/index.js +3 -2
  61. package/dist/Markdown/parser/index.d.ts +10 -0
  62. package/dist/Markdown/parser/index.d.ts.map +1 -0
  63. package/dist/Markdown/parser/index.js +10 -0
  64. package/dist/Markdown/parser.d.ts +220 -38
  65. package/dist/Markdown/parser.d.ts.map +1 -1
  66. package/dist/Markdown/parser.js +1072 -188
  67. package/dist/Markdown/plugins/frontmatter.d.ts +32 -0
  68. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -0
  69. package/dist/Markdown/plugins/frontmatter.js +132 -0
  70. package/dist/Markdown/plugins/index.d.ts +16 -0
  71. package/dist/Markdown/plugins/index.d.ts.map +1 -0
  72. package/dist/Markdown/plugins/index.js +13 -0
  73. package/dist/Markdown/plugins/protocol.d.ts +191 -0
  74. package/dist/Markdown/plugins/protocol.d.ts.map +1 -0
  75. package/dist/Markdown/plugins/protocol.js +957 -0
  76. package/dist/Markdown/plugins/semanticFence.d.ts +36 -0
  77. package/dist/Markdown/plugins/semanticFence.d.ts.map +1 -0
  78. package/dist/Markdown/plugins/semanticFence.js +213 -0
  79. package/dist/Markdown/plugins/sourceDecoration.d.ts +76 -0
  80. package/dist/Markdown/plugins/sourceDecoration.d.ts.map +1 -0
  81. package/dist/Markdown/plugins/sourceDecoration.js +393 -0
  82. package/dist/Markdown/plugins/textTransform.d.ts +30 -0
  83. package/dist/Markdown/plugins/textTransform.d.ts.map +1 -0
  84. package/dist/Markdown/plugins/textTransform.js +374 -0
  85. package/dist/Markdown/remark.d.ts +196 -0
  86. package/dist/Markdown/remark.d.ts.map +1 -0
  87. package/dist/Markdown/remark.js +1062 -0
  88. package/dist/Markdown/url.d.ts +4 -0
  89. package/dist/Markdown/url.d.ts.map +1 -0
  90. package/dist/Markdown/url.js +25 -0
  91. package/dist/Markdown/utils.d.ts +4 -2
  92. package/dist/Markdown/utils.d.ts.map +1 -1
  93. package/dist/Markdown/utils.js +2 -1
  94. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  95. package/dist/NumberInput/NumberInput.js +4 -4
  96. package/dist/Outline/index.d.ts +1 -0
  97. package/dist/Outline/index.d.ts.map +1 -1
  98. package/dist/Outline/parseOutlineFromMarkdown.d.ts +7 -1
  99. package/dist/Outline/parseOutlineFromMarkdown.d.ts.map +1 -1
  100. package/dist/Outline/parseOutlineFromMarkdown.js +14 -8
  101. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -1
  102. package/dist/Outline/useOutlineFromMarkdown.d.ts.map +1 -1
  103. package/dist/Outline/useOutlineFromMarkdown.js +8 -3
  104. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  105. package/dist/PowerSearch/PowerSearchEditPopover.js +46 -30
  106. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  107. package/dist/ProgressBar/ProgressBar.js +36 -31
  108. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  109. package/dist/RadioList/RadioListItem.js +13 -1
  110. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  111. package/dist/SegmentedControl/SegmentedControlItem.js +5 -5
  112. package/dist/Selector/Selector.d.ts.map +1 -1
  113. package/dist/Selector/Selector.js +1 -1
  114. package/dist/SideNav/SideNav.d.ts +2 -1
  115. package/dist/SideNav/SideNav.d.ts.map +1 -1
  116. package/dist/SideNav/SideNav.js +9 -3
  117. package/dist/Slider/Slider.d.ts.map +1 -1
  118. package/dist/Slider/Slider.js +19 -10
  119. package/dist/Spinner/Spinner.d.ts +1 -1
  120. package/dist/Spinner/Spinner.d.ts.map +1 -1
  121. package/dist/Spinner/Spinner.js +45 -21
  122. package/dist/Switch/Switch.d.ts.map +1 -1
  123. package/dist/Switch/Switch.js +11 -0
  124. package/dist/TabList/Tab.d.ts +1 -1
  125. package/dist/TabList/Tab.d.ts.map +1 -1
  126. package/dist/TabList/Tab.js +20 -7
  127. package/dist/TextArea/TextArea.d.ts.map +1 -1
  128. package/dist/TextArea/TextArea.js +1 -1
  129. package/dist/TextInput/TextInput.d.ts.map +1 -1
  130. package/dist/TextInput/TextInput.js +2 -2
  131. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  132. package/dist/TimeInput/TimeInput.js +4 -4
  133. package/dist/ToggleButton/ToggleButton.d.ts +2 -1
  134. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  135. package/dist/ToggleButton/ToggleButton.js +7 -1
  136. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  137. package/dist/Typeahead/BaseTypeahead.js +16 -7
  138. package/dist/astryx.css +19 -8
  139. package/dist/hooks/scrollKeyboardDelegation.d.ts +3 -0
  140. package/dist/hooks/scrollKeyboardDelegation.d.ts.map +1 -0
  141. package/dist/hooks/scrollKeyboardDelegation.js +146 -0
  142. package/dist/hooks/useScrollableArea.d.ts +6 -2
  143. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  144. package/dist/hooks/useScrollableArea.js +17 -5
  145. package/dist/utils/interactionOverlay.stylex.d.ts +8 -0
  146. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  147. package/dist/utils/interactionOverlay.stylex.js +9 -0
  148. package/locales/en.json +16 -0
  149. package/locales/pseudo.json +12 -0
  150. package/package.json +22 -5
  151. package/scripts/agent-doc-state.mjs +1 -1
  152. package/src/BottomSheet/BottomSheet.doc.mjs +8 -1
  153. package/src/BottomSheet/BottomSheet.spec.md +46 -20
  154. package/src/BottomSheet/BottomSheet.test.tsx +6 -3
  155. package/src/BottomSheet/BottomSheet.tsx +3 -1
  156. package/src/BottomSheet/BottomSheetKeyboard.test.tsx +195 -0
  157. package/src/BottomSheet/BottomSheetPanel.test.tsx +11 -1
  158. package/src/BottomSheet/BottomSheetPanel.tsx +49 -16
  159. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +344 -0
  160. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +17 -1
  161. package/src/Button/__tests__/Button.a11y.known-failures.ts +0 -29
  162. package/src/Button/__tests__/Button.a11y.renders.tsx +9 -2
  163. package/src/Button/__tests__/Button.a11y.states.ts +9 -0
  164. package/src/Chat/ChatComposerInput.doc.mjs +3 -3
  165. package/src/Chat/ChatComposerInput.tsx +10 -2
  166. package/src/CheckboxInput/CheckboxInput.doc.mjs +11 -0
  167. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  168. package/src/CheckboxInput/CheckboxInput.tsx +21 -1
  169. package/src/ClickableCard/ClickableCard.test.tsx +102 -5
  170. package/src/Collapsible/Collapsible.doc.mjs +11 -0
  171. package/src/Collapsible/Collapsible.test.tsx +21 -0
  172. package/src/Collapsible/Collapsible.tsx +5 -0
  173. package/src/CommandPalette/CommandPaletteInput.tsx +6 -1
  174. package/src/ComplexSelector/ComplexSelector.tsx +6 -1
  175. package/src/DateInput/DateInput.tsx +6 -1
  176. package/src/DateInput/NativeDateField.tsx +24 -8
  177. package/src/DateInput/TouchDateField.tsx +6 -2
  178. package/src/DateRangeInput/DateRangeInput.doc.mjs +35 -7
  179. package/src/DateRangeInput/DateRangeInput.spec.md +203 -0
  180. package/src/DateRangeInput/DateRangeInput.test.tsx +100 -4
  181. package/src/DateRangeInput/DateRangeInput.tsx +35 -21
  182. package/src/DateTimeInput/DateTimeInput.tsx +6 -1
  183. package/src/DateTimeInput/TouchDateTimeField.tsx +6 -1
  184. package/src/DateTimeInput/nativePickerSegmentStyles.ts +24 -8
  185. package/src/Dialog/Dialog.doc.mjs +3 -0
  186. package/src/Dialog/Dialog.spec.md +1 -1
  187. package/src/Dialog/DialogHeader.doc.mjs +38 -0
  188. package/src/Dialog/DialogHeader.test.tsx +49 -0
  189. package/src/Dialog/DialogHeader.tsx +23 -4
  190. package/src/Dialog/modules/DialogHeader.spec.md +152 -0
  191. package/src/Field/PanelSearchInput.tsx +5 -2
  192. package/src/FieldStatus/__tests__/StatusMessage.a11y.states.ts +1 -1
  193. package/src/FileInput/FileInput.doc.mjs +2 -0
  194. package/src/FileInput/FileInput.spec.md +199 -0
  195. package/src/FileInput/FileInput.test.tsx +14 -0
  196. package/src/FileInput/FileInput.tsx +24 -5
  197. package/src/Kbd/Kbd.doc.mjs +3 -3
  198. package/src/Kbd/Kbd.test.tsx +57 -1
  199. package/src/Kbd/Kbd.tsx +57 -37
  200. package/src/Layout/LayoutFooter.doc.mjs +17 -0
  201. package/src/Link/Link.doc.mjs +11 -0
  202. package/src/Link/Link.test.tsx +24 -0
  203. package/src/Link/Link.tsx +5 -0
  204. package/src/Markdown/Markdown.doc.mjs +439 -42
  205. package/src/Markdown/Markdown.fr23.bench.ts +174 -0
  206. package/src/Markdown/Markdown.fr23.perf.test.ts +249 -0
  207. package/src/Markdown/Markdown.fr23.sampling.ts +49 -0
  208. package/src/Markdown/Markdown.helpers.perf.test.ts +489 -0
  209. package/src/Markdown/Markdown.public.test.ts +280 -0
  210. package/src/Markdown/Markdown.spec.md +304 -72
  211. package/src/Markdown/Markdown.test.tsx +118 -3
  212. package/src/Markdown/Markdown.tsx +489 -129
  213. package/src/Markdown/ast.test.ts +307 -0
  214. package/src/Markdown/ast.ts +337 -0
  215. package/src/Markdown/incremental.test.ts +187 -7
  216. package/src/Markdown/index.ts +43 -1
  217. package/src/Markdown/modules/remark.spec.md +269 -0
  218. package/src/Markdown/parser/index.ts +64 -0
  219. package/src/Markdown/parser.perf.test.ts +3 -1
  220. package/src/Markdown/parser.public.test.ts +103 -0
  221. package/src/Markdown/parser.test.ts +122 -0
  222. package/src/Markdown/parser.ts +1721 -248
  223. package/src/Markdown/plugins/frontmatter.test.tsx +125 -0
  224. package/src/Markdown/plugins/frontmatter.ts +198 -0
  225. package/src/Markdown/plugins/index.ts +53 -0
  226. package/src/Markdown/plugins/protocol.test.tsx +1022 -0
  227. package/src/Markdown/plugins/protocol.ts +1618 -0
  228. package/src/Markdown/plugins/semanticFence.test.tsx +546 -0
  229. package/src/Markdown/plugins/semanticFence.ts +424 -0
  230. package/src/Markdown/plugins/sourceDecoration.test.tsx +799 -0
  231. package/src/Markdown/plugins/sourceDecoration.ts +539 -0
  232. package/src/Markdown/plugins/textTransform.test.ts +467 -0
  233. package/src/Markdown/plugins/textTransform.ts +554 -0
  234. package/src/Markdown/remark.test.tsx +1877 -0
  235. package/src/Markdown/remark.ts +1574 -0
  236. package/src/Markdown/url.ts +30 -0
  237. package/src/Markdown/utils.ts +19 -1
  238. package/src/MultiSelector/MultiSelector.test.tsx +1 -35
  239. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +128 -0
  240. package/src/NumberInput/NumberInput.tsx +6 -1
  241. package/src/Outline/Outline.doc.mjs +7 -5
  242. package/src/Outline/Outline.spec.md +1 -1
  243. package/src/Outline/index.ts +1 -0
  244. package/src/Outline/modules/parseOutlineFromMarkdown.spec.md +142 -0
  245. package/src/Outline/parseOutlineFromMarkdown.ts +40 -10
  246. package/src/Outline/useOutlineFromMarkdown.ts +15 -3
  247. package/src/PowerSearch/PowerSearch.doc.mjs +2 -2
  248. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +150 -1
  249. package/src/PowerSearch/PowerSearchEditPopover.tsx +51 -28
  250. package/src/ProgressBar/ProgressBar.test.tsx +29 -11
  251. package/src/ProgressBar/ProgressBar.tsx +59 -72
  252. package/src/RadioList/RadioList.doc.mjs +11 -0
  253. package/src/RadioList/RadioList.test.tsx +32 -0
  254. package/src/RadioList/RadioListItem.tsx +25 -1
  255. package/src/ScrollableArea/modules/useScrollableArea.spec.md +50 -22
  256. package/src/SegmentedControl/SegmentedControl.doc.mjs +2 -2
  257. package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
  258. package/src/SegmentedControl/SegmentedControlItem.tsx +6 -9
  259. package/src/Selector/Selector.spec.md +12 -9
  260. package/src/Selector/Selector.tsx +6 -1
  261. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +130 -0
  262. package/src/Selector/__tests__/Listbox.a11y.dom.ts +38 -0
  263. package/src/Selector/__tests__/Listbox.a11y.inventory.test.ts +63 -0
  264. package/src/Selector/__tests__/Listbox.a11y.known-failures.ts +37 -0
  265. package/src/Selector/__tests__/Listbox.a11y.states.ts +232 -0
  266. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +121 -0
  267. package/src/SideNav/SideNav.doc.mjs +1 -1
  268. package/src/SideNav/SideNav.test.tsx +10 -0
  269. package/src/SideNav/SideNav.tsx +14 -2
  270. package/src/Slider/Slider.doc.mjs +27 -0
  271. package/src/Slider/Slider.spec.md +61 -47
  272. package/src/Slider/Slider.test.tsx +146 -0
  273. package/src/Slider/Slider.tsx +37 -13
  274. package/src/Spinner/Spinner.doc.mjs +6 -3
  275. package/src/Spinner/Spinner.test.tsx +41 -0
  276. package/src/Spinner/Spinner.tsx +62 -32
  277. package/src/Switch/Switch.doc.mjs +11 -0
  278. package/src/Switch/Switch.test.tsx +16 -0
  279. package/src/Switch/Switch.tsx +28 -0
  280. package/src/TabList/Tab.tsx +35 -7
  281. package/src/TabList/TabList.doc.mjs +11 -0
  282. package/src/TabList/TabList.test.tsx +66 -0
  283. package/src/TabList/__tests__/Tabs.a11y.known-failures.ts +1 -34
  284. package/src/TextArea/TextArea.tsx +6 -1
  285. package/src/TextInput/TextInput.test.tsx +20 -1
  286. package/src/TextInput/TextInput.tsx +6 -1
  287. package/src/TimeInput/TimeInput.tsx +6 -1
  288. package/src/ToggleButton/ToggleButton.test.tsx +133 -0
  289. package/src/ToggleButton/ToggleButton.tsx +9 -2
  290. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +209 -0
  291. package/src/Tokenizer/Tokenizer.spec.md +142 -75
  292. package/src/TreeList/TreeList.spec.md +123 -75
  293. package/src/Typeahead/BaseTypeahead.spec.md +4 -3
  294. package/src/Typeahead/BaseTypeahead.tsx +21 -7
  295. package/src/Typeahead/Typeahead.test.tsx +53 -0
  296. package/src/__tests__/PressedState.a11y.chromium.spec.ts +813 -0
  297. package/src/__tests__/pressState.ts +93 -0
  298. package/src/hooks/scrollKeyboardDelegation.test.ts +155 -0
  299. package/src/hooks/scrollKeyboardDelegation.ts +233 -0
  300. package/src/hooks/useScrollableArea.doc.mjs +15 -3
  301. package/src/hooks/useScrollableArea.test.tsx +59 -1
  302. package/src/hooks/useScrollableArea.ts +34 -10
  303. package/src/inputFontFloor.test.ts +106 -0
  304. package/src/theme/derivedVarRegistry.test.ts +6 -4
  305. package/src/utils/interactionOverlay.stylex.ts +20 -0
@@ -5,8 +5,7 @@ const anatomy = [
5
5
  {
6
6
  name: 'Document',
7
7
  required: true,
8
- description:
9
- 'Root container for block or inline Markdown content.',
8
+ description: 'Root container for block or inline Markdown content.',
10
9
  },
11
10
  {
12
11
  name: 'Heading',
@@ -41,7 +40,8 @@ const anatomy = [
41
40
  {
42
41
  name: 'Table',
43
42
  required: false,
44
- description: 'Scrollable table block rendered from Markdown rows and columns.',
43
+ description:
44
+ 'Scrollable table block rendered from Markdown rows and columns.',
45
45
  },
46
46
  {
47
47
  name: 'Divider',
@@ -138,14 +138,20 @@ export const docs = {
138
138
  name: 'contentAlign',
139
139
  type: "'start' | 'center'",
140
140
  description:
141
- "Alignment of prose content within the container when contentWidth is narrower than the available space.",
141
+ 'Alignment of prose content within the container when contentWidth is narrower than the available space.',
142
142
  default: "'start'",
143
143
  },
144
+ {
145
+ name: 'plugins',
146
+ type: 'readonly MarkdownPluginEntry[]',
147
+ description:
148
+ 'Ordered extensions created by createMarkdownPlugin(). Plugins may add bounded syntax, immutable typed AST transforms, and typed extension renderers. Use isMarkdownExtensionNode() to narrow extension data observed from other plugins. Renderer callbacks are pure; return a child component when hooks are needed. Omitted and empty lists preserve the released Markdown behavior.',
149
+ },
144
150
  {
145
151
  name: 'inlinePlugins',
146
152
  type: 'MarkdownInlinePlugin[]',
147
153
  description:
148
- 'Transforms regex matches in parsed text nodes into custom inline React elements. Use for issue refs, diff refs, mentions, and other shorthand patterns. Inline code and fenced code blocks are unaffected.',
154
+ 'Transforms regex matches in parsed text nodes into custom inline React elements. Use for prefixed identifiers, mentions, and other shorthand patterns. Inline code, fenced code blocks, and math are unaffected.',
149
155
  },
150
156
  {
151
157
  name: 'autolink',
@@ -156,7 +162,8 @@ export const docs = {
156
162
  {
157
163
  name: 'components',
158
164
  type: 'MarkdownComponents',
159
- description: 'Custom React component overrides for rendered Markdown elements (code, inlineCode, link, heading, paragraph, image, blockquote, hr, citation).',
165
+ description:
166
+ 'Custom React component overrides for rendered Markdown elements (code, inlineCode, math, link, heading, paragraph, image, blockquote, hr, citation). Providing math enables `$…$` inline and `$$…$$` display parsing and receives `{value, display}`; omit it when dollar text should stay literal.',
160
167
  },
161
168
  {
162
169
  name: 'xstyle',
@@ -184,7 +191,8 @@ export const docs = {
184
191
  ],
185
192
  playground: {
186
193
  defaults: {
187
- children: '## Getting Started\n\nInstall the package:\n\n```bash\nnpm install @astryxdesign/core\n```\n\nThen import and use any component:\n\n```tsx\nimport {Button} from \'@astryxdesign/core/Button\';\n```\n\n**Bold**, *italic*, and `inline code` all work.',
194
+ children:
195
+ "## Getting Started\n\nInstall the package:\n\n```bash\nnpm install @astryxdesign/core\n```\n\nThen import and use any component:\n\n```tsx\nimport {Button} from '@astryxdesign/core/Button';\n```\n\n**Bold**, *italic*, and `inline code` all work.",
188
196
  },
189
197
  },
190
198
  theming: {
@@ -229,11 +237,76 @@ export const docs = {
229
237
  description:
230
238
  'Renders a markdown string as Astryx-styled components. Use Markdown for user-generated content, AI responses, and documentation; it handles headings, lists, tables, code blocks, and citations with consistent styling.',
231
239
  bestPractices: [
232
- { guidance: true, description: 'Set headingLevelStart to match the page hierarchy, e.g. start at 3 if the markdown sits inside an h2 section.' },
233
- { guidance: true, description: 'Use contentWidth to keep prose at a readable line length in wide layouts.' },
234
- { guidance: true, description: 'Use inlinePlugins for custom shorthand patterns like issue refs, diff refs, and mentions instead of preprocessing the markdown string.' },
235
- { guidance: true, description: 'Pair with Outline and useOutlineFromMarkdown for section navigation: headings render generated id attributes that match the outline item ids, so hash links scroll to their target.' },
236
- { guidance: false, description: 'Use Markdown for hand-authored layouts; use Text and Heading directly when you control the content.' },
240
+ {
241
+ guidance: true,
242
+ description:
243
+ 'Set headingLevelStart to match the page hierarchy, e.g. start at 3 if the markdown sits inside an h2 section.',
244
+ },
245
+ {
246
+ guidance: true,
247
+ description:
248
+ 'Use contentWidth to keep prose at a readable line length in wide layouts.',
249
+ },
250
+ {
251
+ guidance: true,
252
+ description:
253
+ 'Use plugins created by createMarkdownPlugin for reusable syntax, immutable AST transforms, and typed extension rendering. Keep the ordered list stable while its syntax configuration is unchanged.',
254
+ },
255
+ {
256
+ guidance: true,
257
+ description:
258
+ 'Use createMarkdownTextTransform for prose matching; it preserves code, links, images, citations, math, and accepted extension syntax as protected contexts. Provide requiredSubstrings only when they conservatively cover every possible match.',
259
+ },
260
+ {
261
+ guidance: true,
262
+ description:
263
+ 'Use createMarkdownFenceTransform for declared code-fence languages with semantic data. createNode returns an owned block extension node; its standard plugin renderer and toText own presentation. components.code still wins, and a declined or failed proposal keeps the accessible, copyable CodeBlock fallback.',
264
+ },
265
+ {
266
+ guidance: true,
267
+ description:
268
+ 'Use createMarkdownSourceDecoration to attach non-visual metadata — search hits, review annotations — to the blocks a source range touches, and getMarkdownSourceDecorations to read it back in a later plugin. Decorations appear on the settled document rather than on partial streaming chunks, and never change rendering, copyable text, accessible names, ids, focus order, or navigation.',
269
+ },
270
+ {
271
+ guidance: true,
272
+ description:
273
+ 'Import parseMarkdownAst or parseInlineAst from @astryxdesign/core/Markdown/parser when server or React Server Component code needs to run plugins against the canonical readonly tree. The parser and plugin subpaths have no use-client boundary. The Markdown component remains client-owned, so function-bearing plugin entries must not be passed across an RSC serialization boundary.',
274
+ },
275
+ {
276
+ guidance: true,
277
+ description:
278
+ 'Use createMarkdownFrontmatter for typed document metadata. Its parse() method gives the host metadata directly; its plugin removes a complete leading block before rendering and withholds an unfinished block during streaming.',
279
+ },
280
+ {
281
+ guidance: true,
282
+ description:
283
+ "Import createMarkdownRemarkTransform from '@astryxdesign/core/Markdown/remark' only to reuse an existing synchronous transform-only Remark plugin; it stays out of every other bundle. Prove each plugin with fixtures: anything outside the supported MDAST subset — async work, parser or compiler plugins, processor state, raw HTML, unsupported nodes, forged positions, or metadata Astryx cannot represent — keeps the last valid document and reports one diagnostic.",
284
+ },
285
+ {
286
+ guidance: true,
287
+ description:
288
+ 'Use inlinePlugins for prefixed identifiers, mentions, and other prose-only shorthand instead of preprocessing the markdown string.',
289
+ },
290
+ {
291
+ guidance: true,
292
+ description:
293
+ 'Provide components.math only for documents that use dollar-delimited math. The renderer owns typesetting and accessible output; Astryx passes the expression as text and never executes raw HTML.',
294
+ },
295
+ {
296
+ guidance: true,
297
+ description:
298
+ 'For direct parsing, use MathParseOptions and handle InlineNodeWithMath or BlockNodeWithMath. Incremental math parsing also uses createIncrementalState<true>() and IncrementalParseState<true>; default calls and ParseOptions annotations keep the legacy unions.',
299
+ },
300
+ {
301
+ guidance: true,
302
+ description:
303
+ 'Pair with Outline and useOutlineFromMarkdown for section navigation: headings render generated id attributes that match the outline item ids, so hash links scroll to their target.',
304
+ },
305
+ {
306
+ guidance: false,
307
+ description:
308
+ 'Use Markdown for hand-authored layouts; use Text and Heading directly when you control the content.',
309
+ },
237
310
  ],
238
311
  },
239
312
  examples: [
@@ -259,23 +332,191 @@ import {Text} from '@astryxdesign/core/Text';
259
332
  `,
260
333
  },
261
334
  {
262
- label: 'Inline Plugins',
335
+ label: 'Text transform helper',
336
+ code: `
337
+ import {Markdown} from '@astryxdesign/core/Markdown';
338
+ import {
339
+ createMarkdownPlugin,
340
+ createMarkdownTextTransform,
341
+ } from '@astryxdesign/core/Markdown/plugins';
342
+
343
+ const finalLabels = createMarkdownPlugin({
344
+ name: 'final-labels',
345
+ apiVersion: 1,
346
+ transform: createMarkdownTextTransform({
347
+ pattern: /\\bDraft\\b/g,
348
+ requiredSubstrings: ['Draft'],
349
+ replace: () => ({type: 'text', value: 'Final'}),
350
+ }),
351
+ });
352
+
353
+ <Markdown plugins={[finalLabels]}># Draft</Markdown>;
354
+ `,
355
+ },
356
+ {
357
+ label: 'Semantic fence helper',
358
+ code: `
359
+ import {Markdown} from '@astryxdesign/core/Markdown';
360
+ import {
361
+ createMarkdownFenceTransform,
362
+ createMarkdownPlugin,
363
+ type MarkdownExtensionNode,
364
+ } from '@astryxdesign/core/Markdown/plugins';
365
+
366
+ type DiagramNode = MarkdownExtensionNode<
367
+ 'diagrams',
368
+ 'diagram',
369
+ {readonly code: string; readonly label?: string},
370
+ 'block'
371
+ >;
372
+
373
+ const diagrams = createMarkdownPlugin<'diagrams', DiagramNode>({
374
+ name: 'diagrams',
375
+ apiVersion: 1,
376
+ transform: createMarkdownFenceTransform({
377
+ languages: ['mermaid'],
378
+ createNode: ({code, meta}) => ({
379
+ type: 'extension',
380
+ plugin: 'diagrams',
381
+ name: 'diagram',
382
+ display: 'block',
383
+ data: {code, ...(meta == null ? {} : {label: meta})},
384
+ }),
385
+ }),
386
+ renderers: {
387
+ diagram: {
388
+ render: ({node}) => (
389
+ <Diagram source={node.data.code} label={node.data.label} />
390
+ ),
391
+ toText: node => node.data.code,
392
+ },
393
+ },
394
+ });
395
+
396
+ <Markdown plugins={[diagrams]}>
397
+ {'\`\`\`mermaid Checkout flow\\ngraph LR; A-->B\\n\`\`\`'}
398
+ </Markdown>;
399
+ `,
400
+ },
401
+ {
402
+ label: 'Source decoration helper',
403
+ code: `
404
+ import {Markdown} from '@astryxdesign/core/Markdown';
405
+ import {
406
+ createMarkdownPlugin,
407
+ createMarkdownSourceDecoration,
408
+ getMarkdownSourceDecorations,
409
+ } from '@astryxdesign/core/Markdown/plugins';
410
+
411
+ // Ranges are UTF-16 offsets into the same string Markdown renders. Every
412
+ // block a range touches is annotated; rendering, copyable text, and ids
413
+ // never change.
414
+ const searchHits = createMarkdownPlugin({
415
+ name: 'search-hits',
416
+ apiVersion: 1,
417
+ transform: createMarkdownSourceDecoration({
418
+ name: 'search-hit',
419
+ ranges: [{start: 0, end: 15, data: {query: 'release'}}],
420
+ }),
421
+ });
422
+
423
+ const readDecorations = createMarkdownPlugin({
424
+ name: 'read-decorations',
425
+ apiVersion: 1,
426
+ transform: root => {
427
+ report(root.children.map(getMarkdownSourceDecorations));
428
+ return root;
429
+ },
430
+ });
431
+
432
+ <Markdown plugins={[searchHits, readDecorations]}>{source}</Markdown>;
433
+ `,
434
+ },
435
+ {
436
+ label: 'Native frontmatter',
437
+ code: `
438
+ import {Markdown} from '@astryxdesign/core/Markdown';
439
+ import {createMarkdownFrontmatter} from '@astryxdesign/core/Markdown/plugins';
440
+
441
+ const frontmatter = createMarkdownFrontmatter({
442
+ name: 'document-metadata',
443
+ parse: fields => ({
444
+ title: fields.title ?? 'Untitled',
445
+ draft: fields.draft === 'true',
446
+ }),
447
+ });
448
+
449
+ const source = '---\\ntitle: Release notes\\ndraft: true\\n---\\n# Shipped';
450
+ const result = frontmatter.parse(source);
451
+
452
+ <Markdown plugins={[frontmatter.plugin]}>{source}</Markdown>;
453
+ `,
454
+ },
455
+ {
456
+ label: 'Compatible Remark plugin',
457
+ code: `
458
+ import {Markdown} from '@astryxdesign/core/Markdown';
459
+ import {createMarkdownPlugin} from '@astryxdesign/core/Markdown/plugins';
460
+ import {createMarkdownRemarkTransform} from '@astryxdesign/core/Markdown/remark';
461
+
462
+ // A synchronous transform-only Remark plugin in the usual attacher shape.
463
+ const remarkRename =
464
+ ({from, to}) =>
465
+ tree => {
466
+ const rename = node => {
467
+ if (node.type === 'text') {
468
+ node.value = node.value.split(from).join(to);
469
+ }
470
+ node.children?.forEach(rename);
471
+ };
472
+ rename(tree);
473
+ };
474
+
475
+ const productName = createMarkdownPlugin({
476
+ name: 'product-name',
477
+ apiVersion: 1,
478
+ transform: createMarkdownRemarkTransform(remarkRename, {
479
+ from: 'Astryx',
480
+ to: 'Astryx Design',
481
+ }),
482
+ });
483
+
484
+ <Markdown plugins={[productName]}># Astryx release notes</Markdown>;
485
+ `,
486
+ },
487
+ {
488
+ label: 'Entity links',
263
489
  code: `
264
490
  import {Link} from '@astryxdesign/core/Link';
265
491
 
266
- const issuePlugins = [
492
+ const entityPlugins = [
267
493
  {
268
494
  pattern: /\\b([A-Z][A-Z0-9]+-\\d+)\\b/g,
269
495
  render: (match, key) => (
270
- <Link key={key} href={\`/issues/\${match[1]}\`}>
496
+ <Link key={key} href={\`/entities/\${match[1]}\`}>
271
497
  {match[0]}
272
498
  </Link>
273
499
  ),
274
500
  },
275
501
  ];
276
502
 
277
- <Markdown inlinePlugins={issuePlugins}>
278
- {'Fixed PROJ-123. Inline code stays plain: \`PROJ-999\`.'}
503
+ <Markdown inlinePlugins={entityPlugins}>
504
+ {'See DOC-2048. Inline code stays plain: \`DOC-9999\`.'}
505
+ </Markdown>;
506
+ `,
507
+ },
508
+ {
509
+ label: 'Math renderer',
510
+ code: `
511
+ import {BlockMath, InlineMath} from 'react-katex';
512
+
513
+ function MathExpression({value, display}) {
514
+ const Component = display === 'block' ? BlockMath : InlineMath;
515
+ return <Component math={value} />;
516
+ }
517
+
518
+ <Markdown components={{math: MathExpression}}>
519
+ {'Inline $x_1 + y$ and display math:\\n\\n$$\\n\\\\sum_i x_i\\n$$'}
279
520
  </Markdown>;
280
521
  `,
281
522
  },
@@ -315,8 +556,7 @@ export const docsZh = {
315
556
  {
316
557
  name: 'isStreaming',
317
558
  type: 'boolean',
318
- description:
319
- '启用流式模式,使用增量解析和淡入动画处理分块文本。',
559
+ description: '启用流式模式,使用增量解析和淡入动画处理分块文本。',
320
560
  default: 'false',
321
561
  },
322
562
  {
@@ -348,14 +588,20 @@ export const docsZh = {
348
588
  name: 'contentAlign',
349
589
  type: "'start' | 'center'",
350
590
  description:
351
- "当 contentWidth 小于可用空间时,正文内容在容器内的对齐方式。",
591
+ '当 contentWidth 小于可用空间时,正文内容在容器内的对齐方式。',
352
592
  default: "'start'",
353
593
  },
594
+ {
595
+ name: 'plugins',
596
+ type: 'readonly MarkdownPluginEntry[]',
597
+ description:
598
+ '由 createMarkdownPlugin() 创建的有序扩展。插件可添加有界语法、不可变的类型化 AST 转换和类型化扩展渲染器。使用 isMarkdownExtensionNode() 缩小从其他插件观察到的扩展数据类型。渲染回调必须是纯函数;需要 Hook 时请返回子组件。省略或传入空列表时保持已发布的 Markdown 行为。',
599
+ },
354
600
  {
355
601
  name: 'inlinePlugins',
356
602
  type: 'MarkdownInlinePlugin[]',
357
603
  description:
358
- '将已解析文本节点中的正则匹配转换为自定义内联 React 元素。适用于 issue 引用、diff 引用、用户提及等简写模式。内联代码和围栏代码块不受影响。',
604
+ '将已解析文本节点中的正则匹配转换为自定义内联 React 元素。适用于带前缀的标识符、用户提及等简写模式。内联代码、围栏代码块和数学表达式不受影响。',
359
605
  },
360
606
  {
361
607
  name: 'autolink',
@@ -363,6 +609,12 @@ export const docsZh = {
363
609
  description:
364
610
  "可选的裸 URL 和电子邮箱自动链接。设为 'gfm' 启用 GitHub Flavored Markdown 自动链接规则:裸 https?://、www.、<scheme:url>、<email> 以及 user@host 都会变成链接。末尾句末标点和不平衡的末尾右括号会被排除;代码块、现有链接和图片替代文本内部的匹配会被跳过。默认为关闭。",
365
611
  },
612
+ {
613
+ name: 'components',
614
+ type: 'MarkdownComponents',
615
+ description:
616
+ '用于覆盖 Markdown 渲染元素的自定义 React 组件(code、inlineCode、math、link、heading、paragraph、image、blockquote、hr、citation)。提供 math 会启用 `$…$` 行内数学和 `$$…$$` 块级数学解析,并接收 `{value, display}`;不提供时美元符号保持原样。',
617
+ },
366
618
  {
367
619
  name: 'xstyle',
368
620
  type: 'StyleXStyles',
@@ -372,12 +624,14 @@ export const docsZh = {
372
624
  {
373
625
  name: 'className',
374
626
  type: 'string',
375
- description: '根元素的 CSS 类名。建议使用 xstyle,className 适用于非 StyleX 系统集成。',
627
+ description:
628
+ '根元素的 CSS 类名。建议使用 xstyle,className 适用于非 StyleX 系统集成。',
376
629
  },
377
630
  {
378
631
  name: 'style',
379
632
  type: 'CSSProperties',
380
- description: '根元素的内联样式。建议使用 xstyle,内联样式会绕过 StyleX 优化。',
633
+ description:
634
+ '根元素的内联样式。建议使用 xstyle,内联样式会绕过 StyleX 优化。',
381
635
  },
382
636
  {
383
637
  name: 'data-testid',
@@ -443,11 +697,76 @@ export const docsZh = {
443
697
  description:
444
698
  'Renders a markdown string as Astryx-styled components. Use Markdown for user-generated content, AI responses, and documentation; it handles headings, lists, tables, code blocks, and citations with consistent styling.',
445
699
  bestPractices: [
446
- { guidance: true, description: 'Set headingLevelStart to match the page hierarchy, e.g. start at 3 if the markdown sits inside an h2 section.' },
447
- { guidance: true, description: 'Use contentWidth to keep prose at a readable line length in wide layouts.' },
448
- { guidance: true, description: 'Use inlinePlugins for custom shorthand patterns like issue refs, diff refs, and mentions instead of preprocessing the markdown string.' },
449
- { guidance: true, description: 'Pair with Outline and useOutlineFromMarkdown for section navigation: headings render generated id attributes that match the outline item ids, so hash links scroll to their target.' },
450
- { guidance: false, description: 'Use Markdown for hand-authored layouts; use Text and Heading directly when you control the content.' },
700
+ {
701
+ guidance: true,
702
+ description:
703
+ 'Set headingLevelStart to match the page hierarchy, e.g. start at 3 if the markdown sits inside an h2 section.',
704
+ },
705
+ {
706
+ guidance: true,
707
+ description:
708
+ 'Use contentWidth to keep prose at a readable line length in wide layouts.',
709
+ },
710
+ {
711
+ guidance: true,
712
+ description:
713
+ 'Use plugins created by createMarkdownPlugin for reusable syntax, immutable AST transforms, and typed extension rendering. Keep the ordered list stable while its syntax configuration is unchanged.',
714
+ },
715
+ {
716
+ guidance: true,
717
+ description:
718
+ 'Use createMarkdownTextTransform for prose matching; it preserves code, links, images, citations, math, and accepted extension syntax as protected contexts. Provide requiredSubstrings only when they conservatively cover every possible match.',
719
+ },
720
+ {
721
+ guidance: true,
722
+ description:
723
+ 'Use createMarkdownFenceTransform for declared code-fence languages with semantic data. createNode returns an owned block extension node; its standard plugin renderer and toText own presentation. components.code still wins, and a declined or failed proposal keeps the accessible, copyable CodeBlock fallback.',
724
+ },
725
+ {
726
+ guidance: true,
727
+ description:
728
+ 'Use createMarkdownSourceDecoration to attach non-visual metadata — search hits, review annotations — to the blocks a source range touches, and getMarkdownSourceDecorations to read it back in a later plugin. Decorations appear on the settled document rather than on partial streaming chunks, and never change rendering, copyable text, accessible names, ids, focus order, or navigation.',
729
+ },
730
+ {
731
+ guidance: true,
732
+ description:
733
+ 'Import parseMarkdownAst or parseInlineAst from @astryxdesign/core/Markdown/parser when server or React Server Component code needs to run plugins against the canonical readonly tree. The parser and plugin subpaths have no use-client boundary. The Markdown component remains client-owned, so function-bearing plugin entries must not be passed across an RSC serialization boundary.',
734
+ },
735
+ {
736
+ guidance: true,
737
+ description:
738
+ 'Use createMarkdownFrontmatter for typed document metadata. Its parse() method gives the host metadata directly; its plugin removes a complete leading block before rendering and withholds an unfinished block during streaming.',
739
+ },
740
+ {
741
+ guidance: true,
742
+ description:
743
+ "Import createMarkdownRemarkTransform from '@astryxdesign/core/Markdown/remark' only to reuse an existing synchronous transform-only Remark plugin; it stays out of every other bundle. Prove each plugin with fixtures: anything outside the supported MDAST subset — async work, parser or compiler plugins, processor state, raw HTML, unsupported nodes, forged positions, or metadata Astryx cannot represent — keeps the last valid document and reports one diagnostic.",
744
+ },
745
+ {
746
+ guidance: true,
747
+ description:
748
+ 'Use inlinePlugins for prefixed identifiers, mentions, and other prose-only shorthand instead of preprocessing the markdown string.',
749
+ },
750
+ {
751
+ guidance: true,
752
+ description:
753
+ 'Provide components.math only for documents that use dollar-delimited math. The renderer owns typesetting and accessible output; Astryx passes the expression as text and never executes raw HTML.',
754
+ },
755
+ {
756
+ guidance: true,
757
+ description:
758
+ 'For direct parsing, use MathParseOptions and handle InlineNodeWithMath or BlockNodeWithMath. Incremental math parsing also uses createIncrementalState<true>() and IncrementalParseState<true>; default calls and ParseOptions annotations keep the legacy unions.',
759
+ },
760
+ {
761
+ guidance: true,
762
+ description:
763
+ 'Pair with Outline and useOutlineFromMarkdown for section navigation: headings render generated id attributes that match the outline item ids, so hash links scroll to their target.',
764
+ },
765
+ {
766
+ guidance: false,
767
+ description:
768
+ 'Use Markdown for hand-authored layouts; use Text and Heading directly when you control the content.',
769
+ },
451
770
  ],
452
771
  },
453
772
  };
@@ -460,25 +779,103 @@ export const docsDense = {
460
779
  description:
461
780
  'Renders a markdown string as Astryx-styled components. Use Markdown for user-generated content, AI responses, and documentation; it handles headings, lists, tables, code blocks, and citations with consistent styling.',
462
781
  bestPractices: [
463
- { guidance: true, description: 'Set headingLevelStart to match the page hierarchy, e.g. start at 3 if the markdown sits inside an h2 section.' },
464
- { guidance: true, description: 'Use contentWidth to keep prose at a readable line length in wide layouts.' },
465
- { guidance: true, description: 'Use inlinePlugins for custom shorthand patterns (issue refs, diff refs, mentions) instead of preprocessing the markdown string.' },
466
- { guidance: true, description: 'Headings render id attributes matching useOutlineFromMarkdown ids; pair with Outline for hash navigation.' },
467
- { guidance: false, description: 'Use Markdown for hand-authored layouts; use Text and Heading directly when you control the content.' },
782
+ {
783
+ guidance: true,
784
+ description:
785
+ 'Set headingLevelStart to match the page hierarchy, e.g. start at 3 if the markdown sits inside an h2 section.',
786
+ },
787
+ {
788
+ guidance: true,
789
+ description:
790
+ 'Use contentWidth to keep prose at a readable line length in wide layouts.',
791
+ },
792
+ {
793
+ guidance: true,
794
+ description:
795
+ 'Use plugins created by createMarkdownPlugin for reusable syntax, immutable AST transforms, and typed extension rendering. Keep the ordered list stable while its syntax configuration is unchanged.',
796
+ },
797
+ {
798
+ guidance: true,
799
+ description:
800
+ 'Use createMarkdownTextTransform for prose matching; it preserves code, links, images, citations, math, and accepted extension syntax as protected contexts. Provide requiredSubstrings only when they conservatively cover every possible match.',
801
+ },
802
+ {
803
+ guidance: true,
804
+ description:
805
+ 'Use createMarkdownFenceTransform for declared code-fence languages with semantic data. createNode returns an owned block extension node; its standard plugin renderer and toText own presentation. components.code still wins, and a declined or failed proposal keeps the accessible, copyable CodeBlock fallback.',
806
+ },
807
+ {
808
+ guidance: true,
809
+ description:
810
+ 'Use createMarkdownSourceDecoration to attach non-visual metadata — search hits, review annotations — to the blocks a source range touches, and getMarkdownSourceDecorations to read it back in a later plugin. Decorations appear on the settled document rather than on partial streaming chunks, and never change rendering, copyable text, accessible names, ids, focus order, or navigation.',
811
+ },
812
+ {
813
+ guidance: true,
814
+ description:
815
+ 'Import parseMarkdownAst or parseInlineAst from @astryxdesign/core/Markdown/parser when server or React Server Component code needs to run plugins against the canonical readonly tree. The parser and plugin subpaths have no use-client boundary. The Markdown component remains client-owned, so function-bearing plugin entries must not be passed across an RSC serialization boundary.',
816
+ },
817
+ {
818
+ guidance: true,
819
+ description:
820
+ 'Use createMarkdownFrontmatter for typed document metadata. Its parse() method gives the host metadata directly; its plugin removes a complete leading block before rendering and withholds an unfinished block during streaming.',
821
+ },
822
+ {
823
+ guidance: true,
824
+ description:
825
+ "Import createMarkdownRemarkTransform from '@astryxdesign/core/Markdown/remark' only to reuse a synchronous transform-only Remark plugin; it stays out of every other bundle and unsupported behavior keeps the last valid document with one diagnostic.",
826
+ },
827
+ {
828
+ guidance: true,
829
+ description:
830
+ 'Use inlinePlugins for prefixed identifiers, mentions, and other prose-only shorthand instead of preprocessing the markdown string.',
831
+ },
832
+ {
833
+ guidance: true,
834
+ description:
835
+ 'Provide components.math only for documents that use dollar-delimited math; the renderer owns typesetting and accessible output.',
836
+ },
837
+ {
838
+ guidance: true,
839
+ description:
840
+ 'Direct math parser calls use MathParseOptions and the explicit WithMath node unions; incremental calls also use createIncrementalState<true>() and IncrementalParseState<true>. Default calls keep the legacy unions.',
841
+ },
842
+ {
843
+ guidance: true,
844
+ description:
845
+ 'Headings render id attributes matching useOutlineFromMarkdown ids; pair with Outline for hash navigation.',
846
+ },
847
+ {
848
+ guidance: false,
849
+ description:
850
+ 'Use Markdown for hand-authored layouts; use Text and Heading directly when you control the content.',
851
+ },
468
852
  ],
469
853
  },
470
854
  propDescriptions: {
471
855
  children: 'markdown string',
472
856
  density: "Block spacing. 'default'|'compact'. Default: 'default'.",
473
- headingLevelStart: 'Maps # to this heading level (1-6). Clamped to h6. Default: 1.',
474
- isStreaming: 'Incremental parse + fade-in for streamed chunks. Default: false.',
475
- onLinkClick: '(href, event) => void|false. Return false prevents navigation.',
476
- sources: 'Record<string, MarkdownSource>. Citation sources by ID. [id]/【id】 markers render as chips.',
477
- citationStyle: "'label'|'number'. label=chip w/ title+icon, number=compact badge. Default: 'label'.",
478
- contentWidth: 'number|string. Max width for prose (headings, paragraphs, lists). Tables/code unconstrained.',
479
- contentAlign: "'start'|'center'. Prose alignment when contentWidth < container. Default: 'start'.",
480
- inlinePlugins: 'MarkdownInlinePlugin[]. Regex matches in text nodes -> custom inline React elements. Skips inline/fenced code.',
481
- autolink: "'gfm'. Opt-in GFM autolinking: bare URLs (https?://, www.), <scheme:url>, <email>, user@host. Skips code, code blocks, existing links. Default: off.",
857
+ headingLevelStart:
858
+ 'Maps # to this heading level (1-6). Clamped to h6. Default: 1.',
859
+ isStreaming:
860
+ 'Incremental parse + fade-in for streamed chunks. Default: false.',
861
+ onLinkClick:
862
+ '(href, event) => void|false. Return false prevents navigation.',
863
+ sources:
864
+ 'Record<string, MarkdownSource>. Citation sources by ID. [id]/【id】 markers render as chips.',
865
+ citationStyle:
866
+ "'label'|'number'. label=chip w/ title+icon, number=compact badge. Default: 'label'.",
867
+ contentWidth:
868
+ 'number|string. Max width for prose (headings, paragraphs, lists). Tables/code unconstrained.',
869
+ contentAlign:
870
+ "'start'|'center'. Prose alignment when contentWidth < container. Default: 'start'.",
871
+ plugins:
872
+ 'readonly MarkdownPluginEntry[]. Ordered syntax, immutable AST transforms, and typed extension renderers from createMarkdownPlugin(). Narrow observed extensions with isMarkdownExtensionNode(); renderer callbacks are pure. Default: omitted or empty.',
873
+ inlinePlugins:
874
+ 'MarkdownInlinePlugin[]. Regex matches in text nodes -> custom inline React elements. Skips inline/fenced code and math.',
875
+ autolink:
876
+ "'gfm'. Opt-in GFM autolinking: bare URLs (https?://, www.), <scheme:url>, <email>, user@host. Skips code, code blocks, existing links. Default: off.",
877
+ components:
878
+ 'MarkdownComponents. Custom renderers; math({value, display}) opts into $…$/$$…$$ parsing. Renderer owns output and accessibility.',
482
879
  xstyle: 'stylex.create() for layout (margins, sizing).',
483
880
  className: 'CSS class. Prefer xstyle.',
484
881
  style: 'Inline styles. Prefer xstyle.',