@astryxdesign/core 0.7.5 → 0.7.6-canary.5cd7a15

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 (463) 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/DateInput/DateInput.d.ts.map +1 -1
  18. package/dist/DateInput/DateInput.js +12 -4
  19. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  20. package/dist/DateInput/MonthScroller.js +101 -15
  21. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  22. package/dist/DateInput/TouchDateField.js +8 -3
  23. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  24. package/dist/DateRangeInput/DateRangeInput.js +1 -1
  25. package/dist/DateTimeInput/DateTimeInput.d.ts +5 -2
  26. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  27. package/dist/DateTimeInput/DateTimeInput.js +23 -12
  28. package/dist/DateTimeInput/NativeTimeSegment.d.ts.map +1 -1
  29. package/dist/DateTimeInput/NativeTimeSegment.js +5 -4
  30. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  31. package/dist/DateTimeInput/TouchDateTimeField.js +4 -3
  32. package/dist/Dialog/Dialog.d.ts.map +1 -1
  33. package/dist/Dialog/Dialog.js +34 -9
  34. package/dist/Dialog/DialogHeader.d.ts.map +1 -1
  35. package/dist/Dialog/DialogHeader.js +5 -4
  36. package/dist/Divider/Divider.d.ts.map +1 -1
  37. package/dist/Divider/Divider.js +2 -1
  38. package/dist/Drawer/Drawer.d.ts +1 -0
  39. package/dist/Drawer/Drawer.d.ts.map +1 -1
  40. package/dist/Drawer/Drawer.js +7 -2
  41. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  42. package/dist/DropdownMenu/DropdownMenu.js +4 -1
  43. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts.map +1 -1
  44. package/dist/DropdownMenu/MenuBottomSheetActionList.js +6 -5
  45. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +10 -1
  46. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  47. package/dist/DropdownMenu/lazyMenuBottomSheet.js +16 -2
  48. package/dist/DropdownMenu/renderDropdownItems.d.ts.map +1 -1
  49. package/dist/DropdownMenu/renderDropdownItems.js +21 -16
  50. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  51. package/dist/EmptyState/EmptyState.js +2 -1
  52. package/dist/Field/FieldLabel.d.ts +1 -1
  53. package/dist/Field/FieldLabel.d.ts.map +1 -1
  54. package/dist/Field/FieldLabel.js +4 -4
  55. package/dist/Field/InputClearButton.js +3 -3
  56. package/dist/Field/PanelSearchInput.js +2 -2
  57. package/dist/FieldStatus/FieldStatus.js +2 -2
  58. package/dist/FileInput/FileInput.d.ts.map +1 -1
  59. package/dist/FileInput/FileInput.js +7 -1
  60. package/dist/Heading/Heading.js +1 -1
  61. package/dist/Icon/Icon.js +1 -1
  62. package/dist/Indicator/CheckIndicator.d.ts.map +1 -1
  63. package/dist/Indicator/CheckIndicator.js +2 -1
  64. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  65. package/dist/Indicator/CheckboxIndicator.js +3 -1
  66. package/dist/Indicator/RadioIndicator.d.ts.map +1 -1
  67. package/dist/Indicator/RadioIndicator.js +3 -1
  68. package/dist/Item/Item.d.ts.map +1 -1
  69. package/dist/Item/Item.js +2 -1
  70. package/dist/Item/ItemSwipeLayer.js +1 -1
  71. package/dist/Layout/Layout.js +1 -1
  72. package/dist/Layout/LayoutContent.js +1 -1
  73. package/dist/Layout/LayoutFooter.js +1 -1
  74. package/dist/Layout/LayoutHeader.js +1 -1
  75. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  76. package/dist/Lightbox/Lightbox.js +5 -0
  77. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +5 -4
  78. package/dist/List/List.js +1 -1
  79. package/dist/List/ListItem.js +3 -3
  80. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  81. package/dist/MobileNav/MobileNav.js +7 -2
  82. package/dist/MultiSelector/MultiSelector.d.ts +1 -1
  83. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  84. package/dist/MultiSelector/MultiSelector.js +5 -2
  85. package/dist/NumberInput/NumberInput.d.ts +3 -1
  86. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  87. package/dist/NumberInput/NumberInput.js +3 -3
  88. package/dist/NumberInput/numberParser.d.ts +3 -0
  89. package/dist/NumberInput/numberParser.d.ts.map +1 -1
  90. package/dist/NumberInput/numberParser.js +7 -44
  91. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  92. package/dist/ProgressBar/ProgressBar.js +16 -12
  93. package/dist/Resizable/useResizable.d.ts.map +1 -1
  94. package/dist/Resizable/useResizable.js +28 -2
  95. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  96. package/dist/SegmentedControl/SegmentedControlItem.js +4 -1
  97. package/dist/Selector/useSelectorPresentation.d.ts +8 -1
  98. package/dist/Selector/useSelectorPresentation.d.ts.map +1 -1
  99. package/dist/Selector/useSelectorPresentation.js +20 -4
  100. package/dist/Slider/Slider.d.ts.map +1 -1
  101. package/dist/Slider/Slider.js +7 -1
  102. package/dist/Spinner/Spinner.js +2 -2
  103. package/dist/Stack/Stack.js +1 -1
  104. package/dist/Stack/StackItem.js +1 -1
  105. package/dist/TabList/TabList.d.ts.map +1 -1
  106. package/dist/TabList/TabList.js +16 -1
  107. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  108. package/dist/Table/plugins/columnResize/useTableColumnResize.js +9 -1
  109. package/dist/Text/Text.js +1 -1
  110. package/dist/Text/useTruncation.d.ts.map +1 -1
  111. package/dist/Text/useTruncation.js +23 -5
  112. package/dist/TextArea/TextArea.d.ts +1 -1
  113. package/dist/TextArea/TextArea.d.ts.map +1 -1
  114. package/dist/TextArea/TextArea.js +13 -2
  115. package/dist/TextInput/TextInput.d.ts.map +1 -1
  116. package/dist/TextInput/TextInput.js +3 -3
  117. package/dist/TimeInput/TimeInput.d.ts +6 -2
  118. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  119. package/dist/TimeInput/TimeInput.js +21 -14
  120. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  121. package/dist/TimeInput/TouchTimeField.js +5 -4
  122. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  123. package/dist/Timestamp/Timestamp.js +2 -2
  124. package/dist/Timestamp/TimestampHoverCard.js +4 -4
  125. package/dist/Toast/Toast.d.ts.map +1 -1
  126. package/dist/Toast/Toast.js +60 -20
  127. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  128. package/dist/Toast/ToastViewport.js +82 -51
  129. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  130. package/dist/Tokenizer/Tokenizer.js +13 -2
  131. package/dist/Tokenizer/TokenizerBottomSheet.js +3 -3
  132. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  133. package/dist/Toolbar/Toolbar.js +2 -1
  134. package/dist/Typeahead/Typeahead.d.ts +1 -1
  135. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  136. package/dist/Typeahead/Typeahead.js +9 -1
  137. package/dist/astryx.css +15 -1
  138. package/dist/gestures/GestureArena.d.ts +6 -0
  139. package/dist/gestures/GestureArena.d.ts.map +1 -1
  140. package/dist/gestures/GestureArena.js +39 -0
  141. package/dist/gestures/GestureHost.d.ts +352 -0
  142. package/dist/gestures/GestureHost.d.ts.map +1 -0
  143. package/dist/gestures/GestureHost.js +1773 -0
  144. package/dist/gestures/GestureRecognizer.d.ts +10 -0
  145. package/dist/gestures/GestureRecognizer.d.ts.map +1 -1
  146. package/dist/gestures/GestureRecognizer.js +16 -0
  147. package/dist/gestures/LongPressGestureRecognizer.d.ts +1 -0
  148. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -1
  149. package/dist/gestures/LongPressGestureRecognizer.js +3 -0
  150. package/dist/gestures/PanGestureRecognizer.d.ts +1 -0
  151. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -1
  152. package/dist/gestures/PanGestureRecognizer.js +3 -0
  153. package/dist/gestures/PinchGestureRecognizer.d.ts +31 -0
  154. package/dist/gestures/PinchGestureRecognizer.d.ts.map +1 -0
  155. package/dist/gestures/PinchGestureRecognizer.js +128 -0
  156. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts +71 -0
  157. package/dist/gestures/ScreenEdgePanGestureRecognizer.d.ts.map +1 -0
  158. package/dist/gestures/ScreenEdgePanGestureRecognizer.js +223 -0
  159. package/dist/gestures/SwipeGestureRecognizer.d.ts +37 -0
  160. package/dist/gestures/SwipeGestureRecognizer.d.ts.map +1 -0
  161. package/dist/gestures/SwipeGestureRecognizer.js +148 -0
  162. package/dist/gestures/TapGestureRecognizer.d.ts +1 -0
  163. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -1
  164. package/dist/gestures/TapGestureRecognizer.js +3 -0
  165. package/dist/gestures/VelocityTracker.d.ts +6 -2
  166. package/dist/gestures/VelocityTracker.d.ts.map +1 -1
  167. package/dist/gestures/VelocityTracker.js +7 -3
  168. package/dist/gestures/haptics.d.ts +65 -0
  169. package/dist/gestures/haptics.d.ts.map +1 -0
  170. package/dist/gestures/haptics.js +182 -0
  171. package/dist/gestures/nativeScroll.d.ts +42 -0
  172. package/dist/gestures/nativeScroll.d.ts.map +1 -0
  173. package/dist/gestures/nativeScroll.js +228 -0
  174. package/dist/gestures/touchAction.d.ts +60 -0
  175. package/dist/gestures/touchAction.d.ts.map +1 -0
  176. package/dist/gestures/touchAction.js +157 -0
  177. package/dist/gestures/touchActionRule.d.ts +34 -0
  178. package/dist/gestures/touchActionRule.d.ts.map +1 -0
  179. package/dist/gestures/touchActionRule.js +140 -0
  180. package/dist/gestures/types.d.ts +18 -7
  181. package/dist/gestures/types.d.ts.map +1 -1
  182. package/dist/gestures/types.js +22 -2
  183. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
  184. package/dist/hooks/useAdaptivePresentation.js +4 -1
  185. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  186. package/dist/hooks/useMenuHover.js +12 -1
  187. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  188. package/dist/i18n/generated-locales/en.generated.js +3 -0
  189. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  190. package/dist/i18n/generated-locales/pseudo.generated.js +3 -0
  191. package/dist/motion/animator.d.ts +7 -1
  192. package/dist/motion/animator.d.ts.map +1 -1
  193. package/dist/motion/animator.js +119 -27
  194. package/dist/theme/defineTheme.js +1 -1
  195. package/dist/theme/domainTokens/domainTokenDefaults.d.ts +3 -0
  196. package/dist/theme/domainTokens/domainTokenDefaults.d.ts.map +1 -0
  197. package/dist/theme/domainTokens/domainTokenDefaults.js +19 -0
  198. package/dist/theme/domainTokens/index.d.ts +5 -4
  199. package/dist/theme/domainTokens/index.d.ts.map +1 -1
  200. package/dist/theme/domainTokens/index.js +5 -9
  201. package/dist/utils/focusReturn.d.ts +17 -1
  202. package/dist/utils/focusReturn.d.ts.map +1 -1
  203. package/dist/utils/focusReturn.js +11 -4
  204. package/dist/utils/getNodeText.d.ts +8 -0
  205. package/dist/utils/getNodeText.d.ts.map +1 -0
  206. package/dist/utils/getNodeText.js +37 -0
  207. package/dist/utils/interactionModality.d.ts +11 -2
  208. package/dist/utils/interactionModality.d.ts.map +1 -1
  209. package/dist/utils/interactionModality.js +58 -5
  210. package/dist/utils/plainDate.d.ts +2 -0
  211. package/dist/utils/plainDate.d.ts.map +1 -1
  212. package/dist/utils/plainDate.js +46 -3
  213. package/dist/utils/presentation.d.ts +50 -0
  214. package/dist/utils/presentation.d.ts.map +1 -0
  215. package/dist/utils/presentation.js +125 -0
  216. package/dist/utils/primaryClick.d.ts +11 -0
  217. package/dist/utils/primaryClick.d.ts.map +1 -0
  218. package/dist/utils/primaryClick.js +25 -0
  219. package/dist/utils/timeFormat.d.ts +47 -0
  220. package/dist/utils/timeFormat.d.ts.map +1 -0
  221. package/dist/utils/timeFormat.js +240 -0
  222. package/dist/utils/touchPresentation.d.ts.map +1 -1
  223. package/dist/utils/touchPresentation.js +5 -3
  224. package/dist/utils/touchPresentation.stylex.d.ts +15 -0
  225. package/dist/utils/touchPresentation.stylex.d.ts.map +1 -0
  226. package/dist/utils/touchPresentation.stylex.js +33 -0
  227. package/dist/utils/unicodeDigits.d.ts +20 -0
  228. package/dist/utils/unicodeDigits.d.ts.map +1 -0
  229. package/dist/utils/unicodeDigits.js +70 -0
  230. package/locales/en.json +15 -3
  231. package/locales/pseudo.json +9 -0
  232. package/package.json +5 -4
  233. package/src/AlertDialog/AlertDialog.tsx +6 -5
  234. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +18 -6
  235. package/src/Avatar/Avatar.spec.md +22 -22
  236. package/src/Avatar/Avatar.tsx +18 -1
  237. package/src/Avatar/__tests__/AvatarForcedColors.a11y.chromium.spec.ts +126 -0
  238. package/src/Badge/Badge.doc.mjs +1 -1
  239. package/src/Badge/Badge.tsx +19 -2
  240. package/src/Badge/__tests__/BadgeLargerText.a11y.chromium.spec.ts +260 -0
  241. package/src/BottomSheet/BottomSheet.test.tsx +46 -0
  242. package/src/BottomSheet/BottomSheet.tsx +1 -1
  243. package/src/BottomSheet/BottomSheetPanel.tsx +2 -1
  244. package/src/BottomSheet/useSheetGestures.test.ts +52 -0
  245. package/src/BottomSheet/useSheetGestures.ts +37 -6
  246. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +18 -6
  247. package/src/Button/Button.tsx +4 -4
  248. package/src/Calendar/Calendar.spec.md +87 -48
  249. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +21 -7
  250. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +21 -7
  251. package/src/CheckboxInput/CheckboxInput.tsx +6 -5
  252. package/src/Collapsible/Collapsible.spec.md +2 -0
  253. package/src/Collapsible/CollapsibleGroup.spec.md +57 -29
  254. package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +18 -7
  255. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +18 -6
  256. package/src/ComplexSelector/ComplexSelector.test.tsx +37 -0
  257. package/src/ContextMenu/ContextMenu.test.tsx +35 -0
  258. package/src/DateInput/DateInput.test.tsx +115 -3
  259. package/src/DateInput/DateInput.tsx +29 -14
  260. package/src/DateInput/DateInputTouch.test.tsx +76 -0
  261. package/src/DateInput/MonthScroller.tsx +106 -20
  262. package/src/DateInput/MonthScrollerSettle.test.tsx +165 -0
  263. package/src/DateInput/TouchDateField.tsx +14 -3
  264. package/src/DateInput/__tests__/MonthScrollerSteps.interaction.browser.spec.ts +312 -0
  265. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -3
  266. package/src/DateRangeInput/DateRangeInput.tsx +16 -12
  267. package/src/DateTimeInput/DateTimeInput.doc.mjs +10 -8
  268. package/src/DateTimeInput/DateTimeInput.spec.md +75 -51
  269. package/src/DateTimeInput/DateTimeInput.test.tsx +81 -0
  270. package/src/DateTimeInput/DateTimeInput.tsx +46 -24
  271. package/src/DateTimeInput/NativeTimeSegment.tsx +4 -6
  272. package/src/DateTimeInput/TouchDateTimeField.tsx +3 -7
  273. package/src/Dialog/Dialog.test.tsx +216 -2
  274. package/src/Dialog/Dialog.tsx +42 -9
  275. package/src/Dialog/DialogHeader.tsx +5 -4
  276. package/src/Dialog/__tests__/DialogSecondDocument.a11y.browser.spec.ts +202 -0
  277. package/src/Divider/Divider.tsx +2 -1
  278. package/src/Drawer/Drawer.spec.md +111 -80
  279. package/src/Drawer/Drawer.test.tsx +35 -0
  280. package/src/Drawer/Drawer.tsx +13 -2
  281. package/src/Drawer/DrawerHeader.spec.md +181 -0
  282. package/src/Drawer/__tests__/DrawerNonModalPageScroll.a11y.chromium.spec.ts +267 -0
  283. package/src/DropdownMenu/DropdownMenu.test.tsx +41 -0
  284. package/src/DropdownMenu/DropdownMenu.tsx +7 -1
  285. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +34 -0
  286. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +6 -5
  287. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +19 -7
  288. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +21 -9
  289. package/src/DropdownMenu/lazyMenuBottomSheet.test.ts +53 -0
  290. package/src/DropdownMenu/lazyMenuBottomSheet.ts +23 -6
  291. package/src/DropdownMenu/renderDropdownItems.tsx +24 -19
  292. package/src/EmptyState/EmptyState.tsx +2 -1
  293. package/src/Field/FieldLabel.tsx +5 -4
  294. package/src/Field/InputClearButton.tsx +3 -3
  295. package/src/Field/PanelSearchInput.tsx +2 -2
  296. package/src/FieldStatus/FieldStatus.tsx +2 -2
  297. package/src/FileInput/FileInput.test.tsx +21 -0
  298. package/src/FileInput/FileInput.tsx +4 -1
  299. package/src/FormLayout/FormLayout.spec.md +7 -8
  300. package/src/Heading/Heading.tsx +1 -1
  301. package/src/Icon/Icon.tsx +1 -1
  302. package/src/Indicator/CheckIndicator.spec.md +47 -42
  303. package/src/Indicator/CheckIndicator.tsx +2 -1
  304. package/src/Indicator/CheckboxIndicator.spec.md +40 -37
  305. package/src/Indicator/CheckboxIndicator.tsx +3 -1
  306. package/src/Indicator/Indicator.spec.md +188 -0
  307. package/src/Indicator/RadioIndicator.tsx +3 -1
  308. package/src/Item/Item.tsx +2 -1
  309. package/src/Item/ItemSwipeLayer.tsx +1 -1
  310. package/src/Layout/Layout.spec.md +127 -131
  311. package/src/Layout/Layout.tsx +1 -1
  312. package/src/Layout/LayoutContent.spec.md +205 -0
  313. package/src/Layout/LayoutContent.tsx +1 -1
  314. package/src/Layout/LayoutFooter.spec.md +190 -0
  315. package/src/Layout/LayoutFooter.tsx +1 -1
  316. package/src/Layout/LayoutHeader.spec.md +193 -0
  317. package/src/Layout/LayoutHeader.tsx +1 -1
  318. package/src/Layout/LayoutPanel.spec.md +194 -0
  319. package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +18 -6
  320. package/src/Lightbox/Lightbox.test.tsx +18 -0
  321. package/src/Lightbox/Lightbox.tsx +5 -0
  322. package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +8 -4
  323. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +18 -8
  324. package/src/List/List.tsx +1 -1
  325. package/src/List/ListItem.spec.md +205 -0
  326. package/src/List/ListItem.tsx +3 -3
  327. package/src/MobileNav/MobileNav.test.tsx +15 -0
  328. package/src/MobileNav/MobileNav.tsx +9 -1
  329. package/src/MobileNav/__tests__/MobileNavHeader.a11y.chromium.spec.ts +89 -0
  330. package/src/MoreMenu/MoreMenu.test.tsx +11 -0
  331. package/src/MultiSelector/MultiSelector.spec.md +7 -4
  332. package/src/MultiSelector/MultiSelector.test.tsx +118 -1
  333. package/src/MultiSelector/MultiSelector.tsx +6 -2
  334. package/src/MultiSelector/__tests__/MultiSelector.listbox.a11y.test.tsx +8 -1
  335. package/src/NavMenu/NavHeadingMenu.spec.md +1 -5
  336. package/src/NumberInput/NumberInput.doc.mjs +13 -7
  337. package/src/NumberInput/NumberInput.spec.md +59 -37
  338. package/src/NumberInput/NumberInput.tsx +13 -3
  339. package/src/NumberInput/__tests__/NumberInput.coarse-pointer.a11y.chromium.spec.ts +102 -0
  340. package/src/NumberInput/numberParser.ts +7 -45
  341. package/src/ProgressBar/ProgressBar.test.tsx +108 -32
  342. package/src/ProgressBar/ProgressBar.tsx +58 -10
  343. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +21 -9
  344. package/src/ProgressBar/__tests__/ProgressBarMotion.a11y.chromium.spec.ts +831 -0
  345. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +21 -14
  346. package/src/Resizable/useResizable.test.ts +43 -0
  347. package/src/Resizable/useResizable.ts +32 -9
  348. package/src/SegmentedControl/SegmentedControl.test.tsx +84 -0
  349. package/src/SegmentedControl/SegmentedControlItem.tsx +11 -5
  350. package/src/Selector/Selector.test.tsx +90 -1
  351. package/src/Selector/__tests__/Selector.combobox.a11y.test.tsx +8 -1
  352. package/src/Selector/__tests__/Selector.listbox.a11y.test.tsx +8 -1
  353. package/src/Selector/useSelectorPresentation.ts +31 -3
  354. package/src/SideNav/SideNav.test.tsx +27 -0
  355. package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +176 -51
  356. package/src/Slider/Slider.test.tsx +12 -0
  357. package/src/Slider/Slider.tsx +4 -1
  358. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +19 -7
  359. package/src/Spinner/Spinner.tsx +2 -2
  360. package/src/Stack/Stack.tsx +1 -1
  361. package/src/Stack/StackItem.tsx +1 -1
  362. package/src/TabList/TabList.test.tsx +58 -4
  363. package/src/TabList/TabList.tsx +16 -1
  364. package/src/TabList/__tests__/TabPressPointer.interaction.browser.spec.ts +163 -0
  365. package/src/Table/__tests__/Table.a11y.chromium.spec.ts +18 -6
  366. package/src/Table/plugins/columnResize/useTableColumnResize.test.tsx +22 -0
  367. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +8 -4
  368. package/src/Text/Text.tsx +1 -1
  369. package/src/Text/useTruncation.test.tsx +128 -1
  370. package/src/Text/useTruncation.ts +23 -5
  371. package/src/TextArea/TextArea.spec.md +10 -13
  372. package/src/TextArea/TextArea.test.tsx +60 -0
  373. package/src/TextArea/TextArea.tsx +15 -1
  374. package/src/TextInput/TextInput.test.tsx +21 -0
  375. package/src/TextInput/TextInput.tsx +3 -1
  376. package/src/TimeInput/NativeTimeInput.test.tsx +17 -0
  377. package/src/TimeInput/Presentation.test.tsx +21 -0
  378. package/src/TimeInput/TimeInput.doc.mjs +8 -8
  379. package/src/TimeInput/TimeInput.spec.md +45 -48
  380. package/src/TimeInput/TimeInput.test.tsx +76 -0
  381. package/src/TimeInput/TimeInput.tsx +36 -18
  382. package/src/TimeInput/TouchTimeField.tsx +4 -6
  383. package/src/Timestamp/Timestamp.spec.md +6 -12
  384. package/src/Timestamp/Timestamp.test.tsx +30 -5
  385. package/src/Timestamp/Timestamp.tsx +6 -2
  386. package/src/Timestamp/TimestampHoverCard.tsx +4 -4
  387. package/src/Toast/Toast.spec.md +14 -20
  388. package/src/Toast/Toast.tsx +104 -36
  389. package/src/Toast/ToastViewport.test.tsx +719 -1
  390. package/src/Toast/ToastViewport.tsx +100 -50
  391. package/src/Tokenizer/Tokenizer.spec.md +5 -3
  392. package/src/Tokenizer/Tokenizer.test.tsx +68 -0
  393. package/src/Tokenizer/Tokenizer.tsx +14 -2
  394. package/src/Tokenizer/TokenizerBottomSheet.test.tsx +15 -4
  395. package/src/Tokenizer/TokenizerBottomSheet.tsx +3 -3
  396. package/src/Toolbar/Toolbar.spec.md +5 -6
  397. package/src/Toolbar/Toolbar.test.tsx +30 -0
  398. package/src/Toolbar/Toolbar.tsx +2 -1
  399. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +18 -6
  400. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +18 -7
  401. package/src/TopNav/TopNav.test.tsx +27 -0
  402. package/src/Typeahead/Typeahead.test.tsx +40 -0
  403. package/src/Typeahead/Typeahead.tsx +12 -1
  404. package/src/gestures/GestureArena.ts +35 -0
  405. package/src/gestures/GestureHost.ts +2065 -0
  406. package/src/gestures/GestureRecognizer.ts +18 -0
  407. package/src/gestures/LongPressGestureRecognizer.ts +4 -0
  408. package/src/gestures/PanGestureRecognizer.ts +4 -0
  409. package/src/gestures/PinchGestureRecognizer.ts +148 -0
  410. package/src/gestures/ScreenEdgePanGestureRecognizer.ts +256 -0
  411. package/src/gestures/SwipeGestureRecognizer.ts +197 -0
  412. package/src/gestures/TapGestureRecognizer.ts +4 -0
  413. package/src/gestures/VelocityTracker.ts +10 -3
  414. package/src/gestures/__tests__/GestureHost.test.ts +2087 -0
  415. package/src/gestures/__tests__/PanGestureRecognizer.test.ts +4 -4
  416. package/src/gestures/__tests__/PinchGestureRecognizer.test.ts +74 -0
  417. package/src/gestures/__tests__/ScreenEdgePanGestureRecognizer.test.ts +498 -0
  418. package/src/gestures/__tests__/SwipeGestureRecognizer.test.ts +108 -0
  419. package/src/gestures/__tests__/arena.test.ts +5 -0
  420. package/src/gestures/__tests__/arenaPinchSwipeEdge.test.ts +193 -0
  421. package/src/gestures/__tests__/browser/build-fixture.mjs +46 -0
  422. package/src/gestures/__tests__/browser/fixture.ts +307 -0
  423. package/src/gestures/__tests__/browser/gestures.interaction.browser.spec.ts +1137 -0
  424. package/src/gestures/__tests__/browserNegotiation.test.ts +293 -0
  425. package/src/gestures/__tests__/haptics.test.ts +187 -0
  426. package/src/gestures/__tests__/harness.ts +21 -2
  427. package/src/gestures/__tests__/recognizerKind.test.ts +78 -0
  428. package/src/gestures/__tests__/touchActionRule.test.ts +54 -0
  429. package/src/gestures/haptics.ts +203 -0
  430. package/src/gestures/nativeScroll.ts +277 -0
  431. package/src/gestures/touchAction.ts +191 -0
  432. package/src/gestures/touchActionRule.ts +157 -0
  433. package/src/gestures/types.ts +30 -9
  434. package/src/hooks/useAdaptivePresentation.ts +4 -1
  435. package/src/hooks/useMenuHover.ts +15 -1
  436. package/src/i18n/generated-locales/en.generated.ts +4 -0
  437. package/src/i18n/generated-locales/pseudo.generated.ts +4 -0
  438. package/src/motion/README.md +11 -1
  439. package/src/motion/animator.test.ts +151 -3
  440. package/src/motion/animator.ts +149 -33
  441. package/src/theme/defineTheme.ts +1 -1
  442. package/src/theme/derivedVarRegistry.test.ts +4 -0
  443. package/src/theme/domainTokens/domainTokenDefaults.ts +19 -0
  444. package/src/theme/domainTokens/index.ts +6 -10
  445. package/src/utils/focusReturn.ts +17 -6
  446. package/src/utils/getNodeText.test.ts +24 -0
  447. package/src/utils/getNodeText.ts +37 -0
  448. package/src/utils/interactionModality.test.ts +45 -1
  449. package/src/utils/interactionModality.ts +64 -5
  450. package/src/utils/plainDate.test.ts +90 -0
  451. package/src/utils/plainDate.ts +58 -3
  452. package/src/utils/presentation.test.ts +380 -0
  453. package/src/utils/presentation.ts +180 -0
  454. package/src/utils/pressPaintPriority.test.ts +80 -0
  455. package/src/utils/primaryClick.test.ts +38 -0
  456. package/src/utils/primaryClick.ts +28 -0
  457. package/src/utils/timeFormat.test.ts +204 -0
  458. package/src/utils/timeFormat.ts +314 -0
  459. package/src/utils/touchPresentation.stylex.ts +43 -0
  460. package/src/utils/touchPresentation.test.ts +140 -1
  461. package/src/utils/touchPresentation.ts +5 -3
  462. package/src/utils/unicodeDigits.test.ts +44 -0
  463. package/src/utils/unicodeDigits.ts +71 -0
