@astryxdesign/core 0.7.2-canary.fe2c655 → 0.7.2

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 (297) hide show
  1. package/CHANGELOG.md +156 -2
  2. package/README.md +4 -4
  3. package/dist/AppShell/AppShell.d.ts.map +1 -1
  4. package/dist/AppShell/AppShell.js +40 -1
  5. package/dist/AspectRatio/AspectRatio.d.ts +6 -8
  6. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  7. package/dist/AspectRatio/AspectRatio.js +44 -3
  8. package/dist/Avatar/Avatar.d.ts.map +1 -1
  9. package/dist/Avatar/Avatar.js +8 -1
  10. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  11. package/dist/AvatarGroup/AvatarGroupOverflow.js +4 -1
  12. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  13. package/dist/Breadcrumbs/BreadcrumbItem.js +5 -2
  14. package/dist/Chat/ChatLayoutScrollButton.d.ts.map +1 -1
  15. package/dist/Chat/ChatLayoutScrollButton.js +1 -0
  16. package/dist/CheckboxInput/CheckboxInput.d.ts +1 -1
  17. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  18. package/dist/CheckboxInput/CheckboxInput.js +3 -1
  19. package/dist/CheckboxList/CheckboxList.d.ts +1 -1
  20. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  21. package/dist/CheckboxList/CheckboxList.js +6 -2
  22. package/dist/CheckboxList/CheckboxListItem.d.ts +9 -1
  23. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  24. package/dist/CheckboxList/CheckboxListItem.js +4 -2
  25. package/dist/CommandPalette/CommandPaletteInput.d.ts +1 -1
  26. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  27. package/dist/CommandPalette/CommandPaletteInput.js +37 -5
  28. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  29. package/dist/ContextMenu/ContextMenu.js +5 -2
  30. package/dist/Dialog/Dialog.d.ts.map +1 -1
  31. package/dist/Dialog/Dialog.js +20 -8
  32. package/dist/DropdownMenu/DropdownMenu.d.ts +1 -1
  33. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  34. package/dist/DropdownMenu/DropdownMenu.js +84 -113
  35. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +1 -1
  36. package/dist/DropdownMenu/DropdownMenuContext.d.ts +17 -0
  37. package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
  38. package/dist/DropdownMenu/DropdownMenuContext.js +21 -0
  39. package/dist/DropdownMenu/DropdownMenuDivider.d.ts +5 -3
  40. package/dist/DropdownMenu/DropdownMenuDivider.d.ts.map +1 -1
  41. package/dist/DropdownMenu/DropdownMenuDivider.js +7 -3
  42. package/dist/DropdownMenu/DropdownMenuGroup.d.ts +6 -4
  43. package/dist/DropdownMenu/DropdownMenuGroup.d.ts.map +1 -1
  44. package/dist/DropdownMenu/DropdownMenuGroup.js +4 -3
  45. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +1 -1
  46. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  47. package/dist/DropdownMenu/DropdownMenuSubMenu.js +15 -4
  48. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +24 -0
  49. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -0
  50. package/dist/DropdownMenu/lazyMenuBottomSheet.js +46 -0
  51. package/dist/DropdownMenu/menuRegionStops.d.ts +38 -0
  52. package/dist/DropdownMenu/menuRegionStops.d.ts.map +1 -0
  53. package/dist/DropdownMenu/menuRegionStops.js +131 -0
  54. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  55. package/dist/EmptyState/EmptyState.js +4 -10
  56. package/dist/Field/Field.d.ts +1 -1
  57. package/dist/Field/Field.d.ts.map +1 -1
  58. package/dist/Field/Field.js +8 -4
  59. package/dist/FormLayout/FormLayout.d.ts +5 -4
  60. package/dist/FormLayout/FormLayout.d.ts.map +1 -1
  61. package/dist/FormLayout/FormLayout.js +1 -1
  62. package/dist/FormLayout/FormLayoutContext.d.ts +3 -3
  63. package/dist/FormLayout/FormLayoutContext.js +3 -3
  64. package/dist/Grid/Grid.d.ts +8 -7
  65. package/dist/Grid/Grid.d.ts.map +1 -1
  66. package/dist/Grid/Grid.js +5 -4
  67. package/dist/Grid/GridSpan.d.ts +1 -1
  68. package/dist/Grid/GridSpan.d.ts.map +1 -1
  69. package/dist/Grid/GridSpan.js +1 -0
  70. package/dist/Heading/Heading.d.ts.map +1 -1
  71. package/dist/Heading/Heading.js +4 -2
  72. package/dist/Item/Item.d.ts +6 -2
  73. package/dist/Item/Item.d.ts.map +1 -1
  74. package/dist/Item/Item.js +19 -4
  75. package/dist/List/List.d.ts +46 -19
  76. package/dist/List/List.d.ts.map +1 -1
  77. package/dist/List/List.js +28 -10
  78. package/dist/List/ListContext.d.ts +8 -3
  79. package/dist/List/ListContext.d.ts.map +1 -1
  80. package/dist/List/ListContext.js +7 -2
  81. package/dist/List/ListItem.d.ts +13 -5
  82. package/dist/List/ListItem.d.ts.map +1 -1
  83. package/dist/List/ListItem.js +21 -8
  84. package/dist/List/index.d.ts +1 -1
  85. package/dist/List/index.d.ts.map +1 -1
  86. package/dist/Markdown/Markdown.d.ts.map +1 -1
  87. package/dist/Markdown/Markdown.js +8 -1
  88. package/dist/Markdown/parser.d.ts.map +1 -1
  89. package/dist/Markdown/parser.js +8 -2
  90. package/dist/Markdown/plugins/headingLinks.d.ts.map +1 -1
  91. package/dist/Markdown/plugins/headingLinks.js +9 -1
  92. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  93. package/dist/MetadataList/MetadataList.js +5 -1
  94. package/dist/MetadataList/MetadataListContext.d.ts +1 -1
  95. package/dist/MetadataList/MetadataListContext.d.ts.map +1 -1
  96. package/dist/MobileNav/MobileNav.d.ts +9 -0
  97. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  98. package/dist/MobileNav/MobileNav.js +30 -3
  99. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  100. package/dist/PowerSearch/PowerSearch.js +5 -0
  101. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  102. package/dist/PowerSearch/PowerSearchValueEditor.js +45 -11
  103. package/dist/RadioList/RadioList.d.ts +1 -1
  104. package/dist/RadioList/RadioList.d.ts.map +1 -1
  105. package/dist/RadioList/RadioList.js +6 -2
  106. package/dist/RadioList/RadioListItem.d.ts +9 -1
  107. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  108. package/dist/RadioList/RadioListItem.js +2 -0
  109. package/dist/SideNav/SideNavItem.d.ts +8 -1
  110. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  111. package/dist/SideNav/SideNavItem.js +76 -10
  112. package/dist/Text/Text.d.ts.map +1 -1
  113. package/dist/Text/Text.js +4 -2
  114. package/dist/ToggleButton/ToggleButton.d.ts +3 -2
  115. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  116. package/dist/ToggleButton/ToggleButton.js +12 -1
  117. package/dist/Token/Token.js +1 -1
  118. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  119. package/dist/TopNav/TopNavMegaMenu.js +5 -3
  120. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  121. package/dist/TopNav/TopNavMenu.js +5 -3
  122. package/dist/TreeList/TreeList.d.ts.map +1 -1
  123. package/dist/TreeList/TreeList.js +1 -0
  124. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  125. package/dist/TreeList/TreeListBranches.js +2 -2
  126. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  127. package/dist/TreeList/TreeListItem.js +57 -9
  128. package/dist/astryx.css +27 -4
  129. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  130. package/dist/hooks/useMenuHover.js +18 -13
  131. package/dist/reset.a11y.chromium.spec.js +50 -1
  132. package/dist/utils/plainDate.d.ts.map +1 -1
  133. package/dist/utils/plainDate.js +15 -9
  134. package/docs.mjs +4 -4
  135. package/package.json +4 -4
  136. package/scripts/agent-doc-state.mjs +66 -6
  137. package/scripts/postinstall.mjs +44 -3
  138. package/src/AppShell/AppShell.tsx +45 -1
  139. package/src/AspectRatio/AspectRatio.test.tsx +44 -43
  140. package/src/AspectRatio/AspectRatio.tsx +38 -18
  141. package/src/AspectRatio/__tests__/AspectRatioFitLayers.a11y.browser.spec.ts +157 -0
  142. package/src/Avatar/Avatar.doc.mjs +5 -3
  143. package/src/Avatar/Avatar.tsx +11 -2
  144. package/src/AvatarGroup/AvatarGroup.doc.mjs +3 -2
  145. package/src/AvatarGroup/AvatarGroupOverflow.test.tsx +24 -1
  146. package/src/AvatarGroup/AvatarGroupOverflow.tsx +2 -0
  147. package/src/Breadcrumbs/BreadcrumbItem.tsx +4 -1
  148. package/src/Breadcrumbs/Breadcrumbs.test.tsx +30 -1
  149. package/src/Card/Card.doc.mjs +1 -1
  150. package/src/Chat/ChatLayoutScrollButton.test.tsx +13 -0
  151. package/src/Chat/ChatLayoutScrollButton.tsx +4 -2
  152. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +64 -19
  153. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +3 -1
  154. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  155. package/src/CheckboxInput/CheckboxInput.tsx +3 -1
  156. package/src/CheckboxList/CheckboxList.fr10.test.tsx +29 -2
  157. package/src/CheckboxList/CheckboxList.test.tsx +22 -0
  158. package/src/CheckboxList/CheckboxList.tsx +4 -1
  159. package/src/CheckboxList/CheckboxListItem.doc.mjs +16 -0
  160. package/src/CheckboxList/CheckboxListItem.tsx +10 -0
  161. package/src/Code/Code.doc.mjs +1 -0
  162. package/src/CommandPalette/CommandPalette.doc.mjs +2 -0
  163. package/src/CommandPalette/CommandPaletteInput.test.tsx +53 -4
  164. package/src/CommandPalette/CommandPaletteInput.tsx +33 -3
  165. package/src/CommandPalette/__tests__/CommandPaletteInputAudit.a11y.chromium.spec.ts +335 -0
  166. package/src/CommandPalette/__tests__/CommandPaletteItemAudit.a11y.chromium.spec.ts +292 -0
  167. package/src/ContextMenu/ContextMenu.doc.mjs +2 -3
  168. package/src/ContextMenu/ContextMenu.test.tsx +12 -2
  169. package/src/ContextMenu/ContextMenu.tsx +4 -1
  170. package/src/ContextMenu/__tests__/ContextMenuAudit.a11y.chromium.spec.ts +438 -0
  171. package/src/Dialog/Dialog.test.tsx +46 -0
  172. package/src/Dialog/Dialog.tsx +20 -7
  173. package/src/Dialog/__tests__/Dialog.a11y.known-failures.ts +0 -14
  174. package/src/Drawer/Drawer.doc.mjs +1 -0
  175. package/src/DropdownMenu/DropdownMenu.ssr.test.tsx +57 -0
  176. package/src/DropdownMenu/DropdownMenu.test.tsx +79 -6
  177. package/src/DropdownMenu/DropdownMenu.tsx +88 -144
  178. package/src/DropdownMenu/DropdownMenuCheckboxItem.doc.mjs +1 -1
  179. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +1 -1
  180. package/src/DropdownMenu/DropdownMenuContext.tsx +24 -0
  181. package/src/DropdownMenu/DropdownMenuDivider.doc.mjs +2 -2
  182. package/src/DropdownMenu/DropdownMenuDivider.spec.md +192 -0
  183. package/src/DropdownMenu/DropdownMenuDivider.tsx +9 -5
  184. package/src/DropdownMenu/DropdownMenuGroup.doc.mjs +169 -10
  185. package/src/DropdownMenu/DropdownMenuGroup.tsx +6 -4
  186. package/src/DropdownMenu/DropdownMenuLazySheet.test.tsx +126 -0
  187. package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +1 -1
  188. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +1 -1
  189. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +185 -0
  190. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +17 -3
  191. package/src/DropdownMenu/__tests__/DropdownMenuDividerAudit.a11y.chromium.spec.ts +280 -0
  192. package/src/DropdownMenu/__tests__/DropdownMenuGroupAudit.a11y.chromium.spec.ts +334 -0
  193. package/src/DropdownMenu/__tests__/warmMenuBottomSheet.tsx +43 -0
  194. package/src/DropdownMenu/lazyMenuBottomSheet.ts +71 -0
  195. package/src/DropdownMenu/menuRegionStops.ts +167 -0
  196. package/src/EmptyState/EmptyState.doc.mjs +3 -2
  197. package/src/EmptyState/EmptyState.spec.md +189 -0
  198. package/src/EmptyState/EmptyState.test.tsx +74 -3
  199. package/src/EmptyState/EmptyState.tsx +4 -8
  200. package/src/Field/Field.doc.mjs +14 -8
  201. package/src/Field/Field.spec.md +217 -0
  202. package/src/Field/Field.test.tsx +60 -2
  203. package/src/Field/Field.tsx +17 -8
  204. package/src/Field/FieldLabel.doc.mjs +133 -26
  205. package/src/Field/FieldLabel.spec.md +172 -0
  206. package/src/Field/__tests__/FieldLabelAudit.a11y.chromium.spec.ts +296 -0
  207. package/src/FormLayout/FormLayout.doc.mjs +6 -3
  208. package/src/FormLayout/FormLayout.spec.md +192 -0
  209. package/src/FormLayout/FormLayout.test.tsx +15 -0
  210. package/src/FormLayout/FormLayout.tsx +7 -6
  211. package/src/FormLayout/FormLayoutContext.ts +3 -3
  212. package/src/Grid/Grid.doc.mjs +7 -1
  213. package/src/Grid/Grid.spec.md +93 -113
  214. package/src/Grid/Grid.test.tsx +22 -0
  215. package/src/Grid/Grid.tsx +10 -9
  216. package/src/Grid/GridSpan.doc.mjs +3 -3
  217. package/src/Grid/GridSpan.tsx +4 -1
  218. package/src/Heading/Heading.test.tsx +57 -0
  219. package/src/Heading/Heading.tsx +6 -2
  220. package/src/Icon/Icon.doc.mjs +36 -0
  221. package/src/Indicator/Indicator.doc.mjs +3 -3
  222. package/src/Item/Item.doc.mjs +12 -8
  223. package/src/Item/Item.test.tsx +61 -0
  224. package/src/Item/Item.tsx +40 -4
  225. package/src/Layout/LayoutHeader.doc.mjs +5 -0
  226. package/src/List/List.doc.mjs +14 -1
  227. package/src/List/List.spec.md +129 -77
  228. package/src/List/List.test.tsx +163 -94
  229. package/src/List/List.tsx +74 -18
  230. package/src/List/ListContext.tsx +9 -3
  231. package/src/List/ListItem.doc.mjs +16 -0
  232. package/src/List/ListItem.tsx +56 -27
  233. package/src/List/index.ts +1 -1
  234. package/src/Markdown/Markdown.tsx +14 -1
  235. package/src/Markdown/parser.ts +8 -2
  236. package/src/Markdown/plugins/headingLinks.ts +9 -1
  237. package/src/MetadataList/MetadataList.doc.mjs +3 -3
  238. package/src/MetadataList/MetadataList.test.tsx +38 -0
  239. package/src/MetadataList/MetadataList.tsx +8 -1
  240. package/src/MetadataList/MetadataListContext.tsx +1 -1
  241. package/src/MobileNav/MobileNav.tsx +30 -3
  242. package/src/MobileNav/MobileNavCloseEdgeCases.test.tsx +173 -15
  243. package/src/MoreMenu/MoreMenu.test.tsx +5 -1
  244. package/src/PowerSearch/PowerSearch.test.tsx +62 -0
  245. package/src/PowerSearch/PowerSearch.tsx +9 -0
  246. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +71 -0
  247. package/src/PowerSearch/PowerSearchValueEditor.tsx +45 -0
  248. package/src/ProgressBar/ProgressBar.doc.mjs +1 -0
  249. package/src/RadioList/RadioList.fr10.test.tsx +45 -2
  250. package/src/RadioList/RadioList.test.tsx +22 -0
  251. package/src/RadioList/RadioList.tsx +4 -1
  252. package/src/RadioList/RadioListItem.doc.mjs +16 -0
  253. package/src/RadioList/RadioListItem.tsx +10 -1
  254. package/src/Resizable/useResizable.doc.mjs +2 -0
  255. package/src/ScrollableArea/ScrollableArea.doc.mjs +1 -1
  256. package/src/SideNav/SideNav.spec.md +227 -0
  257. package/src/SideNav/SideNav.test.tsx +220 -0
  258. package/src/SideNav/SideNavItem.doc.mjs +2 -2
  259. package/src/SideNav/SideNavItem.tsx +99 -17
  260. package/src/Slider/Slider.spec.md +39 -18
  261. package/src/Spinner/Spinner.doc.mjs +1 -1
  262. package/src/TabList/TabList.spec.md +57 -44
  263. package/src/Table/Table.spec.md +6 -1
  264. package/src/Table/plugins/activation/useTableActivation.spec.md +254 -0
  265. package/src/Text/Text.test.tsx +57 -0
  266. package/src/Text/Text.tsx +6 -2
  267. package/src/TimeInput/TimeInput.fr10.test.tsx +15 -0
  268. package/src/Timestamp/Timestamp.doc.mjs +1 -1
  269. package/src/ToggleButton/ToggleButton.test.tsx +95 -0
  270. package/src/ToggleButton/ToggleButton.tsx +12 -1
  271. package/src/ToggleButton/ToggleButtonGroup.doc.mjs +4 -0
  272. package/src/Token/Token.tsx +1 -1
  273. package/src/Token/__tests__/TokenRemoveTarget.a11y.chromium.spec.ts +86 -0
  274. package/src/Toolbar/Toolbar.test.tsx +0 -8
  275. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +163 -0
  276. package/src/Toolbar/__tests__/Toolbar.a11y.renders.tsx +63 -0
  277. package/src/Toolbar/__tests__/Toolbar.a11y.states.ts +142 -0
  278. package/src/Toolbar/__tests__/Toolbar.a11y.test.tsx +126 -0
  279. package/src/TopNav/TopNavMegaMenu.test.tsx +47 -0
  280. package/src/TopNav/TopNavMegaMenu.tsx +9 -3
  281. package/src/TopNav/TopNavMenu.test.tsx +46 -1
  282. package/src/TopNav/TopNavMenu.tsx +13 -3
  283. package/src/TreeList/TreeList.doc.mjs +1 -0
  284. package/src/TreeList/TreeList.test.tsx +327 -6
  285. package/src/TreeList/TreeList.tsx +5 -1
  286. package/src/TreeList/TreeListBranches.tsx +6 -0
  287. package/src/TreeList/TreeListItem.tsx +88 -13
  288. package/src/docPropLiterals.test.ts +36 -10
  289. package/src/hooks/useMenuHover.ts +18 -13
  290. package/src/postinstall.test.mjs +79 -0
  291. package/src/reset.a11y.chromium.spec.ts +52 -1
  292. package/src/reset.css +9 -29
  293. package/src/reset.test.ts +11 -0
  294. package/src/theme/derivedVarRegistry.test.ts +7 -0
  295. package/src/unicodePropertyEscapes.source-build.test.mjs +69 -0
  296. package/src/utils/plainDate.test.ts +37 -1
  297. package/src/utils/plainDate.ts +15 -5
