@astryxdesign/core 0.5.1 → 0.5.2-canary.00477a5

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 (270) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/BottomSheet/BottomSheet.d.ts +3 -1
  3. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  4. package/dist/BottomSheet/BottomSheet.js +4 -3
  5. package/dist/BottomSheet/BottomSheetEdgeTint.d.ts +2 -2
  6. package/dist/BottomSheet/BottomSheetEdgeTint.d.ts.map +1 -1
  7. package/dist/BottomSheet/BottomSheetEdgeTint.js +7 -10
  8. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  9. package/dist/BottomSheet/BottomSheetSwitcher.js +1 -1
  10. package/dist/Button/Button.d.ts +2 -1
  11. package/dist/Button/Button.d.ts.map +1 -1
  12. package/dist/Button/Button.js +11 -4
  13. package/dist/Carousel/Carousel.d.ts.map +1 -1
  14. package/dist/Carousel/Carousel.js +2 -2
  15. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  16. package/dist/Chat/ChatToolCalls.js +34 -17
  17. package/dist/ContextMenu/ContextMenu.d.ts +14 -3
  18. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  19. package/dist/ContextMenu/ContextMenu.js +149 -26
  20. package/dist/ContextMenu/index.d.ts +1 -0
  21. package/dist/ContextMenu/index.d.ts.map +1 -1
  22. package/dist/DropdownMenu/DropdownMenu.d.ts +24 -5
  23. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  24. package/dist/DropdownMenu/DropdownMenu.js +340 -26
  25. package/dist/DropdownMenu/DropdownMenuContext.d.ts +1 -1
  26. package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
  27. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  28. package/dist/DropdownMenu/DropdownMenuItem.js +1 -1
  29. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +6 -2
  30. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  31. package/dist/DropdownMenu/DropdownMenuSubMenu.js +43 -14
  32. package/dist/DropdownMenu/MenuBottomSheet.d.ts +20 -0
  33. package/dist/DropdownMenu/MenuBottomSheet.d.ts.map +1 -0
  34. package/dist/DropdownMenu/MenuBottomSheet.js +36 -0
  35. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts +10 -0
  36. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -0
  37. package/dist/DropdownMenu/MenuBottomSheetActionList.js +111 -0
  38. package/dist/DropdownMenu/index.d.ts +2 -1
  39. package/dist/DropdownMenu/index.d.ts.map +1 -1
  40. package/dist/DropdownMenu/menuWidth.d.ts +14 -0
  41. package/dist/DropdownMenu/menuWidth.d.ts.map +1 -0
  42. package/dist/DropdownMenu/menuWidth.js +35 -0
  43. package/dist/DropdownMenu/useMenuOverflow.d.ts +10 -0
  44. package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -0
  45. package/dist/DropdownMenu/useMenuOverflow.js +60 -0
  46. package/dist/MoreMenu/MoreMenu.d.ts +8 -2
  47. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  48. package/dist/MoreMenu/MoreMenu.js +2 -0
  49. package/dist/MultiSelector/MultiSelector.d.ts +11 -1
  50. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  51. package/dist/MultiSelector/MultiSelector.js +97 -68
  52. package/dist/MultiSelector/index.d.ts +1 -1
  53. package/dist/MultiSelector/index.d.ts.map +1 -1
  54. package/dist/Popover/Popover.d.ts +10 -6
  55. package/dist/Popover/Popover.d.ts.map +1 -1
  56. package/dist/Popover/Popover.js +141 -16
  57. package/dist/Popover/usePopover.d.ts +4 -0
  58. package/dist/Popover/usePopover.d.ts.map +1 -1
  59. package/dist/Popover/usePopover.js +52 -5
  60. package/dist/Selector/Selector.d.ts +10 -0
  61. package/dist/Selector/Selector.d.ts.map +1 -1
  62. package/dist/Selector/Selector.js +106 -80
  63. package/dist/Selector/SelectorBottomSheet.d.ts +21 -0
  64. package/dist/Selector/SelectorBottomSheet.d.ts.map +1 -0
  65. package/dist/Selector/SelectorBottomSheet.js +83 -0
  66. package/dist/Selector/index.d.ts +1 -1
  67. package/dist/Selector/index.d.ts.map +1 -1
  68. package/dist/Selector/selectorPresentation.stylex.d.ts +16 -0
  69. package/dist/Selector/selectorPresentation.stylex.d.ts.map +1 -0
  70. package/dist/Selector/selectorPresentation.stylex.js +21 -0
  71. package/dist/Selector/useSelectorPresentation.d.ts +32 -0
  72. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -0
  73. package/dist/Selector/useSelectorPresentation.js +90 -0
  74. package/dist/Toast/useToastGesture.d.ts.map +1 -1
  75. package/dist/Toast/useToastGesture.js +46 -9
  76. package/dist/astryx.css +19 -1
  77. package/dist/hooks/useAdaptivePresentation.d.ts +5 -0
  78. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -0
  79. package/dist/hooks/useAdaptivePresentation.js +19 -0
  80. package/dist/hooks/useFocusReturnVisibility.d.ts +7 -0
  81. package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -0
  82. package/dist/hooks/useFocusReturnVisibility.js +35 -0
  83. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  84. package/dist/hooks/useFocusTrap.js +12 -0
  85. package/dist/i18n/InternationalizationContext.d.ts +2 -0
  86. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  87. package/dist/i18n/InternationalizationContext.js +3 -1
  88. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  89. package/dist/i18n/InternationalizationProvider.js +3 -1
  90. package/dist/i18n/resolve.d.ts +1 -1
  91. package/dist/i18n/resolve.d.ts.map +1 -1
  92. package/dist/i18n/resolve.js +37 -38
  93. package/dist/i18n/useTranslator.d.ts.map +1 -1
  94. package/dist/i18n/useTranslator.js +2 -3
  95. package/locales/af-ZA.json +0 -4
  96. package/locales/ar-SA.json +0 -4
  97. package/locales/ca-ES.json +0 -4
  98. package/locales/cs-CZ.json +0 -4
  99. package/locales/da-DK.json +0 -4
  100. package/locales/de-DE.json +0 -4
  101. package/locales/el-GR.json +0 -4
  102. package/locales/en.json +20 -0
  103. package/locales/es-ES.json +0 -4
  104. package/locales/fi-FI.json +0 -4
  105. package/locales/fr-FR.json +0 -4
  106. package/locales/he-IL.json +0 -4
  107. package/locales/hu-HU.json +0 -4
  108. package/locales/it-IT.json +0 -4
  109. package/locales/ja-JP.json +0 -4
  110. package/locales/ko-KR.json +0 -4
  111. package/locales/nl-NL.json +0 -4
  112. package/locales/no-NO.json +0 -4
  113. package/locales/pl-PL.json +0 -4
  114. package/locales/pseudo.json +15 -0
  115. package/locales/pt-BR.json +0 -4
  116. package/locales/pt-PT.json +0 -4
  117. package/locales/ro-RO.json +0 -4
  118. package/locales/ru-RU.json +0 -4
  119. package/locales/sr-SP.json +0 -4
  120. package/locales/sv-SE.json +0 -4
  121. package/locales/tr-TR.json +0 -4
  122. package/locales/uk-UA.json +0 -4
  123. package/locales/vi-VN.json +0 -4
  124. package/locales/zh-CN.json +0 -4
  125. package/locales/zh-TW.json +0 -4
  126. package/package.json +3 -3
  127. package/src/BottomSheet/BottomSheet.doc.mjs +37 -0
  128. package/src/BottomSheet/BottomSheet.spec.md +177 -0
  129. package/src/BottomSheet/BottomSheet.test.tsx +29 -0
  130. package/src/BottomSheet/BottomSheet.tsx +7 -4
  131. package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +4 -6
  132. package/src/BottomSheet/BottomSheetEdgeTint.tsx +7 -10
  133. package/src/BottomSheet/BottomSheetSwitcher.tsx +1 -2
  134. package/src/Button/Button.doc.mjs +56 -0
  135. package/src/Button/Button.test.tsx +10 -0
  136. package/src/Button/Button.tsx +13 -5
  137. package/src/ButtonGroup/ButtonGroup.doc.mjs +47 -0
  138. package/src/Calendar/Calendar.doc.mjs +1 -1
  139. package/src/Carousel/Carousel.test.tsx +83 -0
  140. package/src/Carousel/Carousel.tsx +8 -2
  141. package/src/Chat/ChatToolCalls.test.tsx +44 -0
  142. package/src/Chat/ChatToolCalls.tsx +36 -15
  143. package/src/CheckboxInput/CheckboxInput.doc.mjs +1 -1
  144. package/src/CheckboxList/CheckboxList.doc.mjs +173 -32
  145. package/src/CheckboxList/CheckboxList.spec.md +214 -0
  146. package/src/CommandPalette/CommandPalette.doc.mjs +72 -0
  147. package/src/CommandPalette/CommandPalette.spec.md +223 -0
  148. package/src/ComplexSelector/ComplexSelector.doc.mjs +44 -2
  149. package/src/ComplexSelector/ComplexSelector.spec.md +189 -0
  150. package/src/ContextMenu/ContextMenu.doc.mjs +13 -1
  151. package/src/ContextMenu/ContextMenu.test.tsx +131 -1
  152. package/src/ContextMenu/ContextMenu.tsx +199 -32
  153. package/src/ContextMenu/index.ts +1 -0
  154. package/src/DateInput/DateInput.doc.mjs +1 -1
  155. package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
  156. package/src/DateTimeInput/DateTimeInput.doc.mjs +1 -1
  157. package/src/Divider/Divider.doc.mjs +24 -0
  158. package/src/Divider/Divider.spec.md +150 -0
  159. package/src/DropdownMenu/DropdownMenu.doc.mjs +201 -40
  160. package/src/DropdownMenu/DropdownMenu.test.tsx +518 -7
  161. package/src/DropdownMenu/DropdownMenu.tsx +459 -28
  162. package/src/DropdownMenu/DropdownMenuContext.tsx +1 -1
  163. package/src/DropdownMenu/DropdownMenuItem.tsx +2 -0
  164. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +4 -2
  165. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +124 -0
  166. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +72 -17
  167. package/src/DropdownMenu/MenuBottomSheet.tsx +46 -0
  168. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +141 -0
  169. package/src/DropdownMenu/index.ts +2 -0
  170. package/src/DropdownMenu/menuWidth.ts +51 -0
  171. package/src/DropdownMenu/useMenuOverflow.ts +77 -0
  172. package/src/Field/Field.doc.mjs +1 -1
  173. package/src/FieldStatus/FieldStatus.doc.mjs +22 -1
  174. package/src/FieldStatus/FieldStatus.spec.md +212 -0
  175. package/src/FileInput/FileInput.doc.mjs +1 -1
  176. package/src/Grid/Grid.doc.mjs +19 -0
  177. package/src/Grid/Grid.spec.md +161 -0
  178. package/src/Icon/Icon.doc.mjs +196 -48
  179. package/src/Icon/Icon.spec.md +191 -0
  180. package/src/IconButton/IconButton.doc.mjs +38 -0
  181. package/src/Indicator/Indicator.doc.mjs +1 -1
  182. package/src/InputGroup/InputGroup.doc.mjs +1 -1
  183. package/src/Kbd/Kbd.doc.mjs +18 -0
  184. package/src/Kbd/Kbd.spec.md +141 -0
  185. package/src/Layout/Layout.doc.mjs +32 -0
  186. package/src/Layout/Layout.spec.md +199 -0
  187. package/src/Lightbox/Lightbox.doc.mjs +149 -33
  188. package/src/Lightbox/Lightbox.spec.md +197 -0
  189. package/src/Markdown/Markdown.doc.mjs +60 -0
  190. package/src/Markdown/Markdown.spec.md +200 -0
  191. package/src/MobileNav/MobileNav.doc.mjs +140 -32
  192. package/src/MobileNav/MobileNav.spec.md +208 -0
  193. package/src/MoreMenu/MoreMenu.doc.mjs +17 -0
  194. package/src/MoreMenu/MoreMenu.test.tsx +47 -0
  195. package/src/MoreMenu/MoreMenu.tsx +13 -1
  196. package/src/MultiSelector/MultiSelector.doc.mjs +129 -1
  197. package/src/MultiSelector/MultiSelector.spec.md +266 -0
  198. package/src/MultiSelector/MultiSelector.test.tsx +127 -0
  199. package/src/MultiSelector/MultiSelector.tsx +121 -73
  200. package/src/MultiSelector/index.ts +1 -0
  201. package/src/NavIcon/NavIcon.doc.mjs +17 -0
  202. package/src/NavIcon/NavIcon.spec.md +133 -0
  203. package/src/NavMenu/NavHeadingMenu.spec.md +205 -0
  204. package/src/NavMenu/NavMenu.doc.mjs +37 -0
  205. package/src/NumberInput/NumberInput.doc.mjs +1 -1
  206. package/src/Outline/Outline.doc.mjs +35 -0
  207. package/src/Outline/Outline.spec.md +161 -0
  208. package/src/OverflowList/OverflowList.doc.mjs +24 -0
  209. package/src/OverflowList/OverflowList.spec.md +156 -0
  210. package/src/Pagination/Pagination.doc.mjs +74 -0
  211. package/src/Pagination/Pagination.spec.md +225 -0
  212. package/src/Popover/Popover.doc.mjs +11 -11
  213. package/src/Popover/Popover.test.tsx +397 -2
  214. package/src/Popover/Popover.tsx +228 -21
  215. package/src/Popover/usePopover.tsx +92 -15
  216. package/src/PowerSearch/PowerSearch.doc.mjs +1 -1
  217. package/src/ProgressBar/ProgressBar.doc.mjs +198 -38
  218. package/src/ProgressBar/ProgressBar.spec.md +260 -0
  219. package/src/RadioList/RadioList.doc.mjs +1 -1
  220. package/src/Resizable/Resizable.doc.mjs +59 -16
  221. package/src/Resizable/Resizable.spec.md +194 -0
  222. package/src/Section/Section.doc.mjs +17 -0
  223. package/src/Section/Section.spec.md +138 -0
  224. package/src/SegmentedControl/SegmentedControl.doc.mjs +83 -0
  225. package/src/SegmentedControl/SegmentedControl.spec.md +151 -0
  226. package/src/Selector/Selector.doc.mjs +13 -1
  227. package/src/Selector/Selector.test.tsx +135 -0
  228. package/src/Selector/Selector.tsx +141 -82
  229. package/src/Selector/SelectorBottomSheet.tsx +97 -0
  230. package/src/Selector/index.ts +1 -0
  231. package/src/Selector/selectorPresentation.stylex.ts +20 -0
  232. package/src/Selector/useSelectorPresentation.ts +147 -0
  233. package/src/Skeleton/Skeleton.doc.mjs +12 -0
  234. package/src/Skeleton/Skeleton.spec.md +126 -0
  235. package/src/Slider/Slider.doc.mjs +186 -32
  236. package/src/Slider/Slider.spec.md +223 -0
  237. package/src/Stack/Stack.doc.mjs +22 -0
  238. package/src/Stack/Stack.spec.md +154 -0
  239. package/src/StatusDot/StatusDot.doc.mjs +17 -0
  240. package/src/StatusDot/StatusDot.spec.md +137 -0
  241. package/src/Switch/Switch.doc.mjs +41 -1
  242. package/src/Switch/Switch.spec.md +174 -0
  243. package/src/Text/Text.doc.mjs +190 -43
  244. package/src/Text/Text.spec.md +205 -0
  245. package/src/TextArea/TextArea.doc.mjs +256 -46
  246. package/src/TextArea/TextArea.spec.md +204 -0
  247. package/src/TextInput/TextInput.doc.mjs +1 -1
  248. package/src/TimeInput/TimeInput.doc.mjs +1 -1
  249. package/src/Toast/ToastViewport.test.tsx +118 -4
  250. package/src/Toast/useToastGesture.ts +61 -8
  251. package/src/ToggleButton/ToggleButton.doc.mjs +56 -0
  252. package/src/Tokenizer/Tokenizer.doc.mjs +1 -1
  253. package/src/Toolbar/Toolbar.doc.mjs +19 -0
  254. package/src/Toolbar/Toolbar.spec.md +173 -0
  255. package/src/Tooltip/Tooltip.doc.mjs +17 -0
  256. package/src/Tooltip/Tooltip.spec.md +141 -0
  257. package/src/TreeList/TreeList.doc.mjs +58 -0
  258. package/src/TreeList/TreeList.spec.md +220 -0
  259. package/src/Typeahead/Typeahead.doc.mjs +84 -2
  260. package/src/Typeahead/Typeahead.spec.md +250 -0
  261. package/src/hooks/useAdaptivePresentation.ts +35 -0
  262. package/src/hooks/useFocusReturnVisibility.ts +45 -0
  263. package/src/hooks/useFocusTrap.test.tsx +40 -0
  264. package/src/hooks/useFocusTrap.ts +13 -0
  265. package/src/i18n/InternationalizationContext.ts +3 -0
  266. package/src/i18n/InternationalizationProvider.tsx +8 -1
  267. package/src/i18n/__tests__/resolve.test.ts +23 -1
  268. package/src/i18n/resolve.ts +46 -49
  269. package/src/i18n/useTranslator.ts +2 -7
  270. package/src/theme/themingTargets.test.ts +91 -25
