@astryxdesign/core 0.4.5 → 0.4.6-canary.cea9ecd

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 (538) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/dist/Avatar/Avatar.d.ts +10 -5
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +139 -30
  5. package/dist/Avatar/AvatarStatusDot.d.ts +2 -1
  6. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  7. package/dist/Avatar/AvatarStatusDot.js +30 -4
  8. package/dist/Avatar/AvatarStatusLabelContext.d.ts +39 -0
  9. package/dist/Avatar/AvatarStatusLabelContext.d.ts.map +1 -0
  10. package/dist/Avatar/AvatarStatusLabelContext.js +41 -0
  11. package/dist/AvatarGroup/AvatarGroup.d.ts +3 -1
  12. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  13. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroupOverflow.js +15 -9
  15. package/dist/Blockquote/Blockquote.d.ts +4 -3
  16. package/dist/Blockquote/Blockquote.d.ts.map +1 -1
  17. package/dist/Blockquote/Blockquote.js +9 -10
  18. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  19. package/dist/BottomSheet/BottomSheetPanel.js +21 -5
  20. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  21. package/dist/Breadcrumbs/BreadcrumbItem.js +47 -34
  22. package/dist/Button/Button.d.ts.map +1 -1
  23. package/dist/Button/Button.js +7 -7
  24. package/dist/Calendar/Calendar.d.ts.map +1 -1
  25. package/dist/Calendar/Calendar.js +21 -12
  26. package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
  27. package/dist/Calendar/hooks/useCalendarNavigation.js +8 -4
  28. package/dist/Calendar/styles.d.ts +2 -2
  29. package/dist/Calendar/styles.d.ts.map +1 -1
  30. package/dist/Calendar/styles.js +5 -5
  31. package/dist/Center/Center.d.ts +23 -1
  32. package/dist/Center/Center.d.ts.map +1 -1
  33. package/dist/Center/Center.js +12 -6
  34. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  35. package/dist/Chat/ChatComposer.js +3 -3
  36. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  37. package/dist/Chat/ChatComposerDrawer.js +2 -2
  38. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  39. package/dist/Chat/ChatToolCalls.js +2 -2
  40. package/dist/Chat/useChatDictation.d.ts +1 -1
  41. package/dist/Chat/useChatDictation.d.ts.map +1 -1
  42. package/dist/Chat/useSpeechRecognition.d.ts +1 -1
  43. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  44. package/dist/Chat/useSpeechRecognition.js +4 -3
  45. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  46. package/dist/Chat/useTriggerMenu.js +2 -2
  47. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  48. package/dist/CheckboxInput/CheckboxInput.js +2 -2
  49. package/dist/Citation/Citation.d.ts.map +1 -1
  50. package/dist/Citation/Citation.js +5 -5
  51. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  52. package/dist/ClickableCard/ClickableCard.js +4 -4
  53. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  54. package/dist/CodeBlock/CodeBlock.js +1 -1
  55. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  56. package/dist/Collapsible/Collapsible.js +2 -2
  57. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  58. package/dist/CommandPalette/CommandPaletteItem.js +3 -3
  59. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  60. package/dist/ComplexSelector/ComplexSelector.js +6 -6
  61. package/dist/DateInput/DateInput.d.ts +31 -2
  62. package/dist/DateInput/DateInput.d.ts.map +1 -1
  63. package/dist/DateInput/DateInput.js +90 -22
  64. package/dist/DateInput/MonthScroller.d.ts +35 -0
  65. package/dist/DateInput/MonthScroller.d.ts.map +1 -0
  66. package/dist/DateInput/MonthScroller.js +658 -0
  67. package/dist/DateInput/MonthYearWheels.d.ts +24 -0
  68. package/dist/DateInput/MonthYearWheels.d.ts.map +1 -0
  69. package/dist/DateInput/MonthYearWheels.js +114 -0
  70. package/dist/DateInput/TouchDateField.d.ts +10 -0
  71. package/dist/DateInput/TouchDateField.d.ts.map +1 -0
  72. package/dist/DateInput/TouchDateField.js +810 -0
  73. package/dist/DateInput/Wheel.d.ts +41 -0
  74. package/dist/DateInput/Wheel.d.ts.map +1 -0
  75. package/dist/DateInput/Wheel.js +315 -0
  76. package/dist/DateInput/monthGeometry.d.ts +65 -0
  77. package/dist/DateInput/monthGeometry.d.ts.map +1 -0
  78. package/dist/DateInput/monthGeometry.js +98 -0
  79. package/dist/DateInput/tokens.stylex.d.ts +63 -0
  80. package/dist/DateInput/tokens.stylex.d.ts.map +1 -0
  81. package/dist/DateInput/tokens.stylex.js +74 -0
  82. package/dist/DateInput/useOwnScrollGesture.d.ts +41 -0
  83. package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -0
  84. package/dist/DateInput/useOwnScrollGesture.js +202 -0
  85. package/dist/DateInput/usePointerDragScroll.d.ts +15 -0
  86. package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -0
  87. package/dist/DateInput/usePointerDragScroll.js +216 -0
  88. package/dist/DateInput/useScrollSettle.d.ts +26 -0
  89. package/dist/DateInput/useScrollSettle.d.ts.map +1 -0
  90. package/dist/DateInput/useScrollSettle.js +149 -0
  91. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  92. package/dist/DateRangeInput/DateRangeInput.js +17 -14
  93. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  94. package/dist/DateTimeInput/DateTimeInput.js +17 -14
  95. package/dist/Dialog/Dialog.d.ts.map +1 -1
  96. package/dist/Dialog/Dialog.js +3 -3
  97. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  98. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +2 -2
  99. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  100. package/dist/DropdownMenu/DropdownMenuItem.js +2 -2
  101. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  102. package/dist/DropdownMenu/DropdownMenuRadioItem.js +2 -2
  103. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  104. package/dist/DropdownMenu/DropdownMenuSubMenu.js +2 -2
  105. package/dist/Field/FieldLabel.d.ts.map +1 -1
  106. package/dist/Field/FieldLabel.js +4 -4
  107. package/dist/Field/InputClearButton.d.ts.map +1 -1
  108. package/dist/Field/InputClearButton.js +6 -0
  109. package/dist/Field/inputStyles.stylex.d.ts +1 -1
  110. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  111. package/dist/Field/inputStyles.stylex.js +5 -5
  112. package/dist/FileInput/FileInput.d.ts.map +1 -1
  113. package/dist/FileInput/FileInput.js +6 -6
  114. package/dist/HoverCard/HoverCard.d.ts +13 -3
  115. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  116. package/dist/HoverCard/HoverCard.js +2 -0
  117. package/dist/HoverCard/index.d.ts +1 -1
  118. package/dist/HoverCard/index.d.ts.map +1 -1
  119. package/dist/HoverCard/useHoverCard.d.ts +17 -2
  120. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  121. package/dist/HoverCard/useHoverCard.js +78 -9
  122. package/dist/InputGroup/InputGroup.js +1 -1
  123. package/dist/Item/Item.d.ts +9 -1
  124. package/dist/Item/Item.d.ts.map +1 -1
  125. package/dist/Item/Item.js +52 -14
  126. package/dist/Layer/index.d.ts +4 -2
  127. package/dist/Layer/index.d.ts.map +1 -1
  128. package/dist/Layer/index.js +2 -0
  129. package/dist/Layer/useLayer.d.ts.map +1 -1
  130. package/dist/Layer/useLayer.js +3 -2
  131. package/dist/Layer/useTouchTrigger.d.ts +113 -0
  132. package/dist/Layer/useTouchTrigger.d.ts.map +1 -0
  133. package/dist/Layer/useTouchTrigger.js +241 -0
  134. package/dist/Layout/container.stylex.d.ts +4 -2
  135. package/dist/Layout/container.stylex.d.ts.map +1 -1
  136. package/dist/Layout/container.stylex.js +19 -11
  137. package/dist/Layout/index.d.ts +1 -0
  138. package/dist/Layout/index.d.ts.map +1 -1
  139. package/dist/Layout/index.js +4 -0
  140. package/dist/Layout/padding.stylex.d.ts +315 -12
  141. package/dist/Layout/padding.stylex.d.ts.map +1 -1
  142. package/dist/Layout/padding.stylex.js +389 -12
  143. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  144. package/dist/Lightbox/Lightbox.js +5 -4
  145. package/dist/Link/Link.d.ts.map +1 -1
  146. package/dist/Link/Link.js +6 -6
  147. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  148. package/dist/MetadataList/MetadataList.js +1 -1
  149. package/dist/MobileNav/MobileNav.d.ts +1 -0
  150. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  151. package/dist/MobileNav/MobileNav.js +24 -6
  152. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  153. package/dist/MultiSelector/MultiSelector.js +8 -8
  154. package/dist/NavItem/navItemStyles.stylex.d.ts +4 -4
  155. package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
  156. package/dist/NavItem/navItemStyles.stylex.js +4 -4
  157. package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
  158. package/dist/NavMenu/NavHeadingMenuItem.js +3 -3
  159. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  160. package/dist/NumberInput/NumberInput.js +36 -8
  161. package/dist/Outline/Outline.d.ts.map +1 -1
  162. package/dist/Outline/Outline.js +3 -3
  163. package/dist/Pagination/Pagination.d.ts.map +1 -1
  164. package/dist/Pagination/Pagination.js +2 -2
  165. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  166. package/dist/PowerSearch/PowerSearch.js +11 -12
  167. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchToken.js +3 -1
  169. package/dist/PowerSearch/formatFilterValue.d.ts +11 -2
  170. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  171. package/dist/PowerSearch/formatFilterValue.js +23 -8
  172. package/dist/RadioList/RadioListItem.d.ts +2 -2
  173. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  174. package/dist/RadioList/RadioListItem.js +70 -40
  175. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  176. package/dist/Resizable/ResizeHandle.js +7 -7
  177. package/dist/Section/Section.d.ts +36 -1
  178. package/dist/Section/Section.d.ts.map +1 -1
  179. package/dist/Section/Section.js +12 -2
  180. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  181. package/dist/SegmentedControl/SegmentedControlItem.js +7 -2
  182. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  183. package/dist/SelectableCard/SelectableCard.js +3 -3
  184. package/dist/Selector/Selector.d.ts +26 -1
  185. package/dist/Selector/Selector.d.ts.map +1 -1
  186. package/dist/Selector/Selector.js +93 -20
  187. package/dist/Selector/SelectorOption.d.ts +14 -1
  188. package/dist/Selector/SelectorOption.d.ts.map +1 -1
  189. package/dist/Selector/SelectorOption.js +6 -0
  190. package/dist/Selector/SelectorRowLayoutContext.d.ts +8 -0
  191. package/dist/Selector/SelectorRowLayoutContext.d.ts.map +1 -0
  192. package/dist/Selector/SelectorRowLayoutContext.js +27 -0
  193. package/dist/Selector/types.d.ts +1 -0
  194. package/dist/Selector/types.d.ts.map +1 -1
  195. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  196. package/dist/SideNav/SideNavHeading.js +4 -4
  197. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  198. package/dist/SideNav/SideNavItem.js +3 -3
  199. package/dist/Slider/Slider.d.ts.map +1 -1
  200. package/dist/Slider/Slider.js +7 -7
  201. package/dist/Stack/Stack.d.ts +23 -1
  202. package/dist/Stack/Stack.d.ts.map +1 -1
  203. package/dist/Stack/Stack.js +12 -6
  204. package/dist/Switch/Switch.d.ts.map +1 -1
  205. package/dist/Switch/Switch.js +2 -2
  206. package/dist/TabList/Tab.d.ts.map +1 -1
  207. package/dist/TabList/Tab.js +1 -1
  208. package/dist/TabList/TabMenu.d.ts.map +1 -1
  209. package/dist/TabList/TabMenu.js +3 -3
  210. package/dist/Table/TableRow.js +4 -4
  211. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  212. package/dist/Table/plugins/columnResize/useTableColumnResize.js +1 -1
  213. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  214. package/dist/Table/plugins/filtering/useTableFiltering.js +2 -2
  215. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  216. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +2 -2
  217. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  218. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +2 -2
  219. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  220. package/dist/Table/plugins/sortable/useTableSortable.js +1 -1
  221. package/dist/Table/plugins/sortable/useTableSortableState.d.ts +5 -3
  222. package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
  223. package/dist/Table/plugins/sortable/useTableSortableState.js +12 -9
  224. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  225. package/dist/Table/plugins/tree/useTableTreeData.js +3 -3
  226. package/dist/TextArea/TextArea.js +1 -1
  227. package/dist/TextInput/TextInput.js +1 -1
  228. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  229. package/dist/Thumbnail/Thumbnail.js +3 -3
  230. package/dist/TimeInput/TimeInput.js +2 -2
  231. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  232. package/dist/Timestamp/Timestamp.js +6 -4
  233. package/dist/Timestamp/formatInstant.d.ts +3 -2
  234. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  235. package/dist/Timestamp/formatInstant.js +8 -8
  236. package/dist/Timestamp/tooltipEntries.d.ts +2 -1
  237. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -1
  238. package/dist/Timestamp/tooltipEntries.js +5 -3
  239. package/dist/Toast/Toast.d.ts +4 -3
  240. package/dist/Toast/Toast.d.ts.map +1 -1
  241. package/dist/Toast/Toast.js +10 -7
  242. package/dist/Token/Token.d.ts.map +1 -1
  243. package/dist/Token/Token.js +6 -6
  244. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  245. package/dist/Tokenizer/Tokenizer.js +1 -1
  246. package/dist/Tooltip/Tooltip.d.ts +16 -3
  247. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  248. package/dist/Tooltip/Tooltip.js +2 -0
  249. package/dist/Tooltip/index.d.ts +1 -1
  250. package/dist/Tooltip/index.d.ts.map +1 -1
  251. package/dist/Tooltip/useTooltip.d.ts +21 -2
  252. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  253. package/dist/Tooltip/useTooltip.js +71 -13
  254. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  255. package/dist/TopNav/TopNavHeading.js +4 -4
  256. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavItem.js +3 -3
  258. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  259. package/dist/TopNav/TopNavMegaMenu.js +2 -2
  260. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  261. package/dist/TopNav/TopNavMegaMenuItem.js +2 -2
  262. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  263. package/dist/TopNav/TopNavMenu.js +4 -4
  264. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  265. package/dist/TreeList/TreeListItem.js +7 -7
  266. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  267. package/dist/Typeahead/BaseTypeahead.js +2 -2
  268. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  269. package/dist/Typeahead/Typeahead.js +1 -1
  270. package/dist/astryx.css +124 -62
  271. package/dist/hooks/containerReveal.stylex.d.ts.map +1 -1
  272. package/dist/hooks/containerReveal.stylex.js +18 -18
  273. package/dist/hooks/scrollbarGutter.d.ts +28 -0
  274. package/dist/hooks/scrollbarGutter.d.ts.map +1 -0
  275. package/dist/hooks/scrollbarGutter.js +103 -0
  276. package/dist/hooks/useAutoMediaMode.d.ts +31 -0
  277. package/dist/hooks/useAutoMediaMode.d.ts.map +1 -0
  278. package/dist/hooks/useAutoMediaMode.js +201 -0
  279. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  280. package/dist/hooks/useInputStatusIcon.js +1 -1
  281. package/dist/hooks/useListFocus.d.ts +5 -2
  282. package/dist/hooks/useListFocus.d.ts.map +1 -1
  283. package/dist/hooks/useListFocus.js +12 -6
  284. package/dist/hooks/useScrollLock.d.ts +4 -0
  285. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  286. package/dist/hooks/useScrollLock.js +13 -1
  287. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  288. package/dist/i18n/InternationalizationContext.js +2 -0
  289. package/dist/i18n/index.d.ts +6 -0
  290. package/dist/i18n/index.d.ts.map +1 -1
  291. package/dist/i18n/index.js +6 -0
  292. package/dist/i18n/useCollator.d.ts +12 -0
  293. package/dist/i18n/useCollator.d.ts.map +1 -0
  294. package/dist/i18n/useCollator.js +40 -0
  295. package/dist/i18n/useLocale.d.ts +3 -0
  296. package/dist/i18n/useLocale.d.ts.map +1 -0
  297. package/dist/i18n/useLocale.js +31 -0
  298. package/dist/theme/MediaTheme.d.ts +25 -5
  299. package/dist/theme/MediaTheme.d.ts.map +1 -1
  300. package/dist/theme/MediaTheme.js +31 -6
  301. package/dist/theme/defineTheme.d.ts +5 -0
  302. package/dist/theme/defineTheme.d.ts.map +1 -1
  303. package/dist/theme/defineTheme.js +5 -0
  304. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  305. package/dist/theme/derivedVarRegistry.js +7 -0
  306. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  307. package/dist/theme/generateThemeRules.js +66 -5
  308. package/dist/theme/index.d.ts +1 -1
  309. package/dist/theme/index.d.ts.map +1 -1
  310. package/dist/theme/syntax/index.d.ts +6 -0
  311. package/dist/theme/syntax/index.d.ts.map +1 -1
  312. package/dist/theme/syntax/index.js +7 -2
  313. package/dist/utils/dateParser.d.ts +4 -3
  314. package/dist/utils/dateParser.d.ts.map +1 -1
  315. package/dist/utils/dateParser.js +8 -8
  316. package/dist/utils/index.d.ts +1 -1
  317. package/dist/utils/index.d.ts.map +1 -1
  318. package/dist/utils/index.js +1 -1
  319. package/dist/utils/plainDate.d.ts +5 -2
  320. package/dist/utils/plainDate.d.ts.map +1 -1
  321. package/dist/utils/plainDate.js +20 -4
  322. package/locales/en.json +28 -0
  323. package/locales/pseudo.json +21 -0
  324. package/package.json +3 -3
  325. package/src/Avatar/Avatar.doc.mjs +10 -6
  326. package/src/Avatar/Avatar.test.tsx +219 -1
  327. package/src/Avatar/Avatar.tsx +179 -37
  328. package/src/Avatar/AvatarStatusDot.tsx +30 -4
  329. package/src/Avatar/AvatarStatusLabelContext.ts +47 -0
  330. package/src/AvatarGroup/AvatarGroup.doc.mjs +10 -6
  331. package/src/AvatarGroup/AvatarGroup.test.tsx +62 -0
  332. package/src/AvatarGroup/AvatarGroup.tsx +3 -1
  333. package/src/AvatarGroup/AvatarGroupOverflow.tsx +31 -8
  334. package/src/Banner/Banner.doc.mjs +2 -0
  335. package/src/Blockquote/Blockquote.doc.mjs +30 -7
  336. package/src/Blockquote/Blockquote.test.tsx +34 -3
  337. package/src/Blockquote/Blockquote.tsx +11 -9
  338. package/src/BottomSheet/BottomSheet.doc.mjs +3 -3
  339. package/src/BottomSheet/BottomSheet.test.tsx +24 -0
  340. package/src/BottomSheet/BottomSheetPanel.test.tsx +91 -0
  341. package/src/BottomSheet/BottomSheetPanel.tsx +58 -3
  342. package/src/Breadcrumbs/BreadcrumbItem.tsx +36 -23
  343. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +26 -2
  344. package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -0
  345. package/src/Button/Button.tsx +12 -9
  346. package/src/Calendar/Calendar.tsx +15 -9
  347. package/src/Calendar/hooks/useCalendarNavigation.ts +6 -4
  348. package/src/Calendar/styles.ts +8 -5
  349. package/src/Center/Center.doc.mjs +48 -0
  350. package/src/Center/Center.test.tsx +158 -0
  351. package/src/Center/Center.tsx +50 -9
  352. package/src/Chat/ChatComposer.tsx +11 -5
  353. package/src/Chat/ChatComposerDrawer.tsx +4 -1
  354. package/src/Chat/ChatToolCalls.tsx +13 -4
  355. package/src/Chat/{useChatDictation.test.ts → useChatDictation.test.tsx} +29 -14
  356. package/src/Chat/useChatDictation.ts +1 -1
  357. package/src/Chat/useSpeechRecognition.ts +5 -3
  358. package/src/Chat/useTriggerMenu.tsx +4 -1
  359. package/src/CheckboxInput/CheckboxInput.tsx +5 -2
  360. package/src/Citation/Citation.test.tsx +6 -1
  361. package/src/Citation/Citation.tsx +11 -5
  362. package/src/ClickableCard/ClickableCard.tsx +7 -4
  363. package/src/CodeBlock/CodeBlock.tsx +4 -1
  364. package/src/Collapsible/Collapsible.tsx +5 -2
  365. package/src/CommandPalette/CommandPaletteItem.tsx +6 -3
  366. package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -0
  367. package/src/ComplexSelector/ComplexSelector.tsx +14 -7
  368. package/src/DateInput/DateInput.test.tsx +17 -1
  369. package/src/DateInput/DateInput.tsx +93 -21
  370. package/src/DateInput/DateInputTouch.test.tsx +2582 -0
  371. package/src/DateInput/MonthScroller.tsx +878 -0
  372. package/src/DateInput/MonthYearWheels.tsx +147 -0
  373. package/src/DateInput/TouchDateField.tsx +1223 -0
  374. package/src/DateInput/Wheel.tsx +473 -0
  375. package/src/DateInput/monthGeometry.ts +118 -0
  376. package/src/DateInput/tokens.stylex.ts +99 -0
  377. package/src/DateInput/useOwnScrollGesture.ts +227 -0
  378. package/src/DateInput/usePointerDragScroll.ts +220 -0
  379. package/src/DateInput/useScrollSettle.ts +164 -0
  380. package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
  381. package/src/DateRangeInput/DateRangeInput.tsx +31 -13
  382. package/src/DateTimeInput/DateTimeInput.tsx +25 -9
  383. package/src/Dialog/Dialog.test.tsx +24 -0
  384. package/src/Dialog/Dialog.tsx +3 -0
  385. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +5 -2
  386. package/src/DropdownMenu/DropdownMenuItem.tsx +5 -2
  387. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +5 -2
  388. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +5 -2
  389. package/src/Field/Field.doc.mjs +2 -0
  390. package/src/Field/FieldLabel.tsx +9 -3
  391. package/src/Field/InputClearButton.test.tsx +110 -3
  392. package/src/Field/InputClearButton.tsx +38 -0
  393. package/src/Field/inputStyles.stylex.ts +17 -13
  394. package/src/FileInput/FileInput.tsx +15 -8
  395. package/src/FormLayout/FormLayout.doc.mjs +1 -1
  396. package/src/HoverCard/HoverCard.doc.mjs +18 -0
  397. package/src/HoverCard/HoverCard.test.tsx +189 -0
  398. package/src/HoverCard/HoverCard.tsx +22 -2
  399. package/src/HoverCard/index.ts +1 -0
  400. package/src/HoverCard/useHoverCard.doc.mjs +2 -0
  401. package/src/HoverCard/useHoverCard.tsx +103 -7
  402. package/src/InputGroup/InputGroup.tsx +1 -1
  403. package/src/Item/Item.doc.mjs +1 -0
  404. package/src/Item/Item.test.tsx +50 -0
  405. package/src/Item/Item.tsx +54 -6
  406. package/src/Layer/index.ts +10 -0
  407. package/src/Layer/useLayer.tsx +13 -2
  408. package/src/Layer/useTouchTrigger.test.ts +70 -0
  409. package/src/Layer/useTouchTrigger.ts +366 -0
  410. package/src/Layout/Layout.doc.mjs +18 -0
  411. package/src/Layout/container.stylex.ts +11 -3
  412. package/src/Layout/index.ts +4 -0
  413. package/src/Layout/overlayPaddingReset.test.tsx +222 -0
  414. package/src/Layout/padding.stylex.ts +192 -12
  415. package/src/Lightbox/Lightbox.tsx +11 -3
  416. package/src/Link/Link.tsx +9 -6
  417. package/src/MetadataList/MetadataList.tsx +4 -1
  418. package/src/MobileNav/MobileNav.tsx +61 -5
  419. package/src/MobileNav/MobileNavEntryAnimation.test.tsx +212 -0
  420. package/src/MobileNav/MobileNavScrollbarGutter.test.tsx +109 -0
  421. package/src/MultiSelector/MultiSelector.test.tsx +1 -1
  422. package/src/MultiSelector/MultiSelector.tsx +26 -10
  423. package/src/NavItem/navItemStyles.stylex.ts +7 -4
  424. package/src/NavMenu/NavHeadingMenuItem.tsx +6 -3
  425. package/src/NumberInput/NumberInput.doc.mjs +24 -0
  426. package/src/NumberInput/NumberInput.test.tsx +138 -0
  427. package/src/NumberInput/NumberInput.tsx +47 -8
  428. package/src/Outline/Outline.tsx +5 -2
  429. package/src/Pagination/Pagination.tsx +5 -2
  430. package/src/Popover/Popover.test.tsx +27 -1
  431. package/src/PowerSearch/PowerSearch.tsx +17 -8
  432. package/src/PowerSearch/PowerSearchToken.tsx +3 -0
  433. package/src/PowerSearch/formatFilterValue.test.ts +22 -2
  434. package/src/PowerSearch/formatFilterValue.ts +31 -6
  435. package/src/RadioList/RadioList.doc.mjs +1 -1
  436. package/src/RadioList/RadioList.test.tsx +170 -2
  437. package/src/RadioList/RadioListItem.tsx +88 -53
  438. package/src/Resizable/ResizeHandle.test.tsx +22 -0
  439. package/src/Resizable/ResizeHandle.tsx +25 -7
  440. package/src/Section/Section.doc.mjs +55 -0
  441. package/src/Section/Section.test.tsx +201 -4
  442. package/src/Section/Section.tsx +69 -0
  443. package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
  444. package/src/SegmentedControl/SegmentedControlItem.tsx +15 -3
  445. package/src/SelectableCard/SelectableCard.tsx +6 -3
  446. package/src/Selector/Selector.doc.mjs +16 -2
  447. package/src/Selector/Selector.test.tsx +525 -1
  448. package/src/Selector/Selector.tsx +180 -25
  449. package/src/Selector/SelectorOption.doc.mjs +7 -0
  450. package/src/Selector/SelectorOption.tsx +21 -0
  451. package/src/Selector/SelectorRowLayoutContext.ts +32 -0
  452. package/src/Selector/types.ts +4 -4
  453. package/src/SideNav/SideNavHeading.tsx +14 -5
  454. package/src/SideNav/SideNavItem.tsx +9 -3
  455. package/src/Slider/Slider.tsx +25 -6
  456. package/src/Stack/Stack.doc.mjs +72 -0
  457. package/src/Stack/Stack.test.tsx +156 -0
  458. package/src/Stack/Stack.tsx +50 -8
  459. package/src/Switch/Switch.tsx +5 -2
  460. package/src/TabList/Tab.tsx +4 -1
  461. package/src/TabList/TabMenu.tsx +9 -3
  462. package/src/Table/TableRow.tsx +4 -4
  463. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +6 -2
  464. package/src/Table/plugins/filtering/useTableFiltering.tsx +4 -1
  465. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +10 -3
  466. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +6 -3
  467. package/src/Table/plugins/sortable/useTableSortable.tsx +4 -1
  468. package/src/Table/plugins/sortable/useTableSortableState.test.tsx +34 -0
  469. package/src/Table/plugins/sortable/useTableSortableState.tsx +26 -23
  470. package/src/Table/plugins/tree/useTableTreeData.tsx +10 -4
  471. package/src/TextArea/TextArea.doc.mjs +1 -1
  472. package/src/TextArea/TextArea.tsx +1 -1
  473. package/src/TextInput/TextInput.tsx +1 -1
  474. package/src/Thumbnail/Thumbnail.tsx +9 -3
  475. package/src/TimeInput/TimeInput.tsx +1 -1
  476. package/src/Timestamp/Timestamp.test.tsx +27 -7
  477. package/src/Timestamp/Timestamp.tsx +8 -4
  478. package/src/Timestamp/formatInstant.ts +9 -7
  479. package/src/Timestamp/tooltipEntries.test.ts +11 -6
  480. package/src/Timestamp/tooltipEntries.ts +6 -2
  481. package/src/Toast/Toast.tsx +9 -7
  482. package/src/Token/Token.tsx +14 -5
  483. package/src/Tokenizer/Tokenizer.tsx +4 -1
  484. package/src/Tooltip/Tooltip.doc.mjs +18 -0
  485. package/src/Tooltip/Tooltip.test.tsx +254 -1
  486. package/src/Tooltip/Tooltip.tsx +22 -2
  487. package/src/Tooltip/index.ts +1 -0
  488. package/src/Tooltip/useTooltip.doc.mjs +2 -0
  489. package/src/Tooltip/useTooltip.tsx +99 -21
  490. package/src/TopNav/TopNavHeading.tsx +13 -4
  491. package/src/TopNav/TopNavItem.tsx +6 -3
  492. package/src/TopNav/TopNavMegaMenu.tsx +5 -2
  493. package/src/TopNav/TopNavMegaMenuItem.tsx +5 -2
  494. package/src/TopNav/TopNavMenu.tsx +10 -4
  495. package/src/TreeList/TreeListItem.tsx +22 -7
  496. package/src/Typeahead/BaseTypeahead.tsx +5 -2
  497. package/src/Typeahead/Typeahead.tsx +4 -1
  498. package/src/hooks/containerReveal.stylex.ts +54 -18
  499. package/src/hooks/scrollbarGutter.test.ts +167 -0
  500. package/src/hooks/scrollbarGutter.ts +121 -0
  501. package/src/hooks/useAutoMediaMode.test.ts +109 -0
  502. package/src/hooks/useAutoMediaMode.ts +233 -0
  503. package/src/hooks/useInputStatusIcon.tsx +4 -1
  504. package/src/hooks/useListFocus.doc.mjs +2 -2
  505. package/src/hooks/useListFocus.test.tsx +65 -3
  506. package/src/hooks/useListFocus.ts +15 -7
  507. package/src/hooks/useScrollLock.doc.mjs +4 -4
  508. package/src/hooks/useScrollLock.test.ts +73 -0
  509. package/src/hooks/useScrollLock.ts +14 -0
  510. package/src/i18n/InternationalizationContext.ts +2 -0
  511. package/src/i18n/__tests__/e2e-powersearch.test.tsx +37 -1
  512. package/src/i18n/__tests__/useCollator.test.tsx +115 -0
  513. package/src/i18n/__tests__/useLocale.test.tsx +52 -0
  514. package/src/i18n/index.ts +6 -0
  515. package/src/i18n/useCollator.doc.mjs +84 -0
  516. package/src/i18n/useCollator.ts +44 -0
  517. package/src/i18n/useLocale.doc.mjs +70 -0
  518. package/src/i18n/useLocale.ts +34 -0
  519. package/src/i18n/useTranslator.doc.mjs +1 -1
  520. package/src/reset.css +9 -2
  521. package/src/reset.test.ts +22 -0
  522. package/src/theme/MediaTheme.doc.mjs +23 -4
  523. package/src/theme/MediaTheme.dom.test.tsx +97 -0
  524. package/src/theme/MediaTheme.tsx +42 -7
  525. package/src/theme/defineTheme.test.ts +9 -3
  526. package/src/theme/defineTheme.ts +5 -0
  527. package/src/theme/derivedVarRegistry.test.ts +19 -5
  528. package/src/theme/derivedVarRegistry.ts +4 -0
  529. package/src/theme/generateThemeRules.test.ts +118 -0
  530. package/src/theme/generateThemeRules.ts +83 -5
  531. package/src/theme/index.ts +1 -1
  532. package/src/theme/syntax/index.ts +6 -2
  533. package/src/theme/syntax/serverSafeSyntax.test.ts +68 -0
  534. package/src/utils/dateParser.test.ts +20 -0
  535. package/src/utils/dateParser.ts +14 -7
  536. package/src/utils/index.ts +2 -0
  537. package/src/utils/plainDate.test.ts +6 -0
  538. package/src/utils/plainDate.ts +21 -4
