@astryxdesign/core 0.7.5 → 0.7.6-canary.0ef60dd

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 (559) hide show
  1. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  2. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  3. package/dist/AlertDialog/AlertDialog.js +5 -5
  4. package/dist/Avatar/Avatar.d.ts.map +1 -1
  5. package/dist/Avatar/Avatar.js +12 -3
  6. package/dist/Badge/Badge.d.ts.map +1 -1
  7. package/dist/Badge/Badge.js +7 -1
  8. package/dist/BottomSheet/BottomSheet.js +1 -1
  9. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  10. package/dist/BottomSheet/BottomSheetPanel.js +2 -1
  11. package/dist/BottomSheet/useSheetGestures.d.ts +12 -0
  12. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  13. package/dist/BottomSheet/useSheetGestures.js +30 -3
  14. package/dist/Button/Button.js +4 -4
  15. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  16. package/dist/CheckboxInput/CheckboxInput.js +6 -5
  17. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  18. package/dist/ClickableCard/ClickableCard.js +37 -4
  19. package/dist/DateInput/DateInput.d.ts.map +1 -1
  20. package/dist/DateInput/DateInput.js +12 -4
  21. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  22. package/dist/DateInput/MonthScroller.js +101 -15
  23. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  24. package/dist/DateInput/TouchDateField.js +8 -3
  25. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  26. package/dist/DateRangeInput/DateRangeInput.js +1 -1
  27. package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
  28. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  29. package/dist/DateTimeInput/DateTimeInput.js +23 -12
  30. package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
  31. package/dist/DateTimeInput/NativeTimeSegment.js +5 -4
  32. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  33. package/dist/DateTimeInput/TouchDateTimeField.js +4 -3
  34. package/dist/Dialog/Dialog.d.ts.map +1 -1
  35. package/dist/Dialog/Dialog.js +34 -9
  36. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  37. package/dist/Dialog/DialogHeader.js +5 -4
  38. package/dist/Divider/Divider.d.ts.map +1 -1
  39. package/dist/Divider/Divider.js +2 -1
  40. package/dist/Drawer/Drawer.d.ts +1 -0
  41. package/dist/Drawer/Drawer.d.ts.map +1 -1
  42. package/dist/Drawer/Drawer.js +7 -2
  43. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  44. package/dist/DropdownMenu/DropdownMenu.js +7 -3
  45. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
  46. package/dist/DropdownMenu/MenuBottomSheetActionList.js +6 -5
  47. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +20 -2
  48. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  49. package/dist/DropdownMenu/lazyMenuBottomSheet.js +31 -3
  50. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  51. package/dist/DropdownMenu/renderDropdownItems.js +21 -16
  52. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  53. package/dist/EmptyState/EmptyState.js +2 -1
  54. package/dist/Field/FieldLabel.d.ts +1 -1
  55. package/dist/Field/FieldLabel.d.ts.map +1 -1
  56. package/dist/Field/FieldLabel.js +4 -4
  57. package/dist/Field/InputClearButton.js +3 -3
  58. package/dist/Field/PanelSearchInput.js +2 -2
  59. package/dist/FieldStatus/FieldStatus.js +2 -2
  60. package/dist/FileInput/FileInput.d.ts.map +1 -1
  61. package/dist/FileInput/FileInput.js +7 -1
  62. package/dist/Heading/Heading.js +1 -1
  63. package/dist/Icon/Icon.js +1 -1
  64. package/dist/Indicator/CheckIndicator.d.ts.map +1 -1
  65. package/dist/Indicator/CheckIndicator.js +2 -1
  66. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  67. package/dist/Indicator/CheckboxIndicator.js +3 -1
  68. package/dist/Indicator/RadioIndicator.d.ts.map +1 -1
  69. package/dist/Indicator/RadioIndicator.js +3 -1
  70. package/dist/Item/Item.d.ts.map +1 -1
  71. package/dist/Item/Item.js +2 -1
  72. package/dist/Item/ItemSwipeLayer.js +1 -1
  73. package/dist/Layer/popoverOperations.d.ts +27 -0
  74. package/dist/Layer/popoverOperations.d.ts.map +1 -0
  75. package/dist/Layer/popoverOperations.js +159 -0
  76. package/dist/Layer/useLayer.d.ts +1 -1
  77. package/dist/Layer/useLayer.d.ts.map +1 -1
  78. package/dist/Layer/useLayer.js +93 -59
  79. package/dist/Layout/Layout.js +1 -1
  80. package/dist/Layout/LayoutContent.js +1 -1
  81. package/dist/Layout/LayoutFooter.js +1 -1
  82. package/dist/Layout/LayoutHeader.js +1 -1
  83. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  84. package/dist/Lightbox/Lightbox.js +5 -0
  85. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +5 -4
  86. package/dist/List/List.js +1 -1
  87. package/dist/List/ListItem.js +3 -3
  88. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  89. package/dist/MobileNav/MobileNav.js +7 -2
  90. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +7 -6
  91. package/dist/MultiSelector/MultiSelector.d.ts +1 -1
  92. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  93. package/dist/MultiSelector/MultiSelector.js +26 -10
  94. package/dist/NumberInput/NumberInput.d.ts +3 -1
  95. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  96. package/dist/NumberInput/NumberInput.js +3 -3
  97. package/dist/NumberInput/numberParser.d.ts +3 -0
  98. package/dist/NumberInput/numberParser.d.ts.map +1 -1
  99. package/dist/NumberInput/numberParser.js +7 -44
  100. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  101. package/dist/ProgressBar/ProgressBar.js +16 -12
  102. package/dist/Resizable/useResizable.d.ts.map +1 -1
  103. package/dist/Resizable/useResizable.js +28 -2
  104. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  105. package/dist/SegmentedControl/SegmentedControlItem.js +4 -1
  106. package/dist/Selector/useSelectorPresentation.d.ts +8 -1
  107. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
  108. package/dist/Selector/useSelectorPresentation.js +20 -4
  109. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  110. package/dist/Skeleton/Skeleton.js +1 -1
  111. package/dist/Slider/Slider.d.ts.map +1 -1
  112. package/dist/Slider/Slider.js +10 -2
  113. package/dist/Spinner/Spinner.d.ts.map +1 -1
  114. package/dist/Spinner/Spinner.js +3 -3
  115. package/dist/Stack/Stack.js +1 -1
  116. package/dist/Stack/StackItem.js +1 -1
  117. package/dist/TabList/TabList.d.ts.map +1 -1
  118. package/dist/TabList/TabList.js +16 -1
  119. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  120. package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -1
  121. package/dist/Text/Text.js +1 -1
  122. package/dist/Text/useTruncation.d.ts.map +1 -1
  123. package/dist/Text/useTruncation.js +23 -5
  124. package/dist/TextArea/TextArea.d.ts +1 -1
  125. package/dist/TextArea/TextArea.d.ts.map +1 -1
  126. package/dist/TextArea/TextArea.js +13 -2
  127. package/dist/TextInput/TextInput.d.ts.map +1 -1
  128. package/dist/TextInput/TextInput.js +3 -3
  129. package/dist/TimeInput/TimeInput.d.ts +6 -2
  130. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  131. package/dist/TimeInput/TimeInput.js +21 -14
  132. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  133. package/dist/TimeInput/TouchTimeField.js +5 -4
  134. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  135. package/dist/Timestamp/Timestamp.js +2 -2
  136. package/dist/Timestamp/TimestampHoverCard.js +4 -4
  137. package/dist/Toast/Toast.d.ts.map +1 -1
  138. package/dist/Toast/Toast.js +60 -20
  139. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  140. package/dist/Toast/ToastViewport.js +82 -51
  141. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  142. package/dist/Tokenizer/Tokenizer.js +13 -2
  143. package/dist/Tokenizer/TokenizerBottomSheet.js +3 -3
  144. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  145. package/dist/Toolbar/Toolbar.js +2 -1
  146. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  147. package/dist/TopNav/TopNavMegaMenu.js +3 -0
  148. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  149. package/dist/TopNav/TopNavMenu.js +1 -0
  150. package/dist/Typeahead/Typeahead.d.ts +1 -1
  151. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  152. package/dist/Typeahead/Typeahead.js +9 -1
  153. package/dist/astryx.css +20 -4
  154. package/dist/gestures/GestureArena.d.ts +6 -0
  155. package/dist/gestures/GestureArena.d.ts.map +1 -1
  156. package/dist/gestures/GestureArena.js +39 -0
  157. package/dist/gestures/GestureHost.d.ts +352 -0
  158. package/dist/gestures/GestureHost.d.ts.map +1 -0
  159. package/dist/gestures/GestureHost.js +1773 -0
  160. package/dist/gestures/GestureRecognizer.d.ts +10 -0
  161. package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
  162. package/dist/gestures/GestureRecognizer.js +16 -0
  163. package/dist/gestures/LongPressGestureRecognizer.d.ts +1 -0
  164. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -1
  165. package/dist/gestures/LongPressGestureRecognizer.js +3 -0
  166. package/dist/gestures/PanGestureRecognizer.d.ts +1 -0
  167. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
  168. package/dist/gestures/PanGestureRecognizer.js +3 -0
  169. package/dist/gestures/PinchGestureRecognizer.d.ts +31 -0
  170. package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -0
  171. package/dist/gestures/PinchGestureRecognizer.js +128 -0
  172. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +71 -0
  173. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -0
  174. package/dist/gestures/ScreenEdgePanGestureRecognizer.js +223 -0
  175. package/dist/gestures/SwipeGestureRecognizer.d.ts +37 -0
  176. package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -0
  177. package/dist/gestures/SwipeGestureRecognizer.js +148 -0
  178. package/dist/gestures/TapGestureRecognizer.d.ts +1 -0
  179. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -1
  180. package/dist/gestures/TapGestureRecognizer.js +3 -0
  181. package/dist/gestures/VelocityTracker.d.ts +6 -2
  182. package/dist/gestures/VelocityTracker.d.ts.map +1 -1
  183. package/dist/gestures/VelocityTracker.js +7 -3
  184. package/dist/gestures/haptics.d.ts +65 -0
  185. package/dist/gestures/haptics.d.ts.map +1 -0
  186. package/dist/gestures/haptics.js +182 -0
  187. package/dist/gestures/nativeScroll.d.ts +42 -0
  188. package/dist/gestures/nativeScroll.d.ts.map +1 -0
  189. package/dist/gestures/nativeScroll.js +228 -0
  190. package/dist/gestures/touchAction.d.ts +60 -0
  191. package/dist/gestures/touchAction.d.ts.map +1 -0
  192. package/dist/gestures/touchAction.js +157 -0
  193. package/dist/gestures/touchActionRule.d.ts +34 -0
  194. package/dist/gestures/touchActionRule.d.ts.map +1 -0
  195. package/dist/gestures/touchActionRule.js +140 -0
  196. package/dist/gestures/types.d.ts +18 -7
  197. package/dist/gestures/types.d.ts.map +1 -1
  198. package/dist/gestures/types.js +22 -2
  199. package/dist/hooks/index.d.ts +1 -1
  200. package/dist/hooks/index.d.ts.map +1 -1
  201. package/dist/hooks/modalAnnounce.d.ts.map +1 -1
  202. package/dist/hooks/modalAnnounce.js +107 -61
  203. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
  204. package/dist/hooks/useAdaptivePresentation.js +4 -1
  205. package/dist/hooks/useAnnounce.d.ts +101 -42
  206. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  207. package/dist/hooks/useAnnounce.js +161 -75
  208. package/dist/hooks/useAnnounceRenderedText.d.ts +11 -3
  209. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  210. package/dist/hooks/useAnnounceRenderedText.js +5 -3
  211. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  212. package/dist/hooks/useBusyAnnouncement.js +6 -12
  213. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  214. package/dist/hooks/useMenuHover.js +12 -1
  215. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  216. package/dist/i18n/generated-locales/en.generated.js +5 -0
  217. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  218. package/dist/i18n/generated-locales/pseudo.generated.js +5 -0
  219. package/dist/motion/animator.d.ts +7 -1
  220. package/dist/motion/animator.d.ts.map +1 -1
  221. package/dist/motion/animator.js +119 -27
  222. package/dist/theme/defineTheme.d.ts +19 -5
  223. package/dist/theme/defineTheme.d.ts.map +1 -1
  224. package/dist/theme/defineTheme.js +64 -4
  225. package/dist/theme/domainTokens/domainTokenDefaults.d.ts +3 -0
  226. package/dist/theme/domainTokens/domainTokenDefaults.d.ts.map +1 -0
  227. package/dist/theme/domainTokens/domainTokenDefaults.js +19 -0
  228. package/dist/theme/domainTokens/index.d.ts +5 -4
  229. package/dist/theme/domainTokens/index.d.ts.map +1 -1
  230. package/dist/theme/domainTokens/index.js +5 -9
  231. package/dist/theme/index.d.ts +1 -0
  232. package/dist/theme/index.d.ts.map +1 -1
  233. package/dist/theme/motionKnobs.d.ts +56 -0
  234. package/dist/theme/motionKnobs.d.ts.map +1 -0
  235. package/dist/theme/motionKnobs.js +48 -0
  236. package/dist/theme/resolveThemeValues.d.ts +11 -4
  237. package/dist/theme/resolveThemeValues.d.ts.map +1 -1
  238. package/dist/theme/resolveThemeValues.js +40 -4
  239. package/dist/theme/themeAdaptations.d.ts +7 -3
  240. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  241. package/dist/theme/themeAdaptations.js +36 -7
  242. package/dist/theme/themeMotion.d.ts +96 -0
  243. package/dist/theme/themeMotion.d.ts.map +1 -0
  244. package/dist/theme/themeMotion.js +177 -0
  245. package/dist/theme/tokenReferences.d.ts +31 -0
  246. package/dist/theme/tokenReferences.d.ts.map +1 -0
  247. package/dist/theme/tokenReferences.js +132 -0
  248. package/dist/theme/tokens.d.ts +1 -0
  249. package/dist/theme/tokens.d.ts.map +1 -1
  250. package/dist/theme/tokens.js +9 -129
  251. package/dist/theme/tokens.stylex.d.ts +12 -0
  252. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  253. package/dist/theme/tokens.stylex.js +12 -0
  254. package/dist/utils/focusReturn.d.ts +17 -1
  255. package/dist/utils/focusReturn.d.ts.map +1 -1
  256. package/dist/utils/focusReturn.js +11 -4
  257. package/dist/utils/getNodeText.d.ts +8 -0
  258. package/dist/utils/getNodeText.d.ts.map +1 -0
  259. package/dist/utils/getNodeText.js +37 -0
  260. package/dist/utils/interactionModality.d.ts +11 -2
  261. package/dist/utils/interactionModality.d.ts.map +1 -1
  262. package/dist/utils/interactionModality.js +58 -5
  263. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  264. package/dist/utils/interactionOverlay.stylex.js +17 -8
  265. package/dist/utils/plainDate.d.ts +2 -0
  266. package/dist/utils/plainDate.d.ts.map +1 -1
  267. package/dist/utils/plainDate.js +46 -3
  268. package/dist/utils/presentation.d.ts +50 -0
  269. package/dist/utils/presentation.d.ts.map +1 -0
  270. package/dist/utils/presentation.js +125 -0
  271. package/dist/utils/pressFeedback.d.ts.map +1 -1
  272. package/dist/utils/pressFeedback.js +20 -1
  273. package/dist/utils/primaryClick.d.ts +11 -0
  274. package/dist/utils/primaryClick.d.ts.map +1 -0
  275. package/dist/utils/primaryClick.js +25 -0
  276. package/dist/utils/timeFormat.d.ts +47 -0
  277. package/dist/utils/timeFormat.d.ts.map +1 -0
  278. package/dist/utils/timeFormat.js +240 -0
  279. package/dist/utils/touchPresentation.d.ts.map +1 -1
  280. package/dist/utils/touchPresentation.js +5 -3
  281. package/dist/utils/touchPresentation.stylex.d.ts +15 -0
  282. package/dist/utils/touchPresentation.stylex.d.ts.map +1 -0
  283. package/dist/utils/touchPresentation.stylex.js +33 -0
  284. package/dist/utils/unicodeDigits.d.ts +20 -0
  285. package/dist/utils/unicodeDigits.d.ts.map +1 -0
  286. package/dist/utils/unicodeDigits.js +70 -0
  287. package/locales/en.json +23 -3
  288. package/locales/pseudo.json +15 -0
  289. package/package.json +5 -4
  290. package/src/AlertDialog/AlertDialog.tsx +6 -5
  291. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +18 -6
  292. package/src/Avatar/Avatar.spec.md +22 -22
  293. package/src/Avatar/Avatar.tsx +18 -1
  294. package/src/Avatar/__tests__/AvatarForcedColors.a11y.chromium.spec.ts +126 -0
  295. package/src/Badge/Badge.doc.mjs +1 -1
  296. package/src/Badge/Badge.tsx +19 -2
  297. package/src/Badge/__tests__/BadgeLargerText.a11y.chromium.spec.ts +260 -0
  298. package/src/BottomSheet/BottomSheet.test.tsx +46 -0
  299. package/src/BottomSheet/BottomSheet.tsx +1 -1
  300. package/src/BottomSheet/BottomSheetPanel.tsx +2 -1
  301. package/src/BottomSheet/useSheetGestures.test.ts +52 -0
  302. package/src/BottomSheet/useSheetGestures.ts +37 -6
  303. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +18 -6
  304. package/src/Button/Button.tsx +4 -4
  305. package/src/Calendar/Calendar.spec.md +87 -48
  306. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +21 -7
  307. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +21 -7
  308. package/src/CheckboxInput/CheckboxInput.tsx +6 -5
  309. package/src/ClickableCard/ClickableCard.test.tsx +96 -0
  310. package/src/ClickableCard/ClickableCard.tsx +48 -4
  311. package/src/Collapsible/Collapsible.spec.md +2 -0
  312. package/src/Collapsible/CollapsibleGroup.spec.md +57 -29
  313. package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +18 -7
  314. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +18 -6
  315. package/src/ComplexSelector/ComplexSelector.test.tsx +37 -0
  316. package/src/ContextMenu/ContextMenu.test.tsx +35 -0
  317. package/src/DateInput/DateInput.test.tsx +115 -3
  318. package/src/DateInput/DateInput.tsx +29 -14
  319. package/src/DateInput/DateInputTouch.test.tsx +76 -0
  320. package/src/DateInput/MonthScroller.tsx +106 -20
  321. package/src/DateInput/MonthScrollerSettle.test.tsx +165 -0
  322. package/src/DateInput/TouchDateField.tsx +14 -3
  323. package/src/DateInput/__tests__/MonthScrollerSteps.interaction.browser.spec.ts +312 -0
  324. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -3
  325. package/src/DateRangeInput/DateRangeInput.tsx +16 -12
  326. package/src/DateTimeInput/DateTimeInput.doc.mjs +10 -8
  327. package/src/DateTimeInput/DateTimeInput.spec.md +75 -51
  328. package/src/DateTimeInput/DateTimeInput.test.tsx +81 -0
  329. package/src/DateTimeInput/DateTimeInput.tsx +46 -24
  330. package/src/DateTimeInput/NativeTimeSegment.tsx +4 -6
  331. package/src/DateTimeInput/TouchDateTimeField.tsx +3 -7
  332. package/src/Dialog/Dialog.test.tsx +216 -2
  333. package/src/Dialog/Dialog.tsx +42 -9
  334. package/src/Dialog/DialogHeader.tsx +5 -4
  335. package/src/Dialog/__tests__/DialogSecondDocument.a11y.browser.spec.ts +202 -0
  336. package/src/Divider/Divider.tsx +2 -1
  337. package/src/Drawer/Drawer.spec.md +111 -80
  338. package/src/Drawer/Drawer.test.tsx +35 -0
  339. package/src/Drawer/Drawer.tsx +13 -2
  340. package/src/Drawer/DrawerHeader.spec.md +181 -0
  341. package/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts +267 -0
  342. package/src/DropdownMenu/DropdownMenu.test.tsx +41 -0
  343. package/src/DropdownMenu/DropdownMenu.tsx +10 -3
  344. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +34 -0
  345. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -5
  346. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +19 -7
  347. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +21 -9
  348. package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +60 -0
  349. package/src/DropdownMenu/lazyMenuBottomSheet.ts +36 -7
  350. package/src/DropdownMenu/renderDropdownItems.tsx +24 -19
  351. package/src/EmptyState/EmptyState.tsx +2 -1
  352. package/src/Field/FieldLabel.tsx +5 -4
  353. package/src/Field/InputClearButton.tsx +3 -3
  354. package/src/Field/PanelSearchInput.tsx +2 -2
  355. package/src/FieldStatus/FieldStatus.tsx +2 -2
  356. package/src/FileInput/FileInput.test.tsx +21 -0
  357. package/src/FileInput/FileInput.tsx +4 -1
  358. package/src/FormLayout/FormLayout.spec.md +7 -8
  359. package/src/Heading/Heading.tsx +1 -1
  360. package/src/Icon/Icon.tsx +1 -1
  361. package/src/Indicator/CheckIndicator.spec.md +47 -42
  362. package/src/Indicator/CheckIndicator.tsx +2 -1
  363. package/src/Indicator/CheckboxIndicator.spec.md +40 -37
  364. package/src/Indicator/CheckboxIndicator.tsx +3 -1
  365. package/src/Indicator/Indicator.spec.md +188 -0
  366. package/src/Indicator/RadioIndicator.tsx +3 -1
  367. package/src/Item/Item.tsx +2 -1
  368. package/src/Item/ItemSwipeLayer.tsx +1 -1
  369. package/src/Kbd/Kbd.spec.md +81 -38
  370. package/src/Layer/__tests__/LayerBrowserHide.a11y.chromium.spec.ts +126 -0
  371. package/src/Layer/popoverOperations.test.ts +205 -0
  372. package/src/Layer/popoverOperations.ts +172 -0
  373. package/src/Layer/useLayer.test.tsx +348 -1
  374. package/src/Layer/useLayer.tsx +118 -71
  375. package/src/Layout/Layout.spec.md +127 -131
  376. package/src/Layout/Layout.tsx +1 -1
  377. package/src/Layout/LayoutContent.spec.md +205 -0
  378. package/src/Layout/LayoutContent.tsx +1 -1
  379. package/src/Layout/LayoutFooter.spec.md +190 -0
  380. package/src/Layout/LayoutFooter.tsx +1 -1
  381. package/src/Layout/LayoutHeader.spec.md +193 -0
  382. package/src/Layout/LayoutHeader.tsx +1 -1
  383. package/src/Layout/LayoutPanel.spec.md +194 -0
  384. package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +18 -6
  385. package/src/Lightbox/Lightbox.test.tsx +18 -0
  386. package/src/Lightbox/Lightbox.tsx +5 -0
  387. package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +8 -4
  388. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +18 -8
  389. package/src/List/List.tsx +1 -1
  390. package/src/List/ListItem.spec.md +205 -0
  391. package/src/List/ListItem.tsx +3 -3
  392. package/src/MetadataList/MetadataList.spec.md +187 -0
  393. package/src/MetadataList/MetadataListItem.spec.md +165 -0
  394. package/src/MobileNav/MobileNav.test.tsx +15 -0
  395. package/src/MobileNav/MobileNav.tsx +9 -1
  396. package/src/MobileNav/__tests__/MobileNavHeader.a11y.chromium.spec.ts +89 -0
  397. package/src/MoreMenu/MoreMenu.test.tsx +11 -0
  398. package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +7 -8
  399. package/src/MultiSelector/MultiSelector.spec.md +7 -4
  400. package/src/MultiSelector/MultiSelector.test.tsx +270 -1
  401. package/src/MultiSelector/MultiSelector.tsx +25 -10
  402. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +8 -1
  403. package/src/NavMenu/NavHeadingMenu.spec.md +1 -5
  404. package/src/NumberInput/NumberInput.doc.mjs +13 -7
  405. package/src/NumberInput/NumberInput.spec.md +59 -37
  406. package/src/NumberInput/NumberInput.tsx +13 -3
  407. package/src/NumberInput/__tests__/NumberInput.coarse-pointer.a11y.chromium.spec.ts +102 -0
  408. package/src/NumberInput/numberParser.ts +7 -45
  409. package/src/ProgressBar/ProgressBar.test.tsx +108 -32
  410. package/src/ProgressBar/ProgressBar.tsx +58 -10
  411. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +21 -9
  412. package/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.ts +831 -0
  413. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +21 -14
  414. package/src/Resizable/useResizable.test.ts +43 -0
  415. package/src/Resizable/useResizable.ts +32 -9
  416. package/src/SegmentedControl/SegmentedControl.test.tsx +84 -0
  417. package/src/SegmentedControl/SegmentedControlItem.tsx +11 -5
  418. package/src/Selector/Selector.test.tsx +90 -1
  419. package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +8 -1
  420. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +8 -1
  421. package/src/Selector/useSelectorPresentation.ts +31 -3
  422. package/src/SideNav/SideNav.test.tsx +27 -0
  423. package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +176 -51
  424. package/src/Skeleton/Skeleton.tsx +3 -1
  425. package/src/Slider/Slider.test.tsx +31 -0
  426. package/src/Slider/Slider.tsx +8 -3
  427. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +19 -7
  428. package/src/Spinner/Spinner.tsx +5 -3
  429. package/src/Stack/Stack.tsx +1 -1
  430. package/src/Stack/StackItem.tsx +1 -1
  431. package/src/TabList/TabList.test.tsx +58 -4
  432. package/src/TabList/TabList.tsx +16 -1
  433. package/src/TabList/__tests__/TabPressPointer.interaction.browser.spec.ts +163 -0
  434. package/src/Table/__tests__/Table.a11y.chromium.spec.ts +18 -6
  435. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +22 -0
  436. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -4
  437. package/src/Text/Text.tsx +1 -1
  438. package/src/Text/useTruncation.test.tsx +128 -1
  439. package/src/Text/useTruncation.ts +23 -5
  440. package/src/TextArea/TextArea.spec.md +10 -13
  441. package/src/TextArea/TextArea.test.tsx +60 -0
  442. package/src/TextArea/TextArea.tsx +15 -1
  443. package/src/TextInput/TextInput.test.tsx +21 -0
  444. package/src/TextInput/TextInput.tsx +3 -1
  445. package/src/TimeInput/NativeTimeInput.test.tsx +17 -0
  446. package/src/TimeInput/Presentation.test.tsx +21 -0
  447. package/src/TimeInput/TimeInput.doc.mjs +8 -8
  448. package/src/TimeInput/TimeInput.spec.md +45 -48
  449. package/src/TimeInput/TimeInput.test.tsx +76 -0
  450. package/src/TimeInput/TimeInput.tsx +36 -18
  451. package/src/TimeInput/TouchTimeField.tsx +4 -6
  452. package/src/Timestamp/Timestamp.spec.md +6 -12
  453. package/src/Timestamp/Timestamp.test.tsx +30 -5
  454. package/src/Timestamp/Timestamp.tsx +6 -2
  455. package/src/Timestamp/TimestampHoverCard.tsx +4 -4
  456. package/src/Toast/Toast.spec.md +14 -20
  457. package/src/Toast/Toast.tsx +104 -36
  458. package/src/Toast/ToastViewport.test.tsx +719 -1
  459. package/src/Toast/ToastViewport.tsx +100 -50
  460. package/src/Tokenizer/Tokenizer.spec.md +5 -3
  461. package/src/Tokenizer/Tokenizer.test.tsx +68 -0
  462. package/src/Tokenizer/Tokenizer.tsx +14 -2
  463. package/src/Tokenizer/TokenizerBottomSheet.test.tsx +15 -4
  464. package/src/Tokenizer/TokenizerBottomSheet.tsx +3 -3
  465. package/src/Toolbar/Toolbar.spec.md +5 -6
  466. package/src/Toolbar/Toolbar.test.tsx +30 -0
  467. package/src/Toolbar/Toolbar.tsx +2 -1
  468. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +18 -6
  469. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +18 -7
  470. package/src/TopNav/TopNav.test.tsx +27 -0
  471. package/src/TopNav/TopNavMegaMenu.test.tsx +21 -0
  472. package/src/TopNav/TopNavMegaMenu.tsx +4 -1
  473. package/src/TopNav/TopNavMenu.test.tsx +17 -0
  474. package/src/TopNav/TopNavMenu.tsx +1 -0
  475. package/src/Typeahead/Typeahead.test.tsx +40 -0
  476. package/src/Typeahead/Typeahead.tsx +12 -1
  477. package/src/__tests__/pressState.ts +8 -4
  478. package/src/gestures/GestureArena.ts +35 -0
  479. package/src/gestures/GestureHost.ts +2065 -0
  480. package/src/gestures/GestureRecognizer.ts +18 -0
  481. package/src/gestures/LongPressGestureRecognizer.ts +4 -0
  482. package/src/gestures/PanGestureRecognizer.ts +4 -0
  483. package/src/gestures/PinchGestureRecognizer.ts +148 -0
  484. package/src/gestures/ScreenEdgePanGestureRecognizer.ts +256 -0
  485. package/src/gestures/SwipeGestureRecognizer.ts +197 -0
  486. package/src/gestures/TapGestureRecognizer.ts +4 -0
  487. package/src/gestures/VelocityTracker.ts +10 -3
  488. package/src/gestures/__tests__/GestureHost.test.ts +2087 -0
  489. package/src/gestures/__tests__/PanGestureRecognizer.test.ts +4 -4
  490. package/src/gestures/__tests__/PinchGestureRecognizer.test.ts +74 -0
  491. package/src/gestures/__tests__/ScreenEdgePanGestureRecognizer.test.ts +498 -0
  492. package/src/gestures/__tests__/SwipeGestureRecognizer.test.ts +108 -0
  493. package/src/gestures/__tests__/arena.test.ts +5 -0
  494. package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +193 -0
  495. package/src/gestures/__tests__/browser/build-fixture.mjs +46 -0
  496. package/src/gestures/__tests__/browser/fixture.ts +307 -0
  497. package/src/gestures/__tests__/browser/gestures.interaction.browser.spec.ts +1137 -0
  498. package/src/gestures/__tests__/browserNegotiation.test.ts +293 -0
  499. package/src/gestures/__tests__/haptics.test.ts +187 -0
  500. package/src/gestures/__tests__/harness.ts +21 -2
  501. package/src/gestures/__tests__/recognizerKind.test.ts +78 -0
  502. package/src/gestures/__tests__/touchActionRule.test.ts +54 -0
  503. package/src/gestures/haptics.ts +203 -0
  504. package/src/gestures/nativeScroll.ts +277 -0
  505. package/src/gestures/touchAction.ts +191 -0
  506. package/src/gestures/touchActionRule.ts +157 -0
  507. package/src/gestures/types.ts +30 -9
  508. package/src/hooks/index.ts +5 -1
  509. package/src/hooks/modalAnnounce.ts +129 -72
  510. package/src/hooks/useAdaptivePresentation.ts +4 -1
  511. package/src/hooks/useAnnounce.doc.mjs +35 -3
  512. package/src/hooks/useAnnounce.replace.test.tsx +516 -0
  513. package/src/hooks/useAnnounce.ts +209 -102
  514. package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +10 -1
  515. package/src/hooks/useAnnounceRenderedText.ts +17 -3
  516. package/src/hooks/useBusyAnnouncement.ts +7 -10
  517. package/src/hooks/useMenuHover.ts +15 -1
  518. package/src/i18n/generated-locales/en.generated.ts +6 -0
  519. package/src/i18n/generated-locales/pseudo.generated.ts +6 -0
  520. package/src/motion/README.md +11 -1
  521. package/src/motion/animator.test.ts +151 -3
  522. package/src/motion/animator.ts +149 -33
  523. package/src/theme/Theme.doc.mjs +1 -1
  524. package/src/theme/defineTheme.ts +117 -8
  525. package/src/theme/derivedVarRegistry.test.ts +4 -0
  526. package/src/theme/domainTokens/domainTokenDefaults.ts +19 -0
  527. package/src/theme/domainTokens/index.ts +6 -10
  528. package/src/theme/expandMotionScale.test.ts +1 -1
  529. package/src/theme/index.ts +5 -0
  530. package/src/theme/motionKnobs.ts +82 -0
  531. package/src/theme/resolveThemeValues.ts +68 -6
  532. package/src/theme/themeAdaptations.ts +52 -12
  533. package/src/theme/themeMotion.test.ts +620 -0
  534. package/src/theme/themeMotion.ts +221 -0
  535. package/src/theme/tokenReferences.ts +149 -0
  536. package/src/theme/tokens.stylex.ts +10 -0
  537. package/src/theme/tokens.ts +15 -158
  538. package/src/utils/focusReturn.ts +17 -6
  539. package/src/utils/getNodeText.test.ts +24 -0
  540. package/src/utils/getNodeText.ts +37 -0
  541. package/src/utils/interactionModality.test.ts +45 -1
  542. package/src/utils/interactionModality.ts +64 -5
  543. package/src/utils/interactionOverlay.stylex.ts +12 -3
  544. package/src/utils/plainDate.test.ts +90 -0
  545. package/src/utils/plainDate.ts +58 -3
  546. package/src/utils/presentation.test.ts +380 -0
  547. package/src/utils/presentation.ts +180 -0
  548. package/src/utils/pressFeedback.test.ts +138 -0
  549. package/src/utils/pressFeedback.ts +34 -11
  550. package/src/utils/pressPaintPriority.test.ts +80 -0
  551. package/src/utils/primaryClick.test.ts +38 -0
  552. package/src/utils/primaryClick.ts +28 -0
  553. package/src/utils/timeFormat.test.ts +204 -0
  554. package/src/utils/timeFormat.ts +314 -0
  555. package/src/utils/touchPresentation.stylex.ts +43 -0
  556. package/src/utils/touchPresentation.test.ts +140 -1
  557. package/src/utils/touchPresentation.ts +5 -3
  558. package/src/utils/unicodeDigits.test.ts +44 -0
  559. package/src/utils/unicodeDigits.ts +71 -0
