@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,214 @@
1
+ ---
2
+ schema_version: 1
3
+ template_version: 3
4
+ kind: component
5
+ id: component:CheckboxList
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/CheckboxList/CheckboxList.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
+ # CheckboxList component contract
27
+
28
+ ## Intent
29
+
30
+ CheckboxList presents a labeled group of checkbox options. This draft records
31
+ its current consumer anatomy and the theming ownership of parts rendered by
32
+ CheckboxList, List, CheckboxInput, Field, FieldStatus, and Spinner. It changes no
33
+ runtime behavior or public API.
34
+
35
+ ## Compatibility and migration
36
+
37
+ - Released default preserved: `yes`
38
+ - Compatibility class: additive documentation only; runtime, DOM, styling,
39
+ targets, and public API remain unchanged
40
+ - Controlled/uncontrolled behavior: unchanged
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 checkbox-group composition and its existing `checkbox-list` target.
50
+ - Collection state shared with CheckboxListItem.
51
+
52
+ **Does not own / non-goals**
53
+
54
+ - List and option-row presentation — owned by `component:List`; its
55
+ `list-item` target reaches only the row root.
56
+ - Standard option-label and option-description wrappers — rendered as separate,
57
+ untargeted spans by Item rather than Text; rich label content and end content
58
+ remain caller-owned.
59
+ - The checkbox indicator — owned by `component:CheckboxInput`.
60
+ - Group-label and validation-message presentation — owned by `component:Field`
61
+ and `component:FieldStatus`.
62
+ - Loading-indicator presentation — owned by `component:Spinner`.
63
+ - New targets for untargeted descriptions or caller-provided item content.
64
+
65
+ ## Public concepts
66
+
67
+ No new public concept is introduced. Consumer props, collection and standalone
68
+ item modes, and usage remain documented in `CheckboxList.doc.mjs` and
69
+ `CheckboxListItem.doc.mjs`.
70
+
71
+ ## Behavioral and layout contract
72
+
73
+ | ID | Candidate invariant | Basis | Draft review state |
74
+ | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------- | -------------------------------------------------- |
75
+ | FR1 | The current render places CheckboxListItem children inside a List and a group named by the group label. | Current source, docs, and focused tests | Verified current behavior; no new behavior decided |
76
+ | FR2 | The CheckboxList root carries the current `checkbox-list` target. | Current source and public docs | Verified current behavior; no target change |
77
+ | FR3 | The option-row root and checkbox indicator continue to be rendered by List and CheckboxInput rather than reimplemented. | Current source | Verified composition boundary |
78
+ | FR5 | Item renders option label and description as separate untargeted children; end content remains caller-provided inside its own untargeted slot wrapper. | Current source and focused tests | Verified child ownership; no target change |
79
+ | FR4 | A pending item renders Spinner inside that item's checkbox; a status message renders through detached FieldStatus. | Current source, docs, and focused tests | Verified conditional composition |
80
+
81
+ ### Allowed variation
82
+
83
+ - Option labels, descriptions, and end content may vary with caller-provided
84
+ CheckboxListItem content without becoming new CheckboxList targets.
85
+ - Density, dividers, checked state, and disabled state remain capabilities of
86
+ their current owning components rather than separate anatomy parts.
87
+
88
+ ### Representative states
89
+
90
+ | State | Required invariant | Allowed variation |
91
+ | ------------------------- | --------------------------------------------------------------- | ---------------------------------- |
92
+ | Default collection | Named group, options list, rows, and checkbox indicators render | Option content and selected values |
93
+ | Item pending | Only the pending checkbox includes a Spinner | Which option is pending |
94
+ | Group status with message | Detached FieldStatus follows the group | Error, warning, or success status |
95
+
96
+ ### Transformation and precedence order
97
+
98
+ - No new state, event, layout, or styling precedence rule is introduced.
99
+
100
+ ### Performance and resources
101
+
102
+ - No new performance or resource rule is introduced.
103
+
104
+ ## Accessibility contract
105
+
106
+ This draft does not change or extend CheckboxList's existing group naming,
107
+ checkbox semantics, focus order, busy state, or description/status association.
108
+
109
+ ## Design relationships
110
+
111
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
112
+ | ------------------ | ---------------------------------------------------------------------------- | ------------------------------- | -------------- | ------------------ |
113
+ | Group | Contains the current checkbox-group composition. | Current source and public docs | Supporting | FR1, FR2 |
114
+ | Options and rows | Present the List-owned list and row root plus Item-rendered child structure. | Current source | Supporting | FR1, FR3 |
115
+ | Checkbox | Presents each option's current selection indicator. | Current CheckboxInput source | Prominent | FR3 |
116
+ | Spinner and status | Present the current conditional feedback components. | Current shared-component source | Supporting | FR4 |
117
+
118
+ ### Theming anatomy
119
+
120
+ <!-- anatomy-theming:v1 -->
121
+
122
+ ```json
123
+ {
124
+ "Group": {"target": "checkbox-list"},
125
+ "Group label": {
126
+ "delegatesTo": {"owner": "component:Field", "target": "field-label"}
127
+ },
128
+ "Description": {
129
+ "none": {
130
+ "reason": "unsettled: No current public target reaches the stable Description; future exposure still needs an owner decision"
131
+ }
132
+ },
133
+ "Options list": {
134
+ "delegatesTo": {"owner": "component:List", "target": "list"}
135
+ },
136
+ "Option row": {
137
+ "delegatesTo": {"owner": "component:List", "target": "list-item"}
138
+ },
139
+ "Checkbox": {
140
+ "delegatesTo": {
141
+ "owner": "component:CheckboxInput",
142
+ "target": "checkbox-indicator"
143
+ }
144
+ },
145
+ "Option label": {
146
+ "none": {
147
+ "reason": "unsettled: Item rather than Text renders the stable Option label in a separate untargeted span; future exposure still needs an owner decision"
148
+ }
149
+ },
150
+ "Option description": {
151
+ "none": {
152
+ "reason": "unsettled: Item rather than Text renders the stable Option description in a separate untargeted span; future exposure still needs an owner decision"
153
+ }
154
+ },
155
+ "End content": {
156
+ "none": {
157
+ "reason": "intentional: End content is caller-provided content outside CheckboxList's public theming ownership"
158
+ }
159
+ },
160
+ "Spinner": {
161
+ "delegatesTo": {"owner": "component:Spinner", "target": "spinner"}
162
+ },
163
+ "Status message": {
164
+ "delegatesTo": {
165
+ "owner": "component:FieldStatus",
166
+ "target": "field-status"
167
+ }
168
+ }
169
+ }
170
+ ```
171
+
172
+ `Description` remains stable consumer anatomy, but no current public target
173
+ reaches it. Item, not Text, renders option labels and descriptions in separate
174
+ untargeted spans, so neither delegates to Text nor inherits the row-root
175
+ `list-item` target; future exposure remains unsettled. Rich label content and end
176
+ content are caller-provided, and end content intentionally stays outside
177
+ CheckboxList's public theming ownership.
178
+
179
+ ## Family and system relationships
180
+
181
+ - `architecture:component-theming-surface` owns anatomy qualification, factual
182
+ `none` dispositions, and composition-preserving target ownership.
183
+ - List, CheckboxInput, Field, FieldStatus, and Spinner retain their existing
184
+ public target contracts when composed by CheckboxList.
185
+
186
+ ## Verification map
187
+
188
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
189
+ | ------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------------- |
190
+ | FR1, FR3, FR5 | `CheckboxList.test.tsx` structure, content, and interaction suites plus `Item.tsx` source inspection | Collection mode; string/rich label; description; end content | Removing the group, row, checkbox, or separate content children breaks existing DOM and interaction assertions. | `audit:CheckboxList/anatomy` |
191
+ | FR4 | `CheckboxList.test.tsx` loading and status suites | Pending item and detached status | Removing composed feedback breaks existing spinner, busy-state, or message assertions. | `audit:CheckboxList/anatomy` |
192
+ | Local target source | `themingTargets.test.ts` | `checkbox-list` | Source/docs target drift fails the repository target guard. | `audit:CheckboxList/theming` |
193
+ | Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and current local target | Canonical-key drift, invalid dispositions or target spelling, or an unclaimed current local target fails repository validation. | `audit:CheckboxList/theming` |
194
+
195
+ The focused CheckboxList suite does not pin the exact delegated target classes
196
+ or the local `checkbox-list` class in rendered DOM. The source/metadata target
197
+ guard independently verifies that each owner's emitted targets remain
198
+ documented. No current repository check resolves `delegatesTo` owner/target
199
+ pairs; the pairs in this draft were verified manually, so semantic delegation
200
+ drift remains a validation gap.
201
+
202
+ ## Decision log
203
+
204
+ None. This draft records current facts and introduces no component-local design
205
+ or API decision.
206
+
207
+ ## Open questions
208
+
209
+ None.
210
+
211
+ ## Content boundary
212
+
213
+ This file does not duplicate consumer prop tables, examples, implementation
214
+ steps, or shared-component contracts. It links to their owners.
@@ -1,5 +1,74 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
+ /** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
4
+ const anatomy = [
5
+ {
6
+ name: 'Dialog',
7
+ required: true,
8
+ description: 'Modal surface that contains the command palette.',
9
+ },
10
+ {
11
+ name: 'Input',
12
+ required: true,
13
+ description:
14
+ 'Search region containing the query field and its supporting visuals.',
15
+ },
16
+ {
17
+ name: 'Search glyph',
18
+ required: true,
19
+ description: 'Search symbol rendered by Icon in the default Input.',
20
+ },
21
+ {
22
+ name: 'Query field',
23
+ required: true,
24
+ description: 'Native text field used to enter a search query.',
25
+ },
26
+ {
27
+ name: 'Loading spinner',
28
+ required: false,
29
+ description:
30
+ 'Spinner shown in the default Input while a search is pending.',
31
+ },
32
+ {
33
+ name: 'List',
34
+ required: true,
35
+ description:
36
+ 'Scrollable listbox containing the current results or Empty state.',
37
+ },
38
+ {
39
+ name: 'Item',
40
+ required: false,
41
+ description: 'Selectable command result rendered inside the List.',
42
+ },
43
+ {
44
+ name: 'Group',
45
+ required: false,
46
+ description: 'Optional collection of Items that share a heading.',
47
+ },
48
+ {
49
+ name: 'Group heading',
50
+ required: false,
51
+ description: 'Visible heading rendered for a Group.',
52
+ },
53
+ {
54
+ name: 'Empty',
55
+ required: false,
56
+ description: 'Message shown when the current result set is empty.',
57
+ },
58
+ {
59
+ name: 'Footer',
60
+ required: false,
61
+ description:
62
+ 'Footer region for default keyboard guidance or caller-provided content.',
63
+ },
64
+ {
65
+ name: 'Keyboard shortcut',
66
+ required: false,
67
+ description:
68
+ 'Painted key badges rendered by Kbd in the default Footer guidance.',
69
+ },
70
+ ];
71
+
3
72
  /** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
4
73
  export const docs = {
5
74
  name: 'CommandPalette',
@@ -152,6 +221,7 @@ export const docs = {
152
221
  ],
153
222
  },
154
223
  usage: {
224
+ anatomy,
155
225
  description: 'CommandPalette is a searchable dialog for quick access to commands, navigation, and actions. Use it as a keyboard-driven launcher powered by SearchSource for filtering and selection.',
156
226
  bestPractices: [
157
227
  { guidance: true, description: 'Provide a searchSource with bootstrap results so users see useful options before typing.' },
@@ -165,6 +235,7 @@ export const docs = {
165
235
  /** @type {import('@astryxdesign/cli/authoring').ComponentTranslationDoc} */
