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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (270) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/BottomSheet/BottomSheet.d.ts +3 -1
  3. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  4. package/dist/BottomSheet/BottomSheet.js +4 -3
  5. package/dist/BottomSheet/BottomSheetEdgeTint.d.ts +2 -2
  6. package/dist/BottomSheet/BottomSheetEdgeTint.d.ts.map +1 -1
  7. package/dist/BottomSheet/BottomSheetEdgeTint.js +7 -10
  8. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  9. package/dist/BottomSheet/BottomSheetSwitcher.js +1 -1
  10. package/dist/Button/Button.d.ts +2 -1
  11. package/dist/Button/Button.d.ts.map +1 -1
  12. package/dist/Button/Button.js +11 -4
  13. package/dist/Carousel/Carousel.d.ts.map +1 -1
  14. package/dist/Carousel/Carousel.js +2 -2
  15. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  16. package/dist/Chat/ChatToolCalls.js +34 -17
  17. package/dist/ContextMenu/ContextMenu.d.ts +14 -3
  18. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  19. package/dist/ContextMenu/ContextMenu.js +149 -26
  20. package/dist/ContextMenu/index.d.ts +1 -0
  21. package/dist/ContextMenu/index.d.ts.map +1 -1
  22. package/dist/DropdownMenu/DropdownMenu.d.ts +24 -5
  23. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  24. package/dist/DropdownMenu/DropdownMenu.js +340 -26
  25. package/dist/DropdownMenu/DropdownMenuContext.d.ts +1 -1
  26. package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
  27. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  28. package/dist/DropdownMenu/DropdownMenuItem.js +1 -1
  29. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +6 -2
  30. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  31. package/dist/DropdownMenu/DropdownMenuSubMenu.js +43 -14
  32. package/dist/DropdownMenu/MenuBottomSheet.d.ts +20 -0
  33. package/dist/DropdownMenu/MenuBottomSheet.d.ts.map +1 -0
  34. package/dist/DropdownMenu/MenuBottomSheet.js +36 -0
  35. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts +10 -0
  36. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -0
  37. package/dist/DropdownMenu/MenuBottomSheetActionList.js +111 -0
  38. package/dist/DropdownMenu/index.d.ts +2 -1
  39. package/dist/DropdownMenu/index.d.ts.map +1 -1
  40. package/dist/DropdownMenu/menuWidth.d.ts +14 -0
  41. package/dist/DropdownMenu/menuWidth.d.ts.map +1 -0
  42. package/dist/DropdownMenu/menuWidth.js +35 -0
  43. package/dist/DropdownMenu/useMenuOverflow.d.ts +10 -0
  44. package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -0
  45. package/dist/DropdownMenu/useMenuOverflow.js +60 -0
  46. package/dist/MoreMenu/MoreMenu.d.ts +8 -2
  47. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  48. package/dist/MoreMenu/MoreMenu.js +2 -0
  49. package/dist/MultiSelector/MultiSelector.d.ts +11 -1
  50. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  51. package/dist/MultiSelector/MultiSelector.js +97 -68
  52. package/dist/MultiSelector/index.d.ts +1 -1
  53. package/dist/MultiSelector/index.d.ts.map +1 -1
  54. package/dist/Popover/Popover.d.ts +10 -6
  55. package/dist/Popover/Popover.d.ts.map +1 -1
  56. package/dist/Popover/Popover.js +141 -16
  57. package/dist/Popover/usePopover.d.ts +4 -0
  58. package/dist/Popover/usePopover.d.ts.map +1 -1
  59. package/dist/Popover/usePopover.js +52 -5
  60. package/dist/Selector/Selector.d.ts +10 -0
  61. package/dist/Selector/Selector.d.ts.map +1 -1
  62. package/dist/Selector/Selector.js +106 -80
  63. package/dist/Selector/SelectorBottomSheet.d.ts +21 -0
  64. package/dist/Selector/SelectorBottomSheet.d.ts.map +1 -0
  65. package/dist/Selector/SelectorBottomSheet.js +83 -0
  66. package/dist/Selector/index.d.ts +1 -1
  67. package/dist/Selector/index.d.ts.map +1 -1
  68. package/dist/Selector/selectorPresentation.stylex.d.ts +16 -0
  69. package/dist/Selector/selectorPresentation.stylex.d.ts.map +1 -0
  70. package/dist/Selector/selectorPresentation.stylex.js +21 -0
  71. package/dist/Selector/useSelectorPresentation.d.ts +32 -0
  72. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -0
  73. package/dist/Selector/useSelectorPresentation.js +90 -0
  74. package/dist/Toast/useToastGesture.d.ts.map +1 -1
  75. package/dist/Toast/useToastGesture.js +46 -9
  76. package/dist/astryx.css +19 -1
  77. package/dist/hooks/useAdaptivePresentation.d.ts +5 -0
  78. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -0
  79. package/dist/hooks/useAdaptivePresentation.js +19 -0
  80. package/dist/hooks/useFocusReturnVisibility.d.ts +7 -0
  81. package/dist/hooks/useFocusReturnVisibility.d.ts.map +1 -0
  82. package/dist/hooks/useFocusReturnVisibility.js +35 -0
  83. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  84. package/dist/hooks/useFocusTrap.js +12 -0
  85. package/dist/i18n/InternationalizationContext.d.ts +2 -0
  86. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  87. package/dist/i18n/InternationalizationContext.js +3 -1
  88. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  89. package/dist/i18n/InternationalizationProvider.js +3 -1
  90. package/dist/i18n/resolve.d.ts +1 -1
  91. package/dist/i18n/resolve.d.ts.map +1 -1
  92. package/dist/i18n/resolve.js +37 -38
  93. package/dist/i18n/useTranslator.d.ts.map +1 -1
  94. package/dist/i18n/useTranslator.js +2 -3
  95. package/locales/af-ZA.json +0 -4
  96. package/locales/ar-SA.json +0 -4
  97. package/locales/ca-ES.json +0 -4
  98. package/locales/cs-CZ.json +0 -4
  99. package/locales/da-DK.json +0 -4
  100. package/locales/de-DE.json +0 -4
  101. package/locales/el-GR.json +0 -4
  102. package/locales/en.json +20 -0
  103. package/locales/es-ES.json +0 -4
  104. package/locales/fi-FI.json +0 -4
  105. package/locales/fr-FR.json +0 -4
  106. package/locales/he-IL.json +0 -4
  107. package/locales/hu-HU.json +0 -4
  108. package/locales/it-IT.json +0 -4
  109. package/locales/ja-JP.json +0 -4
  110. package/locales/ko-KR.json +0 -4
  111. package/locales/nl-NL.json +0 -4
  112. package/locales/no-NO.json +0 -4
  113. package/locales/pl-PL.json +0 -4
  114. package/locales/pseudo.json +15 -0
  115. package/locales/pt-BR.json +0 -4
  116. package/locales/pt-PT.json +0 -4
  117. package/locales/ro-RO.json +0 -4
  118. package/locales/ru-RU.json +0 -4
  119. package/locales/sr-SP.json +0 -4
  120. package/locales/sv-SE.json +0 -4
  121. package/locales/tr-TR.json +0 -4
  122. package/locales/uk-UA.json +0 -4
  123. package/locales/vi-VN.json +0 -4
  124. package/locales/zh-CN.json +0 -4
  125. package/locales/zh-TW.json +0 -4
  126. package/package.json +3 -3
  127. package/src/BottomSheet/BottomSheet.doc.mjs +37 -0
  128. package/src/BottomSheet/BottomSheet.spec.md +177 -0
  129. package/src/BottomSheet/BottomSheet.test.tsx +29 -0
  130. package/src/BottomSheet/BottomSheet.tsx +7 -4
  131. package/src/BottomSheet/BottomSheetEdgeTint.test.tsx +4 -6
  132. package/src/BottomSheet/BottomSheetEdgeTint.tsx +7 -10
  133. package/src/BottomSheet/BottomSheetSwitcher.tsx +1 -2
  134. package/src/Button/Button.doc.mjs +56 -0
  135. package/src/Button/Button.test.tsx +10 -0
  136. package/src/Button/Button.tsx +13 -5
  137. package/src/ButtonGroup/ButtonGroup.doc.mjs +47 -0
  138. package/src/Calendar/Calendar.doc.mjs +1 -1
  139. package/src/Carousel/Carousel.test.tsx +83 -0
  140. package/src/Carousel/Carousel.tsx +8 -2
  141. package/src/Chat/ChatToolCalls.test.tsx +44 -0
  142. package/src/Chat/ChatToolCalls.tsx +36 -15
  143. package/src/CheckboxInput/CheckboxInput.doc.mjs +1 -1
  144. package/src/CheckboxList/CheckboxList.doc.mjs +173 -32
  145. package/src/CheckboxList/CheckboxList.spec.md +214 -0
  146. package/src/CommandPalette/CommandPalette.doc.mjs +72 -0
  147. package/src/CommandPalette/CommandPalette.spec.md +223 -0
  148. package/src/ComplexSelector/ComplexSelector.doc.mjs +44 -2
  149. package/src/ComplexSelector/ComplexSelector.spec.md +189 -0
  150. package/src/ContextMenu/ContextMenu.doc.mjs +13 -1
  151. package/src/ContextMenu/ContextMenu.test.tsx +131 -1
  152. package/src/ContextMenu/ContextMenu.tsx +199 -32
  153. package/src/ContextMenu/index.ts +1 -0
  154. package/src/DateInput/DateInput.doc.mjs +1 -1
  155. package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
  156. package/src/DateTimeInput/DateTimeInput.doc.mjs +1 -1
  157. package/src/Divider/Divider.doc.mjs +24 -0
  158. package/src/Divider/Divider.spec.md +150 -0
  159. package/src/DropdownMenu/DropdownMenu.doc.mjs +201 -40
  160. package/src/DropdownMenu/DropdownMenu.test.tsx +518 -7
  161. package/src/DropdownMenu/DropdownMenu.tsx +459 -28
  162. package/src/DropdownMenu/DropdownMenuContext.tsx +1 -1
  163. package/src/DropdownMenu/DropdownMenuItem.tsx +2 -0
  164. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +4 -2
  165. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +124 -0
  166. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +72 -17
  167. package/src/DropdownMenu/MenuBottomSheet.tsx +46 -0
  168. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +141 -0
  169. package/src/DropdownMenu/index.ts +2 -0
  170. package/src/DropdownMenu/menuWidth.ts +51 -0
  171. package/src/DropdownMenu/useMenuOverflow.ts +77 -0
  172. package/src/Field/Field.doc.mjs +1 -1
  173. package/src/FieldStatus/FieldStatus.doc.mjs +22 -1
  174. package/src/FieldStatus/FieldStatus.spec.md +212 -0
  175. package/src/FileInput/FileInput.doc.mjs +1 -1
  176. package/src/Grid/Grid.doc.mjs +19 -0
  177. package/src/Grid/Grid.spec.md +161 -0
  178. package/src/Icon/Icon.doc.mjs +196 -48
  179. package/src/Icon/Icon.spec.md +191 -0
  180. package/src/IconButton/IconButton.doc.mjs +38 -0
  181. package/src/Indicator/Indicator.doc.mjs +1 -1
  182. package/src/InputGroup/InputGroup.doc.mjs +1 -1
  183. package/src/Kbd/Kbd.doc.mjs +18 -0
  184. package/src/Kbd/Kbd.spec.md +141 -0
  185. package/src/Layout/Layout.doc.mjs +32 -0
  186. package/src/Layout/Layout.spec.md +199 -0
  187. package/src/Lightbox/Lightbox.doc.mjs +149 -33
  188. package/src/Lightbox/Lightbox.spec.md +197 -0
  189. package/src/Markdown/Markdown.doc.mjs +60 -0
  190. package/src/Markdown/Markdown.spec.md +200 -0
  191. package/src/MobileNav/MobileNav.doc.mjs +140 -32
  192. package/src/MobileNav/MobileNav.spec.md +208 -0
  193. package/src/MoreMenu/MoreMenu.doc.mjs +17 -0
  194. package/src/MoreMenu/MoreMenu.test.tsx +47 -0
  195. package/src/MoreMenu/MoreMenu.tsx +13 -1
  196. package/src/MultiSelector/MultiSelector.doc.mjs +129 -1
  197. package/src/MultiSelector/MultiSelector.spec.md +266 -0
  198. package/src/MultiSelector/MultiSelector.test.tsx +127 -0
  199. package/src/MultiSelector/MultiSelector.tsx +121 -73
  200. package/src/MultiSelector/index.ts +1 -0
  201. package/src/NavIcon/NavIcon.doc.mjs +17 -0
  202. package/src/NavIcon/NavIcon.spec.md +133 -0
  203. package/src/NavMenu/NavHeadingMenu.spec.md +205 -0
  204. package/src/NavMenu/NavMenu.doc.mjs +37 -0
  205. package/src/NumberInput/NumberInput.doc.mjs +1 -1
  206. package/src/Outline/Outline.doc.mjs +35 -0
  207. package/src/Outline/Outline.spec.md +161 -0
  208. package/src/OverflowList/OverflowList.doc.mjs +24 -0
  209. package/src/OverflowList/OverflowList.spec.md +156 -0
  210. package/src/Pagination/Pagination.doc.mjs +74 -0
  211. package/src/Pagination/Pagination.spec.md +225 -0
  212. package/src/Popover/Popover.doc.mjs +11 -11
  213. package/src/Popover/Popover.test.tsx +397 -2
  214. package/src/Popover/Popover.tsx +228 -21
  215. package/src/Popover/usePopover.tsx +92 -15
  216. package/src/PowerSearch/PowerSearch.doc.mjs +1 -1
  217. package/src/ProgressBar/ProgressBar.doc.mjs +198 -38
  218. package/src/ProgressBar/ProgressBar.spec.md +260 -0
  219. package/src/RadioList/RadioList.doc.mjs +1 -1
  220. package/src/Resizable/Resizable.doc.mjs +59 -16
  221. package/src/Resizable/Resizable.spec.md +194 -0
  222. package/src/Section/Section.doc.mjs +17 -0
  223. package/src/Section/Section.spec.md +138 -0
  224. package/src/SegmentedControl/SegmentedControl.doc.mjs +83 -0
  225. package/src/SegmentedControl/SegmentedControl.spec.md +151 -0
  226. package/src/Selector/Selector.doc.mjs +13 -1
  227. package/src/Selector/Selector.test.tsx +135 -0
  228. package/src/Selector/Selector.tsx +141 -82
  229. package/src/Selector/SelectorBottomSheet.tsx +97 -0
  230. package/src/Selector/index.ts +1 -0
  231. package/src/Selector/selectorPresentation.stylex.ts +20 -0
  232. package/src/Selector/useSelectorPresentation.ts +147 -0
  233. package/src/Skeleton/Skeleton.doc.mjs +12 -0
  234. package/src/Skeleton/Skeleton.spec.md +126 -0
  235. package/src/Slider/Slider.doc.mjs +186 -32
  236. package/src/Slider/Slider.spec.md +223 -0
  237. package/src/Stack/Stack.doc.mjs +22 -0
  238. package/src/Stack/Stack.spec.md +154 -0
  239. package/src/StatusDot/StatusDot.doc.mjs +17 -0
  240. package/src/StatusDot/StatusDot.spec.md +137 -0
  241. package/src/Switch/Switch.doc.mjs +41 -1
  242. package/src/Switch/Switch.spec.md +174 -0
  243. package/src/Text/Text.doc.mjs +190 -43
  244. package/src/Text/Text.spec.md +205 -0
  245. package/src/TextArea/TextArea.doc.mjs +256 -46
  246. package/src/TextArea/TextArea.spec.md +204 -0
  247. package/src/TextInput/TextInput.doc.mjs +1 -1
  248. package/src/TimeInput/TimeInput.doc.mjs +1 -1
  249. package/src/Toast/ToastViewport.test.tsx +118 -4
  250. package/src/Toast/useToastGesture.ts +61 -8
  251. package/src/ToggleButton/ToggleButton.doc.mjs +56 -0
  252. package/src/Tokenizer/Tokenizer.doc.mjs +1 -1
  253. package/src/Toolbar/Toolbar.doc.mjs +19 -0
  254. package/src/Toolbar/Toolbar.spec.md +173 -0
  255. package/src/Tooltip/Tooltip.doc.mjs +17 -0
  256. package/src/Tooltip/Tooltip.spec.md +141 -0
  257. package/src/TreeList/TreeList.doc.mjs +58 -0
  258. package/src/TreeList/TreeList.spec.md +220 -0
  259. package/src/Typeahead/Typeahead.doc.mjs +84 -2
  260. package/src/Typeahead/Typeahead.spec.md +250 -0
  261. package/src/hooks/useAdaptivePresentation.ts +35 -0
  262. package/src/hooks/useFocusReturnVisibility.ts +45 -0
  263. package/src/hooks/useFocusTrap.test.tsx +40 -0
  264. package/src/hooks/useFocusTrap.ts +13 -0
  265. package/src/i18n/InternationalizationContext.ts +3 -0
  266. package/src/i18n/InternationalizationProvider.tsx +8 -1
  267. package/src/i18n/__tests__/resolve.test.ts +23 -1
  268. package/src/i18n/resolve.ts +46 -49
  269. package/src/i18n/useTranslator.ts +2 -7
  270. package/src/theme/themingTargets.test.ts +91 -25