@@ -0,0 +1,197 @@
1
+ ---
2
+ schema_version: 1
3
+ template_version: 3
4
+ kind: component
5
+ id: component:Lightbox
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: [behavior, theming, accessibility]
13
+ verified_by:
14
+ [
15
+ packages/core/src/Lightbox/Lightbox.test.tsx,
16
+ packages/core/src/theme/themingTargets.test.ts,
17
+ scripts/check-knowledge.mjs,
18
+ ]
19
+ families: [family:overlay-dismissal]
20
+ design_specs: []
21
+ architecture:
22
+ [
23
+ architecture:component-theming-surface,
24
+ architecture:interaction-modality,
25
+ architecture:layer-runtime,
26
+ architecture:public-component-api,
27
+ ]
28
+ contributing: []
29
+ system_specs: []
30
+ ---
31
+
32
+ # Lightbox component contract
33
+
34
+ ## Intent
35
+
36
+ Lightbox presents one active image or video in a full-viewport viewer and may
37
+ add gallery navigation, a caption, and a position counter. This draft records
38
+ current consumer anatomy and theming ownership without changing runtime
39
+ behavior, styling, targets, or public API.
40
+
41
+ ## Compatibility and migration
42
+
43
+ - Released default preserved: `yes`
44
+ - Compatibility class: additive documentation only; runtime, DOM, styling,
45
+ targets, aliases, and public API remain unchanged
46
+ - Controlled/uncontrolled behavior: unchanged
47
+ - Migration decision: none
48
+
49
+ Consumer migration instructions belong in consumer docs and release notes.
50
+
51
+ ## Ownership boundary
52
+
53
+ **Owns**
54
+
55
+ - The Viewer overlay and its current `lightbox` target.
56
+ - Media presentation, optional Caption and Counter placement, gallery navigation,
57
+ and current image zoom and pan behavior.
58
+
59
+ **Does not own / non-goals**
60
+
61
+ - The Close, Previous, and Next button surfaces — delegated to
62
+ `component:Button` through IconButton.
63
+ - Caller-provided Caption content.
64
+ - New targets for Media, Caption, or Counter; none exist on current `main`.
65
+ - Shared layer hosting or dismissal policy.
66
+
67
+ ## Public concepts
68
+
69
+ No new public concept is introduced. Consumer props and usage remain documented
70
+ in `Lightbox.doc.mjs`.
71
+
72
+ ## Behavioral and layout contract
73
+
74
+ | ID | Candidate invariant | Basis | Draft review state |
75
+ | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -------------------------------------------------- |
76
+ | FR1 | The current viewer contains one active Media item and a Close button; galleries additionally contain Previous and Next buttons plus a Counter, and Caption renders only when supplied. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
77
+ | FR2 | Viewer overlay carries the current `lightbox` target. Media, Caption, and Counter carry no Lightbox public target. | Current source and public docs | Verified current reachability; no target change |
78
+ | FR3 | Close, Previous, and Next button surfaces use Button's `button` target through IconButton rather than Lightbox-owned button targets. | Current source and target docs | Verified current delegation; no ownership change |
79
+
80
+ ### Allowed variation
81
+
82
+ - **AV1 — Media mode.** Media may be an image or video; zoom and pan are available
83
+ only on the current image path.
84
+ - **AV2 — Gallery mode.** Previous, Next, and Counter are absent for a single
85
+ item. Navigation button disabled state follows the current gallery boundary.
86
+ - **AV3 — Caption content.** Caller-provided Caption content may vary without
87
+ becoming a Lightbox-owned target.
88
+
89
+ ### Representative states
90
+
91
+ | State | Required invariant | Allowed variation |
92
+ | ---------------- | ------------------------------------------------------------------- | --------------------------------------------- |
93
+ | Single image | Viewer overlay, Media, and Close button render. | Caption and zoom may be absent or present. |
94
+ | Gallery boundary | Both navigation buttons and Counter remain rendered. | Previous or Next is disabled at its boundary. |
95
+ | Video | Media renders native video controls without image zoom interaction. | Autoplay follows the existing consumer prop. |
96
+ | Captioned media | Caption follows the active Media inside the centered media group. | Caption content remains caller-provided. |
97
+
98
+ ### Transformation and precedence order
99
+
100
+ - No new index, zoom, pan, media, or styling precedence rule is introduced.
101
+
102
+ ### Performance and resources
103
+
104
+ - No new performance or resource rule is introduced.
105
+
106
+ ## Accessibility contract
107
+
108
+ This draft does not change or extend Lightbox's existing dialog naming, focus,
109
+ media alternatives, announcements, button labels, keyboard behavior, or
110
+ dismissal behavior.
111
+
112
+ ## Design relationships
113
+
114
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
115
+ | ---------------- | -------------------------------------------------------------------- | ------------------------------ | ----------------- | ------------------ |
116
+ | Viewer overlay | Presents the full-viewport dialog and surrounding overlay treatment. | Current source and public docs | Supporting | FR1, FR2 |
117
+ | Media | Presents the active image or video. | Current source and public docs | Prominent | FR1, FR2 |
118
+ | Close button | Provides the persistent viewer dismissal action. | `component:Button` | Supporting | FR1, FR3 |
119
+ | Previous button | Moves gallery presentation to the preceding item. | `component:Button` | Supporting | FR1, FR3 |
120
+ | Next button | Moves gallery presentation to the following item. | `component:Button` | Supporting | FR1, FR3 |
121
+ | Caption | Presents caller-provided context below the active Media. | Current source and public docs | Context-dependent | FR1, FR2 |
122
+ | Counter | Presents current gallery position and total. | Current source and tests | Supporting | FR1, FR2 |
123
+
124
+ Media, Caption, and Counter are stable visible parts, but no current public
125
+ target reaches them. Their `none` dispositions record factual reachability, not
126
+ a decision that they must remain unthemeable.
127
+
128
+ ### Theming anatomy
129
+
130
+ <!-- anatomy-theming:v1 -->
131
+
132
+ ```json
133
+ {
134
+ "Viewer overlay": {"target": "lightbox"},
135
+ "Media": {
136
+ "none": {
137
+ "reason": "reachability-gap: No current public target is applied to the active image or video"
138
+ }
139
+ },
140
+ "Close button": {
141
+ "delegatesTo": {"owner": "component:Button", "target": "button"}
142
+ },
143
+ "Previous button": {
144
+ "delegatesTo": {"owner": "component:Button", "target": "button"}
145
+ },
146
+ "Next button": {
147
+ "delegatesTo": {"owner": "component:Button", "target": "button"}
148
+ },
149
+ "Caption": {
150
+ "none": {
151
+ "reason": "reachability-gap: No current public target is applied to the caption container"
152
+ }
153
+ },
154
+ "Counter": {
155
+ "none": {
156
+ "reason": "reachability-gap: No current public target is applied to the gallery counter"
157
+ }
158
+ }
159
+ }
160
+ ```
161
+
162
+ ## Family and system relationships
163
+
164
+ - `architecture:component-theming-surface` owns anatomy qualification, target
165
+ mapping, delegation, and factual `none` dispositions.
166
+ - `architecture:layer-runtime` owns the current native-dialog host and shared
167
+ layer plumbing; Lightbox retains its current media and local backdrop behavior.
168
+ - `family:overlay-dismissal` owns shared Escape and platform-close ordering and
169
+ records Lightbox as a current adopter.
170
+ - `architecture:interaction-modality` and `architecture:public-component-api`
171
+ own their shared modality and API boundaries; this draft changes neither.
172
+
173
+ ## Verification map
174
+
175
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
176
+ | ------------------- | -------------------------------------------------------------------- | ------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------ |
177
+ | FR1 | `Lightbox.test.tsx` render, gallery, caption, media, and zoom suites | Single image, gallery edges, caption, video | Removing a documented part fails existing role, content, media, or navigation assertions. | `audit:Lightbox/anatomy` |
178
+ | FR2 | Source inspection and `themingTargets.test.ts` | Viewer overlay, Media, Caption, and Counter | Removing the root target or documenting an unshipped child target fails evidence or inventory. | `audit:Lightbox/theming` |
179
+ | FR3 | Source inspection plus Button and IconButton public composition | Close and gallery navigation controls | Re-owning a control surface requires the delegated owner and this map to change. | `audit:Lightbox/theming` |
180
+ | Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and current target | Missing, extra, prefixed, stale, or multiply assigned mappings fail repository validation. | `audit:Lightbox/theming` |
181
+
182
+ ## Decision log
183
+
184
+ None. This draft records current facts and introduces no component-local design,
185
+ API, theming, or layer-system decision.
186
+
187
+ ## Open questions
188
+
189
+ - **OQ1 — Should Media, Caption, or Counter gain a stable public theming target?**
190
+ (`human-api`) Their current lack of reachability is an audit gap, not settled
191
+ intent.
192
+
193
+ ## Content boundary
194
+
195
+ This file does not duplicate consumer prop tables/examples, media algorithms,
196
+ shared layer rules, current audit results, or implementation steps. It links to
197
+ their owners.
@@ -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,200 @@
1
+ ---
2
+ schema_version: 1
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
+ families: []
20
+ design_specs: []
21
+ architecture: [architecture:component-theming-surface]
22
+ contributing: []
23
+ system_specs: []
24
+ ---
25
+
26
+ # Markdown component contract
27
+
28
+ ## Intent
29
+
30
+ Markdown renders parsed content in a Document with stable default block parts.
31
+ This draft records the nine current Markdown targets and the custom-renderer
32
+ boundary without changing parsing, runtime behavior, styling, targets, or public
33
+ API.
34
+
35
+ ## Compatibility and migration
36
+
37
+ - Released default preserved: `yes`
38
+ - Compatibility class: additive documentation only; runtime, DOM, styling,
39
+ targets, aliases, and public API remain unchanged
40
+ - Controlled/uncontrolled behavior: not applicable
41
+ - Migration decision: none
42
+
43
+ Consumer migration instructions belong in consumer docs and release notes.
44
+
45
+ ## Ownership boundary
46
+
47
+ **Owns**
48
+
49
+ - The Document and its current `markdown` target in block and inline display.
50
+ - Default Heading, Paragraph, List, Code block, Blockquote, Table, Divider, and
51
+ Image block presentation and the eight current block targets documented below.
52
+ - Applying block spacing and reflected density (plus Heading level) to those
53
+ targets on the default render path.
54
+
55
+ **Does not own / non-goals**
56
+
57
+ - Output supplied by custom `heading`, `paragraph`, `code`, `blockquote`, `hr`,
58
+ or `image` renderers; the custom component owns that replacement's structure
59
+ and styling.
60
+ - Inline emphasis, link, inline-code, citation, or plugin output as additional
61
+ block anatomy.
62
+ - Nested anatomy or targets owned by CodeBlock, Blockquote, List, CheckboxList,
63
+ or Table.
64
+ - New block types, custom-renderer behavior, target names, public API, or runtime
65
+ behavior.
66
+
67
+ ## Public concepts
68
+
69
+ No new public concept is introduced. Consumer props, renderer hooks, defaults,
70
+ and usage remain documented in `Markdown.doc.mjs`.
71
+
72
+ ## Behavioral and layout contract
73
+
74
+ | ID | Candidate invariant | Basis | Draft review state |
75
+ | --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------ |
76
+ | 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 |
77
+ | 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 |
78
+ | 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 |
79
+ | 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 |
80
+ | 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 |
81
+
82
+ ### Allowed variation
83
+
84
+ - **AV1 — Parsed content.** The number and ordering of block parts may vary with
85
+ the Markdown source without changing their ownership.
86
+ - **AV2 — Lists.** Ordered, unordered, and task lists share the List anatomy and
87
+ current `markdown-list` target.
88
+ - **AV3 — Custom renderers.** Supported custom block renderers may replace their
89
+ default part and own its styling without receiving a Markdown block target.
90
+ - **AV4 — Nested primitives.** Astryx primitives used inside default blocks may
91
+ change internal element shape while preserving their own public contracts and
92
+ Markdown's outer block targets.
93
+
94
+ ### Representative states
95
+
96
+ | State | Required invariant | Allowed variation |
97
+ | ---------------------- | ------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- |
98
+ | Default block content | Every parsed block uses its corresponding current Markdown target. | Block count, order, density, content width, and alignment. |
99
+ | Custom block renderers | The replaced Heading, Paragraph, Code block, Blockquote, Divider, or Image lacks the corresponding Markdown target. | Replacement structure and styling. |
100
+ | Ordered/unordered list | List carries `markdown-list`. | Marker kind, start value, item count, and nested content. |
101
+ | Task list | The outer List part carries `markdown-list`. | Checked values and item content. |
102
+ | Safe block image | Default Image carries `markdown-image`, or a custom image renderer replaces it. | Source and alternative text. |
103
+ | 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. |
104
+ | Inline display | Document carries `markdown`; no block target renders. | Inline text, links, code, citations, and plugin output. |
105
+
106
+ ### Transformation and precedence order
107
+
108
+ - No new parsing, sanitization, heading-level, renderer-selection, spacing, or
109
+ styling precedence rule is introduced.
110
+
111
+ ### Performance and resources
112
+
113
+ - No new parsing, streaming, render, or resource requirement is introduced.
114
+
115
+ ## Accessibility contract
116
+
117
+ This draft does not change or extend Markdown's existing document semantics,
118
+ heading IDs, paragraph role, list semantics, scrollable Table wrapper, image
119
+ alternative text, or custom-renderer responsibilities.
120
+
121
+ ## Design relationships
122
+
123
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
124
+ | ---------------- | -------------------------------------------------------------------------------- | ------------------------------ | -------------- | ------------------ |
125
+ | Document | Contains block or inline rendered Markdown content. | Current source and public docs | Supporting | FR1, FR5 |
126
+ | Heading | Presents one parsed heading with its resolved level and optional generated ID. | Current source and public docs | Prominent | FR2, FR3, FR5 |
127
+ | Paragraph | Presents one prose block using the default composition-safe paragraph structure. | Current source and public docs | Prominent | FR2, FR3 |
128
+ | List | Presents ordered, unordered, or task-list items as one block. | Current source and public docs | Prominent | FR2, FR5 |
129
+ | Code block | Presents fenced code and owns the outer spacing target on the default path. | Current source and public docs | Prominent | FR2, FR3, FR4 |
130
+ | Blockquote | Presents quoted block content on the default path. | Current source and public docs | Prominent | FR2, FR3 |
131
+ | Table | Presents parsed rows and columns in a keyboard-scrollable block wrapper. | Current source and public docs | Prominent | FR2 |
132
+ | Divider | Presents a horizontal separation between blocks. | Current source and public docs | Supporting | FR2, FR3 |
133
+ | Image | Presents a safe block image or the fallback for a rejected image URL. | Current source and public docs | Prominent | FR2, FR3 |
134
+
135
+ Custom renderers replace six default parts rather than becoming nested Markdown
136
+ anatomy. Lists and Tables have no corresponding custom block renderer. The
137
+ Document remains Markdown-owned in every display mode.
138
+
139
+ ### Theming anatomy
140
+
141
+ <!-- anatomy-theming:v1 -->
142
+
143
+ ```json
144
+ {
145
+ "Document": {"target": "markdown"},
146
+ "Heading": {"target": "markdown-heading"},
147
+ "Paragraph": {"target": "markdown-paragraph"},
148
+ "List": {"target": "markdown-list"},
149
+ "Code block": {"target": "markdown-codeblock"},
150
+ "Blockquote": {"target": "markdown-blockquote"},
151
+ "Table": {"target": "markdown-table"},
152
+ "Divider": {"target": "markdown-hr"},
153
+ "Image": {"target": "markdown-image"}
154
+ }
155
+ ```
156
+
157
+ The map records all nine current targets on Markdown's default render paths. For
158
+ Heading, Paragraph, Code block, Blockquote, Divider, and safe Image, a custom
159
+ renderer replaces the default part and therefore replaces its local target. The
160
+ `markdown-codeblock` spelling is a released compatibility anomaly: the current
161
+ naming rule would produce `markdown-code-block`, but shipped targets are frozen
162
+ and this change preserves the existing spelling exactly.
163
+
164
+ ## Family and system relationships
165
+
166
+ - `architecture:component-theming-surface` owns anatomy qualification, target
167
+ mapping, target-capability state, composition boundaries, and compatibility for
168
+ frozen targets.
169
+ - Nested Astryx primitives retain ownership of their own anatomy and targets;
170
+ Markdown owns the outer block targets listed here.
171
+
172
+ ## Verification map
173
+
174
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
175
+ | ------------------- | ------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- | ------------------------ |
176
+ | 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` |
177
+ | 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` |
178
+ | 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` |
179
+ | 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` |
180
+
181
+ Focused tests pin all nine current target names and default block placement. They
182
+ pin target absence only for a custom Heading; custom Paragraph, Code block,
183
+ Blockquote, Divider, and Image replacement paths currently rely on source and
184
+ history for the same ownership rule.
185
+
186
+ ## Decision log
187
+
188
+ None. This draft records current facts and introduces no component-local design,
189
+ API, behavior, or theming decision.
190
+
191
+ ## Open questions
192
+
193
+ - **OQ1 — Which focused tests should pin target absence for the five remaining
194
+ custom block replacement paths?** (`checkable`)
195
+
196
+ ## Content boundary
197
+
198
+ This file does not duplicate consumer prop tables/examples, parser mechanics,
199
+ streaming implementation, nested primitive contracts, current audit results, or
200
+ system theming rules. It links to their owners.