@@ -0,0 +1,205 @@
1
+ ---
2
+ schema_version: 3
3
+ template_version: 7
4
+ kind: component
5
+ id: component:LayoutContent
6
+ authority: current
7
+ archive_reason: null
8
+ superseded_by: null
9
+ approved_by: cixzhang
10
+ approved_at: 2026-10-30
11
+ owners: [cixzhang]
12
+ review_triggers: [public-api, behavior, layout, theming, accessibility]
13
+ verified_by:
14
+ [
15
+ packages/core/src/Layout/LayoutSlots.test.tsx,
16
+ packages/core/src/Layout/__tests__/contentWidth.test.tsx,
17
+ packages/core/src/Layout/__tests__/Layout.a11y.test.tsx,
18
+ packages/core/src/Layout/__tests__/Layout.a11y.chromium.spec.ts,
19
+ .github/visual-baseline/manifest.json,
20
+ scripts/check-knowledge.mjs,
21
+ ]
22
+ modules: []
23
+ families: [family:layout-regions]
24
+ design_specs: []
25
+ architecture:
26
+ [
27
+ architecture:container-padding,
28
+ architecture:component-theming-surface,
29
+ architecture:public-component-api,
30
+ ]
31
+ contributing: []
32
+ system_specs: [spec:AST-038]
33
+ ---
34
+
35
+ # LayoutContent component contract
36
+
37
+ ## Contract at a glance
38
+
39
+ | Area | Contract |
40
+ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
41
+ | Public contract | `children`, `isScrollable`, `padding`, `label`, `role`, root `BaseProps`, and a root `ref`. |
42
+ | Behavior | The main content region fills the Layout's middle area, scrolls by default, and insets its children from neighbouring regions and open edges. |
43
+ | End-user impact | People scroll the main content while headers, footers, and panels stay put, with the scrollbar at the content area's open edge. |
44
+ | Builder impact | None; the record describes shipped behavior. |
45
+ | Compatibility/readiness | Released behavior recorded as current; no API, default, or output changes. Three implementation gaps are listed under Current-state impact. |
46
+ | Review checks | Reject an inner wrapper around the children, a scrollbar moved off the open edge, an inferred landmark, or a further publication mismatch. |
47
+ | Governing rules | `family:layout-regions` FR1, FR3, FR4, FR7, FR8, FR12; `architecture:container-padding`; `architecture:public-component-api` INV5–INV8. |
48
+
49
+ This table is a review projection; the body below is authoritative.
50
+
51
+ ## Intent
52
+
53
+ LayoutContent is the main content region a caller places in a Layout's
54
+ `content` slot. It owns the region's scrolling, inset, and caller-supplied
55
+ landmark semantics; the caller owns its content.
56
+
57
+ Consumer syntax and examples belong in `LayoutContent.doc.mjs`.
58
+
59
+ ## Compatibility and migration
60
+
61
+ - Released default preserved: `yes` — scrollable, automatic inset, no
62
+ landmark role.
63
+ - Compatibility class: records shipped behavior; no public prop, default, DOM,
64
+ target, or styling output changes.
65
+ - Controlled/uncontrolled behavior: not applicable
66
+ - Migration decision: none
67
+
68
+ Consumer migration instructions belong in consumer docs and release notes.
69
+
70
+ ## Current-state impact
71
+
72
+ - **Open inline-end edge keeps the inner inset beside a start panel (FR2).**
73
+ With only a start panel, the open inline-end edge applies the inner inset
74
+ (spacing step 4 by default) instead of the Layout-edge inset, even when the
75
+ Layout sets `padding={0}`, so content stops short of an edge that should be
76
+ full bleed (`family:layout-regions` FR3).
77
+ - **Published padding differs from applied padding (FR2).** With only an end
78
+ panel, the inline-end edge applies the inner inset beside the panel but
79
+ publishes the Layout-edge inset. Beside a header or footer without a
80
+ divider, the block edge applies zero but publishes the inner inset, so a
81
+ nested full-bleed child or Layout starts one inner inset away from the
82
+ content box. `architecture:container-padding` has a region publish its
83
+ applied padding.
84
+ - **Nested content inherits an outer collapse (FR2).** When an outer Layout's
85
+ header or footer has no divider, its middle row zeroes the content's block
86
+ spacing on that side, and a Layout nested inside that row inherits the zero,
87
+ even inside a Dialog, Drawer, or BottomSheet opened from it, so its content
88
+ sits flush against its own header's or footer's divider, where
89
+ `family:layout-regions` FR6 collapses spacing only where the divider is
90
+ absent and `spec:AST-038` FR7 stops inherited layout state at a layer
91
+ boundary.
92
+
93
+ ## Ownership boundary
94
+
95
+ **Owns**
96
+
97
+ - The content root, which carries the `layout-content` target that
98
+ `component:Layout` maps, and is both the scroll container and the direct
99
+ parent of the children.
100
+ - The region's inset, scrolling, and caller-supplied role and label.
101
+
102
+ **Does not own / non-goals**
103
+
104
+ - Slot placement, the Layout-edge inset, and content width — owned by
105
+ `component:Layout`.
106
+ - Content and its meaning — owned by the caller.
107
+
108
+ ## Public concepts
109
+
110
+ | Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
111
+ | --------- | ------------------------- | --------------------------------------------------------------------------- | ----------------------------------------- | --------- | ------------------------- | --------- | -------------------------------- |
112
+ | Scrolling | `true`, `false` | Scrolls overflow, or clips it. | Always | `true` | `component:LayoutContent` | Stable | — |
113
+ | Inset | spacing step; `0`; unset | Uniform padding that replaces the automatic inset; `0` is full bleed. | Always | automatic | `component:LayoutContent` | Stable | Closed union; rejected by types. |
114
+ | Landmark | caller `role` and `label` | Exposes the region as the role the caller names, with that accessible name. | Always | none | caller | Stable | — |
115
+
116
+ ## Behavioral and layout contract
117
+
118
+ | ID | Invariant | Basis |
119
+ | --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
120
+ | FR1 | LayoutContent renders one `div` carrying the `layout-content` target that fills the middle area's height and remaining width and holds the children directly. It scrolls overflow by default; `isScrollable={false}` clips it. | Current source and tests; `family:layout-regions` FR7 |
121
+ | FR2 | Without `padding`, each edge that faces another region (a panel, header, or footer) has the inner inset, and each open edge has the Layout-edge inset, where the Layout-edge inset comes from the Layout's `padding`, else the nearest padding container, and the inner inset from the nearest padding container (Card, Section, Dialog, Drawer, or BottomSheet), each spacing step 4 otherwise; a block edge beside a header or footer without a divider collapses to zero. A `padding` step replaces all four edges, and `0` removes them. The region publishes container-padding values equal to the padding it applies, excluding the content-width alignment gutter of FR3, which is applied but not published. Implementation gaps: with only a start panel the open inline-end edge applies the inner inset; the published values differ from the applied padding with only an end panel and beside a header or footer without a divider; and a nested Layout inherits an outer header's or footer's collapse, so its content sits flush against its own divider (Current-state impact). | Current source; `family:layout-regions` FR4, FR6; `architecture:container-padding` |
122
+ | FR3 | When the Layout sets a content width, the region keeps its own box and scrollbar where `component:Layout` FR6 places them and aligns its children to that width through its inline padding, never less than its inset. With `padding={0}` it stays full bleed. | Current source and tests; `family:layout-regions` FR12 |
123
+ | FR4 | `role` and `label` set the root's `role` and `aria-label`; LayoutContent adds no role of its own. | Current source and tests; `family:layout-regions` FR8 |
124
+ | FR5 | `ref` reaches the root. Supported DOM, data, ARIA, and event props reach the root after the component's own attributes; `xstyle`, `className`, and `style` compose after component styles. | Current source and tests; `architecture:public-component-api` INV5–INV8 |
125
+
126
+ ### Allowed variation
127
+
128
+ - **AV1 — Content.** Any caller content may fill the region.
129
+ - **AV2 — Landmark.** The caller chooses whether the region is a landmark and
130
+ which one.
131
+
132
+ ### Representative states
133
+
134
+ | State | Required invariant | Allowed variation |
135
+ | ------------------------ | ----------------------------------------------------- | ----------------- |
136
+ | Alone in a Layout | Layout-edge inset on every edge; scrolls. | Content. |
137
+ | Beside panels | Inner inset toward each panel. | Panel count. |
138
+ | Content width, no panels | Full-width scrollport; children aligned to the width. | Width. |
139
+ | Full bleed | No padding; zero published inset. | — |
140
+ | Main landmark | `role="main"` and the caller's name on the root. | Name. |
141
+
142
+ ### Transformation and precedence order
143
+
144
+ - **ORD1 — Padding.** `padding` → automatic inset per edge (inner toward a
145
+ region, Layout-edge on an open side, zero beside a header or footer without
146
+ a divider); content-width alignment only increases inline padding.
147
+
148
+ ### Performance and resources
149
+
150
+ - **PR1 — No external lifecycle.** LayoutContent reads which slots its Layout
151
+ fills and adds no listener, observer, timer, or measurement.
152
+
153
+ ## Accessibility contract
154
+
155
+ - **AR1 — Explicit landmarks only.** The region is a landmark only when the
156
+ caller supplies `role`, named only by the caller's `label`
157
+ (`family:layout-regions` FR8).
158
+ - **AR2 — Keyboard scrolling.** A scrolling region is a browser scroll
159
+ container, so its overflow scrolls with the keyboard once focus is inside
160
+ it or on it.
161
+
162
+ ## Design relationships
163
+
164
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
165
+ | ---------------- | -------------------------------------- | ------------------------ | -------------- | ------------------ |
166
+ | Content area | The main scrolling region of a Layout. | Current source and docs | Prominent | FR1–FR3 |
167
+
168
+ Theming: the root carries the `layout-content` target, which `Layout.doc.mjs`
169
+ declares and `component:Layout` maps. `LayoutContent.doc.mjs` declares no
170
+ anatomy of its own, so no anatomy-theming block is declared here.
171
+
172
+ ## Family and system relationships
173
+
174
+ - `family:layout-regions` owns region scrolling, padding replacement, divider
175
+ spacing, landmarks, and content-width scrollbar placement; FR1–FR4 and AR1
176
+ apply them.
177
+ - `architecture:container-padding` owns inset publication; FR2 applies it and
178
+ records the gap.
179
+ - `component:Layout` owns slot placement, the Layout-edge inset, content
180
+ width, and the `layout-content` target mapping.
181
+
182
+ ## Verification map
183
+
184
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
185
+ | --------- | -------------------------------------------------------------------------------------------------------------------- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------- |
186
+ | FR1 | `LayoutSlots.test.tsx` class, scroll-owner, and Layout-slot tests | Alone; in a Layout | A lost `layout-content` class, a non-scrolling default, or an inner wrapper around the children fails. Gap: `isScrollable={false}` and the fill sizing have no check. | `audit:LayoutContent/layout` |
187
+ | FR2, ORD1 | `LayoutSlots.test.tsx` padding test | `padding={0}`; numeric padding | Gap: the padding test checks only that the region renders, and no test covers the automatic per-edge inset, the start-panel inline-end inset, the collapse beside a header or footer without a divider, or the published values. | `audit:LayoutContent/layout` |
188
+ | FR3 | `contentWidth.test.tsx`; stable visual baseline `core-layout--content-width-scrollbar-placement` | No panels, one panel, both; zero padding | A content region that is not full width without panels, children not aligned, or a lost full bleed fails; a scrollbar moved off its edge comes back changed for review. | `audit:LayoutContent/layout` |
189
+ | FR4, AR1 | `LayoutSlots.test.tsx` landmark test; `Layout.a11y.test.tsx` and `Layout.a11y.chromium.spec.ts` `content-main` state | Caller `main` role and label | A lost role or name fails, including at the accessibility tree. Gap: no test asserts that a region without `role` exposes none. | `audit:LayoutContent/accessibility` |
190
+ | FR5 | `LayoutSlots.test.tsx` ref and className/style tests | Ref; caller class and style | A ref on another element, or a dropped class or style, fails. Gap: no test covers DOM, data, or event props, or the `xstyle` merge order. | `audit:LayoutContent/api` |
191
+ | AR2, PR1 | Source review | Scrolling region | Gap: no automated check covers keyboard scrolling or fails if LayoutContent adds a listener or measurement. | `audit:LayoutContent/behavior` |
192
+
193
+ ## Decision log
194
+
195
+ None recorded. The record describes shipped behavior.
196
+
197
+ ## Open questions
198
+
199
+ None.
200
+
201
+ ## Content boundary
202
+
203
+ This file does not duplicate consumer prop tables/examples, current audit
204
+ results, implementation steps, Layout slot rules, or container-padding
205
+ mechanics. It links to their owners.
@@ -21,7 +21,7 @@ import {use} from 'react';
21
21
  import * as stylex from '@stylexjs/stylex';