@@ -1,20 +1,20 @@
1
1
  ---
2
2
  schema_version: 3
3
- template_version: 6
3
+ template_version: 7
4
4
  kind: component
5
5
  id: component:CheckboxIndicator
6
- authority: draft
6
+ authority: current
7
7
  archive_reason: null
8
8
  superseded_by: null
9
- approved_by: null
10
- approved_at: null
9
+ approved_by: cixzhang
10
+ approved_at: 2026-10-31
11
11
  owners: [cixzhang]
12
12
  review_triggers: [public-api, behavior, theming, accessibility, visual]
13
13
  verified_by:
14
14
  [
15
+ packages/core/src/CheckboxInput/CheckboxInput.test.tsx,
15
16
  packages/core/src/Indicator/Indicator.test.tsx,
16
17
  packages/core/src/theme/themingTargets.test.ts,
17
- apps/storybook/stories/Indicator.stories.tsx,
18
18
  ]
19
19
  modules: []
20
20
  families: []
@@ -39,11 +39,11 @@ system_specs: []
39
39
  | Behavior | A decorative checkbox chrome is always rendered. Checked and indeterminate states draw their matching mark unless the shallow `isRenderable()` predicate treats `children` as replacement content. |
40
40
  | End-user impact | People receive one visible checkbox-state cue while the owning control retains all semantics, focus, keyboard, and activation behavior. |
