@astryxdesign/core 0.7.4 → 0.7.5-canary.04434e7

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 (546) hide show
  1. package/dist/AlertDialog/AlertDialog.d.ts +2 -2
  2. package/dist/AlertDialog/index.d.ts +4 -4
  3. package/dist/AlertDialog/useImperativeAlertDialog.d.ts +1 -1
  4. package/dist/AppShell/AppShell.d.ts +4 -4
  5. package/dist/AppShell/index.d.ts +4 -4
  6. package/dist/AspectRatio/AspectRatio.d.ts +1 -1
  7. package/dist/AspectRatio/index.d.ts +2 -2
  8. package/dist/Avatar/Avatar.d.ts +2 -2
  9. package/dist/Avatar/AvatarStatusDot.d.ts +2 -2
  10. package/dist/Avatar/index.d.ts +4 -4
  11. package/dist/AvatarGroup/AvatarGroup.d.ts +2 -2
  12. package/dist/AvatarGroup/AvatarGroupContext.d.ts +1 -1
  13. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  14. package/dist/AvatarGroup/index.d.ts +6 -6
  15. package/dist/Badge/Badge.d.ts +2 -2
  16. package/dist/Badge/index.d.ts +2 -2
  17. package/dist/Banner/Banner.d.ts +4 -4
  18. package/dist/Banner/index.d.ts +2 -2
  19. package/dist/Blockquote/Blockquote.d.ts +1 -1
  20. package/dist/Blockquote/index.d.ts +2 -2
  21. package/dist/BottomSheet/BottomSheet.d.ts +10 -6
  22. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  23. package/dist/BottomSheet/BottomSheet.js +12 -1
  24. package/dist/BottomSheet/BottomSheetPanel.d.ts +3 -3
  25. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +1 -1
  26. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +2 -2
  27. package/dist/BottomSheet/index.d.ts +4 -4
  28. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +4 -4
  29. package/dist/Breadcrumbs/Breadcrumbs.d.ts +2 -2
  30. package/dist/Breadcrumbs/index.d.ts +12 -12
  31. package/dist/Button/Button.d.ts +4 -4
  32. package/dist/Button/index.d.ts +2 -2
  33. package/dist/ButtonGroup/ButtonGroup.d.ts +4 -4
  34. package/dist/ButtonGroup/index.d.ts +4 -4
  35. package/dist/Calendar/Calendar.d.ts +3 -3
  36. package/dist/Calendar/dayCellUtils.d.ts +1 -1
  37. package/dist/Calendar/getInitialFocusDate.d.ts +2 -2
  38. package/dist/Calendar/getStandaloneShortWeekdayNames.d.ts +1 -1
  39. package/dist/Calendar/hooks/index.d.ts +6 -6
  40. package/dist/Calendar/hooks/useCalendarConstraints.d.ts +2 -2
  41. package/dist/Calendar/hooks/useCalendarDays.d.ts +2 -2
  42. package/dist/Calendar/hooks/useCalendarNavigation.d.ts +2 -2
  43. package/dist/Calendar/index.d.ts +5 -5
  44. package/dist/Calendar/utils.d.ts +1 -1
  45. package/dist/Card/Card.d.ts +4 -4
  46. package/dist/Card/index.d.ts +2 -2
  47. package/dist/Carousel/Carousel.d.ts +2 -2
  48. package/dist/Carousel/index.d.ts +2 -2
  49. package/dist/Center/Center.d.ts +2 -2
  50. package/dist/Center/index.d.ts +2 -2
  51. package/dist/Chat/ChatComposer.d.ts +1 -1
  52. package/dist/Chat/ChatComposerDrawer.d.ts +1 -1
  53. package/dist/Chat/ChatComposerInput.d.ts +4 -4
  54. package/dist/Chat/ChatDictationButton.d.ts +2 -2
  55. package/dist/Chat/ChatLayout.d.ts +1 -1
  56. package/dist/Chat/ChatLayoutScrollButton.d.ts +1 -1
  57. package/dist/Chat/ChatMessage.d.ts +2 -2
  58. package/dist/Chat/ChatMessageBubble.d.ts +2 -2
  59. package/dist/Chat/ChatMessageList.d.ts +3 -3
  60. package/dist/Chat/ChatMessageMetadata.d.ts +1 -1
  61. package/dist/Chat/ChatSendButton.d.ts +1 -1
  62. package/dist/Chat/ChatSystemMessage.d.ts +1 -1
  63. package/dist/Chat/ChatTokenizedText.d.ts +2 -2
  64. package/dist/Chat/ChatToolCalls.d.ts +1 -1
  65. package/dist/Chat/index.d.ts +43 -43
  66. package/dist/Chat/useChatComposerTokens.d.ts +1 -1
  67. package/dist/Chat/useChatDictation.d.ts +1 -1
  68. package/dist/Chat/useChatPasteAsToken.d.ts +1 -1
  69. package/dist/Chat/useTriggerMenu.d.ts +2 -2
  70. package/dist/CheckboxInput/CheckboxInput.d.ts +4 -4
  71. package/dist/CheckboxInput/index.d.ts +2 -2
  72. package/dist/CheckboxList/CheckboxList.d.ts +4 -4
  73. package/dist/CheckboxList/CheckboxListItem.d.ts +2 -2
  74. package/dist/CheckboxList/index.d.ts +4 -4
  75. package/dist/Citation/Citation.d.ts +1 -1
  76. package/dist/Citation/index.d.ts +2 -2
  77. package/dist/ClickableCard/ClickableCard.d.ts +3 -3
  78. package/dist/ClickableCard/index.d.ts +2 -2
  79. package/dist/Code/Code.d.ts +1 -1
  80. package/dist/Code/index.d.ts +1 -1
  81. package/dist/CodeBlock/CodeBlock.d.ts +2 -2
  82. package/dist/CodeBlock/highlightRanges.d.ts +1 -1
  83. package/dist/CodeBlock/index.d.ts +8 -8
  84. package/dist/Collapsible/Collapsible.d.ts +2 -2
  85. package/dist/Collapsible/CollapsibleGroup.d.ts +2 -2
  86. package/dist/Collapsible/index.d.ts +7 -7
  87. package/dist/CommandPalette/CommandPalette.d.ts +2 -2
  88. package/dist/CommandPalette/CommandPaletteContext.d.ts +1 -1
  89. package/dist/CommandPalette/CommandPaletteEmpty.d.ts +1 -1
  90. package/dist/CommandPalette/CommandPaletteFooter.d.ts +1 -1
  91. package/dist/CommandPalette/CommandPaletteGroup.d.ts +1 -1
  92. package/dist/CommandPalette/CommandPaletteInput.d.ts +1 -1
  93. package/dist/CommandPalette/CommandPaletteItem.d.ts +1 -1
  94. package/dist/CommandPalette/CommandPaletteList.d.ts +1 -1
  95. package/dist/CommandPalette/index.d.ts +16 -16
  96. package/dist/ComplexSelector/ComplexSelector.d.ts +5 -5
  97. package/dist/ComplexSelector/index.d.ts +1 -1
  98. package/dist/ContextMenu/ContextMenu.d.ts +4 -4
  99. package/dist/ContextMenu/index.d.ts +9 -9
  100. package/dist/DateInput/DateInput.d.ts +7 -7
  101. package/dist/DateInput/MonthScroller.d.ts +1 -1
  102. package/dist/DateInput/NativeDateField.d.ts +1 -1
  103. package/dist/DateInput/TouchDateField.d.ts +1 -1
  104. package/dist/DateInput/Wheel.d.ts.map +1 -1
  105. package/dist/DateInput/Wheel.js +1 -1
  106. package/dist/DateInput/index.d.ts +2 -2
  107. package/dist/DateInput/monthGeometry.d.ts +1 -1
  108. package/dist/DateRangeInput/DateRangeInput.d.ts +6 -6
  109. package/dist/DateRangeInput/index.d.ts +2 -2
  110. package/dist/DateTimeInput/DateTimeInput.d.ts +6 -6
  111. package/dist/DateTimeInput/NativeDateSegment.d.ts +3 -3
  112. package/dist/DateTimeInput/NativeTimeSegment.d.ts +4 -4
  113. package/dist/DateTimeInput/TouchDateTimeField.d.ts +1 -1
  114. package/dist/DateTimeInput/index.d.ts +2 -2
  115. package/dist/Dialog/Dialog.d.ts +3 -3
  116. package/dist/Dialog/DialogHeader.d.ts +1 -1
  117. package/dist/Dialog/index.d.ts +6 -6
  118. package/dist/Dialog/useImperativeDialog.d.ts +1 -1
  119. package/dist/Divider/Divider.d.ts +2 -2
  120. package/dist/Divider/index.d.ts +2 -2
  121. package/dist/Drawer/Drawer.d.ts +3 -3
  122. package/dist/Drawer/DrawerHeader.d.ts +1 -1
  123. package/dist/Drawer/index.d.ts +4 -4
  124. package/dist/DropdownMenu/DropdownMenu.d.ts +5 -5
  125. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +2 -2
  126. package/dist/DropdownMenu/DropdownMenuDivider.d.ts +1 -1
  127. package/dist/DropdownMenu/DropdownMenuGroup.d.ts +1 -1
  128. package/dist/DropdownMenu/DropdownMenuItem.d.ts +2 -2
  129. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -1
  130. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +12 -7
  131. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  132. package/dist/DropdownMenu/DropdownMenuRadioItem.js +13 -5
  133. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +2 -2
  134. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts +1 -1
  135. package/dist/DropdownMenu/index.d.ts +10 -10
  136. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +2 -2
  137. package/dist/DropdownMenu/renderDropdownItems.d.ts +1 -1
  138. package/dist/DropdownMenu/useMenuDrillIn.d.ts +1 -1
  139. package/dist/EmptyState/EmptyState.d.ts +1 -1
  140. package/dist/EmptyState/index.d.ts +2 -2
  141. package/dist/Field/Field.d.ts +5 -5
  142. package/dist/Field/FieldLabel.d.ts +2 -2
  143. package/dist/Field/PanelSearchInput.d.ts +1 -1
  144. package/dist/Field/fieldInputFamily.testing.d.ts +1 -1
  145. package/dist/Field/fieldParts.d.ts +1 -1
  146. package/dist/Field/index.d.ts +10 -10
  147. package/dist/Field/inputDisabledFocus.d.ts +14 -0
  148. package/dist/Field/inputDisabledFocus.d.ts.map +1 -0
  149. package/dist/Field/inputDisabledFocus.js +19 -0
  150. package/dist/FieldStatus/FieldStatus.d.ts +3 -3
  151. package/dist/FieldStatus/index.d.ts +2 -2
  152. package/dist/FieldStatus/useFieldStatusAnnouncement.d.ts +1 -1
  153. package/dist/FileInput/FileInput.d.ts +4 -4
  154. package/dist/FileInput/index.d.ts +2 -2
  155. package/dist/FormLayout/FormLayout.d.ts +2 -2
  156. package/dist/FormLayout/index.d.ts +4 -4
  157. package/dist/Grid/Grid.d.ts +3 -3
  158. package/dist/Grid/GridSpan.d.ts +1 -1
  159. package/dist/Grid/index.d.ts +4 -4
  160. package/dist/HStack/HStack.d.ts +2 -2
  161. package/dist/HStack/index.d.ts +1 -1
  162. package/dist/Heading/Heading.d.ts +4 -4
  163. package/dist/Heading/index.d.ts +1 -1
  164. package/dist/HoverCard/HoverCard.d.ts +4 -4
  165. package/dist/HoverCard/index.d.ts +4 -4
  166. package/dist/HoverCard/useHoverCard.d.ts +2 -2
  167. package/dist/Icon/Icon.d.ts +3 -3
  168. package/dist/Icon/IconDefaultSizeContext.d.ts +1 -1
  169. package/dist/Icon/defaultIcons.d.ts +1 -1
  170. package/dist/Icon/globalIconRegistry.d.ts +1 -1
  171. package/dist/Icon/index.d.ts +5 -5
  172. package/dist/Icon/useIcon.d.ts +1 -1
  173. package/dist/IconButton/IconButton.d.ts +1 -1
  174. package/dist/IconButton/index.d.ts +2 -2
  175. package/dist/Indicator/CheckIndicator.d.ts +1 -1
  176. package/dist/Indicator/CheckboxIndicator.d.ts +1 -1
  177. package/dist/Indicator/RadioIndicator.d.ts +1 -1
  178. package/dist/Indicator/index.d.ts +8 -8
  179. package/dist/Indicator/indicatorRegistry.d.ts +2 -2
  180. package/dist/Indicator/types.d.ts +1 -1
  181. package/dist/Indicator/useIndicator.d.ts +2 -2
  182. package/dist/InputGroup/InputGroup.d.ts +2 -2
  183. package/dist/InputGroup/InputGroupText.d.ts +1 -1
  184. package/dist/InputGroup/index.d.ts +6 -6
  185. package/dist/InteractiveRoleContext/InteractiveRoleContext.d.ts +1 -1
  186. package/dist/InteractiveRoleContext/index.d.ts +1 -1
  187. package/dist/Item/Item.d.ts +1 -1
  188. package/dist/Item/ItemSwipeLayer.d.ts +2 -2
  189. package/dist/Item/index.d.ts +2 -2
  190. package/dist/Kbd/Kbd.d.ts +1 -1
  191. package/dist/Kbd/index.d.ts +2 -2
  192. package/dist/Layer/LayerProvider.d.ts +1 -1
  193. package/dist/Layer/index.d.ts +18 -18
  194. package/dist/Layer/layerInset.d.ts +1 -1
  195. package/dist/Layer/layerSlideRules.d.ts +1 -1
  196. package/dist/Layer/modalOutlet.d.ts +1 -1
  197. package/dist/Layer/modalOutlet.js +1 -1
  198. package/dist/Layer/useLayerDismissal.d.ts +1 -1
  199. package/dist/Layer/useTouchTrigger.d.ts +14 -1
  200. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  201. package/dist/Layer/useTouchTrigger.js +72 -17
  202. package/dist/Layout/Layout.d.ts +2 -2
  203. package/dist/Layout/LayoutContent.d.ts +2 -2
  204. package/dist/Layout/LayoutFooter.d.ts +2 -2
  205. package/dist/Layout/LayoutHeader.d.ts +2 -2
  206. package/dist/Layout/LayoutPanel.d.ts +3 -3
  207. package/dist/Layout/index.d.ts +29 -29
  208. package/dist/Layout/padding.stylex.d.ts +1 -1
  209. package/dist/Lightbox/Lightbox.d.ts +1 -1
  210. package/dist/Lightbox/index.d.ts +4 -4
  211. package/dist/Lightbox/useLightbox.d.ts +1 -1
  212. package/dist/Link/Link.d.ts +3 -3
  213. package/dist/Link/LinkContext.d.ts +1 -1
  214. package/dist/Link/LinkProvider.d.ts +1 -1
  215. package/dist/Link/index.d.ts +8 -8
  216. package/dist/Link/useLinkComponent.d.ts +1 -1
  217. package/dist/List/List.d.ts +3 -3
  218. package/dist/List/ListItem.d.ts +2 -2
  219. package/dist/List/index.d.ts +4 -4
  220. package/dist/Markdown/Markdown.d.ts +4 -4
  221. package/dist/Markdown/headingProjection.d.ts +3 -3
  222. package/dist/Markdown/index.d.ts +7 -7
  223. package/dist/Markdown/parser/index.d.ts +3 -3
  224. package/dist/Markdown/parser.d.ts +3 -3
  225. package/dist/Markdown/plugin-renderer/MarkdownPluginNodeRenderer.d.ts +1 -1
  226. package/dist/Markdown/plugin-renderer/index.d.ts +2 -2
  227. package/dist/Markdown/plugins/frontmatter.d.ts +2 -2
  228. package/dist/Markdown/plugins/headingLinks.d.ts +2 -2
  229. package/dist/Markdown/plugins/index.d.ts +14 -14
  230. package/dist/Markdown/plugins/protocol.d.ts +1 -1
  231. package/dist/Markdown/plugins/semanticFence.d.ts +2 -2
  232. package/dist/Markdown/plugins/softBreaks.d.ts +1 -1
  233. package/dist/Markdown/plugins/sourceDecoration.d.ts +2 -2
  234. package/dist/Markdown/plugins/sourceLines.d.ts +1 -1
  235. package/dist/Markdown/plugins/textTransform.d.ts +2 -2
  236. package/dist/Markdown/remark.d.ts +1 -1
  237. package/dist/Markdown/utils.d.ts +4 -4
  238. package/dist/MetadataList/MetadataList.d.ts +2 -2
  239. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  240. package/dist/MetadataList/index.d.ts +5 -5
  241. package/dist/MobileNav/MobileNav.d.ts +1 -1
  242. package/dist/MobileNav/MobileNavToggle.d.ts +1 -1
  243. package/dist/MobileNav/index.d.ts +4 -4
  244. package/dist/MoreMenu/MoreMenu.d.ts +4 -4
  245. package/dist/MoreMenu/index.d.ts +1 -1
  246. package/dist/MultiSelector/MultiSelector.d.ts +7 -7
  247. package/dist/MultiSelector/hooks.d.ts +1 -1
  248. package/dist/MultiSelector/index.d.ts +3 -3
  249. package/dist/MultiSelector/types.d.ts +1 -1
  250. package/dist/NavIcon/NavIcon.d.ts +1 -1
  251. package/dist/NavIcon/index.d.ts +2 -2
  252. package/dist/NavMenu/NavHeadingMenu.d.ts +2 -2
  253. package/dist/NavMenu/NavHeadingMenuItem.d.ts +2 -2
  254. package/dist/NavMenu/index.d.ts +6 -6
  255. package/dist/NumberInput/NumberInput.d.ts +8 -8
  256. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  257. package/dist/NumberInput/NumberInput.js +46 -20
  258. package/dist/NumberInput/index.d.ts +2 -2
  259. package/dist/NumberInput/numberInputCommit.d.ts +1 -1
  260. package/dist/NumberInput/numberParser.d.ts +1 -1
  261. package/dist/Outline/Outline.d.ts +3 -3
  262. package/dist/Outline/index.d.ts +7 -7
  263. package/dist/Outline/parseOutlineFromMarkdown.d.ts +2 -2
  264. package/dist/Outline/useOutlineFromDOM.d.ts +1 -1
  265. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -3
  266. package/dist/Outline/useScrollSpy.d.ts +1 -1
  267. package/dist/OverflowList/OverflowList.d.ts +2 -2
  268. package/dist/OverflowList/index.d.ts +2 -2
  269. package/dist/Overlay/Overlay.d.ts +2 -2
  270. package/dist/Overlay/index.d.ts +5 -5
  271. package/dist/Overlay/useOverlay.d.ts +1 -1
  272. package/dist/Pagination/Pagination.d.ts +2 -2
  273. package/dist/Pagination/index.d.ts +2 -2
  274. package/dist/Popover/Popover.d.ts +3 -3
  275. package/dist/Popover/index.d.ts +4 -4
  276. package/dist/Popover/usePopover.d.ts +2 -2
  277. package/dist/PowerSearch/PowerSearch.d.ts +5 -5
  278. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +2 -2
  279. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts +1 -1
  280. package/dist/PowerSearch/PowerSearchToken.d.ts +1 -1
  281. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +2 -2
  282. package/dist/PowerSearch/formatFilterValue.d.ts +3 -3
  283. package/dist/PowerSearch/index.d.ts +8 -8
  284. package/dist/PowerSearch/resolveDateTimeRangePart.d.ts +1 -1
  285. package/dist/PowerSearch/resolveOperatorLabel.d.ts +2 -2
  286. package/dist/PowerSearch/types.d.ts +1 -1
  287. package/dist/PowerSearch/useInternalConfig.d.ts +1 -1
  288. package/dist/PowerSearch/usePowerSearchConfig.d.ts +1 -1
  289. package/dist/PowerSearch/usePowerSearchSource.d.ts +3 -3
  290. package/dist/PowerSearch/utils.d.ts +3 -3
  291. package/dist/ProgressBar/ProgressBar.d.ts +2 -2
  292. package/dist/ProgressBar/index.d.ts +2 -2
  293. package/dist/RadioList/RadioList.d.ts +3 -3
  294. package/dist/RadioList/RadioListItem.d.ts +2 -2
  295. package/dist/RadioList/index.d.ts +4 -4
  296. package/dist/Resizable/ResizeHandle.d.ts +2 -2
  297. package/dist/Resizable/index.d.ts +6 -6
  298. package/dist/Resizable/useResizable.d.ts +2 -2
  299. package/dist/Resizable/utils.d.ts +3 -3
  300. package/dist/ScrollableArea/ScrollableArea.d.ts +3 -3
  301. package/dist/ScrollableArea/index.d.ts +4 -4
  302. package/dist/Section/Section.d.ts +3 -3
  303. package/dist/Section/index.d.ts +2 -2
  304. package/dist/SegmentedControl/SegmentedControl.d.ts +2 -2
  305. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  306. package/dist/SegmentedControl/index.d.ts +5 -5
  307. package/dist/SelectableCard/SelectableCard.d.ts +3 -3
  308. package/dist/SelectableCard/index.d.ts +2 -2
  309. package/dist/Selector/Selector.d.ts +8 -8
  310. package/dist/Selector/SelectorOption.d.ts +1 -1
  311. package/dist/Selector/hooks.d.ts +1 -1
  312. package/dist/Selector/index.d.ts +4 -4
  313. package/dist/Selector/types.d.ts +1 -1
  314. package/dist/Selector/useSelectorPresentation.d.ts +2 -2
  315. package/dist/Selector/utils.d.ts +1 -1
  316. package/dist/SideNav/SideNav.d.ts +3 -3
  317. package/dist/SideNav/SideNavCollapseButton.d.ts +3 -3
  318. package/dist/SideNav/SideNavHeading.d.ts +2 -2
  319. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  320. package/dist/SideNav/SideNavHeading.js +34 -0
  321. package/dist/SideNav/SideNavItem.d.ts +4 -4
  322. package/dist/SideNav/SideNavSection.d.ts +1 -1
  323. package/dist/SideNav/index.d.ts +14 -14
  324. package/dist/SizeContext/index.d.ts +1 -1
  325. package/dist/Skeleton/Skeleton.d.ts +1 -1
  326. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  327. package/dist/Skeleton/Skeleton.js +12 -3
  328. package/dist/Skeleton/index.d.ts +2 -2
  329. package/dist/Slider/Slider.d.ts +3 -3
  330. package/dist/Slider/index.d.ts +2 -2
  331. package/dist/Spinner/Spinner.d.ts +1 -1
  332. package/dist/Spinner/index.d.ts +2 -2
  333. package/dist/Stack/Stack.d.ts +3 -3
  334. package/dist/Stack/StackItem.d.ts +2 -2
  335. package/dist/Stack/index.d.ts +6 -6
  336. package/dist/Stack/stack.stylex.d.ts +1 -1
  337. package/dist/StatusDot/StatusDot.d.ts +2 -2
  338. package/dist/StatusDot/index.d.ts +2 -2
  339. package/dist/Stepper/Step.d.ts +2 -2
  340. package/dist/Stepper/Step.d.ts.map +1 -1
  341. package/dist/Stepper/Step.js +3 -3
  342. package/dist/Stepper/Stepper.d.ts +2 -2
  343. package/dist/Stepper/index.d.ts +7 -7
  344. package/dist/Switch/Switch.d.ts +4 -4
  345. package/dist/Switch/index.d.ts +2 -2
  346. package/dist/TabList/Tab.d.ts +2 -2
  347. package/dist/TabList/TabList.d.ts +3 -3
  348. package/dist/TabList/TabMenu.d.ts +2 -2
  349. package/dist/TabList/index.d.ts +8 -8
  350. package/dist/Table/BaseTable.d.ts +1 -1
  351. package/dist/Table/Table.d.ts +1 -1
  352. package/dist/Table/TableBody.d.ts +1 -1
  353. package/dist/Table/TableCell.d.ts +3 -3
  354. package/dist/Table/TableContext.d.ts +1 -1
  355. package/dist/Table/TableFooter.d.ts +1 -1
  356. package/dist/Table/TableHeader.d.ts +1 -1
  357. package/dist/Table/TableHeaderCell.d.ts +3 -3
  358. package/dist/Table/TableRow.d.ts +2 -2
  359. package/dist/Table/TableSelectionToolbar.d.ts +2 -2
  360. package/dist/Table/columnUtils.d.ts +1 -1
  361. package/dist/Table/index.d.ts +54 -54
  362. package/dist/Table/plugins/columnResize/index.d.ts +2 -2
  363. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts +1 -1
  364. package/dist/Table/plugins/columnSettings/index.d.ts +4 -4
  365. package/dist/Table/plugins/columnSettings/useTableColumnSettings.d.ts +2 -2
  366. package/dist/Table/plugins/columnSettings/useTableColumnSettingsState.d.ts +1 -1
  367. package/dist/Table/plugins/filtering/index.d.ts +4 -4
  368. package/dist/Table/plugins/filtering/useTableFilterState.d.ts +1 -1
  369. package/dist/Table/plugins/filtering/useTableFiltering.d.ts +2 -2
  370. package/dist/Table/plugins/groupedRows/index.d.ts +2 -2
  371. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +1 -1
  372. package/dist/Table/plugins/pagination/index.d.ts +3 -3
  373. package/dist/Table/plugins/pagination/useTablePagination.d.ts +1 -1
  374. package/dist/Table/plugins/rowExpansion/index.d.ts +2 -2
  375. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +1 -1
  376. package/dist/Table/plugins/rowIndex/index.d.ts +2 -2
  377. package/dist/Table/plugins/rowIndex/useTableRowIndex.d.ts +1 -1
  378. package/dist/Table/plugins/rowStatus/index.d.ts +2 -2
  379. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +2 -2
  380. package/dist/Table/plugins/selection/index.d.ts +4 -4
  381. package/dist/Table/plugins/selection/useTableSelection.d.ts +1 -1
  382. package/dist/Table/plugins/selection/useTableSelectionState.d.ts +1 -1
  383. package/dist/Table/plugins/sortable/index.d.ts +4 -4
  384. package/dist/Table/plugins/sortable/useTableSortable.d.ts +1 -1
  385. package/dist/Table/plugins/sortable/useTableSortableState.d.ts +1 -1
  386. package/dist/Table/plugins/stickyColumns/index.d.ts +2 -2
  387. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts +1 -1
  388. package/dist/Table/plugins/tree/index.d.ts +4 -4
  389. package/dist/Table/plugins/tree/useTableTreeData.d.ts +1 -1
  390. package/dist/Table/plugins/tree/useTableTreeState.d.ts +1 -1
  391. package/dist/Table/tableContextMenu.d.ts +2 -2
  392. package/dist/Table/types.d.ts +3 -3
  393. package/dist/Table/useBaseTablePlugins.d.ts +1 -1
  394. package/dist/Table/useTableCellStyles.d.ts +2 -2
  395. package/dist/Table/utils.d.ts +2 -2
  396. package/dist/Text/Text.d.ts +3 -3
  397. package/dist/Text/index.d.ts +4 -4
  398. package/dist/TextArea/TextArea.d.ts +10 -8
  399. package/dist/TextArea/TextArea.d.ts.map +1 -1
  400. package/dist/TextArea/TextArea.js +14 -11
  401. package/dist/TextArea/index.d.ts +2 -2
  402. package/dist/TextInput/TextInput.d.ts +11 -9
  403. package/dist/TextInput/TextInput.d.ts.map +1 -1
  404. package/dist/TextInput/TextInput.js +27 -17
  405. package/dist/TextInput/index.d.ts +2 -2
  406. package/dist/Thumbnail/Thumbnail.d.ts +1 -1
  407. package/dist/Thumbnail/index.d.ts +2 -2
  408. package/dist/TimeInput/TimeInput.d.ts +6 -6
  409. package/dist/TimeInput/TouchTimeField.d.ts +1 -1
  410. package/dist/TimeInput/index.d.ts +3 -3
  411. package/dist/Timer/Timer.d.ts +2 -2
  412. package/dist/Timer/index.d.ts +2 -2
  413. package/dist/Timestamp/Timestamp.d.ts +3 -3
  414. package/dist/Timestamp/TimestampHoverCard.d.ts +1 -1
  415. package/dist/Timestamp/formatInstant.d.ts +2 -2
  416. package/dist/Timestamp/formatRelativeTime.d.ts +1 -1
  417. package/dist/Timestamp/index.d.ts +3 -3
  418. package/dist/Timestamp/tooltipEntries.d.ts +2 -2
  419. package/dist/Toast/Toast.d.ts +2 -2
  420. package/dist/Toast/ToastContext.d.ts +1 -1
  421. package/dist/Toast/ToastViewport.d.ts +2 -2
  422. package/dist/Toast/index.d.ts +6 -6
  423. package/dist/Toast/useToast.d.ts +1 -1
  424. package/dist/ToggleButton/ToggleButton.d.ts +3 -3
  425. package/dist/ToggleButton/ToggleButtonGroup.d.ts +1 -1
  426. package/dist/ToggleButton/index.d.ts +4 -4
  427. package/dist/Token/Token.d.ts +2 -2
  428. package/dist/Token/TokenLink.d.ts +1 -1
  429. package/dist/Token/index.d.ts +2 -2
  430. package/dist/Tokenizer/Tokenizer.d.ts +6 -6
  431. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  432. package/dist/Tokenizer/Tokenizer.js +44 -40
  433. package/dist/Tokenizer/index.d.ts +2 -2
  434. package/dist/Tokenizer/useEndLaneReserve.d.ts +3 -2
  435. package/dist/Tokenizer/useEndLaneReserve.d.ts.map +1 -1
  436. package/dist/Tokenizer/useEndLaneReserve.js +3 -2
  437. package/dist/Toolbar/Toolbar.d.ts +4 -4
  438. package/dist/Toolbar/index.d.ts +2 -2
  439. package/dist/Tooltip/Tooltip.d.ts +3 -3
  440. package/dist/Tooltip/index.d.ts +4 -4
  441. package/dist/Tooltip/useTooltip.d.ts +2 -2
  442. package/dist/TopNav/TopNav.d.ts +1 -1
  443. package/dist/TopNav/TopNavHeading.d.ts +2 -2
  444. package/dist/TopNav/TopNavItem.d.ts +3 -3
  445. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  446. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +1 -1
  447. package/dist/TopNav/TopNavMegaMenuItem.d.ts +2 -2
  448. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  449. package/dist/TopNav/index.d.ts +16 -16
  450. package/dist/TreeList/TreeList.d.ts +3 -3
  451. package/dist/TreeList/TreeListItem.d.ts +1 -1
  452. package/dist/TreeList/TreeListTypes.d.ts +1 -1
  453. package/dist/TreeList/index.d.ts +3 -3
  454. package/dist/Typeahead/BaseTypeahead.d.ts +2 -2
  455. package/dist/Typeahead/Typeahead.d.ts +6 -6
  456. package/dist/Typeahead/TypeaheadItem.d.ts +2 -2
  457. package/dist/Typeahead/createStaticSource.d.ts +1 -1
  458. package/dist/Typeahead/index.d.ts +9 -9
  459. package/dist/Typeahead/utils.d.ts +3 -3
  460. package/dist/VStack/VStack.d.ts +2 -2
  461. package/dist/VStack/index.d.ts +1 -1
  462. package/dist/VisuallyHidden/VisuallyHidden.d.ts +24 -6
  463. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -1
  464. package/dist/VisuallyHidden/VisuallyHidden.js +24 -5
  465. package/dist/VisuallyHidden/index.d.ts +2 -2
  466. package/dist/astryx.css +8 -16
  467. package/dist/hooks/index.d.ts +52 -52
  468. package/dist/hooks/useAutoMediaMode.d.ts +1 -1
  469. package/dist/hooks/useInputContainer.d.ts +1 -1
  470. package/dist/hooks/useInputStatusIcon.d.ts +3 -3
  471. package/dist/hooks/useMenuPress.d.ts +1 -1
  472. package/dist/hooks/usePressFeedback.d.ts +1 -1
  473. package/dist/hooks/useScrollableArea.d.ts +1 -1
  474. package/dist/i18n/InternationalizationContext.d.ts +2 -2
  475. package/dist/i18n/InternationalizationProvider.d.ts +1 -1
  476. package/dist/i18n/index.d.ts +12 -12
  477. package/dist/i18n/resolve.d.ts +1 -1
  478. package/dist/i18n/useLocale.d.ts +1 -1
  479. package/dist/index.d.ts +111 -111
  480. package/dist/theme/Theme.d.ts +2 -2
  481. package/dist/theme/contrast.d.ts +1 -1
  482. package/dist/theme/defineTheme.d.ts +12 -12
  483. package/dist/theme/domainTokens/index.d.ts +6 -6
  484. package/dist/theme/generateThemeRules.d.ts +1 -1
  485. package/dist/theme/index.d.ts +31 -31
  486. package/dist/theme/localTokens.d.ts +1 -1
  487. package/dist/theme/mergeComponents.d.ts +1 -1
  488. package/dist/theme/onMediaTokens.d.ts +1 -1
  489. package/dist/theme/resolveThemeValues.d.ts +7 -7
  490. package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
  491. package/dist/theme/syntax/index.d.ts +7 -7
  492. package/dist/theme/syntax/presets.d.ts +1 -1
  493. package/dist/theme/themeAdaptations.d.ts +5 -5
  494. package/dist/theme/themeRegistry.d.ts +1 -1
  495. package/dist/theme/tokens.d.ts +1 -1
  496. package/dist/theme/types.d.ts +1 -1
  497. package/dist/theme/useTheme.d.ts +2 -2
  498. package/dist/utils/dateParser.d.ts +3 -3
  499. package/dist/utils/groupItems.d.ts +1 -1
  500. package/dist/utils/index.d.ts +29 -29
  501. package/dist/utils/plainDate.d.ts +3 -3
  502. package/package.json +5 -5
  503. package/src/Badge/Badge.doc.mjs +2 -1
  504. package/src/BottomSheet/BottomSheet.tsx +12 -1
  505. package/src/BottomSheet/__tests__/BottomSheetToastOutlet.a11y.chromium.spec.ts +82 -0
  506. package/src/DateInput/DateInputTouch.test.tsx +9 -0
  507. package/src/DateInput/Wheel.tsx +4 -1
  508. package/src/DateInput/__tests__/WheelPinchZoom.a11y.chromium.spec.ts +158 -0
  509. package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +5 -2
  510. package/src/DropdownMenu/DropdownMenuRadioItem.spec.md +226 -0
  511. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +32 -16
  512. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +158 -0
  513. package/src/DropdownMenu/__tests__/DropdownMenuRadioItemAudit.a11y.chromium.spec.ts +539 -0
  514. package/src/Field/inputDisabledFocus.ts +28 -0
  515. package/src/HoverCard/HoverCard.test.tsx +93 -3
  516. package/src/Icon/Icon.spec.md +40 -29
  517. package/src/Layer/__tests__/TouchTrigger.a11y.chromium.spec.ts +199 -0
  518. package/src/Layer/modalOutlet.ts +1 -1
  519. package/src/Layer/useTouchTrigger.ts +95 -41
  520. package/src/NumberInput/NumberInput.doc.mjs +6 -6
  521. package/src/NumberInput/NumberInput.test.tsx +144 -14
  522. package/src/NumberInput/NumberInput.tsx +68 -21
  523. package/src/Pagination/Pagination.test.tsx +2 -2
  524. package/src/SideNav/SideNav.test.tsx +15 -6
  525. package/src/SideNav/SideNavHeading.tsx +41 -0
  526. package/src/Skeleton/Skeleton.test.tsx +108 -1
  527. package/src/Skeleton/Skeleton.tsx +30 -2
  528. package/src/Stepper/Step.tsx +7 -0
  529. package/src/Stepper/Stepper.test.tsx +33 -0
  530. package/src/TextArea/TextArea.doc.mjs +6 -6
  531. package/src/TextArea/TextArea.test.tsx +65 -6
  532. package/src/TextArea/TextArea.tsx +26 -14
  533. package/src/TextInput/TextInput.doc.mjs +8 -8
  534. package/src/TextInput/TextInput.test.tsx +83 -10
  535. package/src/TextInput/TextInput.tsx +38 -19
  536. package/src/Toast/ToastViewport.modalHost.test.tsx +139 -4
  537. package/src/Tokenizer/Tokenizer.test.tsx +26 -8
  538. package/src/Tokenizer/Tokenizer.tsx +65 -72
  539. package/src/Tokenizer/__tests__/TokenizerEndLane.a11y.chromium.spec.ts +471 -0
  540. package/src/Tokenizer/useEndLaneReserve.ts +3 -2
  541. package/src/Tooltip/Tooltip.test.tsx +148 -3
  542. package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +2 -2
  543. package/src/VisuallyHidden/VisuallyHidden.doc.mjs +1 -1
  544. package/src/VisuallyHidden/VisuallyHidden.test.tsx +39 -0
  545. package/src/VisuallyHidden/VisuallyHidden.tsx +38 -5
  546. package/src/theme/tokens.test.ts +60 -0