@@ -0,0 +1,156 @@
1
+ ---
2
+ schema_version: 1
3
+ template_version: 3
4
+ kind: component
5
+ id: component:OverflowList
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/OverflowList/OverflowList.test.tsx,
16
+ scripts/check-knowledge.mjs,
17
+ ]
18
+ families: []
19
+ design_specs: []
20
+ architecture: [architecture:component-theming-surface]
21
+ contributing: []
22
+ system_specs: []
23
+ ---
24
+
25
+ # OverflowList component contract
26
+
27
+ ## Intent
28
+
29
+ OverflowList renders a selected subset of caller-supplied items in a visible
30
+ horizontal list and may render a caller-supplied indicator for collapsed items.
31
+ Items may collapse because they exceed the measured space or a configured count
32
+ limit. This draft records the current consumer anatomy and theming ownership
33
+ without changing measurement, collapse behavior, targets, 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 visible list container and its current `overflow-list` theming target.
50
+ - Measuring available space, applying configured count limits, and choosing
51
+ which supplied items remain visible.
52
+
53
+ **Does not own / non-goals**
54
+
55
+ - The items supplied through `children` — owned by the caller.
56
+ - The overflow indicator returned by `overflowRenderer` — owned by the caller.
57
+ - The hidden inert measurement container as consumer-facing anatomy or a public
58
+ target.
59
+
60
+ ## Public concepts
61
+
62
+ No new public concept is introduced. Consumer props and usage remain documented
63
+ in `OverflowList.doc.mjs`.
64
+
65
+ ## Behavioral and layout contract
66
+
67
+ | ID | Candidate invariant | Basis | Draft review state |
68
+ | --- | ------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- | -------------------------------------------------- |
69
+ | FR1 | The visible list container carries the `overflow-list` target and renders the caller-supplied items selected by current width and count limits. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
70
+ | FR2 | When the current overflow calculation collapses items and a renderer is supplied, its returned indicator appears at the configured collapse edge. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
71
+ | FR3 | The hidden inert measurement copy carries no public theming target and is not consumer-facing anatomy. | Current source and tests | Verified current behavior; no target change |
72
+
73
+ ### Allowed variation
74
+
75
+ - Item and overflow-indicator content may vary without becoming
76
+ OverflowList-owned theming targets.
77
+
78
+ ### Representative states
79
+
80
+ - With no configured count cap, a sufficiently wide list shows every item and
81
+ no indicator. Width pressure or `maxVisibleItems` may instead collapse a
82
+ subset; the remaining items and optional indicator stay inside the same
83
+ targeted list container.
84
+
85
+ ### Transformation and precedence order
86
+
87
+ - No new measurement, collapse, or rendering order is introduced.
88
+
89
+ ### Performance and resources
90
+
91
+ - This draft records the existing hidden measurement structure but introduces no
92
+ new measurement or observer requirement.
93
+
94
+ ## Accessibility contract
95
+
96
+ This draft does not change or extend the existing hidden measurement container,
97
+ DOM forwarding, or caller-content accessibility behavior.
98
+
99
+ ## Design relationships
100
+
101
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
102
+ | ------------------ | --------------------------------------------------------------------------------------- | ------------------------------ | ----------------- | ------------------ |
103
+ | List | Presents the current visible list container. | Current source and public docs | Supporting | FR1 |
104
+ | Items | Present caller-supplied content selected for visible display by width and count limits. | Caller-supplied content | Context-dependent | FR1 |
105
+ | Overflow indicator | Presents caller-rendered access to or a count of collapsed items. | Caller-supplied content | Context-dependent | FR2 |
106
+
107
+ The hidden measurement copy is implementation plumbing rather than
108
+ consumer-facing anatomy.
109
+
110
+ ### Theming anatomy
111
+
112
+ <!-- anatomy-theming:v1 -->
113
+
114
+ ```json
115
+ {
116
+ "List": {"target": "overflow-list"},
117
+ "Items": {
118
+ "none": {
119
+ "reason": "intentional: Caller-supplied items retain their own theming ownership; OverflowList applies no target to them."
120
+ }
121
+ },
122
+ "Overflow indicator": {
123
+ "none": {
124
+ "reason": "intentional: The caller-rendered overflow indicator retains its own theming ownership; OverflowList applies no target to it."
125
+ }
126
+ }
127
+ }
128
+ ```
129
+
130
+ ## Family and system relationships
131
+
132
+ - `architecture:component-theming-surface` owns anatomy qualification and factual
133
+ `none` dispositions for caller-owned content.
134
+
135
+ ## Verification map
136
+
137
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
138
+ | ------------------- | ----------------------------------------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------- | ---------------------------- |
139
+ | FR1, FR2 | `OverflowList.test.tsx` fit, cap, and overflow suites | All items visible; count-capped; start/end overflow | Removing visible items or changing capped/width-driven indicator placement fails existing content assertions. | `audit:OverflowList/anatomy` |
140
+ | FR1, FR3 | `OverflowList.test.tsx` rendering-contract suites | Visible and hidden measurement containers | Moving the target from the visible list or exposing measurement content fails assertions. | `audit:OverflowList/theming` |
141
+ | Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and current target | Missing, extra, prefixed, or stale mappings fail repository validation. | `audit:OverflowList/theming` |
142
+
143
+ ## Decision log
144
+
145
+ None. This draft records current facts and introduces no component-local design
146
+ or API decision.
147
+
148
+ ## Open questions
149
+
150
+ None.
151
+
152
+ ## Content boundary
153
+
154
+ This file does not duplicate consumer prop tables, examples, overflow
155
+ measurement mechanics, implementation steps, or system rules. It links to their
156
+ owners.
@@ -1,5 +1,76 @@
1
1
  // Copyright (c) Meta Platforms, Inc. and affiliates.