41
41
  | Builder impact | Builders may restyle the canonical targets or replace the named indicator without taking over the owning control's semantics. |
42
- | Compatibility/readiness | The released component and legacy `checkbox` target remain supported. This draft records shipped behavior and introduces no API or runtime change. |
43
- | Review checks | Reject lost `aria-hidden`, missing state marks, dropped passthrough/ref/styling, changed replacement precedence, or removal of the legacy target before its approved window. |
42
+ | Compatibility/readiness | Records shipped behavior; no API, default, or DOM change. Only the canonical `checkbox-indicator` target is emitted. |
43
+ | Review checks | Reject lost `aria-hidden`, missing state marks, dropped passthrough/ref/styling, changed replacement precedence, or a second target alias on the root. |
44
44
  | Governing rules | `architecture:public-component-api/INV1,INV5,INV6,INV8,INV9`; `architecture:component-theming-surface/INV3–INV8,INV12`; `architecture:component-test-sufficiency/INV1–INV7,INV10–INV11`. |
45
45
 
46
- This table is a review projection; the body below is authoritative only after owner approval.
46
+ This table is a review projection; the body below is authoritative.
47
47
 
48
48
  ## Intent
49
49
 
@@ -52,9 +52,10 @@ Render the replaceable, decorative visual that communicates a checkbox owner's u
52
52
  ## Compatibility and migration