@@ -13,6 +13,8 @@ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
13
13
  import {act, useState} from 'react';
14
14
  import {render, screen, fireEvent, waitFor} from '@testing-library/react';
15
15
  import userEvent from '@testing-library/user-event';
16
+ import * as stylex from '@stylexjs/stylex';
17
+ import {colorVars} from '../theme/tokens.stylex';
16
18
  import {TestIcon} from '../__tests__/TestIcon';
17
19
  import {InternationalizationProvider} from '../i18n';
18
20
  import {registerIcons, resetIcons} from '../Icon';
@@ -22,6 +24,21 @@ import {defineTheme} from '../theme/defineTheme';
22
24
  import {generateThemeCSS} from '../theme/generateThemeRules';
23
25
  import {__resetLiveRegionsForTest} from '../hooks/useAnnounce';
24
26
 
27
+ // jsdom cannot match `:focus-visible`: compare the ring's StyleX class hash.
28
+ const RING = stylex
29
+ .props(
30
+ stylex.create({
31
+ ring: {
32
+ boxShadow: {
33
+ default: null,
34
+ ':has(> [aria-disabled="true"]:focus-visible)': `inset 0px 0px 0px 2px ${colorVars['--color-accent-muted']}`,
35
+ },
36
+ },
37
+ }).ring,
38
+ )
39
+ .className!.split(' ')
40
+ .pop()!;
41
+
25
42
  // FieldStatus announces status messages through the persistent useAnnounce
