@astryxdesign/core 0.1.1 → 0.1.2-canary.04e71b2

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 (631) hide show
  1. package/CHANGELOG.md +105 -0
  2. package/README.md +131 -13
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +11 -5
  5. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  6. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  7. package/dist/AvatarGroup/AvatarGroupOverflow.js +4 -1
  8. package/dist/Banner/Banner.d.ts +7 -0
  9. package/dist/Banner/Banner.d.ts.map +1 -1
  10. package/dist/Banner/Banner.js +9 -2
  11. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +1 -1
  12. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  13. package/dist/Breadcrumbs/BreadcrumbItem.js +24 -5
  14. package/dist/Button/Button.d.ts +12 -2
  15. package/dist/Button/Button.d.ts.map +1 -1
  16. package/dist/Button/Button.js +53 -17
  17. package/dist/Calendar/Calendar.d.ts +5 -4
  18. package/dist/Calendar/Calendar.d.ts.map +1 -1
  19. package/dist/Calendar/Calendar.js +82 -43
  20. package/dist/Calendar/hooks/index.d.ts +0 -2
  21. package/dist/Calendar/hooks/index.d.ts.map +1 -1
  22. package/dist/Calendar/hooks/index.js +1 -2
  23. package/dist/Calendar/index.d.ts +3 -3
  24. package/dist/Calendar/index.d.ts.map +1 -1
  25. package/dist/Calendar/index.js +1 -1
  26. package/dist/Calendar/styles.d.ts +3 -9
  27. package/dist/Calendar/styles.d.ts.map +1 -1
  28. package/dist/Calendar/styles.js +3 -11
  29. package/dist/Carousel/Carousel.d.ts.map +1 -1
  30. package/dist/Carousel/Carousel.js +17 -3
  31. package/dist/Center/Center.d.ts +11 -1
  32. package/dist/Center/Center.d.ts.map +1 -1
  33. package/dist/Center/Center.js +9 -3
  34. package/dist/Chat/ChatMessageList.d.ts +14 -1
  35. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  36. package/dist/Chat/ChatMessageList.js +2 -0
  37. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  38. package/dist/Chat/useTriggerMenu.js +4 -1
  39. package/dist/CheckboxInput/CheckboxInput.d.ts +23 -2
  40. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  41. package/dist/CheckboxInput/CheckboxInput.js +51 -9
  42. package/dist/CheckboxList/CheckboxList.d.ts +13 -1
  43. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  44. package/dist/CheckboxList/CheckboxList.js +39 -9
  45. package/dist/CheckboxList/CheckboxListContext.d.ts +7 -0
  46. package/dist/CheckboxList/CheckboxListContext.d.ts.map +1 -1
  47. package/dist/Citation/Citation.d.ts.map +1 -1
  48. package/dist/Citation/Citation.js +3 -3
  49. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  50. package/dist/CodeBlock/CodeBlock.js +49 -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 +59 -8
  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/EmptyState/EmptyState.d.ts.map +1 -1
  71. package/dist/EmptyState/EmptyState.js +7 -1
  72. package/dist/Field/Field.d.ts +19 -2
  73. package/dist/Field/Field.d.ts.map +1 -1
  74. package/dist/Field/Field.js +4 -0
  75. package/dist/Field/FieldLabel.d.ts +21 -2
  76. package/dist/Field/FieldLabel.d.ts.map +1 -1
  77. package/dist/Field/FieldLabel.js +41 -26
  78. package/dist/FileInput/FileInput.d.ts +22 -1
  79. package/dist/FileInput/FileInput.d.ts.map +1 -1
  80. package/dist/FileInput/FileInput.js +56 -10
  81. package/dist/Grid/Grid.d.ts +11 -1
  82. package/dist/Grid/Grid.d.ts.map +1 -1
  83. package/dist/Grid/Grid.js +8 -0
  84. package/dist/HoverCard/HoverCard.d.ts +2 -2
  85. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  86. package/dist/HoverCard/HoverCard.js +18 -6
  87. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  88. package/dist/HoverCard/useHoverCard.js +7 -3
  89. package/dist/InputGroup/InputGroup.d.ts +2 -2
  90. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  91. package/dist/InputGroup/InputGroup.js +14 -5
  92. package/dist/InputGroup/InputGroupContext.d.ts +4 -0
  93. package/dist/InputGroup/InputGroupContext.d.ts.map +1 -1
  94. package/dist/InputGroup/InputGroupContext.js +2 -2
  95. package/dist/InputGroup/index.d.ts +1 -0
  96. package/dist/InputGroup/index.d.ts.map +1 -1
  97. package/dist/Kbd/Kbd.d.ts.map +1 -1
  98. package/dist/Kbd/Kbd.js +34 -2
  99. package/dist/Layer/anchorName.d.ts +20 -0
  100. package/dist/Layer/anchorName.d.ts.map +1 -0
  101. package/dist/Layer/anchorName.js +36 -0
  102. package/dist/Layer/layerAnimations.stylex.d.ts +4 -0
  103. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  104. package/dist/Layer/layerAnimations.stylex.js +8 -4
  105. package/dist/Layer/useLayer.d.ts +29 -0
  106. package/dist/Layer/useLayer.d.ts.map +1 -1
  107. package/dist/Layer/useLayer.js +55 -11
  108. package/dist/Layout/Layout.d.ts +4 -11
  109. package/dist/Layout/Layout.d.ts.map +1 -1
  110. package/dist/Layout/Layout.js +10 -11
  111. package/dist/Layout/LayoutFooter.d.ts +2 -2
  112. package/dist/Layout/LayoutFooter.d.ts.map +1 -1
  113. package/dist/Layout/LayoutHeader.d.ts +2 -2
  114. package/dist/Layout/LayoutHeader.d.ts.map +1 -1
  115. package/dist/Layout/LayoutPanel.d.ts +2 -2
  116. package/dist/Layout/LayoutPanel.d.ts.map +1 -1
  117. package/dist/Layout/padding.stylex.d.ts +51 -0
  118. package/dist/Layout/padding.stylex.d.ts.map +1 -1
  119. package/dist/Layout/padding.stylex.js +63 -0
  120. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  121. package/dist/Lightbox/Lightbox.js +4 -2
  122. package/dist/Link/Link.d.ts +17 -2
  123. package/dist/Link/Link.d.ts.map +1 -1
  124. package/dist/Link/Link.js +20 -9
  125. package/dist/Link/LinkProvider.d.ts +1 -0
  126. package/dist/Link/LinkProvider.d.ts.map +1 -1
  127. package/dist/Link/LinkProvider.js +1 -0
  128. package/dist/Markdown/Markdown.d.ts.map +1 -1
  129. package/dist/Markdown/Markdown.js +18 -3
  130. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  131. package/dist/MobileNav/MobileNav.js +13 -0
  132. package/dist/MoreMenu/MoreMenu.d.ts +1 -7
  133. package/dist/MoreMenu/MoreMenu.d.ts.map +1 -1
  134. package/dist/MoreMenu/MoreMenu.js +0 -2
  135. package/dist/MultiSelector/MultiSelector.d.ts +25 -2
  136. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  137. package/dist/MultiSelector/MultiSelector.js +103 -22
  138. package/dist/MultiSelector/hooks.d.ts +12 -1
  139. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  140. package/dist/MultiSelector/hooks.js +14 -1
  141. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  142. package/dist/NavMenu/NavHeadingMenu.js +34 -3
  143. package/dist/NumberInput/NumberInput.d.ts +23 -2
  144. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  145. package/dist/NumberInput/NumberInput.js +62 -12
  146. package/dist/Pagination/Pagination.d.ts +1 -1
  147. package/dist/Pagination/Pagination.d.ts.map +1 -1
  148. package/dist/Pagination/Pagination.js +46 -28
  149. package/dist/Popover/usePopover.d.ts +25 -2
  150. package/dist/Popover/usePopover.d.ts.map +1 -1
  151. package/dist/Popover/usePopover.js +18 -6
  152. package/dist/PowerSearch/PowerSearch.d.ts +11 -1
  153. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  154. package/dist/PowerSearch/PowerSearch.js +6 -1
  155. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  156. package/dist/ProgressBar/ProgressBar.js +3 -5
  157. package/dist/RadioList/RadioList.d.ts +20 -2
  158. package/dist/RadioList/RadioList.d.ts.map +1 -1
  159. package/dist/RadioList/RadioList.js +105 -9
  160. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  161. package/dist/RadioList/RadioListItem.js +13 -2
  162. package/dist/SegmentedControl/SegmentedControl.d.ts +13 -2
  163. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  164. package/dist/SegmentedControl/SegmentedControl.js +78 -44
  165. package/dist/SegmentedControl/SegmentedControlContext.d.ts +7 -0
  166. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  167. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  168. package/dist/SegmentedControl/SegmentedControlItem.js +13 -2
  169. package/dist/Selector/Selector.d.ts +22 -1
  170. package/dist/Selector/Selector.d.ts.map +1 -1
  171. package/dist/Selector/Selector.js +84 -23
  172. package/dist/Selector/hooks.d.ts +8 -1
  173. package/dist/Selector/hooks.d.ts.map +1 -1
  174. package/dist/Selector/hooks.js +14 -1
  175. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  176. package/dist/SideNav/SideNavItem.js +1 -1
  177. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  178. package/dist/Skeleton/Skeleton.js +8 -2
  179. package/dist/Slider/Slider.d.ts +21 -0
  180. package/dist/Slider/Slider.d.ts.map +1 -1
  181. package/dist/Slider/Slider.js +38 -11
  182. package/dist/Spinner/Spinner.d.ts.map +1 -1
  183. package/dist/Spinner/Spinner.js +1 -1
  184. package/dist/Stack/Stack.d.ts +38 -23
  185. package/dist/Stack/Stack.d.ts.map +1 -1
  186. package/dist/Stack/Stack.js +25 -1
  187. package/dist/Stack/StackItem.d.ts +12 -23
  188. package/dist/Stack/StackItem.d.ts.map +1 -1
  189. package/dist/Stack/StackItem.js +8 -1
  190. package/dist/Switch/Switch.d.ts +23 -2
  191. package/dist/Switch/Switch.d.ts.map +1 -1
  192. package/dist/Switch/Switch.js +41 -11
  193. package/dist/TabList/Tab.d.ts.map +1 -1
  194. package/dist/TabList/Tab.js +6 -0
  195. package/dist/TabList/TabList.d.ts +16 -4
  196. package/dist/TabList/TabList.d.ts.map +1 -1
  197. package/dist/TabList/TabList.js +86 -10
  198. package/dist/TabList/TabListContext.d.ts +5 -0
  199. package/dist/TabList/TabListContext.d.ts.map +1 -1
  200. package/dist/TabList/TabListContext.js +5 -0
  201. package/dist/TabList/TabMenu.d.ts.map +1 -1
  202. package/dist/TabList/TabMenu.js +6 -1
  203. package/dist/Table/BaseTable.d.ts.map +1 -1
  204. package/dist/Table/BaseTable.js +38 -16
  205. package/dist/Table/Table.d.ts.map +1 -1
  206. package/dist/Table/Table.js +36 -7
  207. package/dist/Table/TableCell.d.ts +8 -1
  208. package/dist/Table/TableCell.d.ts.map +1 -1
  209. package/dist/Table/TableCell.js +10 -10
  210. package/dist/Table/TableHeaderCell.d.ts +8 -1
  211. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  212. package/dist/Table/TableHeaderCell.js +16 -16
  213. package/dist/Table/TableRow.d.ts +6 -1
  214. package/dist/Table/TableRow.d.ts.map +1 -1
  215. package/dist/Table/TableRow.js +15 -7
  216. package/dist/Table/index.d.ts +4 -1
  217. package/dist/Table/index.d.ts.map +1 -1
  218. package/dist/Table/index.js +3 -2
  219. package/dist/Table/plugins/pagination/paginateData.d.ts +2 -1
  220. package/dist/Table/plugins/pagination/paginateData.d.ts.map +1 -1
  221. package/dist/Table/plugins/pagination/paginateData.js +8 -3
  222. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  223. package/dist/Table/plugins/pagination/useTablePagination.js +6 -1
  224. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  225. package/dist/Table/plugins/sortable/useTableSortable.js +59 -3
  226. package/dist/Table/plugins/stickyColumns/index.d.ts +3 -0
  227. package/dist/Table/plugins/stickyColumns/index.d.ts.map +1 -0
  228. package/dist/Table/plugins/stickyColumns/index.js +3 -0
  229. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts +25 -0
  230. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -0
  231. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +369 -0
  232. package/dist/Table/tableContextMenu.d.ts +33 -0
  233. package/dist/Table/tableContextMenu.d.ts.map +1 -0
  234. package/dist/Table/tableContextMenu.js +133 -0
  235. package/dist/Table/types.d.ts +161 -5
  236. package/dist/Table/types.d.ts.map +1 -1
  237. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  238. package/dist/Table/useBaseTablePlugins.js +1 -1
  239. package/dist/Text/text.stylex.d.ts +2 -2
  240. package/dist/Text/text.stylex.js +2 -2
  241. package/dist/TextArea/TextArea.d.ts +22 -1
  242. package/dist/TextArea/TextArea.d.ts.map +1 -1
  243. package/dist/TextArea/TextArea.js +41 -9
  244. package/dist/TextInput/TextInput.d.ts +23 -2
  245. package/dist/TextInput/TextInput.d.ts.map +1 -1
  246. package/dist/TextInput/TextInput.js +55 -10
  247. package/dist/TimeInput/TimeInput.d.ts +23 -1
  248. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  249. package/dist/TimeInput/TimeInput.js +53 -10
  250. package/dist/Timestamp/Timestamp.d.ts +1 -1
  251. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  252. package/dist/Timestamp/Timestamp.js +28 -3
  253. package/dist/Toast/Toast.d.ts.map +1 -1
  254. package/dist/Toast/Toast.js +14 -0
  255. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  256. package/dist/Toast/ToastViewport.js +132 -3
  257. package/dist/ToggleButton/ToggleButton.d.ts +7 -9
  258. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  259. package/dist/ToggleButton/ToggleButton.js +34 -57
  260. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  261. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  262. package/dist/Tokenizer/Tokenizer.js +27 -5
  263. package/dist/Toolbar/Toolbar.d.ts +3 -3
  264. package/dist/Toolbar/Toolbar.d.ts.map +1 -1
  265. package/dist/Toolbar/Toolbar.js +51 -7
  266. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  267. package/dist/Tooltip/useTooltip.js +57 -9
  268. package/dist/TreeList/TreeList.d.ts +1 -1
  269. package/dist/TreeList/TreeList.d.ts.map +1 -1
  270. package/dist/TreeList/TreeList.js +72 -2
  271. package/dist/TreeList/TreeListItem.d.ts +11 -1
  272. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  273. package/dist/TreeList/TreeListItem.js +51 -12
  274. package/dist/TreeList/treeListItem.markers.stylex.d.ts +16 -0
  275. package/dist/TreeList/treeListItem.markers.stylex.d.ts.map +1 -0
  276. package/dist/TreeList/treeListItem.markers.stylex.js +22 -0
  277. package/dist/Typeahead/BaseTypeahead.d.ts +9 -0
  278. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  279. package/dist/Typeahead/BaseTypeahead.js +67 -6
  280. package/dist/Typeahead/Typeahead.d.ts +24 -1
  281. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  282. package/dist/Typeahead/Typeahead.js +29 -5
  283. package/dist/VisuallyHidden/VisuallyHidden.d.ts +61 -0
  284. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -0
  285. package/dist/VisuallyHidden/VisuallyHidden.js +65 -0
  286. package/dist/VisuallyHidden/index.d.ts +11 -0
  287. package/dist/VisuallyHidden/index.d.ts.map +1 -0
  288. package/dist/VisuallyHidden/index.js +13 -0
  289. package/dist/astryx.css +40 -1
  290. package/dist/astryx.umd.js +147 -0
  291. package/dist/astryx.umd.js.map +7 -0
  292. package/dist/hooks/focusableSelector.d.ts +22 -0
  293. package/dist/hooks/focusableSelector.d.ts.map +1 -0
  294. package/dist/hooks/focusableSelector.js +24 -0
  295. package/dist/hooks/index.d.ts +12 -2
  296. package/dist/hooks/index.d.ts.map +1 -1
  297. package/dist/hooks/index.js +7 -2
  298. package/dist/hooks/useAnnounce.d.ts +40 -0
  299. package/dist/hooks/useAnnounce.d.ts.map +1 -0
  300. package/dist/hooks/useAnnounce.js +142 -0
  301. package/dist/hooks/useClickableContainer.d.ts +16 -1
  302. package/dist/hooks/useClickableContainer.d.ts.map +1 -1
  303. package/dist/hooks/useClickableContainer.js +16 -4
  304. package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
  305. package/dist/hooks/useEntryAnimation.js +4 -4
  306. package/dist/hooks/useFocusTrap.d.ts +18 -0
  307. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  308. package/dist/hooks/useFocusTrap.js +87 -3
  309. package/dist/hooks/useGridFocus.d.ts +88 -1
  310. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  311. package/dist/hooks/useGridFocus.js +261 -62
  312. package/dist/hooks/useKeyboardHint.d.ts +82 -0
  313. package/dist/hooks/useKeyboardHint.d.ts.map +1 -0
  314. package/dist/hooks/useKeyboardHint.js +220 -0
  315. package/dist/hooks/useListFocus.d.ts +78 -7
  316. package/dist/hooks/useListFocus.d.ts.map +1 -1
  317. package/dist/hooks/useListFocus.js +305 -52
  318. package/dist/hooks/useLongPress.d.ts +21 -0
  319. package/dist/hooks/useLongPress.d.ts.map +1 -0
  320. package/dist/hooks/useLongPress.js +89 -0
  321. package/dist/hooks/useTreeFocus.d.ts +157 -0
  322. package/dist/hooks/useTreeFocus.d.ts.map +1 -0
  323. package/dist/hooks/useTreeFocus.js +337 -0
  324. package/dist/hooks/useTypeahead.d.ts +63 -0
  325. package/dist/hooks/useTypeahead.d.ts.map +1 -0
  326. package/dist/hooks/useTypeahead.js +117 -0
  327. package/dist/index.d.ts +1 -0
  328. package/dist/index.d.ts.map +1 -1
  329. package/dist/index.js +1 -0
  330. package/dist/theme/generateThemeRules.js +1 -1
  331. package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
  332. package/dist/theme/syntax/SyntaxTheme.js +1 -1
  333. package/dist/theme/syntax/defineSyntaxTheme.d.ts.map +1 -1
  334. package/dist/theme/syntax/defineSyntaxTheme.js +2 -2
  335. package/dist/theme/syntax/presets.d.ts +1 -1
  336. package/dist/theme/syntax/presets.d.ts.map +1 -1
  337. package/dist/theme/syntax/presets.js +1 -1
  338. package/dist/theme/syntax/tokens.d.ts +1 -1
  339. package/dist/theme/syntax/tokens.js +1 -1
  340. package/dist/theme/types.d.ts +1 -1
  341. package/dist/utils/dateTypes.d.ts +12 -0
  342. package/dist/utils/dateTypes.d.ts.map +1 -1
  343. package/dist/utils/dateTypes.js +41 -1
  344. package/dist/utils/index.d.ts +4 -0
  345. package/dist/utils/index.d.ts.map +1 -1
  346. package/dist/utils/index.js +3 -1
  347. package/dist/utils/inputAria.d.ts +29 -0
  348. package/dist/utils/inputAria.d.ts.map +1 -0
  349. package/dist/utils/inputAria.js +30 -0
  350. package/dist/utils/timeParser.d.ts.map +1 -1
  351. package/dist/utils/timeParser.js +5 -2
  352. package/package.json +15 -5
  353. package/src/Avatar/Avatar.test.tsx +37 -0
  354. package/src/Avatar/Avatar.tsx +10 -5
  355. package/src/AvatarGroup/AvatarGroupOverflow.tsx +3 -0
  356. package/src/Banner/Banner.doc.mjs +8 -0
  357. package/src/Banner/Banner.test.tsx +16 -7
  358. package/src/Banner/Banner.tsx +9 -2
  359. package/src/Breadcrumbs/BreadcrumbItem.tsx +25 -7
  360. package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -10
  361. package/src/Button/Button.doc.mjs +6 -0
  362. package/src/Button/Button.test.tsx +105 -11
  363. package/src/Button/Button.tsx +76 -21
  364. package/src/Calendar/Calendar.doc.mjs +4 -4
  365. package/src/Calendar/Calendar.test.tsx +168 -30
  366. package/src/Calendar/Calendar.tsx +121 -66
  367. package/src/Calendar/hooks/index.ts +0 -6
  368. package/src/Calendar/index.ts +1 -3
  369. package/src/Calendar/styles.ts +4 -9
  370. package/src/Carousel/Carousel.doc.mjs +7 -1
  371. package/src/Carousel/Carousel.test.tsx +20 -0
  372. package/src/Carousel/Carousel.tsx +16 -1
  373. package/src/Center/Center.doc.mjs +12 -2
  374. package/src/Center/Center.tsx +28 -3
  375. package/src/Chat/ChatComposer.doc.mjs +3 -0
  376. package/src/Chat/ChatComposerDrawer.doc.mjs +12 -0
  377. package/src/Chat/ChatMessageList.doc.mjs +8 -0
  378. package/src/Chat/ChatMessageList.test.tsx +18 -0
  379. package/src/Chat/ChatMessageList.tsx +16 -0
  380. package/src/Chat/useTriggerMenu.tsx +3 -0
  381. package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -0
  382. package/src/CheckboxInput/CheckboxInput.test.tsx +172 -27
  383. package/src/CheckboxInput/CheckboxInput.tsx +78 -6
  384. package/src/CheckboxList/CheckboxList.doc.mjs +9 -0
  385. package/src/CheckboxList/CheckboxList.test.tsx +169 -16
  386. package/src/CheckboxList/CheckboxList.tsx +56 -3
  387. package/src/CheckboxList/CheckboxListContext.tsx +7 -0
  388. package/src/Citation/Citation.doc.mjs +10 -0
  389. package/src/Citation/Citation.test.tsx +117 -0
  390. package/src/Citation/Citation.tsx +9 -1
  391. package/src/ClickableCard/ClickableCard.doc.mjs +15 -0
  392. package/src/CodeBlock/CodeBlock.test.tsx +115 -0
  393. package/src/CodeBlock/CodeBlock.tsx +61 -33
  394. package/src/CommandPalette/CommandPalette.test.tsx +47 -1
  395. package/src/CommandPalette/CommandPalette.tsx +9 -21
  396. package/src/ContextMenu/ContextMenu.doc.mjs +4 -4
  397. package/src/ContextMenu/ContextMenu.test.tsx +155 -1
  398. package/src/ContextMenu/ContextMenu.tsx +113 -16
  399. package/src/DateInput/DateInput.doc.mjs +281 -56
  400. package/src/DateInput/DateInput.test.tsx +188 -2
  401. package/src/DateInput/DateInput.tsx +89 -10
  402. package/src/DateRangeInput/DateRangeInput.doc.mjs +251 -46
  403. package/src/DateRangeInput/DateRangeInput.test.tsx +182 -20
  404. package/src/DateRangeInput/DateRangeInput.tsx +63 -5
  405. package/src/DateTimeInput/DateTimeInput.doc.mjs +368 -67
  406. package/src/DateTimeInput/DateTimeInput.test.tsx +279 -11
  407. package/src/DateTimeInput/DateTimeInput.tsx +125 -17
  408. package/src/Dialog/Dialog.doc.mjs +2 -2
  409. package/src/Dialog/Dialog.tsx +12 -0
  410. package/src/DropdownMenu/DropdownMenu.doc.mjs +1 -8
  411. package/src/DropdownMenu/DropdownMenu.test.tsx +56 -42
  412. package/src/DropdownMenu/DropdownMenu.tsx +52 -18
  413. package/src/EmptyState/EmptyState.test.tsx +4 -2
  414. package/src/EmptyState/EmptyState.tsx +6 -2
  415. package/src/Field/Field.test.tsx +32 -0
  416. package/src/Field/Field.tsx +23 -5
  417. package/src/Field/FieldLabel.tsx +55 -17
  418. package/src/FileInput/FileInput.doc.mjs +17 -0
  419. package/src/FileInput/FileInput.test.tsx +283 -49
  420. package/src/FileInput/FileInput.tsx +76 -4
  421. package/src/Grid/Grid.doc.mjs +14 -4
  422. package/src/Grid/Grid.tsx +20 -0
  423. package/src/HoverCard/HoverCard.doc.mjs +3 -0
  424. package/src/HoverCard/HoverCard.test.tsx +189 -2
  425. package/src/HoverCard/HoverCard.tsx +20 -16
  426. package/src/HoverCard/useHoverCard.tsx +13 -10
  427. package/src/Icon/Icon.doc.mjs +8 -0
  428. package/src/InputGroup/InputGroup.doc.mjs +2 -2
  429. package/src/InputGroup/InputGroup.test.tsx +98 -60
  430. package/src/InputGroup/InputGroup.tsx +21 -4
  431. package/src/InputGroup/InputGroupContext.ts +9 -4
  432. package/src/InputGroup/index.ts +1 -0
  433. package/src/Kbd/Kbd.test.tsx +22 -4
  434. package/src/Kbd/Kbd.tsx +37 -12
  435. package/src/Layer/anchorName.test.ts +146 -0
  436. package/src/Layer/anchorName.ts +46 -0
  437. package/src/Layer/layerAnimations.stylex.ts +20 -4
  438. package/src/Layer/useLayer.doc.mjs +12 -2
  439. package/src/Layer/useLayer.tsx +100 -15
  440. package/src/Layout/Layout.doc.mjs +1 -1
  441. package/src/Layout/Layout.tsx +8 -16
  442. package/src/Layout/LayoutFooter.doc.mjs +4 -4
  443. package/src/Layout/LayoutFooter.tsx +3 -3
  444. package/src/Layout/LayoutHeader.doc.mjs +4 -4
  445. package/src/Layout/LayoutHeader.tsx +3 -3
  446. package/src/Layout/LayoutPanel.tsx +3 -3
  447. package/src/Layout/padding.stylex.ts +52 -0
  448. package/src/Lightbox/Lightbox.doc.mjs +9 -2
  449. package/src/Lightbox/Lightbox.test.tsx +53 -5
  450. package/src/Lightbox/Lightbox.tsx +9 -4
  451. package/src/Link/Link.doc.mjs +14 -0
  452. package/src/Link/Link.test.tsx +52 -2
  453. package/src/Link/Link.tsx +42 -7
  454. package/src/Link/LinkProvider.tsx +1 -0
  455. package/src/List/List.doc.mjs +7 -0
  456. package/src/Markdown/Markdown.doc.mjs +2 -0
  457. package/src/Markdown/Markdown.test.tsx +28 -26
  458. package/src/Markdown/Markdown.tsx +21 -6
  459. package/src/MetadataList/MetadataListItem.doc.mjs +4 -0
  460. package/src/MobileNav/MobileNav.doc.mjs +8 -8
  461. package/src/MobileNav/MobileNav.tsx +13 -0
  462. package/src/MobileNav/MobileNavReopen.test.tsx +118 -0
  463. package/src/MoreMenu/MoreMenu.doc.mjs +2 -17
  464. package/src/MoreMenu/MoreMenu.tsx +0 -9
  465. package/src/MultiSelector/MultiSelector.doc.mjs +25 -0
  466. package/src/MultiSelector/MultiSelector.test.tsx +375 -8
  467. package/src/MultiSelector/MultiSelector.tsx +145 -21
  468. package/src/MultiSelector/hooks.ts +27 -0
  469. package/src/NavMenu/NavHeadingMenu.test.tsx +77 -1
  470. package/src/NavMenu/NavHeadingMenu.tsx +50 -3
  471. package/src/NumberInput/NumberInput.doc.mjs +17 -0
  472. package/src/NumberInput/NumberInput.test.tsx +242 -40
  473. package/src/NumberInput/NumberInput.tsx +89 -11
  474. package/src/OverflowList/OverflowList.doc.mjs +17 -0
  475. package/src/Pagination/Pagination.doc.mjs +3 -3
  476. package/src/Pagination/Pagination.test.tsx +250 -14
  477. package/src/Pagination/Pagination.tsx +54 -29
  478. package/src/Popover/usePopover.doc.mjs +7 -3
  479. package/src/Popover/usePopover.tsx +49 -6
  480. package/src/PowerSearch/PowerSearch.doc.mjs +15 -0
  481. package/src/PowerSearch/PowerSearch.test.tsx +97 -1
  482. package/src/PowerSearch/PowerSearch.tsx +16 -3
  483. package/src/ProgressBar/ProgressBar.test.tsx +45 -27
  484. package/src/ProgressBar/ProgressBar.tsx +3 -4
  485. package/src/RadioList/RadioList.doc.mjs +9 -0
  486. package/src/RadioList/RadioList.test.tsx +252 -16
  487. package/src/RadioList/RadioList.tsx +166 -10
  488. package/src/RadioList/RadioListItem.tsx +14 -2
  489. package/src/Resizable/Resizable.doc.mjs +1 -1
  490. package/src/Section/Section.doc.mjs +11 -0
  491. package/src/SegmentedControl/SegmentedControl.doc.mjs +9 -0
  492. package/src/SegmentedControl/SegmentedControl.test.tsx +214 -42
  493. package/src/SegmentedControl/SegmentedControl.tsx +102 -54
  494. package/src/SegmentedControl/SegmentedControlContext.ts +7 -0
  495. package/src/SegmentedControl/SegmentedControlItem.tsx +14 -1
  496. package/src/SelectableCard/SelectableCard.doc.mjs +15 -0
  497. package/src/Selector/Selector.doc.mjs +25 -0
  498. package/src/Selector/Selector.test.tsx +322 -15
  499. package/src/Selector/Selector.tsx +126 -40
  500. package/src/Selector/hooks.ts +23 -0
  501. package/src/SideNav/SideNav.test.tsx +16 -0
  502. package/src/SideNav/SideNavItem.tsx +2 -4
  503. package/src/Skeleton/Skeleton.doc.mjs +11 -1
  504. package/src/Skeleton/Skeleton.test.tsx +25 -0
  505. package/src/Skeleton/Skeleton.tsx +11 -1
  506. package/src/Slider/Slider.doc.mjs +19 -0
  507. package/src/Slider/Slider.test.tsx +158 -18
  508. package/src/Slider/Slider.tsx +54 -6
  509. package/src/Spinner/Spinner.tsx +7 -1
  510. package/src/Stack/Stack.doc.mjs +77 -0
  511. package/src/Stack/Stack.test.tsx +55 -5
  512. package/src/Stack/Stack.tsx +73 -24
  513. package/src/Stack/StackItem.test.tsx +23 -0
  514. package/src/Stack/StackItem.tsx +20 -23
  515. package/src/Switch/Switch.doc.mjs +15 -0
  516. package/src/Switch/Switch.test.tsx +162 -27
  517. package/src/Switch/Switch.tsx +61 -21
  518. package/src/TabList/Tab.tsx +6 -0
  519. package/src/TabList/TabList.doc.mjs +12 -0
  520. package/src/TabList/TabList.test.tsx +208 -0
  521. package/src/TabList/TabList.tsx +102 -12
  522. package/src/TabList/TabListContext.ts +7 -3
  523. package/src/TabList/TabMenu.tsx +6 -3
  524. package/src/Table/BaseTable.tsx +72 -41
  525. package/src/Table/Table.doc.mjs +14 -0
  526. package/src/Table/Table.test.tsx +39 -30
  527. package/src/Table/Table.tsx +27 -1
  528. package/src/Table/TableCell.tsx +25 -23
  529. package/src/Table/TableHeaderCell.tsx +28 -29
  530. package/src/Table/TableRow.tsx +37 -7
  531. package/src/Table/index.ts +6 -2
  532. package/src/Table/plugins/pagination/paginateData.ts +10 -3
  533. package/src/Table/plugins/pagination/useTablePagination.test.tsx +16 -0
  534. package/src/Table/plugins/pagination/useTablePagination.tsx +8 -1
  535. package/src/Table/plugins/sortable/useTableSortable.test.tsx +91 -2
  536. package/src/Table/plugins/sortable/useTableSortable.tsx +53 -1
  537. package/src/Table/plugins/stickyColumns/index.ts +4 -0
  538. package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +163 -0
  539. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +407 -0
  540. package/src/Table/tableContextMenu.test.tsx +157 -0
  541. package/src/Table/tableContextMenu.tsx +142 -0
  542. package/src/Table/types.ts +175 -4
  543. package/src/Table/useBaseTablePlugins.ts +1 -0
  544. package/src/Table/useTableColumnResize.doc.mjs +96 -0
  545. package/src/Table/useTableStickyColumns.doc.mjs +59 -0
  546. package/src/Text/Heading.doc.mjs +15 -2
  547. package/src/Text/Text.doc.mjs +7 -1
  548. package/src/Text/text.stylex.ts +2 -2
  549. package/src/TextArea/TextArea.doc.mjs +17 -0
  550. package/src/TextArea/TextArea.test.tsx +167 -35
  551. package/src/TextArea/TextArea.tsx +62 -15
  552. package/src/TextInput/TextInput.doc.mjs +17 -0
  553. package/src/TextInput/TextInput.test.tsx +168 -34
  554. package/src/TextInput/TextInput.tsx +77 -9
  555. package/src/TimeInput/TimeInput.doc.mjs +335 -60
  556. package/src/TimeInput/TimeInput.test.tsx +144 -7
  557. package/src/TimeInput/TimeInput.tsx +74 -5
  558. package/src/Timestamp/Timestamp.doc.mjs +9 -0
  559. package/src/Timestamp/Timestamp.test.tsx +44 -18
  560. package/src/Timestamp/Timestamp.tsx +30 -10
  561. package/src/Toast/Toast.tsx +14 -0
  562. package/src/Toast/ToastViewport.test.tsx +204 -0
  563. package/src/Toast/ToastViewport.tsx +167 -21
  564. package/src/ToggleButton/ToggleButton.doc.mjs +9 -3
  565. package/src/ToggleButton/ToggleButton.test.tsx +39 -18
  566. package/src/ToggleButton/ToggleButton.tsx +46 -83
  567. package/src/Tokenizer/Tokenizer.doc.mjs +15 -0
  568. package/src/Tokenizer/Tokenizer.test.tsx +105 -1
  569. package/src/Tokenizer/Tokenizer.tsx +41 -2
  570. package/src/Toolbar/Toolbar.doc.mjs +65 -5
  571. package/src/Toolbar/Toolbar.test.tsx +109 -6
  572. package/src/Toolbar/Toolbar.tsx +59 -5
  573. package/src/Tooltip/Tooltip.test.tsx +81 -0
  574. package/src/Tooltip/useTooltip.tsx +57 -11
  575. package/src/TreeList/TreeList.test.tsx +295 -6
  576. package/src/TreeList/TreeList.tsx +73 -1
  577. package/src/TreeList/TreeListItem.tsx +51 -5
  578. package/src/TreeList/treeListItem.markers.stylex.ts +20 -0
  579. package/src/Typeahead/BaseTypeahead.tsx +86 -9
  580. package/src/Typeahead/Typeahead.doc.mjs +136 -30
  581. package/src/Typeahead/Typeahead.test.tsx +331 -1
  582. package/src/Typeahead/Typeahead.tsx +52 -1
  583. package/src/VisuallyHidden/VisuallyHidden.doc.mjs +80 -0
  584. package/src/VisuallyHidden/VisuallyHidden.test.tsx +76 -0
  585. package/src/VisuallyHidden/VisuallyHidden.tsx +113 -0
  586. package/src/VisuallyHidden/index.ts +15 -0
  587. package/src/hooks/focusableSelector.ts +25 -0
  588. package/src/hooks/index.ts +28 -2
  589. package/src/hooks/useAnnounce.test.tsx +101 -0
  590. package/src/hooks/useAnnounce.ts +168 -0
  591. package/src/hooks/useClickableContainer.ts +16 -4
  592. package/src/hooks/useEntryAnimation.ts +16 -4
  593. package/src/hooks/useFocusTrap.test.tsx +132 -0
  594. package/src/hooks/useFocusTrap.ts +98 -4
  595. package/src/hooks/useGridFocus.doc.mjs +40 -2
  596. package/src/hooks/useGridFocus.test.tsx +132 -0
  597. package/src/hooks/useGridFocus.ts +343 -67
  598. package/src/hooks/useImageMode.test.ts +133 -0
  599. package/src/hooks/useKeyboardHint.doc.mjs +101 -0
  600. package/src/hooks/useKeyboardHint.test.tsx +70 -0
  601. package/src/hooks/useKeyboardHint.tsx +332 -0
  602. package/src/hooks/useListFocus.doc.mjs +50 -10
  603. package/src/hooks/useListFocus.test.tsx +375 -0
  604. package/src/hooks/useListFocus.ts +395 -57
  605. package/src/hooks/useLongPress.test.tsx +134 -0
  606. package/src/hooks/useLongPress.ts +119 -0
  607. package/src/hooks/useTreeFocus.doc.mjs +140 -0
  608. package/src/hooks/useTreeFocus.test.tsx +214 -0
  609. package/src/hooks/useTreeFocus.ts +559 -0
  610. package/src/hooks/useTypeahead.test.tsx +109 -0
  611. package/src/hooks/useTypeahead.ts +183 -0
  612. package/src/index.ts +1 -0
  613. package/src/theme/derivedVarRegistry.test.ts +4 -0
  614. package/src/theme/generateThemeRules.test.ts +7 -8
  615. package/src/theme/generateThemeRules.ts +1 -1
  616. package/src/theme/syntax/SyntaxTheme.tsx +1 -1
  617. package/src/theme/syntax/defineSyntaxTheme.ts +20 -11
  618. package/src/theme/syntax/presets.ts +5 -2
  619. package/src/theme/syntax/tokens.ts +1 -1
  620. package/src/theme/types.ts +1 -1
  621. package/src/utils/dateTypes.test.ts +40 -0
  622. package/src/utils/dateTypes.ts +40 -0
  623. package/src/utils/index.ts +9 -0
  624. package/src/utils/inputAria.test.ts +39 -0
  625. package/src/utils/inputAria.ts +58 -0
  626. package/src/utils/timeParser.test.ts +10 -0
  627. package/src/utils/timeParser.ts +5 -2
  628. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts +0 -57
  629. package/dist/Calendar/hooks/useCalendarRovingTabindex.d.ts.map +0 -1
  630. package/dist/Calendar/hooks/useCalendarRovingTabindex.js +0 -96
  631. package/src/Calendar/hooks/useCalendarRovingTabindex.ts +0 -118