53
53
 
54
54
  - Released default preserved: yes
55
- - Compatibility class: observational only; no runtime or public-type change
55
+ - Compatibility class: records shipped behavior; no public prop, default,
56
+ export, or DOM change
56
57
  - Controlled/uncontrolled behavior: not applicable; `state` is supplied by the owner
57
- - Migration decision: the deprecated `checkbox` target remains emitted beside `checkbox-indicator` under `architecture:component-theming-surface/INV12`
58
+ - Migration decision: none
58
59
 
59
60
  Consumer migration instructions belong in consumer docs and release notes.
60
61
 
@@ -73,24 +74,24 @@ Consumer migration instructions belong in consumer docs and release notes.
73
74
 
74
75
  ## Public concepts
75
76
 
76
- | Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
77
- | ------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------------------ | ----------------------------- | ------------------------------------------ | -------------------------------------------------- |
78
- | state | `unchecked`, `checked`, `indeterminate` | Chooses the built-in visual state. | All render paths. | required | `component:CheckboxIndicator` | stable | rejected by the public type |
79
- | size | `sm`, `md` | Selects the 20px or 24px visual box and matching mark geometry. | All states. | `md` | `component:CheckboxIndicator` | stable | rejected by the public type |
80
- | disabled appearance | enabled, disabled | Mirrors the owning control's disabled presentation without creating semantics. | All states. | enabled | `component:CheckboxIndicator` | stable | boolean only |
81
- | replacement content | shallow renderable or empty | Replaces both built-in marks when `isRenderable(children)` returns true. React elements and containers take this branch even when descendants render nothing. | All states. | built-in mark path | `component:CheckboxIndicator` | observed; empty-container policy unsettled | unsupported values follow React rendering behavior |
77
+ | Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
78
+ | ------------------- | --------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------- | ------------------ | ----------------------------- | ----------------------------------------- | -------------------------------------------------- |
79
+ | state | `unchecked`, `checked`, `indeterminate` | Chooses the built-in visual state. | All render paths. | required | `component:CheckboxIndicator` | stable | rejected by the public type |
80
+ | size | `sm`, `md` | Selects the 20px or 24px visual box and matching mark geometry. | All states. | `md` | `component:CheckboxIndicator` | stable | rejected by the public type |
81
+ | disabled appearance | enabled, disabled | Mirrors the owning control's disabled presentation without creating semantics. | All states. | enabled | `component:CheckboxIndicator` | stable | boolean only |
82
+ | replacement content | shallow renderable or empty | Replaces both built-in marks when `isRenderable(children)` returns true. React elements and containers take this branch even when descendants render nothing. | All states. | built-in mark path | `component:CheckboxIndicator` | stable; empty-container policy open (OQ1) | unsupported values follow React rendering behavior |
82
83
 