@@ -16,7 +16,14 @@
16
16
  * - /packages/cli/assets/templates/blocks/components/DateRangeInput/ (showcase blocks)
17
17
  */
18
18
 
19
- import {useId, useCallback, useMemo, useOptimistic, useTransition} from 'react';
19
+ import {
20
+ use,
21
+ useId,
22
+ useCallback,
23
+ useMemo,
24
+ useOptimistic,
25
+ useTransition,
26
+ } from 'react';
20
27
  import * as stylex from '@stylexjs/stylex';
21
28
  import {
22
29
  plainDateFromISO,
@@ -65,7 +72,8 @@ import {useResolvedRequired} from '../hooks/useResolvedRequired';
65
72
  import {themeProps} from '../utils/themeProps';
66
73
  import {focusOutlineStyles} from '../utils/focusOutline.stylex';
67
74
  import {stableClassName} from '../naming';
68
- import {useTranslator} from '../i18n';
75
+ import {useTranslator, InternationalizationContext} from '../i18n';
76
+ import type {Locale} from '../i18n/types';
69
77
 
70
78
  export type {DateRange} from '../Calendar';
71
79
 
@@ -98,7 +106,10 @@ const styles = stylex.create({
98
106
  color: colorVars['--color-text-primary'],
99
107
  backgroundColor: 'transparent',
100
108
  outline: 'none',
101
- cursor: 'pointer',
109
+ cursor: {
110
+ default: 'pointer',
111
+ ':is(:disabled,[aria-disabled="true"])': 'default',
112
+ },
102
113
  textAlign: 'start',
103
114
  whiteSpace: 'nowrap',
104
115
  overflow: 'hidden',
@@ -108,7 +119,7 @@ const styles = stylex.create({
108
119
  color: colorVars['--color-text-secondary'],
109
120
  },
110
121
  triggerDisabled: {
111
- cursor: 'not-allowed',
122
+ cursor: 'default',
112
123
  },
113
124
  iconButton: {
114
125
  display: 'flex',
@@ -119,11 +130,14 @@ const styles = stylex.create({
119
130
  borderWidth: 0,
120
131
  borderStyle: 'none',
121
132
  backgroundColor: 'transparent',
122
- cursor: 'pointer',
133
+ cursor: {
134
+ default: 'pointer',
135
+ ':is(:disabled,[aria-disabled="true"])': 'default',
136
+ },
123
137
  borderRadius: radiusVars['--radius-element'],
124
138
  },
125
139
  iconButtonDisabled: {
126
- cursor: 'not-allowed',
140
+ cursor: 'default',
127
141
  },
128
142
  popoverLayout: {
129
143
  display: 'flex',
@@ -148,7 +162,7 @@ const styles = stylex.create({
148
162
  borderRadius: radiusVars['--radius-element'],
149
163
  backgroundColor: {
150
164
  default: 'transparent',
151
- ':hover': {
165
+ ':hover:where(:not(:disabled,[aria-disabled="true"]))': {
152
166
  '@media (hover: hover)': colorVars['--color-overlay-hover'],
153
167
  },
154
168
  },
@@ -156,7 +170,10 @@ const styles = stylex.create({
156
170
  fontSize: typeScaleVars['--text-label-size'],
157
171
  lineHeight: typeScaleVars['--text-label-leading'],
158
172
  color: colorVars['--color-text-primary'],
159
- cursor: 'pointer',
173
+ cursor: {
174
+ default: 'pointer',
175
+ ':is(:disabled,[aria-disabled="true"])': 'default',
176
+ },
160
177
  textAlign: 'start',
161
178
  },
162
179
  presetButtonActive: {
@@ -165,7 +182,7 @@ const styles = stylex.create({
165
182
  },
166
183
  presetButtonDisabled: {
167
184
  color: colorVars['--color-text-disabled'],
168
- cursor: 'not-allowed',
185
+ cursor: 'default',
169
186
  backgroundColor: 'transparent',
170
187
  },
171
188
  });
@@ -185,7 +202,7 @@ const sizeStyles = stylex.create({
185
202
  },
186
203
  });
187
204
 
188
- function formatRangeDisplay(range: DateRange | null): string {
205
+ function formatRangeDisplay(range: DateRange | null, locale?: Locale): string {
189
206
  if (!range) {
190
207
  return '';
191
208
  }
@@ -195,7 +212,7 @@ function formatRangeDisplay(range: DateRange | null): string {
195
212
  const sameYear = start.year === end.year && start.year === currentYear;
196
213
 
197
214
  const fmt = sameYear ? DATE_FORMAT_SHORT : DATE_FORMAT_SHORT_WITH_YEAR;
198
- return `${plainDateFormat(start, fmt)} – ${plainDateFormat(end, fmt)}`;
215
+ return `${plainDateFormat(start, fmt, locale)} – ${plainDateFormat(end, fmt, locale)}`;
199
216
  }
200
217
 
201
218
  function isRangeEqual(a: DateRange | null, b: DateRange | null): boolean {
@@ -475,6 +492,7 @@ export function DateRangeInput({
475
492
  }: DateRangeInputProps) {
476
493
  const t = useTranslator();
477
494
  const isEffectivelyRequired = useResolvedRequired({isRequired, isOptional});
495
+ const {locale} = use(InternationalizationContext);
478
496
  const placeholder =
479
497
  placeholderFromProps ?? t('@astryx.dateRangeInput.placeholder');
480
498
  const size = useSize(sizeProp, 'md');
@@ -521,8 +539,8 @@ export function DateRangeInput({
521
539
  .join(' ') || undefined;
522
540
 
523
541
  const displayValue = useMemo(
524
- () => formatRangeDisplay(optimisticValue),
525
- [optimisticValue],
542
+ () => formatRangeDisplay(optimisticValue, locale),
543
+ [optimisticValue, locale],
526
544
  );
527
545
 
528
546
  const popover = usePopover({
@@ -17,6 +17,7 @@
17
17
  */
18
18
 
19
19
  import {
20
+ use,
20
21
  useId,
21
22
  useState,
22
23
  useCallback,
@@ -88,7 +89,7 @@ import {useResolvedRequired} from '../hooks/useResolvedRequired';
88
89
  import {useSize} from '../SizeContext/SizeContext';
89
90
  import {themeProps} from '../utils/themeProps';
90
91
  import {focusOutlineStyles} from '../utils/focusOutline.stylex';
91
- import {useTranslator} from '../i18n';
92
+ import {useTranslator, InternationalizationContext} from '../i18n';
92
93
 
93
94
  export type ISODateTimeString = string & {
94
95
  readonly __brand: 'ISODateTimeString';
@@ -120,11 +121,14 @@ const styles = stylex.create({
120
121
  borderWidth: 0,
121
122
  borderStyle: 'none',
122
123
  backgroundColor: 'transparent',
123
- cursor: 'pointer',
124
+ cursor: {
125
+ default: 'pointer',
126
+ ':is(:disabled,[aria-disabled="true"])': 'default',
127
+ },
124
128
  borderRadius: radiusVars['--radius-element'],
125
129
  },
126
130
  iconButtonDisabled: {
127
- cursor: 'not-allowed',
131
+ cursor: 'default',
128
132
  },
129
133
  icon: {
130
134
  display: 'flex',
@@ -153,7 +157,7 @@ const styles = stylex.create({
153
157
  },
154
158
  },
155
159
  inputDisabled: {
156
- cursor: 'not-allowed',
160
+ cursor: 'default',
157
161
  },
158
162
  inputInvalid: {
159
163
  color: colorVars['--color-text-secondary'],
@@ -450,6 +454,7 @@ export function DateTimeInput({
450
454
  }: DateTimeInputProps) {
451
455
  const t = useTranslator();
452
456
  const isEffectivelyRequired = useResolvedRequired({isRequired, isOptional});
457
+ const {locale} = use(InternationalizationContext);
453
458
  // Speaks arrow-key stepping results through the persistent live regions:
454
459
  // stepping programmatically rewrites a plain textbox's value, which screen
455
460
  // readers do not announce on their own (WCAG 4.1.2).
@@ -560,13 +565,17 @@ export function DateTimeInput({
560
565
  datePendingInput !== null
561
566
  ? datePendingInput
562
567
  : valueParts.date && /^\d{4}-\d{2}-\d{2}$/.test(valueParts.date)
563
- ? plainDateFormat(plainDateFromISO(valueParts.date), DATE_FORMAT_LONG)
568
+ ? plainDateFormat(
569
+ plainDateFromISO(valueParts.date),
570
+ DATE_FORMAT_LONG,
571
+ locale,
572
+ )
564
573
  : '';
565
574
 
566
575
  const isDateInputValid =
567
576
  datePendingInput === null || !datePendingInput.trim()
568
577
  ? true
569
- : parseDateInput(datePendingInput) !== null;
578
+ : parseDateInput(datePendingInput, locale) !== null;
570
579
 
571
580
  // --- Time input state ---
572
581
  const [timePendingInput, setTimePendingInput] = useState<string | null>(null);
@@ -694,7 +703,7 @@ export function DateTimeInput({
694
703
  const text = e.target.value;
695
704
  setDatePendingInput(text);
696
705
 
697
- const parsed = parseDateInput(text);
706
+ const parsed = parseDateInput(text, locale);
698
707
  if (
699
708
  parsed &&
700
709
  plainDateToISO(parsed) !== valueParts.date &&
@@ -706,7 +715,13 @@ export function DateTimeInput({
706
715
  calendarRef.current?.navigateTo(parsedISO);
707
716
  }
708
717
  },
709
- [valueParts.date, isDateDisabled, handleDateChange, isEffectivelyDisabled],
718
+ [
719
+ valueParts.date,
720
+ isDateDisabled,
721
+ handleDateChange,
722
+ isEffectivelyDisabled,
723
+ locale,
724
+ ],
710
725
  );
711
726
 
712
727
  const commitDatePendingInput = useCallback(() => {
@@ -722,7 +737,7 @@ export function DateTimeInput({
722
737
  return;
723
738
  }
724
739
 
725
- const parsed = parseDateInput(datePendingInput);
740
+ const parsed = parseDateInput(datePendingInput, locale);
726
741
  if (parsed && !isDateDisabled(parsed)) {
727
742
  const parsedISO = plainDateToISO(parsed);
728
743
  if (parsedISO !== valueParts.date) {
@@ -737,6 +752,7 @@ export function DateTimeInput({
737
752
  fireChange,
738
753
  isDateDisabled,
739
754
  handleDateChange,
755
+ locale,
740
756
  ]);
741
757
 
742
758
  const handleDateBlur = useCallback(() => {
@@ -461,4 +461,28 @@ describe('Dialog', () => {
461
461
  before.remove();
462
462
  });
463
463
  });
464
+
465
+ describe('container padding isolation', () => {
466
+ it('resets container padding custom properties on the root dialog element', () => {
467
+ render(
468
+ <Dialog isOpen={true} onOpenChange={() => {}}>
469
+ Content
470
+ </Dialog>,
471
+ );
472
+ const dialog = screen.getByRole('dialog');
473
+ const computed = window.getComputedStyle(dialog);
474
+ expect(
475
+ computed.getPropertyValue('--container-padding-inline-start'),
476
+ ).toBe('0px');
477
+ expect(computed.getPropertyValue('--container-padding-inline-end')).toBe(
478
+ '0px',
479
+ );
480
+ expect(computed.getPropertyValue('--container-padding-block-start')).toBe(
481
+ '0px',
482
+ );
483
+ expect(computed.getPropertyValue('--container-padding-block-end')).toBe(
484
+ '0px',
485
+ );
486
+ });
487
+ });
464
488
  });
@@ -44,6 +44,7 @@ import {
44
44
  containerPaddingBlockStartVarStyles,
45
45
  containerPaddingBlockEndVarStyles,
46
46
  spacingStepToToken,
47
+ overlayPaddingReset,
47
48
  } from '../Layout/padding.stylex';
48
49
  import type {SpacingStep} from '../utils/types';
49
50
  import {mergeProps, mergeRefs} from '../utils';
@@ -610,6 +611,7 @@ export function Dialog({
610
611
  themeProps('dialog', {variant}),
611
612
  stylex.props(
612
613
  styles.inlineWrapper,
614
+ overlayPaddingReset.reset,
613
615
  !isFullscreen && dynamicStyles.sizing(width, maxHeight),
614
616
  isFullscreen && styles.fullscreen,
615
617
  xstyle,
@@ -636,6 +638,7 @@ export function Dialog({
636
638
  themeProps('dialog', {variant}),
637
639
  focusOutlineProps.focusVisible(
638
640
  styles.dialog,
641
+ overlayPaddingReset.reset,
639
642
  isOpen && styles.open,
640
643
  styles.backdrop,
641
644
  !isFullscreen && dynamicStyles.sizing(width, maxHeight),
@@ -46,12 +46,15 @@ const styles = stylex.create({
46
46
  default: 'transparent',
47
47
  ':focus': colorVars['--color-overlay-hover'],
48
48
  },
49
- cursor: 'pointer',
49
+ cursor: {
50
+ default: 'pointer',
51
+ ':is(:disabled,[aria-disabled="true"])': 'default',
52
+ },
50
53
  outline: 'none',
51
54
  },
52
55
  disabled: {
53
56
  opacity: 0.5,
54
- cursor: 'not-allowed',
57
+ cursor: 'default',
55
58
  },
56
59
  // Rendered in Item's `marker` slot as a raw flex child, so `order` moves it
57
60
  // relative to the label within the row. On touch it moves to the inline-end.
@@ -54,13 +54,16 @@ const menuItemStyles = stylex.create({
54
54
  ':focus': colorVars['--color-overlay-hover'],
55
55
  },
56
56
  border: 'none',
57
- cursor: 'pointer',
57
+ cursor: {
58
+ default: 'pointer',
59
+ ':is(:disabled,[aria-disabled="true"])': 'default',
60
+ },
58
61
  textAlign: 'start',
59
62
  outline: 'none',
60
63
  },
61
64
  disabled: {
62
65
  opacity: 0.5,
63
- cursor: 'not-allowed',
66
+ cursor: 'default',
64
67
  },
65
68
  destructive: {
66
69
  // Only recolor the text/icon; the hover / focus background stays the shared
@@ -42,12 +42,15 @@ const styles = stylex.create({
42
42
  default: 'transparent',
43
43
  ':focus': colorVars['--color-overlay-hover'],
44
44
  },
45
- cursor: 'pointer',
45
+ cursor: {
46
+ default: 'pointer',
47
+ ':is(:disabled,[aria-disabled="true"])': 'default',
48
+ },
46
49
  outline: 'none',
47
50
  },
48
51
  disabled: {
49
52
  opacity: 0.5,
50
- cursor: 'not-allowed',
53
+ cursor: 'default',
51
54
  },
52
55
  // Rendered in Item's `marker` slot as a raw flex child. On touch it moves to
53
56
  // the inline-end of the row via `order`.
@@ -96,7 +96,10 @@ const triggerStyles = stylex.create({
96
96
  ':focus': colorVars['--color-overlay-hover'],
97
97
  },
98
98
  border: 'none',
99
- cursor: 'pointer',
99
+ cursor: {
100
+ default: 'pointer',
101
+ ':is(:disabled,[aria-disabled="true"])': 'default',
102
+ },
100
103
  textAlign: 'start',
101
104
  outline: 'none',
102
105
  },
@@ -107,7 +110,7 @@ const triggerStyles = stylex.create({
107
110
  },
108
111
  disabled: {
109
112
  opacity: 0.5,
110
- cursor: 'not-allowed',
113
+ cursor: 'default',
111
114
  },
112
115
  caret: {
113
116
  display: 'flex',
@@ -39,6 +39,8 @@ export const docs = {
39
39
  ],
40
40
  vars: [
41
41
  {name: '--_field-radius', description: 'Border radius of input fields', default: 'var(--radius-element)', private: true},
42
+ {name: '--_input-clear-hit-inset', description: 'Outset of the clear (\u2715) button\u2019s invisible hit area, applied to a ::after overlay. 0 on a fine pointer; negative on a coarse one, which grows the 20px button to the 24px touch target without changing what is drawn.', default: '0px', private: true},
43
+ {name: '--_input-clear-hit-content', description: 'Whether the clear (\u2715) button\u2019s invisible hit overlay exists. `none` on a fine pointer, so no ::after is generated and hover still reaches the glyph; `""` on a coarse one, where the overlay provides the 24px touch target.', default: 'none', private: true},
42
44
  ],
43
45
  derived: [
44
46
  {property: 'borderRadius', vars: ['--_field-radius']},
@@ -45,11 +45,14 @@ const styles = stylex.create({
45
45
  lineHeight: typeScaleVars['--text-label-leading'],
46
46
  fontWeight: fontWeightVars['--font-weight-medium'],
47
47
  color: colorVars['--color-text-secondary'],
48
- cursor: 'pointer',
48
+ cursor: {
49
+ default: 'pointer',
50
+ ':is(:disabled,[aria-disabled="true"])': 'default',
51
+ },
49
52
  },
50
53
  labelDisabled: {
51
54
  color: colorVars['--color-text-disabled'],
52
- cursor: 'not-allowed',
55
+ cursor: 'default',
53
56
  },
54
57
  srOnly: {
55
58
  borderStyle: 'none',
@@ -82,7 +85,10 @@ const styles = stylex.create({
82
85
  // When the description forwards clicks to a click-activatable control
83
86
  // (checkbox/switch), it reads as part of the same hit target as the label.
84
87
  descriptionClickable: {
85
- cursor: 'pointer',
88
+ cursor: {
89
+ default: 'pointer',
90
+ ':is(:disabled,[aria-disabled="true"])': 'default',
91
+ },
86
92
  },
87
93
  });
88
94
 
@@ -2,7 +2,8 @@
2
2
 
3
3
  /**
4
4
  * @file InputClearButton.test.tsx
5
- * @input Uses vitest, @testing-library/react, InputClearButton, Icon, theme
5
+ * @input Uses node:fs, node:path, vitest, @testing-library/react, InputClearButton, Icon,
6
+ * theme
6
7
  * @output Unit tests for the shared clear-button primitive
7
8
  * @position Testing; validates InputClearButton.tsx — the single home for the
8
9
  * clearable input family's clear (✕) affordance and its theme target.
@@ -10,6 +11,8 @@
10
11
  * SYNC: When InputClearButton.tsx changes, update tests to match new behavior.
11
12
  */
12
13
 
14
+ import {readFileSync} from 'node:fs';
15
+ import path from 'node:path';
13
16
  import {describe, it, expect, vi} from 'vitest';
14
17
  import {render, screen, fireEvent} from '@testing-library/react';
15
18
  import {InputClearButton} from './InputClearButton';
@@ -22,6 +25,39 @@ function generateThemeTestCSS(theme: Parameters<typeof generateThemeCSS>[0]) {
22
25
  return [prose, component].filter(Boolean).join('\n\n');
23
26
  }
24
27
 
28
+ interface InjectedRule {
29
+ selector: string;
30
+ text: string;
31
+ media: string | null;
32
+ }
33
+
34
+ /**
35
+ * Every style rule StyleX has injected at runtime (`runtimeInjection` in the
36
+ * root vitest config), flattened out of any at-rule wrapper and tagged with
37
+ * that wrapper's condition — so a `@media (pointer: coarse)` rule stays
38
+ * distinguishable from the unconditional one.
39
+ */
40
+ function injectedRules(): InjectedRule[] {
41
+ const walk = (rules: CSSRuleList, condition: string | null) =>
42
+ [...rules].flatMap((rule): InjectedRule[] => {
43
+ const {selectorText} = rule as CSSStyleRule;
44
+ if (typeof selectorText === 'string') {
45
+ return [{selector: selectorText, text: rule.cssText, media: condition}];
46
+ }
47
+ // A grouping rule (@media, @keyframes, ...): descend, carrying the
48
+ // innermost condition down. jsdom hangs an empty `cssRules` off plain
49
+ // style rules too, which is why the leaf check comes first.
50
+ const nested = (rule as CSSGroupingRule).cssRules;
51
+ if (nested == null) {
52
+ return [];
53
+ }
54
+ const own = (rule as CSSMediaRule).media?.mediaText;
55
+ return walk(nested, own != null && own !== '' ? own : condition);
56
+ });
57
+
58
+ return [...document.styleSheets].flatMap(sheet => walk(sheet.cssRules, null));
59
+ }
60
+
25
61
  const getGlyph = (): HTMLElement => {
26
62
  const button = screen.getByRole('button', {name: 'Clear'});
27
63
  const icon = button.querySelector('.astryx-icon');
@@ -111,7 +147,7 @@ describe('InputClearButton', () => {
111
147
  const css = generateThemeTestCSS(theme);
112
148
  expect(css).toContain('.astryx-input-clear-icon {');
113
149
  expect(css).toContain('width: 12px');
114
- expect(css).toContain('.astryx-input-clear-icon:hover {');
150
+ expect(css).toContain('.astryx-input-clear-icon:hover');
115
151
  expect(css).toContain('color: var(--color-icon-primary)');
116
152
  });
117
153
 
@@ -121,6 +157,77 @@ describe('InputClearButton', () => {
121
157
  expect(button).toHaveClass('astryx-input-clear-button');
122
158
  });
123
159
 
160
+ it('grows the hit area to 24px on a coarse pointer only (WCAG 2.5.8 AA)', () => {
161
+ // The visual glyph stays 20px; an ::after overlay expands only the
162
+ // tappable region, and only under a coarse pointer. Asserted against the
163
+ // CSS StyleX injects at runtime, because jsdom resolves neither media
164
+ // queries nor pseudo-element boxes.
165
+ render(<InputClearButton label="Clear" onClick={() => {}} />);
166
+ const button = screen.getByRole('button', {name: 'Clear'});
167
+ const classes = new Set(button.className.split(' ').filter(Boolean));
168
+
169
+ const css = injectedRules();
170
+ const rulesForButton = css.filter(({selector}) =>
171
+ [...classes].some(c => selector.includes(`.${c}`)),
172
+ );
173
+ // Guards every assertion below against silently passing if StyleX's
174
+ // runtime injection or the class plumbing ever changes shape.
175
+ expect(rulesForButton.length).toBeGreaterThan(0);
176
+
177
+ const decl = (pattern: RegExp, inMedia?: string) =>
178
+ rulesForButton.some(
179
+ ({text, media}) =>
180
+ pattern.test(text) &&
181
+ (inMedia == null ? media == null : (media ?? '').includes(inMedia)),
182
+ );
183
+
184
+ // Fine pointer: hit area == the 20px visual glyph, no expansion.
185
+ expect(decl(/--_input-clear-hit-inset\s*:\s*0px/)).toBe(true);
186
+ // Coarse pointer: 20px + 2px on each side = 24x24, the AA floor.
187
+ expect(decl(/--_input-clear-hit-inset\s*:\s*-2px/, 'pointer: coarse')).toBe(
188
+ true,
189
+ );
190
+ // ...and nothing wider than that, which would reach into the adornment
191
+ // gap and the input's caret area. Scoped to the coarse block, because
192
+ // that is the only place a wider value can appear.
193
+ expect(
194
+ decl(
195
+ /--_input-clear-hit-inset\s*:\s*-(?:[3-9]|\d{2,})px/,
196
+ 'pointer: coarse',
197
+ ),
198
+ ).toBe(false);
199
+ // The overlay exists only on touch. On a fine pointer a generated
200
+ // ::after would cover the button and take hover away from the glyph
201
+ // target, so `content` is gated the same way the inset is.
202
+ expect(decl(/--_input-clear-hit-content\s*:\s*none/)).toBe(true);
203
+ expect(decl(/--_input-clear-hit-content\s*:\s*""/, 'pointer: coarse')).toBe(
204
+ true,
205
+ );
206
+ // The overlay itself is what carries the expansion, and what is gated.
207
+ expect(
208
+ decl(/::after\s*\{[^}]*inset\s*:\s*var\(--_input-clear-hit-inset\)/),
209
+ ).toBe(true);
210
+ expect(
211
+ decl(/::after\s*\{[^}]*content\s*:\s*var\(--_input-clear-hit-content\)/),
212
+ ).toBe(true);
213
+ });
214
+
215
+ it('declares its own containing block for the hit overlay', () => {
216
+ // The ::after overlay must resolve against this button. Button happens to
217
+ // set `position: relative` on itself, so at runtime the overlay is
218
+ // correctly placed either way — and StyleX compiles both declarations to
219
+ // the same atomic class, so the rendered CSS cannot tell the two apart.
220
+ // Assert on the source instead, so a future edit can't quietly leave the
221
+ // overlay depending on another component's internal.
222
+ const source = readFileSync(
223
+ path.resolve(__dirname, './InputClearButton.tsx'),
224
+ 'utf-8',
225
+ );
226
+ const buttonStyle = source.match(/button:\s*\{[\s\S]*?\n {2}\},/)?.[0];
227
+ expect(buttonStyle).toBeDefined();
228
+ expect(buttonStyle).toMatch(/position:\s*'relative'/);
229
+ });
230
+
124
231
  it('exposes input-clear-button so a theme controls the button size and hover', () => {
125
232
  const theme = defineTheme({
126
233
  name: 'input-clear-button-test',
@@ -136,7 +243,7 @@ describe('InputClearButton', () => {
136
243
  const css = generateThemeTestCSS(theme);
137
244
  expect(css).toContain('.astryx-input-clear-button {');
138
245
  expect(css).toContain('height: 28px');
139
- expect(css).toContain('.astryx-input-clear-button:hover {');
246
+ expect(css).toContain('.astryx-input-clear-button:hover');
140
247
  expect(css).toContain('background-image: none');
141
248
  });
142
249
  });
@@ -25,6 +25,44 @@ const styles = stylex.create({
25
25
  button: {
26
26
  height: '20px',
27
27
  flexShrink: 0,
28
+ // Containing block for the ::after hit overlay below. Button sets its own
29
+ // `position: relative`, so the overlay would resolve correctly without
30
+ // this — but that is another component's internal, and if it ever changes
31
+ // the overlay silently reattaches to some ancestor and the hit area lands
32
+ // in the wrong place. Declaring it here keeps the containing block
33
+ // colocated with the thing that depends on it. No-op at runtime.
34
+ position: 'relative',
35
+ // Expand the tap target to 24px ONLY on touch (WCAG 2.5.8 AA is a touch
36
+ // requirement, and its floor is 24x24). On a fine pointer the 20px glyph
37
+ // is precise enough, and an unconditional overlay could overlap
38
+ // neighboring controls in dense layouts. The inset is 0 by default (hit
39
+ // area == visual glyph) and grows to -2px (=> 24x24) under a coarse
40
+ // pointer — no further, because at -4px the overlay reaches into the 8px
41
+ // adornment gap and, on the inline-start side, over the input's own caret
42
+ // area. Driven through a custom property because StyleX only allows plain
43
+ // values inside a pseudo-element; the conditional lives on this top-level
44
+ // property instead. Private (--_) because it is an internal implementation
45
+ // detail, not a themeable target.
46
+ '--_input-clear-hit-inset': {
47
+ default: '0px',
48
+ '@media (pointer: coarse)': '-2px',
49
+ },
50
+ // The overlay itself is gated too, not just its size. An ::after that is
51
+ // generated on a fine pointer sits exactly over the button at inset 0,
52
+ // where it adds no hit area but is the topmost hit-test box — so hover
53
+ // stops reaching the descendants and `.astryx-input-clear-icon:hover`, a
54
+ // public theme target, no longer matches. `content: none` means the
55
+ // pseudo-element is not generated at all, so on a fine pointer the
56
+ // overlay does not exist.
57
+ '--_input-clear-hit-content': {
58
+ default: 'none',
59
+ '@media (pointer: coarse)': '""',
60
+ },
61
+ '::after': {
62
+ content: 'var(--_input-clear-hit-content)',
63
+ position: 'absolute',
64
+ inset: 'var(--_input-clear-hit-inset)',
65
+ },
28
66
  },
29
67
  });
30
68
 
@@ -56,15 +56,16 @@ export const inputWrapperStyles = stylex.create({
56
56
  transitionTimingFunction: easeVars['--ease-standard'],
57
57
  boxShadow: {
58
58
  default: 'none',
59
- ':hover:not(:focus-within)': {
60
- '@media (hover: hover)': `inset 0px 0px 0px 2px color-mix(in srgb, ${colorVars['--color-border-emphasized']} 30%, transparent)`,
61
- },
59
+ ':hover:not(:focus-within):where(:not(:disabled,[aria-disabled="true"]))':
60
+ {
61
+ '@media (hover: hover)': `inset 0px 0px 0px 2px color-mix(in srgb, ${colorVars['--color-border-emphasized']} 30%, transparent)`,
62
+ },
62
63
  ':focus-within': `inset 0px 0px 0px 2px ${colorVars['--color-accent-muted']}`,
63
64
  },
64
65
  outline: 'none',
65
66
  },
66
67
  disabled: {
67
- cursor: 'not-allowed',
68
+ cursor: 'default',
68
69
  opacity: 0.5,
69
70
  borderColor: colorVars['--color-border-emphasized'],
70
71
  // Suppress the base hover ring — a disabled control must not react to hover.
@@ -96,25 +97,28 @@ export const inputStatusHoverShadowStyles = stylex.create({
96
97
  warning: {
97
98
  boxShadow: {
98
99
  default: 'none',
99
- ':hover:not(:focus-within)': {
100
- '@media (hover: hover)': shadowVars['--shadow-inset-warning'],
101
- },
100
+ ':hover:not(:focus-within):where(:not(:disabled,[aria-disabled="true"]))':
101
+ {
102
+ '@media (hover: hover)': shadowVars['--shadow-inset-warning'],
103
+ },
102
104
  },
103
105
  },
104
106
  error: {
105
107
  boxShadow: {
106
108
  default: 'none',
107
- ':hover:not(:focus-within)': {
108
- '@media (hover: hover)': shadowVars['--shadow-inset-error'],
109
- },
109
+ ':hover:not(:focus-within):where(:not(:disabled,[aria-disabled="true"]))':
110
+ {
111
+ '@media (hover: hover)': shadowVars['--shadow-inset-error'],
112
+ },
110
113
  },
111
114
  },
112
115
  success: {
113
116
  boxShadow: {
114
117
  default: 'none',
115
- ':hover:not(:focus-within)': {
116
- '@media (hover: hover)': shadowVars['--shadow-inset-success'],
117
- },
118
+ ':hover:not(:focus-within):where(:not(:disabled,[aria-disabled="true"]))':
119
+ {
120
+ '@media (hover: hover)': shadowVars['--shadow-inset-success'],
121
+ },
118
122
  },
119
123
  },
120
124
  });