2
2
 
3
+ /** @type {import('@astryxdesign/cli/authoring').ComponentAnatomyElement[]} */
4
+ const anatomy = [
5
+ {
6
+ name: 'Pagination',
7
+ required: true,
8
+ description:
9
+ 'Navigation landmark containing the current paging controls and optional page-size selector.',
10
+ },
11
+ {
12
+ name: 'Page-size selector',
13
+ required: false,
14
+ description: 'Optional Selector for choosing how many items appear per page.',
15
+ },
16
+ {
17
+ name: 'First/last buttons',
18
+ required: false,
19
+ description:
20
+ 'Optional Button controls that jump to the first or last known page.',
21
+ },
22
+ {
23
+ name: 'Previous/next buttons',
24
+ required: true,
25
+ description:
26
+ 'Button controls that move backward or forward through the pages.',
27
+ },
28
+ {
29
+ name: 'Page number button',
30
+ required: false,
31
+ description:
32
+ 'Button for one directly selectable page in the numbered presentation.',
33
+ },
34
+ {
35
+ name: 'Ellipsis',
36
+ required: false,
37
+ description:
38
+ 'Visual omission marker between non-adjacent page-number buttons.',
39
+ },
40
+ {
41
+ name: 'Count readout',
42
+ required: false,
43
+ description:
44
+ 'Text showing the current item range and total item count.',
45
+ },
46
+ {
47
+ name: 'Compact readout',
48
+ required: false,
49
+ description: 'Text showing the current page and total page count.',
50
+ },
51
+ {
52
+ name: 'Dot',
53
+ required: false,
54
+ description:
55
+ 'Page indicator control that reflects and changes the active page.',
56
+ },
57
+ {
58
+ name: 'Page input label',
59
+ required: false,
60
+ description: 'Leading visible label for the editable page-number field.',
61
+ },
62
+ {
63
+ name: 'Page input',
64
+ required: false,
65
+ description: 'NumberInput used to enter a page directly.',
66
+ },
67
+ {
68
+ name: 'Page input total',
69
+ required: false,
70
+ description: 'Trailing text showing the known total page count.',
71
+ },
72
+ ];
73
+
3
74
  /** @type {import('@astryxdesign/cli/authoring').ComponentDoc} */
