@astryxdesign/core 0.4.7 → 0.5.0-canary.54bb922

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 (467) hide show
  1. package/CHANGELOG.md +161 -1
  2. package/dist/AppShell/AppShell.d.ts.map +1 -1
  3. package/dist/AppShell/AppShell.js +3 -2
  4. package/dist/AspectRatio/AspectRatio.d.ts +24 -0
  5. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  6. package/dist/AspectRatio/AspectRatio.js +23 -4
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +15 -10
  9. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  10. package/dist/AvatarGroup/AvatarGroup.js +3 -2
  11. package/dist/Banner/Banner.d.ts +40 -15
  12. package/dist/Banner/Banner.d.ts.map +1 -1
  13. package/dist/Banner/Banner.js +51 -18
  14. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  15. package/dist/BottomSheet/BottomSheet.js +17 -4
  16. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  17. package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
  18. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  19. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
  20. package/dist/Button/Button.d.ts.map +1 -1
  21. package/dist/Button/Button.js +5 -4
  22. package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
  23. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  24. package/dist/ButtonGroup/ButtonGroup.js +26 -7
  25. package/dist/Calendar/Calendar.d.ts +3 -1
  26. package/dist/Calendar/Calendar.d.ts.map +1 -1
  27. package/dist/Calendar/Calendar.js +13 -14
  28. package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
  29. package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
  30. package/dist/Calendar/getInitialFocusDate.js +62 -0
  31. package/dist/Carousel/Carousel.d.ts.map +1 -1
  32. package/dist/Carousel/Carousel.js +3 -3
  33. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  34. package/dist/Chat/ChatComposerInput.js +2 -3
  35. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  36. package/dist/Chat/ChatLayout.js +3 -3
  37. package/dist/Chat/ChatMessageList.d.ts +22 -3
  38. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  39. package/dist/Chat/ChatMessageList.js +6 -3
  40. package/dist/Chat/ChatTokenizedText.d.ts +2 -0
  41. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  42. package/dist/Chat/ChatTokenizedText.js +11 -6
  43. package/dist/Chat/useChatComposerTokens.js +1 -1
  44. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  45. package/dist/CheckboxInput/CheckboxInput.js +3 -2
  46. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  47. package/dist/ClickableCard/ClickableCard.js +3 -3
  48. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  49. package/dist/CommandPalette/CommandPaletteInput.js +3 -2
  50. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  51. package/dist/CommandPalette/CommandPaletteItem.js +3 -2
  52. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  53. package/dist/ContextMenu/ContextMenu.js +4 -3
  54. package/dist/DateInput/DateInput.d.ts.map +1 -1
  55. package/dist/DateInput/DateInput.js +3 -2
  56. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  57. package/dist/DateInput/TouchDateField.js +38 -4
  58. package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
  59. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  60. package/dist/DateTimeInput/DateTimeInput.js +406 -12
  61. package/dist/DateTimeInput/index.d.ts +1 -1
  62. package/dist/DateTimeInput/index.d.ts.map +1 -1
  63. package/dist/Dialog/Dialog.d.ts +7 -1
  64. package/dist/Dialog/Dialog.d.ts.map +1 -1
  65. package/dist/Dialog/Dialog.js +89 -58
  66. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  67. package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
  68. package/dist/FileInput/FileInput.d.ts.map +1 -1
  69. package/dist/FileInput/FileInput.js +3 -2
  70. package/dist/Heading/Heading.d.ts.map +1 -1
  71. package/dist/Heading/Heading.js +6 -2
  72. package/dist/HoverCard/HoverCard.d.ts +6 -0
  73. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  74. package/dist/HoverCard/useHoverCard.d.ts +5 -0
  75. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  76. package/dist/HoverCard/useHoverCard.js +67 -25
  77. package/dist/Item/Item.d.ts.map +1 -1
  78. package/dist/Item/Item.js +4 -2
  79. package/dist/Kbd/Kbd.d.ts.map +1 -1
  80. package/dist/Kbd/Kbd.js +2 -19
  81. package/dist/Layer/LayerDepthContext.d.ts +52 -0
  82. package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
  83. package/dist/Layer/LayerDepthContext.js +66 -0
  84. package/dist/Layer/index.d.ts +3 -0
  85. package/dist/Layer/index.d.ts.map +1 -1
  86. package/dist/Layer/index.js +4 -0
  87. package/dist/Layer/layerStack.d.ts +98 -0
  88. package/dist/Layer/layerStack.d.ts.map +1 -0
  89. package/dist/Layer/layerStack.js +306 -0
  90. package/dist/Layer/useLayerDismissal.d.ts +93 -0
  91. package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
  92. package/dist/Layer/useLayerDismissal.js +91 -0
  93. package/dist/Lightbox/Lightbox.d.ts +1 -0
  94. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  95. package/dist/Lightbox/Lightbox.js +103 -81
  96. package/dist/Markdown/index.d.ts +1 -1
  97. package/dist/Markdown/index.d.ts.map +1 -1
  98. package/dist/Markdown/parser.d.ts +38 -1
  99. package/dist/Markdown/parser.d.ts.map +1 -1
  100. package/dist/Markdown/parser.js +177 -29
  101. package/dist/MobileNav/MobileNav.d.ts +6 -1
  102. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  103. package/dist/MobileNav/MobileNav.js +61 -36
  104. package/dist/MultiSelector/MultiSelector.d.ts +15 -1
  105. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  106. package/dist/MultiSelector/MultiSelector.js +17 -6
  107. package/dist/MultiSelector/index.d.ts +1 -1
  108. package/dist/MultiSelector/index.d.ts.map +1 -1
  109. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  110. package/dist/NavMenu/NavHeadingMenu.js +3 -2
  111. package/dist/Outline/Outline.d.ts.map +1 -1
  112. package/dist/Outline/Outline.js +3 -2
  113. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  114. package/dist/OverflowList/OverflowList.js +3 -2
  115. package/dist/Overlay/Overlay.d.ts.map +1 -1
  116. package/dist/Overlay/Overlay.js +3 -2
  117. package/dist/Popover/usePopover.d.ts.map +1 -1
  118. package/dist/Popover/usePopover.js +20 -17
  119. package/dist/PowerSearch/PowerSearch.d.ts +8 -2
  120. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  121. package/dist/PowerSearch/PowerSearch.js +19 -6
  122. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
  123. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  124. package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
  125. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
  126. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  127. package/dist/PowerSearch/PowerSearchValueEditor.js +19 -9
  128. package/dist/PowerSearch/types.d.ts +2 -0
  129. package/dist/PowerSearch/types.d.ts.map +1 -1
  130. package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
  131. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  132. package/dist/PowerSearch/usePowerSearchSource.js +14 -5
  133. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  134. package/dist/Resizable/ResizeHandle.js +3 -2
  135. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  136. package/dist/SegmentedControl/SegmentedControl.js +3 -2
  137. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  138. package/dist/SelectableCard/SelectableCard.js +3 -3
  139. package/dist/Selector/Selector.d.ts.map +1 -1
  140. package/dist/Selector/Selector.js +5 -0
  141. package/dist/SideNav/SideNav.d.ts.map +1 -1
  142. package/dist/SideNav/SideNav.js +4 -3
  143. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  144. package/dist/SideNav/SideNavHeading.js +6 -5
  145. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  146. package/dist/SideNav/SideNavItem.js +4 -3
  147. package/dist/Slider/Slider.d.ts.map +1 -1
  148. package/dist/Slider/Slider.js +3 -3
  149. package/dist/Spinner/Spinner.d.ts +3 -3
  150. package/dist/Spinner/Spinner.d.ts.map +1 -1
  151. package/dist/Spinner/Spinner.js +130 -78
  152. package/dist/Stepper/Step.d.ts +140 -0
  153. package/dist/Stepper/Step.d.ts.map +1 -0
  154. package/dist/Stepper/Step.js +1045 -0
  155. package/dist/Stepper/StepStatus.d.ts +24 -0
  156. package/dist/Stepper/StepStatus.d.ts.map +1 -0
  157. package/dist/Stepper/StepStatus.js +1 -0
  158. package/dist/Stepper/Stepper.d.ts +93 -0
  159. package/dist/Stepper/Stepper.d.ts.map +1 -0
  160. package/dist/Stepper/Stepper.js +184 -0
  161. package/dist/Stepper/StepperContext.d.ts +41 -0
  162. package/dist/Stepper/StepperContext.d.ts.map +1 -0
  163. package/dist/Stepper/StepperContext.js +34 -0
  164. package/dist/Stepper/index.d.ts +8 -0
  165. package/dist/Stepper/index.d.ts.map +1 -0
  166. package/dist/Stepper/index.js +7 -0
  167. package/dist/Stepper/stepper.stylex.d.ts +15 -0
  168. package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
  169. package/dist/Stepper/stepper.stylex.js +20 -0
  170. package/dist/Switch/Switch.d.ts.map +1 -1
  171. package/dist/Switch/Switch.js +3 -2
  172. package/dist/TabList/Tab.d.ts +15 -2
  173. package/dist/TabList/Tab.d.ts.map +1 -1
  174. package/dist/TabList/Tab.js +32 -7
  175. package/dist/TabList/TabList.d.ts +46 -7
  176. package/dist/TabList/TabList.d.ts.map +1 -1
  177. package/dist/TabList/TabList.js +353 -23
  178. package/dist/TabList/TabListContext.d.ts +11 -1
  179. package/dist/TabList/TabListContext.d.ts.map +1 -1
  180. package/dist/TabList/TabListContext.js +11 -2
  181. package/dist/TabList/TabMenu.d.ts.map +1 -1
  182. package/dist/TabList/TabMenu.js +3 -2
  183. package/dist/TabList/index.d.ts +2 -2
  184. package/dist/TabList/index.d.ts.map +1 -1
  185. package/dist/Table/BaseTable.d.ts.map +1 -1
  186. package/dist/Table/BaseTable.js +4 -1
  187. package/dist/Table/TableRow.d.ts +16 -5
  188. package/dist/Table/TableRow.d.ts.map +1 -1
  189. package/dist/Table/TableRow.js +16 -5
  190. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  191. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +20 -8
  192. package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
  193. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  194. package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
  195. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  196. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  197. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  198. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
  199. package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
  200. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  201. package/dist/Table/plugins/selection/useTableSelection.js +19 -5
  202. package/dist/Table/types.d.ts +22 -4
  203. package/dist/Table/types.d.ts.map +1 -1
  204. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  205. package/dist/Table/useBaseTablePlugins.js +5 -0
  206. package/dist/Text/Text.d.ts.map +1 -1
  207. package/dist/Text/Text.js +6 -2
  208. package/dist/TextArea/TextArea.d.ts.map +1 -1
  209. package/dist/TextArea/TextArea.js +3 -2
  210. package/dist/TextInput/TextInput.d.ts.map +1 -1
  211. package/dist/TextInput/TextInput.js +3 -2
  212. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  213. package/dist/TimeInput/TimeInput.js +3 -2
  214. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  215. package/dist/Timestamp/Timestamp.js +5 -3
  216. package/dist/Token/TokenLink.d.ts.map +1 -1
  217. package/dist/Token/TokenLink.js +2 -2
  218. package/dist/Tokenizer/Tokenizer.d.ts +3 -1
  219. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  220. package/dist/Tokenizer/Tokenizer.js +2 -0
  221. package/dist/Tooltip/Tooltip.d.ts +5 -0
  222. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  223. package/dist/Tooltip/useTooltip.d.ts +5 -0
  224. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  225. package/dist/Tooltip/useTooltip.js +39 -24
  226. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  227. package/dist/TopNav/TopNavHeading.js +3 -2
  228. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  229. package/dist/TopNav/TopNavMegaMenu.js +3 -3
  230. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  231. package/dist/TopNav/TopNavMenu.js +4 -3
  232. package/dist/Typeahead/BaseTypeahead.d.ts +2 -0
  233. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  234. package/dist/Typeahead/BaseTypeahead.js +68 -29
  235. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  236. package/dist/Typeahead/Typeahead.js +3 -2
  237. package/dist/astryx.css +68 -2
  238. package/dist/hooks/index.d.ts +1 -0
  239. package/dist/hooks/index.d.ts.map +1 -1
  240. package/dist/hooks/index.js +1 -0
  241. package/dist/hooks/useFocusTrap.d.ts +7 -4
  242. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  243. package/dist/hooks/useFocusTrap.js +60 -95
  244. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  245. package/dist/hooks/useHotkeys.js +3 -18
  246. package/dist/hooks/useMergedRefs.d.ts +18 -0
  247. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  248. package/dist/hooks/useMergedRefs.js +25 -0
  249. package/dist/index.d.ts +1 -0
  250. package/dist/index.d.ts.map +1 -1
  251. package/dist/index.js +1 -0
  252. package/dist/utils/groupItems.d.ts +5 -1
  253. package/dist/utils/groupItems.d.ts.map +1 -1
  254. package/dist/utils/groupItems.js +9 -9
  255. package/dist/utils/index.d.ts +1 -1
  256. package/dist/utils/index.d.ts.map +1 -1
  257. package/dist/utils/isApplePlatform.d.ts +18 -0
  258. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  259. package/dist/utils/isApplePlatform.js +37 -0
  260. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  261. package/dist/utils/sharedResizeObserver.js +10 -1
  262. package/dist/utils/timeParser.d.ts +1 -1
  263. package/dist/utils/timeParser.d.ts.map +1 -1
  264. package/dist/utils/timeParser.js +26 -12
  265. package/locales/en.json +31 -7
  266. package/locales/pseudo.json +18 -0
  267. package/package.json +8 -3
  268. package/src/AppShell/AppShell.tsx +3 -2
  269. package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
  270. package/src/AspectRatio/AspectRatio.test.tsx +57 -10
  271. package/src/AspectRatio/AspectRatio.tsx +40 -1
  272. package/src/Avatar/Avatar.doc.mjs +2 -1
  273. package/src/Avatar/Avatar.test.tsx +17 -0
  274. package/src/Avatar/Avatar.tsx +61 -38
  275. package/src/AvatarGroup/AvatarGroup.tsx +3 -2
  276. package/src/Banner/Banner.doc.mjs +13 -11
  277. package/src/Banner/Banner.test.tsx +102 -15
  278. package/src/Banner/Banner.tsx +72 -25
  279. package/src/BottomSheet/BottomSheet.test.tsx +123 -0
  280. package/src/BottomSheet/BottomSheet.tsx +17 -4
  281. package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
  282. package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
  283. package/src/Button/Button.doc.mjs +22 -0
  284. package/src/Button/Button.test.tsx +13 -0
  285. package/src/Button/Button.tsx +5 -4
  286. package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
  287. package/src/ButtonGroup/ButtonGroup.test.tsx +391 -1
  288. package/src/ButtonGroup/ButtonGroup.tsx +23 -5
  289. package/src/Calendar/Calendar.doc.mjs +4 -3
  290. package/src/Calendar/Calendar.test.tsx +52 -0
  291. package/src/Calendar/Calendar.tsx +18 -15
  292. package/src/Calendar/getInitialFocusDate.test.ts +94 -0
  293. package/src/Calendar/getInitialFocusDate.ts +93 -0
  294. package/src/Carousel/Carousel.tsx +3 -2
  295. package/src/Chat/ChatComposerInput.tsx +5 -1
  296. package/src/Chat/ChatLayout.tsx +3 -2
  297. package/src/Chat/ChatMessageList.doc.mjs +9 -1
  298. package/src/Chat/ChatMessageList.test.tsx +46 -0
  299. package/src/Chat/ChatMessageList.tsx +28 -4
  300. package/src/Chat/ChatTokenizedText.tsx +17 -10
  301. package/src/Chat/useChatComposerTokens.ts +1 -1
  302. package/src/CheckboxInput/CheckboxInput.tsx +3 -2
  303. package/src/ClickableCard/ClickableCard.tsx +3 -2
  304. package/src/CodeBlock/CodeBlock.doc.mjs +6 -0
  305. package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
  306. package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
  307. package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
  308. package/src/ContextMenu/ContextMenu.tsx +4 -3
  309. package/src/DateInput/DateInput.tsx +3 -2
  310. package/src/DateInput/DateInputTouch.test.tsx +36 -0
  311. package/src/DateInput/TouchDateField.tsx +38 -4
  312. package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
  313. package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
  314. package/src/DateTimeInput/DateTimeInput.tsx +556 -24
  315. package/src/DateTimeInput/index.ts +1 -0
  316. package/src/Dialog/Dialog.doc.mjs +8 -3
  317. package/src/Dialog/Dialog.test.tsx +261 -1
  318. package/src/Dialog/Dialog.tsx +109 -58
  319. package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
  320. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
  321. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
  322. package/src/Field/Field.doc.mjs +13 -2
  323. package/src/FileInput/FileInput.tsx +3 -2
  324. package/src/Heading/Heading.test.tsx +23 -1
  325. package/src/Heading/Heading.tsx +6 -2
  326. package/src/HoverCard/HoverCard.doc.mjs +5 -0
  327. package/src/HoverCard/HoverCard.tsx +6 -0
  328. package/src/HoverCard/useHoverCard.tsx +81 -30
  329. package/src/Item/Item.tsx +5 -4
  330. package/src/Kbd/Kbd.tsx +2 -19
  331. package/src/Layer/LayerDepthContext.tsx +62 -0
  332. package/src/Layer/index.ts +9 -0
  333. package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
  334. package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
  335. package/src/Layer/layerStack.ts +362 -0
  336. package/src/Layer/useLayerDismissal.test.tsx +469 -0
  337. package/src/Layer/useLayerDismissal.ts +173 -0
  338. package/src/Layout/Layout.doc.mjs +2 -2
  339. package/src/Lightbox/Lightbox.doc.mjs +12 -0
  340. package/src/Lightbox/Lightbox.tsx +124 -102
  341. package/src/Link/Link.doc.mjs +39 -0
  342. package/src/Markdown/Markdown.doc.mjs +5 -0
  343. package/src/Markdown/incremental.test.ts +16 -2
  344. package/src/Markdown/index.ts +1 -0
  345. package/src/Markdown/parser.perf.test.ts +96 -1
  346. package/src/Markdown/parser.test.ts +145 -2
  347. package/src/Markdown/parser.ts +244 -29
  348. package/src/MobileNav/MobileNav.tsx +62 -36
  349. package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
  350. package/src/MultiSelector/MultiSelector.doc.mjs +27 -0
  351. package/src/MultiSelector/MultiSelector.test.tsx +106 -0
  352. package/src/MultiSelector/MultiSelector.tsx +50 -6
  353. package/src/MultiSelector/index.ts +1 -0
  354. package/src/NavMenu/NavHeadingMenu.tsx +3 -2
  355. package/src/NumberInput/NumberInput.doc.mjs +5 -0
  356. package/src/Outline/Outline.tsx +3 -2
  357. package/src/OverflowList/OverflowList.tsx +3 -2
  358. package/src/Overlay/Overlay.tsx +3 -2
  359. package/src/Popover/usePopover.tsx +31 -28
  360. package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
  361. package/src/PowerSearch/PowerSearch.test.tsx +240 -1
  362. package/src/PowerSearch/PowerSearch.tsx +34 -5
  363. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +201 -0
  364. package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
  365. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +47 -1
  366. package/src/PowerSearch/PowerSearchValueEditor.tsx +15 -0
  367. package/src/PowerSearch/types.ts +2 -0
  368. package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
  369. package/src/PowerSearch/usePowerSearchSource.ts +13 -3
  370. package/src/Resizable/ResizeHandle.tsx +3 -2
  371. package/src/SegmentedControl/SegmentedControl.tsx +3 -2
  372. package/src/SelectableCard/SelectableCard.tsx +3 -2
  373. package/src/Selector/Selector.doc.mjs +12 -1
  374. package/src/Selector/Selector.test.tsx +45 -1
  375. package/src/Selector/Selector.tsx +11 -1
  376. package/src/SideNav/SideNav.doc.mjs +6 -6
  377. package/src/SideNav/SideNav.tsx +4 -2
  378. package/src/SideNav/SideNavHeading.tsx +10 -10
  379. package/src/SideNav/SideNavItem.tsx +4 -2
  380. package/src/Slider/Slider.tsx +3 -2
  381. package/src/Spinner/Spinner.test.tsx +147 -1
  382. package/src/Spinner/Spinner.tsx +120 -101
  383. package/src/Stepper/Step.doc.mjs +98 -0
  384. package/src/Stepper/Step.tsx +1638 -0
  385. package/src/Stepper/StepStatus.ts +26 -0
  386. package/src/Stepper/Stepper.doc.mjs +370 -0
  387. package/src/Stepper/Stepper.test.tsx +1024 -0
  388. package/src/Stepper/Stepper.tsx +258 -0
  389. package/src/Stepper/StepperContext.ts +71 -0
  390. package/src/Stepper/index.ts +18 -0
  391. package/src/Stepper/stepper.stylex.ts +19 -0
  392. package/src/Switch/Switch.tsx +3 -2
  393. package/src/TabList/Tab.doc.mjs +13 -1
  394. package/src/TabList/Tab.tsx +67 -7
  395. package/src/TabList/TabList.doc.mjs +22 -6
  396. package/src/TabList/TabList.test.tsx +559 -0
  397. package/src/TabList/TabList.tsx +490 -22
  398. package/src/TabList/TabListContext.ts +13 -2
  399. package/src/TabList/TabMenu.tsx +3 -2
  400. package/src/TabList/index.ts +6 -2
  401. package/src/Table/BaseTable.tsx +6 -3
  402. package/src/Table/Table.doc.mjs +6 -1
  403. package/src/Table/Table.test.tsx +132 -14
  404. package/src/Table/TableBody.doc.mjs +40 -0
  405. package/src/Table/TableFooter.doc.mjs +40 -0
  406. package/src/Table/TableHeader.doc.mjs +40 -0
  407. package/src/Table/TableRow.tsx +16 -5
  408. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
  409. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
  410. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +17 -8
  411. package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
  412. package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
  413. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
  414. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
  415. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
  416. package/src/Table/plugins/selection/useTableSelection.test.tsx +76 -0
  417. package/src/Table/plugins/selection/useTableSelection.tsx +40 -7
  418. package/src/Table/types.ts +22 -4
  419. package/src/Table/useBaseTablePlugins.ts +5 -0
  420. package/src/Table/useTableGroupedRows.doc.mjs +5 -4
  421. package/src/Table/useTablePagination.doc.mjs +7 -0
  422. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  423. package/src/Table/useTableSelection.doc.mjs +31 -0
  424. package/src/Text/Text.test.tsx +23 -1
  425. package/src/Text/Text.tsx +6 -2
  426. package/src/TextArea/TextArea.tsx +3 -2
  427. package/src/TextInput/TextInput.doc.mjs +10 -0
  428. package/src/TextInput/TextInput.tsx +3 -2
  429. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  430. package/src/TimeInput/TimeInput.tsx +2 -2
  431. package/src/Timestamp/Timestamp.tsx +4 -2
  432. package/src/Toast/Toast.doc.mjs +6 -0
  433. package/src/Token/TokenLink.tsx +2 -2
  434. package/src/Tokenizer/Tokenizer.doc.mjs +27 -0
  435. package/src/Tokenizer/Tokenizer.tsx +4 -0
  436. package/src/Toolbar/Toolbar.doc.mjs +5 -0
  437. package/src/Tooltip/Tooltip.doc.mjs +5 -0
  438. package/src/Tooltip/Tooltip.test.tsx +32 -0
  439. package/src/Tooltip/Tooltip.tsx +5 -0
  440. package/src/Tooltip/useTooltip.tsx +47 -24
  441. package/src/TopNav/TopNavHeading.tsx +3 -2
  442. package/src/TopNav/TopNavMegaMenu.tsx +3 -2
  443. package/src/TopNav/TopNavMenu.tsx +4 -3
  444. package/src/Typeahead/BaseTypeahead.doc.mjs +11 -0
  445. package/src/Typeahead/BaseTypeahead.tsx +85 -33
  446. package/src/Typeahead/Typeahead.doc.mjs +5 -0
  447. package/src/Typeahead/Typeahead.test.tsx +49 -0
  448. package/src/Typeahead/Typeahead.tsx +3 -2
  449. package/src/hooks/index.ts +2 -0
  450. package/src/hooks/useContainerReveal.doc.mjs +2 -2
  451. package/src/hooks/useFocusTrap.test.tsx +14 -0
  452. package/src/hooks/useFocusTrap.ts +62 -111
  453. package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
  454. package/src/hooks/useHotkeys.ts +3 -18
  455. package/src/hooks/useMergedRefs.doc.mjs +79 -0
  456. package/src/hooks/useMergedRefs.test.tsx +62 -0
  457. package/src/hooks/useMergedRefs.ts +36 -0
  458. package/src/index.ts +1 -0
  459. package/src/theme/MediaTheme.doc.mjs +5 -5
  460. package/src/utils/groupItems.ts +12 -6
  461. package/src/utils/index.ts +1 -1
  462. package/src/utils/isApplePlatform.test.ts +61 -0
  463. package/src/utils/isApplePlatform.ts +37 -0
  464. package/src/utils/sharedResizeObserver.ts +10 -2
  465. package/src/utils/timeParser.test.ts +6 -1
  466. package/src/utils/timeParser.ts +35 -13
  467. package/src/__tests__/inputWidthContract.test.tsx +0 -69
