@astryxdesign/core 0.1.2 → 0.1.3-canary.6d57c8d

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 (567) hide show
  1. package/CHANGELOG.md +165 -0
  2. package/README.md +12 -12
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +11 -5
  5. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
  6. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  7. package/dist/Breadcrumbs/BreadcrumbItem.js +24 -5
  8. package/dist/Button/Button.d.ts.map +1 -1
  9. package/dist/Button/Button.js +2 -4
  10. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  11. package/dist/ButtonGroup/ButtonGroup.js +0 -1
  12. package/dist/Calendar/Calendar.d.ts +5 -4
  13. package/dist/Calendar/Calendar.d.ts.map +1 -1
  14. package/dist/Calendar/Calendar.js +82 -43
  15. package/dist/Calendar/hooks/index.d.ts +0 -2
  16. package/dist/Calendar/hooks/index.d.ts.map +1 -1
  17. package/dist/Calendar/hooks/index.js +1 -2
  18. package/dist/Calendar/index.d.ts +3 -3
  19. package/dist/Calendar/index.d.ts.map +1 -1
  20. package/dist/Calendar/index.js +1 -1
  21. package/dist/Calendar/styles.d.ts +3 -9
  22. package/dist/Calendar/styles.d.ts.map +1 -1
  23. package/dist/Calendar/styles.js +3 -11
  24. package/dist/Carousel/Carousel.d.ts.map +1 -1
  25. package/dist/Carousel/Carousel.js +17 -3
  26. package/dist/Center/Center.d.ts +11 -1
  27. package/dist/Center/Center.d.ts.map +1 -1
  28. package/dist/Center/Center.js +9 -3
  29. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  30. package/dist/Chat/ChatComposerInput.js +0 -1
  31. package/dist/Chat/ChatMessageList.d.ts +14 -1
  32. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  33. package/dist/Chat/ChatMessageList.js +2 -0
  34. package/dist/Chat/useTriggerMenu.d.ts +8 -1
  35. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  36. package/dist/Chat/useTriggerMenu.js +15 -3
  37. package/dist/CheckboxInput/CheckboxInput.d.ts +23 -2
  38. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  39. package/dist/CheckboxInput/CheckboxInput.js +51 -9
  40. package/dist/CheckboxList/CheckboxList.d.ts +13 -1
  41. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  42. package/dist/CheckboxList/CheckboxList.js +39 -9
  43. package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
  44. package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
  45. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  46. package/dist/CheckboxList/CheckboxListItem.js +0 -1
  47. package/dist/Citation/Citation.d.ts.map +1 -1
  48. package/dist/Citation/Citation.js +9 -5
  49. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  50. package/dist/CodeBlock/CodeBlock.js +51 -37
  51. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  52. package/dist/CommandPalette/CommandPalette.js +5 -5
  53. package/dist/ContextMenu/ContextMenu.d.ts +4 -5
  54. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  55. package/dist/ContextMenu/ContextMenu.js +93 -11
  56. package/dist/DateInput/DateInput.d.ts +23 -1
  57. package/dist/DateInput/DateInput.d.ts.map +1 -1
  58. package/dist/DateInput/DateInput.js +167 -99
  59. package/dist/DateRangeInput/DateRangeInput.d.ts +23 -1
  60. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  61. package/dist/DateRangeInput/DateRangeInput.js +42 -9
  62. package/dist/DateTimeInput/DateTimeInput.d.ts +35 -2
  63. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  64. package/dist/DateTimeInput/DateTimeInput.js +78 -15
  65. package/dist/Dialog/Dialog.d.ts.map +1 -1
  66. package/dist/Dialog/Dialog.js +12 -0
  67. package/dist/DropdownMenu/DropdownMenu.d.ts +1 -8
  68. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  69. package/dist/DropdownMenu/DropdownMenu.js +42 -14
  70. package/dist/Field/Field.d.ts +19 -2
  71. package/dist/Field/Field.d.ts.map +1 -1
  72. package/dist/Field/Field.js +4 -0
  73. package/dist/Field/FieldLabel.d.ts +21 -2
  74. package/dist/Field/FieldLabel.d.ts.map +1 -1
  75. package/dist/Field/FieldLabel.js +41 -26
  76. package/dist/FileInput/FileInput.d.ts +22 -1
  77. package/dist/FileInput/FileInput.d.ts.map +1 -1
  78. package/dist/FileInput/FileInput.js +56 -10
  79. package/dist/Grid/Grid.d.ts +11 -1
  80. package/dist/Grid/Grid.d.ts.map +1 -1
  81. package/dist/Grid/Grid.js +32 -6
  82. package/dist/InputGroup/InputGroup.d.ts +4 -3
  83. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  84. package/dist/InputGroup/InputGroup.js +16 -6
  85. package/dist/InputGroup/InputGroupContext.d.ts +4 -0
  86. package/dist/InputGroup/InputGroupContext.d.ts.map +1 -1
  87. package/dist/InputGroup/InputGroupContext.js +2 -2
  88. package/dist/InputGroup/groupStyles.d.ts +1 -1
  89. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  90. package/dist/InputGroup/groupStyles.js +3 -3
  91. package/dist/InputGroup/index.d.ts +1 -0
  92. package/dist/InputGroup/index.d.ts.map +1 -1
  93. package/dist/Kbd/Kbd.d.ts.map +1 -1
  94. package/dist/Kbd/Kbd.js +33 -1
  95. package/dist/Layer/layerAnimations.stylex.d.ts +4 -0
  96. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  97. package/dist/Layer/layerAnimations.stylex.js +8 -4
  98. package/dist/Layer/useLayer.d.ts +10 -0
  99. package/dist/Layer/useLayer.d.ts.map +1 -1
  100. package/dist/Layer/useLayer.js +64 -9
  101. package/dist/Layout/Layout.d.ts +4 -11
  102. package/dist/Layout/Layout.d.ts.map +1 -1
  103. package/dist/Layout/Layout.js +10 -11
  104. package/dist/Layout/LayoutFooter.d.ts +2 -2
  105. package/dist/Layout/LayoutFooter.d.ts.map +1 -1
  106. package/dist/Layout/LayoutHeader.d.ts +2 -2
  107. package/dist/Layout/LayoutHeader.d.ts.map +1 -1
  108. package/dist/Layout/LayoutPanel.d.ts +2 -2
  109. package/dist/Layout/LayoutPanel.d.ts.map +1 -1
  110. package/dist/Layout/padding.stylex.d.ts +51 -0
  111. package/dist/Layout/padding.stylex.d.ts.map +1 -1
  112. package/dist/Layout/padding.stylex.js +63 -0
  113. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  114. package/dist/Lightbox/Lightbox.js +4 -2
  115. package/dist/Link/Link.d.ts +16 -1
  116. package/dist/Link/Link.d.ts.map +1 -1
  117. package/dist/Link/Link.js +18 -7
  118. package/dist/Markdown/Markdown.d.ts.map +1 -1
  119. package/dist/Markdown/Markdown.js +7 -0
  120. package/dist/MoreMenu/MoreMenu.d.ts +1 -7
  121. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  122. package/dist/MoreMenu/MoreMenu.js +0 -2
  123. package/dist/MultiSelector/MultiSelector.d.ts +27 -2
  124. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  125. package/dist/MultiSelector/MultiSelector.js +141 -42
  126. package/dist/MultiSelector/hooks.d.ts +12 -1
  127. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  128. package/dist/MultiSelector/hooks.js +14 -1
  129. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  130. package/dist/NavMenu/NavHeadingMenu.js +34 -3
  131. package/dist/NumberInput/NumberInput.d.ts +23 -2
  132. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  133. package/dist/NumberInput/NumberInput.js +62 -12
  134. package/dist/Pagination/Pagination.d.ts +1 -1
  135. package/dist/Pagination/Pagination.d.ts.map +1 -1
  136. package/dist/Pagination/Pagination.js +15 -1
  137. package/dist/Popover/Popover.d.ts +18 -2
  138. package/dist/Popover/Popover.d.ts.map +1 -1
  139. package/dist/Popover/Popover.js +5 -2
  140. package/dist/Popover/usePopover.d.ts +38 -3
  141. package/dist/Popover/usePopover.d.ts.map +1 -1
  142. package/dist/Popover/usePopover.js +24 -9
  143. package/dist/PowerSearch/PowerSearch.d.ts +11 -1
  144. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  145. package/dist/PowerSearch/PowerSearch.js +6 -1
  146. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  147. package/dist/ProgressBar/ProgressBar.js +3 -5
  148. package/dist/RadioList/RadioList.d.ts +20 -2
  149. package/dist/RadioList/RadioList.d.ts.map +1 -1
  150. package/dist/RadioList/RadioList.js +105 -9
  151. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  152. package/dist/RadioList/RadioListItem.js +13 -2
  153. package/dist/SegmentedControl/SegmentedControl.d.ts +13 -2
  154. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  155. package/dist/SegmentedControl/SegmentedControl.js +78 -44
  156. package/dist/SegmentedControl/SegmentedControlContext.d.ts +7 -0
  157. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  158. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  159. package/dist/SegmentedControl/SegmentedControlItem.js +13 -2
  160. package/dist/Selector/Selector.d.ts +24 -1
  161. package/dist/Selector/Selector.d.ts.map +1 -1
  162. package/dist/Selector/Selector.js +122 -43
  163. package/dist/Selector/hooks.d.ts +8 -1
  164. package/dist/Selector/hooks.d.ts.map +1 -1
  165. package/dist/Selector/hooks.js +14 -1
  166. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  167. package/dist/SideNav/SideNavHeading.js +2 -0
  168. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  169. package/dist/SideNav/SideNavItem.js +1 -1
  170. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  171. package/dist/Skeleton/Skeleton.js +8 -2
  172. package/dist/Slider/Slider.d.ts +21 -0
  173. package/dist/Slider/Slider.d.ts.map +1 -1
  174. package/dist/Slider/Slider.js +36 -9
  175. package/dist/Spinner/Spinner.d.ts.map +1 -1
  176. package/dist/Spinner/Spinner.js +1 -1
  177. package/dist/Stack/Stack.d.ts +38 -23
  178. package/dist/Stack/Stack.d.ts.map +1 -1
  179. package/dist/Stack/Stack.js +25 -1
  180. package/dist/Stack/StackItem.d.ts +12 -23
  181. package/dist/Stack/StackItem.d.ts.map +1 -1
  182. package/dist/Stack/StackItem.js +8 -1
  183. package/dist/Switch/Switch.d.ts +23 -2
  184. package/dist/Switch/Switch.d.ts.map +1 -1
  185. package/dist/Switch/Switch.js +41 -11
  186. package/dist/TabList/Tab.d.ts.map +1 -1
  187. package/dist/TabList/Tab.js +6 -0
  188. package/dist/TabList/TabList.d.ts +16 -4
  189. package/dist/TabList/TabList.d.ts.map +1 -1
  190. package/dist/TabList/TabList.js +87 -10
  191. package/dist/TabList/TabListContext.d.ts +5 -0
  192. package/dist/TabList/TabListContext.d.ts.map +1 -1
  193. package/dist/TabList/TabListContext.js +5 -0
  194. package/dist/TabList/TabMenu.d.ts.map +1 -1
  195. package/dist/TabList/TabMenu.js +6 -1
  196. package/dist/Table/BaseTable.d.ts.map +1 -1
  197. package/dist/Table/BaseTable.js +11 -8
  198. package/dist/Table/Table.d.ts.map +1 -1
  199. package/dist/Table/Table.js +10 -1
  200. package/dist/Table/TableCell.d.ts +8 -1
  201. package/dist/Table/TableCell.d.ts.map +1 -1
  202. package/dist/Table/TableCell.js +10 -10
  203. package/dist/Table/TableHeaderCell.d.ts +8 -1
  204. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  205. package/dist/Table/TableHeaderCell.js +16 -16
  206. package/dist/Table/index.d.ts +2 -1
  207. package/dist/Table/index.d.ts.map +1 -1
  208. package/dist/Table/index.js +2 -2
  209. package/dist/Table/plugins/pagination/paginateData.d.ts +2 -1
  210. package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
  211. package/dist/Table/plugins/pagination/paginateData.js +8 -3
  212. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  213. package/dist/Table/plugins/pagination/useTablePagination.js +6 -1
  214. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  215. package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
  216. package/dist/Table/tableContextMenu.d.ts +33 -0
  217. package/dist/Table/tableContextMenu.d.ts.map +1 -0
  218. package/dist/Table/tableContextMenu.js +133 -0
  219. package/dist/Table/types.d.ts +66 -0
  220. package/dist/Table/types.d.ts.map +1 -1
  221. package/dist/TextArea/TextArea.d.ts +22 -1
  222. package/dist/TextArea/TextArea.d.ts.map +1 -1
  223. package/dist/TextArea/TextArea.js +41 -9
  224. package/dist/TextInput/TextInput.d.ts +23 -2
  225. package/dist/TextInput/TextInput.d.ts.map +1 -1
  226. package/dist/TextInput/TextInput.js +55 -10
  227. package/dist/TimeInput/TimeInput.d.ts +23 -1
  228. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  229. package/dist/TimeInput/TimeInput.js +147 -76
  230. package/dist/Toast/Toast.d.ts.map +1 -1
  231. package/dist/Toast/Toast.js +14 -0
  232. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  233. package/dist/Toast/ToastViewport.js +131 -3
  234. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  235. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  236. package/dist/Tokenizer/Tokenizer.js +26 -4
  237. package/dist/Toolbar/Toolbar.d.ts +3 -3
  238. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  239. package/dist/Toolbar/Toolbar.js +51 -7
  240. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  241. package/dist/Tooltip/useTooltip.js +56 -9
  242. package/dist/TopNav/TopNavHeading.d.ts +7 -1
  243. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  244. package/dist/TopNav/TopNavHeading.js +8 -0
  245. package/dist/TreeList/TreeList.d.ts +1 -1
  246. package/dist/TreeList/TreeList.d.ts.map +1 -1
  247. package/dist/TreeList/TreeList.js +72 -2
  248. package/dist/TreeList/TreeListItem.d.ts +11 -1
  249. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  250. package/dist/TreeList/TreeListItem.js +51 -12
  251. package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
  252. package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
  253. package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
  254. package/dist/Typeahead/BaseTypeahead.d.ts +13 -0
  255. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  256. package/dist/Typeahead/BaseTypeahead.js +69 -6
  257. package/dist/Typeahead/Typeahead.d.ts +26 -3
  258. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  259. package/dist/Typeahead/Typeahead.js +65 -29
  260. package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
  261. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
  262. package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
  263. package/dist/VisuallyHidden/index.d.ts +11 -0
  264. package/dist/VisuallyHidden/index.d.ts.map +1 -0
  265. package/dist/VisuallyHidden/index.js +13 -0
  266. package/dist/astryx.css +18 -0
  267. package/dist/astryx.umd.js +55 -55
  268. package/dist/astryx.umd.js.map +4 -4
  269. package/dist/hooks/focusableSelector.d.ts +22 -0
  270. package/dist/hooks/focusableSelector.d.ts.map +1 -0
  271. package/dist/hooks/focusableSelector.js +24 -0
  272. package/dist/hooks/index.d.ts +12 -2
  273. package/dist/hooks/index.d.ts.map +1 -1
  274. package/dist/hooks/index.js +7 -2
  275. package/dist/hooks/useAnnounce.d.ts +40 -0
  276. package/dist/hooks/useAnnounce.d.ts.map +1 -0
  277. package/dist/hooks/useAnnounce.js +142 -0
  278. package/dist/hooks/useClickableContainer.d.ts +16 -1
  279. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  280. package/dist/hooks/useClickableContainer.js +16 -4
  281. package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
  282. package/dist/hooks/useEntryAnimation.js +4 -4
  283. package/dist/hooks/useFocusTrap.d.ts +18 -0
  284. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  285. package/dist/hooks/useFocusTrap.js +87 -3
  286. package/dist/hooks/useGridFocus.d.ts +88 -1
  287. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  288. package/dist/hooks/useGridFocus.js +261 -62
  289. package/dist/hooks/useKeyboardHint.d.ts +82 -0
  290. package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
  291. package/dist/hooks/useKeyboardHint.js +220 -0
  292. package/dist/hooks/useListFocus.d.ts +78 -7
  293. package/dist/hooks/useListFocus.d.ts.map +1 -1
  294. package/dist/hooks/useListFocus.js +305 -52
  295. package/dist/hooks/useLongPress.d.ts +21 -0
  296. package/dist/hooks/useLongPress.d.ts.map +1 -0
  297. package/dist/hooks/useLongPress.js +89 -0
  298. package/dist/hooks/useTreeFocus.d.ts +157 -0
  299. package/dist/hooks/useTreeFocus.d.ts.map +1 -0
  300. package/dist/hooks/useTreeFocus.js +337 -0
  301. package/dist/hooks/useTypeahead.d.ts +63 -0
  302. package/dist/hooks/useTypeahead.d.ts.map +1 -0
  303. package/dist/hooks/useTypeahead.js +117 -0
  304. package/dist/index.d.ts +1 -0
  305. package/dist/index.d.ts.map +1 -1
  306. package/dist/index.js +1 -0
  307. package/dist/utils/dateTypes.d.ts +12 -0
  308. package/dist/utils/dateTypes.d.ts.map +1 -1
  309. package/dist/utils/dateTypes.js +41 -1
  310. package/dist/utils/index.d.ts +4 -0
  311. package/dist/utils/index.d.ts.map +1 -1
  312. package/dist/utils/index.js +3 -1
  313. package/dist/utils/inputAria.d.ts +29 -0
  314. package/dist/utils/inputAria.d.ts.map +1 -0
  315. package/dist/utils/inputAria.js +30 -0
  316. package/dist/utils/timeParser.d.ts.map +1 -1
  317. package/dist/utils/timeParser.js +5 -2
  318. package/docs.mjs +2 -2
  319. package/package.json +12 -8
  320. package/src/Avatar/Avatar.test.tsx +37 -0
  321. package/src/Avatar/Avatar.tsx +10 -5
  322. package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
  323. package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
  324. package/src/Button/Button.tsx +3 -16
  325. package/src/ButtonGroup/ButtonGroup.test.tsx +9 -9
  326. package/src/ButtonGroup/ButtonGroup.tsx +0 -1
  327. package/src/Calendar/Calendar.doc.mjs +4 -4
  328. package/src/Calendar/Calendar.test.tsx +168 -30
  329. package/src/Calendar/Calendar.tsx +121 -66
  330. package/src/Calendar/hooks/index.ts +0 -6
  331. package/src/Calendar/index.ts +1 -3
  332. package/src/Calendar/styles.ts +4 -9
  333. package/src/Carousel/Carousel.doc.mjs +7 -1
  334. package/src/Carousel/Carousel.test.tsx +20 -0
  335. package/src/Carousel/Carousel.tsx +16 -1
  336. package/src/Center/Center.doc.mjs +12 -2
  337. package/src/Center/Center.tsx +28 -3
  338. package/src/Chat/ChatComposerInput.test.tsx +26 -7
  339. package/src/Chat/ChatComposerInput.tsx +0 -1
  340. package/src/Chat/ChatDictationButton.doc.mjs +1 -1
  341. package/src/Chat/ChatMessageList.doc.mjs +8 -0
  342. package/src/Chat/ChatMessageList.test.tsx +18 -0
  343. package/src/Chat/ChatMessageList.tsx +16 -0
  344. package/src/Chat/useTriggerMenu.tsx +22 -4
  345. package/src/CheckboxInput/CheckboxInput.doc.mjs +10 -0
  346. package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
  347. package/src/CheckboxInput/CheckboxInput.tsx +78 -6
  348. package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
  349. package/src/CheckboxList/CheckboxList.test.tsx +192 -26
  350. package/src/CheckboxList/CheckboxList.tsx +56 -3
  351. package/src/CheckboxList/CheckboxListContext.tsx +7 -0
  352. package/src/CheckboxList/CheckboxListItem.tsx +0 -3
  353. package/src/Citation/Citation.doc.mjs +10 -0
  354. package/src/Citation/Citation.test.tsx +121 -0
  355. package/src/Citation/Citation.tsx +15 -3
  356. package/src/CodeBlock/CodeBlock.test.tsx +115 -0
  357. package/src/CodeBlock/CodeBlock.tsx +63 -33
  358. package/src/CommandPalette/CommandPalette.test.tsx +47 -1
  359. package/src/CommandPalette/CommandPalette.tsx +9 -21
  360. package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
  361. package/src/ContextMenu/ContextMenu.test.tsx +155 -1
  362. package/src/ContextMenu/ContextMenu.tsx +113 -16
  363. package/src/DateInput/DateInput.doc.mjs +286 -56
  364. package/src/DateInput/DateInput.test.tsx +248 -2
  365. package/src/DateInput/DateInput.tsx +196 -100
  366. package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
  367. package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
  368. package/src/DateRangeInput/DateRangeInput.tsx +63 -5
  369. package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
  370. package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
  371. package/src/DateTimeInput/DateTimeInput.tsx +125 -17
  372. package/src/Dialog/Dialog.doc.mjs +2 -2
  373. package/src/Dialog/Dialog.tsx +12 -0
  374. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
  375. package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
  376. package/src/DropdownMenu/DropdownMenu.tsx +52 -18
  377. package/src/Field/Field.doc.mjs +59 -18
  378. package/src/Field/Field.test.tsx +32 -0
  379. package/src/Field/Field.tsx +23 -5
  380. package/src/Field/FieldLabel.tsx +55 -17
  381. package/src/FileInput/FileInput.doc.mjs +17 -0
  382. package/src/FileInput/FileInput.test.tsx +283 -49
  383. package/src/FileInput/FileInput.tsx +76 -4
  384. package/src/Grid/Grid.doc.mjs +17 -4
  385. package/src/Grid/Grid.test.tsx +43 -30
  386. package/src/Grid/Grid.tsx +38 -3
  387. package/src/Icon/Icon.doc.mjs +3 -3
  388. package/src/InputGroup/InputGroup.doc.mjs +111 -23
  389. package/src/InputGroup/InputGroup.test.tsx +257 -60
  390. package/src/InputGroup/InputGroup.tsx +23 -5
  391. package/src/InputGroup/InputGroupContext.ts +9 -4
  392. package/src/InputGroup/groupStyles.ts +7 -1
  393. package/src/InputGroup/index.ts +1 -0
  394. package/src/Kbd/Kbd.test.tsx +22 -4
  395. package/src/Kbd/Kbd.tsx +35 -3
  396. package/src/Layer/layerAnimations.stylex.ts +20 -4
  397. package/src/Layer/useLayer.doc.mjs +5 -0
  398. package/src/Layer/useLayer.test.tsx +111 -0
  399. package/src/Layer/useLayer.tsx +90 -9
  400. package/src/Layout/Layout.tsx +8 -16
  401. package/src/Layout/LayoutFooter.doc.mjs +4 -4
  402. package/src/Layout/LayoutFooter.tsx +3 -3
  403. package/src/Layout/LayoutHeader.doc.mjs +4 -4
  404. package/src/Layout/LayoutHeader.tsx +3 -3
  405. package/src/Layout/LayoutPanel.tsx +3 -3
  406. package/src/Layout/padding.stylex.ts +52 -0
  407. package/src/Lightbox/Lightbox.doc.mjs +9 -0
  408. package/src/Lightbox/Lightbox.test.tsx +53 -5
  409. package/src/Lightbox/Lightbox.tsx +9 -4
  410. package/src/Link/Link.doc.mjs +14 -0
  411. package/src/Link/Link.test.tsx +50 -0
  412. package/src/Link/Link.tsx +39 -4
  413. package/src/Markdown/Markdown.test.tsx +11 -0
  414. package/src/Markdown/Markdown.tsx +7 -0
  415. package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
  416. package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
  417. package/src/MoreMenu/MoreMenu.tsx +0 -9
  418. package/src/MultiSelector/MultiSelector.doc.mjs +30 -0
  419. package/src/MultiSelector/MultiSelector.test.tsx +375 -8
  420. package/src/MultiSelector/MultiSelector.tsx +194 -48
  421. package/src/MultiSelector/hooks.ts +27 -0
  422. package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
  423. package/src/NavMenu/NavHeadingMenu.tsx +50 -3
  424. package/src/NumberInput/NumberInput.doc.mjs +17 -0
  425. package/src/NumberInput/NumberInput.test.tsx +242 -40
  426. package/src/NumberInput/NumberInput.tsx +89 -11
  427. package/src/Pagination/Pagination.doc.mjs +3 -3
  428. package/src/Pagination/Pagination.test.tsx +117 -5
  429. package/src/Pagination/Pagination.tsx +21 -1
  430. package/src/Popover/Popover.doc.mjs +26 -0
  431. package/src/Popover/Popover.test.tsx +121 -0
  432. package/src/Popover/Popover.tsx +23 -2
  433. package/src/Popover/usePopover.doc.mjs +9 -3
  434. package/src/Popover/usePopover.tsx +70 -12
  435. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  436. package/src/PowerSearch/PowerSearch.test.tsx +97 -1
  437. package/src/PowerSearch/PowerSearch.tsx +16 -3
  438. package/src/ProgressBar/ProgressBar.test.tsx +34 -26
  439. package/src/ProgressBar/ProgressBar.tsx +3 -4
  440. package/src/RadioList/RadioList.doc.mjs +9 -0
  441. package/src/RadioList/RadioList.test.tsx +252 -16
  442. package/src/RadioList/RadioList.tsx +166 -10
  443. package/src/RadioList/RadioListItem.tsx +14 -2
  444. package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
  445. package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
  446. package/src/SegmentedControl/SegmentedControl.tsx +102 -54
  447. package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
  448. package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
  449. package/src/SelectableCard/SelectableCard.doc.mjs +1 -1
  450. package/src/Selector/Selector.doc.mjs +26 -0
  451. package/src/Selector/Selector.test.tsx +387 -15
  452. package/src/Selector/Selector.tsx +175 -67
  453. package/src/Selector/hooks.ts +23 -0
  454. package/src/SideNav/SideNav.test.tsx +48 -0
  455. package/src/SideNav/SideNavHeading.tsx +8 -2
  456. package/src/SideNav/SideNavItem.tsx +2 -4
  457. package/src/Skeleton/Skeleton.test.tsx +25 -0
  458. package/src/Skeleton/Skeleton.tsx +11 -1
  459. package/src/Slider/Slider.doc.mjs +15 -0
  460. package/src/Slider/Slider.test.tsx +155 -2
  461. package/src/Slider/Slider.tsx +53 -5
  462. package/src/Spinner/Spinner.tsx +7 -1
  463. package/src/Stack/Stack.doc.mjs +77 -0
  464. package/src/Stack/Stack.test.tsx +55 -5
  465. package/src/Stack/Stack.tsx +73 -24
  466. package/src/Stack/StackItem.test.tsx +23 -0
  467. package/src/Stack/StackItem.tsx +20 -23
  468. package/src/Switch/Switch.doc.mjs +15 -0
  469. package/src/Switch/Switch.test.tsx +162 -27
  470. package/src/Switch/Switch.tsx +61 -21
  471. package/src/TabList/Tab.tsx +6 -0
  472. package/src/TabList/TabList.doc.mjs +6 -0
  473. package/src/TabList/TabList.test.tsx +251 -0
  474. package/src/TabList/TabList.tsx +103 -12
  475. package/src/TabList/TabListContext.ts +7 -3
  476. package/src/TabList/TabMenu.tsx +6 -3
  477. package/src/Table/BaseTable.tsx +21 -17
  478. package/src/Table/Table.doc.mjs +2 -0
  479. package/src/Table/Table.test.tsx +10 -0
  480. package/src/Table/Table.tsx +8 -0
  481. package/src/Table/TableCell.tsx +25 -23
  482. package/src/Table/TableHeaderCell.tsx +28 -29
  483. package/src/Table/index.ts +3 -2
  484. package/src/Table/plugins/pagination/paginateData.ts +10 -3
  485. package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
  486. package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
  487. package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
  488. package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
  489. package/src/Table/tableContextMenu.test.tsx +157 -0
  490. package/src/Table/tableContextMenu.tsx +142 -0
  491. package/src/Table/types.ts +74 -0
  492. package/src/Table/useTableColumnResize.doc.mjs +3 -3
  493. package/src/Table/useTableStickyColumns.doc.mjs +2 -2
  494. package/src/Text/Text.doc.mjs +18 -18
  495. package/src/TextArea/TextArea.doc.mjs +17 -0
  496. package/src/TextArea/TextArea.test.tsx +167 -35
  497. package/src/TextArea/TextArea.tsx +62 -15
  498. package/src/TextInput/TextInput.doc.mjs +17 -0
  499. package/src/TextInput/TextInput.test.tsx +168 -34
  500. package/src/TextInput/TextInput.tsx +77 -9
  501. package/src/Thumbnail/Thumbnail.doc.mjs +4 -4
  502. package/src/TimeInput/TimeInput.doc.mjs +340 -60
  503. package/src/TimeInput/TimeInput.test.tsx +255 -7
  504. package/src/TimeInput/TimeInput.tsx +176 -70
  505. package/src/Timestamp/Timestamp.doc.mjs +19 -19
  506. package/src/Toast/Toast.tsx +14 -0
  507. package/src/Toast/ToastViewport.test.tsx +214 -0
  508. package/src/Toast/ToastViewport.tsx +167 -21
  509. package/src/Tokenizer/Tokenizer.doc.mjs +29 -14
  510. package/src/Tokenizer/Tokenizer.test.tsx +105 -1
  511. package/src/Tokenizer/Tokenizer.tsx +37 -1
  512. package/src/Toolbar/Toolbar.test.tsx +109 -6
  513. package/src/Toolbar/Toolbar.tsx +59 -5
  514. package/src/Tooltip/Tooltip.test.tsx +68 -0
  515. package/src/Tooltip/useTooltip.tsx +55 -8
  516. package/src/TopNav/TopNav.test.tsx +50 -0
  517. package/src/TopNav/TopNavHeading.tsx +17 -1
  518. package/src/TreeList/TreeList.test.tsx +295 -6
  519. package/src/TreeList/TreeList.tsx +73 -1
  520. package/src/TreeList/TreeListItem.tsx +51 -5
  521. package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
  522. package/src/Typeahead/BaseTypeahead.tsx +93 -9
  523. package/src/Typeahead/Typeahead.doc.mjs +141 -30
  524. package/src/Typeahead/Typeahead.test.tsx +331 -1
  525. package/src/Typeahead/Typeahead.tsx +105 -33
  526. package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
  527. package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
  528. package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
  529. package/src/VisuallyHidden/index.ts +15 -0
  530. package/src/docs-script.test.mjs +50 -0
  531. package/src/hooks/focusableSelector.ts +25 -0
  532. package/src/hooks/index.ts +28 -2
  533. package/src/hooks/useAnnounce.test.tsx +101 -0
  534. package/src/hooks/useAnnounce.ts +168 -0
  535. package/src/hooks/useClickableContainer.ts +16 -4
  536. package/src/hooks/useEntryAnimation.ts +16 -4
  537. package/src/hooks/useFocusTrap.test.tsx +132 -0
  538. package/src/hooks/useFocusTrap.ts +98 -4
  539. package/src/hooks/useGridFocus.doc.mjs +40 -2
  540. package/src/hooks/useGridFocus.test.tsx +132 -0
  541. package/src/hooks/useGridFocus.ts +343 -67
  542. package/src/hooks/useKeyboardHint.doc.mjs +101 -0
  543. package/src/hooks/useKeyboardHint.test.tsx +70 -0
  544. package/src/hooks/useKeyboardHint.tsx +332 -0
  545. package/src/hooks/useListFocus.doc.mjs +50 -10
  546. package/src/hooks/useListFocus.test.tsx +375 -0
  547. package/src/hooks/useListFocus.ts +395 -57
  548. package/src/hooks/useLongPress.test.tsx +134 -0
  549. package/src/hooks/useLongPress.ts +119 -0
  550. package/src/hooks/useTreeFocus.doc.mjs +140 -0
  551. package/src/hooks/useTreeFocus.test.tsx +214 -0
  552. package/src/hooks/useTreeFocus.ts +559 -0
  553. package/src/hooks/useTypeahead.test.tsx +109 -0
  554. package/src/hooks/useTypeahead.ts +183 -0
  555. package/src/index.ts +1 -0
  556. package/src/theme/derivedVarRegistry.test.ts +10 -5
  557. package/src/utils/dateTypes.test.ts +40 -0
  558. package/src/utils/dateTypes.ts +40 -0
  559. package/src/utils/index.ts +9 -0
  560. package/src/utils/inputAria.test.ts +39 -0
  561. package/src/utils/inputAria.ts +58 -0
  562. package/src/utils/timeParser.test.ts +10 -0
  563. package/src/utils/timeParser.ts +5 -2
  564. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
  565. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
  566. package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
  567. package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