@@ -25,38 +25,51 @@ design_specs: []
25
25
  architecture:
26
26
  [architecture:container-padding, architecture:public-component-api]
27
27
  contributing: [contributing:api-conventions]
28
- system_specs: [spec:AST-002/DEC-1, spec:AST-002/DEC-2, spec:AST-057/FR9]
28
+ system_specs:
29
+ [spec:AST-002/DEC-1, spec:AST-002/DEC-2, spec:AST-017/FR4, spec:AST-057/FR9]
29
30
  ---
30
31
 
31
32
  # List component contract
32
33
 
33
34
  ## Contract at a glance
34
35
 
35
- | Area | Contract |
36
- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
37
- | Public contract | Add optional `edgeCompensation?: 'inline'`; omission preserves current layout. |
38
- | Behavior | Every ListItem row moves its content toward a neutral host's inline content edges, reaching them when the host inset is at least the Item inset, while retaining Item-owned interaction padding. |
39
- | End-user impact | List content can reduce or remove the extra inset beside its optional header and adjacent content without shrinking hover, press, selection, or focus paint. |
40
- | Builder impact | Builders opt in only when the List is placed directly in an eligible container-padding host state. |
41
- | Compatibility/readiness | Additive API; implementation and required real-browser evidence are pending. |
42
- | Review checks | Reject header movement, unbounded negative margins, duplicated padding values, physical-edge logic, automatic opt-in, or a ListItem-level public prop. |
43
- | Governing rules | `architecture:container-padding/INV9–INV11`; `spec:AST-002/DEC-1–DEC-2`. |
36
+ | Area | Contract |
37
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
+ | Public contract | Optional `edge?: 'padded' \| 'flush' \| 'outset' \| 'bleed'`, default `'padded'`. Deprecated `edgeCompensation?: 'inline'` resolves to `'outset'`. |
39
+ | Behavior | One edge treatment applies to every ListItem row and decides where row content and row paint sit relative to the list's edges and the host's padding. |
40
+ | End-user impact | Row text can share the line of the list header and a heading above, with row paint stopping at the text, reaching into the host padding, or reaching the host edges. |
41
+ | Builder impact | One choice per list. `flush` works anywhere; `outset` and `bleed` act only inside a host that publishes container padding. |
42
+ | Compatibility/readiness | Additive; omission keeps current geometry; `edgeCompensation` keeps working with a codemod to `edge`. |
43
+ | Review checks | Reject header movement, row paint past the host's padding edge, duplicated padding values, physical-edge logic, automatic opt-in, a ListItem-level prop, or a second prop that can contradict `edge`. |
44
+ | Governing rules | `architecture:container-padding/INV3`, `INV9–INV11`; `spec:AST-002/DEC-1–DEC-2`; `spec:AST-017/FR4`; `spec:AST-057/FR9`. |
44
45
 