@@ -0,0 +1,117 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file Citation.test.tsx
5
+ * @input Uses React Testing Library, Citation, theme tokens
6
+ * @output Tests for Citation component
7
+ */
8
+
9
+ import {render, screen} from '@testing-library/react';
10
+ import {describe, it, expect} from 'vitest';
11
+ import * as stylex from '@stylexjs/stylex';
12
+ import {colorVars} from '../theme/tokens.stylex';
13
+ import {Citation} from './Citation';
14
+
15
+ // StyleX emits one deterministic atomic class per property/value pair, so an
16
+ // element carries a probe's class exactly when it has the same declaration.
17
+ // The dev-mode debug class (contains "__") varies by source location and is
18
+ // excluded from the comparison.
19
+ const probe = stylex.create({
20
+ secondaryText: {color: colorVars['--color-text-secondary']},
21
+ accentText: {color: colorVars['--color-text-accent']},
22
+ badgeBackground: {backgroundColor: colorVars['--color-accent-muted']},
23
+ });
24
+
25
+ function atomicClasses(style: (typeof probe)[keyof typeof probe]): string[] {
26
+ const {className = ''} = stylex.props(style);
27
+ return className.split(' ').filter(c => c !== '' && !c.includes('__'));
28
+ }
29
+
30
+ describe('Citation', () => {
31
+ const source = {title: 'Example Source', url: 'https://example.com'};
32
+
33
+ it('renders the source title as a link in the label variant', () => {
34
+ render(<Citation source={source} number={1} data-testid="citation" />);
35
+ const el = screen.getByTestId('citation');
36
+ expect(el.tagName).toBe('A');
37
+ expect(el).toHaveAttribute('href', 'https://example.com');
38
+ expect(el).toHaveTextContent('Example Source');
39
+ });
40
+
41
+ it('renders the index as a badge in the number variant', () => {
42
+ render(
43
+ <Citation
44
+ source={source}
45
+ number={3}
46
+ variant="number"
47
+ data-testid="citation"
48
+ />,
49
+ );
50
+ const el = screen.getByTestId('citation');
51
+ expect(el).toHaveTextContent('3');
52
+ expect(el).toHaveAttribute('role', 'doc-noteref');
53
+ expect(el).toHaveAttribute('aria-label', 'Citation 3: Example Source');
54
+ });
55
+
56
+ it('renders as a span when the source has no url', () => {
57
+ render(
58
+ <Citation
59
+ source={{title: 'No link'}}
60
+ number={1}
61
+ data-testid="citation"
62
+ />,
63
+ );
64
+ expect(screen.getByTestId('citation').tagName).toBe('SPAN');
65
+ });
66
+
67
+ it('renders astryx-* class names for theme targeting', () => {
68
+ render(<Citation source={source} number={1} data-testid="citation" />);
69
+ expect(screen.getByTestId('citation').className).toContain(
70
+ 'astryx-citation',
71
+ );
72
+ });
73
+
74
+ it('uses the secondary text color in the label variant', () => {
75
+ render(<Citation source={source} number={1} data-testid="citation" />);
76
+ const el = screen.getByTestId('citation');
77
+ for (const cls of atomicClasses(probe.secondaryText)) {
78
+ expect(el.classList.contains(cls)).toBe(true);
79
+ }
80
+ });
81
+
82
+ it('uses the secondary text color, not accent, in the number variant', () => {
83
+ render(
84
+ <Citation
85
+ source={source}
86
+ number={1}
87
+ variant="number"
88
+ data-testid="citation"
89
+ />,
90
+ );
91
+ const el = screen.getByTestId('citation');
92
+ for (const cls of atomicClasses(probe.secondaryText)) {
93
+ expect(el.classList.contains(cls)).toBe(true);
94
+ }
95
+ for (const cls of atomicClasses(probe.accentText)) {
96
+ expect(el.classList.contains(cls)).toBe(false);
97
+ }
98
+ });
99
+
100
+ it('keeps the accent-muted badge background when the source has a url', () => {
101
+ // `numberHover` must not clobber the base background: a hover-only
102
+ // conditional without a default replaces the whole property on merge,
103
+ // leaving linked badges with a transparent pill.
104
+ render(
105
+ <Citation
106
+ source={source}
107
+ number={1}
108
+ variant="number"
109
+ data-testid="citation"
110
+ />,
111
+ );
112
+ const el = screen.getByTestId('citation');
113
+ for (const cls of atomicClasses(probe.badgeBackground)) {
114
+ expect(el.classList.contains(cls)).toBe(true);
115
+ }
116
+ });
117
+ });
@@ -83,6 +83,10 @@ const styles = stylex.create({
83
83
  },
84
84
  },
