@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,174 @@
1
+ ---
2
+ schema_version: 1
3
+ template_version: 3
4
+ kind: component
5
+ id: component:Switch
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/Switch/Switch.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
+ # Switch component contract
27
+
28
+ ## Intent
29
+
30
+ Switch presents a labeled boolean control whose change takes effect immediately.
31
+ This draft records current consumer anatomy and theming ownership without
32
+ changing runtime behavior, styling, targets, or public API.
33
+
34
+ ## Compatibility and migration
35
+
36
+ - Released default preserved: `yes`
37
+ - Compatibility class: additive documentation only; runtime, DOM, styling,
38
+ targets, and public API remain unchanged
39
+ - Controlled/uncontrolled behavior: unchanged; Switch remains controlled
40
+ - Migration decision: none
41
+
42
+ Consumer migration instructions belong in consumer docs and release notes.
43
+
44
+ ## Ownership boundary
45
+
46
+ **Owns**
47
+
48
+ - The switch field, track, thumb, and label presentations represented by the
49
+ existing `switch-field`, `switch`, `switch-thumb`, and `switch-label` targets.
50
+
51
+ **Does not own / non-goals**
52
+
53
+ - Description styling through a dedicated public target; none currently exists.
54
+ - Validation-message presentation — owned by `component:FieldStatus`.
55
+ - Loading-indicator presentation — owned by `component:Spinner`.
56
+ - Tooltip surfaces used for shared label and disabled-reason behavior.
57
+
58
+ ## Public concepts
59
+
60
+ No new public concept is introduced. Consumer props, states, and usage remain
61
+ documented in `Switch.doc.mjs`.
62
+
63
+ ## Behavioral and layout contract
64
+
65
+ | ID | Candidate invariant | Basis | Draft review state |
66
+ | --- | ------------------------------------------------------------------------------------------------------ | --------------------------------------- | -------------------------------------------------- |
67
+ | FR1 | The current render places a thumb inside the switch track and arranges that control with its label. | Current source, docs, and focused tests | Verified current behavior; no new behavior decided |
68
+ | FR2 | The field, track, thumb, and label carry their existing local targets. | Current source, public docs, and tests | Verified current behavior; no target change |
69
+ | FR3 | A busy switch renders Spinner inside the thumb; a status message renders through detached FieldStatus. | Current source, docs, and focused tests | Verified conditional composition |
70
+
71
+ ### Allowed variation
72
+
73
+ - Label position and spacing, size, checked state, and disabled state remain
74
+ current target capabilities rather than separate anatomy parts.
75
+ - A description may be absent without changing the remaining anatomy.
76
+
77
+ ### Representative states
78
+
79
+ | State | Required invariant | Allowed variation |
80
+ | ------------------- | ------------------------------------------------------- | -------------------------------------- |
81
+ | Off or on | Track, thumb, and label render within the switch field. | Checked state, size, label placement |
82
+ | Busy | Spinner renders inside the thumb. | Controlled or optimistic checked value |
83
+ | Status with message | Detached FieldStatus follows the switch row. | Error, warning, or success status |
84
+
85
+ ### Transformation and precedence order
86
+
87
+ - No new state, event, layout, or styling precedence rule is introduced.
88
+
89
+ ### Performance and resources
90
+
91
+ - No new performance or resource rule is introduced.
92
+
93
+ ## Accessibility contract
94
+
95
+ This draft does not change or extend Switch's existing accessible name, switch
96
+ role, checked state, busy state, description/status association, or disabled
97
+ behavior.
98
+
99
+ ## Design relationships
100
+
101
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
102
+ | ---------------- | -------------------------------------------------------- | ------------------------------- | -------------- | ------------------ |
103
+ | Field | Arranges the switch control with its label and feedback. | Current source and public docs | Supporting | FR1, FR2 |
104
+ | Track and thumb | Present the current on/off control. | Current source and public docs | Prominent | FR1, FR2 |
105
+ | Label | Identifies the controlled setting. | Current source and public docs | Prominent | FR1, FR2 |
106
+ | Spinner/status | Present conditional progress and validation feedback. | Current shared-component source | Supporting | FR3 |
107
+
108
+ ### Theming anatomy
109
+
110
+ <!-- anatomy-theming:v1 -->
111
+
112
+ ```json
113
+ {
114
+ "Field": {"target": "switch-field"},
115
+ "Track": {"target": "switch"},
116
+ "Thumb": {"target": "switch-thumb"},
117
+ "Label": {"target": "switch-label"},
118
+ "Description": {
119
+ "none": {
120
+ "reason": "unsettled: No current public target reaches the stable Description; future exposure still needs an owner decision"
121
+ }
122
+ },
123
+ "Spinner": {
124
+ "delegatesTo": {"owner": "component:Spinner", "target": "spinner"}
125
+ },
126
+ "Status message": {
127
+ "delegatesTo": {
128
+ "owner": "component:FieldStatus",
129
+ "target": "field-status"
130
+ }
131
+ }
132
+ }
133
+ ```
134
+
135
+ `Description` remains stable consumer anatomy, but no current public target
136
+ reaches it. The map classifies future exposure as unsettled rather than silently
137
+ making the absence intentional.
138
+
139
+ ## Family and system relationships
140
+
141
+ - `architecture:component-theming-surface` owns anatomy qualification, factual
142
+ `none` dispositions, and composition-preserving target ownership.
143
+ - FieldStatus and Spinner retain their existing public target contracts when
144
+ composed by Switch.
145
+
146
+ ## Verification map
147
+
148
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
149
+ | ------------------- | ----------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
150
+ | FR1 | `Switch.test.tsx` structure and interaction suites | On/off, size, label position, hidden label | Removing or reordering stable parts breaks existing role, label, or DOM assertions. | `audit:Switch/anatomy` |
151
+ | FR2 | `Switch.test.tsx` label-target suite and `themingTargets.test.ts` | Current local targets | Removing the label target fails focused coverage; source/docs drift fails the target guard. | `audit:Switch/theming` |
152
+ | FR3 | `Switch.test.tsx` loading and status suites | Busy and detached status | Removing composed feedback breaks existing spinner, busy-state, or message assertions. | `audit:Switch/anatomy` |
153
+ | Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and all current targets | Canonical-key drift, invalid dispositions or target spelling, or an unclaimed current local target fails repository validation. | `audit:Switch/theming` |
154
+
155
+ The focused Switch suite pins `switch-label`, but does not separately assert the
156
+ exact `switch-field`, `switch`, or `switch-thumb` class placement. The
157
+ source/metadata target guard covers those local declarations. No current
158
+ repository check resolves `delegatesTo` owner/target pairs; the pairs in this
159
+ draft were verified manually, so semantic delegation drift remains a validation
160
+ gap.
161
+
162
+ ## Decision log
163
+
164
+ None. This draft records current facts and introduces no component-local design
165
+ or API decision.
166
+
167
+ ## Open questions
168
+
169
+ None.
170
+
171
+ ## Content boundary
172
+
173
+ This file does not duplicate consumer prop tables, examples, implementation
174
+ steps, or shared-component contracts. It links to their owners.
@@ -1,12 +1,44 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
+ /** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
4
+ const anatomy = [
5
+ {
6
+ name: 'Text',
7
+ required: true,
8
+ description:
9
+ 'Polymorphic text element that renders the supplied content with themed typography.',
10
+ },
11
+ {
12
+ name: 'Heading',
13
+ required: false,
14
+ description:
15
+ 'Referenced Heading member that renders the supplied content as a semantic h1–h6 element.',
16
+ },
17
+ {
18
+ name: 'Truncation tooltip',
19
+ required: false,
20
+ description:
21
+ 'Tooltip-owned surface available only when Text or Heading is measured as truncated and truncation tooltips are enabled.',
22
+ },
23
+ ];
24
+
3
25
  /** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
4
26
 
5
27
  export const docs = {
6
28
  name: 'Text',
7
29
  displayName: 'Text',
8
30
  category: 'Content',
9
- keywords: ["text","typography","label","paragraph","heading","caption","font","body","subtitle"],
31
+ keywords: [
32
+ 'text',
33
+ 'typography',
34
+ 'label',
35
+ 'paragraph',
36
+ 'heading',
37
+ 'caption',
38
+ 'font',
39
+ 'body',
40
+ 'subtitle',
41
+ ],
10
42
  playground: {
11
43
  defaults: {
12
44
  children: 'The quick brown fox jumps over the lazy dog.',
@@ -19,12 +51,14 @@ export const docs = {
19
51
  {className: 'astryx-text', visualProps: ['type', 'size', 'color']},
20
52
  ],
21
53
  },
22
- description: 'Semantic body text component that renders text with type-based styling from the theme, with optional truncation, decoration, and layout props.',
54
+ description:
55
+ 'Semantic body text component that renders text with type-based styling from the theme, with optional truncation, decoration, and layout props.',
23
56
  props: [
24
57
  {
25
58
  name: 'type',
26
59
  type: "'body' | 'large' | 'label' | 'supporting' | 'code' | 'display-1' | 'display-2' | 'display-3' | 'inherit'",
27
- description: "Semantic text type. Determines size, weight, and line-height from the theme. 'inherit' takes all three from the surrounding text instead. Themes may add custom types. Note: this prop is called `type`, not `variant`.",
60
+ description:
61
+ "Semantic text type. Determines size, weight, and line-height from the theme. 'inherit' takes all three from the surrounding text instead. Themes may add custom types. Note: this prop is called `type`, not `variant`.",
28
62
  default: "'body'",
29
63
  },
30
64
  {
@@ -36,12 +70,14 @@ export const docs = {
36
70
  {
37
71
  name: 'size',
38
72
  type: "'4xs' | '3xs' | '2xs' | 'xsm' | 'sm' | 'base' | 'lg' | 'xl' | '2xl' | '3xl' | '4xl'",
39
- description: 'Explicit font size override. Overrides the size from `type` but preserves other type properties. Prefer using `type` alone.',
73
+ description:
74
+ 'Explicit font size override. Overrides the size from `type` but preserves other type properties. Prefer using `type` alone.',
40
75
  },
41
76
  {
42
77
  name: 'color',
43
78
  type: "'primary' | 'secondary' | 'disabled' | 'placeholder' | 'accent' | 'inherit'",
44
- description: "Text color. Defaults to 'secondary' for the 'supporting' type, 'primary' for all others. Themes may add custom colors.",
79
+ description:
80
+ "Text color. Defaults to 'secondary' for the 'supporting' type, 'primary' for all others. Themes may add custom colors.",
45
81
  },
46
82
  {
47
83
  name: 'weight',
@@ -51,7 +87,8 @@ export const docs = {
51
87
  {
52
88
  name: 'display',
53
89
  type: "'inline' | 'block'",
54
- description: "Display type. Silently overridden to 'block' when maxLines > 0 or hasCapsize is true.",
90
+ description:
91
+ "Display type. Silently overridden to 'block' when maxLines > 0 or hasCapsize is true.",
55
92
  default: "'inline'",
56
93
  },
57
94
  {
@@ -63,19 +100,22 @@ export const docs = {
63
100
  {
64
101
  name: 'maxLines',
65
102
  type: 'number',
66
- description: 'Maximum lines before truncation. 0 means no truncation. When set, shows a tooltip on hover if content is truncated.',
103
+ description:
104
+ 'Maximum lines before truncation. 0 means no truncation. When set, shows a tooltip on hover if content is truncated.',
67
105
  default: '0',
68
106
  },
69
107
  {
70
108
  name: 'hasTruncateTooltip',
71
109
  type: "boolean | 'above' | 'below' | 'start' | 'end'",
72
- description: "Controls tooltip behavior for truncated text. true shows the tooltip at the default position, false disables it, or a placement string ('above' | 'below' | 'start' | 'end') sets a specific position.",
110
+ description:
111
+ "Controls tooltip behavior for truncated text. true shows the tooltip at the default position, false disables it, or a placement string ('above' | 'below' | 'start' | 'end') sets a specific position.",
73
112
  default: 'true',
74
113
  },
75
114
  {
76
115
  name: 'wordBreak',
77
116
  type: "'break-word' | 'break-all'",
78
- description: "Word break behavior when truncating. Defaults to 'break-all' for single-line truncation, 'break-word' otherwise.",
117
+ description:
118
+ "Word break behavior when truncating. Defaults to 'break-all' for single-line truncation, 'break-word' otherwise.",
79
119
  },
80
120
  {
81
121
  name: 'textWrap',
@@ -85,13 +125,15 @@ export const docs = {
85
125
  {
86
126
  name: 'justify',
87
127
  type: "'start' | 'center' | 'end'",
88
- description: 'Text alignment (justification). Uses logical values (start/end) for i18n/RTL compatibility.',
128
+ description:
129
+ 'Text alignment (justification). Uses logical values (start/end) for i18n/RTL compatibility.',
89
130
  default: "'start'",
90
131
  },
91
132
  {
92
133
  name: 'hasCapsize',
93
134
  type: 'boolean',
94
- description: 'Enable optical alignment using text-box-trim. Forces block display.',
135
+ description:
136
+ 'Enable optical alignment using text-box-trim. Forces block display.',
95
137
  default: 'false',
96
138
  },
97
139
  {
@@ -114,25 +156,61 @@ export const docs = {
114
156
  {
115
157
  name: 'xstyle',
116
158
  type: 'StyleXStyles',
117
- description: 'StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}.',
159
+ description:
160
+ 'StyleX styles for layout customization (margins, positioning, sizing). Must be a stylex.create() value: not an inline style object like style={{}}.',
118
161
  },
119
162
  ],
120
- components: [
121
- {name: 'Heading'},
122
- ],
163
+ components: [{name: 'Heading'}],
123
164
  usage: {
165
+ anatomy,
124
166
  description:
125
167
  'Text renders styled body text and headings from the theme. Use Text with a semantic type for body copy, labels, and captions, and Heading for section titles that output the correct h1\u2013h6 element.',
126
168
  bestPractices: [
127
- { guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.' },
128
- { guidance: true, description: 'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.' },
129
- { guidance: true, description: 'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.' },
130
- { guidance: true, description: 'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.' },
131
- { guidance: false, description: 'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.' },
132
- { guidance: false, description: 'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.' },
133
- { guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.' },
134
- { guidance: false, description: 'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.' },
135
- { guidance: false, description: 'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.' },
169
+ {
170
+ guidance: true,
171
+ description:
172
+ 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.',
173
+ },
174
+ {
175
+ guidance: true,
176
+ description:
177
+ 'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.',
178
+ },
179
+ {
180
+ guidance: true,
181
+ description:
182
+ 'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.',
183
+ },
184
+ {
185
+ guidance: true,
186
+ description:
187
+ 'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.',
188
+ },
189
+ {
190
+ guidance: false,
191
+ description:
192
+ 'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.',
193
+ },
194
+ {
195
+ guidance: false,
196
+ description:
197
+ 'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.',
198
+ },
199
+ {
200
+ guidance: false,
201
+ description:
202
+ 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.',
203
+ },
204
+ {
205
+ guidance: false,
206
+ description:
207
+ 'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.',
208
+ },
209
+ {
210
+ guidance: false,
211
+ description:
212
+ 'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.',
213
+ },
136
214
  ],
137
215
  },
138
216
  };
@@ -143,35 +221,104 @@ export const docsZh = {
143
221
  description:
144
222
  'Text renders styled body text and headings from the theme. Use Text with a semantic type for body copy, labels, and captions, and Heading for section titles that output the correct h1\u2013h6 element.',
145
223
  bestPractices: [
146
- { guidance: true, description: 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.' },
147
- { guidance: true, description: 'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.' },
148
- { guidance: true, description: 'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.' },
149
- { guidance: true, description: 'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.' },
150
- { guidance: false, description: 'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.' },
151
- { guidance: false, description: 'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.' },
152
- { guidance: false, description: 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.' },
153
- { guidance: false, description: 'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.' },
154
- { guidance: false, description: 'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.' },
224
+ {
225
+ guidance: true,
226
+ description:
227
+ 'Pick a semantic type (body, label, supporting, large, code) instead of manually setting size and weight; the theme handles the details.',
228
+ },
229
+ {
230
+ guidance: true,
231
+ description:
232
+ 'Set accessibilityLevel on Heading when the visual level differs from the document outline so screen readers announce the correct hierarchy.',
233
+ },
234
+ {
235
+ guidance: true,
236
+ description:
237
+ 'Use maxLines with a number to truncate long content; a tooltip appears automatically on hover so no text is lost.',
238
+ },
239
+ {
240
+ guidance: true,
241
+ description:
242
+ 'Enable hasTabularNumbers for columns of numeric data so digits align vertically across rows.',
243
+ },
244
+ {
245
+ guidance: false,
246
+ description:
247
+ 'Override size and weight when a semantic type already matches; extra overrides fight the theme and break when themes change.',
248
+ },
249
+ {
250
+ guidance: false,
251
+ description:
252
+ 'Skip heading levels in the document outline; go h1 then h2 then h3, never h1 then h3.',
253
+ },
254
+ {
255
+ guidance: false,
256
+ description:
257
+ 'Use raw HTML tags like <p>, <h1>\u2013<h6>, or <span> for text; Text and Heading apply the correct theme tokens automatically.',
258
+ },
259
+ {
260
+ guidance: false,
261
+ description:
262
+ 'Pass a `variant` prop; Text does not have a `variant` prop. Use `type` for semantic styling (body, label, large, supporting, code) or use Heading for headings.',
263
+ },
264
+ {
265
+ guidance: false,
266
+ description:
267
+ 'Use Text for headings; use Heading with a `level` prop (1\u20136) for section titles and headings.',
268
+ },
155
269
  ],
156
270
  },
157
271
  };
158
272
 
159
273
  /** @type {import('@astryxdesign/cli/authoring').ComponentTranslationDoc} */