45
46
  This table is a review projection; the body below is authoritative.
46
47
 
47
48
  ## Intent
48
49
 
49
- List owns collection-wide edge alignment because its optional header is not
50
- horizontally inset while every ListItem retains Item's inline padding. The caller
51
- knows whether the List is placed in a neutral host where these content lines
52
- should align; List cannot derive that design relationship from its children.
50
+ Every ListItem keeps Item's inline inset so hover, press, and selection paint has
51
+ room around row content. That inset leaves row text off the line of the List
52
+ header, a heading above the list, and the host container's padding. How a
53
+ collection resolves that depends on its rows and its host: static rows need no
54
+ room around paint, interactive rows do, and a list inside a padded container can
55
+ reach into that padding. The caller knows which applies; List cannot derive it
56
+ from its rows, and the choice must hold for the whole collection.
53
57
 
54
58
  ## Compatibility and migration
55
59
 
56
60
  - Released default preserved: `yes`; omission keeps current List and ListItem geometry.
57
- - Compatibility class: additive optional prop with no default behavior change.
61
+ - Compatibility class: additive optional prop; `edgeCompensation` is a deprecated
62
+ alias with the same meaning as `edge="outset"`. Its `@deprecated` type reports
63
+ plain use; development warns only when both props are set, naming
64
+ `astryx upgrade` (`spec:AST-017` FR29–FR29b).
58
65
  - Controlled/uncontrolled behavior: not applicable.