166
236
  export const docsZh = {
167
237
  usage: {
238
+ anatomy,
168
239
  description: 'CommandPalette is a searchable dialog for quick access to commands, navigation, and actions. Use it as a keyboard-driven launcher powered by SearchSource for filtering and selection.',
169
240
  bestPractices: [
170
241
  { guidance: true, description: 'Provide a searchSource with bootstrap results so users see useful options before typing.' },
@@ -180,6 +251,7 @@ export const docsDense = {
180
251
  description:
181
252
  'searchSource-driven command palette dialog; filtering, keyboard nav, grouping, selection; same SearchSource interface as Typeahead',
182
253
  usage: {
254
+ anatomy,
183
255
  description: 'CommandPalette is a searchable dialog for quick access to commands, navigation, and actions. Use it as a keyboard-driven launcher powered by SearchSource for filtering and selection.',
184
256
  bestPractices: [
185
257
  { guidance: true, description: 'Provide a searchSource with bootstrap results so users see useful options before typing.' },
@@ -0,0 +1,223 @@
1
+ ---
2
+ schema_version: 1
3
+ template_version: 3
4
+ kind: component
5
+ id: component:CommandPalette
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/CommandPalette/CommandPalette.test.tsx,
16
+ packages/core/src/CommandPalette/CommandPaletteInput.test.tsx,
17
+ packages/core/src/CommandPalette/CommandPaletteList.test.tsx,
18
+ packages/core/src/CommandPalette/CommandPaletteItem.test.tsx,
19
+ packages/core/src/CommandPalette/CommandPaletteGroup.test.tsx,
20
+ packages/core/src/CommandPalette/CommandPaletteFooter.test.tsx,
21
+ packages/core/src/theme/themingTargets.test.ts,
22
+ scripts/check-knowledge.mjs,
23
+ ]
24
+ families: [family:overlay-dismissal]
25
+ design_specs: []
26
+ architecture:
27
+ [
28
+ architecture:component-theming-surface,
29
+ architecture:interaction-modality,
30
+ architecture:public-component-api,
31
+ ]
32
+ contributing: []
33
+ system_specs: []
34
+ ---
35
+
36
+ # CommandPalette component contract
37
+
38
+ ## Intent
39
+
40
+ CommandPalette presents searchable commands inside a Dialog. This draft records
41
+ its current aggregate consumer anatomy, target ownership, and delegated stable
42
+ parts without changing runtime behavior, styling, targets, or public API.
43
+
44
+ ## Compatibility and migration
45
+
46
+ - Released default preserved: `yes`
47
+ - Compatibility class: additive documentation only; runtime, DOM, styling,
48
+ targets, aliases, and public API remain unchanged
49
+ - Controlled/uncontrolled behavior: unchanged
50
+ - Migration decision: none
51
+
52
+ Consumer migration instructions belong in consumer docs and release notes.
53
+
54
+ ## Ownership boundary
55
+
56
+ **Owns**
57
+
58
+ - Search orchestration and the current Input, List, Item, Group, Group heading,
59
+ Empty, and Footer parts and targets.
60
+ - The native Query field rendered inside the default Input.
61
+
62
+ **Does not own / non-goals**
63
+
64
+ - Dialog's surface, Icon's glyph, Spinner's loading indicator, or Kbd's shortcut
65
+ badges — owned by their respective components.
66
+ - Caller-provided replacement Input, Footer, item content, or trailing input
67
+ content — owned by the product callsite.
68
+ - A `command-palette` root target — no such current target exists, and this
69
+ factual backfill does not invent one.
70
+ - Shared layer hosting, positioning, or lifecycle rules beyond the current
71
+ records linked below.
72
+
73
+ ## Public concepts
74
+
75
+ No new public concept is introduced. Consumer props, slots, and usage remain
76
+ documented in `CommandPalette.doc.mjs` and its subcomponent docs.
77
+
78
+ ## Behavioral and layout contract
79
+
80
+ | ID | Candidate invariant | Basis | Draft review state |
81
+ | --- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------------- |
82
+ | FR1 | The current default render places Input and Footer around a List inside a delegated Dialog; the List contains Items, optional Groups and Group headings, or Empty according to the current results. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
83
+ | FR2 | Input, List, Item, Group, Group heading, Empty, and Footer carry the seven current `command-palette-*` targets documented below; no `command-palette` root target exists. | Current source and target docs | Verified current inventory; focused placement coverage is partial |
84
+ | FR3 | The default Input delegates its Search glyph to Icon and pending Loading spinner to Spinner; the default Footer delegates keyboard shortcuts to Kbd; the containing surface delegates to Dialog. | Current source and component docs | Verified current composition; no ownership change |
85
+ | FR4 | Query field is a distinct native text field inside Input and currently has no separate public target. The `command-palette-input` target is on the surrounding search region, not the native field. | Current source and target docs | Verified current reachability; long-term theming intent remains unsettled |
86
+
87
+ ### Allowed variation
88
+
89
+ - **AV1 — Results.** Item count, grouping, selected content, and empty state may
90
+ vary without changing the aggregate anatomy.
91
+ - **AV2 — Slots.** Caller-provided Input and Footer content may replace the
92
+ defaults without becoming CommandPalette-owned subparts.
93
+ - **AV3 — Delegated rendering.** Dialog, Icon, Spinner, and Kbd may change their
94
+ internal element shape while preserving their own public contracts.
95
+
96
+ ### Representative states
97
+
98
+ | State | Required invariant | Allowed variation |
99
+ | ---------------------- | ------------------------------------------------------- | ----------------------------------------------- |
100
+ | Ungrouped results | List contains Item instances. | Item count and caller-rendered content. |
101
+ | Grouped results | List contains Group, Group heading, and Item instances. | Group names, count, ordering, and item content. |
102
+ | Empty bootstrap/search | List contains Empty instead of Items. | Caller-provided empty content. |
103
+ | Pending search | Default Input may contain Loading spinner. | Spinner is absent when no search is pending. |
104
+ | Default slots | Input and Footer render their documented defaults. | Footer shortcut text and translated labels. |
105
+ | Caller-replaced slots | The slot content replaces the corresponding default. | Replacement structure remains caller-owned. |
106
+
107
+ ### Transformation and precedence order
108
+
109
+ - No new search, selection, layout, or styling precedence rule is introduced.
110
+
111
+ ### Performance and resources
112
+
113
+ - No new performance or resource rule is introduced.
114
+
115
+ ## Accessibility contract
116
+
117
+ This draft does not change or extend CommandPalette's current Dialog, combobox,
118
+ listbox, option, announcement, or keyboard behavior.
119
+
120
+ ## Design relationships
121
+
122
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
123
+ | ----------------- | ----------------------------------------------------------------------- | ------------------------------ | -------------- | ------------------ |
124
+ | Dialog | Presents the containing modal surface. | `component:Dialog` | Supporting | FR1, FR3 |
125
+ | Input | Paints the search region around the query field and supporting visuals. | Current source and public docs | Prominent | FR1, FR2, FR4 |
126
+ | Search glyph | Presents the search symbol in the default Input. | `component:Icon` | Supporting | FR3 |
127
+ | Query field | Accepts the native text query inside Input. | Current source and public docs | Prominent | FR1, FR4 |
128
+ | Loading spinner | Indicates a pending search in the default Input. | `component:Spinner` | Supporting | FR3 |
129
+ | List | Presents the current result collection or Empty state. | Current source and public docs | Supporting | FR1, FR2 |
130
+ | Item | Presents one selectable command result. | Current source and public docs | Prominent | FR1, FR2 |
131
+ | Group | Arranges related Items together. | Current source and public docs | Supporting | FR1, FR2 |
132
+ | Group heading | Labels one Group visually. | Current source and public docs | Supporting | FR1, FR2 |
133
+ | Empty | Presents the no-results or no-query message. | Current source and public docs | Prominent | FR1, FR2 |
134
+ | Footer | Presents default guidance or caller-provided footer content. | Current source and public docs | Supporting | FR1, FR2 |
135
+ | Keyboard shortcut | Presents one shortcut as painted key badges in the default Footer. | `component:Kbd` | Supporting | FR3 |
136
+
137
+ The native Query field is separate from the Input region that carries
138
+ `command-palette-input`. Its current lack of a direct target is observed
139
+ reachability, not a decision that it must remain unthemeable.
140
+
141
+ ### Theming anatomy
142
+
143
+ <!-- anatomy-theming:v1 -->
144
+
145
+ ```json
146
+ {
147
+ "Dialog": {
148
+ "delegatesTo": {"owner": "component:Dialog", "target": "dialog"}
149
+ },
150
+ "Input": {"target": "command-palette-input"},
151
+ "Search glyph": {
152
+ "delegatesTo": {"owner": "component:Icon", "target": "icon"}
153
+ },
154
+ "Query field": {
155
+ "none": {
156
+ "reason": "unsettled: No current public target is applied directly to the native query field; future exposure still needs an owner decision"
157
+ }
158
+ },
159
+ "Loading spinner": {
160
+ "delegatesTo": {"owner": "component:Spinner", "target": "spinner"}
161
+ },
162
+ "List": {"target": "command-palette-list"},
163
+ "Item": {"target": "command-palette-item"},
164
+ "Group": {"target": "command-palette-group"},
165
+ "Group heading": {"target": "command-palette-group-heading"},
166
+ "Empty": {"target": "command-palette-empty"},
167
+ "Footer": {"target": "command-palette-footer"},
168
+ "Keyboard shortcut": {
169
+ "delegatesTo": {"owner": "component:Kbd", "target": "kbd"}
170
+ }
171
+ }
172
+ ```
173
+
174
+ The seven local targets are current public seams. The delegated parts retain
175
+ their existing component owners. The Query field `none` disposition records a
176
+ current audit gap and does not authorize a new target.
177
+
178
+ ## Family and system relationships
179
+
180
+ - `architecture:component-theming-surface` owns anatomy qualification, target
181
+ mapping, delegation, and factual `none` dispositions.
182
+ - `architecture:public-component-api` owns the stable props and composition
183
+ surface; this documentation adds no API.
184
+ - `architecture:interaction-modality` owns shared keyboard and pointer modality;
185
+ this draft does not redefine focus ownership or input behavior.
186
+ - `family:overlay-dismissal` identifies CommandPalette as a current member and
187
+ records its component-local Escape handling as an adoption gap.
188
+ - No layer-runtime record is linked because no current record with that scope is
189
+ present in this checkout.
190
+
191
+ ## Verification map
192
+
193
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
194
+ | ------------------- | ------------------------------------------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------ |
195
+ | FR1 | CommandPalette root and subcomponent render suites plus source inspection | Default, grouped, empty, pending, and replaced slots | Removing the asserted Dialog, Query field, List, Item, Group, Group heading, Empty, or Footer content fails existing role, content, or slot assertions; Search glyph, Loading spinner, and Keyboard shortcut presence remain source-inspected only. | `audit:CommandPalette/anatomy` |
196
+ | FR2 | Source inspection, `themingTargets.test.ts`, and `CommandPaletteGroup.test.tsx` | Seven local targets; Group and Group heading placement | Removing a current target fails the global inventory; moving Group or Group heading fails focused class assertions. | `audit:CommandPalette/theming` |
197
+ | FR3 | Source inspection plus Dialog, Icon, Spinner, and Kbd public target metadata | Default surface, Input visuals, and Footer shortcuts | Existing focused tests do not assert the composed Icon, Spinner, or Kbd instances; changing delegated ownership requires this map and the delegated component metadata to change. | `audit:CommandPalette/theming` |
198
+ | FR4 | `CommandPaletteInput.test.tsx` and source inspection | Native query field with idle and pending Input | Removing the field fails combobox tests; adding a field target requires an explicit map update. | `audit:CommandPalette/anatomy` |
199
+ | Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and seven current local targets | Missing, extra, prefixed, stale, or alias-backed mappings fail repository validation. | `audit:CommandPalette/theming` |
200
+
201
+ Focused target-placement assertions currently cover Group and Group heading.
202
+ Input, List, Item, Empty, and Footer placement rely on source inspection plus the
203
+ global target inventory. Existing tests assert default Footer text and pending
204
+ announcements, but do not assert that Icon, Spinner, or Kbd renders.
205
+
206
+ ## Decision log
207
+
208
+ None. This draft records current facts and introduces no component-local design,
209
+ layer, API, or theming decision.
210
+
211
+ ## Open questions
212
+
213
+ - **OQ1 — Should Query field gain a stable public theming target?** (`human-api`)
214
+ Its current lack of direct reachability is an audit gap, not settled intent.
215
+ - **OQ2 — Should focused tests pin the default Search glyph, pending Loading
216
+ spinner, and default Footer Keyboard shortcuts?** (`checkable`) Their presence
217
+ is currently source-inspected rather than asserted.
218
+
219
+ ## Content boundary
220
+
221
+ This file does not duplicate consumer prop tables/examples, shared layer or
222
+ modality rules, current audit results, or implementation steps. It links to
223
+ their owners.
@@ -9,13 +9,53 @@
9
9
  * SYNC: When modified, update ComplexSelector.tsx, tests, and stories.
10
10
  */
11
11
 
12
+ /** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
13
+ const anatomy = [
14
+ {
15
+ name: 'Field',
16
+ required: true,
17
+ description:
18
+ 'Field shell that provides the label and optional supporting field content.',
19
+ },
20
+ {
21
+ name: 'Trigger',
22
+ required: true,
23
+ description:
24
+ 'Control that displays the current value or placeholder and opens the popup.',
25
+ },
26
+ {
27
+ name: 'Icon-rendered start icon',
28
+ required: false,
29
+ description:
30
+ 'Optional leading semantic icon or icon component rendered through Icon.',
31
+ },
32
+ {
33
+ name: 'Caller-rendered start content',
34
+ required: false,
35
+ description:
36
+ 'Optional arbitrary React content rendered directly at the start of the trigger.',
37
+ },
38
+ {
39
+ name: 'Indicator icon',
40
+ required: true,
41
+ description:
42
+ 'Trailing chevron that rotates to reflect whether the popup is open.',
43
+ },
44
+ {
45
+ name: 'Popup',
46
+ required: true,
47
+ description:
48
+ 'Mounted dialog surface that is painted and shown while open and hidden while closed.',
49
+ },
50
+ ];
51
+
12
52
  /** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
13
53
 
14
54
  export const docs = {
15
55
  name: 'ComplexSelector',
16
56
  displayName: 'Complex Selector',
17
57
  group: 'Selector',
18
- category: 'Data Input',
58
+ category: 'Form Controls',
19
59
  keywords: [
20
60
  'selector',
21
61
  'picker',
@@ -158,6 +198,7 @@ export const docs = {
158
198
  },
159
199
  ],
160
200
  usage: {
201
+ anatomy,
161
202
  description:
162
203
  'Use ComplexSelector when a selection needs richer custom content than a Selector option row. It is intentionally one component: ComplexSelector owns the field, trigger, popover, focus restore, and changeAction flow, while the content render prop owns the selector-specific accessible structure.',
163
204
  bestPractices: [
@@ -214,10 +255,11 @@ export const docsDense = {
214
255
  name: 'ComplexSelector',
215
256
  displayName: 'Complex Selector',
216
257
  group: 'Selector',
217
- category: 'Data Input',
258
+ category: 'Form Controls',
218
259
  description:
219
260
  'Input/ghost trigger + dialog-popover shell for rich custom selectors. Content gets value/onChange/close/state; content owns semantics. Use focus hooks and evaluate custom content against WCAG 2.2.',
220
261
  usage: {
262
+ anatomy,
221
263
  description:
222
264
  'Use when a selection needs richer custom content than a Selector row. One component: it owns field, trigger, popover, focus restore, and changeAction; the render prop owns the selector-specific accessible structure.',
223
265
  bestPractices: [