@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.
- package/CHANGELOG.md +19 -0
- package/dist/BottomSheet/BottomSheet.d.ts +3 -1
- package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheet.js +4 -3
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts +2 -2
- package/dist/BottomSheet/BottomSheetEdgeTint.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetEdgeTint.js +7 -10
- package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
- package/dist/BottomSheet/BottomSheetSwitcher.js +1 -1
- package/dist/Button/Button.d.ts +2 -1
- package/dist/Button/Button.d.ts.map +1 -1
- package/dist/Button/Button.js +11 -4
- package/dist/Carousel/Carousel.d.ts.map +1 -1
- package/dist/Carousel/Carousel.js +2 -2
- package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
- package/dist/Chat/ChatToolCalls.js +34 -17
- package/dist/ContextMenu/ContextMenu.d.ts +14 -3
- package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
- package/dist/ContextMenu/ContextMenu.js +149 -26
- package/dist/ContextMenu/index.d.ts +1 -0
- package/dist/ContextMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.d.ts +24 -5
- package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenu.js +340 -26
- package/dist/DropdownMenu/DropdownMenuContext.d.ts +1 -1
- package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuItem.js +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +6 -2
- package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
- package/dist/DropdownMenu/DropdownMenuSubMenu.js +43 -14
- package/dist/DropdownMenu/MenuBottomSheet.d.ts +20 -0
- package/dist/DropdownMenu/MenuBottomSheet.d.ts.map +1 -0
- package/dist/DropdownMenu/MenuBottomSheet.js +36 -0
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts +10 -0
- package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -0
- package/dist/DropdownMenu/MenuBottomSheetActionList.js +111 -0
- package/dist/DropdownMenu/index.d.ts +2 -1
- package/dist/DropdownMenu/index.d.ts.map +1 -1
- package/dist/DropdownMenu/menuWidth.d.ts +14 -0
- package/dist/DropdownMenu/menuWidth.d.ts.map +1 -0
- package/dist/DropdownMenu/menuWidth.js +35 -0
- package/dist/DropdownMenu/useMenuOverflow.d.ts +10 -0
- package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -0
- package/dist/DropdownMenu/useMenuOverflow.js +60 -0
- package/dist/MoreMenu/MoreMenu.d.ts +8 -2
- package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
- package/dist/MoreMenu/MoreMenu.js +2 -0
- package/dist/MultiSelector/MultiSelector.d.ts +11 -1
- package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
- package/dist/MultiSelector/MultiSelector.js +97 -68
- package/dist/MultiSelector/index.d.ts +1 -1
- package/dist/MultiSelector/index.d.ts.map +1 -1
- package/dist/Popover/Popover.d.ts +10 -6
- package/dist/Popover/Popover.d.ts.map +1 -1
- package/dist/Popover/Popover.js +141 -16
- package/dist/Popover/usePopover.d.ts +4 -0
- package/dist/Popover/usePopover.d.ts.map +1 -1
- package/dist/Popover/usePopover.js +52 -5
- package/dist/Selector/Selector.d.ts +10 -0
- package/dist/Selector/Selector.d.ts.map +1 -1
- package/dist/Selector/Selector.js +106 -80
- package/dist/Selector/SelectorBottomSheet.d.ts +21 -0
- package/dist/Selector/SelectorBottomSheet.d.ts.map +1 -0
- package/dist/Selector/SelectorBottomSheet.js +83 -0
- package/dist/Selector/index.d.ts +1 -1
- package/dist/Selector/index.d.ts.map +1 -1
- package/dist/Selector/selectorPresentation.stylex.d.ts +16 -0
- package/dist/Selector/selectorPresentation.stylex.d.ts.map +1 -0
- package/dist/Selector/selectorPresentation.stylex.js +21 -0
- package/dist/Selector/useSelectorPresentation.d.ts +32 -0
- package/dist/Selector/useSelectorPresentation.d.ts.map +1 -0
- package/dist/Selector/useSelectorPresentation.js +90 -0
- package/dist/Toast/useToastGesture.d.ts.map +1 -1
- package/dist/Toast/useToastGesture.js +46 -9
- package/dist/astryx.css +19 -1
- package/dist/hooks/useAdaptivePresentation.d.ts +5 -0
- package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -0
- package/dist/hooks/useAdaptivePresentation.js +19 -0
- package/dist/hooks/useFocusReturnVisibility.d.ts +7 -0
- package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -0
- package/dist/hooks/useFocusReturnVisibility.js +35 -0
- package/dist/hooks/useFocusTrap.d.ts.map +1 -1
- package/dist/hooks/useFocusTrap.js +12 -0
- package/dist/i18n/InternationalizationContext.d.ts +2 -0
- package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
- package/dist/i18n/InternationalizationContext.js +3 -1
- package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
- package/dist/i18n/InternationalizationProvider.js +3 -1
- package/dist/i18n/resolve.d.ts +1 -1
- package/dist/i18n/resolve.d.ts.map +1 -1
- package/dist/i18n/resolve.js +37 -38
- package/dist/i18n/useTranslator.d.ts.map +1 -1
- package/dist/i18n/useTranslator.js +2 -3
- package/locales/af-ZA.json +0 -4
- package/locales/ar-SA.json +0 -4
- package/locales/ca-ES.json +0 -4
- package/locales/cs-CZ.json +0 -4
- package/locales/da-DK.json +0 -4
- package/locales/de-DE.json +0 -4
- package/locales/el-GR.json +0 -4
- package/locales/en.json +20 -0
- package/locales/es-ES.json +0 -4
- package/locales/fi-FI.json +0 -4
- package/locales/fr-FR.json +0 -4
- package/locales/he-IL.json +0 -4
- package/locales/hu-HU.json +0 -4
- package/locales/it-IT.json +0 -4
- package/locales/ja-JP.json +0 -4
- package/locales/ko-KR.json +0 -4
- package/locales/nl-NL.json +0 -4
- package/locales/no-NO.json +0 -4
- package/locales/pl-PL.json +0 -4
- package/locales/pseudo.json +15 -0
- package/locales/pt-BR.json +0 -4
- package/locales/pt-PT.json +0 -4
- package/locales/ro-RO.json +0 -4
- package/locales/ru-RU.json +0 -4
- package/locales/sr-SP.json +0 -4
- package/locales/sv-SE.json +0 -4
- package/locales/tr-TR.json +0 -4
- package/locales/uk-UA.json +0 -4
- package/locales/vi-VN.json +0 -4
- package/locales/zh-CN.json +0 -4
- package/locales/zh-TW.json +0 -4
- package/package.json +3 -3
- package/src/BottomSheet/BottomSheet.doc.mjs +37 -0
- package/src/BottomSheet/BottomSheet.spec.md +177 -0
- package/src/BottomSheet/BottomSheet.test.tsx +29 -0
- package/src/BottomSheet/BottomSheet.tsx +7 -4
- package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +4 -6
- package/src/BottomSheet/BottomSheetEdgeTint.tsx +7 -10
- package/src/BottomSheet/BottomSheetSwitcher.tsx +1 -2
- package/src/Button/Button.doc.mjs +56 -0
- package/src/Button/Button.test.tsx +10 -0
- package/src/Button/Button.tsx +13 -5
- package/src/ButtonGroup/ButtonGroup.doc.mjs +47 -0
- package/src/Calendar/Calendar.doc.mjs +1 -1
- package/src/Carousel/Carousel.test.tsx +83 -0
- package/src/Carousel/Carousel.tsx +8 -2
- package/src/Chat/ChatToolCalls.test.tsx +44 -0
- package/src/Chat/ChatToolCalls.tsx +36 -15
- package/src/CheckboxInput/CheckboxInput.doc.mjs +1 -1
- package/src/CheckboxList/CheckboxList.doc.mjs +173 -32
- package/src/CheckboxList/CheckboxList.spec.md +214 -0
- package/src/CommandPalette/CommandPalette.doc.mjs +72 -0
- package/src/CommandPalette/CommandPalette.spec.md +223 -0
- package/src/ComplexSelector/ComplexSelector.doc.mjs +44 -2
- package/src/ComplexSelector/ComplexSelector.spec.md +189 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +13 -1
- package/src/ContextMenu/ContextMenu.test.tsx +131 -1
- package/src/ContextMenu/ContextMenu.tsx +199 -32
- package/src/ContextMenu/index.ts +1 -0
- package/src/DateInput/DateInput.doc.mjs +1 -1
- package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
- package/src/DateTimeInput/DateTimeInput.doc.mjs +1 -1
- package/src/Divider/Divider.doc.mjs +24 -0
- package/src/Divider/Divider.spec.md +150 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +201 -40
- package/src/DropdownMenu/DropdownMenu.test.tsx +518 -7
- package/src/DropdownMenu/DropdownMenu.tsx +459 -28
- package/src/DropdownMenu/DropdownMenuContext.tsx +1 -1
- package/src/DropdownMenu/DropdownMenuItem.tsx +2 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +4 -2
- package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +124 -0
- package/src/DropdownMenu/DropdownMenuSubMenu.tsx +72 -17
- package/src/DropdownMenu/MenuBottomSheet.tsx +46 -0
- package/src/DropdownMenu/MenuBottomSheetActionList.tsx +141 -0
- package/src/DropdownMenu/index.ts +2 -0
- package/src/DropdownMenu/menuWidth.ts +51 -0
- package/src/DropdownMenu/useMenuOverflow.ts +77 -0
- package/src/Field/Field.doc.mjs +1 -1
- package/src/FieldStatus/FieldStatus.doc.mjs +22 -1
- package/src/FieldStatus/FieldStatus.spec.md +212 -0
- package/src/FileInput/FileInput.doc.mjs +1 -1
- package/src/Grid/Grid.doc.mjs +19 -0
- package/src/Grid/Grid.spec.md +161 -0
- package/src/Icon/Icon.doc.mjs +196 -48
- package/src/Icon/Icon.spec.md +191 -0
- package/src/IconButton/IconButton.doc.mjs +38 -0
- package/src/Indicator/Indicator.doc.mjs +1 -1
- package/src/InputGroup/InputGroup.doc.mjs +1 -1
- package/src/Kbd/Kbd.doc.mjs +18 -0
- package/src/Kbd/Kbd.spec.md +141 -0
- package/src/Layout/Layout.doc.mjs +32 -0
- package/src/Layout/Layout.spec.md +199 -0
- package/src/Lightbox/Lightbox.doc.mjs +149 -33
- package/src/Lightbox/Lightbox.spec.md +197 -0
- package/src/Markdown/Markdown.doc.mjs +60 -0
- package/src/Markdown/Markdown.spec.md +200 -0
- package/src/MobileNav/MobileNav.doc.mjs +140 -32
- package/src/MobileNav/MobileNav.spec.md +208 -0
- package/src/MoreMenu/MoreMenu.doc.mjs +17 -0
- package/src/MoreMenu/MoreMenu.test.tsx +47 -0
- package/src/MoreMenu/MoreMenu.tsx +13 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +129 -1
- package/src/MultiSelector/MultiSelector.spec.md +266 -0
- package/src/MultiSelector/MultiSelector.test.tsx +127 -0
- package/src/MultiSelector/MultiSelector.tsx +121 -73
- package/src/MultiSelector/index.ts +1 -0
- package/src/NavIcon/NavIcon.doc.mjs +17 -0
- package/src/NavIcon/NavIcon.spec.md +133 -0
- package/src/NavMenu/NavHeadingMenu.spec.md +205 -0
- package/src/NavMenu/NavMenu.doc.mjs +37 -0
- package/src/NumberInput/NumberInput.doc.mjs +1 -1
- package/src/Outline/Outline.doc.mjs +35 -0
- package/src/Outline/Outline.spec.md +161 -0
- package/src/OverflowList/OverflowList.doc.mjs +24 -0
- package/src/OverflowList/OverflowList.spec.md +156 -0
- package/src/Pagination/Pagination.doc.mjs +74 -0
- package/src/Pagination/Pagination.spec.md +225 -0
- package/src/Popover/Popover.doc.mjs +11 -11
- package/src/Popover/Popover.test.tsx +397 -2
- package/src/Popover/Popover.tsx +228 -21
- package/src/Popover/usePopover.tsx +92 -15
- package/src/PowerSearch/PowerSearch.doc.mjs +1 -1
- package/src/ProgressBar/ProgressBar.doc.mjs +198 -38
- package/src/ProgressBar/ProgressBar.spec.md +260 -0
- package/src/RadioList/RadioList.doc.mjs +1 -1
- package/src/Resizable/Resizable.doc.mjs +59 -16
- package/src/Resizable/Resizable.spec.md +194 -0
- package/src/Section/Section.doc.mjs +17 -0
- package/src/Section/Section.spec.md +138 -0
- package/src/SegmentedControl/SegmentedControl.doc.mjs +83 -0
- package/src/SegmentedControl/SegmentedControl.spec.md +151 -0
- package/src/Selector/Selector.doc.mjs +13 -1
- package/src/Selector/Selector.test.tsx +135 -0
- package/src/Selector/Selector.tsx +141 -82
- package/src/Selector/SelectorBottomSheet.tsx +97 -0
- package/src/Selector/index.ts +1 -0
- package/src/Selector/selectorPresentation.stylex.ts +20 -0
- package/src/Selector/useSelectorPresentation.ts +147 -0
- package/src/Skeleton/Skeleton.doc.mjs +12 -0
- package/src/Skeleton/Skeleton.spec.md +126 -0
- package/src/Slider/Slider.doc.mjs +186 -32
- package/src/Slider/Slider.spec.md +223 -0
- package/src/Stack/Stack.doc.mjs +22 -0
- package/src/Stack/Stack.spec.md +154 -0
- package/src/StatusDot/StatusDot.doc.mjs +17 -0
- package/src/StatusDot/StatusDot.spec.md +137 -0
- package/src/Switch/Switch.doc.mjs +41 -1
- package/src/Switch/Switch.spec.md +174 -0
- package/src/Text/Text.doc.mjs +190 -43
- package/src/Text/Text.spec.md +205 -0
- package/src/TextArea/TextArea.doc.mjs +256 -46
- package/src/TextArea/TextArea.spec.md +204 -0
- package/src/TextInput/TextInput.doc.mjs +1 -1
- package/src/TimeInput/TimeInput.doc.mjs +1 -1
- package/src/Toast/ToastViewport.test.tsx +118 -4
- package/src/Toast/useToastGesture.ts +61 -8
- package/src/ToggleButton/ToggleButton.doc.mjs +56 -0
- package/src/Tokenizer/Tokenizer.doc.mjs +1 -1
- package/src/Toolbar/Toolbar.doc.mjs +19 -0
- package/src/Toolbar/Toolbar.spec.md +173 -0
- package/src/Tooltip/Tooltip.doc.mjs +17 -0
- package/src/Tooltip/Tooltip.spec.md +141 -0
- package/src/TreeList/TreeList.doc.mjs +58 -0
- package/src/TreeList/TreeList.spec.md +220 -0
- package/src/Typeahead/Typeahead.doc.mjs +84 -2
- package/src/Typeahead/Typeahead.spec.md +250 -0
- package/src/hooks/useAdaptivePresentation.ts +35 -0
- package/src/hooks/useFocusReturnVisibility.ts +45 -0
- package/src/hooks/useFocusTrap.test.tsx +40 -0
- package/src/hooks/useFocusTrap.ts +13 -0
- package/src/i18n/InternationalizationContext.ts +3 -0
- package/src/i18n/InternationalizationProvider.tsx +8 -1
- package/src/i18n/__tests__/resolve.test.ts +23 -1
- package/src/i18n/resolve.ts +46 -49
- package/src/i18n/useTranslator.ts +2 -7
- 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: '
|
|
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: '
|
|
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: [
|