59
- - Migration decision: `component:List/DEC-1` and `component:List/DEC-2`.
66
+ - Migration decision: `component:List/DEC-3`; an `astryx upgrade` codemod renames
67
+ static `edgeCompensation="inline"` to `edge="outset"`, removes
68
+ `edgeCompensation` beside an `edge` string that no later spread can override,
69
+ and keeps the old prop with a TODO where `edge` is computed, on a dynamic value,
70
+ and where the List also spreads props (`spec:AST-017` FR29c–FR29d). A spread onto a
71
+ List that never writes `edgeCompensation` stays unchanged (`spec:AST-040` FR1);
72
+ the `@deprecated` type reports a typed use where the props are written.
60
73
 
61
74
  Consumer migration instructions belong in consumer docs and release notes.
62
75
 
@@ -64,108 +77,118 @@ Consumer migration instructions belong in consumer docs and release notes.
64
77
 
65
78
  **Owns**
66
79
 
67
- - The collection-wide `edgeCompensation` opt-in and its propagation to every
68
- ListItem row.
69
- - Keeping the optional header in place while moving row content toward its line.
70
- - The supported relationship between ListItem row geometry and Item's normal
71
- density- and theme-aware inline inset.
80
+ - The collection-wide `edge` treatment and its application to every ListItem row.
81
+ - The deprecated `edgeCompensation` alias and its resolution.
82
+ - Keeping the optional header in place for every treatment.
83
+ - The relationship between row geometry and Item's density- and theme-aware
84
+ inline inset.
72
85
 