83
84
  ## Behavioral and layout contract
84
85
 
85
- | ID | Candidate invariant | Basis | Draft review state |
86
- | --- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------ | ------------------ |
87
- | FR1 | The component MUST render one decorative span chrome in every state and MUST set its own `aria-hidden="true"` after caller passthrough. | shipped source; `architecture:public-component-api/INV5` | verify |
88
- | FR2 | `unchecked` MUST show no built-in mark, `checked` MUST show the checkmark, and `indeterminate` MUST show the dash. | shipped source, docs, tests, and stories | verify |
89
- | FR3 | The current implementation uses shallow `isRenderable(children)` replacement precedence: nullish values, booleans, and the empty string keep the state mark; React elements and containers replace it even when descendants render nothing. This draft does not settle whether empty-container behavior should remain public policy. | shipped source and regression tests | verify |
90
- | FR4 | The root MUST preserve supported DOM props, `ref`, `className`, `style`, and `xstyle` while keeping component-owned accessibility precedence. | `architecture:public-component-api/INV5,INV6,INV8` | verify |
91
- | FR5 | The canonical root target MUST be `checkbox-indicator`; `checkbox` MUST remain a same-element deprecated alias until its approved removal window. | `architecture:component-theming-surface/INV4,INV6,INV12` | settled |
92
- | FR6 | Size, checked/indeterminate, and disabled state MUST be reflected on the root target; the check and dash MUST retain their dedicated painting targets. | shipped source; `architecture:component-theming-surface/INV4,INV6` | verify |
93
- | FR7 | State transitions MUST honor reduced motion, and checked/indeterminate marks MUST remain perceivable in forced-colors mode. | shipped source and WCAG 2.2 1.4.11 | verify |
86
+ | ID | Invariant | Basis |
87
+ | --- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
88
+ | FR1 | The component MUST render one decorative span chrome in every state and MUST set its own `aria-hidden="true"` after caller passthrough. | shipped source; `architecture:public-component-api/INV5` |
89
+ | FR2 | `unchecked` MUST show no built-in mark, `checked` MUST show the checkmark, and `indeterminate` MUST show the dash. | shipped source, docs, tests, and stories |
90
+ | FR3 | Replacement uses shallow `isRenderable(children)` precedence: nullish values, booleans, and the empty string keep the state mark; React elements and containers replace it even when descendants render nothing (OQ1). | shipped source and regression tests |
91
+ | FR4 | The root MUST preserve supported DOM props, `ref`, `className`, `style`, and `xstyle` while keeping component-owned accessibility precedence. | `architecture:public-component-api/INV5,INV6,INV8` |
92
+ | FR5 | The root target MUST be `checkbox-indicator`, the only target on that element; no alias target is emitted. | `architecture:component-theming-surface/INV4,INV6`; current tests |
93
+ | FR6 | Size, checked or indeterminate (`data-checked`), and disabled state MUST be reflected on the root target; the check and dash MUST retain their dedicated `checkbox-indicator-check` and `checkbox-indicator-dash` painting targets. | shipped source; `architecture:component-theming-surface/INV4,INV6` |
94
+ | FR7 | State transitions MUST honor reduced motion, and checked/indeterminate marks MUST remain perceivable in forced-colors mode. | shipped source and WCAG 2.2 1.4.11 |
94
95
 