26
43
  // singletons; remove them between tests so role/aria-live queries in this
27
44
  // file never match a leftover region.
@@ -149,7 +166,7 @@ describe('NumberInput', () => {
149
166
  expect(screen.getByRole('spinbutton')).not.toHaveAttribute('aria-required');
150
167
  });
151
168
 
152
- it('sets disabled attribute when isDisabled is true', () => {
169
+ it('exposes aria-disabled, not native disabled, when isDisabled is true (spec:AST-085)', () => {
153
170
  render(
154
171
  <NumberInput
155
172
  label="Quantity"
@@ -158,7 +175,76 @@ describe('NumberInput', () => {
158
175
  onChange={() => {}}
159
176
  />,
160
177
  );
161
- expect(screen.getByRole('spinbutton')).toBeDisabled();
178
+ expect(screen.getByRole('spinbutton')).toHaveAttribute(
179
+ 'aria-disabled',
180
+ 'true',
181
+ );
182
+ });
183
+
184
+ it('keeps a disabled input in the tab order and rings it (spec:AST-085 FR1, FR6)', async () => {
185
+ const user = userEvent.setup();
186
+ render(
187
+ <>
188
+ <NumberInput label="First" value={1} onChange={() => {}} />
189
+ <NumberInput label="Second" value={2} onChange={() => {}} isDisabled />
190
+ </>,
191
+ );
192
+ await user.tab();
193
+ await user.tab();
194
+ const input = screen.getByRole('spinbutton', {name: 'Second'});
195
+ expect(input).toHaveFocus();
196
+ expect(input.parentElement).toHaveClass(RING);
197
+ });
198
+
199
+ it('runs no caller handler, steps nothing and submits no form while disabled (spec:AST-085 FR2)', async () => {
200
+ const user = userEvent.setup();
201
+ const handlers = {
202
+ onChange: vi.fn(),
203
+ onEnter: vi.fn(),
204
+ onKeyDown: vi.fn(),
205
+ onPaste: vi.fn(),
206
+ };
207
+ const onSubmit = vi.fn((e: React.FormEvent) => e.preventDefault());
208
+ render(
209
+ <form onSubmit={onSubmit}>
210
+ <NumberInput
211
+ label="Quantity"
212
+ value={5}
213
+ isDisabled
214
+ hasNumberSteppers
215
+ {...handlers}
216
+ />
217
+ </form>,
218
+ );
219
+ await user.click(screen.getByRole('spinbutton'));
220
+ await user.keyboard('{ArrowUp}{ArrowDown}{Enter}');
221
+ await user.paste('9');
222
+ await user.click(screen.getByRole('button', {name: 'Increment Quantity'}));
223
+ for (const handler of [...Object.values(handlers), onSubmit]) {
224
+ expect(handler).not.toHaveBeenCalled();
225
+ }
226
+ });
227
+
228
+ it('commits nothing when a field disabled mid-entry loses focus (spec:AST-085 FR2)', async () => {
229
+ const user = userEvent.setup();
230
+ const onChange = vi.fn();
231
+ const field = (isDisabled: boolean) => (
232
+ <NumberInput
233
+ label="Quantity"
234
+ value={5}
235
+ onChange={onChange}
236
+ isDisabled={isDisabled}
237
+ />
238
+ );
239
+ const {rerender} = render(field(false));
240
+ const input = screen.getByRole('spinbutton');
241
+ await user.clear(input);
242
+ await user.type(input, '8');
243
+ onChange.mockClear();
244
+ rerender(field(true));
245
+ await user.tab();
246
+ expect(onChange).not.toHaveBeenCalled();
247
+ expect(input).toHaveValue('5');
162
248
  });
163
249
 
164
250
  it('does not fire onChange when disabled', async () => {
@@ -1424,10 +1510,10 @@ describe('NumberInput', () => {
1424
1510
  const increment = screen.getByRole('button', {
1425
1511
  name: 'Increment Quantity',
1426
1512
  });
1427
- expect(increment).toBeDisabled();
1513
+ expect(increment).toHaveAttribute('aria-disabled', 'true');
1428
1514
  expect(
1429
1515
  screen.getByRole('button', {name: 'Decrement Quantity'}),
1430
- ).toBeDisabled();
1516
+ ).toHaveAttribute('aria-disabled', 'true');
1431
1517
 
1432
1518
  fireEvent.click(increment);
1433
1519
  expect(handleChange).not.toHaveBeenCalled();
@@ -1446,7 +1532,10 @@ describe('NumberInput', () => {
1446
1532
  />
1447
1533
  </form>,
1448
1534
  );
1449
- expect(screen.getByRole('spinbutton')).toBeDisabled();
1535
+ expect(screen.getByRole('spinbutton')).toHaveAttribute(
1536
+ 'aria-disabled',
1537
+ 'true',
1538
+ );
1450
1539
  expect([
1451
1540
  ...new FormData(container.querySelector('form')!).keys(),
1452
1541
  ]).toEqual([]);
@@ -1480,6 +1569,24 @@ describe('NumberInput', () => {
1480
1569
  ).toBeInTheDocument();
1481
1570
  });
1482
1571
 
1572
+ it('focuses the field inside the tap that clears it, without scrolling', () => {
1573
+ // iOS Safari brings up its keyboard only for a focus made while
1574
+ // handling the touch.
1575
+ const onChange = vi.fn();
1576
+ const focusSpy = vi.spyOn(HTMLElement.prototype, 'focus');
1577
+ render(
1578
+ <NumberInput label="Qty" value={5} onChange={onChange} hasClear />,
1579
+ );
1580
+ const input = screen.getByRole('spinbutton');
1581
+ fireEvent.click(screen.getByRole('button', {name: 'Clear Qty'}), {
1582
+ detail: 1,
1583
+ });
1584
+ expect(onChange).toHaveBeenCalledWith(null);
1585
+ expect(document.activeElement).toBe(input);
1586
+ expect(focusSpy).toHaveBeenLastCalledWith({preventScroll: true});
1587
+ focusSpy.mockRestore();
1588
+ });
1589
+
1483
1590
  it('does not show clear button when value is null', () => {
1484
1591
  render(
1485
1592
  <NumberInput label="Qty" value={null} onChange={() => {}} hasClear />,
@@ -1693,7 +1800,7 @@ describe('NumberInput', () => {
1693
1800
  expect(onChange).not.toHaveBeenCalled();
1694
1801
  });
1695
1802
 
1696
- it('remains natively disabled when disabled without a reason', () => {
1803
+ it('stays focusable when disabled without a reason', () => {
1697
1804
  render(
1698
1805
  <NumberInput
1699
1806
  label="Quantity"
@@ -1703,8 +1810,8 @@ describe('NumberInput', () => {
1703
1810
  />,
1704
1811
  );
1705
1812
  const input = screen.getByRole('spinbutton');
1706
- expect(input).toBeDisabled();
1707
- expect(input).not.toHaveAttribute('aria-disabled');
1813
+ expect(input).not.toBeDisabled();
1814
+ expect(input).toHaveAttribute('aria-disabled', 'true');
1708
1815
  });
1709
1816
  });
1710
1817
  });
@@ -2006,14 +2113,14 @@ describe('NumberInput stepping', () => {
2006
2113
 
2007
2114
  const input = screen.getByRole('spinbutton');
2008
2115
  const increment = screen.getByRole('button', {name: 'Increment Amount'});
2009
- expect(increment).toBeEnabled();
2116
+ expect(increment).not.toHaveAttribute('aria-disabled');
2010
2117
 
2011
2118
  fireEvent.click(increment);
2012
2119
 
2013
2120
  expect(input).toHaveValue('99.99');
2014
2121
  expect(input).toHaveAttribute('aria-valuenow', '99.99');
2015
2122
  expect(input).not.toHaveAttribute('aria-invalid');
2016
- expect(increment).toBeDisabled();
2123
+ expect(increment).toHaveAttribute('aria-disabled', 'true');
2017
2124
  });
2018
2125
 
2019
2126
  it('allows wheel stepping by default and consumes the focused gesture', () => {
@@ -2259,10 +2366,33 @@ describe('NumberInput stepping', () => {
2259
2366
  );
2260
2367
  expect(
2261
2368
  screen.getByRole('button', {name: 'Increment Quantity'}),
2262
- ).toBeDisabled();
2369
+ ).toHaveAttribute('aria-disabled', 'true');
2263
2370
  expect(
2264
2371
  screen.getByRole('button', {name: 'Decrement Quantity'}),
2265
- ).not.toBeDisabled();
2372
+ ).not.toHaveAttribute('aria-disabled');
2373
+ });
2374
+
2375
+ it('commits nothing from a click on the stepper at the reached boundary (spec:AST-085 FR2)', async () => {
2376
+ const user = userEvent.setup();
2377
+ const onChange = vi.fn();
2378
+ render(
2379
+ <NumberInput
2380
+ label="Quantity"
2381
+ value={5}
2382
+ onChange={onChange}
2383
+ min={0}
2384
+ max={10}
2385
+ hasNumberSteppers
2386
+ />,
2387
+ );
2388
+ const input = screen.getByRole('spinbutton');
2389
+ await user.clear(input);
2390
+ await user.type(input, '10');
2391
+ onChange.mockClear();
2392
+ await user.click(
2393
+ screen.getByRole('button', {name: 'Increment Quantity'}),
2394
+ );
2395
+ expect(onChange).not.toHaveBeenCalled();
2266
2396
  });
2267
2397
 
2268
2398
  it('disables both steppers with the input', () => {
@@ -2277,10 +2407,10 @@ describe('NumberInput stepping', () => {
2277
2407
  );
2278
2408
  expect(
2279
2409
  screen.getByRole('button', {name: 'Increment Quantity'}),
2280
- ).toBeDisabled();
2410
+ ).toHaveAttribute('aria-disabled', 'true');
2281
2411
  expect(
2282
2412
  screen.getByRole('button', {name: 'Decrement Quantity'}),
2283
- ).toBeDisabled();
2413
+ ).toHaveAttribute('aria-disabled', 'true');
2284
2414
  });
2285
2415
  });
2286
2416
  });
@@ -53,6 +53,7 @@ import {useTooltip} from '../Tooltip';
53
53
  import {getInputARIA} from '../utils';
54
54
  import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
55
55
  import {usePressFeedback} from '../hooks/usePressFeedback';
56
+ import {inputDisabledFocusStyles} from '../Field/inputDisabledFocus';
56
57
  import {useSize} from '../SizeContext/SizeContext';
57
58
  import {useInputContainer} from '../hooks/useInputContainer';
58
59
  import {useInputStatusIcon} from '../hooks/useInputStatusIcon';
@@ -261,7 +262,7 @@ interface NumberInputPropsBase extends Omit<
261
262
  * Whether the input is read-only.
262
263
  * The value is shown at full opacity and still submits with the form, but
263
264
  * cannot be edited. Unlike `isDisabled`, a read-only input is not dimmed and
264
- * stays in the tab order — use it for a value the user should see and send
265
+ * keeps its form value — use it for a value the user should see and send
265
266
  * but not change. Stepping is off in every form while read-only: arrow keys,
266
267
  * the wheel, and the number steppers. `isDisabled` takes precedence when both
267
268
  * are set.
@@ -275,8 +276,8 @@ interface NumberInputPropsBase extends Omit<
275
276
  * keyboard and assistive technology. The field cannot be edited (it becomes
276
277
  * read-only) while disabled.
277
278
  *
278
- * Use this instead of wrapping a disabled input in `Tooltip` — disabled
279
- * controls don't emit the pointer events an external tooltip needs.
279
+ * Use this instead of wrapping a disabled input in `Tooltip`, so the reason
280
+ * is attached to the field itself.
280
281
  *
281
282
  * @example
282
283
  * ```
@@ -600,12 +601,20 @@ export function NumberInput({
600
601
  const [pendingInput, setPendingInput] = useState<string | null>(null);
601
602
  const [isFocused, setIsFocused] = useState(false);
602
603
 
603
- // Disabled-reason tooltip. Disabled controls swallow pointer events, so the
604
- // tooltip listeners attach to the input container (which already exists) and
604
+ // Disabled-reason tooltip. The tooltip listeners attach to the input container (which already exists) and
605
605
  // the input stays perceivable via aria-disabled instead of the native
606
606
  // disabled attribute. The field is made read-only so it can't be typed into,
607
607
  // and value mutation is blocked by the isDisabled guard in the handlers.
608
608
  const showsDisabledMessage = isDisabled && !!disabledMessage;
609
+ // A disabled field keeps its tab stop but, like a natively disabled one,
610
+ // runs no caller event handler other than focus and blur (`spec:AST-085` FR2).
611
+ const fieldProps = isDisabled
612
+ ? Object.fromEntries(
613
+ Object.entries(rest).filter(
614
+ ([key]) => !/^on[A-Z]/.test(key) || /^on(Focus|Blur)/.test(key),
615
+ ),
616
+ )
617
+ : rest;
609
618
  const disabledMessageTooltip = useTooltip({
610
619
  placement: 'above',
611
620
  // The container div is not naturally focusable; focusin bubbles up from
@@ -699,6 +708,12 @@ export function NumberInput({
699
708
  if (pendingInput === null) {
700
709
  return;
701
710
  }
711
+ if (isDisabled) {
712
+ // A field disabled mid-entry commits nothing; its draft is dropped, as
713
+ // a natively disabled field's was (spec:AST-085 FR2).
714
+ setPendingInput(null);
715
+ return;
716
+ }
702
717
 
703
718
  const decision = resolveNumberInputCommit(pendingInput, {
704
719
  min,
@@ -722,7 +737,17 @@ export function NumberInput({
722
737
  onChange(decision.value);
723
738
  }
724
739
  },
725
- [hasClear, isIntegerOnly, locale, max, min, onChange, pendingInput, value],
740
+ [
741
+ hasClear,
742
+ isDisabled,
743
+ isIntegerOnly,
744
+ locale,
745
+ max,
746
+ min,
747
+ onChange,
748
+ pendingInput,
749
+ value,
750
+ ],
726
751
  );
727
752
 
728
753
  // Blur ends the edit and displays the resulting committed value.
@@ -780,6 +805,13 @@ export function NumberInput({
780
805
  // Handle keyboard events
781
806
  const handleKeyDown = useCallback(
782
807
  (e: KeyboardEvent<HTMLInputElement>) => {
808
+ if (isDisabled) {
809
+ // A read-only field still submits its form on Enter.
810
+ if (e.key === 'Enter') {
811
+ e.preventDefault();
812
+ }
813
+ return;
814
+ }
783
815
  // The field is type="text" for formatted display, so an IME can compose
784
816
  // into it: Enter commits the candidate and the arrows walk the candidate
785
817
  // window. The composing keydown fires before compositionend, so without
@@ -804,7 +836,7 @@ export function NumberInput({
804
836
  }
805
837
  onKeyDown?.(e);
806
838
  },
807
- [commitPendingInput, onEnter, onKeyDown, stepValue],
839
+ [commitPendingInput, isDisabled, onEnter, onKeyDown, stepValue],
808
840
  );
809
841
 
810
842
  // React's delegated wheel listener can be passive, so use a native,
@@ -860,11 +892,12 @@ export function NumberInput({
860
892
  if (!e || e.detail === 0) {
861
893
  inputRef.current?.focus();
862
894
  } else {
863
- // Defer focus restoration past the button's unmount task so iOS Safari
864
- // and touch browsers don't jump the page scroll to 0 on tap.
865
- requestAnimationFrame(() => {
866
- inputRef.current?.focus({preventScroll: true});
867
- });
895
+ // Focus inside the tap: iOS Safari brings up its keyboard only for a
896
+ // focus made while handling the touch, so a field the tap reaches
897
+ // unfocused gets its keyboard, as UIKit's clear button makes the
898
+ // field first responder. `preventScroll` keeps a scrolled page where
899
+ // it is.
900
+ inputRef.current?.focus({preventScroll: true});
868
901
  }
869
902
  },
870
903
  [hasClear, onChange],
@@ -902,6 +935,7 @@ export function NumberInput({
902
935
  hasNumberSteppers && styles.wrapperWithNumberSteppers,
903
936
  sizeStyles[size],
904
937
  isDisabled && inputWrapperStyles.disabled,
938
+ isDisabled && inputDisabledFocusStyles.ring,
905
939
  status && inputStatusBorderStyles[status.type],
906
940
  status && !isDisabled && inputStatusHoverShadowStyles[status.type],
907
941
  status && inputStatusFocusWithinStyles[status.type],
@@ -914,7 +948,7 @@ export function NumberInput({
914
948
  {startIcon && renderIconSlot(startIcon, {size: 'sm', color: 'secondary'})}
915
949
  {inputGroup && <VisuallyHidden id={inputLabelID}>{label}</VisuallyHidden>}
916
950
  <input
917
- {...rest}
951
+ {...fieldProps}
918
952
  ref={mergedInputRef}
919
953
  id={id}
920
954
  name={isDisabled || formatValue ? undefined : htmlName}
@@ -928,12 +962,11 @@ export function NumberInput({
928
962
  onBlur={handleBlur}
929
963
  onKeyDown={handleKeyDown}
930
964
  placeholder={placeholder}
931
- // With a disabledMessage the input keeps focusability via aria-disabled
932
- // so the reason is focus-discoverable; readOnly + the handler guards
933
- // keep the value from changing.
934
- disabled={isDisabled && !showsDisabledMessage}
935
- aria-disabled={showsDisabledMessage ? 'true' : undefined}
936
- readOnly={isReadOnly || showsDisabledMessage || undefined}
965
+ // A disabled input keeps its place in the tab order (spec:AST-085):
966
+ // aria-disabled instead of the native attribute, with readOnly + the
967
+ // handler guards keeping the value from changing.
968
+ aria-disabled={isDisabled ? 'true' : undefined}
969
+ readOnly={isReadOnly || isDisabled || undefined}
937
970
  autoFocus={hasAutoFocus}
938
971
  data-autofocus={hasAutoFocus || undefined}
939
972
  aria-valuemin={min ?? undefined}
@@ -992,10 +1025,17 @@ export function NumberInput({
992
1025
  type="button"
993
1026
  tabIndex={-1}
994
1027
  {...pressable}
995
- disabled={isDisabled || isReadOnly || !canIncrement}
1028
+ aria-disabled={
1029
+ isDisabled || isReadOnly || !canIncrement || undefined
1030
+ }
996
1031
  aria-label={t('@astryx.numberInput.incrementLabel', {label})}
997
1032
  onPointerDown={event => event.preventDefault()}
998
1033
  onClick={() => {
1034
+ // An aria-disabled stepper does nothing, as a natively disabled
1035
+ // one did (spec:AST-085 FR2).
1036
+ if (isDisabled || isReadOnly || !canIncrement) {
1037
+ return;
1038
+ }
999
1039
  inputRef.current?.focus();
1000
1040
  stepValue(1);
1001
1041
  }}
@@ -1016,10 +1056,17 @@ export function NumberInput({
1016
1056
  type="button"
1017
1057
  tabIndex={-1}
1018
1058
  {...pressable}
1019
- disabled={isDisabled || isReadOnly || !canDecrement}
1059
+ aria-disabled={
1060
+ isDisabled || isReadOnly || !canDecrement || undefined
1061
+ }
1020
1062
  aria-label={t('@astryx.numberInput.decrementLabel', {label})}
1021
1063
  onPointerDown={event => event.preventDefault()}
1022
1064
  onClick={() => {
1065
+ // An aria-disabled stepper does nothing, as a natively disabled
1066
+ // one did (spec:AST-085 FR2).
1067
+ if (isDisabled || isReadOnly || !canDecrement) {
1068
+ return;
1069
+ }
1023
1070
  inputRef.current?.focus();
1024
1071
  stepValue(-1);
1025
1072
  }}
@@ -965,7 +965,7 @@ describe('Pagination', () => {
965
965
  />,
966
966
  );
967
967
  const box = screen.getByRole('spinbutton', {name: 'Go to page'});
968
- expect(box).toBeDisabled();
968
+ expect(box).toHaveAttribute('aria-disabled', 'true');
969
969
  // Disabled input never fires a change.
970
970
  await user.type(box, '5{Enter}');
971
971
  expect(onChange).not.toHaveBeenCalled();
@@ -999,7 +999,7 @@ describe('Pagination', () => {
999
999
  // editable box is inert rather than accepting entries it can't resolve.
1000
1000
  expect(
1001
1001
  screen.getByRole('spinbutton', {name: 'Go to page'}),
1002
- ).toBeDisabled();
1002
+ ).toHaveAttribute('aria-disabled', 'true');
1003
1003
  });
1004
1004
 
1005
1005
  it('renders the localized "Page" label by default and a custom pageLabel', () => {
@@ -668,18 +668,27 @@ describe('SideNavHeading headerEndContent', () => {
668
668
  expect(screen.getByTestId('end-badge')).toBeInTheDocument();
669
669
  });
670
670
 
671
- it('renders headerEndContent inside the link in isWholeHeadingLink path', () => {
671
+ it('renders headerEndContent beside the link, not inside it, in isWholeHeadingLink path', () => {
672
+ const onPress = vi.fn();
672
673
  render(
673
674
  <SideNavHeading
674
675
  heading="My App"
675
676
  headingHref="/home"
676
- headerEndContent={<span data-testid="end-badge">3</span>}
677
+ headerEndContent={
678
+ <button type="button" onClick={onPress}>
679
+ Create
680
+ </button>
681
+ }
677
682
  />,
678
683
  );
679
- const badge = screen.getByTestId('end-badge');
680
- expect(badge).toBeInTheDocument();
681
- // Badge renders inside the link
682
- expect(badge.closest('a')).not.toBeNull();
684
+ const link = screen.getByRole('link', {name: 'My App'});
685
+ expect(link).toHaveAttribute('href', '/home');
686
+ // A control inside a link is invalid and its press would follow the link.
687
+ const button = screen.getByRole('button', {name: 'Create'});
688
+ expect(button.closest('a')).toBeNull();
689
+ expect(link.parentElement).toBe(button.parentElement?.parentElement);
690
+ fireEvent.click(button);
691
+ expect(onPress).toHaveBeenCalledTimes(1);
683
692
  });
684
693
 
685
694
  it('renders headerEndContent in isWholeHeadingTrigger path', () => {
@@ -189,6 +189,17 @@ const styles = stylex.create({
189
189
  // today. The 28px min box still wins over Icon's width/height.
190
190
  fontSize: 'inherit',
191
191
  },
192
+ // The link part of a whole-heading link row that also has end content.
193
+ linkBesideEndContent: {
194
+ display: 'flex',
195
+ alignItems: 'center',
196
+ alignSelf: 'stretch',
197
+ gap: spacingVars['--spacing-2'],
198
+ flexGrow: 1,
199
+ minWidth: 0,
200
+ textDecoration: 'none',
201
+ color: 'inherit',
202
+ },
192
203
  headerEndContent: {
193
204
  flexShrink: 0,
194
205
  display: 'flex',
@@ -640,6 +651,36 @@ export function SideNavHeading({
640
651
  </button>
641
652
  );
642
653
 
654
+ // Whole heading is a link (no menu, single headingHref). End content may
655
+ // be a control, which must not sit inside the link (no interactive content
656
+ // in an <a>), so with end content the row is a div holding the link and the
657
+ // end content side by side, as the mixed mode does.
658
+ if (isWholeHeadingLink && headingHref && headerEndContentElement) {
659
+ return (
660
+ <div
661
+ ref={ref}
662
+ data-testid={testId}
663
+ {...mergeProps(
664
+ themeProps('side-nav-heading'),
665
+ stylex.props(styles.root, xstyle),
666
+ className,
667
+ style,
668
+ )}>
669
+ <LinkComponent
670
+ href={headingHref}
671
+ {...focusOutlineProps.focusVisible(
672
+ styles.linkBesideEndContent,
673
+ styles.menuTrigger,
674
+ )}
675
+ {...(props as React.AnchorHTMLAttributes<HTMLAnchorElement>)}>
676
+ {icon && <span {...stylex.props(styles.icon)}>{icon}</span>}
677
+ {renderTextContent()}
678
+ </LinkComponent>
679
+ {headerEndContentElement}
680
+ </div>
681
+ );
682
+ }
683
+
643
684
  // Whole heading is a link (no menu, single headingHref)
644
685
  if (isWholeHeadingLink && headingHref) {
645
686
  return (
@@ -3,7 +3,63 @@
3
3
  import {describe, it, expect} from 'vitest';
4
4
  import {render, screen} from '@testing-library/react';
5
5
  import {Skeleton} from './Skeleton';
6
- import {getForcedColorsRules} from '../__tests__/forcedColors';
6
+ import {
7
+ getAllInjectedCss,
8
+ getForcedColorsRules,
9
+ } from '../__tests__/forcedColors';
10
+
11
+ /** The declarations the element's atomic classes carry, as `prop: value`. */
12
+ function declarationsOf(el: Element, css: string): string[] {
13
+ const out: string[] = [];
14
+ for (const cls of Array.from(el.classList)) {
15
+ const re = new RegExp(`\\.${cls}\\b[^{]*\\{([^}]*)\\}`, 'g');
16
+ for (const match of css.matchAll(re)) {
17
+ out.push(
18
+ ...match[1]
19
+ .split(';')
20
+ .map(d => d.trim())
21
+ .filter(Boolean),
22
+ );
23
+ }
24
+ }
25
+ return out;
26
+ }
27
+
28
+ /** The whole `@keyframes <name> { … }` rule, braces matched. */
29
+ function keyframesRule(css: string, name: string): string {
30
+ const start = css.search(new RegExp(`@keyframes ${name}\\b`, 'i'));
31
+ expect(start).toBeGreaterThanOrEqual(0);
32
+ let depth = 0;
33
+ for (let i = css.indexOf('{', start); i < css.length; i += 1) {
34
+ if (css[i] === '{') {
35
+ depth += 1;
36
+ }
37
+ if (css[i] === '}' && --depth === 0) {
38
+ return css.slice(start, i + 1);
39
+ }
40
+ }
41
+ throw new Error(`unterminated @keyframes ${name}`);
42
+ }
43
+
44
+ /** The named animation's opacity keyframes as [offset 0..1, opacity], in order. */
45
+ function opacityKeyframes(css: string, name: string): [number, number][] {
46
+ return Array.from(
47
+ keyframesRule(css, name).matchAll(/([\d.]+)%\s*\{\s*opacity:\s*([\d.]+)/g),
48
+ m => [Number(m[1]) / 100, Number(m[2])] as [number, number],
49
+ );
50
+ }
51
+
52
+ /** Opacity at iteration progress x, linear between keyframes. */
53
+ function opacityAt(frames: [number, number][], x: number): number {
54
+ for (let i = 1; i < frames.length; i += 1) {
55
+ const [x0, y0] = frames[i - 1];
56
+ const [x1, y1] = frames[i];
57
+ if (x <= x1) {
58
+ return x1 === x0 ? y1 : y0 + ((y1 - y0) * (x - x0)) / (x1 - x0);
59
+ }
60
+ }
61
+ return frames[frames.length - 1][1];
62
+ }
7
63
 
8
64
  describe('Skeleton', () => {
9
65
  it('renders a placeholder element', () => {
@@ -25,6 +81,57 @@ describe('Skeleton', () => {
25
81
  });
26
82
  });
27
83
 
84
+ describe('pulse', () => {
85
+ function pulse() {
86
+ render(<Skeleton width={200} height={20} data-testid="sk" />);
87
+ const css = getAllInjectedCss();
88
+ const declarations = declarationsOf(screen.getByTestId('sk'), css);
89
+ const value = (prop: string) =>
90
+ declarations
91
+ .filter(d => d.startsWith(`${prop}:`))
92
+ .map(d => d.slice(prop.length + 1).trim());
93
+ return {css, value};
94
+ }
95
+
96
+ // WebKit runs no animation with a steps() timing function on the
97
+ // compositor, so a stepped pulse would freeze in Safari while a script runs.
98
+ it('keeps steps() out of the timing function so every engine can composite it', () => {
99
+ const {css, value} = pulse();
100
+ expect(value('animation-timing-function')).toEqual(['linear']);
101
+ expect(value('animation-direction')).toEqual(['alternate']);
102
+ expect(value('animation-iteration-count')).toEqual(['infinite']);
103
+ const name = value('animation-name').find(v => v !== 'none');
104
+ expect(name).toBeTruthy();
105
+ const rule = keyframesRule(css, name ?? '');
106
+ expect(rule).toMatch(/opacity/);
107
+ expect(rule).not.toMatch(/steps\(|animation-timing-function/);
108
+ });
109
+
110
+ it('climbs and falls through the same ten opacity steps at the same times', () => {
111
+ const {css, value} = pulse();
112
+ const name = value('animation-name').find(v => v !== 'none') ?? '';
113
+ const frames = opacityKeyframes(css, name);
114
+ expect(frames[0]).toEqual([0, 0.25]);
115
+ // The previous pulse: 0.25 → 1 through steps(10, end), played back down
116
+ // by `alternate`. Sample each tenth away from its edges.
117
+ for (let step = 0; step < 10; step += 1) {
118
+ for (const within of [0.02, 0.5, 0.98]) {
119
+ const x = (step + within) / 10;
120
+ const expected = 0.25 + 0.75 * (step / 10);
121
+ expect(opacityAt(frames, x)).toBeCloseTo(expected, 6);
122
+ }
123
+ }
124
+ // Each change between steps takes 0.01% of an iteration.
125
+ for (let i = 1; i < frames.length; i += 1) {
126
+ const [x0, y0] = frames[i - 1];
127
+ const [x1, y1] = frames[i];
128
+ if (y1 !== y0) {
129
+ expect(x1 - x0).toBeCloseTo(0.0001, 6);
130
+ }
131
+ }
132
+ });
133
+ });
134
+
28
135
  // jsdom cannot emulate forced-colors rendering, so these assert that the
29
136
  // compiled output includes the forced-colors rules; visual behavior needs
30
137
  // manual verification under Windows High Contrast.