73
86
  **Does not own / non-goals**
74
87
 
75
88
  - Container padding values, nesting, or overlay resets — owned by
76
89
  `architecture:container-padding`.
77
- - A ListItem-level compensation prop, automatic host detection, full bleed, or
78
- arbitrary margin controls.
90
+ - A ListItem-level edge prop, per-edge or arbitrary inset values, automatic host
91
+ detection, or block-axis bleed.
79
92
  - TabList or Button projections.
80
93
 
81
94
  ## Public concepts
82
95
 
83
- | Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
84
- | ----------------- | ----------------------- | ----------------------------------------------------------------------------------------------------- | ------------------------------------------------------- | ------- | ---------------- | -------------------------------- | -------------------------------------------- |
85
- | Edge compensation | omitted, `inline` | Move row content toward both logical host content edges while retaining row-local interaction padding | Every List density and marker style in an eligible host | omitted | `component:List` | accepted; implementation pending | Other values are rejected by the public type |
96
+ | Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
97
+ | ------------------------------ | ------------------------------------ | --------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | -------- | ---------------- | ---------- | -------------------------------------------- |
98
+ | Edge treatment | `padded`, `flush`, `outset`, `bleed` | Where row content and row paint sit relative to the list's edges and the host's padding | Every density, marker style, and divider setting; `outset` and `bleed` read host padding | `padded` | `component:List` | accepted | Other values are rejected by the public type |
99
+ | Edge compensation (deprecated) | omitted, `inline` | Same as `edge="outset"` | As `outset` | omitted | `component:List` | deprecated | Other values are rejected by the public type |
86
100
 
87
101
  ## Behavioral and layout contract
88
102
 