85
85
  color: {
86
+ // Explicit default: without it, this hover-only conditional replaces
87
+ // the base secondary color from `label` (last-wins property merge),
88
+ // leaving linked citations to inherit the surrounding text color.
89
+ default: colorVars['--color-text-secondary'],
86
90
  ':hover': {
87
91
  '@media (hover: hover)': colorVars['--color-text-primary'],
88
92
  },
@@ -96,7 +100,7 @@ const styles = stylex.create({
96
100
  fontSize: typeScaleVars['--text-supporting-size'],
97
101
  fontWeight: fontWeightVars['--font-weight-semibold'],
98
102
  lineHeight: typeScaleVars['--text-supporting-leading'],
99
- color: colorVars['--color-text-accent'],
103
+ color: colorVars['--color-text-secondary'],
100
104
  backgroundColor: colorVars['--color-accent-muted'],
101
105
  borderRadius: radiusVars['--radius-full'],
102
106
  minWidth: spacingVars['--spacing-5'],
@@ -110,6 +114,10 @@ const styles = stylex.create({
110
114
  },
111
115
  numberHover: {
112
116
  backgroundColor: {
117
+ // Explicit default for the same reason as labelHover's color: a
118
+ // hover-only conditional replaces the base accent-muted pill from
119
+ // `number` on merge, leaving linked badges transparent.
120
+ default: colorVars['--color-accent-muted'],
113
121
  ':hover': {
114
122
  '@media (hover: hover)': colorVars['--color-overlay-hover'],
115
123
  },
@@ -37,6 +37,21 @@ export const docs = {
37
37
  container: true,
38
38
  targets: [{className: 'astryx-clickable-card', visualProps: ['variant']}],
39
39
  },
40
+ playground: {
41
+ defaults: {
42
+ label: 'View product details',
43
+ href: '#',
44
+ padding: 4,
45
+ children: {
46
+ __element: 'XDSVStack',
47
+ props: {gap: 1},
48
+ children: [
49
+ {__element: 'XDSHeading', props: {level: 3}, children: 'Wireless Headphones'},
50
+ {__element: 'XDSText', props: {type: 'body'}, children: 'Noise-cancelling over-ear headphones with 30-hour battery life.'},
51
+ ],
52
+ },
53
+ },
54
+ },
40
55
  };
41
56
 
42
57
  /** @type {import('../docs-types').TranslationDoc} */
@@ -0,0 +1,115 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file CodeBlock.test.tsx
5
+ * @input Uses vitest, @testing-library/react, CodeBlock component
6
+ * @output Unit tests for CodeBlock (copy button, collapse, scroll region a11y)
7
+ * @position Testing; validates CodeBlock implementation
8
+ *
9
+ * SYNC: When CodeBlock.tsx changes, update tests to match new behavior
10
+ */
11
+
12
+ import {describe, it, expect, vi, beforeEach} from 'vitest';
13
+ import {render, screen, fireEvent} from '@testing-library/react';
14
+ import {CodeBlock} from './CodeBlock';
15
+
16
+ // A code sample long enough to exceed the default collapsible threshold (10).
17
+ const LONG_CODE = Array.from(
18
+ {length: 15},
19
+ (_, i) => `const line${i} = ${i};`,
20
+ ).join('\n');
21
+
22
+ describe('CodeBlock', () => {
23
+ beforeEach(() => {
24
+ // jsdom does not implement the async Clipboard API.
25
+ Object.assign(navigator, {
26
+ clipboard: {writeText: vi.fn().mockResolvedValue(undefined)},
27
+ });
28
+ });
29
+
30
+ it('renders the code', () => {
31
+ render(<CodeBlock code="const x = 1;" language="javascript" />);
32
+ expect(screen.getByText(/const/)).toBeInTheDocument();
33
+ });
34
+
35
+ it('makes the scroll container keyboard-focusable', () => {
36
+ render(<CodeBlock code="const x = 1;" language="javascript" />);
37
+ const region = screen.getByRole('region');
38
+ expect(region).toHaveAttribute('tabindex', '0');
39
+ expect(region).toHaveAttribute('aria-label', 'javascript');
40
+ });
41
+
42
+ it('labels the scroll region "Code" when no language label is shown', () => {
43
+ render(<CodeBlock code="hello" hasLanguageLabel={false} />);
44
+ const region = screen.getByRole('region');
45
+ expect(region).toHaveAttribute('tabindex', '0');
46
+ expect(region).toHaveAttribute('aria-label', 'Code');
47
+ });
48
+
49
+ it('copies code when the copy button is clicked', () => {
50
+ render(<CodeBlock code="const x = 1;" language="javascript" />);
51
+ const copyButton = screen.getByRole('button', {name: 'Copy code'});
52
+ fireEvent.click(copyButton);
53
+ expect(navigator.clipboard.writeText).toHaveBeenCalledWith('const x = 1;');
54
+ });
55
+
56
+ it('does NOT collapse the block when the copy button is clicked', () => {
57
+ render(
58
+ <CodeBlock
59
+ code={LONG_CODE}
60
+ language="javascript"
61
+ title="example"
62
+ isCollapsible
63
+ />,
64
+ );
65
+ // The collapsible header exposes aria-expanded.
66
+ const header = screen
67
+ .getAllByRole('button')
68
+ .find(el => el.hasAttribute('aria-expanded'));
69
+ expect(header).toBeTruthy();
70
+ expect(header).toHaveAttribute('aria-expanded', 'true');
71
+
72
+ const copyButton = screen.getByRole('button', {name: 'Copy code'});
73
+ fireEvent.click(copyButton);
74
+
75
+ // Clicking Copy must not toggle the collapsible header.
76
+ expect(header).toHaveAttribute('aria-expanded', 'true');
77
+ expect(navigator.clipboard.writeText).toHaveBeenCalled();
78
+ });
79
+
80
+ it('does not nest the copy button inside the collapsible header role="button"', () => {
81
+ render(
82
+ <CodeBlock
83
+ code={LONG_CODE}
84
+ language="javascript"
85
+ title="example"
86
+ isCollapsible
87
+ />,
88
+ );
89
+ const header = screen
90
+ .getAllByRole('button')
91
+ .find(el => el.hasAttribute('aria-expanded'));
92
+ const copyButton = screen.getByRole('button', {name: 'Copy code'});
93
+ expect(header).toBeTruthy();
94
+ // The copy button must be a sibling, not a descendant of the interactive
95
+ // header — nested interactive controls are invalid ARIA.
96
+ expect(header!.contains(copyButton)).toBe(false);
97
+ });
98
+
99
+ it('still toggles collapse when the header itself is clicked', () => {
100
+ render(
101
+ <CodeBlock
102
+ code={LONG_CODE}
103
+ language="javascript"
104
+ title="example"
105
+ isCollapsible
106
+ />,
107
+ );
108
+ const header = screen
109
+ .getAllByRole('button')
110
+ .find(el => el.hasAttribute('aria-expanded'))!;
111
+ expect(header).toHaveAttribute('aria-expanded', 'true');
112
+ fireEvent.click(header);
113
+ expect(header).toHaveAttribute('aria-expanded', 'false');
114
+ });
115
+ });
@@ -87,7 +87,7 @@ const styles = stylex.create({
87
87
  backgroundColor: 'var(--color-syntax-background)',
88
88
  overflow: 'hidden',
89
89
  },
90
- header: {
90
+ headerRow: {
91
91
  display: 'flex',
92
92
  alignItems: 'center',
93
93
  justifyContent: 'space-between',
@@ -97,6 +97,19 @@ const styles = stylex.create({
97
97
  top: 0,
98
98
  zIndex: 1,
99
99
  },
100
+ header: {
101
+ display: 'flex',
102
+ alignItems: 'center',
103
+ flex: 1,
104
+ minWidth: 0,
105
+ // Reset default <button> appearance for the collapsible title control.
106
+ padding: 0,
107
+ border: 'none',
108
+ backgroundColor: 'transparent',
109
+ color: 'inherit',
110
+ font: 'inherit',
111
+ textAlign: 'start',
112
+ },
100
113
  headerWithDivider: {
101
114
  paddingBlock: spacingVars['--spacing-2'],
102
115
  borderBottomWidth: borderVars['--border-width'],
@@ -469,7 +482,10 @@ function useTokenLines(
469
482
  // Span-mode code element
470
483
  // ---------------------------------------------------------------------------
471
484
 
472
- function buildSpanLine(lineText: string, tokens: SyntaxToken[]): React.ReactNode {
485
+ function buildSpanLine(
486
+ lineText: string,
487
+ tokens: SyntaxToken[],
488
+ ): React.ReactNode {
473
489
  if (tokens.length === 0) {
474
490
  return lineText || '\u200b';
475
491
  }
@@ -677,7 +693,9 @@ export function CodeBlock({
677
693
  const copyButtonEl = hasCopyButton ? (
678
694
  <button
679
695
  type="button"
680
- onClick={() => {
696
+ onClick={e => {
697
+ // Stop propagation so copying does not toggle the collapsible header.
698
+ e.stopPropagation();
681
699
  void handleCopy();
682
700
  }}
683
701
  aria-label={copied ? 'Copied' : 'Copy code'}
@@ -691,39 +709,44 @@ export function CodeBlock({
691
709
 
692
710
  const headerEl = showHeader ? (
693
711
  <div
694
- role={canCollapse ? 'button' : undefined}
695
- tabIndex={canCollapse ? 0 : undefined}
696
- aria-expanded={canCollapse ? !isCollapsed : undefined}
697
- onClick={canCollapse ? () => setIsCollapsed(prev => !prev) : undefined}
698
- onKeyDown={
699
- canCollapse
700
- ? (e: React.KeyboardEvent) => {
701
- if (e.key === 'Enter' || e.key === ' ') {
702
- e.preventDefault();
703
- setIsCollapsed(prev => !prev);
704
- }
705
- }
706
- : undefined
707
- }
708
712
  {...stylex.props(
709
- styles.header,
713
+ styles.headerRow,
710
714
  hasLineNumbers ? styles.headerWithDivider : styles.headerCompact,
711
- canCollapse && styles.headerCollapsible,
712
715
  )}>
713
- <span {...stylex.props(styles.headerTitle)}>
714
- {title}
715
- {title && languageLabel ? ' — ' : ''}
716
- {languageLabel}
717
- {canCollapse && (
718
- <span
719
- {...stylex.props(
720
- styles.collapseChevron,
721
- isCollapsed && styles.collapseChevronCollapsed,
722
- )}>
723
- <Icon icon="chevronDown" size="xsm" color="inherit" />
724
- </span>
725
- )}
726
- </span>
716
+ <div
717
+ role={canCollapse ? 'button' : undefined}
718
+ tabIndex={canCollapse ? 0 : undefined}
719
+ aria-expanded={canCollapse ? !isCollapsed : undefined}
720
+ onClick={canCollapse ? () => setIsCollapsed(prev => !prev) : undefined}
721
+ onKeyDown={
722
+ canCollapse
723
+ ? (e: React.KeyboardEvent) => {
724
+ if (e.key === 'Enter' || e.key === ' ') {
725
+ e.preventDefault();
726
+ setIsCollapsed(prev => !prev);
727
+ }
728
+ }
729
+ : undefined
730
+ }
731
+ {...stylex.props(
732
+ styles.header,
733
+ canCollapse && styles.headerCollapsible,
734
+ )}>
735
+ <span {...stylex.props(styles.headerTitle)}>
736
+ {title}
737
+ {title && languageLabel ? ' — ' : ''}
738
+ {languageLabel}
739
+ {canCollapse && (
740
+ <span
741
+ {...stylex.props(
742
+ styles.collapseChevron,
743
+ isCollapsed && styles.collapseChevronCollapsed,
744
+ )}>
745
+ <Icon icon="chevronDown" size="xsm" color="inherit" />
746
+ </span>
747
+ )}
748
+ </span>
749
+ </div>
727
750
  {copyButtonEl}
728
751
  </div>
729
752
  ) : null;
@@ -731,6 +754,11 @@ export function CodeBlock({
731
754
  const codeBody = (
732
755
  <div
733
756
  ref={scrollContainerRef}
757
+ // The scroll container is keyboard-focusable so keyboard users can
758
+ // scroll long or wide code that overflows the viewport.
759
+ tabIndex={0}
760
+ role="region"
761
+ aria-label={languageLabel ?? 'Code'}
734
762
  {...mergeProps(stylex.props(styles.scrollContainer), {
735
763
  style: scrollStyle,
736
764
  })}>
@@ -8,9 +8,10 @@
8
8
  */
9
9
 
10
10
  import {describe, it, expect, vi, beforeEach} from 'vitest';
11
- import {render, screen, waitFor} from '@testing-library/react';
11
+ import {render, screen, waitFor, fireEvent} from '@testing-library/react';
12
12
  import {CommandPalette} from './CommandPalette';
13
13
  import {createStaticSource} from '@astryxdesign/core/Typeahead';
14
+ import type {SearchSource, SearchableItem} from '@astryxdesign/core/Typeahead';
14
15
 
15
16
  const simpleSource = createStaticSource([
16
17
  {id: 'home', label: 'Home'},
@@ -223,4 +224,49 @@ describe('CommandPalette', () => {
223
224
  dialog.dispatchEvent(escapeEvent);
224
225
  expect(handleOpenChange).toHaveBeenCalledWith(false);
225
226
  });
227
+
228
+ it('keeps the empty state mounted while a no-result search is pending', async () => {
229
+ // A source whose searches resolve only when we release them, so we can
230
+ // observe the render output while a search transition is in flight.
231
+ const resolvers: ((items: SearchableItem[]) => void)[] = [];
232
+ const source: SearchSource = {
233
+ bootstrap: () => [],
234
+ async search(): Promise<SearchableItem[]> {
235
+ return new Promise<SearchableItem[]>(resolve => {
236
+ resolvers.push(resolve);
237
+ });
238
+ },
239
+ };
240
+
241
+ render(
242
+ <CommandPalette
243
+ isOpen={true}
244
+ onOpenChange={() => {}}
245
+ searchSource={source}
246
+ emptyBootstrapText="Type to search"
247
+ emptySearchText="No results"
248
+ />,
249
+ );
250
+
251
+ const input = screen.getByRole('combobox');
252
+
253
+ // First search: commits an empty result for query "z".
254
+ fireEvent.change(input, {target: {value: 'z'}});
255
+ await waitFor(() => expect(resolvers).toHaveLength(1));
256
+ resolvers[0]([]);
257
+ await waitFor(() =>
258
+ expect(screen.getByText('No results')).toBeInTheDocument(),
259
+ );
260
+
261
+ // Second keystroke while already empty: the empty state must remain in the
262
+ // DOM for the whole pending window — no unmount/remount flash.
263
+ fireEvent.change(input, {target: {value: 'zz'}});
264
+ expect(screen.getByText('No results')).toBeInTheDocument();
265
+ await waitFor(() => expect(resolvers).toHaveLength(2));
266
+ expect(screen.getByText('No results')).toBeInTheDocument();
267
+ resolvers[1]([]);
268
+ await waitFor(() =>
269
+ expect(screen.getByText('No results')).toBeInTheDocument(),
270
+ );
271
+ });
226
272
  });
@@ -24,12 +24,7 @@ import {
24
24
  type ReactNode,
25
25
  } from 'react';
26
26
  import {Dialog} from '../Dialog';
27
- import {
28
- Layout,
29
- LayoutHeader,
30
- LayoutContent,
31
- LayoutFooter,
32
- } from '../Layout';
27
+ import {Layout, LayoutHeader, LayoutContent, LayoutFooter} from '../Layout';
33
28
  import type {SearchSource, SearchableItem} from '../Typeahead';
34
29
  import {useCombobox} from '../Selector';
35
30
  import type {SelectorOptionData} from '../Selector';
@@ -133,9 +128,7 @@ function getGroup(item: SearchableItem): string | undefined {
133
128
  * When groups are present, items are ordered by group (preserving insertion order),
134
129
  * with ungrouped items at the end — matching the DefaultRenderer layout.
135
130
  */
136
- function buildSelectableItems(
137
- items: SearchableItem[],
138
- ): SelectorOptionData[] {
131
+ function buildSelectableItems(items: SearchableItem[]): SelectorOptionData[] {
139
132
  const hasGroups = items.some(item => getGroup(item) != null);
140
133
 
141
134
  if (!hasGroups) {
@@ -258,9 +251,7 @@ function ItemRenderer<T extends SearchableItem>({
258
251
  * />
259
252
  * ```
260
253
  */
261
- export function CommandPalette<
262
- T extends SearchableItem = SearchableItem,
263
- >({
254
+ export function CommandPalette<T extends SearchableItem = SearchableItem>({
264
255
  ref,
265
256
  isOpen,
266
257
  isInline,
@@ -488,13 +479,12 @@ export function CommandPalette<
488
479
  ],
489
480
  );
490
481
 
491
- // Empty state uses committed search (= what current results correspond to),
492
- // not optimisticSearch (= what the user typed).
493
- // While the transition is pending, search stays at '' so showEmptyBootstrap
494
- // remains true even after the user has started typing.
482
+ // `search` is the committed query the on-screen results correspond to (it
483
+ // still holds the previous query while a transition is pending). Keeping both
484
+ // flags ungated by `isPending` makes them exhaustive over the empty case, so
485
+ // the empty state is never unmounted and re-added mid-search (which flashed).
495
486
  const showEmptyBootstrap = search === '' && optimisticResults.length === 0;
496
- const showEmptySearch =
497
- !isPending && search !== '' && optimisticResults.length === 0;
487
+ const showEmptySearch = search !== '' && optimisticResults.length === 0;
498
488
 
499
489
  let listContent: ReactNode;
500
490
  if (showEmptyBootstrap) {
@@ -502,9 +492,7 @@ export function CommandPalette<
502
492
  <CommandPaletteEmpty>{emptyBootstrapText}</CommandPaletteEmpty>
503
493
  );
504
494
  } else if (showEmptySearch) {
505
- listContent = (
506
- <CommandPaletteEmpty>{emptySearchText}</CommandPaletteEmpty>
507
- );
495
+ listContent = <CommandPaletteEmpty>{emptySearchText}</CommandPaletteEmpty>;
508
496
  } else {
509
497
  listContent = (
510
498
  <ItemRenderer
@@ -53,10 +53,10 @@ export const docs = {
53
53
  default: "'md'",
54
54
  },
55
55
  {
56
- name: 'hasAutoFocus',
57
- type: 'boolean',
58
- description: 'Whether to auto-focus the first menu item when the menu opens. Set to false for inline showcases.',
59
- default: 'true',
56
+ name: 'label',
57
+ type: 'string',
58
+ description: 'Accessible name for the menu surface, announced when it opens.',
59
+ default: "'Context menu'",
60
60
  },
61
61
  {
62
62
  name: 'isDisabled',