160
274
  export const docsDense = {
161
- description: 'semantic body text + headings w/ theme-driven type scale, truncation, tabular numbers',
275
+ description:
276
+ 'semantic body text + headings w/ theme-driven type scale, truncation, tabular numbers',
162
277
  usage: {
163
278
  description:
164
279
  'Text renders styled body text and headings. Text for body copy with semantic types, Heading for h1\u2013h6 with theme tokens.',
165
280
  bestPractices: [
166
- { guidance: true, description: 'Semantic type (body, label, supporting, large, code) instead of manual size/weight.' },
167
- { guidance: true, description: 'accessibilityLevel on Heading when visual level differs from document outline.' },
168
- { guidance: true, description: 'maxLines for truncation; tooltip shows full text on hover.' },
169
- { guidance: true, description: 'hasTabularNumbers for aligned numeric columns.' },
170
- { guidance: false, description: 'Override size/weight when a semantic type already matches.' },
171
- { guidance: false, description: 'Skip heading levels; sequential h1 \u2192 h2 \u2192 h3.' },
172
- { guidance: false, description: 'Raw <p>/<h1>/<span>; use Text/Heading for theme tokens.' },
173
- { guidance: false, description: '`variant` prop, which does not exist. Use `type` for text styling or Heading for headings.' },
174
- { guidance: false, description: 'Text for headings: use Heading with level (1\u20136).' },
281
+ {
282
+ guidance: true,
283
+ description:
284
+ 'Semantic type (body, label, supporting, large, code) instead of manual size/weight.',
285
+ },
286
+ {
287
+ guidance: true,
288
+ description:
289
+ 'accessibilityLevel on Heading when visual level differs from document outline.',
290
+ },
291
+ {
292
+ guidance: true,
293
+ description:
294
+ 'maxLines for truncation; tooltip shows full text on hover.',
295
+ },
296
+ {
297
+ guidance: true,
298
+ description: 'hasTabularNumbers for aligned numeric columns.',
299
+ },
300
+ {
301
+ guidance: false,
302
+ description:
303
+ 'Override size/weight when a semantic type already matches.',
304
+ },
305
+ {
306
+ guidance: false,
307
+ description: 'Skip heading levels; sequential h1 \u2192 h2 \u2192 h3.',
308
+ },
309
+ {
310
+ guidance: false,
311
+ description: 'Raw <p>/<h1>/<span>; use Text/Heading for theme tokens.',
312
+ },
313
+ {
314
+ guidance: false,
315
+ description:
316
+ '`variant` prop, which does not exist. Use `type` for text styling or Heading for headings.',
317
+ },
318
+ {
319
+ guidance: false,
320
+ description: 'Text for headings: use Heading with level (1\u20136).',
321
+ },
175
322
  ],
176
323
  },
177
324
  };