@astryxdesign/core 0.5.2-canary.c9c8564 → 0.5.2-canary.e03511b
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/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/locales/en.json +20 -0
- package/locales/pseudo.json +15 -0
- package/package.json +2 -2
- 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/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/CheckboxList/CheckboxList.doc.mjs +172 -31
- 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 +42 -0
- package/src/ComplexSelector/ComplexSelector.spec.md +189 -0
- package/src/ContextMenu/ContextMenu.doc.mjs +61 -1
- package/src/ContextMenu/ContextMenu.spec.md +206 -0
- package/src/ContextMenu/ContextMenu.test.tsx +131 -1
- package/src/ContextMenu/ContextMenu.tsx +199 -32
- package/src/ContextMenu/index.ts +1 -0
- package/src/Divider/Divider.doc.mjs +24 -0
- package/src/Divider/Divider.spec.md +150 -0
- package/src/DropdownMenu/DropdownMenu.doc.mjs +305 -40
- package/src/DropdownMenu/DropdownMenu.spec.md +245 -0
- 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/FieldStatus/FieldStatus.doc.mjs +21 -0
- package/src/FieldStatus/FieldStatus.spec.md +212 -0
- 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/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 +59 -0
- package/src/MoreMenu/MoreMenu.spec.md +221 -0
- package/src/MoreMenu/MoreMenu.test.tsx +47 -0
- package/src/MoreMenu/MoreMenu.tsx +13 -1
- package/src/MultiSelector/MultiSelector.doc.mjs +128 -0
- 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/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/ProgressBar/ProgressBar.doc.mjs +198 -38
- package/src/ProgressBar/ProgressBar.spec.md +260 -0
- 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 +12 -0
- package/src/Selector/Selector.spec.md +202 -0
- 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 +184 -30
- 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 +40 -0
- package/src/Switch/Switch.spec.md +174 -0
- package/src/Table/Table.doc.mjs +102 -24
- package/src/Table/Table.spec.md +283 -0
- package/src/Text/Text.doc.mjs +190 -43
- package/src/Text/Text.spec.md +205 -0
- package/src/TextArea/TextArea.doc.mjs +255 -45
- package/src/TextArea/TextArea.spec.md +204 -0
- 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/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 +83 -1
- 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/theme/themingTargets.test.ts +91 -25
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1
|
|
3
|
+
template_version: 3
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:Switch
|
|
6
|
+
authority: draft
|
|
7
|
+
archive_reason: null
|
|
8
|
+
superseded_by: null
|
|
9
|
+
approved_by: null
|
|
10
|
+
approved_at: null
|
|
11
|
+
owners: [cixzhang]
|
|
12
|
+
review_triggers: [theming]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/Switch/Switch.test.tsx,
|
|
16
|
+
packages/core/src/theme/themingTargets.test.ts,
|
|
17
|
+
scripts/check-knowledge.mjs,
|
|
18
|
+
]
|
|
19
|
+
families: []
|
|
20
|
+
design_specs: []
|
|
21
|
+
architecture: [architecture:component-theming-surface]
|
|
22
|
+
contributing: []
|
|
23
|
+
system_specs: []
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
# Switch component contract
|
|
27
|
+
|
|
28
|
+
## Intent
|
|
29
|
+
|
|
30
|
+
Switch presents a labeled boolean control whose change takes effect immediately.
|
|
31
|
+
This draft records current consumer anatomy and theming ownership without
|
|
32
|
+
changing runtime behavior, styling, targets, or public API.
|
|
33
|
+
|
|
34
|
+
## Compatibility and migration
|
|
35
|
+
|
|
36
|
+
- Released default preserved: `yes`
|
|
37
|
+
- Compatibility class: additive documentation only; runtime, DOM, styling,
|
|
38
|
+
targets, and public API remain unchanged
|
|
39
|
+
- Controlled/uncontrolled behavior: unchanged; Switch remains controlled
|
|
40
|
+
- Migration decision: none
|
|
41
|
+
|
|
42
|
+
Consumer migration instructions belong in consumer docs and release notes.
|
|
43
|
+
|
|
44
|
+
## Ownership boundary
|
|
45
|
+
|
|
46
|
+
**Owns**
|
|
47
|
+
|
|
48
|
+
- The switch field, track, thumb, and label presentations represented by the
|
|
49
|
+
existing `switch-field`, `switch`, `switch-thumb`, and `switch-label` targets.
|
|
50
|
+
|
|
51
|
+
**Does not own / non-goals**
|
|
52
|
+
|
|
53
|
+
- Description styling through a dedicated public target; none currently exists.
|
|
54
|
+
- Validation-message presentation — owned by `component:FieldStatus`.
|
|
55
|
+
- Loading-indicator presentation — owned by `component:Spinner`.
|
|
56
|
+
- Tooltip surfaces used for shared label and disabled-reason behavior.
|
|
57
|
+
|
|
58
|
+
## Public concepts
|
|
59
|
+
|
|
60
|
+
No new public concept is introduced. Consumer props, states, and usage remain
|
|
61
|
+
documented in `Switch.doc.mjs`.
|
|
62
|
+
|
|
63
|
+
## Behavioral and layout contract
|
|
64
|
+
|
|
65
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
66
|
+
| --- | ------------------------------------------------------------------------------------------------------ | --------------------------------------- | -------------------------------------------------- |
|
|
67
|
+
| FR1 | The current render places a thumb inside the switch track and arranges that control with its label. | Current source, docs, and focused tests | Verified current behavior; no new behavior decided |
|
|
68
|
+
| FR2 | The field, track, thumb, and label carry their existing local targets. | Current source, public docs, and tests | Verified current behavior; no target change |
|
|
69
|
+
| FR3 | A busy switch renders Spinner inside the thumb; a status message renders through detached FieldStatus. | Current source, docs, and focused tests | Verified conditional composition |
|
|
70
|
+
|
|
71
|
+
### Allowed variation
|
|
72
|
+
|
|
73
|
+
- Label position and spacing, size, checked state, and disabled state remain
|
|
74
|
+
current target capabilities rather than separate anatomy parts.
|
|
75
|
+
- A description may be absent without changing the remaining anatomy.
|
|
76
|
+
|
|
77
|
+
### Representative states
|
|
78
|
+
|
|
79
|
+
| State | Required invariant | Allowed variation |
|
|
80
|
+
| ------------------- | ------------------------------------------------------- | -------------------------------------- |
|
|
81
|
+
| Off or on | Track, thumb, and label render within the switch field. | Checked state, size, label placement |
|
|
82
|
+
| Busy | Spinner renders inside the thumb. | Controlled or optimistic checked value |
|
|
83
|
+
| Status with message | Detached FieldStatus follows the switch row. | Error, warning, or success status |
|
|
84
|
+
|
|
85
|
+
### Transformation and precedence order
|
|
86
|
+
|
|
87
|
+
- No new state, event, layout, or styling precedence rule is introduced.
|
|
88
|
+
|
|
89
|
+
### Performance and resources
|
|
90
|
+
|
|
91
|
+
- No new performance or resource rule is introduced.
|
|
92
|
+
|
|
93
|
+
## Accessibility contract
|
|
94
|
+
|
|
95
|
+
This draft does not change or extend Switch's existing accessible name, switch
|
|
96
|
+
role, checked state, busy state, description/status association, or disabled
|
|
97
|
+
behavior.
|
|
98
|
+
|
|
99
|
+
## Design relationships
|
|
100
|
+
|
|
101
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
102
|
+
| ---------------- | -------------------------------------------------------- | ------------------------------- | -------------- | ------------------ |
|
|
103
|
+
| Field | Arranges the switch control with its label and feedback. | Current source and public docs | Supporting | FR1, FR2 |
|
|
104
|
+
| Track and thumb | Present the current on/off control. | Current source and public docs | Prominent | FR1, FR2 |
|
|
105
|
+
| Label | Identifies the controlled setting. | Current source and public docs | Prominent | FR1, FR2 |
|
|
106
|
+
| Spinner/status | Present conditional progress and validation feedback. | Current shared-component source | Supporting | FR3 |
|
|
107
|
+
|
|
108
|
+
### Theming anatomy
|
|
109
|
+
|
|
110
|
+
<!-- anatomy-theming:v1 -->
|
|
111
|
+
|
|
112
|
+
```json
|
|
113
|
+
{
|
|
114
|
+
"Field": {"target": "switch-field"},
|
|
115
|
+
"Track": {"target": "switch"},
|
|
116
|
+
"Thumb": {"target": "switch-thumb"},
|
|
117
|
+
"Label": {"target": "switch-label"},
|
|
118
|
+
"Description": {
|
|
119
|
+
"none": {
|
|
120
|
+
"reason": "unsettled: No current public target reaches the stable Description; future exposure still needs an owner decision"
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
"Spinner": {
|
|
124
|
+
"delegatesTo": {"owner": "component:Spinner", "target": "spinner"}
|
|
125
|
+
},
|
|
126
|
+
"Status message": {
|
|
127
|
+
"delegatesTo": {
|
|
128
|
+
"owner": "component:FieldStatus",
|
|
129
|
+
"target": "field-status"
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
`Description` remains stable consumer anatomy, but no current public target
|
|
136
|
+
reaches it. The map classifies future exposure as unsettled rather than silently
|
|
137
|
+
making the absence intentional.
|
|
138
|
+
|
|
139
|
+
## Family and system relationships
|
|
140
|
+
|
|
141
|
+
- `architecture:component-theming-surface` owns anatomy qualification, factual
|
|
142
|
+
`none` dispositions, and composition-preserving target ownership.
|
|
143
|
+
- FieldStatus and Spinner retain their existing public target contracts when
|
|
144
|
+
composed by Switch.
|
|
145
|
+
|
|
146
|
+
## Verification map
|
|
147
|
+
|
|
148
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
149
|
+
| ------------------- | ----------------------------------------------------------------- | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------- | ---------------------- |
|
|
150
|
+
| FR1 | `Switch.test.tsx` structure and interaction suites | On/off, size, label position, hidden label | Removing or reordering stable parts breaks existing role, label, or DOM assertions. | `audit:Switch/anatomy` |
|
|
151
|
+
| FR2 | `Switch.test.tsx` label-target suite and `themingTargets.test.ts` | Current local targets | Removing the label target fails focused coverage; source/docs drift fails the target guard. | `audit:Switch/theming` |
|
|
152
|
+
| FR3 | `Switch.test.tsx` loading and status suites | Busy and detached status | Removing composed feedback breaks existing spinner, busy-state, or message assertions. | `audit:Switch/anatomy` |
|
|
153
|
+
| Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and all current targets | Canonical-key drift, invalid dispositions or target spelling, or an unclaimed current local target fails repository validation. | `audit:Switch/theming` |
|
|
154
|
+
|
|
155
|
+
The focused Switch suite pins `switch-label`, but does not separately assert the
|
|
156
|
+
exact `switch-field`, `switch`, or `switch-thumb` class placement. The
|
|
157
|
+
source/metadata target guard covers those local declarations. No current
|
|
158
|
+
repository check resolves `delegatesTo` owner/target pairs; the pairs in this
|
|
159
|
+
draft were verified manually, so semantic delegation drift remains a validation
|
|
160
|
+
gap.
|
|
161
|
+
|
|
162
|
+
## Decision log
|
|
163
|
+
|
|
164
|
+
None. This draft records current facts and introduces no component-local design
|
|
165
|
+
or API decision.
|
|
166
|
+
|
|
167
|
+
## Open questions
|
|
168
|
+
|
|
169
|
+
None.
|
|
170
|
+
|
|
171
|
+
## Content boundary
|
|
172
|
+
|
|
173
|
+
This file does not duplicate consumer prop tables, examples, implementation
|
|
174
|
+
steps, or shared-component contracts. It links to their owners.
|
package/src/Table/Table.doc.mjs
CHANGED
|
@@ -1,5 +1,104 @@
|
|
|
1
1
|
// Copyright (c) Meta Platforms, Inc. and affiliates.
|
|
2
2
|
|
|
3
|
+
/** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
|
|
4
|
+
const anatomy = [
|
|
5
|
+
{
|
|
6
|
+
name: 'Table',
|
|
7
|
+
required: true,
|
|
8
|
+
description:
|
|
9
|
+
'Semantic table element that groups the table sections, rows, and cells.',
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'Scroll region',
|
|
13
|
+
required: true,
|
|
14
|
+
description:
|
|
15
|
+
'Keyboard-focusable outer region that scrolls horizontally when the columns overflow.',
|
|
16
|
+
},
|
|
17
|
+
{
|
|
18
|
+
name: 'Header section',
|
|
19
|
+
required: false,
|
|
20
|
+
description:
|
|
21
|
+
'Column-heading section generated when data-driven columns are present or supplied with TableHeader in children mode.',
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'Column header cell',
|
|
25
|
+
required: false,
|
|
26
|
+
description:
|
|
27
|
+
'Cell that identifies one column and may contain sorting or bulk-selection controls.',
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
name: 'Sort control',
|
|
31
|
+
required: false,
|
|
32
|
+
description:
|
|
33
|
+
"Button that wraps a sortable column label and changes that column's sort direction.",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: 'Sort indicator glyph',
|
|
37
|
+
required: false,
|
|
38
|
+
description: 'Directional symbol rendered by Icon inside a Sort control.',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: 'Sort priority',
|
|
42
|
+
required: false,
|
|
43
|
+
description:
|
|
44
|
+
'Number shown for a sorted column when multi-column sorting is active.',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: 'Selection control',
|
|
48
|
+
required: false,
|
|
49
|
+
description:
|
|
50
|
+
'CheckboxInput rendered in the header and selectable body rows by the selection plugin.',
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: 'Body section',
|
|
54
|
+
required: true,
|
|
55
|
+
description:
|
|
56
|
+
'Section containing data rows or the current empty state; data-driven mode renders it automatically.',
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: 'Row',
|
|
60
|
+
required: false,
|
|
61
|
+
description:
|
|
62
|
+
'Repeated TableRow that groups cells in a standard header, body, or footer row.',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
name: 'Cell',
|
|
66
|
+
required: false,
|
|
67
|
+
description:
|
|
68
|
+
'TableCell containing one value or caller-provided content in a standard body or footer row.',
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
name: 'Default empty state',
|
|
72
|
+
required: false,
|
|
73
|
+
description:
|
|
74
|
+
'Compact EmptyState shown for an empty data array unless it is replaced or disabled.',
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'Expansion control',
|
|
78
|
+
required: false,
|
|
79
|
+
description:
|
|
80
|
+
'Button in a leading cell that expands or collapses one expandable row.',
|
|
81
|
+
},
|
|
82
|
+
{
|
|
83
|
+
name: 'Expansion glyph',
|
|
84
|
+
required: false,
|
|
85
|
+
description:
|
|
86
|
+
'Directional symbol rendered by Icon inside an Expansion control.',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: 'Expanded detail panel',
|
|
90
|
+
required: false,
|
|
91
|
+
description:
|
|
92
|
+
'Detail row and spanning cell rendered below an expanded row around caller-provided content.',
|
|
93
|
+
},
|
|
94
|
+
{
|
|
95
|
+
name: 'Footer section',
|
|
96
|
+
required: false,
|
|
97
|
+
description:
|
|
98
|
+
'Optional summary or totals section supplied with TableFooter in children mode.',
|
|
99
|
+
},
|
|
100
|
+
];
|
|
101
|
+
|
|
3
102
|
/** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
|
|
4
103
|
|
|
5
104
|
export const docs = {
|
|
@@ -147,14 +246,7 @@ export const docs = {
|
|
|
147
246
|
{ guidance: false, description: 'Enable every plugin at once. Add only the features your use case requires to keep the interface focused.' },
|
|
148
247
|
{ guidance: false, description: 'Omit width on text-heavy columns; without an explicit proportional() width they have no minimum and can squish to near-zero on mobile.' },
|
|
149
248
|
],
|
|
150
|
-
anatomy
|
|
151
|
-
{name: 'Column Header', required: true, description: 'Displays titles, sorting controls, and bulk selection.'},
|
|
152
|
-
{name: 'Body Rows', required: true, description: 'Rows with consistent data structure.'},
|
|
153
|
-
{name: 'Footer', required: false, description: 'Displays summary or totals.'},
|
|
154
|
-
{name: 'Top Bar', required: false, description: 'Contains title, toolbar, and filters.'},
|
|
155
|
-
{name: 'Bottom Bar', required: false, description: 'Contains pagination controls.'},
|
|
156
|
-
{name: 'Support Panels', required: false, description: 'Displays row details in a side panel.'},
|
|
157
|
-
],
|
|
249
|
+
anatomy,
|
|
158
250
|
},
|
|
159
251
|
};
|
|
160
252
|
|
|
@@ -169,14 +261,7 @@ export const docsZh = {
|
|
|
169
261
|
{ guidance: false, description: 'Use a table for data without consistent columns. Use a list or card layout for heterogeneous content.' },
|
|
170
262
|
{ guidance: false, description: 'Enable every plugin at once. Add only the features your use case requires to keep the interface focused.' },
|
|
171
263
|
],
|
|
172
|
-
anatomy
|
|
173
|
-
{name: 'Column Header', required: true, description: 'Displays titles, sorting controls, and bulk selection.'},
|
|
174
|
-
{name: 'Body Rows', required: true, description: 'Rows with consistent data structure.'},
|
|
175
|
-
{name: 'Footer', required: false, description: 'Displays summary or totals.'},
|
|
176
|
-
{name: 'Top Bar', required: false, description: 'Contains title, toolbar, and filters.'},
|
|
177
|
-
{name: 'Bottom Bar', required: false, description: 'Contains pagination controls.'},
|
|
178
|
-
{name: 'Support Panels', required: false, description: 'Displays row details in a side panel.'},
|
|
179
|
-
],
|
|
264
|
+
anatomy,
|
|
180
265
|
},
|
|
181
266
|
};
|
|
182
267
|
|
|
@@ -196,13 +281,6 @@ export const docsDense = {
|
|
|
196
281
|
{ guidance: false, description: 'Enable every plugin at once. Add only the features your use case requires to keep the interface focused.' },
|
|
197
282
|
{ guidance: false, description: 'Omit width on text-heavy columns; w/o explicit proportional() width they have no minimum and can squish to near-zero on mobile.' },
|
|
198
283
|
],
|
|
199
|
-
anatomy
|
|
200
|
-
{name: 'Column Header', required: true, description: 'Displays titles, sorting controls, and bulk selection.'},
|
|
201
|
-
{name: 'Body Rows', required: true, description: 'Rows with consistent data structure.'},
|
|
202
|
-
{name: 'Footer', required: false, description: 'Displays summary or totals.'},
|
|
203
|
-
{name: 'Top Bar', required: false, description: 'Contains title, toolbar, and filters.'},
|
|
204
|
-
{name: 'Bottom Bar', required: false, description: 'Contains pagination controls.'},
|
|
205
|
-
{name: 'Support Panels', required: false, description: 'Displays row details in a side panel.'},
|
|
206
|
-
],
|
|
284
|
+
anatomy,
|
|
207
285
|
},
|
|
208
286
|
};
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
---
|
|
2
|
+
schema_version: 1
|
|
3
|
+
template_version: 3
|
|
4
|
+
kind: component
|
|
5
|
+
id: component:Table
|
|
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: [public-api, behavior, layout, theming, accessibility]
|
|
13
|
+
verified_by:
|
|
14
|
+
[
|
|
15
|
+
packages/core/src/Table/Table.test.tsx,
|
|
16
|
+
packages/core/src/Table/plugins/selection/useTableSelection.test.tsx,
|
|
17
|
+
packages/core/src/Table/plugins/sortable/useTableSortable.test.tsx,
|
|
18
|
+
packages/core/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx,
|
|
19
|
+
packages/cli/foundation/discovery/theming-targets.test.mjs,
|
|
20
|
+
packages/cli/api/theme/targets/targets.test.mjs,
|
|
21
|
+
packages/core/src/theme/themingTargets.test.ts,
|
|
22
|
+
scripts/check-knowledge.mjs,
|
|
23
|
+
]
|
|
24
|
+
families: []
|
|
25
|
+
design_specs: []
|
|
26
|
+
architecture:
|
|
27
|
+
[
|
|
28
|
+
architecture:component-theming-surface,
|
|
29
|
+
architecture:container-padding,
|
|
30
|
+
architecture:interaction-modality,
|
|
31
|
+
architecture:public-component-api,
|
|
32
|
+
]
|
|
33
|
+
contributing: []
|
|
34
|
+
system_specs: []
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
# Table component contract
|
|
38
|
+
|
|
39
|
+
## Intent
|
|
40
|
+
|
|
41
|
+
Table presents consistently structured data in semantic rows and columns. This
|
|
42
|
+
draft records its current aggregate anatomy, parent-owned target inventory, and
|
|
43
|
+
stable sorting, selection, expansion, and empty-state parts without changing
|
|
44
|
+
runtime behavior, DOM, styling, targets, aliases, or public API.
|
|
45
|
+
|
|
46
|
+
## Compatibility and migration
|
|
47
|
+
|
|
48
|
+
- Released default preserved: `yes`
|
|
49
|
+
- Compatibility class: additive documentation only; runtime, DOM, styling,
|
|
50
|
+
targets, aliases, and public API remain unchanged
|
|
51
|
+
- Controlled/uncontrolled behavior: unchanged
|
|
52
|
+
- Migration decision: none
|
|
53
|
+
|
|
54
|
+
Consumer migration instructions belong in consumer docs and release notes.
|
|
55
|
+
|
|
56
|
+
## Ownership boundary
|
|
57
|
+
|
|
58
|
+
**Owns**
|
|
59
|
+
|
|
60
|
+
- The Table and Scroll region, the aggregate Header section, Body section,
|
|
61
|
+
conditional Footer section, Row, Column header cell, and Cell anatomy, and the
|
|
62
|
+
eight current `table*` targets mapped below.
|
|
63
|
+
- The stable Sort control and Sort priority rendered by useTableSortable.
|
|
64
|
+
- The stable Expansion control and Expanded detail panel rendered by
|
|
65
|
+
useTableRowExpansion.
|
|
66
|
+
- Placement of selection-plugin CheckboxInput controls in generated header and
|
|
67
|
+
body cells.
|
|
68
|
+
|
|
69
|
+
**Does not own / non-goals**
|
|
70
|
+
|
|
71
|
+
- CheckboxInput visuals, Icon glyphs, or the default EmptyState surface; those
|
|
72
|
+
remain owned by their respective components.
|
|
73
|
+
- Cell values, custom cell renderers, custom empty states, footer content, or
|
|
74
|
+
expanded detail content supplied by the caller.
|
|
75
|
+
- Pagination, filtering, column-management, tree, grouping, sticky-column, or
|
|
76
|
+
context-menu anatomy beyond the stable parts explicitly recorded here.
|
|
77
|
+
- New targets for current untargeted plugin parts, or correction of current
|
|
78
|
+
target-reachability gaps.
|
|
79
|
+
- New runtime behavior, DOM, API, target, alias, or plugin contract.
|
|
80
|
+
|
|
81
|
+
## Public concepts
|
|
82
|
+
|
|
83
|
+
No new public concept is introduced. Consumer data, columns, props, composition,
|
|
84
|
+
plugins, defaults, and usage remain documented in `Table.doc.mjs` and the member
|
|
85
|
+
and hook docs.
|
|
86
|
+
|
|
87
|
+
## Behavioral and layout contract
|
|
88
|
+
|
|
89
|
+
| ID | Candidate invariant | Basis | Draft review state |
|
|
90
|
+
| --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------- | ------------------------------------------------------------------------- |
|
|
91
|
+
| FR1 | Styled Table renders one keyboard-focusable Scroll region around one semantic Table. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
|
|
92
|
+
| FR2 | Data-driven mode renders a Body section and a Header section with Column header cells when columns are present. Each data item renders a standard Row and Cells; an empty data array instead renders the configured empty-state row when enabled. It never creates a Footer section. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
|
|
93
|
+
| FR3 | Children mode passes caller composition through to the Table. TableHeader, TableBody, and TableFooter provide the respective sections, and TableRow, TableHeaderCell, and TableCell provide standard rows and cells. | Current source, docs, and tests | Verified current composition; no new API or DOM rule |
|
|
94
|
+
| FR4 | `Table.doc.mjs` is the canonical aggregate consumer owner for the eight current targets: `table`, `table-scroll-wrapper`, `table-header`, `table-body`, `table-footer`, `table-row`, `table-cell`, and `table-header-cell`. Member docs retain direct lookup metadata through `subComponentOf: 'Table'`. | Current docs and CLI target tests | Verified parent ownership; focused placement coverage is partial |
|
|
95
|
+
| FR5 | For a sortable column, useTableSortable renders a Sort control around the column label, an Icon-owned Sort indicator glyph, and a numeric Sort priority only while multi-sort has more than one active entry. | Current source, docs, and tests | Control and priority are tested; glyph presence is source-inspected only |
|
|
96
|
+
| FR6 | useTableSelection renders CheckboxInput-owned Selection controls in the generated selection Column header cell and each selectable body Cell; selection remains row state rather than separate anatomy. | Current source, docs, and tests | Verified stable delegated controls; no target or state change |
|
|
97
|
+
| FR7 | For an expandable row, useTableRowExpansion renders an Expansion control with an Icon-owned Expansion glyph and conditionally appends an Expanded detail panel whose cell spans the column count captured by that plugin's `transformColumns` step. | Current source, docs, and tests | Verified stable plugin parts; current target gaps remain |
|
|
98
|
+
| FR8 | Empty data renders the default compact EmptyState unless the caller supplies replacement content or disables it. | Current source, docs, and tests | Verified conditional delegation; caller content remains outside ownership |
|
|
99
|
+
|
|
100
|
+
### Current evidence and gaps
|
|
101
|
+
|
|
102
|
+
- The `table`, `table-scroll-wrapper`, `table-row`, `table-cell`, and
|
|
103
|
+
`table-header-cell` placements have focused runtime assertions. The
|
|
104
|
+
`table-header`, `table-body`, and `table-footer` placements are source-inspected;
|
|
105
|
+
existing section tests assert element structure and prop forwarding but not the
|
|
106
|
+
target classes.
|
|
107
|
+
- Sort tests assert the Sort control, labels, state, and conditional priority, but
|
|
108
|
+
the test named `renders sort icon for sortable columns` checks only the buttons.
|
|
109
|
+
Sort indicator glyph presence is source-inspected and lacks focused regression
|
|
110
|
+
evidence. Selection and expansion suites assert their stable controls, states,
|
|
111
|
+
and panel structure; delegated Icon and CheckboxInput target classes also remain
|
|
112
|
+
source-inspected.
|
|
113
|
+
- The Expanded detail panel uses raw `tr` and `td` elements rather than TableRow
|
|
114
|
+
and TableCell, so the existing `table-row` and `table-cell` targets do not reach
|
|
115
|
+
that panel wrapper. Its `colSpan` comes from the column count captured when the
|
|
116
|
+
expansion plugin runs `transformColumns`; a later custom plugin can add or remove
|
|
117
|
+
columns and leave the span stale. The current full-span test covers only the case
|
|
118
|
+
where expansion captures the final column set. This draft records both gaps and
|
|
119
|
+
does not correct them.
|
|
120
|
+
|
|
121
|
+
### Allowed variation
|
|
122
|
+
|
|
123
|
+
- **AV1 - Rendering mode.** Data-driven mode generates sections, rows, and cells;
|
|
124
|
+
children mode uses the caller-supplied composition without changing aggregate
|
|
125
|
+
ownership.
|
|
126
|
+
- **AV2 - Repetition and content.** Column, Row, and Cell counts and caller-owned
|
|
127
|
+
content may vary without creating new anatomy parts.
|
|
128
|
+
- **AV3 - Optional parts.** Header section, Footer section, default EmptyState,
|
|
129
|
+
Sort, Selection, and Expansion parts may be absent according to columns,
|
|
130
|
+
rendering mode, plugin configuration, data, and row eligibility.
|
|
131
|
+
- **AV4 - Delegated rendering.** CheckboxInput, Icon, and EmptyState may change
|
|
132
|
+
internal element shape while preserving their own public contracts.
|
|
133
|
+
|
|
134
|
+
### Representative states
|
|
135
|
+
|
|
136
|
+
| State | Required invariant | Allowed variation |
|
|
137
|
+
| ---------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- |
|
|
138
|
+
| Data-driven rows | Scroll region contains Table, Header section when columns exist, Body section, and one standard Row with Cells per data item. | Counts, values, density, dividers, and cell content. |
|
|
139
|
+
| Empty data | Body section contains default EmptyState unless replaced or disabled. | Caller replacement content or no empty state. |
|
|
140
|
+
| Children mode | Caller-supplied sections are passed directly to Table. | Header, Body, and Footer section presence and content. |
|
|
141
|
+
| Sortable column | Column header cell contains Sort control and Sort indicator glyph. | Direction and conditional multi-sort priority. |
|
|
142
|
+
| Selectable rows | Selection controls occupy generated header and body cells. | Checked, indeterminate, disabled, or absent per row. |
|
|
143
|
+
| Expandable row | Expansion control occupies a generated Cell; open state adds the detail panel after its row using the expansion plugin's captured column count. | Expanded state, caller detail content, and later plugin column transforms. |
|
|
144
|
+
|
|
145
|
+
### Transformation and precedence order
|
|
146
|
+
|
|
147
|
+
- No new plugin ordering, column transformation, slot placement, wrapping,
|
|
148
|
+
sizing, or styling precedence rule is introduced.
|
|
149
|
+
|
|
150
|
+
### Performance and resources
|
|
151
|
+
|
|
152
|
+
- No new performance or resource rule is introduced. Existing memoization and
|
|
153
|
+
plugin-specific render behavior remain outside this documentation change.
|
|
154
|
+
|
|
155
|
+
## Accessibility contract
|
|
156
|
+
|
|
157
|
+
This draft does not change or extend the current native table semantics,
|
|
158
|
+
focusable Scroll region, column-header scope, sort `aria-sort`, selection
|
|
159
|
+
`aria-selected`, CheckboxInput labels, or expansion `aria-expanded` behavior.
|
|
160
|
+
|
|
161
|
+
## Design relationships
|
|
162
|
+
|
|
163
|
+
| Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
|
|
164
|
+
| --------------------- | --------------------------------------------------------------------------------- | ------------------------------ | -------------- | ------------------ |
|
|
165
|
+
| Table | Groups the semantic table structure. | Current source and public docs | Supporting | FR1-FR4 |
|
|
166
|
+
| Scroll region | Provides keyboard-reachable horizontal overflow around Table. | Current source and public docs | Supporting | FR1, FR4 |
|
|
167
|
+
| Header section | Groups Column header cells separately from body data. | Current source and public docs | Supporting | FR2-FR4 |
|
|
168
|
+
| Column header cell | Identifies one column and hosts optional header controls. | Current source and public docs | Prominent | FR2-FR6 |
|
|
169
|
+
| Sort control | Activates sorting for one sortable column. | Current source and public docs | Prominent | FR5 |
|
|
170
|
+
| Sort indicator glyph | Shows the current sort direction through Icon. | `component:Icon` | Supporting | FR5 |
|
|
171
|
+
| Sort priority | Shows a column's position in active multi-sort order. | Current source and public docs | Supporting | FR5 |
|
|
172
|
+
| Selection control | Selects all eligible rows or one eligible row through CheckboxInput. | `component:CheckboxInput` | Prominent | FR6 |
|
|
173
|
+
| Body section | Groups data, empty-state, and expanded-detail rows. | Current source and public docs | Supporting | FR2-FR4, FR7, FR8 |
|
|
174
|
+
| Row | Groups standard header, body, or footer cells. | Current source and public docs | Supporting | FR2-FR4, FR6 |
|
|
175
|
+
| Cell | Contains one value or caller-provided content in a standard body or footer row. | Current source and public docs | Prominent | FR2-FR4, FR6, FR7 |
|
|
176
|
+
| Default empty state | Communicates that the current data array has no rows through EmptyState. | `component:EmptyState` | Prominent | FR8 |
|
|
177
|
+
| Expansion control | Expands or collapses one eligible row. | Current source and public docs | Prominent | FR7 |
|
|
178
|
+
| Expansion glyph | Shows the current expansion direction through Icon. | `component:Icon` | Supporting | FR7 |
|
|
179
|
+
| Expanded detail panel | Presents caller-provided detail content in a spanning row below the expanded row. | Current source and public docs | Prominent | FR7 |
|
|
180
|
+
| Footer section | Groups caller-supplied summary or total rows below the body. | Current source and public docs | Supporting | FR3, FR4 |
|
|
181
|
+
|
|
182
|
+
### Theming anatomy
|
|
183
|
+
|
|
184
|
+
<!-- anatomy-theming:v1 -->
|
|
185
|
+
|
|
186
|
+
```json
|
|
187
|
+
{
|
|
188
|
+
"Table": {"target": "table"},
|
|
189
|
+
"Scroll region": {"target": "table-scroll-wrapper"},
|
|
190
|
+
"Header section": {"target": "table-header"},
|
|
191
|
+
"Column header cell": {"target": "table-header-cell"},
|
|
192
|
+
"Sort control": {"inherits": "table-header-cell"},
|
|
193
|
+
"Sort indicator glyph": {
|
|
194
|
+
"delegatesTo": {"owner": "component:Icon", "target": "icon"}
|
|
195
|
+
},
|
|
196
|
+
"Sort priority": {
|
|
197
|
+
"none": {
|
|
198
|
+
"reason": "unsettled: The multi-sort rank has no direct public target and uses a component-owned accent style; future exposure still needs an owner decision"
|
|
199
|
+
}
|
|
200
|
+
},
|
|
201
|
+
"Selection control": {
|
|
202
|
+
"delegatesTo": {
|
|
203
|
+
"owner": "component:CheckboxInput",
|
|
204
|
+
"target": "checkbox-input"
|
|
205
|
+
}
|
|
206
|
+
},
|
|
207
|
+
"Body section": {"target": "table-body"},
|
|
208
|
+
"Row": {"target": "table-row"},
|
|
209
|
+
"Cell": {"target": "table-cell"},
|
|
210
|
+
"Default empty state": {
|
|
211
|
+
"delegatesTo": {"owner": "component:EmptyState", "target": "empty-state"}
|
|
212
|
+
},
|
|
213
|
+
"Expansion control": {
|
|
214
|
+
"none": {
|
|
215
|
+
"reason": "unsettled: The expansion button has no direct public target and uses component-owned styles; future exposure still needs an owner decision"
|
|
216
|
+
}
|
|
217
|
+
},
|
|
218
|
+
"Expansion glyph": {
|
|
219
|
+
"delegatesTo": {"owner": "component:Icon", "target": "icon"}
|
|
220
|
+
},
|
|
221
|
+
"Expanded detail panel": {
|
|
222
|
+
"none": {
|
|
223
|
+
"reason": "reachability-gap: The plugin renders its detail row and cell as raw elements, so the current table-row and table-cell targets do not reach the panel wrapper"
|
|
224
|
+
}
|
|
225
|
+
},
|
|
226
|
+
"Footer section": {"target": "table-footer"}
|
|
227
|
+
}
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
The exact map records all eight current non-deprecated Table targets once. The
|
|
231
|
+
legacy `base-table` alias is compatibility, not anatomy. TableHeader, TableBody,
|
|
232
|
+
TableFooter, TableRow, TableCell, and TableHeaderCell retain direct docs linked by
|
|
233
|
+
`subComponentOf: 'Table'`; they do not need independent component specs for this
|
|
234
|
+
aggregate ownership.
|
|
235
|
+
|
|
236
|
+
## Family and system relationships
|
|
237
|
+
|
|
238
|
+
- `architecture:component-theming-surface` owns anatomy qualification, exact
|
|
239
|
+
target mapping, delegation, inheritance, factual `none` classifications, and
|
|
240
|
+
the rule that deprecated aliases do not count as anatomy.
|
|
241
|
+
- `architecture:container-padding` owns the inherited inset protocol consumed by
|
|
242
|
+
the Scroll region and Cell edge compensation.
|
|
243
|
+
- `architecture:interaction-modality` owns shared keyboard and pointer modality;
|
|
244
|
+
Table and its plugins retain their current local interactions.
|
|
245
|
+
- `architecture:public-component-api` owns the stable props, components, hooks,
|
|
246
|
+
exports, and compatibility boundary; this documentation adds no API.
|
|
247
|
+
|
|
248
|
+
## Verification map
|
|
249
|
+
|
|
250
|
+
| Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
|
|
251
|
+
| ------------------- | ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------- |
|
|
252
|
+
| FR1-FR3 | `Table.test.tsx` render, structure, children-mode, section, and target assertions | Data-driven rows, empty data, and children composition | Removing Table, Scroll region, or configured structure fails existing role, structure, class, or prop-forwarding assertions; Row and Cell are conditional on rendered data or caller composition. | `audit:Table/anatomy` |
|
|
253
|
+
| FR4 | CLI discovery and API target tests plus source inspection | Direct member docs and unfiltered/scoped target output | Duplicating a parent/member target or changing the canonical owner fails parent-aware discovery assertions; section target placement remains source-inspected. | `audit:Table/theming` |
|
|
254
|
+
| FR5 | `plugins/sortable/useTableSortable.test.tsx` plus source inspection | Unsorted, ascending, descending, and multi-sort | Removing the Sort control, conditional priority, or ARIA state fails existing assertions. Removing the Sort indicator glyph does not currently fail a focused test; glyph presence and delegated Icon target placement remain source-inspected. | `audit:Table/anatomy` |
|
|
255
|
+
| FR6 | `plugins/selection/useTableSelection.test.tsx` | Select all, individual, disabled, and non-selectable | Removing header/body Selection controls or row selection state fails existing structure, label, interaction, and ARIA assertions; delegated CheckboxInput target placement remains source-inspected. | `audit:Table/anatomy` |
|
|
256
|
+
| FR7 | `plugins/rowExpansion/useTableRowExpansion.test.tsx` plus source inspection | Collapsed, expanded, and non-expandable rows | Removing the Expansion control, conditional detail panel, captured-count `colSpan`, or ARIA state fails existing assertions in the covered plugin order; later column transforms, delegated Icon target placement, and untargeted panel wrappers remain source-inspected. | `audit:Table/anatomy` |
|
|
257
|
+
| FR8 | `Table.test.tsx` empty-state suite plus EmptyState public target metadata | Default, custom, disabled, and non-empty | Removing conditional empty behavior fails existing assertions; default EmptyState delegation remains source-inspected. | `audit:Table/anatomy` |
|
|
258
|
+
| Theming anatomy map | `scripts/check-knowledge.mjs`, `themingTargets.test.ts`, and CLI parent-aware target discovery tests | Canonical anatomy, eight current targets, legacy alias | Missing, extra, duplicated, prefixed, stale, alias-backed, or independently owned member mappings fail repository validation or discovery coverage. | `audit:Table/theming` |
|
|
259
|
+
|
|
260
|
+
## Decision log
|
|
261
|
+
|
|
262
|
+
None. This draft records current facts and the user-directed canonical parent
|
|
263
|
+
ownership without introducing a component-local design, API, behavior, layout,
|
|
264
|
+
or theming decision.
|
|
265
|
+
|
|
266
|
+
## Open questions
|
|
267
|
+
|
|
268
|
+
- **OQ1 - Should the current untargeted Sort priority, Expansion control, or
|
|
269
|
+
Expanded detail panel gain direct public theming targets?** (`human-api`) This
|
|
270
|
+
factual map does not decide future exposure.
|
|
271
|
+
- **OQ2 - Should focused runtime tests pin the Sort indicator glyph, the
|
|
272
|
+
`table-header`, `table-body`, and `table-footer` target classes, and delegated
|
|
273
|
+
component target placement?** (`checkable`) Current evidence is source
|
|
274
|
+
inspection plus structural and global inventory tests.
|
|
275
|
+
- **OQ3 - Should row expansion derive its panel span after all column transforms?**
|
|
276
|
+
(`checkable`) A later custom `transformColumns` plugin can currently make the
|
|
277
|
+
captured count stale.
|
|
278
|
+
|
|
279
|
+
## Content boundary
|
|
280
|
+
|
|
281
|
+
This file does not duplicate consumer prop tables or examples, plugin usage,
|
|
282
|
+
container-padding mechanics, shared modality rules, current audit results, or
|
|
283
|
+
implementation steps. It links to their owners.
|