22
22
  import {spacingVars} from '../theme/tokens.stylex';
23
23
  import {LayoutSlotsContext} from './LayoutSlotsContext';
24
- import {mergeProps} from '../utils';
24
+ import {mergeProps} from '../utils/mergeProps';
25
25
  import type {SpacingStep} from '../utils/types';
26
26
  import {themeProps} from '../utils/themeProps';
27
27
  import {
@@ -0,0 +1,190 @@
1
+ ---
2
+ schema_version: 3
3
+ template_version: 7
4
+ kind: component
5
+ id: component:LayoutFooter
6
+ authority: current
7
+ archive_reason: null
8
+ superseded_by: null
9
+ approved_by: cixzhang
10
+ approved_at: 2026-10-30
11
+ owners: [cixzhang]
12
+ review_triggers: [public-api, behavior, layout, theming, accessibility]
13
+ verified_by:
14
+ [
15
+ packages/core/src/Layout/LayoutSlots.test.tsx,
16
+ packages/core/src/Layout/Layout.test.tsx,
17
+ packages/core/src/Layout/__tests__/contentWidth.test.tsx,
18
+ packages/core/src/Layout/__tests__/Layout.a11y.test.tsx,
19
+ packages/core/src/Layout/__tests__/Layout.a11y.chromium.spec.ts,
20
+ scripts/check-knowledge.mjs,
21
+ ]
22
+ modules: []
23
+ families: [family:layout-regions]
24
+ design_specs: []
25
+ architecture:
26
+ [
27
+ architecture:container-padding,
28
+ architecture:component-theming-surface,
29
+ architecture:public-component-api,
30
+ ]
31
+ contributing: []
32
+ system_specs: [spec:AST-038]
33
+ ---
34
+
35
+ # LayoutFooter component contract
36
+
37
+ ## Contract at a glance
38
+
39
+ | Area | Contract |
40
+ | ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
41
+ | Public contract | `children`, `hasDivider`, `height`, `padding`, `label`, `role`, root `BaseProps`, and a root `ref`. |
42
+ | Behavior | A non-shrinking footer region whose inner wrapper applies and publishes the Layout inset and aligns to the Layout's content width. |
43
+ | End-user impact | People see a footer that keeps its height below scrolling content, with content aligned to the page's readable width. |
44
+ | Builder impact | None; the record describes shipped behavior. |
45
+ | Compatibility/readiness | Released behavior recorded as current; no API, default, or output changes. Two implementation gaps are listed under Current-state impact. |
46
+ | Review checks | Reject a footer that shrinks, a published inset that differs from the applied padding, an inferred landmark, or a lost divider default. |
47
+ | Governing rules | `family:layout-regions` FR1, FR4–FR6, FR8; `architecture:container-padding`; `architecture:public-component-api` INV5–INV8. |
48
+
49
+ This table is a review projection; the body below is authoritative.
50
+
51
+ ## Intent
52
+
53
+ LayoutFooter is the optional footer region a caller places in a Layout's
54
+ `footer` slot. It owns the footer's size, inset, divider, and caller-supplied
55
+ landmark semantics; the caller owns its content.
56
+
57
+ Consumer syntax and examples belong in `LayoutFooter.doc.mjs`.
58
+
59
+ ## Compatibility and migration
60
+
61
+ - Released default preserved: `yes` — no divider unless a Layout default says
62
+ so, automatic inset, no landmark role.
63
+ - Compatibility class: records shipped behavior; no public prop, default, DOM,
64
+ target, or styling output changes.
65
+ - Controlled/uncontrolled behavior: not applicable
66
+ - Migration decision: none
67
+
68
+ Consumer migration instructions belong in consumer docs and release notes.
69
+
70
+ ## Current-state impact
71
+
72
+ - **Caller `data-divider` overrides the reflected divider (FR5).** Caller
73
+ props spread after the component's `data-divider`, so a caller value replaces
74
+ it: `data-divider="false"` draws no line yet stops the middle row above
75
+ from collapsing its spacing, where `architecture:public-component-api` INV5
76
+ keeps component-owned behavior from being overwritten.
77
+ - **Nested Layouts inherit the collapse (FR3).** When this footer has no
78
+ divider, Layouts nested in the middle row, including inside a Dialog,
79
+ Drawer, or BottomSheet opened from it, inherit its spacing collapse and sit
80
+ flush against their own dividers (`family:layout-regions` FR6;
81
+ `spec:AST-038` FR7).
82
+
83
+ ## Ownership boundary
84
+
85
+ **Owns**
86
+
87
+ - The footer root, which carries the `layout-footer` target that
88
+ `component:Layout` maps, and its inner padding wrapper.
89
+ - Footer height, divider, inset, and caller-supplied role and label.
90
+
91
+ **Does not own / non-goals**
92
+
93
+ - Slot placement, the Layout-edge inset, content width, and the divider
94
+ default — owned by `component:Layout`.
95
+ - Footer content and its meaning — owned by the caller.
96
+
97
+ ## Public concepts
98
+
99
+ | Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
100
+ | -------- | ------------------------------------- | --------------------------------------------------------------------------- | ----------------------------------------- | ------------------------- | ------------------------ | --------- | -------------------------------- |
101
+ | Divider | `true`, `false`, unset | Draws a line on the footer's block-start edge. | Always | Layout default, else none | `component:LayoutFooter` | Stable | — |
102
+ | Height | number (px); CSS length string; unset | Fixes the footer's block size. | Always | content height | `component:LayoutFooter` | Stable | — |
103
+ | Inset | spacing step; `0`; unset | Uniform padding that replaces the automatic inset; `0` is full bleed. | Always | automatic | `component:LayoutFooter` | Stable | Closed union; rejected by types. |
104
+ | Landmark | caller `role` and `label` | Exposes the footer as the role the caller names, with that accessible name. | Always | none | caller | Stable | — |
105
+
106
+ ## Behavioral and layout contract
107
+
108
+ | ID | Invariant | Basis |
109
+ | --- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
110
+ | FR1 | LayoutFooter renders a root `div` carrying the `layout-footer` target that does not shrink, around an inner `div` that holds the children, has the Layout's content width as its maximum width, and centers within the root. `height` fixes the root's block size, with numbers as pixels. | Current source and tests |
111
+ | FR2 | Without `padding`, the inner wrapper's inline and block-end padding is the Layout-edge inset and its block-start padding is the inner inset, where the Layout-edge inset comes from the Layout's `padding`, else the nearest padding container, and the inner inset from the nearest padding container (Card, Section, Dialog, Drawer, or BottomSheet), each spacing step 4 otherwise. A `padding` step replaces all four edges, and `0` removes them. The wrapper publishes container-padding values equal to the padding it applies. | Current source and tests; `family:layout-regions` FR4; `architecture:container-padding` |
112
+ | FR3 | A divider draws a 1px solid `--color-border` line on the root's block-start edge and reflects `data-divider="true"`. `hasDivider` decides; when unset, the nearest Layout `defaultHasDividers` in the same layer decides (the default stops at a layer boundary, `spec:AST-038` FR7); otherwise there is no divider. A footer without a divider lets the middle row above it collapse its block-end spacing. Implementation gap: Layouts nested in that middle row, including inside a Dialog, Drawer, or BottomSheet opened from it, inherit the collapse (`component:LayoutContent` Current-state impact; `spec:AST-038` FR7). | Current source and tests; `family:layout-regions` FR6 |
113
+ | FR4 | `role` and `label` set the root's `role` and `aria-label`; LayoutFooter adds no role of its own. | Current source and tests; `family:layout-regions` FR8 |
114
+ | FR5 | `ref` reaches the root. Supported DOM, data, ARIA, and event props reach the root, `xstyle`, `className`, and `style` compose after component styles, and the reflected `data-divider` stays component-owned (`architecture:public-component-api` INV5). Implementation gap: caller props spread after `data-divider`, so a caller `data-divider` replaces the reflected value and changes the neighbouring spacing collapse (Current-state impact). | Current source and tests; `architecture:public-component-api` INV5–INV8 |
115
+
116
+ ### Allowed variation
117
+
118
+ - **AV1 — Content.** Any caller content may fill the footer.
119
+ - **AV2 — Landmark.** The caller chooses whether the footer is a landmark and
120
+ which one.
121
+
122
+ ### Representative states
123
+
124
+ | State | Required invariant | Allowed variation |
125
+ | -------------------- | ------------------------------------------------------- | ----------------- |
126
+ | Default in Layout | Automatic inset, no divider, no role. | Content. |
127
+ | With divider | Block-start line and `data-divider="true"`. | — |
128
+ | Explicit padding | Uniform padding, published to children. | Step. |
129
+ | Contentinfo landmark | `role="contentinfo"` and the caller's name on the root. | Name. |
130
+
131
+ ### Transformation and precedence order
132
+
133
+ - **ORD1 — Divider.** `hasDivider` → Layout `defaultHasDividers` → none.
134
+ - **ORD2 — Padding.** `padding` → the automatic inset.
135
+
136
+ ### Performance and resources
137
+
138
+ - **PR1 — No external lifecycle.** LayoutFooter reads the divider default from
139
+ its Layout and adds no listener, observer, timer, or measurement.
140
+
141
+ ## Accessibility contract
142
+
143
+ - **AR1 — Explicit landmarks only.** The footer is a landmark only when the
144
+ caller supplies `role`, and it is named only by the caller's `label`
145
+ (`family:layout-regions` FR8).
146
+
147
+ ## Design relationships
148
+
149
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
150
+ | ---------------- | --------------------------------------------------------- | ------------------------ | -------------- | ------------------ |
151
+ | Footer | A fixed footer band with an optional block-start divider. | Current source and docs | Supporting | FR1–FR3 |
152
+
153
+ Theming: the root carries the `layout-footer` target, which `Layout.doc.mjs`
154
+ declares and `component:Layout` maps. `LayoutFooter.doc.mjs` declares no anatomy
155
+ of its own, so no anatomy-theming block is declared here.
156
+
157
+ ## Family and system relationships
158
+
159
+ - `family:layout-regions` owns region boundaries, padding replacement, divider
160
+ spacing, and landmark rules; FR2–FR4 and AR1 apply them.
161
+ - `architecture:container-padding` owns inset publication; FR2 applies it.
162
+ - `component:Layout` owns slot placement, the Layout-edge inset, content
163
+ width, the divider default, and the `layout-footer` target mapping.
164
+ - `architecture:public-component-api` owns caller-input routing; FR5 applies
165
+ it.
166
+
167
+ ## Verification map
168
+
169
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
170
+ | --------- | -------------------------------------------------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------- |
171
+ | FR1 | `LayoutSlots.test.tsx` class test; `contentWidth.test.tsx` LayoutFooter inner-wrapper and divider tests | Default; content width | A lost `layout-footer` class, children placed on the root instead of the inner wrapper, or a divider off the outer element fails. Gap: `height`, the non-shrinking root, the content-width maximum, and centering have no check. | `audit:LayoutFooter/layout` |
172
+ | FR2, ORD2 | Source review | Automatic, explicit, and zero padding | Gap: no test covers the automatic inset, the `padding` replacement, full bleed, or the published values. | `audit:LayoutFooter/layout` |
173
+ | FR3, ORD1 | `LayoutSlots.test.tsx` and `Layout.test.tsx` divider tests | Default; `hasDivider`; Layout default | A missing or unexpected `data-divider`, or an ignored Layout default, fails. Gap: no test covers an explicit `false` beating a Layout default on a footer. Gap: the line's paint and the collapsed spacing above a footer without a divider have no check. No test covers the default stopping at a layer boundary or the inherited nested collapse. | `audit:LayoutFooter/layout` |
174
+ | FR4, AR1 | `LayoutSlots.test.tsx` landmark test; `Layout.a11y.test.tsx` and `Layout.a11y.chromium.spec.ts` `footer-contentinfo` state | Caller `contentinfo` role and label | A lost role or name fails, including at the accessibility tree. Gap: no test asserts that a footer without `role` exposes none. | `audit:LayoutFooter/accessibility` |
175
+ | FR5 | `LayoutSlots.test.tsx` ref test | Ref | A ref on another element fails. Gap: no test covers `className`, `style`, DOM, data, or event props, or the `xstyle` merge order. No test covers a caller `data-divider`. | `audit:LayoutFooter/api` |
176
+ | PR1 | Source review | Every state | Gap: no automated check fails if LayoutFooter adds a listener, timer, or measurement. | `audit:LayoutFooter/behavior` |
177
+
178
+ ## Decision log
179
+
180
+ None recorded. The record describes shipped behavior.
181
+
182
+ ## Open questions
183
+
184
+ None.
185
+
186
+ ## Content boundary
187
+
188
+ This file does not duplicate consumer prop tables/examples, current audit
189
+ results, implementation steps, Layout slot rules, or container-padding
190
+ mechanics. It links to their owners.
@@ -22,7 +22,7 @@ import * as stylex from '@stylexjs/stylex';
22
22
  import {layoutFooterMarker} from './layoutEdges.stylex';
23
23
  import {LayoutDividerContext} from './LayoutDividerContext';
24
24
  import {colorVars, spacingVars} from '../theme/tokens.stylex';
25
- import {mergeProps} from '../utils';
25
+ import {mergeProps} from '../utils/mergeProps';
26
26
  import type {SizeValue, SpacingStep} from '../utils/types';
27
27
  import {themeProps} from '../utils/themeProps';
28
28
  import {