95
96
  ### Allowed variation
96
97
 
@@ -129,32 +130,34 @@ Consumer migration instructions belong in consumer docs and release notes.
129
130
  | Checkmark | Visible checked-state mark | observed shipped representation | supporting state cue | FR2, FR6–FR7 |
130
131
  | Indeterminate mark | Visible partial-state mark | observed shipped representation | supporting state cue | FR2, FR6–FR7 |
131
132
 
132
- The shared `Indicator.doc.mjs` owns anatomy and targets for CheckboxIndicator, CheckIndicator, and RadioIndicator together. This component draft does not add an `anatomy-theming:v1` block while that shared consumer record remains the canonical cross-component inventory; the block is optional during migration. The deprecated `checkbox` alias still maps to the CheckboxIndicator chrome for compatibility and is not a separate anatomy part.
133
+ The shared `Indicator.doc.mjs` lists anatomy and targets for CheckboxIndicator, CheckIndicator, and RadioIndicator together, so this record carries no anatomy-theming map.
133
134
 
134
135
  ## Family and system relationships
135
136
 
136
- - `architecture:component-theming-surface` owns target placement, reflected state, and deprecated-alias compatibility.
137
+ - `architecture:component-theming-surface` owns target placement and reflected state.
138
+ - `component:Indicator` owns the registry name `checkbox` and theme replacement.
137
139
  - `architecture:public-component-api` owns export, passthrough, styling composition, ref, and compatibility requirements.
138
140
  - `architecture:component-test-sufficiency` owns the evidence needed for each critical promise and distinct risk partition.
139
141
 
140
142
  ## Verification map
141
143
 
142
- | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
143
- | -------- | ----------------------------------------------------------- | ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------- |
144
- | FR1, AR1 | `Indicator.test.tsx` decorative-contract cases | every built-in path; hostile `aria-hidden` input | Removing or reordering owned `aria-hidden` exposes duplicate semantics. | `audit:CheckboxIndicator/a11y` |
145
- | FR2–FR3 | `Indicator.test.tsx` state and replacement-content cases | unchecked, checked, indeterminate, empty scalar, visible child | Removing a state mark or choosing the wrong children branch fails observable DOM assertions. | `audit:CheckboxIndicator/behavior` |
146
- | FR4 | `Indicator.test.tsx`, strict lint, and public type checks | neutral DOM props, ref, class/style/xstyle | Passthrough, ref, or styling composition stops reaching the root. | `audit:CheckboxIndicator/api` |
147
- | FR5–FR6 | theming target guards and `Indicator.test.tsx` | canonical/legacy targets; size/state/disabled axes | A target disappears, moves off its painter, or loses reflected state. | `audit:CheckboxIndicator/theming` |
148
- | FR7, AR2 | source review plus exact-head Chromium evidence | light/dark; checked/indeterminate; reduced motion; forced colors | Motion persists under reduced motion or a state mark disappears in forced colors. | `audit:CheckboxIndicator/design-rendered` |
149
- | All | `Indicator.stories.tsx`, component-scoped axe and RTL audit | all states, sizes, disabled, replacement content | A required rendered state is unreachable or gains an accessibility/RTL failure. | `audit:CheckboxIndicator/testing` |
144
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
145
+ | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------- |
146
+ | FR1, AR1 | `Indicator.test.tsx` decorative-contract cases | Checked state; a caller `aria-hidden={false}` | A checked indicator that a caller can expose fails. Evidence gap: no test checks `aria-hidden` in the unchecked or indeterminate state, or that replacement content is not the only state expression (AR3). | `audit:CheckboxIndicator/accessibility` |
147
+ | FR2, FR3 | `Indicator.test.tsx` default-indicator, replacement, and falsy-children cases | Checked with falsy and real children; checked with a replacement child | A removed checkmark element, a falsy child that suppresses it, or real children that do not replace it fails. Evidence gap: no test looks for the dash element, and since both marks render in every state with their display toggled, no test asserts which mark is visible in each state. | `audit:CheckboxIndicator/behavior` |
148
+ | FR4 | `Indicator.test.tsx` decorative-contract "still forwards ordinary props" cases | Neutral DOM props | A dropped `data-testid`, `id`, or `dir` fails. Evidence gap: no test asserts `ref`, `className`, `style`, or `xstyle` on the root. | `audit:CheckboxIndicator/api` |
149
+ | FR5, FR6 | `Indicator.test.tsx` checkbox-target and canonical-target cases; `themingTargets.test.ts` | Indeterminate at `sm`; canonical target | A missing or aliased `checkbox-indicator` target, or a missing `data-checked="indeterminate"` or `data-size`, fails. Evidence gap: no test asserts `data-checked` in the checked state, checkbox `data-disabled` (the disabled-state case renders RadioIndicator), or the `checkbox-indicator-check` and `checkbox-indicator-dash` targets. | `audit:CheckboxIndicator/theming` |
150
+ | FR7, AR2 | `CheckboxInput.test.tsx` forced-colors cases ("compiles a forced-colors fill so the indeterminate mark survives Windows High Contrast", "compiles a forced-colors color so the checkmark survives Windows High Contrast") | Checked and indeterminate under forced colors | Evidence gap: the forced-colors cases pass on any matching injected rule, so removing the checkmark and dash `CanvasText` rules still passes; no test asserts the reduced-motion transition. | `audit:CheckboxIndicator/visual` |
151
+ | ORD1, PR1 | Covered by the FR1–FR4 rows. Evidence gap: no test asserts the absence of state, effects, or listeners | — | — | `audit:CheckboxIndicator/behavior` |
150
152
 
151
153
  ## Decision log
152
154
 
153
- None. This draft records only verified shipped behavior.
155
+ No component-local decision.
154
156
 
155
157
  ## Open questions
156
158
 
157
- - Whether empty React containers should continue to suppress the built-in state mark is intentionally unsettled; this observational draft records the current branch without approving it as future policy.
159
+ - **OQ1 — Should an empty React container in `children` keep suppressing the
160
+ built-in state mark?** (`human-api`) FR3 records that it does today.
158
161
 
159
162
  ## Content boundary
160
163
 
@@ -16,7 +16,9 @@ import {
16
16
  easeVars,
17
17
  radiusVars,
18
18
  } from '../theme/tokens.stylex';