@@ -15,7 +15,6 @@
15
15
  import {createElement, type ElementType, type ReactNode, type Ref} from 'react';
16
16
  import type {BaseProps} from '../BaseProps';
17
17
  import * as stylex from '@stylexjs/stylex';
18
- import type {StyleXStyles} from '@stylexjs/stylex';
19
18
  import {
20
19
  stack,
21
20
  type StackCrossAlignment,
@@ -25,9 +24,19 @@ import {
25
24
  type SpacingStep,
26
25
  } from './stack.stylex';
27
26
  import type {SizeValue} from '../utils/types';
27
+ import {
28
+ paddingInlineStyles,
29
+ paddingBlockStyles,
30
+ } from '../Layout/padding.stylex';
28
31
  import {mergeProps} from '../utils';
29
32
  import {themeProps} from '../utils/themeProps';
30
33
 
34
+ const overflowStyles = stylex.create({
35
+ scrollable: {
36
+ overflow: 'auto',
37
+ },
38
+ });
39
+
31
40
  /**
32
41
  * Alignment values accepted by Stack.
33
42
  *
@@ -40,7 +49,6 @@ import {themeProps} from '../utils/themeProps';
40
49
  */
41
50
  export type StackAlignment = StackMainAlignment | StackCrossAlignment;
42
51
 
43
-
44
52
  export interface StackProps extends BaseProps<HTMLElement> {
45
53
  /** Ref forwarded to the root element */
46
54
  ref?: React.Ref<HTMLElement>;
@@ -100,12 +108,55 @@ export interface StackProps extends BaseProps<HTMLElement> {
100
108
  */
101
109
  height?: SizeValue;
102
110
 
111
+ /**
112
+ * Maximum width of the stack container.
113
+ * Numbers are treated as pixels, strings are used as-is (e.g., '100%').
114
+ */
115
+ maxWidth?: SizeValue;
116
+
117
+ /**
118
+ * Minimum height of the stack container.
119
+ * Numbers are treated as pixels, strings are used as-is (e.g., '100%').
120
+ */
121
+ minHeight?: SizeValue;
122
+
103
123
  /**
104
124
  * Spacing between items.
105
125
  * Accepts numeric spacing steps: 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10.
106
126
  */
107
127
  gap?: SpacingStep;
108
128
 
129
+ /**
130
+ * Inner padding on all sides, using the spacing scale.
131
+ * Accepts numeric spacing steps: 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6, 8, 10.
132
+ *
133
+ * Matches the `padding` prop on `Card`, `LayoutContent`, and `LayoutPanel`.
134
+ */
135
+ padding?: SpacingStep;
136
+
137
+ /**
138
+ * Inline (horizontal) padding, using the spacing scale.
139
+ * Overrides `padding` on the inline axis when both are set.
140
+ */
141
+ paddingInline?: SpacingStep;
142
+
143
+ /**
144
+ * Block (vertical) padding, using the spacing scale.
145
+ * Overrides `padding` on the block axis when both are set.
146
+ */
147
+ paddingBlock?: SpacingStep;
148
+
149
+ /**
150
+ * Enables scrollable overflow (`overflow: auto`) for the stack.
151
+ *
152
+ * Matches the `isScrollable` prop on `LayoutContent` and `LayoutPanel`.
153
+ * When the stack is itself a flex child that should scroll, pair it with
154
+ * a parent `StackItem size="fill" isScrollable` (StackItem applies the
155
+ * `min-height: 0` reset that flex scroll regions require).
156
+ * @default false
157
+ */
158
+ isScrollable?: boolean;
159
+
109
160
  /**
110
161
  * Whether items should wrap.
111
162
  * - `nowrap`: Items stay on one line (default)
@@ -121,28 +172,6 @@ export interface StackProps extends BaseProps<HTMLElement> {
121
172
  */
122
173
  as?: ElementType;
123
174
 
124
- /**
125
- * StyleX styles created via `stylex.create()`. Merged with the component's
126
- * base styles inside a single `stylex.props()` call for optimal deduplication.
127
- *
128
- * @example
129
- * ```
130
- * const overrides = stylex.create({ root: { marginBottom: 8 } });
131
- * <Component xstyle={overrides.root} />
132
- * ```
133
- */
134
- xstyle?: StyleXStyles;
135
- /**
136
- * CSS class name(s) appended to the root element.
137
- * If you're using StyleX, prefer `xstyle` for optimal style deduplication.
138
- */
139
- className?: string;
140
- /**
141
- * Inline styles to apply to the root element. Spread after StyleX
142
- * inline styles, so these values take priority.
143
- */
144
- style?: React.CSSProperties;
145
-
146
175
  /**
147
176
  * Content to render inside the stack.
148
177
  */
@@ -180,8 +209,14 @@ export function Stack({
180
209
  justify,
181
210
  align,
182
211
  gap,
212
+ padding,
213
+ paddingInline,
214
+ paddingBlock,
215
+ isScrollable,
183
216
  width,
184
217
  height,
218
+ maxWidth,
219
+ minHeight,
185
220
  wrap,
186
221
  as: element = 'div',
187
222
  xstyle,
@@ -207,6 +242,11 @@ export function Stack({
207
242
  ? (resolvedVAlign as StackCrossAlignment | undefined)
208
243
  : (resolvedHAlign as StackCrossAlignment | undefined);
209
244
 
245
+ // Resolve padding to per-axis values: `padding` sets both axes; `paddingInline`
246
+ // / `paddingBlock` take precedence on their own axis when provided.
247
+ const resolvedPaddingInline = paddingInline ?? padding;
248
+ const resolvedPaddingBlock = paddingBlock ?? padding;
249
+
210
250
  const stylexProps = stylex.props(
211
251
  ...stack({
212
252
  direction,
@@ -215,6 +255,9 @@ export function Stack({
215
255
  gap,
216
256
  wrap,
217
257
  }),
258
+ resolvedPaddingInline != null && paddingInlineStyles[resolvedPaddingInline],
259
+ resolvedPaddingBlock != null && paddingBlockStyles[resolvedPaddingBlock],
260
+ isScrollable && overflowStyles.scrollable,
218
261
  xstyle,
219
262
  );
220
263
 
@@ -226,6 +269,12 @@ export function Stack({
226
269
  ...(height != null && {
227
270
  height: typeof height === 'number' ? `${height}px` : height,
228
271
  }),
272
+ ...(maxWidth != null && {
273
+ maxWidth: typeof maxWidth === 'number' ? `${maxWidth}px` : maxWidth,
274
+ }),
275
+ ...(minHeight != null && {
276
+ minHeight: typeof minHeight === 'number' ? `${minHeight}px` : minHeight,
277
+ }),
229
278
  };
230
279
 
231
280
  return createElement(
@@ -79,4 +79,27 @@ describe('StackItem', () => {
79
79
  const element = screen.getByTestId('stack-item');
80
80
  expect(element).toHaveAttribute('aria-label', 'Stack item');
81
81
  });
82
+
83
+ it('applies an overflow class when isScrollable is set', () => {
84
+ const {rerender} = render(
85
+ <StackItem data-testid="stack-item">Content</StackItem>,
86
+ );
87
+ const withoutScroll = screen.getByTestId('stack-item').className;
88
+ rerender(
89
+ <StackItem isScrollable data-testid="stack-item">
90
+ Content
91
+ </StackItem>,
92
+ );
93
+ const withScroll = screen.getByTestId('stack-item').className;
94
+ expect(withScroll).not.toBe(withoutScroll);
95
+ });
96
+
97
+ it('composes isScrollable with size="fill"', () => {
98
+ render(
99
+ <StackItem size="fill" isScrollable data-testid="stack-item">
100
+ Content
101
+ </StackItem>,
102
+ );
103
+ expect(screen.getByTestId('stack-item').className).not.toBe('');
104
+ });
82
105
  });
@@ -14,7 +14,6 @@
14
14
  import {createElement, type ElementType, type ReactNode, type Ref} from 'react';
15
15
  import type {BaseProps} from '../BaseProps';
16
16
  import * as stylex from '@stylexjs/stylex';
17
- import type {StyleXStyles} from '@stylexjs/stylex';
18
17
  import {
19
18
  stackItem,
20
19
  type StackItemCrossAlignSelf,
@@ -23,6 +22,12 @@ import {
23
22
  import {mergeProps} from '../utils';
24
23
  import {themeProps} from '../utils/themeProps';
25
24
 
25
+ const overflowStyles = stylex.create({
26
+ scrollable: {
27
+ overflow: 'auto',
28
+ },
29
+ });
30
+
26
31
  export interface StackItemProps extends BaseProps<HTMLElement> {
27
32
  /** Ref forwarded to the root element */
28
33
  ref?: React.Ref<HTMLElement>;
@@ -42,32 +47,22 @@ export interface StackItemProps extends BaseProps<HTMLElement> {
42
47
  size?: StackItemSize;
43
48
 
44
49
  /**
45
- * The element type to render.
46
- * @default 'div'
47
- */
48
- as?: ElementType;
49
-
50
- /**
51
- * StyleX styles created via `stylex.create()`. Merged with the component's
52
- * base styles inside a single `stylex.props()` call for optimal deduplication.
50
+ * Enables scrollable overflow (`overflow: auto`) for the item.
53
51
  *
54
- * @example
55
- * ```
56
- * const overrides = stylex.create({ root: { marginBottom: 8 } });
57
- * <Component xstyle={overrides.root} />
58
- * ```
52
+ * StackItem already applies the flex `min-height: 0` / `min-width: 0`
53
+ * reset, so `<StackItem size="fill" isScrollable>` is a complete scroll
54
+ * region it grows to fill the stack and scrolls its own overflow with
55
+ * no extra style plumbing. Matches `isScrollable` on `LayoutContent`
56
+ * and `LayoutPanel`.
57
+ * @default false
59
58
  */
60
- xstyle?: StyleXStyles;
61
- /**
62
- * CSS class name(s) appended to the root element.
63
- * If you're using StyleX, prefer `xstyle` for optimal style deduplication.
64
- */
65
- className?: string;
59
+ isScrollable?: boolean;
60
+
66
61
  /**
67
- * Inline styles to apply to the root element. Spread after StyleX
68
- * inline styles, so these values take priority.
62
+ * The element type to render.
63
+ * @default 'div'
69
64
  */
70
- style?: React.CSSProperties;
65
+ as?: ElementType;
71
66
 
72
67
  /**
73
68
  * Content to render inside the stack item.
@@ -92,6 +87,7 @@ export interface StackItemProps extends BaseProps<HTMLElement> {
92
87
  export function StackItem({
93
88
  crossAlignSelf,
94
89
  size,
90
+ isScrollable,
95
91
  as: element = 'div',
96
92
  xstyle,
97
93
  className,
@@ -102,6 +98,7 @@ export function StackItem({
102
98
  }: StackItemProps) {
103
99
  const stylexProps = stylex.props(
104
100
  ...stackItem({crossAlignSelf, size}),
101
+ isScrollable && overflowStyles.scrollable,
105
102
  xstyle,
106
103
  );
107
104
 
@@ -62,6 +62,12 @@ export const docs = {
62
62
  description: 'Whether the switch is disabled.',
63
63
  default: 'false',
64
64
  },
65
+ {
66
+ name: 'disabledMessage',
67
+ type: 'string',
68
+ description:
69
+ 'Explains why the switch is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the switch focusable via aria-disabled (toggling stays blocked). Use this instead of wrapping a disabled Switch in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
70
+ },
65
71
  {
66
72
  name: 'isOptional',
67
73
  type: 'boolean',
@@ -133,6 +139,7 @@ export const docs = {
133
139
  { guidance: true, description: 'Pair with a clear, concise label that describes the setting being controlled.' },
134
140
  { guidance: false, description: 'Use for options that require a form submission to take effect; use a checkbox instead.' },
135
141
  { guidance: false, description: 'Use a switch for multi-state values; it\'s strictly on/off.' },
142
+ { guidance: false, description: 'Wrap a disabled switch in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
136
143
  ],
137
144
  },
138
145
  };
@@ -196,6 +203,12 @@ export const docsZh = {
196
203
  description: '开关是否被禁用。',
197
204
  default: 'false',
198
205
  },
206
+ {
207
+ name: 'disabledMessage',
208
+ type: 'string',
209
+ description:
210
+ 'Explains why the switch is disabled. With isDisabled, shows a tooltip on hover/keyboard focus and keeps the switch focusable via aria-disabled (toggling stays blocked). Use this instead of wrapping a disabled Switch in Tooltip — disabled controls swallow the hover events an external Tooltip needs.',
211
+ },
199
212
  {
200
213
  name: 'isOptional',
201
214
  type: 'boolean',
@@ -267,6 +280,7 @@ export const docsZh = {
267
280
  { guidance: true, description: 'Pair with a clear, concise label that describes the setting being controlled.' },
268
281
  { guidance: false, description: 'Use for options that require a form submission to take effect; use a checkbox instead.' },
269
282
  { guidance: false, description: 'Use a switch for multi-state values; it\'s strictly on/off.' },
283
+ { guidance: false, description: 'Wrap a disabled switch in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
270
284
  ],
271
285
  },
272
286
  };
@@ -282,6 +296,7 @@ export const docsDense = {
282
296
  { guidance: true, description: 'Pair with a clear, concise label that describes the setting being controlled.' },
283
297
  { guidance: false, description: 'Use for options that require a form submission to take effect; use a checkbox instead.' },
284
298
  { guidance: false, description: 'Use a switch for multi-state values; it\'s strictly on/off.' },
299
+ { guidance: false, description: 'Wrap a disabled switch in Tooltip to explain why it is disabled; disabled controls swallow the hover events the wrapper needs. Use the disabledMessage prop instead.' },
285
300
  ],
286
301
  },
287
302
  propDescriptions: {
@@ -9,41 +9,56 @@
9
9
  * SYNC: When Switch.tsx changes, update tests to match new behavior
10
10
  */
11
11
 
12
- import {describe, it, expect, vi} from 'vitest';
13
- import {render, screen} from '@testing-library/react';
12
+ import {describe, it, expect, vi, beforeEach} from 'vitest';
13
+ import {render, screen, fireEvent, waitFor} from '@testing-library/react';
14
14
  import userEvent from '@testing-library/user-event';
15
15
  import {Switch} from './Switch';
16
16
 
17
+ // Mock showPopover/hidePopover (not implemented in jsdom) so the tooltip layer
18
+ // reflects its open state via a `popover-open` attribute the tests can assert.
19
+ beforeEach(() => {
20
+ HTMLElement.prototype.showPopover = vi.fn(function (this: HTMLElement) {
21
+ this.setAttribute('popover-open', '');
22
+ const event = new Event('toggle', {bubbles: false});
23
+ Object.defineProperty(event, 'newState', {value: 'open'});
24
+ this.dispatchEvent(event);
25
+ });
26
+ HTMLElement.prototype.hidePopover = vi.fn(function (this: HTMLElement) {
27
+ this.removeAttribute('popover-open');
28
+ const event = new Event('toggle', {bubbles: false});
29
+ Object.defineProperty(event, 'newState', {value: 'closed'});
30
+ this.dispatchEvent(event);
31
+ });
32
+ const originalMatches = HTMLElement.prototype.matches;
33
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
34
+ (HTMLElement.prototype as any).matches = function (
35
+ selector: string,
36
+ ): boolean {
37
+ if (selector === ':popover-open') {
38
+ return this.hasAttribute('popover-open');
39
+ }
40
+ return originalMatches.call(this, selector);
41
+ };
42
+ });
43
+
17
44
  describe('Switch', () => {
18
45
  it('renders with label', () => {
19
46
  render(
20
- <Switch
21
- label="Enable notifications"
22
- value={false}
23
- onChange={() => {}}
24
- />,
47
+ <Switch label="Enable notifications" value={false} onChange={() => {}} />,
25
48
  );
26
49
  expect(screen.getByLabelText('Enable notifications')).toBeInTheDocument();
27
50
  });
28
51
 
29
52
  it('renders as off by default', () => {
30
53
  render(
31
- <Switch
32
- label="Enable notifications"
33
- value={false}
34
- onChange={() => {}}
35
- />,
54
+ <Switch label="Enable notifications" value={false} onChange={() => {}} />,
36
55
  );
37
56
  expect(screen.getByRole('switch')).not.toBeChecked();
38
57
  });
39
58
 
40
59
  it('renders as on when value prop is true', () => {
41
60
  render(
42
- <Switch
43
- label="Enable notifications"
44
- value={true}
45
- onChange={() => {}}
46
- />,
61
+ <Switch label="Enable notifications" value={true} onChange={() => {}} />,
47
62
  );
48
63
  expect(screen.getByRole('switch')).toBeChecked();
49
64
  });
@@ -184,11 +199,7 @@ describe('Switch', () => {
184
199
 
185
200
  it('shows label visually by default', () => {
186
201
  render(
187
- <Switch
188
- label="Enable notifications"
189
- value={false}
190
- onChange={() => {}}
191
- />,
202
+ <Switch label="Enable notifications" value={false} onChange={() => {}} />,
192
203
  );
193
204
  const label = screen.getByText('Enable notifications');
194
205
  expect(label).toBeVisible();
@@ -230,11 +241,7 @@ describe('Switch', () => {
230
241
 
231
242
  it('has role="switch" for accessibility', () => {
232
243
  render(
233
- <Switch
234
- label="Enable notifications"
235
- value={false}
236
- onChange={() => {}}
237
- />,
244
+ <Switch label="Enable notifications" value={false} onChange={() => {}} />,
238
245
  );
239
246
  expect(screen.getByRole('switch')).toBeInTheDocument();
240
247
  });
@@ -335,4 +342,132 @@ describe('Switch', () => {
335
342
  expect(screen.getByRole('switch')).toBeRequired();
336
343
  });
337
344
 
345
+ describe('disabledMessage', () => {
346
+ const h = {hidden: true} as const;
347
+
348
+ function getRow(): HTMLElement {
349
+ return screen.getByRole('switch', h).closest('div')!.parentElement!;
350
+ }
351
+
352
+ it('shows the reason tooltip on hover when disabled with a reason', async () => {
353
+ render(
354
+ <Switch
355
+ label="Enable notifications"
356
+ value={false}
357
+ onChange={() => {}}
358
+ isDisabled
359
+ disabledMessage="Notifications are turned off org-wide"
360
+ />,
361
+ );
362
+ const tooltip = screen.getByRole('tooltip', h);
363
+ expect(tooltip).toHaveTextContent(
364
+ 'Notifications are turned off org-wide',
365
+ );
366
+ fireEvent.mouseEnter(getRow());
367
+ await waitFor(() => expect(tooltip).toHaveAttribute('popover-open'));
368
+ fireEvent.mouseLeave(getRow());
369
+ await waitFor(() => expect(tooltip).not.toHaveAttribute('popover-open'));
370
+ });
371
+
372
+ it('shows the reason tooltip on keyboard focus', async () => {
373
+ const user = userEvent.setup();
374
+ render(
375
+ <Switch
376
+ label="Enable notifications"
377
+ value={false}
378
+ onChange={() => {}}
379
+ isDisabled
380
+ disabledMessage="Notifications are turned off org-wide"
381
+ />,
382
+ );
383
+ const tooltip = screen.getByRole('tooltip', h);
384
+ await user.tab();
385
+ expect(screen.getByRole('switch', h)).toHaveFocus();
386
+ await waitFor(() => expect(tooltip).toHaveAttribute('popover-open'));
387
+ });
388
+
389
+ it('does not render a tooltip when not disabled', () => {
390
+ render(
391
+ <Switch
392
+ label="Enable notifications"
393
+ value={false}
394
+ onChange={() => {}}
395
+ disabledMessage="Notifications are turned off org-wide"
396
+ />,
397
+ );
398
+ expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
399
+ });
400
+
401
+ it('does not render a tooltip when disabled without a reason', () => {
402
+ render(
403
+ <Switch
404
+ label="Enable notifications"
405
+ value={false}
406
+ onChange={() => {}}
407
+ isDisabled
408
+ />,
409
+ );
410
+ expect(screen.queryByRole('tooltip', h)).not.toBeInTheDocument();
411
+ });
412
+
413
+ it('keeps the switch focusable via aria-disabled when a reason is provided', () => {
414
+ render(
415
+ <Switch
416
+ label="Enable notifications"
417
+ value={false}
418
+ onChange={() => {}}
419
+ isDisabled
420
+ disabledMessage="Notifications are turned off org-wide"
421
+ />,
422
+ );
423
+ const control = screen.getByRole('switch', h);
424
+ expect(control).not.toBeDisabled();
425
+ expect(control).toHaveAttribute('aria-disabled', 'true');
426
+ });
427
+
428
+ it('links the reason tooltip via aria-describedby', () => {
429
+ render(
430
+ <Switch
431
+ label="Enable notifications"
432
+ value={false}
433
+ onChange={() => {}}
434
+ isDisabled
435
+ disabledMessage="Notifications are turned off org-wide"
436
+ />,
437
+ );
438
+ const control = screen.getByRole('switch', h);
439
+ const tooltip = screen.getByRole('tooltip', h);
440
+ expect(control.getAttribute('aria-describedby')).toContain(tooltip.id);
441
+ });
442
+
443
+ it('blocks toggling while focusable-disabled', async () => {
444
+ const user = userEvent.setup();
445
+ const onChange = vi.fn();
446
+ render(
447
+ <Switch
448
+ label="Enable notifications"
449
+ value={false}
450
+ onChange={onChange}
451
+ isDisabled
452
+ disabledMessage="Notifications are turned off org-wide"
453
+ />,
454
+ );
455
+ const control = screen.getByRole('switch', h);
456
+ await user.click(control);
457
+ expect(onChange).not.toHaveBeenCalled();
458
+ expect(control).not.toBeChecked();
459
+ });
460
+
461
+ it('remains natively disabled when disabled without a reason', () => {
462
+ render(
463
+ <Switch
464
+ label="Enable notifications"
465
+ value={false}
466
+ onChange={() => {}}
467
+ isDisabled
468
+ />,
469
+ );
470
+ expect(screen.getByRole('switch')).toBeDisabled();
471
+ });
472
+ });
338
473
  });