@astryxdesign/core 0.5.2-canary.2da7a39 → 0.5.2-canary.2e51213

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 (375) hide show
  1. package/dist/AppShell/AppShell.d.ts +2 -2
  2. package/dist/AppShell/AppShell.d.ts.map +1 -1
  3. package/dist/AppShell/AppShell.js +10 -7
  4. package/dist/Banner/Banner.d.ts +5 -0
  5. package/dist/Banner/Banner.d.ts.map +1 -1
  6. package/dist/Banner/Banner.js +7 -2
  7. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +3 -2
  8. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  9. package/dist/Breadcrumbs/BreadcrumbItem.js +22 -15
  10. package/dist/Carousel/Carousel.d.ts.map +1 -1
  11. package/dist/Carousel/Carousel.js +2 -2
  12. package/dist/Chat/ChatComposer.d.ts +2 -2
  13. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  14. package/dist/Chat/ChatComposer.js +21 -2
  15. package/dist/Chat/ChatToolCalls.d.ts +1 -1
  16. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  17. package/dist/Chat/ChatToolCalls.js +12 -34
  18. package/dist/Chat/useChatNewMessages.js +3 -3
  19. package/dist/CheckboxList/CheckboxListItem.d.ts +5 -3
  20. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  21. package/dist/DateTimeInput/DateTimeInput.d.ts +47 -13
  22. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  23. package/dist/DateTimeInput/DateTimeInput.js +269 -162
  24. package/dist/DateTimeInput/NativeDateSegment.d.ts +24 -0
  25. package/dist/DateTimeInput/NativeDateSegment.d.ts.map +1 -0
  26. package/dist/DateTimeInput/NativeDateSegment.js +235 -0
  27. package/dist/DateTimeInput/NativeTimeSegment.d.ts +30 -0
  28. package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -0
  29. package/dist/DateTimeInput/NativeTimeSegment.js +248 -0
  30. package/dist/DateTimeInput/index.d.ts +1 -1
  31. package/dist/DateTimeInput/index.d.ts.map +1 -1
  32. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts +95 -0
  33. package/dist/DateTimeInput/nativePickerSegmentStyles.d.ts.map +1 -0
  34. package/dist/DateTimeInput/nativePickerSegmentStyles.js +103 -0
  35. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  36. package/dist/DropdownMenu/DropdownMenu.js +2 -4
  37. package/dist/Field/Field.d.ts.map +1 -1
  38. package/dist/Field/Field.js +10 -4
  39. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  40. package/dist/Field/PanelSearchInput.js +3 -5
  41. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  42. package/dist/FieldStatus/FieldStatus.js +4 -2
  43. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  44. package/dist/Layer/useTouchTrigger.js +2 -4
  45. package/dist/Layout/Layout.d.ts +7 -8
  46. package/dist/Layout/Layout.d.ts.map +1 -1
  47. package/dist/Layout/Layout.js +7 -8
  48. package/dist/MultiSelector/MultiSelector.d.ts +11 -1
  49. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  50. package/dist/MultiSelector/MultiSelector.js +89 -45
  51. package/dist/RadioList/RadioListItem.d.ts +30 -5
  52. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  53. package/dist/RadioList/RadioListItem.js +17 -4
  54. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  55. package/dist/Resizable/ResizeHandle.js +102 -44
  56. package/dist/Resizable/index.d.ts +2 -0
  57. package/dist/Resizable/index.d.ts.map +1 -1
  58. package/dist/Resizable/index.js +1 -0
  59. package/dist/Resizable/useResizable.d.ts +89 -8
  60. package/dist/Resizable/useResizable.d.ts.map +1 -1
  61. package/dist/Resizable/useResizable.js +521 -38
  62. package/dist/Resizable/utils.d.ts +35 -0
  63. package/dist/Resizable/utils.d.ts.map +1 -0
  64. package/dist/Resizable/utils.js +27 -0
  65. package/dist/Selector/Selector.d.ts +10 -0
  66. package/dist/Selector/Selector.d.ts.map +1 -1
  67. package/dist/Selector/Selector.js +105 -57
  68. package/dist/Selector/useSelectorPresentation.d.ts +1 -0
  69. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
  70. package/dist/Selector/useSelectorPresentation.js +17 -2
  71. package/dist/Slider/Slider.d.ts.map +1 -1
  72. package/dist/Slider/Slider.js +3 -5
  73. package/dist/Spinner/Spinner.d.ts.map +1 -1
  74. package/dist/Spinner/Spinner.js +9 -10
  75. package/dist/Stepper/Step.d.ts +2 -1
  76. package/dist/Stepper/Step.d.ts.map +1 -1
  77. package/dist/Stepper/Step.js +75 -11
  78. package/dist/Stepper/Stepper.d.ts.map +1 -1
  79. package/dist/Stepper/Stepper.js +1 -0
  80. package/dist/TabList/TabList.d.ts.map +1 -1
  81. package/dist/TabList/TabList.js +2 -3
  82. package/dist/Table/index.d.ts +16 -1
  83. package/dist/Table/index.d.ts.map +1 -1
  84. package/dist/Table/index.js +4 -0
  85. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  86. package/dist/Table/plugins/columnResize/useTableColumnResize.js +8 -9
  87. package/dist/Table/plugins/rowStatus/index.d.ts +1 -1
  88. package/dist/Table/plugins/rowStatus/index.d.ts.map +1 -1
  89. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +11 -30
  90. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  91. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +108 -62
  92. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  93. package/dist/Table/plugins/sortable/useTableSortable.js +9 -1
  94. package/dist/Text/useTruncation.d.ts +1 -1
  95. package/dist/Text/useTruncation.d.ts.map +1 -1
  96. package/dist/Text/useTruncation.js +8 -7
  97. package/dist/TimeInput/TimeInput.d.ts +16 -1
  98. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  99. package/dist/TimeInput/TimeInput.js +98 -60
  100. package/dist/TimeInput/index.d.ts +1 -1
  101. package/dist/TimeInput/index.d.ts.map +1 -1
  102. package/dist/Timestamp/Timestamp.d.ts +2 -2
  103. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  104. package/dist/Timestamp/Timestamp.js +4 -145
  105. package/dist/Timestamp/formatRelativeTime.d.ts +20 -0
  106. package/dist/Timestamp/formatRelativeTime.d.ts.map +1 -0
  107. package/dist/Timestamp/formatRelativeTime.js +81 -0
  108. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  109. package/dist/Toast/ToastViewport.js +125 -77
  110. package/dist/Tokenizer/Tokenizer.d.ts +0 -38
  111. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  112. package/dist/Tokenizer/Tokenizer.js +94 -26
  113. package/dist/Tokenizer/useEndLaneReserve.d.ts +31 -0
  114. package/dist/Tokenizer/useEndLaneReserve.d.ts.map +1 -0
  115. package/dist/Tokenizer/useEndLaneReserve.js +136 -0
  116. package/dist/Tooltip/useTooltip.d.ts +1 -1
  117. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  118. package/dist/Tooltip/useTooltip.js +53 -42
  119. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  120. package/dist/Typeahead/BaseTypeahead.js +85 -30
  121. package/dist/Typeahead/Typeahead.d.ts +0 -21
  122. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  123. package/dist/Typeahead/Typeahead.js +108 -67
  124. package/dist/Typeahead/busyIndicatorLane.d.ts +62 -0
  125. package/dist/Typeahead/busyIndicatorLane.d.ts.map +1 -0
  126. package/dist/Typeahead/busyIndicatorLane.js +98 -0
  127. package/dist/astryx.css +25 -7
  128. package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -1
  129. package/dist/hooks/useFocusReturnVisibility.js +3 -5
  130. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +2 -2
  131. package/dist/hooks/useIsomorphicLayoutEffect.d.ts.map +1 -1
  132. package/dist/hooks/useOverflow.js +11 -11
  133. package/dist/hooks/useScrollOverflow.d.ts.map +1 -1
  134. package/dist/hooks/useScrollOverflow.js +7 -4
  135. package/dist/theme/defineTheme.d.ts +13 -0
  136. package/dist/theme/defineTheme.d.ts.map +1 -1
  137. package/dist/theme/defineTheme.js +7 -0
  138. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  139. package/dist/theme/generateThemeRules.js +1 -1
  140. package/dist/theme/localTokens.d.ts +18 -0
  141. package/dist/theme/localTokens.d.ts.map +1 -0
  142. package/dist/theme/localTokens.js +162 -0
  143. package/dist/utils/interactionModality.d.ts +6 -28
  144. package/dist/utils/interactionModality.d.ts.map +1 -1
  145. package/dist/utils/interactionModality.js +72 -37
  146. package/dist/utils/sharedResizeObserver.d.ts +17 -9
  147. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  148. package/dist/utils/sharedResizeObserver.js +54 -12
  149. package/locales/en.json +8 -0
  150. package/locales/pseudo.json +6 -0
  151. package/package.json +7 -2
  152. package/src/AlertDialog/useImperativeAlertDialog.test.tsx +163 -0
  153. package/src/AppShell/AppShell.doc.mjs +4 -3
  154. package/src/AppShell/AppShell.test.tsx +21 -0
  155. package/src/AppShell/AppShell.tsx +12 -7
  156. package/src/Banner/Banner.doc.mjs +5 -1
  157. package/src/Banner/Banner.tsx +12 -1
  158. package/src/BottomSheet/BottomSheet.doc.mjs +31 -0
  159. package/src/BottomSheet/BottomSheet.spec.md +178 -0
  160. package/src/Breadcrumbs/BreadcrumbItem.tsx +18 -9
  161. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +4 -1
  162. package/src/Breadcrumbs/Breadcrumbs.test.tsx +12 -0
  163. package/src/Button/Button.doc.mjs +56 -0
  164. package/src/ButtonGroup/ButtonGroup.doc.mjs +47 -0
  165. package/src/Calendar/hooks/useCalendarConstraints.test.ts +153 -0
  166. package/src/Calendar/hooks/useCalendarDays.test.ts +265 -0
  167. package/src/Calendar/hooks/useCalendarNavigation.test.ts +252 -0
  168. package/src/Carousel/Carousel.test.tsx +83 -0
  169. package/src/Carousel/Carousel.tsx +8 -2
  170. package/src/Chat/ChatComposer.doc.mjs +7 -4
  171. package/src/Chat/ChatComposer.test.tsx +84 -2
  172. package/src/Chat/ChatComposer.tsx +45 -3
  173. package/src/Chat/ChatSendButton.test.tsx +189 -0
  174. package/src/Chat/ChatToolCalls.doc.mjs +1 -1
  175. package/src/Chat/ChatToolCalls.test.tsx +33 -1
  176. package/src/Chat/ChatToolCalls.tsx +13 -34
  177. package/src/Chat/useChatNewMessages.ts +3 -3
  178. package/src/Chat/useChatPasteAsToken.test.ts +191 -0
  179. package/src/CheckboxList/CheckboxList.doc.mjs +172 -31
  180. package/src/CheckboxList/CheckboxList.spec.md +215 -0
  181. package/src/CheckboxList/CheckboxList.test.tsx +45 -0
  182. package/src/CheckboxList/CheckboxListItem.doc.mjs +11 -9
  183. package/src/CheckboxList/CheckboxListItem.tsx +5 -3
  184. package/src/Collapsible/useCollapsible.test.tsx +236 -0
  185. package/src/CommandPalette/CommandPalette.doc.mjs +72 -0
  186. package/src/CommandPalette/CommandPalette.spec.md +224 -0
  187. package/src/CommandPalette/CommandPaletteEmpty.test.tsx +101 -0
  188. package/src/ComplexSelector/ComplexSelector.doc.mjs +42 -0
  189. package/src/ComplexSelector/ComplexSelector.spec.md +190 -0
  190. package/src/ContextMenu/ContextMenu.doc.mjs +48 -0
  191. package/src/ContextMenu/ContextMenu.spec.md +207 -0
  192. package/src/DateTimeInput/DateTimeInput.doc.mjs +43 -23
  193. package/src/DateTimeInput/DateTimeInput.tsx +388 -181
  194. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +10 -2
  195. package/src/DateTimeInput/NativeDateSegment.tsx +308 -0
  196. package/src/DateTimeInput/NativePickerSegments.test.tsx +626 -0
  197. package/src/DateTimeInput/NativeTimeSegment.tsx +331 -0
  198. package/src/DateTimeInput/index.ts +1 -0
  199. package/src/DateTimeInput/nativePickerSegmentStyles.ts +120 -0
  200. package/src/Divider/Divider.doc.mjs +24 -0
  201. package/src/Divider/Divider.spec.md +157 -0
  202. package/src/DropdownMenu/DropdownMenu.doc.mjs +104 -0
  203. package/src/DropdownMenu/DropdownMenu.spec.md +246 -0
  204. package/src/DropdownMenu/DropdownMenu.tsx +2 -4
  205. package/src/Field/Field.doc.mjs +1 -0
  206. package/src/Field/Field.test.tsx +39 -0
  207. package/src/Field/Field.tsx +18 -1
  208. package/src/Field/InputClearButton.test.tsx +68 -6
  209. package/src/Field/PanelSearchInput.tsx +3 -5
  210. package/src/FieldStatus/FieldStatus.doc.mjs +21 -0
  211. package/src/FieldStatus/FieldStatus.spec.md +213 -0
  212. package/src/FieldStatus/FieldStatus.test.tsx +17 -0
  213. package/src/FieldStatus/FieldStatus.tsx +7 -2
  214. package/src/Grid/Grid.doc.mjs +19 -0
  215. package/src/Grid/Grid.spec.md +162 -0
  216. package/src/Icon/Icon.doc.mjs +196 -48
  217. package/src/Icon/Icon.spec.md +192 -0
  218. package/src/IconButton/IconButton.doc.mjs +38 -0
  219. package/src/Kbd/Kbd.doc.mjs +18 -0
  220. package/src/Kbd/Kbd.spec.md +142 -0
  221. package/src/Layer/useTouchTrigger.ts +2 -4
  222. package/src/Layout/Layout.doc.mjs +57 -17
  223. package/src/Layout/Layout.spec.md +235 -0
  224. package/src/Layout/Layout.test.tsx +1 -1
  225. package/src/Layout/Layout.tsx +7 -8
  226. package/src/Layout/LayoutHeader.doc.mjs +9 -0
  227. package/src/Layout/LayoutPanel.doc.mjs +4 -3
  228. package/src/Lightbox/Lightbox.doc.mjs +149 -33
  229. package/src/Lightbox/Lightbox.spec.md +198 -0
  230. package/src/Lightbox/useLightbox.test.tsx +263 -0
  231. package/src/Markdown/Markdown.doc.mjs +60 -0
  232. package/src/Markdown/Markdown.spec.md +207 -0
  233. package/src/MobileNav/MobileNav.doc.mjs +140 -32
  234. package/src/MobileNav/MobileNav.spec.md +209 -0
  235. package/src/MoreMenu/MoreMenu.doc.mjs +42 -0
  236. package/src/MoreMenu/MoreMenu.spec.md +222 -0
  237. package/src/MultiSelector/MultiSelector.doc.mjs +124 -1
  238. package/src/MultiSelector/MultiSelector.spec.md +293 -0
  239. package/src/MultiSelector/MultiSelector.test.tsx +305 -2
  240. package/src/MultiSelector/MultiSelector.tsx +124 -55
  241. package/src/NavIcon/NavIcon.doc.mjs +17 -0
  242. package/src/NavIcon/NavIcon.spec.md +134 -0
  243. package/src/NavMenu/NavHeadingMenu.spec.md +210 -0
  244. package/src/NavMenu/NavMenu.doc.mjs +37 -0
  245. package/src/Outline/Outline.doc.mjs +35 -0
  246. package/src/Outline/Outline.spec.md +162 -0
  247. package/src/OverflowList/OverflowList.doc.mjs +24 -0
  248. package/src/OverflowList/OverflowList.spec.md +157 -0
  249. package/src/Pagination/Pagination.doc.mjs +74 -0
  250. package/src/Pagination/Pagination.spec.md +226 -0
  251. package/src/Popover/Popover.doc.mjs +264 -65
  252. package/src/Popover/Popover.spec.md +421 -0
  253. package/src/Popover/usePopover.doc.mjs +208 -33
  254. package/src/PowerSearch/PowerSearch.spec.md +291 -0
  255. package/src/PowerSearch/PowerSearchFilterEditor.test.tsx +253 -0
  256. package/src/PowerSearch/PowerSearchToken.test.tsx +228 -0
  257. package/src/ProgressBar/ProgressBar.doc.mjs +198 -38
  258. package/src/ProgressBar/ProgressBar.spec.md +261 -0
  259. package/src/RadioList/RadioList.test.tsx +136 -2
  260. package/src/RadioList/RadioListItem.doc.mjs +30 -11
  261. package/src/RadioList/RadioListItem.tsx +44 -8
  262. package/src/Resizable/Resizable.doc.mjs +130 -24
  263. package/src/Resizable/Resizable.spec.md +246 -0
  264. package/src/Resizable/ResizeHandle.test.tsx +177 -56
  265. package/src/Resizable/ResizeHandle.tsx +128 -45
  266. package/src/Resizable/index.ts +2 -0
  267. package/src/Resizable/shippedDirections.test.ts +462 -0
  268. package/src/Resizable/useResizable.doc.mjs +124 -29
  269. package/src/Resizable/useResizable.test.ts +1277 -3
  270. package/src/Resizable/useResizable.ts +760 -48
  271. package/src/Resizable/utils.test.ts +74 -0
  272. package/src/Resizable/utils.ts +35 -0
  273. package/src/Section/Section.doc.mjs +17 -0
  274. package/src/Section/Section.spec.md +139 -0
  275. package/src/SegmentedControl/SegmentedControl.doc.mjs +83 -0
  276. package/src/SegmentedControl/SegmentedControl.spec.md +152 -0
  277. package/src/Selector/Selector.doc.mjs +133 -97
  278. package/src/Selector/Selector.spec.md +300 -0
  279. package/src/Selector/Selector.test.tsx +318 -1
  280. package/src/Selector/Selector.tsx +127 -60
  281. package/src/Selector/useSelectorPresentation.ts +24 -4
  282. package/src/SideNav/SideNav.test.tsx +3 -3
  283. package/src/SideNav/SideNavCollapseButton.doc.mjs +8 -0
  284. package/src/SideNav/SideNavItem.doc.mjs +1 -1
  285. package/src/Skeleton/Skeleton.doc.mjs +12 -0
  286. package/src/Skeleton/Skeleton.spec.md +127 -0
  287. package/src/Slider/Slider.doc.mjs +184 -30
  288. package/src/Slider/Slider.spec.md +224 -0
  289. package/src/Slider/Slider.tsx +2 -5
  290. package/src/Spinner/Spinner.doc.mjs +5 -5
  291. package/src/Spinner/Spinner.test.tsx +32 -7
  292. package/src/Spinner/Spinner.tsx +46 -14
  293. package/src/Stack/Stack.doc.mjs +22 -0
  294. package/src/Stack/Stack.spec.md +155 -0
  295. package/src/StatusDot/StatusDot.doc.mjs +17 -0
  296. package/src/StatusDot/StatusDot.spec.md +138 -0
  297. package/src/Stepper/Step.doc.mjs +1 -1
  298. package/src/Stepper/Step.tsx +118 -5
  299. package/src/Stepper/Stepper.doc.mjs +51 -1
  300. package/src/Stepper/Stepper.spec.md +245 -0
  301. package/src/Stepper/Stepper.test.tsx +315 -0
  302. package/src/Stepper/Stepper.tsx +8 -0
  303. package/src/Switch/Switch.doc.mjs +40 -0
  304. package/src/Switch/Switch.spec.md +175 -0
  305. package/src/TabList/TabList.tsx +2 -3
  306. package/src/Table/Table.doc.mjs +102 -24
  307. package/src/Table/Table.perf.test.tsx +51 -1
  308. package/src/Table/Table.spec.md +325 -0
  309. package/src/Table/TableHeaderCell.test.tsx +291 -0
  310. package/src/Table/index.ts +19 -4
  311. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -12
  312. package/src/Table/plugins/filtering/useTableFilterState.test.tsx +143 -0
  313. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +2 -1
  314. package/src/Table/plugins/rowStatus/index.ts +1 -4
  315. package/src/Table/plugins/rowStatus/useTableRowStatus.public.test.ts +92 -0
  316. package/src/Table/plugins/rowStatus/useTableRowStatus.spec.md +354 -0
  317. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +431 -56
  318. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +155 -84
  319. package/src/Table/plugins/sortable/useTableSortable.test.tsx +72 -0
  320. package/src/Table/plugins/sortable/useTableSortable.tsx +18 -1
  321. package/src/Table/useTableGroupedRows.doc.mjs +2 -2
  322. package/src/Table/useTableRowStatus.doc.mjs +5 -5
  323. package/src/Text/Text.doc.mjs +190 -43
  324. package/src/Text/Text.spec.md +206 -0
  325. package/src/Text/useTruncation.ts +8 -7
  326. package/src/TextArea/TextArea.doc.mjs +255 -45
  327. package/src/TextArea/TextArea.spec.md +205 -0
  328. package/src/TimeInput/NativeTimeInput.test.tsx +269 -0
  329. package/src/TimeInput/TimeInput.doc.mjs +47 -23
  330. package/src/TimeInput/TimeInput.tsx +109 -50
  331. package/src/TimeInput/index.ts +1 -0
  332. package/src/Timestamp/Timestamp.doc.mjs +2 -2
  333. package/src/Timestamp/Timestamp.test.tsx +75 -3
  334. package/src/Timestamp/Timestamp.tsx +7 -153
  335. package/src/Timestamp/formatRelativeTime.ts +96 -0
  336. package/src/Toast/ToastViewport.test.tsx +194 -0
  337. package/src/Toast/ToastViewport.tsx +136 -58
  338. package/src/ToggleButton/ToggleButton.doc.mjs +56 -0
  339. package/src/Tokenizer/Tokenizer.doc.mjs +2 -0
  340. package/src/Tokenizer/Tokenizer.spec.md +293 -0
  341. package/src/Tokenizer/Tokenizer.test.tsx +335 -1
  342. package/src/Tokenizer/Tokenizer.tsx +129 -46
  343. package/src/Tokenizer/useEndLaneReserve.ts +146 -0
  344. package/src/Toolbar/Toolbar.doc.mjs +19 -0
  345. package/src/Toolbar/Toolbar.spec.md +174 -0
  346. package/src/Tooltip/Tooltip.doc.mjs +17 -0
  347. package/src/Tooltip/Tooltip.spec.md +142 -0
  348. package/src/Tooltip/Tooltip.test.tsx +21 -1
  349. package/src/Tooltip/useTooltip.test.tsx +318 -0
  350. package/src/Tooltip/useTooltip.tsx +60 -39
  351. package/src/TreeList/TreeList.doc.mjs +58 -0
  352. package/src/TreeList/TreeList.spec.md +224 -0
  353. package/src/Typeahead/BaseTypeahead.tsx +96 -25
  354. package/src/Typeahead/Typeahead.doc.mjs +89 -1
  355. package/src/Typeahead/Typeahead.spec.md +257 -0
  356. package/src/Typeahead/Typeahead.test.tsx +502 -1
  357. package/src/Typeahead/Typeahead.tsx +187 -69
  358. package/src/Typeahead/TypeaheadItem.test.tsx +93 -2
  359. package/src/Typeahead/busyIndicatorLane.tsx +109 -0
  360. package/src/__tests__/stylexDeclarations.ts +51 -0
  361. package/src/hooks/useFocusReturnVisibility.ts +3 -5
  362. package/src/hooks/useOverflow.ts +11 -11
  363. package/src/hooks/useScrollLock.test.ts +103 -0
  364. package/src/hooks/useScrollOverflow.ts +7 -4
  365. package/src/i18n/useTranslator.test.tsx +197 -0
  366. package/src/theme/defineTheme.test.ts +227 -0
  367. package/src/theme/defineTheme.ts +30 -0
  368. package/src/theme/derivedVarRegistry.test.ts +6 -0
  369. package/src/theme/generateThemeRules.ts +4 -1
  370. package/src/theme/localTokens.ts +272 -0
  371. package/src/theme/themingTargets.test.ts +126 -28
  372. package/src/utils/interactionModality.test.ts +83 -0
  373. package/src/utils/interactionModality.ts +88 -36
  374. package/src/utils/sharedResizeObserver.test.ts +124 -5
  375. package/src/utils/sharedResizeObserver.ts +60 -14