19
- import {isRenderable, mergeProps, themeProps} from '../utils';
19
+ import {isRenderable} from '../utils/isRenderable';
20
+ import {mergeProps} from '../utils/mergeProps';
21
+ import {themeProps} from '../utils/themeProps';
20
22
  import {indicatorScope} from './indicator.markers.stylex';
21
23
  import type {IndicatorProps} from './types';
22
24
 
@@ -0,0 +1,188 @@
1
+ ---
2
+ schema_version: 3
3
+ template_version: 7
4
+ kind: component
5
+ id: component:Indicator
6
+ authority: current
7
+ archive_reason: null
8
+ superseded_by: null
9
+ approved_by: cixzhang
10
+ approved_at: 2026-10-31
11
+ owners: [cixzhang]
12
+ review_triggers: [public-api, behavior, theming, accessibility]
13
+ verified_by:
14
+ [
15
+ packages/core/src/Indicator/Indicator.test.tsx,
16
+ packages/core/src/Indicator/indicatorRegistry.test.tsx,
17
+ packages/core/src/theme/themingTargets.test.ts,
18
+ ]
19
+ modules: []
20
+ families: []
21
+ design_specs: []
22
+ architecture:
23
+ [
24
+ architecture:component-theming-surface,
25
+ architecture:public-component-api,
26
+ architecture:theme-authoring-contract,
27
+ ]
28
+ contributing: []
29
+ system_specs: []
30
+ ---
31
+
32
+ # Indicator component contract
33
+
34
+ ## Contract at a glance
35
+
36
+ | Area | Contract |
37
+ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
38
+ | Public contract | None changes. `@astryxdesign/core/Indicator` exports the three built-in indicators (`CheckboxIndicator`, `CheckIndicator`, `RadioIndicator`), the shared indicator props and types, the default registry, and name-based resolution. |
39
+ | Behavior | Hosts draw a decorative control visual by name (`check`, `checkbox`, `radio`). A theme's `indicators` entry for that name replaces it in every host that resolves indicators by name; otherwise the built-in renders. Every indicator is hidden from assistive technology. |
40
+ | End-user impact | People see one consistent mark for a chosen option, a checkbox, or a radio across the components that resolve indicators by name, and screen-reader users hear the host control's semantics, never a duplicate. |
41
+ | Builder impact | None. |
42
+ | Compatibility/readiness | Records shipped behavior; no API, default, or DOM change. Three hosts render the built-ins directly instead of resolving by name; listed under Current-state impact. |
43
+ | Review checks | Reject an indicator that is exposed to assistive technology, a theme override that a host resolving by name ignores, a falsy `children` that suppresses the built-in mark, or a role or tab stop on an indicator. |
44
+ | Governing rules | `architecture:component-theming-surface`; `architecture:public-component-api` INV5; `architecture:theme-authoring-contract`. |
45
+
46
+ This table is a review projection; the body below is authoritative.
47
+
48
+ ## Intent
49
+
50
+ Indicator is the shared, replaceable set of decorative control visuals: the
51
+ mark on a chosen option, the box a checkbox draws, and the circle a radio
52
+ draws. It owns the indicator names, theme replacement by name, the shared
53
+ decorative prop contract, and RadioIndicator. Consumer usage lives in
54
+ `Indicator.doc.mjs`.
55
+
56
+ ## Compatibility and migration
57
+
58
+ - Released default preserved: `yes`; with no theme override, `check`,
59
+ `checkbox`, and `radio` resolve to the built-ins
60
+ - Compatibility class: records shipped behavior; no public prop, default,
61
+ export, or DOM change
62
+ - Controlled/uncontrolled behavior: not applicable; hosts supply `state`
63
+ - Migration decision: none
64
+
65
+ Consumer migration instructions belong in consumer docs and release notes.
66
+
67
+ ## Ownership boundary
68
+
69
+ **Owns**
70
+
71
+ - The core indicator names and the default registry that maps them to the
72
+ built-ins.
73
+ - Theme replacement by name and the shared indicator prop contract.
74
+ - RadioIndicator, documented as an inline component of `Indicator.doc.mjs`,
75
+ with the `radio-indicator` and `radio-indicator-dot` targets.
76
+ - The `indicatorScope` marker hosts put on the element whose hover drives the
77
+ indicator's hover tint.
78
+
79
+ **Does not own / non-goals**
80
+
81
+ - CheckboxIndicator — owned by `component:CheckboxIndicator`.
82
+ - CheckIndicator — owned by `component:CheckIndicator`.
83
+ - Role, name, state, focus, keyboard, and activation of the host control —
84
+ owned by each host (CheckboxInput, RadioList, Selector, menu rows).
85
+ - `useIndicator` and `getIndicator` as API — a public hook and function without
86
+ their own module records; uncontracted beyond the resolution FR2 states.
87
+
88
+ ## Public concepts
89
+
90
+ | Concept | Closed values or states | Meaning | Availability by variant/orientation/state | Default | Owner | Stability | Invalid-value behavior |
91
+ | ------------------- | ------------------------------------------------------ | ------------------------------------------------- | ----------------------------------------- | -------- | --------------------- | --------- | ------------------------------------------------------------------- |
92
+ | Indicator name | `check`, `checkbox`, `radio`, plus augmented names | Which visual a host draws. | Always. | — | `component:Indicator` | Stable | An augmented name no theme supplies resolves to nothing. |
93
+ | State | `unchecked`, `checked`, and `indeterminate` (checkbox) | The host's selection state. | Per indicator family. | required | `component:Indicator` | Stable | TypeScript rejects values outside the family. |
94
+ | Size | `sm`, `md` | Indicator box size. | Always. | `md` | `component:Indicator` | Stable | TypeScript rejects other values. |
95
+ | Replacement content | renderable `children` | Content drawn instead of the built-in state mark. | Always. | none | `component:Indicator` | Stable | Nullish, boolean, and empty-string children keep the built-in mark. |
96
+
97
+ ## Behavioral and layout contract
98
+
99
+ | ID | Invariant | Basis |
100
+ | --- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------- |
101
+ | FR1 | The default registry maps exactly `check` → CheckIndicator, `checkbox` → CheckboxIndicator, and `radio` → RadioIndicator. | Current tests |
102
+ | FR2 | A host resolves an indicator by name from the nearest theme: the theme's `indicators` entry for that name wins, otherwise the built-in. One override reaches every host that resolves that name. The Tokenizer bottom sheet and the Lab MobileTokenizer and MobilePowerSearch value editor render CheckboxIndicator and RadioIndicator directly, so a theme's `checkbox` or `radio` entry does not reach them. An augmented name resolves only when a theme supplies it. | `architecture:theme-authoring-contract`; current tests |
103
+ | FR3 | Every built-in indicator root sets `aria-hidden="true"` after caller props, so a caller cannot expose it; the public props type rejects `role` and `tabIndex`. Indicators receive `state`, `size`, `isDisabled`, and `children` and nothing that would give them semantics. | `architecture:public-component-api` INV5; current tests |
104
+ | FR4 | Renderable `children` replace the built-in state mark inside the indicator; nullish, boolean, and empty-string children keep it, and `0` counts as content. | Current tests |
105
+ | FR5 | RadioIndicator renders one circular span (20 or 24 CSS px) whose border and fill follow the state: an emphasized border on the surface when unchecked, an accent fill when checked with an on-accent dot (8 or 10 CSS px) inside. Disabled halves the opacity and mutes the border (and the fill when unchecked). Under a hover-capable pointer, hovering the host's `indicatorScope` tints it. The dot stays visible under forced colors. Transitions are instant under reduced motion. | Current source and tests |
106
+ | FR6 | RadioIndicator's root carries `astryx-radio-indicator` with `data-size`, `data-checked`, and `data-disabled`; the dot carries `astryx-radio-indicator-dot` with `data-size`. No alias target is emitted. Caller props, `ref`, `className`, `style`, and `xstyle` reach the root. | `architecture:component-theming-surface`; current tests |
107
+
108
+ ### Allowed variation
109
+
110
+ - **AV1 — Replacement.** A theme may replace any named indicator with a
111
+ component that honors FR3.
112
+ - **AV2 — Theme paint.** Themes may restyle the built-ins through their
113
+ targets without replacing them.
114
+
115
+ ### Representative states
116
+
117
+ | State | Required invariant | Allowed variation |
118
+ | ----------------- | ----------------------------------------------------- | ----------------- |
119
+ | No theme override | Built-ins render for each name. | — |
120
+ | Theme override | Every host that resolves the name draws the override. | Override design. |
121
+ | Radio checked | Accent circle with dot; `data-checked`. | Size. |
122
+ | Falsy children | Built-in mark still renders. | — |
123
+
124
+ ### Transformation and precedence order
125
+
126
+ - **ORD1 — Resolution.** Nearest theme's `indicators[name]`, then the built-in,
127
+ then nothing for an unsupplied augmented name.
128
+ - **ORD2 — Attributes.** Caller props, then the indicator's own `aria-hidden`.
129
+
130
+ ### Performance and resources
131
+
132
+ - **PR1 — Pure render.** Indicators own no state, effect, listener, or
133
+ observer.
134
+
135
+ ## Accessibility contract
136
+
137
+ - **AR1 — Decorative.** Indicators are hidden from assistive technology; the
138
+ host owns all semantics (FR3).
139
+ - **AR2 — Forced colors.** The radio dot stays visible under forced colors.
140
+
141
+ ## Design relationships
142
+
143
+ | Anatomy or state | Design requirement | Representation authority | Hierarchy role | Component contract |
144
+ | ---------------- | ------------------------------------------------- | ------------------------ | -------------- | ------------------ |
145
+ | Radio circle | Emphasized border unchecked; accent fill checked. | Current source | Supporting | FR5, FR6 |
146
+ | Radio dot | On-accent dot when checked. | Current source | Supporting | FR5, FR6 |
147
+
148
+ No design record governs Indicator. The checkbox and check visuals are owned by
149
+ their own records.
150
+
151
+ ## Family and system relationships
152
+
153
+ - `architecture:theme-authoring-contract` owns how a theme supplies
154
+ `indicators`.
155
+ - `component:CheckboxIndicator` and `component:CheckIndicator` own the other two
156
+ built-ins.
157
+ - CheckboxInput, RadioListItem, Selector, and menu selection rows host
158
+ indicators.
159
+
160
+ ## Verification map
161
+
162
+ | Contract | Verification | Representative states | Mutation or failure expectation | Audit section |
163
+ | --------------- | ---------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------- |
164
+ | FR1, FR2 | `indicatorRegistry.test.tsx`; `Indicator.test.tsx` useIndicator suite | No theme; theme override; augmented names | A wrong default, an ignored override, or a resolved unsupplied name fails. | `audit:Indicator/behavior` |
165
+ | FR3 | `Indicator.test.tsx` decorative-contract suite | Each built-in in the checked state; a caller `aria-hidden={false}`; `role` and `tabIndex` as literal props | An indicator a caller can expose, a dropped ordinary prop, or an accepted literal `role` or `tabIndex` fails. Evidence gap: no test checks `aria-hidden` on the unchecked states. | `audit:Indicator/accessibility` |
166
+ | FR4 | `Indicator.test.tsx` falsy-children suite | `null`, `false`, `''`, `0`, real children | A falsy child (`false`, `null`, `undefined`, or `''`) that suppresses any built-in's mark fails, and CheckIndicator treating `0` as empty fails. Evidence gap: no test renders `0` as children of CheckboxIndicator or RadioIndicator. | `audit:Indicator/behavior` |
167
+ | FR5, FR6, AR2 | `Indicator.test.tsx` radio-dot, disabled, and target-name cases | Checked and unchecked; disabled; canonical targets | A dot when unchecked, no dot when checked, a missing checked `data-checked` or disabled `data-disabled`, or an alias target fails. Evidence gap: no test asserts the radio sizes, the state colors (emphasized border, accent fill, on-accent dot), the instant transitions under reduced motion, the disabled opacity and border, the hover tint, the forced-colors dot (the RadioList forced-colors case passes on any matching rule), radio `data-size` on the root and dot, `ref`, or caller `className`, `style`, and `xstyle` on the root. | `audit:Indicator/theming` |
168
+ | ORD1, ORD2, PR1 | Covered by the FR2 and FR3 rows. Evidence gap: no test asserts the absence of state, effects, or listeners | — | — | `audit:Indicator/behavior` |
169
+
170
+ ## Current-state impact
171
+
172
+ - **Direct indicator imports (FR2).** The Tokenizer bottom sheet and the Lab
173
+ MobileTokenizer and MobilePowerSearch value editor render CheckboxIndicator
174
+ and RadioIndicator directly, so a theme's `checkbox` or `radio` override does
175
+ not reach them.
176
+
177
+ ## Decision log
178
+
179
+ No component-local decision.
180
+
181
+ ## Open questions
182
+
183
+ None.
184
+
185
+ ## Content boundary
186
+
187
+ This file does not duplicate consumer prop tables/examples, current audit
188
+ results, implementation steps, or family/system rules. It links to their owners.
@@ -16,7 +16,9 @@ import {
16
16
  easeVars,
17
17
  radiusVars,
18
18
  } from '../theme/tokens.stylex';