89
- | ID | Invariant | Basis | Status |
90
- | --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------- | ----------------------------------------- |
91
- | FR1 | List MUST own `edgeCompensation?: 'inline'`; ListItem MUST NOT expose a parallel public prop. | `component:List/DEC-1` | Accepted contract; implementation pending |
92
- | FR2 | Omission MUST preserve current header, list, and row geometry. Enabling `inline` MUST leave the optional header in place and apply one compensation policy to every ListItem, including non-interactive rows. | Owner direction | Accepted contract; implementation pending |
93
- | FR3 | Each row MUST resolve each logical margin independently as the negative smaller of its own component-owned inline inset and the matching available host inset. Missing host inset MUST resolve to zero. Content reaches the host line only when the host inset is at least the row inset; otherwise it moves toward that line without crossing the host boundary. | `architecture:container-padding/INV9–INV10`; `component:List/DEC-2` | Accepted contract; implementation pending |
94
- | FR4 | The retained row inset MUST come from the same private density- and theme-derived source as Item's applied inline padding. A consumer override of row padding through `xstyle`, `className`, or `style` is outside the alignment guarantee; `edgeCompensation` MUST NOT mirror or infer that arbitrary CSS. | Shared two-owner geometry contract | Accepted contract; implementation pending |
95
- | FR5 | Compensation MUST preserve Item's hover, press, selection, focus, content, semantics, and hit target. It MUST NOT make the row a full-bleed surface or pull it past either available host edge. | Owner direction | Accepted contract; implementation pending |
96
- | FR6 | The opt-in is valid only under a host state whose published inline inset matches its applied padding and whose relevant boundary is visually neutral. Current automatic LayoutContent/LayoutPanel states with known publication mismatch are not eligible until that conformance gap is fixed. | `architecture:container-padding/INV8–INV11` | Accepted contract; implementation pending |
97
- | FR7 | The list element containing the rows MUST clip in the inline axis with `overflow-inline: clip`, never `hidden`, so a row dragged aside for its swipe actions paints no further than the list's inline edge without the list becoming a scroll container. | `spec:AST-057/FR9` | Verified by `List.test.tsx` |
103
+ | ID | Invariant | Basis | Status |
104
+ | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------- | ----------------------------------------------------- |
105
+ | FR1 | List MUST own `edge` and apply one treatment to every ListItem row, interactive or not; ListItem MUST NOT expose a parallel public prop. A defined `edge` MUST win over `edgeCompensation`, and `edgeCompensation="inline"` with `edge` undefined MUST resolve to `outset`. | `component:List/DEC-1`, `component:List/DEC-3` | Accepted contract |
106
+ | FR2 | `padded` MUST preserve current header, list, and row geometry. No treatment MAY move the header or change row block padding, gap, markers, start and end content, semantics, or hit target relative to the row box. | Owner direction | Accepted contract |
107
+ | FR3 | `flush` MUST resolve each row's inline inset to zero through the private source that supplies Item's applied inline padding, so row content and row paint share the list's inline edges. It reads no host padding. A theme override of row inline padding takes precedence over the zero (FR7). | `component:List/DEC-3` | Accepted contract |
108
+ | FR4 | `outset` MUST place each row so it reaches past the host content line by the smaller of its own inline inset and the matching host inset, per logical edge, keeping its inset inside. Content reaches the host line when the host inset is at least the row inset. | `architecture:container-padding/INV9–INV10`; `component:List/DEC-2` | Accepted contract |
109
+ | FR5 | `bleed` MUST place each row so it reaches the host's padding edge on each logical edge, with square corners. Row content sits on the host content line, or at the row's own inset from its edge when the host inset is smaller. A theme override of row inline padding sets the content's inset instead (FR7). | `architecture:container-padding/INV3`; `component:List/DEC-4` | Accepted contract |
110
+ | FR6 | Missing or reset host inset MUST resolve to zero, so `outset` and `bleed` place content as `padded` does outside a padded host. No row paint MAY reach past the host's padding edge. | `architecture:container-padding/INV6`, `INV9` | Accepted contract |
111
+ | FR7 | Each row's retained inset MUST come from the same private density- and theme-derived source as Item's applied inline padding. A theme `item.paddingInline` override takes precedence over every treatment's row padding, as it does over density. A consumer override of row padding through `xstyle`, `className`, or `style` is outside the alignment guarantee. | Shared two-owner geometry contract | Accepted contract |
112
+ | FR8 | `outset` and `bleed` are valid only under a host state whose published inline inset matches its applied padding: a visually neutral host, such as a Layout region with explicit padding or a padded ScrollableArea, or the content area of a Card, Section (any variant), Dialog, or BottomSheet. Those hosts bound their padding with a border, background, or clip; FR6 keeps row paint inside the padding edge, so it never covers the border or changes the host's outline. Automatic LayoutContent/LayoutPanel states with a known publication mismatch are not eligible until that gap is fixed, and Drawer's content area is not admitted until it has its own evidence. | `architecture:container-padding/INV8–INV11`; real-browser evidence in each admitted host | Accepted contract |
113
+ | FR9 | The list element containing the rows MUST clip in the inline axis with `overflow-inline: clip`, never `hidden`. Under `outset` and `bleed` its inline edges MUST reach the host's padding edge, so the clip never cuts resting row paint and a swiped row paints no further than that edge. | `spec:AST-057/FR9` | Verified by `List.test.tsx` and real-browser geometry |
98
114
 
99
115
  ### Allowed variation
100
116
 
101
117
  - Density and `item.paddingInline` theme overrides may change the retained inset;
102
- compensation follows the same derived value.
103
- - Container padding may be uniform, asymmetric, zero, or absent; each logical
104
- edge resolves independently.
118
+ every treatment follows the same derived value. A theme override of row inline
119
+ padding takes precedence over every treatment, as it does over density.
120
+ - Host padding may be uniform, asymmetric, zero, or absent; each logical edge
121
+ resolves independently.
105
122
  - Labels, descriptions, markers, start/end content, interactivity, and selection