4
75
 
5
76
  export const docs = {
@@ -138,6 +209,7 @@ export const docs = {
138
209
  },
139
210
  },
140
211
  usage: {
212
+ anatomy,
141
213
  description:
142
214
  'Pagination lets users step through pages of content. Place it below a table, list, or card grid so users can move forward and backward through results. Pick a variant to match the context: numbered pages for data tables, a count for large lists, compact for tight spaces, or dots for carousels.',
143
215
  bestPractices: [
@@ -280,6 +352,7 @@ export const docsZh = {
280
352
  ],
281
353
  },
282
354
  usage: {
355
+ anatomy,
283
356
  description:
284
357
  'Pagination lets users step through pages of content. Place it below a table, list, or card grid so users can move forward and backward through results. Pick a variant to match the context: numbered pages for data tables, a count for large lists, compact for tight spaces, or dots for carousels.',
285
358
  bestPractices: [
@@ -300,6 +373,7 @@ export const docsDense = {
300
373
  description:
301
374
  'Standalone pagination controls for navigating content pages. Supports multiple display variants + works w/ known totals or cursor-based pagination.',
302
375
  usage: {
376
+ anatomy,
303
377
  description:
304
378
  'Pagination lets users step through pages of content. Place it below a table, list, or card grid so users can move forward and backward through results. Pick a variant to match the context: numbered pages for data tables, a count for large lists, compact for tight spaces, or dots for carousels.',
305
379
  bestPractices: [
@@ -0,0 +1,225 @@
1
+ ---
2
+ schema_version: 1
3
+ template_version: 3
4
+ kind: component
5
+ id: component:Pagination
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/Pagination/Pagination.test.tsx,
16
+ packages/core/src/Button/Button.test.tsx,
17
+ packages/core/src/Text/Text.test.tsx,
18
+ packages/core/src/NumberInput/NumberInput.test.tsx,
19
+ packages/core/src/Selector/Selector.test.tsx,
20
+ packages/core/src/theme/themingTargets.test.ts,
21
+ scripts/check-knowledge.mjs,
22
+ ]
23
+ families: []
24
+ design_specs: []
25
+ architecture: [architecture:component-theming-surface]
26
+ contributing: []
27
+ system_specs: []
28
+ ---
29
+
30
+ # Pagination component contract
31
+
32
+ ## Intent
33
+
34
+ Pagination presents controls for moving through pages and may let people choose a
35
+ page size or enter a page directly. This draft records its current consumer
36
+ anatomy, four local theming targets, delegated control ownership, and current
37
+ unreached Ellipsis without changing runtime behavior, styling, targets, or public
38
+ API.
39
+
40
+ ## Compatibility and migration
41
+
42
+ - Released default preserved: `yes`
43
+ - Compatibility class: additive documentation only; runtime, DOM, styling,
44
+ targets, aliases, and public API remain unchanged
45
+ - Controlled/uncontrolled behavior: unchanged
46
+ - Migration decision: none
47
+
48
+ Consumer migration instructions belong in consumer docs and release notes.
49
+
50
+ ## Ownership boundary
51
+
52
+ **Owns**
53
+
54
+ - The Pagination navigation landmark and its current `pagination` target.
55
+ - The Dot, Page input label, and Page input total parts and their current
56
+ `pagination-dot`, `pagination-input-label`, and `pagination-input-total`
57
+ targets.
58
+ - Choosing which stable controls and readouts render for the current paging
59
+ configuration.
60
+
61
+ **Does not own / non-goals**
62
+
63
+ - Button, Text, NumberInput, or Selector presentation and targets; those remain
64
+ owned by their respective components.
65
+ - Button icon artwork or other internals of delegated controls.
66
+ - A public target for Ellipsis; none exists on current `main`.
67
+ - New paging behavior, variants, state, public API, or theming targets.
68
+
69
+ ## Public concepts
70
+
71
+ No new public concept is introduced. Consumer props, presentations, defaults,
72
+ and usage remain documented in `Pagination.doc.mjs`.
73
+
74
+ ## Behavioral and layout contract
75
+
76
+ | ID | Candidate invariant | Basis | Draft review state |
77
+ | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------- |
78
+ | FR1 | The current render contains one Pagination landmark and Previous/next buttons. Page-size selector, First/last buttons, Page number buttons, Ellipsis, Count readout, Compact readout, Dots, Page input label, Page input, and Page input total appear only when their existing conditions are met. | Current source, docs, and tests | Verified current behavior; no new behavior decided |
79
+ | FR2 | Pagination, Dot, Page input label, and Page input total carry the four current local targets `pagination`, `pagination-dot`, `pagination-input-label`, and `pagination-input-total`. | Current source, docs, and history | Verified current inventory; focused placement coverage is absent |
80
+ | FR3 | Page-size selector delegates to Selector; First/last, Previous/next, and Page number buttons delegate to Button; Count and Compact readouts delegate to Text; Page input delegates to NumberInput. | Current source and owner evidence | Verified current ownership; no target change |
81
+ | FR4 | Ellipsis is stable visible Pagination-rendered content in a numbered presentation and currently carries no public target. | Current source, tests, and target docs | Verified current reachability; long-term theming intent remains unsettled |
82
+
83
+ ### Allowed variation
84
+
85
+ - **AV1 — Paging data.** Current page, total pages, total items, page size, and
86
+ stride may vary without changing anatomy ownership.
87
+ - **AV2 — Presentation.** Existing presentation selection changes which optional
88
+ stable parts are present; presentation names and runtime states are not anatomy.
89
+ - **AV3 — Delegated rendering.** Button, Text, NumberInput, and Selector may
90
+ change internal element shape while preserving their own public contracts.
91
+
92
+ ### Representative states
93
+
94
+ | State | Required invariant | Allowed variation |
95
+ | ----------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------- |
96
+ | Numbered, known page count | Page number buttons render; Ellipsis appears only where pages are omitted. | Page count, sibling range, and active page. |
97
+ | Count with known item total | Count readout renders between Previous/next buttons. | Range and total text. |
98
+ | Compact with known page count | Compact readout renders between Previous/next buttons. | Current and total page text. |
99
+ | Dots with known page count | One Dot renders for each page and active state stays on the Dot target. | Dot count and active Dot. |
100
+ | Input with known page count | Page input label, Page input, and Page input total render; First/last may render. | Label text and first/last opt-out. |
101
+ | Input with unknown page count | Page input label and disabled Page input remain; total and First/last are absent. | Cursor-backed current page. |
102
+ | None | Previous/next buttons remain without a presentation-specific part between them. | Enabled state follows current paging availability. |
103
+
104
+ The optional Page-size selector may precede the paging controls in any current
105
+ presentation when page-size options are provided.
106
+
107
+ ### Transformation and precedence order
108
+
109
+ - No new page calculation, range generation, optimistic update, or styling
110
+ precedence rule is introduced.
111
+
112
+ ### Performance and resources
113
+
114
+ - No new performance or resource rule is introduced.
115
+
116
+ ## Accessibility contract
117
+
118
+ This draft does not change or extend Pagination's existing navigation landmark,
119
+ button naming, current-page semantics, roving Dot focus, live announcements, or
120
+ input bounds.
121
+
122
+ ## Design relationships
123
+
124
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
125
+ | --------------------- | ------------------------------------------------------------------ | ------------------------------ | -------------- | ------------------ |
126
+ | Pagination | Groups the page-size and paging controls in a navigation landmark. | Current source and public docs | Supporting | FR1, FR2 |
127
+ | Page-size selector | Lets people choose the number of items shown per page. | `component:Selector` | Supporting | FR1, FR3 |
128
+ | First/last buttons | Jump directly to the first or last known page. | `component:Button` | Supporting | FR1, FR3 |
129
+ | Previous/next buttons | Move backward or forward through pages. | `component:Button` | Prominent | FR1, FR3 |
130
+ | Page number button | Selects one page directly in the numbered presentation. | `component:Button` | Prominent | FR1, FR3 |
131
+ | Ellipsis | Indicates an omitted span of page numbers. | Current source and public docs | Supporting | FR1, FR4 |
132
+ | Count readout | Presents the visible item range and total. | `component:Text` | Prominent | FR1, FR3 |
133
+ | Compact readout | Presents the current and total page counts. | `component:Text` | Prominent | FR1, FR3 |
134
+ | Dot | Presents and selects one page in the dot presentation. | Current source and public docs | Prominent | FR1, FR2 |
135
+ | Page input label | Names the editable page field visually. | Current source and public docs | Supporting | FR1, FR2 |
136
+ | Page input | Accepts a direct page-number entry. | `component:NumberInput` | Prominent | FR1, FR3 |
137
+ | Page input total | Presents the known total after the editable page field. | Current source and public docs | Supporting | FR1, FR2 |
138
+
139
+ The three Button rows are separate stable controls with different conditions and
140
+ jobs; they do not create Pagination-owned Button targets. Presentation values,
141
+ size, disabled state, and active state remain capabilities on owning targets,
142
+ not anatomy entries.
143
+
144
+ ### Theming anatomy
145
+
146
+ <!-- anatomy-theming:v1 -->
147
+
148
+ ```json
149
+ {
150
+ "Pagination": {"target": "pagination"},
151
+ "Page-size selector": {
152
+ "delegatesTo": {"owner": "component:Selector", "target": "selector"}
153
+ },
154
+ "First/last buttons": {
155
+ "delegatesTo": {"owner": "component:Button", "target": "button"}
156
+ },
157
+ "Previous/next buttons": {
158
+ "delegatesTo": {"owner": "component:Button", "target": "button"}
159
+ },
160
+ "Page number button": {
161
+ "delegatesTo": {"owner": "component:Button", "target": "button"}
162
+ },
163
+ "Ellipsis": {
164
+ "none": {
165
+ "reason": "unsettled: no current public target is applied to the Pagination-rendered ellipsis"
166
+ }
167
+ },
168
+ "Count readout": {
169
+ "delegatesTo": {"owner": "component:Text", "target": "text"}
170
+ },
171
+ "Compact readout": {
172
+ "delegatesTo": {"owner": "component:Text", "target": "text"}
173
+ },
174
+ "Dot": {"target": "pagination-dot"},
175
+ "Page input label": {"target": "pagination-input-label"},
176
+ "Page input": {
177
+ "delegatesTo": {"owner": "component:NumberInput", "target": "number-input"}
178
+ },
179
+ "Page input total": {"target": "pagination-input-total"}
180
+ }
181
+ ```
182
+
183
+ The four local targets are current public seams. Delegated controls retain their
184
+ component owners. Ellipsis has no current target; that factual `none` disposition
185
+ does not decide whether it should remain unreachable.
186
+
187
+ ## Family and system relationships
188
+
189
+ - `architecture:component-theming-surface` owns anatomy qualification, local
190
+ target mapping, delegation, state placement, and factual `none` dispositions.
191
+ - Button, Text, NumberInput, and Selector retain ownership of their delegated
192
+ targets and presentation.
193
+
194
+ ## Verification map
195
+
196
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
197
+ | ------------------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------------------------------- | -------------------------------------------------------------------------------------------------- | -------------------------- |
198
+ | FR1 | `Pagination.test.tsx` presentation, page-size, input, and navigation suites | Numbered, count, compact, dots, input, none, known/unknown | Removing or misplacing a stable control fails existing role, text, or interaction assertions. | `audit:Pagination/anatomy` |
199
+ | FR2 | Source inspection, public target metadata, target-introduction history, and `themingTargets.test.ts` | Four local targets and their current capabilities | Removing a current target fails the global inventory; focused placement is not currently pinned. | `audit:Pagination/theming` |
200
+ | FR3 | Pagination composition tests plus Button, Text, NumberInput, and Selector target tests and metadata | All delegated controls and readouts | A composed owner losing its target fails owner coverage; replacing it requires this map to change. | `audit:Pagination/theming` |
201
+ | FR4 | `generatePageRange` tests, render-source inspection, and current target metadata | Left, right, and two-sided omission | Adding or documenting an Ellipsis target requires an explicit map and target-inventory update. | `audit:Pagination/theming` |
202
+ | Theming anatomy map | `scripts/check-knowledge.mjs` | Canonical anatomy and four current local targets | Missing, extra, prefixed, stale, or multiply assigned local mappings fail repository validation. | `audit:Pagination/theming` |
203
+
204
+ Pagination has broad behavior coverage but no focused assertions for placement
205
+ of its four local target classes. Delegated owner tests pin the owner targets;
206
+ Pagination tests pin that the corresponding controls render, not their target
207
+ class composition.
208
+
209
+ ## Decision log
210
+
211
+ None. This draft records current facts and introduces no component-local design,
212
+ API, behavior, or theming decision.
213
+
214
+ ## Open questions
215
+
216
+ - **OQ1 — Which focused tests should pin placement and reflected properties for
217
+ the four local Pagination targets?** (`checkable`)
218
+ - **OQ2 — Should Ellipsis gain a stable public theming target?** (`human-api`)
219
+ Its current lack of reachability is an audit gap, not settled intent.
220
+
221
+ ## Content boundary
222
+
223
+ This file does not duplicate consumer prop tables/examples, paging algorithms,
224
+ implementation steps, owner-component internals, or system theming rules. It
225
+ links to their owners.
@@ -64,7 +64,7 @@ export const docs = {
64
64
  {
65
65
  name: 'width',
66
66
  type: 'number | string',
67
- description: 'Width of the popover container.',
67
+ description: 'Width of the popover container. The layer still caps to the viewport with alignment-aware safe-area gutters before scrolling long content.',
68
68
  default: "'auto'",
69
69
  },
70
70
  {
@@ -101,7 +101,7 @@ export const docs = {
101
101
  {
102
102
  name: 'hasAutoFocus',
103
103
  type: 'boolean',
104
- description: 'Whether to auto-focus the first focusable element when the popover opens. Set to false for inline showcases or documentation previews.',
104
+ description: 'Whether to move focus into the popover when it opens. Keyboard activation focuses the first content control; pointer activation focuses the labeled dialog container so an action does not appear preselected. Set to false for inline showcases or documentation previews.',
105
105
  default: 'true',
106
106
  },
107
107
  {
@@ -149,8 +149,8 @@ export const docs = {
149
149
  { guidance: true, description: 'Keep popover content focused on a single task or piece of information.' },
150
150
  { guidance: true, description: 'Provide a clear way to close: either by clicking outside or with an explicit close button.' },
151
151
  { guidance: false, description: 'Nest popovers inside other popovers; it creates confusing focus and navigation.' },
152
- { guidance: false, description: 'Use a popover for content that requires heavy user input; use a Dialog instead.' },
153
- { guidance: false, description: 'Put too much content in a popover; if it needs scrolling, use a Dialog instead.' },
152
+ { guidance: false, description: 'Assume input complexity alone determines the presentation; evaluate the task’s focus, space, and interaction requirements.' },
153
+ { guidance: false, description: 'Assume scrolling alone means Popover is the wrong component; a bounded Popover may scroll while a focused anchored interaction remains appropriate.' },
154
154
  ],
155
155
  anatomy: [
156
156
  {name: 'Header', required: true, description: 'Contains the title, optional subheader, and close button.'},
@@ -220,7 +220,7 @@ export const docsZh = {
220
220
  {
221
221
  name: 'width',
222
222
  type: 'number | string',
223
- description: '弹出框容器的宽度。',
223
+ description: '弹出框容器的宽度。弹出层仍会限制在视口和安全区域留白内,长内容再滚动。',
224
224
  default: "'auto'",
225
225
  },
226
226
  {
@@ -294,8 +294,8 @@ export const docsZh = {
294
294
  { guidance: true, description: 'Keep popover content focused on a single task or piece of information.' },
295
295
  { guidance: true, description: 'Provide a clear way to close: either by clicking outside or with an explicit close button.' },
296
296
  { guidance: false, description: 'Nest popovers inside other popovers; it creates confusing focus and navigation.' },
297
- { guidance: false, description: 'Use a popover for content that requires heavy user input; use a Dialog instead.' },
298
- { guidance: false, description: 'Put too much content in a popover; if it needs scrolling, use a Dialog instead.' },
297
+ { guidance: false, description: 'Assume input complexity alone determines the presentation; evaluate the task’s focus, space, and interaction requirements.' },
298
+ { guidance: false, description: 'Assume scrolling alone means Popover is the wrong component; a bounded Popover may scroll while a focused anchored interaction remains appropriate.' },
299
299
  ],
300
300
  anatomy: [
301
301
  {name: 'Header', required: true, description: 'Contains the title, optional subheader, and close button.'},
@@ -316,8 +316,8 @@ export const docsDense = {
316
316
  { guidance: true, description: 'Keep popover content focused on a single task or piece of information.' },
317
317
  { guidance: true, description: 'Provide a clear way to close: either by clicking outside or with an explicit close button.' },
318
318
  { guidance: false, description: 'Nest popovers inside other popovers; it creates confusing focus and navigation.' },
319
- { guidance: false, description: 'Use a popover for content that requires heavy user input; use a Dialog instead.' },
320
- { guidance: false, description: 'Put too much content in a popover; if it needs scrolling, use a Dialog instead.' },
319
+ { guidance: false, description: 'Assume input complexity alone determines the presentation; evaluate the task’s focus, space, and interaction requirements.' },
320
+ { guidance: false, description: 'Assume scrolling alone means Popover is the wrong component; a bounded Popover may scroll while a focused anchored interaction remains appropriate.' },
321
321
  ],
322
322
  anatomy: [
323
323
  {name: 'Header', required: true, description: 'Contains the title, optional subheader, and close button.'},
@@ -340,11 +340,11 @@ export const docsDense = {
340
340
  isOpen: 'Whether popover shown in controlled mode.',
341
341
  onOpenChange: 'Callback fired when popover visibility changes.',
342
342
  isEnabled: 'When false, trigger interactions ignored.',
343
- width: 'Popover container width.',
343
+ width: 'Popover container width; capped to alignment-aware viewport/safe-area gutters before long content scrolls.',
344
344
  label: 'Accessible label for popover dialog.',
345
345
  hasCloseButton: 'Whether to include hidden close button for accessibility.',
346
346
  closeButtonLabel: 'Label for hidden close button.',
347
- hasAutoFocus: 'Auto-focus first element on open; false for showcases.',
347
+ hasAutoFocus: 'Move focus into the popover on open; keyboard targets the first control and pointer targets the dialog container.',
348
348
  hasLightDismiss: 'Outside click dismisses; false for explicit-dismiss surfaces (coachmarks).',
349
349
  hasEscapeDismiss: 'Escape dismisses; full effect only with hasLightDismiss=false.',
350
350
  },