19
- import {isRenderable, mergeProps, themeProps} from '../utils';
19
+ import {isRenderable} from '../utils/isRenderable';
20
+ import {mergeProps} from '../utils/mergeProps';
21
+ import {themeProps} from '../utils/themeProps';
20
22
  import {indicatorScope} from './indicator.markers.stylex';
21
23
  import type {IndicatorProps} from './types';
22
24
 
package/src/Item/Item.tsx CHANGED
@@ -48,7 +48,8 @@ import {
48
48
  typeScaleVars,
49
49
  } from '../theme/tokens.stylex';
50
50
  import type {BaseProps} from '../BaseProps';
51
- import {isRenderable, mergeProps} from '../utils';
51
+ import {isRenderable} from '../utils/isRenderable';
52
+ import {mergeProps} from '../utils/mergeProps';
52
53
  import {ItemDescriptionContext} from './ItemDescriptionContext';
53
54
  import {ItemMarkerColumnsContext} from './ItemMarkerColumnsContext';
54
55
  import {useMergedRefs} from '../hooks/useMergedRefs';
@@ -29,7 +29,7 @@ import {
29
29
  spacingVars,
30
30
  typeScaleVars,
31
31
  } from '../theme/tokens.stylex';
32
- import {mergeProps} from '../utils';
32
+ import {mergeProps} from '../utils/mergeProps';
33
33
  import {themeProps} from '../utils/themeProps';
34
34
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
35
35
  import {useMediaQuery} from '../hooks/useMediaQuery';