106
- may vary without changing the collection-wide alignment rule.
123
+ may vary without changing the collection-wide treatment.
107
124
 
108
125
  ### Representative states
109
126
 
110
- | State | Required invariant | Allowed variation |
111
- | ------------------------------------ | --------------------------------------------------------------------------------------- | --------------------------------------------------------- |
112
- | Default/omitted | Header and every row keep current geometry. | Any current List content and density. |
113
- | Host inset at least Item inset | Row content reaches the host content line; row-local paint keeps Item padding. | Uniform or asymmetric inline padding. |
114
- | Smaller, zero, or missing host inset | The row moves only by the available inset and is never pulled beyond the host boundary. | Either logical edge may independently be smaller or zero. |
115
- | LTR or RTL | Logical start/end mapping follows direction without changing the `inline` meaning. | Writing direction. |
116
- | Themed Item padding | Row padding and compensation move together. | Supported `item.paddingInline` value. |
127
+ | State | Required invariant | Allowed variation |
128
+ | ------------------------------------------------------ | -------------------------------------------------------------------------------------- | ----------------------------------- |
129
+ | `padded` (default) | Header and every row keep current geometry. | Any content, density, or host. |
130
+ | `flush` | Row content and paint share the list's inline edges with the header and divider ends. | Any host, including none. |
131
+ | `outset`, host inset at least row inset | Row content reaches the host content line; row paint reaches past it by the row inset. | Uniform or asymmetric host padding. |
132
+ | `bleed`, host inset at least row inset | Row paint reaches the host's padding edge; row content sits on the host content line. | Uniform or asymmetric host padding. |
133
+ | `outset` or `bleed`, host inset smaller than row inset | Row paint stops at the host's padding edge; content keeps the row inset. | Either logical edge independently. |
134
+ | `outset` or `bleed`, no host inset | Content placed as `padded`; `bleed` rows are square. | Standalone lists and overlays. |
135
+ | LTR or RTL | Logical start/end mapping follows direction. | Writing direction. |
117
136
 
118
137
  ### Transformation and precedence order
119
138
 
120
- - **ORD1 — Host bound.** Read the matching published host inset for each selected
121
- logical edge, with missing values falling back to zero.
122
- - **ORD2 — Local inset.** Resolve Item's component-owned inline inset from density
123
- and theme through the same private value that supplies applied padding.
124
- - **ORD3 — Compensation.** Apply the negative minimum of those values to the row;
125
- then compose supported consumer styles without claiming alignment for a consumer
139
+ - **ORD1 — Treatment.** Resolve `edge`, else `outset` for `edgeCompensation="inline"`,
140
+ else `padded`.
141
+ - **ORD2 — Host bound.** Read the matching published host inset for each logical
142
+ edge, with missing values falling back to zero.
143
+ - **ORD3 — Local inset.** Resolve Item's inline inset through the private value
144
+ that supplies applied padding: density sets it, `flush` replaces it with zero,
145
+ and a theme `item.paddingInline` override replaces either.
146
+ - **ORD4 — Placement.** Apply the treatment's geometry from those values; then
147
+ compose supported consumer styles without claiming alignment for a consumer
126
148
  override of row inline padding.
127
149
 
128
150
  ### Performance and resources
129
151
 
130
- - **PR1 — CSS geometry only.** Edge compensation MUST add no measurement,
131
- observer, listener, state, Effect, or render pass.
152
+ - **PR1 — CSS geometry only.** Every treatment MUST add no measurement, observer,
153
+ listener, state, Effect, or render pass. Deprecation warnings are dev-only.
132
154
 
133
155
  ## Accessibility contract
134
156
 
135
- - **AR1 — Interaction geometry remains local.** Compensation MUST NOT change the
136
- interactive element, accessible role/name/state, focus target, tab order, or
137
- hit target.
138
- - **AR2 — Direction remains logical.** The same `inline` value MUST produce the
139
- corresponding mirrored geometry under RTL without changing DOM order.
157
+ - **AR1 — Interaction geometry remains local.** No treatment MAY change the
158
+ interactive element, accessible role/name/state, focus target, or tab order.
159
+ - **AR2 — Direction remains logical.** Each treatment MUST produce the mirrored
160
+ geometry under RTL without changing DOM order.
140
161
 
141
162
  ## Design relationships
142
163
 
143
- | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
144
- | ---------------- | ----------------------------------------------------------------------------------------------------------- | ------------------------ | ------------------ | ------------------ |
145
- | Optional header | Stays on the host content line and is not moved by row compensation. | `component:List/DEC-1` | Context | FR2 |
146
- | ListItem row | Retains local interaction paint and hit-target padding. | Item composition | Supporting surface | FR3–FR5 |
147
- | Row content | Moves toward each host content line and reaches it only when the host inset can fully absorb the row inset. | `component:List/DEC-2` | Prominent | FR2–FR5 |
164
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
165
+ | ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------ | ------------------ | ------------------ |
166
+ | Optional header | Stays on the host content line for every treatment. | `component:List/DEC-1` | Context | FR2 |
167
+ | ListItem row paint | Stops at the content (`flush`), reaches past it by the row inset (`padded`, `outset`), or reaches the host edge (`bleed`). | `component:List/DEC-3` | Supporting surface | FR3–FR6 |
168
+ | Row content | The row's first content (its marker, start content, or label) sits inside the row inset (`padded`) or on the host content line when the host inset allows (`flush`, `outset`, `bleed`). | `component:List/DEC-3` | Prominent | FR2–FR5 |
148
169
 