@@ -0,0 +1,263 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file useLightbox.test.tsx
5
+ * @input Uses vitest, @testing-library/react, useLightbox hook
6
+ * @output Unit tests for lightbox open/close state and trigger props
7
+ * @position Testing; validates useLightbox.tsx implementation
8
+ *
9
+ * SYNC: When useLightbox.tsx changes, update tests to match new behavior
10
+ */
11
+
12
+ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
13
+ import {
14
+ render,
15
+ screen,
16
+ fireEvent,
17
+ renderHook,
18
+ act,
19
+ } from '@testing-library/react';
20
+ import {useLightbox} from './useLightbox';
21
+ import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
22
+
23
+ // jsdom doesn't implement dialog.showModal/close.
24
+ beforeEach(() => {
25
+ HTMLDialogElement.prototype.showModal = vi.fn(function (
26
+ this: HTMLDialogElement,
27
+ ) {
28
+ this.setAttribute('open', '');
29
+ });
30
+ HTMLDialogElement.prototype.close = vi.fn(function (this: HTMLDialogElement) {
31
+ this.removeAttribute('open');
32
+ });
33
+ });
34
+
35
+ // Lightbox announces gallery navigation through the singleton live regions
36
+ // useAnnounce mounts on <body>; reset them so nothing leaks between tests.
37
+ afterEach(() => {
38
+ __resetLiveRegionsForTest();
39
+ });
40
+
41
+ // Module scope so the reference stays stable across rerenders.
42
+ const photos = [
43
+ {src: '/p1.jpg', alt: 'Photo 1'},
44
+ {src: '/p2.jpg', alt: 'Photo 2'},
45
+ {src: '/p3.jpg', alt: 'Photo 3'},
46
+ {src: '/p4.jpg', alt: 'Photo 4'},
47
+ ];
48
+
49
+ /** Renders both trigger flavors plus the lightbox element itself. */
50
+ function Gallery() {
51
+ const lightbox = useLightbox({media: photos});
52
+
53
+ return (
54
+ <div>
55
+ <span data-testid="status">{lightbox.isOpen ? 'open' : 'closed'}</span>
56
+ <span data-testid="index">{lightbox.index}</span>
57
+ <span data-testid="shared" {...lightbox.triggerProps}>
58
+ Open gallery
59
+ </span>
60
+ {photos.map((photo, i) => (
61
+ <img
62
+ key={photo.src}
63
+ src={photo.src}
64
+ alt={`thumb ${i}`}
65
+ data-testid={`thumb-${i}`}
66
+ {...lightbox.getTriggerProps(i)}
67
+ />
68
+ ))}
69
+ {lightbox.element}
70
+ </div>
71
+ );
72
+ }
73
+
74
+ describe('useLightbox — state', () => {
75
+ it('starts closed at the first item', () => {
76
+ const {result} = renderHook(() => useLightbox({media: photos}));
77
+ expect(result.current.isOpen).toBe(false);
78
+ expect(result.current.index).toBe(0);
79
+ });
80
+
81
+ it('opens at the first item when open() is called without an index', () => {
82
+ const {result} = renderHook(() => useLightbox({media: photos}));
83
+
84
+ act(() => result.current.open(2));
85
+ act(() => result.current.close());
86
+ // A bare open() resets to the start rather than reusing the last index.
87
+ act(() => result.current.open());
88
+
89
+ expect(result.current.isOpen).toBe(true);
90
+ expect(result.current.index).toBe(0);
91
+ });
92
+
93
+ it('opens at the requested index', () => {
94
+ const {result} = renderHook(() => useLightbox({media: photos}));
95
+
96
+ act(() => result.current.open(2));
97
+
98
+ expect(result.current.isOpen).toBe(true);
99
+ expect(result.current.index).toBe(2);
100
+ });
101
+
102
+ it('close() closes without rewinding the index', () => {
103
+ const {result} = renderHook(() => useLightbox({media: photos}));
104
+
105
+ act(() => result.current.open(3));
106
+ act(() => result.current.close());
107
+
108
+ expect(result.current.isOpen).toBe(false);
109
+ expect(result.current.index).toBe(3);
110
+ });
111
+
112
+ // The `if (!nextOpen)` guard in the hook's onOpenChange is deliberately not
113
+ // covered: Lightbox only ever reports `false`, so the ignored-`true` path is
114
+ // unreachable through the public surface. Reaching into the element's props
115
+ // to force it would assert a value that is already settled, and it can only
116
+ // be exercised for real once something emits `true`.
117
+ });
118
+
119
+ describe('useLightbox — trigger props', () => {
120
+ it('gives the trigger button semantics', () => {
121
+ render(<Gallery />);
122
+ const trigger = screen.getByTestId('shared');
123
+ expect(trigger).toHaveAttribute('role', 'button');
124
+ expect(trigger).toHaveAttribute('tabindex', '0');
125
+ expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
126
+ });
127
+
128
+ it('gives every indexed trigger the same button semantics', () => {
129
+ render(<Gallery />);
130
+ const trigger = screen.getByTestId('thumb-2');
131
+ expect(trigger).toHaveAttribute('role', 'button');
132
+ expect(trigger).toHaveAttribute('tabindex', '0');
133
+ expect(trigger).toHaveAttribute('aria-haspopup', 'dialog');
134
+ });
135
+
136
+ it('opens at the first item when the shared trigger is clicked', () => {
137
+ render(<Gallery />);
138
+ fireEvent.click(screen.getByTestId('shared'));
139
+ expect(screen.getByTestId('status').textContent).toBe('open');
140
+ expect(screen.getByTestId('index').textContent).toBe('0');
141
+ });
142
+
143
+ it('opens on Enter and swallows the key press', () => {
144
+ render(<Gallery />);
145
+ const notDefaultPrevented = fireEvent.keyDown(
146
+ screen.getByTestId('shared'),
147
+ {
148
+ key: 'Enter',
149
+ },
150
+ );
151
+ expect(notDefaultPrevented).toBe(false);
152
+ expect(screen.getByTestId('status').textContent).toBe('open');
153
+ });
154
+
155
+ it('opens on Space and swallows the key press', () => {
156
+ render(<Gallery />);
157
+ const notDefaultPrevented = fireEvent.keyDown(
158
+ screen.getByTestId('shared'),
159
+ {
160
+ key: ' ',
161
+ },
162
+ );
163
+ expect(notDefaultPrevented).toBe(false);
164
+ expect(screen.getByTestId('status').textContent).toBe('open');
165
+ });
166
+
167
+ it('leaves other keys alone', () => {
168
+ render(<Gallery />);
169
+ for (const key of ['a', 'Tab', 'ArrowRight', 'Escape']) {
170
+ const notDefaultPrevented = fireEvent.keyDown(
171
+ screen.getByTestId('shared'),
172
+ {key},
173
+ );
174
+ expect(notDefaultPrevented).toBe(true);
175
+ expect(screen.getByTestId('status').textContent).toBe('closed');
176
+ }
177
+ });
178
+
179
+ it('opens at the trigger index when an indexed trigger is clicked', () => {
180
+ render(<Gallery />);
181
+ fireEvent.click(screen.getByTestId('thumb-2'));
182
+ expect(screen.getByTestId('status').textContent).toBe('open');
183
+ expect(screen.getByTestId('index').textContent).toBe('2');
184
+ });
185
+
186
+ it('opens at the trigger index on Enter and swallows the key press', () => {
187
+ render(<Gallery />);
188
+ const notDefaultPrevented = fireEvent.keyDown(
189
+ screen.getByTestId('thumb-3'),
190
+ {key: 'Enter'},
191
+ );
192
+ expect(notDefaultPrevented).toBe(false);
193
+ expect(screen.getByTestId('index').textContent).toBe('3');
194
+ });
195
+
196
+ it('opens at the trigger index on Space and swallows the key press', () => {
197
+ render(<Gallery />);
198
+ const notDefaultPrevented = fireEvent.keyDown(
199
+ screen.getByTestId('thumb-1'),
200
+ {key: ' '},
201
+ );
202
+ expect(notDefaultPrevented).toBe(false);
203
+ expect(screen.getByTestId('index').textContent).toBe('1');
204
+ });
205
+
206
+ it('leaves other keys alone on an indexed trigger', () => {
207
+ render(<Gallery />);
208
+ const notDefaultPrevented = fireEvent.keyDown(
209
+ screen.getByTestId('thumb-1'),
210
+ {key: 'a'},
211
+ );
212
+ expect(notDefaultPrevented).toBe(true);
213
+ expect(screen.getByTestId('status').textContent).toBe('closed');
214
+ });
215
+ });
216
+
217
+ describe('useLightbox — element wiring', () => {
218
+ it('keeps the lightbox closed until a trigger fires', () => {
219
+ render(<Gallery />);
220
+ expect(document.querySelector('dialog')).not.toHaveAttribute('open');
221
+ });
222
+
223
+ it('shows the media for the index the trigger opened', () => {
224
+ render(<Gallery />);
225
+ fireEvent.click(screen.getByTestId('thumb-2'));
226
+
227
+ const dialog = document.querySelector('dialog')!;
228
+ expect(dialog).toHaveAttribute('open');
229
+ expect(screen.getByAltText('Photo 3')).toBeInTheDocument();
230
+ expect(screen.queryByAltText('Photo 1')).toBeNull();
231
+ });
232
+
233
+ it('closes when the lightbox close button is pressed', () => {
234
+ render(<Gallery />);
235
+ fireEvent.click(screen.getByTestId('thumb-2'));
236
+
237
+ fireEvent.click(screen.getByRole('button', {name: 'Close'}));
238
+
239
+ expect(screen.getByTestId('status').textContent).toBe('closed');
240
+ expect(document.querySelector('dialog')).not.toHaveAttribute('open');
241
+ });
242
+
243
+ it('follows the index when the lightbox navigates', () => {
244
+ render(<Gallery />);
245
+ fireEvent.click(screen.getByTestId('thumb-2'));
246
+
247
+ fireEvent.click(screen.getByRole('button', {name: 'Next'}));
248
+
249
+ expect(screen.getByTestId('index').textContent).toBe('3');
250
+ expect(screen.getByAltText('Photo 4')).toBeInTheDocument();
251
+ });
252
+
253
+ it('reopens at a new index after closing', () => {
254
+ render(<Gallery />);
255
+ fireEvent.click(screen.getByTestId('thumb-0'));
256
+ fireEvent.click(screen.getByRole('button', {name: 'Close'}));
257
+
258
+ fireEvent.click(screen.getByTestId('thumb-3'));
259
+
260
+ expect(screen.getByTestId('index').textContent).toBe('3');
261
+ expect(screen.getByAltText('Photo 4')).toBeInTheDocument();
262
+ });
263
+ });
@@ -1,5 +1,62 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
+ /** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
4
+ const anatomy = [
5
+ {
6
+ name: 'Document',
7
+ required: true,
8
+ description:
9
+ 'Root container for block or inline Markdown content.',
10
+ },
11
+ {
12
+ name: 'Heading',
13
+ required: false,
14
+ description:
15
+ 'Rendered heading block; a custom heading renderer replaces the default part.',
16
+ },
17
+ {
18
+ name: 'Paragraph',
19
+ required: false,
20
+ description:
21
+ 'Rendered paragraph block; a custom paragraph renderer replaces the default part.',
22
+ },
23
+ {
24
+ name: 'List',
25
+ required: false,
26
+ description:
27
+ 'Ordered, unordered, or task-list block rendered from Markdown items.',
28
+ },
29
+ {
30
+ name: 'Code block',
31
+ required: false,
32
+ description:
33
+ 'Fenced code block; a custom code renderer replaces the default part.',
34
+ },
35
+ {
36
+ name: 'Blockquote',
37
+ required: false,
38
+ description:
39
+ 'Quoted block; a custom blockquote renderer replaces the default part.',
40
+ },
41
+ {
42
+ name: 'Table',
43
+ required: false,
44
+ description: 'Scrollable table block rendered from Markdown rows and columns.',
45
+ },
46
+ {
47
+ name: 'Divider',
48
+ required: false,
49
+ description:
50
+ 'Horizontal rule block; a custom hr renderer replaces the default part.',
51
+ },
52
+ {
53
+ name: 'Image',
54
+ required: false,
55
+ description:
56
+ 'Block image or unsafe-URL fallback; a custom image renderer replaces a safe default image.',
57
+ },
58
+ ];
59
+
3
60
  /** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
4
61
 
5
62
  export const docs = {
@@ -168,6 +225,7 @@ export const docs = {
168
225
  ],
169
226
  },
170
227
  usage: {
228
+ anatomy,
171
229
  description:
172
230
  '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.',
173
231
  bestPractices: [
@@ -381,6 +439,7 @@ export const docsZh = {
381
439
  ],
382
440
  },
383
441
  usage: {
442
+ anatomy,
384
443
  description:
385
444
  '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.',
386
445
  bestPractices: [
@@ -397,6 +456,7 @@ export const docsDense = {
397
456
  description:
398
457
  'Renders markdown string as Astryx-styled components. Use for user-generated content, AI responses, docs. Headings, lists, tables, code, citations w/ consistent styling.',
399
458
  usage: {
459
+ anatomy,
400
460
  description:
401
461
  '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.',
402
462
  bestPractices: [
@@ -0,0 +1,207 @@
1
+ ---
2
+ schema_version: 3
3
+ template_version: 3
4
+ kind: component
5
+ id: component:Markdown
6
+ authority: draft
7
+ archive_reason: null
8
+ superseded_by: null
9
+ approved_by: null
10
+ approved_at: null
11
+ owners: [cixzhang]
12
+ review_triggers: [theming]
13
+ verified_by:
14
+ [
15
+ packages/core/src/Markdown/Markdown.test.tsx,
16
+ packages/core/src/theme/themingTargets.test.ts,
17
+ scripts/check-knowledge.mjs,
18
+ ]
19
+ modules: []
20
+ families: [family:navigation-destinations]
21
+ design_specs: []
22
+ architecture: [architecture:component-theming-surface]
23
+ contributing: []
24
+ system_specs: [spec:AST-005/DEC-1, spec:AST-005/DEC-2]
25
+ ---
26
+
27
+ # Markdown component contract
28
+
29
+ ## Intent
30
+
31
+ Markdown renders parsed content in a Document with stable default block parts.
32
+ This draft records the nine current Markdown targets and the custom-renderer
33
+ boundary without changing parsing, runtime behavior, styling, targets, or public
34
+ API.
35
+
36
+ ## Compatibility and migration
37
+
38
+ - Released default preserved: `yes`
39
+ - Compatibility class: additive documentation only; runtime, DOM, styling,
40
+ targets, aliases, and public API remain unchanged
41
+ - Controlled/uncontrolled behavior: not applicable
42
+ - Migration decision: none
43
+
44
+ Consumer migration instructions belong in consumer docs and release notes.
45
+
46
+ ## Ownership boundary
47
+
48
+ **Owns**
49
+
50
+ - The Document and its current `markdown` target in block and inline display.
51
+ - Default Heading, Paragraph, List, Code block, Blockquote, Table, Divider, and
52
+ Image block presentation and the eight current block targets documented below.
53
+ - Applying block spacing and reflected density (plus Heading level) to those
54
+ targets on the default render path.
55
+
56
+ **Does not own / non-goals**
57
+
58
+ - Output supplied by custom `heading`, `paragraph`, `code`, `blockquote`, `hr`,
59
+ or `image` renderers; the custom component owns that replacement's structure
60
+ and styling.
61
+ - Inline emphasis, link, inline-code, citation, or plugin output as additional
62
+ block anatomy.
63
+ - Nested anatomy or targets owned by CodeBlock, Blockquote, List, CheckboxList,
64
+ or Table.
65
+ - New block types, custom-renderer behavior, target names, public API, or runtime
66
+ behavior.
67
+
68
+ ## Public concepts
69
+
70
+ No new public concept is introduced. Consumer props, renderer hooks, defaults,
71
+ and usage remain documented in `Markdown.doc.mjs`.
72
+
73
+ ## Behavioral and layout contract
74
+
75
+ | ID | Candidate invariant | Basis | Draft review state |
76
+ | --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------ |
77
+ | FR1 | Block and inline displays render one Document root carrying the current `markdown` target. Inline display renders no block anatomy. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
78
+ | FR2 | On the default block render path, Heading, Paragraph, List, Code block, Blockquote, Table, Divider, and Image carry the eight current local block targets documented below. | Current source, docs, tests, and history | Verified current inventory and placement |
79
+ | FR3 | A supplied `heading`, `paragraph`, `code`, `blockquote`, `hr`, or safe-URL `image` renderer replaces the corresponding default part, so Markdown does not impose that part's local target on the replacement. | Current source, docs, and history | Verified behavior; focused absence coverage is partial |
80
+ | FR4 | The released Code block target is spelled `markdown-codeblock`. Although this runs together a compound name and predates the current naming rule, it is a frozen public target and this factual backfill neither renames it nor adds an alias. | Current source, docs, tests, history, and architecture | Verified compatibility constraint; no target change |
81
+ | FR5 | Density and Heading level remain reflected capabilities on their owning targets. Display mode, density, Heading level, streaming state, list kind, and custom-renderer selection do not become separate anatomy entries. | Current source, docs, tests, and architecture | Verified current model; no new anatomy or state target |
82
+
83
+ ### Allowed variation
84
+
85
+ - **AV1 — Parsed content.** The number and ordering of block parts may vary with
86
+ the Markdown source without changing their ownership.
87
+ - **AV2 — Lists.** Ordered, unordered, and task lists share the List anatomy and
88
+ current `markdown-list` target.
89
+ - **AV3 — Custom renderers.** Supported custom block renderers may replace their
90
+ default part and own its styling without receiving a Markdown block target.
91
+ - **AV4 — Nested primitives.** Astryx primitives used inside default blocks may
92
+ change internal element shape while preserving their own public contracts and
93
+ Markdown's outer block targets.
94
+
95
+ ### Representative states
96
+
97
+ | State | Required invariant | Allowed variation |
98
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
99
+ | Default block content | Every parsed block uses its corresponding current Markdown target. | Block count, order, density, content width, and alignment. |
100
+ | Custom block renderers | The replaced Heading, Paragraph, Code block, Blockquote, Divider, or Image lacks the corresponding Markdown target. | Replacement structure and styling. |
101
+ | Ordered/unordered list | List carries `markdown-list`. | Marker kind, start value, item count, and nested content. |
102
+ | Task list | The outer List part carries `markdown-list`. | Checked values and item content. |
103
+ | Safe block image | Default Image carries `markdown-image`, or a custom image renderer replaces it. | Source and alternative text. |
104
+ | Unsafe block image URL | Markdown renders its fallback Image part with `markdown-image`; no custom image renderer receives the rejected URL. | Alternative text shown by the fallback. |
105
+ | Inline display | Document carries `markdown`; no block target renders. | Inline text, links, code, citations, and plugin output. |
106
+
107
+ ### Transformation and precedence order
108
+
109
+ - No new parsing, sanitization, heading-level, renderer-selection, spacing, or
110
+ styling precedence rule is introduced.
111
+
112
+ ### Performance and resources
113
+
114
+ - No new parsing, streaming, render, or resource requirement is introduced.
115
+
116
+ ## Accessibility contract
117
+
118
+ This draft does not change or extend Markdown's existing document semantics,
119
+ heading IDs, paragraph role, list semantics, scrollable Table wrapper, image
120
+ alternative text, or custom-renderer responsibilities.
121
+
122
+ ## Design relationships
123
+
124
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
125
+ | ---------------- | -------------------------------------------------------------------------------- | ------------------------------ | -------------- | ------------------ |
126
+ | Document | Contains block or inline rendered Markdown content. | Current source and public docs | Supporting | FR1, FR5 |
127
+ | Heading | Presents one parsed heading with its resolved level and optional generated ID. | Current source and public docs | Prominent | FR2, FR3, FR5 |
128
+ | Paragraph | Presents one prose block using the default composition-safe paragraph structure. | Current source and public docs | Prominent | FR2, FR3 |
129
+ | List | Presents ordered, unordered, or task-list items as one block. | Current source and public docs | Prominent | FR2, FR5 |
130
+ | Code block | Presents fenced code and owns the outer spacing target on the default path. | Current source and public docs | Prominent | FR2, FR3, FR4 |
131
+ | Blockquote | Presents quoted block content on the default path. | Current source and public docs | Prominent | FR2, FR3 |
132
+ | Table | Presents parsed rows and columns in a keyboard-scrollable block wrapper. | Current source and public docs | Prominent | FR2 |
133
+ | Divider | Presents a horizontal separation between blocks. | Current source and public docs | Supporting | FR2, FR3 |
134
+ | Image | Presents a safe block image or the fallback for a rejected image URL. | Current source and public docs | Prominent | FR2, FR3 |
135
+
136
+ Custom renderers replace six default parts rather than becoming nested Markdown
137
+ anatomy. Lists and Tables have no corresponding custom block renderer. The
138
+ Document remains Markdown-owned in every display mode.
139
+
140
+ ### Theming anatomy
141
+
142
+ <!-- anatomy-theming:v1 -->
143
+
144
+ ```json
145
+ {
146
+ "Document": {"target": "markdown"},
147
+ "Heading": {"target": "markdown-heading"},
148
+ "Paragraph": {"target": "markdown-paragraph"},
149
+ "List": {"target": "markdown-list"},
150
+ "Code block": {"target": "markdown-codeblock"},
151
+ "Blockquote": {"target": "markdown-blockquote"},
152
+ "Table": {"target": "markdown-table"},
153
+ "Divider": {"target": "markdown-hr"},
154
+ "Image": {"target": "markdown-image"}
155
+ }
156
+ ```
157
+
158
+ The map records all nine current targets on Markdown's default render paths. For
159
+ Heading, Paragraph, Code block, Blockquote, Divider, and safe Image, a custom
160
+ renderer replaces the default part and therefore replaces its local target. The
161
+ `markdown-codeblock` spelling is a released compatibility anomaly: the current
162
+ naming rule would produce `markdown-code-block`, but shipped targets are frozen
163
+ and this change preserves the existing spelling exactly.
164
+
165
+ ## Family and system relationships
166
+
167
+ - `architecture:component-theming-surface` owns anatomy qualification, target
168
+ mapping, target-capability state, composition boundaries, and compatibility for
169
+ frozen targets.
170
+ - `family:navigation-destinations` owns the shared accept/block result for parsed
171
+ links and every Astryx-owned navigation sink. `spec:AST-005/DEC-1` requires
172
+ Markdown navigation to remain conformant with Core link plumbing.
173
+ - `spec:AST-005/DEC-2` keeps embedded-resource policy separate. Markdown may
174
+ reject a broader set of image/resource URLs without narrowing the shared
175
+ navigation contract.
176
+ - Nested Astryx primitives retain ownership of their own anatomy and targets;
177
+ Markdown owns the outer block targets listed here.
178
+
179
+ ## Verification map
180
+
181
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
182
+ | ------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------ |
183
+ | FR1 | `Markdown.test.tsx` root-class, block-root, inline-root, and base-prop suites | Block and inline Document | Removing or moving the root target fails focused root assertions or the global inventory. | `audit:Markdown/anatomy` |
184
+ | FR2, FR4, FR5 | `Markdown.test.tsx` block-spacing-target, density, Heading-level, task-list, and render suites | All eight default block types, both densities, Heading level | Removing, renaming, or moving a block target fails focused class or reflected-property assertions. | `audit:Markdown/theming` |
185
+ | FR3 | `Markdown.test.tsx` custom Heading and custom Image suites plus source and target-introduction history | Six replaceable default block parts | Imposing a target on a custom replacement violates the owner boundary; only Heading absence is directly pinned today. | `audit:Markdown/theming` |
186
+ | Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and all nine current targets | Missing, extra, prefixed, stale, or multiply assigned mappings fail repository validation. | `audit:Markdown/theming` |
187
+
188
+ Focused tests pin all nine current target names and default block placement. They
189
+ pin target absence only for a custom Heading; custom Paragraph, Code block,
190
+ Blockquote, Divider, and Image replacement paths currently rely on source and
191
+ history for the same ownership rule.
192
+
193
+ ## Decision log
194
+
195
+ None. This draft records current facts and introduces no component-local design,
196
+ API, behavior, or theming decision.
197
+
198
+ ## Open questions
199
+
200
+ - **OQ1 — Which focused tests should pin target absence for the five remaining
201
+ custom block replacement paths?** (`checkable`)
202
+
203
+ ## Content boundary
204
+
205
+ This file does not duplicate consumer prop tables/examples, parser mechanics,
206
+ streaming implementation, nested primitive contracts, current audit results, or
207
+ system theming rules. It links to their owners.