@@ -0,0 +1,417 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file layerDismissalInvariants.test.tsx
5
+ * @input Uses vitest, @testing-library/react, Dialog, Lightbox
6
+ * @output Tests the one invariant the shared stack exists to hold
7
+ * @position Colocated with layerStack. `useLayerDismissal.test.tsx` covers the
8
+ * hook's mechanics against synthetic layers; this file asks the user's
9
+ * question of real overlays — after one Escape, what is still on screen?
10
+ *
11
+ * Every assertion here reads the DOM (`which dialogs are open`) rather than a
12
+ * dismiss spy. A spy passes when the stack routes to the wrong layer as long as
13
+ * something was called; the open-dialog census cannot.
14
+ *
15
+ * jsdom models neither the close watcher nor IME composition, so the rows that
16
+ * depend on a real engine are driven through the same channels the browser
17
+ * would use — a `cancel` event, a keydown carrying `isComposing` — and the
18
+ * end-to-end behavior is measured in Chromium instead (probe-kit).
19
+ *
20
+ * SYNC: When a new overlay family joins the stack, add it here.
21
+ */
22
+
23
+ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
24
+ import {render, screen, act} from '@testing-library/react';
25
+ import {useState} from 'react';
26
+
27
+ import {Dialog} from '../Dialog/Dialog';
28
+ import {Lightbox} from '../Lightbox/Lightbox';
29
+ import {resetLayerStackForTests} from './layerStack';
30
+ import {useLayerDismissal} from './useLayerDismissal';
31
+
32
+ // jsdom implements neither, and Dialog drives both.
33
+ beforeEach(() => {
34
+ HTMLDialogElement.prototype.showModal = vi.fn(function (
35
+ this: HTMLDialogElement,
36
+ ) {
37
+ this.setAttribute('open', '');
38
+ });
39
+ HTMLDialogElement.prototype.close = vi.fn(function (this: HTMLDialogElement) {
40
+ this.removeAttribute('open');
41
+ });
42
+ });
43
+
44
+ afterEach(() => {
45
+ resetLayerStackForTests();
46
+ });
47
+
48
+ /**
49
+ * Everything on screen right now, named the way a person would name it and
50
+ * sorted so the census is about WHICH layers are up, not what order two role
51
+ * queries happened to return them in.
52
+ */
53
+ function onScreen(): string[] {
54
+ // `purpose="required"` renders role="alertdialog", so both roles have to be
55
+ // asked for or a required Dialog is invisible to the census.
56
+ return [
57
+ ...screen.queryAllByRole('dialog', {hidden: true}),
58
+ ...screen.queryAllByRole('alertdialog', {hidden: true}),
59
+ ]
60
+ .filter(d => (d as HTMLDialogElement).open)
61
+ .map(d => d.getAttribute('aria-label') ?? '(unnamed)')
62
+ .sort();
63
+ }
64
+
65
+ function pressEscape(options: KeyboardEventInit = {}): KeyboardEvent {
66
+ const event = new KeyboardEvent('keydown', {
67
+ key: 'Escape',
68
+ bubbles: true,
69
+ cancelable: true,
70
+ ...options,
71
+ });
72
+ act(() => {
73
+ document.dispatchEvent(event);
74
+ });
75
+ return event;
76
+ }
77
+
78
+ function composingEscape(): KeyboardEvent {
79
+ const event = new KeyboardEvent('keydown', {
80
+ key: 'Escape',
81
+ bubbles: true,
82
+ cancelable: true,
83
+ });
84
+ Object.defineProperty(event, 'isComposing', {value: true});
85
+ act(() => {
86
+ document.dispatchEvent(event);
87
+ });
88
+ return event;
89
+ }
90
+
91
+ function fireCancel(label: string): Event {
92
+ const event = new Event('cancel', {bubbles: false, cancelable: true});
93
+ const dialog = [
94
+ ...screen.queryAllByRole('dialog', {hidden: true}),
95
+ ...screen.queryAllByRole('alertdialog', {hidden: true}),
96
+ ].find(d => d.getAttribute('aria-label') === label)!;
97
+ act(() => {
98
+ dialog.dispatchEvent(event);
99
+ });
100
+ return event;
101
+ }
102
+
103
+ /** A modal whose own open state is real, so the DOM changes when it closes. */
104
+ function Modal({
105
+ label,
106
+ purpose,
107
+ isOpenInitially = true,
108
+ children,
109
+ }: {
110
+ label: string;
111
+ purpose?: 'required';
112
+ isOpenInitially?: boolean;
113
+ children?: React.ReactNode;
114
+ }) {
115
+ const [isOpen, setIsOpen] = useState(isOpenInitially);
116
+ return (
117
+ <Dialog
118
+ isOpen={isOpen}
119
+ onOpenChange={setIsOpen}
120
+ purpose={purpose}
121
+ aria-label={label}>
122
+ {label}
123
+ {children}
124
+ </Dialog>
125
+ );
126
+ }
127
+
128
+ describe('one Escape dismisses exactly one layer', () => {
129
+ it('peels a modal-in-modal one press at a time', () => {
130
+ render(
131
+ <Modal label="Outer">
132
+ <Modal label="Inner" />
133
+ </Modal>,
134
+ );
135
+ expect(onScreen()).toEqual(['Inner', 'Outer']);
136
+
137
+ pressEscape();
138
+ expect(onScreen()).toEqual(['Outer']);
139
+
140
+ pressEscape();
141
+ expect(onScreen()).toEqual([]);
142
+ });
143
+
144
+ it('peels three layers in order, never two on one press', () => {
145
+ render(
146
+ <Modal label="Outer">
147
+ <Modal label="Middle">
148
+ <Modal label="Inner" />
149
+ </Modal>
150
+ </Modal>,
151
+ );
152
+ expect(onScreen()).toEqual(['Inner', 'Middle', 'Outer']);
153
+
154
+ pressEscape();
155
+ expect(onScreen()).toEqual(['Middle', 'Outer']);
156
+
157
+ pressEscape();
158
+ expect(onScreen()).toEqual(['Outer']);
159
+
160
+ pressEscape();
161
+ expect(onScreen()).toEqual([]);
162
+ });
163
+
164
+ it('lets a Lightbox over a required Dialog take the press, and only it', () => {
165
+ function LightboxInRequired() {
166
+ const [isLightboxOpen, setIsLightboxOpen] = useState(true);
167
+ return (
168
+ <Modal label="Required" purpose="required">
169
+ <Lightbox
170
+ isOpen={isLightboxOpen}
171
+ onOpenChange={setIsLightboxOpen}
172
+ media={{src: '/photo.jpg', alt: 'A photo'}}
173
+ />
174
+ </Modal>
175
+ );
176
+ }
177
+ render(<LightboxInRequired />);
178
+ expect(onScreen()).toEqual(['A photo', 'Required']);
179
+
180
+ pressEscape();
181
+ expect(onScreen()).toEqual(['Required']);
182
+ });
183
+
184
+ it('reaches the layer below once the one above is closed another way', () => {
185
+ // Closing the inner modal with its own control must leave the stack clean,
186
+ // so the next Escape finds the outer rather than falling into a gap.
187
+ function OuterAndInner() {
188
+ const [isInnerOpen, setIsInnerOpen] = useState(true);
189
+ return (
190
+ <Modal label="Outer">
191
+ <button type="button" onClick={() => setIsInnerOpen(false)}>
192
+ close inner
193
+ </button>
194
+ {isInnerOpen ? <Modal label="Inner" /> : null}
195
+ </Modal>
196
+ );
197
+ }
198
+ render(<OuterAndInner />);
199
+ expect(onScreen()).toEqual(['Inner', 'Outer']);
200
+
201
+ act(() => {
202
+ screen.getByText('close inner').click();
203
+ });
204
+ expect(onScreen()).toEqual(['Outer']);
205
+
206
+ pressEscape();
207
+ expect(onScreen()).toEqual([]);
208
+ });
209
+ });
210
+
211
+ describe("escapeBehavior: 'block'", () => {
212
+ it('swallows the press so nothing behind a required Dialog dismisses either', () => {
213
+ render(
214
+ <Modal label="Host">
215
+ <Modal label="Required" purpose="required" />
216
+ </Modal>,
217
+ );
218
+
219
+ const event = pressEscape();
220
+
221
+ expect(onScreen()).toEqual(['Host', 'Required']);
222
+ // Claimed, not merely ignored — an unclaimed press is what lets the
223
+ // browser's own close watcher dismiss something behind our back.
224
+ expect(event.defaultPrevented).toBe(true);
225
+ });
226
+
227
+ it('does not block a layer opened ON TOP of the required Dialog', () => {
228
+ render(
229
+ <Modal label="Required" purpose="required">
230
+ <Modal label="Above" />
231
+ </Modal>,
232
+ );
233
+
234
+ pressEscape();
235
+ expect(onScreen()).toEqual(['Required']);
236
+ });
237
+ });
238
+
239
+ describe('re-registration does not reorder the stack', () => {
240
+ it('keeps a Dialog whose purpose flips below the layer opened over it', () => {
241
+ // A Dialog re-registers when `purpose` changes, because that changes its
242
+ // escapeBehavior. Re-registering must not promote it above a layer that
243
+ // opened on top of it — otherwise a flip to `required` silently starts
244
+ // swallowing presses meant for the layer above.
245
+ function FlippingHost() {
246
+ const [purpose, setPurpose] = useState<'required' | undefined>(undefined);
247
+ return (
248
+ <>
249
+ <Modal label="Host" purpose={purpose} />
250
+ <Modal label="Later" />
251
+ <button type="button" onClick={() => setPurpose('required')}>
252
+ make required
253
+ </button>
254
+ </>
255
+ );
256
+ }
257
+ render(<FlippingHost />);
258
+ expect(onScreen()).toEqual(['Host', 'Later']);
259
+
260
+ act(() => {
261
+ screen.getByText('make required').click();
262
+ });
263
+
264
+ pressEscape();
265
+ expect(onScreen()).toEqual(['Host']);
266
+ });
267
+ });
268
+
269
+ describe('close requests the browser starts itself', () => {
270
+ it('follows the same top-most rule as a press', () => {
271
+ render(
272
+ <Modal label="Outer">
273
+ <Modal label="Inner" />
274
+ </Modal>,
275
+ );
276
+
277
+ // The Android back gesture on the layer that is NOT on top.
278
+ const outerRequest = fireCancel('Outer');
279
+ expect(outerRequest.defaultPrevented).toBe(true);
280
+ expect(onScreen()).toEqual(['Inner', 'Outer']);
281
+
282
+ fireCancel('Inner');
283
+ expect(onScreen()).toEqual(['Outer']);
284
+ });
285
+
286
+ it('is declined while an IME composition is running', () => {
287
+ render(
288
+ <Modal label="Composing">
289
+ <input aria-label="field" />
290
+ </Modal>,
291
+ );
292
+ const field = screen.getByLabelText('field');
293
+
294
+ act(() => {
295
+ field.dispatchEvent(
296
+ new CompositionEvent('compositionstart', {bubbles: true}),
297
+ );
298
+ });
299
+ fireCancel('Composing');
300
+ expect(onScreen()).toEqual(['Composing']);
301
+
302
+ act(() => {
303
+ field.dispatchEvent(
304
+ new CompositionEvent('compositionend', {bubbles: true}),
305
+ );
306
+ });
307
+ fireCancel('Composing');
308
+ expect(onScreen()).toEqual([]);
309
+ });
310
+ });
311
+
312
+ describe('an Escape that cancels an IME composition', () => {
313
+ it('dismisses nothing AND claims the press, so no close request follows', () => {
314
+ render(<Modal label="Composing" />);
315
+
316
+ const event = composingEscape();
317
+
318
+ expect(onScreen()).toEqual(['Composing']);
319
+ // The half that matters. Standing down without claiming leaves the browser
320
+ // free to raise its own close request, which arrives at `cancel` with no
321
+ // composition state to read and closes the dialog on the same keypress.
322
+ expect(event.defaultPrevented).toBe(true);
323
+ });
324
+
325
+ it('leaves the press alone when there is no layer to protect', () => {
326
+ render(<Modal label="Closed" isOpenInitially={false} />);
327
+
328
+ const event = composingEscape();
329
+
330
+ expect(event.defaultPrevented).toBe(false);
331
+ });
332
+ });
333
+
334
+ describe('registration and teardown', () => {
335
+ it('drops a layer from the stack when it unmounts', () => {
336
+ function Pair({hasTop}: {hasTop: boolean}) {
337
+ return (
338
+ <Modal label="Bottom">{hasTop ? <Modal label="Top" /> : null}</Modal>
339
+ );
340
+ }
341
+ const {rerender} = render(<Pair hasTop={true} />);
342
+ rerender(<Pair hasTop={false} />);
343
+
344
+ pressEscape();
345
+ expect(onScreen()).toEqual([]);
346
+ });
347
+
348
+ it('stops claiming Escape once the last layer is gone', () => {
349
+ // The listener is shared and lives on `document`. If unmounting left an
350
+ // entry behind, the page would keep losing Escape presses to a layer that
351
+ // is not there — no error, no visual tell.
352
+ const {unmount} = render(<Modal label="Only" />);
353
+ expect(pressEscape().defaultPrevented).toBe(true);
354
+
355
+ unmount();
356
+
357
+ expect(pressEscape().defaultPrevented).toBe(false);
358
+ });
359
+ });
360
+
361
+ describe('presence is asked at press time', () => {
362
+ it('skips a registered layer that is no longer on screen', () => {
363
+ // Hover layers register for their whole lifetime and answer presence from
364
+ // the DOM. A cached answer would let an idle tooltip eat a press meant for
365
+ // the dialog underneath it.
366
+ const isTipShowing = false;
367
+ const tipDismissed = vi.fn();
368
+
369
+ function TipLayer() {
370
+ useLayerDismissal({
371
+ isActive: true,
372
+ isPresent: () => isTipShowing,
373
+ onDismiss: tipDismissed,
374
+ });
375
+ return null;
376
+ }
377
+
378
+ render(
379
+ <Modal label="Host">
380
+ <TipLayer />
381
+ </Modal>,
382
+ );
383
+
384
+ // Idle: the press must reach the dialog.
385
+ pressEscape();
386
+ expect(tipDismissed).not.toHaveBeenCalled();
387
+ expect(onScreen()).toEqual([]);
388
+ });
389
+
390
+ it('lets the same registration claim the press once it is showing', () => {
391
+ let isTipShowing = true;
392
+ const tipDismissed = vi.fn();
393
+
394
+ function TipLayer() {
395
+ useLayerDismissal({
396
+ isActive: true,
397
+ isPresent: () => isTipShowing,
398
+ onDismiss: tipDismissed,
399
+ });
400
+ return null;
401
+ }
402
+
403
+ render(
404
+ <Modal label="Host">
405
+ <TipLayer />
406
+ </Modal>,
407
+ );
408
+
409
+ pressEscape();
410
+ expect(tipDismissed).toHaveBeenCalledTimes(1);
411
+ expect(onScreen()).toEqual(['Host']);
412
+
413
+ isTipShowing = false;
414
+ pressEscape();
415
+ expect(onScreen()).toEqual([]);
416
+ });
417
+ });