149
170
  ## Family and system relationships
150
171
 
151
- - `architecture:container-padding` owns host publication, the shared
152
- `edgeCompensation` vocabulary, eligibility, logical-edge semantics, and overlay
153
- reset.
154
- - `architecture:public-component-api` and `spec:AST-002` own public API admission.
172
+ - `architecture:container-padding` owns host publication, eligibility,
173
+ logical-edge semantics, overlay reset, and the shared `edge` vocabulary. List's
174
+ `edge` projects all four values onto both inline edges of every row.
175
+ - `architecture:public-component-api`, `spec:AST-002`, and `spec:AST-017` own
176
+ public API admission and the deprecation lifecycle.
155
177
  - Item remains the implementation owner of row padding and interaction paint;
156
- List owns only the collection-level opt-in and row application.
178
+ List owns only the collection-level treatment and row placement.
157
179
  - `spec:AST-057` owns swipe actions on `Item` and the rule that the element
158
- containing swipe-capable rows clips in the inline axis; List carries that
159
- clip (FR7) and `ListItem` passes `swipeActions` and `swipeBehavior` through
160
- to `Item` unchanged.
180
+ containing swipe-capable rows clips in the inline axis; List carries that clip
181
+ (FR9) and `ListItem` passes `swipeActions` and `swipeBehavior` through to
182
+ `Item` unchanged.
161
183
 
162
184
  ## Verification map
163
185
 
164
- | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
165
- | ---------------- | ------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | ------------------- |
166
- | FR1–FR4 | List, Item, and theme-registry tests | omitted/enabled; all densities; theme override; static/interactive rows | Removing context propagation, duplicating a padding value, or using one host edge for both margins fails | `audit:List/layout` |
167
- | FR2–FR6, AR1–AR2 | Real-browser List geometry evidence | header; LTR/RTL; uniform/asymmetric/zero/missing host inset; host inset smaller/equal/larger than Item inset; hover/selection/focus | Header movement, over-pull, wrong bounded movement, or lost row-local paint fails | `audit:List/visual` |
168
- | Documentation | `List.doc.mjs`, Storybook, and `scripts/check-knowledge.mjs` | public prop/default and representative composition | Missing or stale contract, docs, or example fails | `audit:List/docs` |
186
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
187
+ | ------------------------- | ------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------- |
188
+ | FR1–FR7, FR9 | List, Item, and theme-registry tests | every treatment; all densities; static and interactive rows; header; deprecated alias alone and with `edge`; ListItem outside a List | Removing context propagation, using one host edge for both inline edges, zeroing padding without the shared inset source, or dropping the list's reach or clip fails | `audit:List/layout` |
189
+ | FR2–FR6, FR8–FR9, AR1–AR2 | Real-browser List geometry evidence | each treatment in a Card at two paddings, a Section, an inline Dialog with and without Layout, a BottomSheet, a padded ScrollableArea scrolling vertically and in both axes, a LayoutContent with explicit padding, and standalone; header and dividers; LTR/RTL; hovered and selected rows; a swiped row under `outset` and `bleed` | Header movement, content off the expected line, paint past the host's padding edge, clipped resting paint, or a changed row box fails | `audit:List/visual` |
190
+ | Migration | `astryx upgrade` codemod tests | static, aliased, already-migrated, dynamic, and computed-`edge` callsites; a second run | A dynamic value or a computed `edge` rewritten, a static one missed, or a second run that changes output fails | `audit:List/docs` |
191
+ | Documentation | `List.doc.mjs`, Storybook, and `scripts/check-knowledge.mjs` | public prop, values, default, deprecation, and representative composition | Missing or stale contract, docs, or example fails | `audit:List/docs` |
169
192
 
170
193
  ## Decision log
171
194
 
@@ -194,6 +217,35 @@ without pulling row paint beyond the host boundary.
194
217
  Rejected: `isFullBleed`, because the row may stop inside the host padding and the
195
218
  name would promise outer-edge bleed that the component does not provide.
196
219
 
220
+ ### DEC-3 — One edge prop names every row edge treatment
221
+
222
+ **Reference:** `component:List/DEC-3`
223
+
224
+ **Decider:** cixzhang, 2026-10-15
225
+
226
+ `padded`, `flush`, `outset`, and `bleed` are mutually exclusive answers to one
227
+ question, so one closed-value prop carries them and no combination can
228
+ contradict. The names are the shared edge vocabulary of
229
+ `architecture:container-padding`. `outset` is the bounded compensation of DEC-2;
230
+ `edgeCompensation` remains its deprecated alias.
231
+
232
+ Rejected: separate boolean props beside `edgeCompensation`, because they could
233
+ request two treatments at once.
234
+
235
+ ### DEC-4 — Bleed reaches the host edge and keeps content on its padding line
236
+
237
+ **Reference:** `component:List/DEC-4`
238
+
239
+ **Decider:** cixzhang, 2026-10-15
240
+
241
+ `bleed` matches Table rows in a padded host: row paint reaches the host's padding
242
+ edge with square corners, and content sits on the host content line, never closer
243
+ to the row edge than the row's own inset. It is opt-in, so existing lists keep
244
+ their geometry.
245
+
246
+ Rejected: bleed as the default inside padded hosts, because it would move every
247
+ existing list in a container.
248
+
197
249
  ## Open questions
198
250
 
199
251
  None.