@astryxdesign/core 0.4.7 → 0.5.0-canary.009bcb3

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 (730) hide show
  1. package/CHANGELOG.md +161 -1
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -1
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +45 -20
  5. package/dist/AppShell/AppShell.d.ts.map +1 -1
  6. package/dist/AppShell/AppShell.js +3 -2
  7. package/dist/AspectRatio/AspectRatio.d.ts +24 -0
  8. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  9. package/dist/AspectRatio/AspectRatio.js +23 -4
  10. package/dist/Avatar/Avatar.d.ts +25 -1
  11. package/dist/Avatar/Avatar.d.ts.map +1 -1
  12. package/dist/Avatar/Avatar.js +58 -19
  13. package/dist/Avatar/index.d.ts +2 -2
  14. package/dist/Avatar/index.d.ts.map +1 -1
  15. package/dist/Avatar/index.js +1 -1
  16. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  17. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroup.js +8 -4
  19. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  20. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  21. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  22. package/dist/AvatarGroup/AvatarGroupOverflow.js +10 -6
  23. package/dist/Banner/Banner.d.ts +49 -15
  24. package/dist/Banner/Banner.d.ts.map +1 -1
  25. package/dist/Banner/Banner.js +62 -20
  26. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  27. package/dist/BottomSheet/BottomSheet.js +17 -4
  28. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  29. package/dist/BottomSheet/BottomSheetSwitcher.js +3 -2
  30. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  31. package/dist/Breadcrumbs/BreadcrumbItem.js +11 -10
  32. package/dist/Button/Button.d.ts.map +1 -1
  33. package/dist/Button/Button.js +11 -6
  34. package/dist/ButtonGroup/ButtonGroup.d.ts +5 -1
  35. package/dist/ButtonGroup/ButtonGroup.d.ts.map +1 -1
  36. package/dist/ButtonGroup/ButtonGroup.js +26 -7
  37. package/dist/Calendar/Calendar.d.ts +7 -3
  38. package/dist/Calendar/Calendar.d.ts.map +1 -1
  39. package/dist/Calendar/Calendar.js +21 -23
  40. package/dist/Calendar/getInitialFocusDate.d.ts +46 -0
  41. package/dist/Calendar/getInitialFocusDate.d.ts.map +1 -0
  42. package/dist/Calendar/getInitialFocusDate.js +62 -0
  43. package/dist/Calendar/styles.d.ts +5 -14
  44. package/dist/Calendar/styles.d.ts.map +1 -1
  45. package/dist/Calendar/styles.js +15 -15
  46. package/dist/Card/Card.d.ts +12 -12
  47. package/dist/Card/Card.d.ts.map +1 -1
  48. package/dist/Card/Card.js +17 -9
  49. package/dist/Card/index.d.ts +35 -1
  50. package/dist/Card/index.d.ts.map +1 -1
  51. package/dist/Card/index.js +21 -1
  52. package/dist/Carousel/Carousel.d.ts.map +1 -1
  53. package/dist/Carousel/Carousel.js +3 -3
  54. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  55. package/dist/Chat/ChatComposerInput.js +2 -3
  56. package/dist/Chat/ChatLayout.d.ts.map +1 -1
  57. package/dist/Chat/ChatLayout.js +3 -3
  58. package/dist/Chat/ChatMessageList.d.ts +22 -3
  59. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  60. package/dist/Chat/ChatMessageList.js +6 -3
  61. package/dist/Chat/ChatTokenizedText.d.ts +2 -0
  62. package/dist/Chat/ChatTokenizedText.d.ts.map +1 -1
  63. package/dist/Chat/ChatTokenizedText.js +11 -6
  64. package/dist/Chat/useChatComposerTokens.js +1 -1
  65. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  66. package/dist/CheckboxInput/CheckboxInput.js +10 -3
  67. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  68. package/dist/ClickableCard/ClickableCard.js +3 -3
  69. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  70. package/dist/CodeBlock/CodeBlock.js +15 -4
  71. package/dist/CodeBlock/highlightRanges.js +1 -1
  72. package/dist/CodeBlock/highlightStyles.js +13 -13
  73. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  74. package/dist/CommandPalette/CommandPaletteInput.js +3 -2
  75. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  76. package/dist/CommandPalette/CommandPaletteItem.js +3 -2
  77. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  78. package/dist/ComplexSelector/ComplexSelector.js +1 -3
  79. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  80. package/dist/ContextMenu/ContextMenu.js +4 -3
  81. package/dist/DateInput/DateInput.d.ts +43 -0
  82. package/dist/DateInput/DateInput.d.ts.map +1 -1
  83. package/dist/DateInput/DateInput.js +22 -2
  84. package/dist/DateInput/NativeDateField.d.ts +10 -0
  85. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  86. package/dist/DateInput/NativeDateField.js +494 -0
  87. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  88. package/dist/DateInput/TouchDateField.js +82 -23
  89. package/dist/DateInput/index.d.ts +1 -1
  90. package/dist/DateInput/index.d.ts.map +1 -1
  91. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  92. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  93. package/dist/DateInput/nativeDateSegments.js +111 -0
  94. package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
  95. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  96. package/dist/DateTimeInput/DateTimeInput.d.ts +21 -1
  97. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  98. package/dist/DateTimeInput/DateTimeInput.js +406 -12
  99. package/dist/DateTimeInput/index.d.ts +1 -1
  100. package/dist/DateTimeInput/index.d.ts.map +1 -1
  101. package/dist/Dialog/Dialog.d.ts +21 -1
  102. package/dist/Dialog/Dialog.d.ts.map +1 -1
  103. package/dist/Dialog/Dialog.js +110 -58
  104. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  105. package/dist/DropdownMenu/DropdownMenu.js +4 -13
  106. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  107. package/dist/DropdownMenu/DropdownMenuSubMenu.js +6 -5
  108. package/dist/Field/FieldLabel.d.ts.map +1 -1
  109. package/dist/Field/FieldLabel.js +9 -1
  110. package/dist/Field/InputClearButton.d.ts +9 -3
  111. package/dist/Field/InputClearButton.d.ts.map +1 -1
  112. package/dist/Field/InputClearButton.js +14 -3
  113. package/dist/FileInput/FileInput.d.ts.map +1 -1
  114. package/dist/FileInput/FileInput.js +3 -2
  115. package/dist/Heading/Heading.d.ts.map +1 -1
  116. package/dist/Heading/Heading.js +6 -3
  117. package/dist/HoverCard/HoverCard.d.ts +6 -0
  118. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  119. package/dist/HoverCard/HoverCard.js +104 -3
  120. package/dist/HoverCard/useHoverCard.d.ts +19 -2
  121. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  122. package/dist/HoverCard/useHoverCard.js +74 -26
  123. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  124. package/dist/Indicator/CheckboxIndicator.js +6 -2
  125. package/dist/Item/Item.d.ts.map +1 -1
  126. package/dist/Item/Item.js +4 -2
  127. package/dist/Kbd/Kbd.d.ts.map +1 -1
  128. package/dist/Kbd/Kbd.js +2 -19
  129. package/dist/Layer/LayerDepthContext.d.ts +52 -0
  130. package/dist/Layer/LayerDepthContext.d.ts.map +1 -0
  131. package/dist/Layer/LayerDepthContext.js +66 -0
  132. package/dist/Layer/gestureCounter.d.ts +8 -0
  133. package/dist/Layer/gestureCounter.d.ts.map +1 -0
  134. package/dist/Layer/gestureCounter.js +53 -0
  135. package/dist/Layer/index.d.ts +3 -0
  136. package/dist/Layer/index.d.ts.map +1 -1
  137. package/dist/Layer/index.js +4 -0
  138. package/dist/Layer/layerStack.d.ts +98 -0
  139. package/dist/Layer/layerStack.d.ts.map +1 -0
  140. package/dist/Layer/layerStack.js +306 -0
  141. package/dist/Layer/useLayer.d.ts +23 -13
  142. package/dist/Layer/useLayer.d.ts.map +1 -1
  143. package/dist/Layer/useLayer.js +128 -8
  144. package/dist/Layer/useLayerDismissal.d.ts +93 -0
  145. package/dist/Layer/useLayerDismissal.d.ts.map +1 -0
  146. package/dist/Layer/useLayerDismissal.js +91 -0
  147. package/dist/Lightbox/Lightbox.d.ts +1 -0
  148. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  149. package/dist/Lightbox/Lightbox.js +103 -81
  150. package/dist/List/List.d.ts +1 -1
  151. package/dist/List/List.d.ts.map +1 -1
  152. package/dist/List/List.js +15 -4
  153. package/dist/Markdown/Markdown.d.ts +1 -1
  154. package/dist/Markdown/Markdown.d.ts.map +1 -1
  155. package/dist/Markdown/Markdown.js +20 -7
  156. package/dist/Markdown/index.d.ts +1 -1
  157. package/dist/Markdown/index.d.ts.map +1 -1
  158. package/dist/Markdown/parser.d.ts +38 -1
  159. package/dist/Markdown/parser.d.ts.map +1 -1
  160. package/dist/Markdown/parser.js +182 -32
  161. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  162. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  163. package/dist/MetadataList/MetadataListItem.js +4 -1
  164. package/dist/MobileNav/MobileNav.d.ts +6 -1
  165. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  166. package/dist/MobileNav/MobileNav.js +61 -36
  167. package/dist/MultiSelector/MultiSelector.d.ts +32 -1
  168. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  169. package/dist/MultiSelector/MultiSelector.js +73 -15
  170. package/dist/MultiSelector/hooks.d.ts +7 -1
  171. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  172. package/dist/MultiSelector/hooks.js +3 -2
  173. package/dist/MultiSelector/index.d.ts +1 -1
  174. package/dist/MultiSelector/index.d.ts.map +1 -1
  175. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  176. package/dist/NavIcon/NavIcon.js +5 -1
  177. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  178. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  179. package/dist/NavMenu/NavHeadingMenu.js +9 -5
  180. package/dist/NumberInput/NumberInput.d.ts +6 -1
  181. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  182. package/dist/NumberInput/NumberInput.js +54 -104
  183. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  184. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  185. package/dist/NumberInput/numberInputCommit.js +71 -0
  186. package/dist/NumberInput/numberParser.d.ts +64 -0
  187. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  188. package/dist/NumberInput/numberParser.js +350 -0
  189. package/dist/Outline/Outline.d.ts.map +1 -1
  190. package/dist/Outline/Outline.js +3 -2
  191. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  192. package/dist/OverflowList/OverflowList.js +3 -2
  193. package/dist/Overlay/Overlay.d.ts.map +1 -1
  194. package/dist/Overlay/Overlay.js +3 -2
  195. package/dist/Popover/Popover.d.ts.map +1 -1
  196. package/dist/Popover/Popover.js +1 -9
  197. package/dist/Popover/usePopover.d.ts +7 -41
  198. package/dist/Popover/usePopover.d.ts.map +1 -1
  199. package/dist/Popover/usePopover.js +40 -21
  200. package/dist/PowerSearch/PowerSearch.d.ts +8 -2
  201. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  202. package/dist/PowerSearch/PowerSearch.js +19 -6
  203. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +3 -1
  204. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  205. package/dist/PowerSearch/PowerSearchEditPopover.js +28 -6
  206. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -1
  207. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  208. package/dist/PowerSearch/PowerSearchValueEditor.js +110 -27
  209. package/dist/PowerSearch/types.d.ts +2 -0
  210. package/dist/PowerSearch/types.d.ts.map +1 -1
  211. package/dist/PowerSearch/usePowerSearchSource.d.ts +6 -1
  212. package/dist/PowerSearch/usePowerSearchSource.d.ts.map +1 -1
  213. package/dist/PowerSearch/usePowerSearchSource.js +14 -5
  214. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  215. package/dist/ProgressBar/ProgressBar.js +18 -5
  216. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  217. package/dist/Resizable/ResizeHandle.js +3 -2
  218. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  219. package/dist/SegmentedControl/SegmentedControl.js +3 -2
  220. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  221. package/dist/SelectableCard/SelectableCard.js +12 -3
  222. package/dist/Selector/Selector.d.ts +18 -1
  223. package/dist/Selector/Selector.d.ts.map +1 -1
  224. package/dist/Selector/Selector.js +91 -18
  225. package/dist/Selector/hooks.d.ts +7 -1
  226. package/dist/Selector/hooks.d.ts.map +1 -1
  227. package/dist/Selector/hooks.js +3 -2
  228. package/dist/SideNav/SideNav.d.ts.map +1 -1
  229. package/dist/SideNav/SideNav.js +4 -3
  230. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  231. package/dist/SideNav/SideNavHeading.js +8 -7
  232. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  233. package/dist/SideNav/SideNavItem.js +4 -3
  234. package/dist/Slider/Slider.d.ts.map +1 -1
  235. package/dist/Slider/Slider.js +37 -5
  236. package/dist/Spinner/Spinner.d.ts +3 -3
  237. package/dist/Spinner/Spinner.d.ts.map +1 -1
  238. package/dist/Spinner/Spinner.js +130 -78
  239. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  240. package/dist/StatusDot/StatusDot.js +6 -1
  241. package/dist/Stepper/Step.d.ts +140 -0
  242. package/dist/Stepper/Step.d.ts.map +1 -0
  243. package/dist/Stepper/Step.js +1045 -0
  244. package/dist/Stepper/StepStatus.d.ts +24 -0
  245. package/dist/Stepper/StepStatus.d.ts.map +1 -0
  246. package/dist/Stepper/StepStatus.js +1 -0
  247. package/dist/Stepper/Stepper.d.ts +93 -0
  248. package/dist/Stepper/Stepper.d.ts.map +1 -0
  249. package/dist/Stepper/Stepper.js +184 -0
  250. package/dist/Stepper/StepperContext.d.ts +41 -0
  251. package/dist/Stepper/StepperContext.d.ts.map +1 -0
  252. package/dist/Stepper/StepperContext.js +34 -0
  253. package/dist/Stepper/index.d.ts +8 -0
  254. package/dist/Stepper/index.d.ts.map +1 -0
  255. package/dist/Stepper/index.js +7 -0
  256. package/dist/Stepper/stepper.stylex.d.ts +15 -0
  257. package/dist/Stepper/stepper.stylex.d.ts.map +1 -0
  258. package/dist/Stepper/stepper.stylex.js +20 -0
  259. package/dist/Switch/Switch.d.ts.map +1 -1
  260. package/dist/Switch/Switch.js +8 -3
  261. package/dist/TabList/Tab.d.ts +15 -2
  262. package/dist/TabList/Tab.d.ts.map +1 -1
  263. package/dist/TabList/Tab.js +32 -7
  264. package/dist/TabList/TabList.d.ts +46 -7
  265. package/dist/TabList/TabList.d.ts.map +1 -1
  266. package/dist/TabList/TabList.js +353 -23
  267. package/dist/TabList/TabListContext.d.ts +11 -1
  268. package/dist/TabList/TabListContext.d.ts.map +1 -1
  269. package/dist/TabList/TabListContext.js +11 -2
  270. package/dist/TabList/TabMenu.d.ts.map +1 -1
  271. package/dist/TabList/TabMenu.js +3 -2
  272. package/dist/TabList/index.d.ts +2 -2
  273. package/dist/TabList/index.d.ts.map +1 -1
  274. package/dist/Table/BaseTable.d.ts.map +1 -1
  275. package/dist/Table/BaseTable.js +10 -2
  276. package/dist/Table/Table.d.ts.map +1 -1
  277. package/dist/Table/Table.js +3 -6
  278. package/dist/Table/TableRow.d.ts +16 -5
  279. package/dist/Table/TableRow.d.ts.map +1 -1
  280. package/dist/Table/TableRow.js +16 -5
  281. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  282. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  283. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
  284. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  285. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +54 -11
  286. package/dist/Table/plugins/pagination/useTablePagination.d.ts +3 -0
  287. package/dist/Table/plugins/pagination/useTablePagination.d.ts.map +1 -1
  288. package/dist/Table/plugins/pagination/useTablePagination.js +21 -4
  289. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  290. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +7 -2
  291. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts.map +1 -1
  292. package/dist/Table/plugins/rowStatus/useTableRowStatus.js +10 -3
  293. package/dist/Table/plugins/selection/useTableSelection.d.ts +16 -0
  294. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  295. package/dist/Table/plugins/selection/useTableSelection.js +43 -5
  296. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  297. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  298. package/dist/Table/types.d.ts +22 -4
  299. package/dist/Table/types.d.ts.map +1 -1
  300. package/dist/Table/useBaseTablePlugins.d.ts.map +1 -1
  301. package/dist/Table/useBaseTablePlugins.js +5 -0
  302. package/dist/Text/Text.d.ts.map +1 -1
  303. package/dist/Text/Text.js +6 -3
  304. package/dist/TextArea/TextArea.d.ts.map +1 -1
  305. package/dist/TextArea/TextArea.js +16 -10
  306. package/dist/TextInput/TextInput.d.ts.map +1 -1
  307. package/dist/TextInput/TextInput.js +3 -2
  308. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  309. package/dist/TimeInput/TimeInput.js +3 -2
  310. package/dist/Timestamp/Timestamp.d.ts +1 -1
  311. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  312. package/dist/Timestamp/Timestamp.js +15 -21
  313. package/dist/Toast/Toast.d.ts.map +1 -1
  314. package/dist/Toast/Toast.js +22 -7
  315. package/dist/Toast/ToastViewport.d.ts +1 -0
  316. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  317. package/dist/Toast/ToastViewport.js +71 -18
  318. package/dist/Token/Token.d.ts +1 -1
  319. package/dist/Token/Token.d.ts.map +1 -1
  320. package/dist/Token/Token.js +20 -9
  321. package/dist/Token/TokenLink.d.ts +1 -1
  322. package/dist/Token/TokenLink.d.ts.map +1 -1
  323. package/dist/Token/TokenLink.js +7 -4
  324. package/dist/Tokenizer/Tokenizer.d.ts +14 -1
  325. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  326. package/dist/Tokenizer/Tokenizer.js +33 -21
  327. package/dist/Tooltip/Tooltip.d.ts +5 -0
  328. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  329. package/dist/Tooltip/useTooltip.d.ts +5 -0
  330. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  331. package/dist/Tooltip/useTooltip.js +39 -24
  332. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  333. package/dist/TopNav/TopNavHeading.js +5 -4
  334. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  335. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  336. package/dist/TopNav/TopNavMegaMenu.js +31 -11
  337. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  338. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  339. package/dist/TopNav/TopNavMenu.js +22 -7
  340. package/dist/TreeList/TreeList.d.ts +1 -1
  341. package/dist/TreeList/TreeList.d.ts.map +1 -1
  342. package/dist/TreeList/TreeList.js +7 -2
  343. package/dist/Typeahead/BaseTypeahead.d.ts +35 -0
  344. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  345. package/dist/Typeahead/BaseTypeahead.js +119 -37
  346. package/dist/Typeahead/Typeahead.d.ts +8 -1
  347. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  348. package/dist/Typeahead/Typeahead.js +5 -2
  349. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  350. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  351. package/dist/Typeahead/TypeaheadItem.js +7 -2
  352. package/dist/astryx.css +113 -11
  353. package/dist/hooks/index.d.ts +1 -0
  354. package/dist/hooks/index.d.ts.map +1 -1
  355. package/dist/hooks/index.js +1 -0
  356. package/dist/hooks/useFocusTrap.d.ts +7 -4
  357. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  358. package/dist/hooks/useFocusTrap.js +60 -95
  359. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  360. package/dist/hooks/useHotkeys.js +3 -18
  361. package/dist/hooks/useMergedRefs.d.ts +18 -0
  362. package/dist/hooks/useMergedRefs.d.ts.map +1 -0
  363. package/dist/hooks/useMergedRefs.js +25 -0
  364. package/dist/index.d.ts +1 -0
  365. package/dist/index.d.ts.map +1 -1
  366. package/dist/index.js +1 -0
  367. package/dist/theme/Theme.d.ts.map +1 -1
  368. package/dist/theme/Theme.js +46 -10
  369. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  370. package/dist/theme/derivedVarRegistry.js +24 -4
  371. package/dist/theme/generateThemeRules.d.ts +21 -0
  372. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  373. package/dist/theme/generateThemeRules.js +26 -0
  374. package/dist/theme/syntax/tokens.d.ts +1 -1
  375. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  376. package/dist/theme/syntax/tokens.js +5 -2
  377. package/dist/utils/groupItems.d.ts +5 -1
  378. package/dist/utils/groupItems.d.ts.map +1 -1
  379. package/dist/utils/groupItems.js +9 -9
  380. package/dist/utils/index.d.ts +1 -1
  381. package/dist/utils/index.d.ts.map +1 -1
  382. package/dist/utils/isApplePlatform.d.ts +18 -0
  383. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  384. package/dist/utils/isApplePlatform.js +37 -0
  385. package/dist/utils/sharedResizeObserver.d.ts.map +1 -1
  386. package/dist/utils/sharedResizeObserver.js +10 -1
  387. package/dist/utils/timeParser.d.ts +1 -1
  388. package/dist/utils/timeParser.d.ts.map +1 -1
  389. package/dist/utils/timeParser.js +26 -12
  390. package/locales/af-ZA.json +6 -6
  391. package/locales/ar-SA.json +6 -6
  392. package/locales/ca-ES.json +5 -5
  393. package/locales/cs-CZ.json +6 -6
  394. package/locales/da-DK.json +6 -6
  395. package/locales/de-DE.json +6 -6
  396. package/locales/el-GR.json +6 -6
  397. package/locales/en.json +163 -11
  398. package/locales/es-ES.json +5 -5
  399. package/locales/fi-FI.json +6 -6
  400. package/locales/fr-FR.json +6 -6
  401. package/locales/he-IL.json +6 -6
  402. package/locales/hu-HU.json +6 -6
  403. package/locales/it-IT.json +6 -6
  404. package/locales/ja-JP.json +6 -6
  405. package/locales/ko-KR.json +6 -6
  406. package/locales/nl-NL.json +6 -6
  407. package/locales/no-NO.json +6 -6
  408. package/locales/pl-PL.json +6 -6
  409. package/locales/pseudo.json +114 -0
  410. package/locales/pt-BR.json +6 -6
  411. package/locales/pt-PT.json +6 -6
  412. package/locales/ro-RO.json +6 -6
  413. package/locales/ru-RU.json +6 -6
  414. package/locales/sr-SP.json +6 -6
  415. package/locales/sv-SE.json +6 -6
  416. package/locales/tr-TR.json +6 -6
  417. package/locales/uk-UA.json +6 -6
  418. package/locales/vi-VN.json +6 -6
  419. package/locales/zh-CN.json +6 -6
  420. package/locales/zh-TW.json +6 -6
  421. package/package.json +8 -3
  422. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  423. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  424. package/src/AlertDialog/AlertDialog.tsx +62 -20
  425. package/src/AppShell/AppShell.tsx +3 -2
  426. package/src/AspectRatio/AspectRatio.doc.mjs +6 -3
  427. package/src/AspectRatio/AspectRatio.test.tsx +57 -10
  428. package/src/AspectRatio/AspectRatio.tsx +40 -1
  429. package/src/Avatar/Avatar.doc.mjs +14 -3
  430. package/src/Avatar/Avatar.test.tsx +97 -0
  431. package/src/Avatar/Avatar.tsx +125 -52
  432. package/src/Avatar/index.ts +2 -2
  433. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  434. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  435. package/src/AvatarGroup/AvatarGroup.tsx +15 -6
  436. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  437. package/src/AvatarGroup/AvatarGroupOverflow.tsx +10 -4
  438. package/src/Banner/Banner.doc.mjs +22 -11
  439. package/src/Banner/Banner.test.tsx +177 -25
  440. package/src/Banner/Banner.tsx +93 -27
  441. package/src/BottomSheet/BottomSheet.test.tsx +123 -0
  442. package/src/BottomSheet/BottomSheet.tsx +17 -4
  443. package/src/BottomSheet/BottomSheetSwitcher.tsx +3 -2
  444. package/src/Breadcrumbs/BreadcrumbItem.tsx +9 -5
  445. package/src/Button/Button.doc.mjs +24 -1
  446. package/src/Button/Button.test.tsx +32 -4
  447. package/src/Button/Button.tsx +12 -5
  448. package/src/ButtonGroup/ButtonGroup.doc.mjs +10 -1
  449. package/src/ButtonGroup/ButtonGroup.test.tsx +404 -1
  450. package/src/ButtonGroup/ButtonGroup.tsx +23 -5
  451. package/src/Calendar/Calendar.doc.mjs +7 -6
  452. package/src/Calendar/Calendar.test.tsx +143 -0
  453. package/src/Calendar/Calendar.tsx +30 -26
  454. package/src/Calendar/getInitialFocusDate.test.ts +94 -0
  455. package/src/Calendar/getInitialFocusDate.ts +93 -0
  456. package/src/Calendar/styles.ts +49 -31
  457. package/src/Card/Card.doc.mjs +10 -7
  458. package/src/Card/Card.test.tsx +113 -19
  459. package/src/Card/Card.tsx +67 -89
  460. package/src/Card/index.ts +36 -1
  461. package/src/Carousel/Carousel.tsx +3 -2
  462. package/src/Chat/ChatComposerInput.tsx +5 -1
  463. package/src/Chat/ChatLayout.tsx +3 -2
  464. package/src/Chat/ChatMessageList.doc.mjs +9 -1
  465. package/src/Chat/ChatMessageList.test.tsx +46 -0
  466. package/src/Chat/ChatMessageList.tsx +28 -4
  467. package/src/Chat/ChatTokenizedText.tsx +17 -10
  468. package/src/Chat/useChatComposerTokens.ts +1 -1
  469. package/src/CheckboxInput/CheckboxInput.doc.mjs +2 -0
  470. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  471. package/src/CheckboxInput/CheckboxInput.tsx +8 -2
  472. package/src/ClickableCard/ClickableCard.tsx +3 -2
  473. package/src/CodeBlock/CodeBlock.doc.mjs +16 -4
  474. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  475. package/src/CodeBlock/CodeBlock.tsx +20 -4
  476. package/src/CodeBlock/highlightRanges.ts +1 -1
  477. package/src/CodeBlock/highlightStyles.ts +13 -13
  478. package/src/CommandPalette/CommandPaletteInput.tsx +3 -2
  479. package/src/CommandPalette/CommandPaletteItem.tsx +3 -2
  480. package/src/ComplexSelector/ComplexSelector.test.tsx +32 -0
  481. package/src/ComplexSelector/ComplexSelector.tsx +1 -3
  482. package/src/ContextMenu/ContextMenu.doc.mjs +5 -0
  483. package/src/ContextMenu/ContextMenu.tsx +4 -3
  484. package/src/DateInput/DateInput.doc.mjs +16 -0
  485. package/src/DateInput/DateInput.tsx +55 -2
  486. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  487. package/src/DateInput/NativeDateField.test.tsx +635 -0
  488. package/src/DateInput/NativeDateField.tsx +641 -0
  489. package/src/DateInput/TouchDateField.tsx +108 -24
  490. package/src/DateInput/index.ts +1 -0
  491. package/src/DateInput/nativeDateSegments.ts +127 -0
  492. package/src/DateRangeInput/DateRangeInput.doc.mjs +2 -2
  493. package/src/DateRangeInput/DateRangeInput.test.tsx +22 -0
  494. package/src/DateRangeInput/DateRangeInput.tsx +4 -2
  495. package/src/DateTimeInput/DateTimeInput.doc.mjs +18 -0
  496. package/src/DateTimeInput/DateTimeInput.test.tsx +1088 -0
  497. package/src/DateTimeInput/DateTimeInput.tsx +556 -24
  498. package/src/DateTimeInput/index.ts +1 -0
  499. package/src/Dialog/Dialog.doc.mjs +8 -3
  500. package/src/Dialog/Dialog.test.tsx +429 -2
  501. package/src/Dialog/Dialog.tsx +133 -58
  502. package/src/DropdownMenu/DropdownMenu.doc.mjs +6 -0
  503. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  504. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  505. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +8 -5
  506. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +8 -11
  507. package/src/Field/Field.doc.mjs +13 -2
  508. package/src/Field/FieldLabel.test.tsx +29 -0
  509. package/src/Field/FieldLabel.tsx +7 -0
  510. package/src/Field/InputClearButton.test.tsx +15 -1
  511. package/src/Field/InputClearButton.tsx +28 -4
  512. package/src/FileInput/FileInput.tsx +3 -2
  513. package/src/Heading/Heading.test.tsx +23 -1
  514. package/src/Heading/Heading.tsx +6 -3
  515. package/src/HoverCard/HoverCard.doc.mjs +13 -2
  516. package/src/HoverCard/HoverCard.test.tsx +154 -4
  517. package/src/HoverCard/HoverCard.tsx +143 -3
  518. package/src/HoverCard/useHoverCard.tsx +104 -33
  519. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  520. package/src/Indicator/Indicator.doc.mjs +2 -0
  521. package/src/Item/Item.tsx +5 -4
  522. package/src/Kbd/Kbd.tsx +2 -19
  523. package/src/Layer/LayerDepthContext.tsx +62 -0
  524. package/src/Layer/gestureCounter.ts +57 -0
  525. package/src/Layer/index.ts +9 -0
  526. package/src/Layer/layerDismissalFamilies.test.tsx +359 -0
  527. package/src/Layer/layerDismissalInvariants.test.tsx +417 -0
  528. package/src/Layer/layerStack.ts +362 -0
  529. package/src/Layer/useLayer.test.tsx +324 -15
  530. package/src/Layer/useLayer.tsx +164 -8
  531. package/src/Layer/useLayerDismissal.test.tsx +469 -0
  532. package/src/Layer/useLayerDismissal.ts +173 -0
  533. package/src/Layout/Layout.doc.mjs +2 -2
  534. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  535. package/src/Lightbox/Lightbox.doc.mjs +12 -0
  536. package/src/Lightbox/Lightbox.tsx +124 -102
  537. package/src/Link/Link.doc.mjs +39 -0
  538. package/src/List/List.test.tsx +38 -0
  539. package/src/List/List.tsx +8 -1
  540. package/src/Markdown/Markdown.doc.mjs +5 -0
  541. package/src/Markdown/Markdown.test.tsx +37 -0
  542. package/src/Markdown/Markdown.tsx +16 -5
  543. package/src/Markdown/incremental.test.ts +16 -2
  544. package/src/Markdown/index.ts +1 -0
  545. package/src/Markdown/parser.perf.test.ts +96 -1
  546. package/src/Markdown/parser.test.ts +178 -2
  547. package/src/Markdown/parser.ts +253 -32
  548. package/src/MetadataList/MetadataList.test.tsx +75 -2
  549. package/src/MetadataList/MetadataListItem.tsx +5 -2
  550. package/src/MobileNav/MobileNav.tsx +62 -36
  551. package/src/MoreMenu/MoreMenu.doc.mjs +7 -1
  552. package/src/MultiSelector/MultiSelector.doc.mjs +49 -1
  553. package/src/MultiSelector/MultiSelector.test.tsx +311 -0
  554. package/src/MultiSelector/MultiSelector.tsx +151 -15
  555. package/src/MultiSelector/hooks.ts +9 -2
  556. package/src/MultiSelector/index.ts +1 -0
  557. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  558. package/src/NavIcon/NavIcon.test.tsx +9 -0
  559. package/src/NavIcon/NavIcon.tsx +5 -1
  560. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  561. package/src/NavMenu/NavHeadingMenu.tsx +9 -5
  562. package/src/NumberInput/NumberInput.doc.mjs +31 -7
  563. package/src/NumberInput/NumberInput.test.tsx +436 -8
  564. package/src/NumberInput/NumberInput.tsx +62 -114
  565. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  566. package/src/NumberInput/numberInputCommit.ts +103 -0
  567. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  568. package/src/NumberInput/numberParser.test.ts +222 -0
  569. package/src/NumberInput/numberParser.ts +403 -0
  570. package/src/Outline/Outline.tsx +3 -2
  571. package/src/OverflowList/OverflowList.tsx +3 -2
  572. package/src/Overlay/Overlay.tsx +3 -2
  573. package/src/Pagination/Pagination.test.tsx +3 -2
  574. package/src/Popover/Popover.test.tsx +14 -0
  575. package/src/Popover/Popover.tsx +1 -9
  576. package/src/Popover/usePopover.tsx +57 -32
  577. package/src/PowerSearch/PowerSearch.doc.mjs +160 -28
  578. package/src/PowerSearch/PowerSearch.test.tsx +240 -1
  579. package/src/PowerSearch/PowerSearch.tsx +34 -5
  580. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +288 -0
  581. package/src/PowerSearch/PowerSearchEditPopover.tsx +29 -2
  582. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +111 -1
  583. package/src/PowerSearch/PowerSearchValueEditor.tsx +124 -10
  584. package/src/PowerSearch/types.ts +2 -0
  585. package/src/PowerSearch/usePowerSearchSource.test.ts +82 -2
  586. package/src/PowerSearch/usePowerSearchSource.ts +13 -3
  587. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  588. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  589. package/src/ProgressBar/ProgressBar.tsx +28 -8
  590. package/src/Resizable/ResizeHandle.tsx +3 -2
  591. package/src/SegmentedControl/SegmentedControl.tsx +3 -2
  592. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  593. package/src/SelectableCard/SelectableCard.tsx +19 -2
  594. package/src/Selector/Selector.doc.mjs +26 -1
  595. package/src/Selector/Selector.test.tsx +346 -1
  596. package/src/Selector/Selector.tsx +148 -21
  597. package/src/Selector/hooks.ts +17 -2
  598. package/src/SideNav/SideNav.doc.mjs +6 -6
  599. package/src/SideNav/SideNav.tsx +4 -2
  600. package/src/SideNav/SideNavHeading.tsx +12 -12
  601. package/src/SideNav/SideNavItem.tsx +4 -2
  602. package/src/Slider/Slider.test.tsx +106 -1
  603. package/src/Slider/Slider.tsx +55 -3
  604. package/src/Spinner/Spinner.test.tsx +147 -1
  605. package/src/Spinner/Spinner.tsx +120 -101
  606. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  607. package/src/StatusDot/StatusDot.test.tsx +9 -0
  608. package/src/StatusDot/StatusDot.tsx +7 -1
  609. package/src/Stepper/Step.doc.mjs +98 -0
  610. package/src/Stepper/Step.tsx +1638 -0
  611. package/src/Stepper/StepStatus.ts +26 -0
  612. package/src/Stepper/Stepper.doc.mjs +370 -0
  613. package/src/Stepper/Stepper.test.tsx +1024 -0
  614. package/src/Stepper/Stepper.tsx +258 -0
  615. package/src/Stepper/StepperContext.ts +71 -0
  616. package/src/Stepper/index.ts +18 -0
  617. package/src/Stepper/stepper.stylex.ts +19 -0
  618. package/src/Switch/Switch.doc.mjs +2 -0
  619. package/src/Switch/Switch.test.tsx +10 -0
  620. package/src/Switch/Switch.tsx +6 -2
  621. package/src/TabList/Tab.doc.mjs +13 -1
  622. package/src/TabList/Tab.tsx +67 -7
  623. package/src/TabList/TabList.doc.mjs +22 -6
  624. package/src/TabList/TabList.test.tsx +559 -0
  625. package/src/TabList/TabList.tsx +490 -22
  626. package/src/TabList/TabListContext.ts +13 -2
  627. package/src/TabList/TabMenu.tsx +3 -2
  628. package/src/TabList/index.ts +6 -2
  629. package/src/Table/BaseTable.tsx +12 -4
  630. package/src/Table/Table.doc.mjs +9 -2
  631. package/src/Table/Table.test.tsx +132 -14
  632. package/src/Table/Table.tsx +3 -8
  633. package/src/Table/TableBody.doc.mjs +40 -0
  634. package/src/Table/TableFooter.doc.mjs +40 -0
  635. package/src/Table/TableHeader.doc.mjs +40 -0
  636. package/src/Table/TableRow.tsx +16 -5
  637. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  638. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  639. package/src/Table/plugins/groupedRows/useTableGroupedRows-perf.test.tsx +112 -0
  640. package/src/Table/plugins/groupedRows/useTableGroupedRows.test.tsx +100 -0
  641. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +67 -12
  642. package/src/Table/plugins/pagination/useTablePagination.test.tsx +34 -4
  643. package/src/Table/plugins/pagination/useTablePagination.tsx +35 -3
  644. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +9 -2
  645. package/src/Table/plugins/rowStatus/useTableRowStatus.test.tsx +13 -7
  646. package/src/Table/plugins/rowStatus/useTableRowStatus.tsx +12 -3
  647. package/src/Table/plugins/selection/useTableSelection.test.tsx +138 -0
  648. package/src/Table/plugins/selection/useTableSelection.tsx +63 -7
  649. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  650. package/src/Table/types.ts +22 -4
  651. package/src/Table/useBaseTablePlugins.ts +5 -0
  652. package/src/Table/useTableGroupedRows.doc.mjs +5 -4
  653. package/src/Table/useTablePagination.doc.mjs +7 -0
  654. package/src/Table/useTableRowStatus.doc.mjs +1 -1
  655. package/src/Table/useTableSelection.doc.mjs +31 -0
  656. package/src/Text/Text.test.tsx +67 -1
  657. package/src/Text/Text.tsx +6 -3
  658. package/src/TextArea/TextArea.doc.mjs +12 -2
  659. package/src/TextArea/TextArea.test.tsx +11 -0
  660. package/src/TextArea/TextArea.tsx +37 -24
  661. package/src/TextInput/TextInput.doc.mjs +10 -0
  662. package/src/TextInput/TextInput.tsx +3 -2
  663. package/src/Thumbnail/Thumbnail.doc.mjs +1 -1
  664. package/src/TimeInput/TimeInput.tsx +2 -2
  665. package/src/Timestamp/Timestamp.test.tsx +58 -0
  666. package/src/Timestamp/Timestamp.tsx +12 -10
  667. package/src/Toast/Toast.doc.mjs +26 -12
  668. package/src/Toast/Toast.tsx +28 -4
  669. package/src/Toast/ToastViewport.test.tsx +536 -8
  670. package/src/Toast/ToastViewport.tsx +81 -12
  671. package/src/Token/Token.test.tsx +95 -0
  672. package/src/Token/Token.tsx +15 -10
  673. package/src/Token/TokenLink.tsx +14 -5
  674. package/src/Tokenizer/Tokenizer.doc.mjs +43 -3
  675. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  676. package/src/Tokenizer/Tokenizer.tsx +53 -24
  677. package/src/Toolbar/Toolbar.doc.mjs +5 -0
  678. package/src/Tooltip/Tooltip.doc.mjs +5 -0
  679. package/src/Tooltip/Tooltip.test.tsx +32 -0
  680. package/src/Tooltip/Tooltip.tsx +5 -0
  681. package/src/Tooltip/useTooltip.tsx +47 -24
  682. package/src/TopNav/TopNavHeading.tsx +5 -4
  683. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  684. package/src/TopNav/TopNavMegaMenu.tsx +47 -5
  685. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  686. package/src/TopNav/TopNavMenu.tsx +38 -7
  687. package/src/TreeList/TreeList.test.tsx +49 -0
  688. package/src/TreeList/TreeList.tsx +7 -2
  689. package/src/Typeahead/BaseTypeahead.doc.mjs +24 -0
  690. package/src/Typeahead/BaseTypeahead.tsx +181 -39
  691. package/src/Typeahead/Typeahead.doc.mjs +11 -0
  692. package/src/Typeahead/Typeahead.test.tsx +203 -0
  693. package/src/Typeahead/Typeahead.tsx +12 -2
  694. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  695. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  696. package/src/hooks/index.ts +2 -0
  697. package/src/hooks/useAnnounce.doc.mjs +96 -0
  698. package/src/hooks/useContainerReveal.doc.mjs +2 -2
  699. package/src/hooks/useDevWarning.doc.mjs +96 -0
  700. package/src/hooks/useFocusTrap.test.tsx +14 -0
  701. package/src/hooks/useFocusTrap.ts +62 -111
  702. package/src/hooks/useFocusTrapEscapeShim.test.tsx +165 -0
  703. package/src/hooks/useHotkeys.ts +3 -18
  704. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  705. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  706. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  707. package/src/hooks/useLongPress.doc.mjs +123 -0
  708. package/src/hooks/useMergedRefs.doc.mjs +79 -0
  709. package/src/hooks/useMergedRefs.test.tsx +62 -0
  710. package/src/hooks/useMergedRefs.ts +36 -0
  711. package/src/hooks/useTypeahead.doc.mjs +153 -0
  712. package/src/index.ts +1 -0
  713. package/src/raw-import.d.ts +14 -0
  714. package/src/theme/MediaTheme.doc.mjs +5 -5
  715. package/src/theme/Theme.test.tsx +104 -2
  716. package/src/theme/Theme.tsx +49 -14
  717. package/src/theme/defineTheme.test.ts +23 -0
  718. package/src/theme/derivedVarRegistry.test.ts +26 -3
  719. package/src/theme/derivedVarRegistry.ts +23 -4
  720. package/src/theme/generateThemeRules.test.ts +99 -1
  721. package/src/theme/generateThemeRules.ts +28 -0
  722. package/src/theme/syntax/tokens.ts +5 -2
  723. package/src/utils/groupItems.ts +12 -6
  724. package/src/utils/index.ts +1 -1
  725. package/src/utils/isApplePlatform.test.ts +61 -0
  726. package/src/utils/isApplePlatform.ts +37 -0
  727. package/src/utils/sharedResizeObserver.ts +10 -2
  728. package/src/utils/timeParser.test.ts +6 -1
  729. package/src/utils/timeParser.ts +35 -13
  730. package/src/__tests__/inputWidthContract.test.tsx +0 -69
@@ -132,7 +132,11 @@ export function TypeaheadItem<T extends SearchableItem>({
132
132
  icon,
133
133
  description,
134
134
  isDisabled = false,
135
+ group: _group,
135
136
  xstyle,
137
+ className,
138
+ style,
139
+ ...rest
136
140
  }: TypeaheadItemProps<T>) {
137
141
  // If item has a pre-rendered element, use it
138
142
  if (item.element) {
@@ -145,7 +149,10 @@ export function TypeaheadItem<T extends SearchableItem>({
145
149
  {...mergeProps(
146
150
  themeProps('typeahead-item'),
147
151
  stylex.props(styles.container, isDisabled && styles.disabled, xstyle),
148
- )}>
152
+ className,
153
+ style,
154
+ )}
155
+ {...rest}>
149
156
  {icon}
150
157
  <div {...stylex.props(styles.content)}>
151
158
  <span {...stylex.props(styles.label)}>{item.label}</span>
@@ -56,6 +56,8 @@ export type {UseTypeaheadOptions, UseTypeaheadReturn} from './useTypeahead';
56
56
 
57
57
  export {useMediaQuery} from './useMediaQuery';
58
58
 
59
+ export {useMergedRefs} from './useMergedRefs';
60
+
59
61
  export {useOverflow} from './useOverflow';
60
62
  export type {UseOverflowOptions, UseOverflowReturn} from './useOverflow';
61
63
 
@@ -0,0 +1,96 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('@astryxdesign/cli/authoring').HookDoc} */
4
+ export const docs = {
5
+ name: 'useAnnounce',
6
+ displayName: 'useAnnounce',
7
+ keywords: [
8
+ 'announce',
9
+ 'live region',
10
+ 'aria-live',
11
+ 'screen reader',
12
+ 'accessibility',
13
+ 'a11y',
14
+ 'status',
15
+ 'alert',
16
+ 'polite',
17
+ 'assertive',
18
+ 'visually hidden',
19
+ 'wcag',
20
+ ],
21
+ params: [],
22
+ returns: [
23
+ {
24
+ name: 'announce',
25
+ type: '(message: string, politeness?: "polite" | "assertive") => void',
26
+ description:
27
+ 'Speaks a message through the shared live region. Politeness defaults to "polite"; an empty message clears any lingering status instead of announcing.',
28
+ },
29
+ ],
30
+ usage: {
31
+ description:
32
+ 'Imperatively announces a message to screen readers through a visually-hidden live region. Use it for state that is only conveyed visually; search result counts, "no results", loading and saved confirmations, validation errors (WCAG 4.1.3 Status Messages). The polite and assertive regions are created empty on first use and stay mounted, which is what makes announcements reliable: most screen readers ignore a live region that is inserted together with its content. Each message is cleared a couple of seconds after it is announced so stale status does not linger in the accessibility tree.',
33
+ bestPractices: [
34
+ {
35
+ guidance: true,
36
+ description:
37
+ 'Reach for this instead of hand-rolling an aria-live div; a region rendered with its content usually does not announce at all.',
38
+ },
39
+ {
40
+ guidance: true,
41
+ description:
42
+ 'Keep "polite" for status and result counts; reserve "assertive" for errors and time-sensitive alerts, since it interrupts whatever the screen reader is saying.',
43
+ },
44
+ {
45
+ guidance: true,
46
+ description:
47
+ 'Announce the outcome, not the interaction; "12 results" rather than "search ran".',
48
+ },
49
+ {
50
+ guidance: false,
51
+ description:
52
+ 'Announce content that is already visible and correctly labeled in the DOM; that doubles up for screen reader users.',
53
+ },
54
+ ],
55
+ },
56
+ relatedComponents: ['VisuallyHidden', 'Toast'],
57
+ relatedHooks: ['useClipboard'],
58
+ importPath: '@astryxdesign/core/hooks',
59
+ category: 'accessibility',
60
+ };
61
+
62
+ /** @type {import('@astryxdesign/cli/authoring').HookTranslationDoc} */
63
+ export const docsDense = {
64
+ description:
65
+ 'Imperative screen-reader announcements via a visually-hidden live region. Polite + assertive regions created empty on first use + kept mounted, so announcements are reliable (most AT ignore a live region inserted together w/ its content). Messages auto-clear after ~2s.',
66
+ returnDescriptions: {
67
+ announce:
68
+ 'speaks message through shared live region. politeness defaults "polite"; empty message clears lingering status.',
69
+ },
70
+ usage: {
71
+ description:
72
+ 'Announces visual-only state to screen readers: result counts, "no results", loading / saved confirmations, validation errors (WCAG 4.1.3). Regions mounted empty up front, so updates announce; text auto-clears so stale status does not linger in a11y tree.',
73
+ bestPractices: [
74
+ {
75
+ guidance: true,
76
+ description:
77
+ 'Use instead of hand-rolled aria-live div; region rendered w/ its content usually does not announce.',
78
+ },
79
+ {
80
+ guidance: true,
81
+ description:
82
+ '"polite" for status / counts; "assertive" only for errors + time-sensitive alerts (it interrupts).',
83
+ },
84
+ {
85
+ guidance: true,
86
+ description:
87
+ 'Announce outcome, not interaction; "12 results", not "search ran".',
88
+ },
89
+ {
90
+ guidance: false,
91
+ description:
92
+ 'Announce content already visible + labeled in DOM; doubles up for AT users.',
93
+ },
94
+ ],
95
+ },
96
+ };
@@ -24,7 +24,7 @@ export const docs = {
24
24
  {
25
25
  name: 'getContainerProps',
26
26
  type: '(options?: ContainerRevealOptions) => {className?: string; style?: CSSProperties}',
27
- description: 'Spread onto the container whose hover/focus-within drives the reveal. Accepts hoverDelay (ms the pointer must dwell before the reveal starts — a hover-intent gate like Tooltip\'s and HoverCard\'s delay, so a cursor sweeping across a list leaves nothing painted behind it) and forceState ("active" | "inactive") to pin the trigger state when a caller owns it — a motion gate, a scroll, a row whose menu is open. "inactive" still yields to keyboard focus and coarse pointers.',
27
+ description: 'Spread onto the container whose hover/focus-within drives the reveal. Accepts hoverDelay (ms the pointer must dwell before the reveal starts: a hover-intent gate like Tooltip\'s and HoverCard\'s delay, so a cursor sweeping across a list leaves nothing painted behind it) and forceState ("active" | "inactive") to pin the trigger state when a caller owns it: a motion gate, a scroll, or a row whose menu is open. "inactive" still yields to keyboard focus and coarse pointers.',
28
28
  },
29
29
  {
30
30
  name: 'getContentRevealProps',
@@ -61,7 +61,7 @@ export const docsDense = {
61
61
  'options.isEnabled': 'when false hook is inert: no container styles, content getters return no styles, content always shown. Read every render, so it can flip after mount.',
62
62
  },
63
63
  returnDescriptions: {
64
- getContainerProps: 'spread onto container whose hover/focus-within drives reveal. Accepts hoverDelay (ms dwell before reveal starts — hover-intent gate like Tooltip / HoverCard delay) + forceState ("active" | "inactive") to pin trigger state when a caller owns it. "inactive" yields to keyboard focus + coarse pointers.',
64
+ getContainerProps: 'spread onto container whose hover/focus-within drives reveal. Accepts hoverDelay (ms dwell before reveal starts: hover-intent gate like Tooltip / HoverCard delay) + forceState ("active" | "inactive") to pin trigger state when a caller owns it. "inactive" yields to keyboard focus + coarse pointers.',
65
65
  getContentRevealProps: 'spread onto each revealed / concealed child. Accepts isRevealInverted (conceal-on-hover), isLayoutPreserved (reserve layout box while hidden) + forceVisibility ("shown" | "hidden") to pin this element regardless of container. "hidden" yields to focus.',
66
66
  },
67
67
  usage: {
@@ -0,0 +1,96 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /** @type {import('@astryxdesign/cli/authoring').HookDoc} */
4
+ export const docs = {
5
+ name: 'useDevWarning',
6
+ displayName: 'useDevWarning',
7
+ keywords: [
8
+ 'warning',
9
+ 'dev',
10
+ 'development',
11
+ 'console',
12
+ 'guardrail',
13
+ 'misuse',
14
+ 'invariant',
15
+ 'debug',
16
+ 'devWarn',
17
+ ],
18
+ params: [
19
+ {
20
+ name: 'component',
21
+ type: 'string',
22
+ description: 'Component or hook name, used as the message prefix.',
23
+ required: true,
24
+ },
25
+ {
26
+ name: 'message',
27
+ type: 'string',
28
+ description: 'What went wrong and how to fix it.',
29
+ required: true,
30
+ },
31
+ {
32
+ name: 'condition',
33
+ type: 'boolean',
34
+ description: 'Whether to warn.',
35
+ default: 'true',
36
+ },
37
+ ],
38
+ returns: [],
39
+ usage: {
40
+ description:
41
+ 'Fires a dev-only "Component: message" console warning once per mount while the condition holds. It is the render-safe way for a component to flag misuse: warning straight from the render body repeats on every render, and gating it with state adds a re-render, so this uses a ref and an effect instead. For a warning outside a component, use the imperative devWarn utility.',
42
+ bestPractices: [
43
+ {
44
+ guidance: true,
45
+ description:
46
+ 'Say what is wrong and what the builder should do instead; the message is the whole value of the warning.',
47
+ },
48
+ {
49
+ guidance: true,
50
+ description:
51
+ 'Warn about combinations the types cannot express, such as two mutually exclusive props being set together.',
52
+ },
53
+ {
54
+ guidance: false,
55
+ description:
56
+ 'Use it for anything a user could see or for runtime error handling; it is stripped from production builds.',
57
+ },
58
+ ],
59
+ },
60
+ relatedComponents: [],
61
+ relatedHooks: [],
62
+ importPath: '@astryxdesign/core/hooks',
63
+ category: 'utility',
64
+ };
65
+
66
+ /** @type {import('@astryxdesign/cli/authoring').HookTranslationDoc} */
67
+ export const docsDense = {
68
+ description:
69
+ 'Dev-only "Component: message" console warning, once per mount while condition holds. Ref + effect, so it never repeats per render nor causes a re-render. Outside a component, use the imperative devWarn utility.',
70
+ paramDescriptions: {
71
+ component: 'component / hook name, used as message prefix.',
72
+ message: 'what went wrong + how to fix it.',
73
+ condition: 'whether to warn.',
74
+ },
75
+ usage: {
76
+ description:
77
+ 'Render-safe guardrail warning from inside a component. Stripped from production builds.',
78
+ bestPractices: [
79
+ {
80
+ guidance: true,
81
+ description:
82
+ 'Say what is wrong + what to do instead; the message is the value.',
83
+ },
84
+ {
85
+ guidance: true,
86
+ description:
87
+ 'Warn about combinations types cannot express (mutually exclusive props set together).',
88
+ },
89
+ {
90
+ guidance: false,
91
+ description:
92
+ 'Use for user-visible problems / runtime error handling; it is dev-only.',
93
+ },
94
+ ],
95
+ },
96
+ };
@@ -208,6 +208,20 @@ describe('useFocusTrap tabbable model (infra-8)', () => {
208
208
  expect(target).toHaveFocus();
209
209
  expect(screen.getByTestId('outside')).not.toHaveFocus();
210
210
  });
211
+
212
+ it('leaves Tab alone when focus is outside a trap with no tabbable controls', () => {
213
+ render(
214
+ <Trap>
215
+ <div role="option" tabIndex={-1} data-testid="option">
216
+ Option
217
+ </div>
218
+ </Trap>,
219
+ );
220
+ const outside = screen.getByTestId('outside');
221
+ outside.focus();
222
+
223
+ expect(fireEvent.keyDown(outside, {key: 'Tab'})).toBe(true);
224
+ });
211
225
  });
212
226
 
213
227
  describe('FOCUSABLE_SELECTOR href matching', () => {
@@ -19,80 +19,26 @@
19
19
  import {useCallback, useEffect, useRef} from 'react';
20
20
 
21
21
  import {FOCUSABLE_SELECTOR} from './focusableSelector';
22
- import {isImeKeyEvent} from '../utils/ime';
22
+ import {useLayerDismissal} from '../Layer/useLayerDismissal';
23
23
 
24
- /**
25
- * Module-level stack of active focus-trap Escape handlers.
26
- *
27
- * Every active `useFocusTrap` used to attach its own document-level `keydown`
28
- * listener with no coordination, so a single Escape press closed *every* open
29
- * layer at once (e.g. a popover nested inside a Dialog closed both). Tracking
30
- * traps in a shared stack lets only the top-most trap respond to Escape.
31
- *
32
- * "Top-most" is resolved by DOM containment first, push order second. Push
33
- * order alone is not reliable: React runs child effects before parent
34
- * effects, so when an outer and an inner (DOM-nested) trap mount in the SAME
35
- * commit, the inner trap pushes first and the outer trap would wrongly win a
36
- * pure last-pushed comparison.
37
- */
38
- interface EscapeStackEntry {
39
- handler: () => void;
40
- getContainer: () => HTMLElement | null;
41
- }
42
-
43
- const escapeStack: EscapeStackEntry[] = [];
44
-
45
- function pushEscapeHandler(entry: EscapeStackEntry): void {
46
- escapeStack.push(entry);
47
- }
48
-
49
- function removeEscapeHandler(handler: () => void): void {
50
- for (let i = escapeStack.length - 1; i >= 0; i--) {
51
- if (escapeStack[i].handler === handler) {
52
- escapeStack.splice(i, 1);
53
- return;
54
- }
55
- }
56
- }
24
+ // Escape-dismissible focus traps currently mounted. This is the whole state
25
+ // behind `hasActiveFocusTrapEscape`, which predates the shared stack and must
26
+ // keep answering about focus traps alone — the stack now carries families that
27
+ // never trapped focus (tooltips, hover cards), and counting those would tell
28
+ // callers a trap is above them when none is.
29
+ let activeEscapeTrapCount = 0;
57
30
 
58
31
  /**
59
- * Resolve the top-most trap: walk the stack in push order, keeping the
60
- * deepest container by DOM containment. When a later entry's container
61
- * contains the current candidate's container, the candidate is nested inside
62
- * it and stays on top; otherwise the later push wins (containment for nested
63
- * traps, push order as the tiebreaker for unrelated ones).
64
- */
65
- function isTopEscapeHandler(handler: () => void): boolean {
66
- if (escapeStack.length === 0) {
67
- return false;
68
- }
69
- let top = escapeStack[0];
70
- for (let i = 1; i < escapeStack.length; i++) {
71
- const entry = escapeStack[i];
72
- const topContainer = top.getContainer();
73
- const entryContainer = entry.getContainer();
74
- if (
75
- topContainer != null &&
76
- entryContainer != null &&
77
- entryContainer !== topContainer &&
78
- entryContainer.contains(topContainer)
79
- ) {
80
- // The current top is nested inside this entry — it stays on top.
81
- continue;
82
- }
83
- top = entry;
84
- }
85
- return top.handler === handler;
86
- }
87
-
88
- /**
89
- * Whether any focus-trap Escape handler is currently active (i.e. a popover
90
- * layer is open). Other overlay primitives that manage their own Escape (e.g.
91
- * Dialog) can consult this to defer to a popover layered on top of them,
92
- * giving topmost-only dismissal until a full layer stack exists.
32
+ * Whether an Escape-dismissible focus trap is currently active — a Popover,
33
+ * menu or other trapped layer that would take an Escape press.
34
+ *
35
+ * @deprecated The focus trap no longer owns Escape coordination — every overlay
36
+ * family shares one stack (`useLayerDismissal`), which routes each press to
37
+ * the top-most layer. A layer that wants the same ordering should join the
38
+ * stack rather than ask whether a trap exists.
93
39
  */
94
40
  export function hasActiveFocusTrapEscape(): boolean {
95
- return escapeStack.length > 0;
41
+ return activeEscapeTrapCount > 0;
96
42
  }
97
43
 
98
44
  /**
@@ -243,6 +189,38 @@ export function useFocusTrap<T extends HTMLElement = HTMLElement>(
243
189
  // Track if focus change was triggered by keyboard (Tab key)
244
190
  const isKeyboardNavigationRef = useRef(false);
245
191
 
192
+ // Join the shared layer dismissal stack. The trap no longer listens for
193
+ // Escape itself: the stack owns one listener and routes each press to the
194
+ // top-most layer, so a popover inside a Dialog, a submenu inside a menu, and
195
+ // a modal inside a modal all peel off one at a time. A trap with no
196
+ // `onEscape` is not dismissible and stays off the stack, so a press flows
197
+ // past it to whatever is underneath.
198
+ // One expression drives both the stack registration and the deprecated
199
+ // `hasActiveFocusTrapEscape` count, so the two can never disagree about
200
+ // whether this trap is active.
201
+ const isEscapeTrap = isActive && onEscape != null;
202
+
203
+ useLayerDismissal({
204
+ isActive: isEscapeTrap,
205
+ onDismiss: () => {
206
+ onEscape?.();
207
+ },
208
+ // The trap renders nothing, so it cannot push a depth provider around its
209
+ // content; hand the stack the container instead so two DOM-nested traps
210
+ // still resolve in the right order.
211
+ getContainer: () => containerRef.current,
212
+ });
213
+
214
+ useEffect(() => {
215
+ if (!isEscapeTrap) {
216
+ return;
217
+ }
218
+ activeEscapeTrapCount += 1;
219
+ return () => {
220
+ activeEscapeTrapCount -= 1;
221
+ };
222
+ }, [isEscapeTrap]);
223
+
246
224
  /**
247
225
  * Focus the first focusable element.
248
226
  */
@@ -353,67 +331,43 @@ export function useFocusTrap<T extends HTMLElement = HTMLElement>(
353
331
  }, [isActive]);
354
332
 
355
333
  /**
356
- * Handle Tab key to wrap focus at boundaries, and Escape to close.
357
- * Also tracks that keyboard navigation is occurring.
334
+ * Handle Tab key to wrap focus at boundaries. Also tracks that keyboard
335
+ * navigation is occurring.
336
+ *
337
+ * No Escape here, and no IME guard: the shared stack owns the press, claims
338
+ * a composing Escape so no close request follows, and dismisses the trap
339
+ * through `onEscape` above. The trap renders no element of its own, so it
340
+ * has no `cancel` to answer either.
358
341
  */
359
342
  useEffect(() => {
360
343
  if (!isActive) {
361
344
  return;
362
345
  }
363
346
 
364
- // Register this trap on the shared Escape stack so only the top-most
365
- // active trap responds to Escape. A stable identity per active period is
366
- // enough — we push on activate and remove on cleanup. The container is
367
- // read lazily: the ref may not be attached yet at effect time, and the
368
- // stack resolves top-most by DOM containment at keydown time.
369
- const escapeHandler = () => {
370
- onEscape?.();
371
- };
372
- if (onEscape) {
373
- pushEscapeHandler({
374
- handler: escapeHandler,
375
- getContainer: () => containerRef.current,
376
- });
377
- }
378
-
379
347
  const handleKeyDown = (event: KeyboardEvent) => {
380
348
  const container = containerRef.current;
381
349
  if (!container) {
382
350
  return;
383
351
  }
384
352
 
385
- if (event.key === 'Escape' && onEscape) {
386
- // Ignore Escape that is cancelling an IME composition, already handled
387
- // by a nested handler, or not targeting the top-most trap.
388
- if (
389
- event.defaultPrevented ||
390
- isImeKeyEvent(event) ||
391
- !isTopEscapeHandler(escapeHandler)
392
- ) {
393
- return;
394
- }
395
- // Mark handled and stop propagation so an outer layer (e.g. a Dialog
396
- // hosting this popover) does not also dismiss on the same press.
397
- event.preventDefault();
398
- event.stopPropagation();
399
- onEscape();
400
- return;
401
- }
402
-
403
353
  if (event.key === 'Tab') {
404
354
  // Mark that keyboard navigation is happening
405
355
  isKeyboardNavigationRef.current = true;
406
356
 
407
357
  const focusable = getFocusableElements(container);
408
358
  if (focusable.length === 0) {
359
+ const active = document.activeElement;
360
+ if (!(active instanceof HTMLElement) || !container.contains(active)) {
361
+ // A layer can be open while focus legitimately sits outside it —
362
+ // a listbox popup anchored to its own input. Cancelling there
363
+ // would take Tab away from the whole page.
364
+ return;
365
+ }
409
366
  // There is nowhere to advance to. Keep focus on the current
410
367
  // programmatic target (for example a dialog panel with tabIndex=-1)
411
368
  // rather than allowing the browser to move into background content.
412
369
  event.preventDefault();
413
- const active = document.activeElement;
414
- if (active instanceof HTMLElement && container.contains(active)) {
415
- lastFocusRef.current = active;
416
- }
370
+ lastFocusRef.current = active;
417
371
  isKeyboardNavigationRef.current = false;
418
372
  return;
419
373
  }
@@ -441,9 +395,6 @@ export function useFocusTrap<T extends HTMLElement = HTMLElement>(
441
395
 
442
396
  return () => {
443
397
  document.removeEventListener('keydown', handleKeyDown);
444
- if (onEscape) {
445
- removeEscapeHandler(escapeHandler);
446
- }
447
398
  };
448
399
  }, [isActive, onEscape]);
449
400
 
@@ -0,0 +1,165 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file useFocusTrapEscapeShim.test.tsx
5
+ * @input Uses vitest, @testing-library/react, useFocusTrap, Dialog, Lightbox,
6
+ * MobileNav, Tooltip, Popover
7
+ * @output Tests that hasActiveFocusTrapEscape still means what it meant in
8
+ * 0.4.2 — an Escape-dismissible FOCUS TRAP is active, not "a layer is open"
9
+ * @position Testing; guards the deprecated public shim in useFocusTrap.ts
10
+ *
11
+ * The shim is public API. Its answer must not change now that Escape moved to
12
+ * the shared stack: `BottomSheetSwitcher` gates its own dismissal on it, so a
13
+ * shim that also counts tooltips, hover cards and dialogs tells the sheet a
14
+ * trap is above it when none is, and the sheet stops closing.
15
+ *
16
+ * SYNC: When useFocusTrap.ts changes, update tests to match new behavior
17
+ */
18
+
19
+ import {describe, it, expect, vi, beforeEach, afterEach} from 'vitest';
20
+ import {render} from '@testing-library/react';
21
+
22
+ import {hasActiveFocusTrapEscape, useFocusTrap} from './useFocusTrap';
23
+ import {Dialog} from '../Dialog/Dialog';
24
+ import {Lightbox} from '../Lightbox/Lightbox';
25
+ import {MobileNav} from '../MobileNav/MobileNav';
26
+ import {Popover} from '../Popover/Popover';
27
+ import {Tooltip} from '../Tooltip/Tooltip';
28
+ import {resetLayerStackForTests} from '../Layer/layerStack';
29
+
30
+ beforeEach(() => {
31
+ HTMLDialogElement.prototype.showModal = vi.fn(function (
32
+ this: HTMLDialogElement,
33
+ ) {
34
+ this.setAttribute('open', '');
35
+ });
36
+ HTMLDialogElement.prototype.close = vi.fn(function (this: HTMLDialogElement) {
37
+ this.removeAttribute('open');
38
+ });
39
+ });
40
+
41
+ afterEach(() => {
42
+ resetLayerStackForTests();
43
+ });
44
+
45
+ function Trap({
46
+ isActive = true,
47
+ hasEscape = true,
48
+ children,
49
+ }: {
50
+ isActive?: boolean;
51
+ hasEscape?: boolean;
52
+ children?: React.ReactNode;
53
+ }) {
54
+ const {containerRef} = useFocusTrap<HTMLDivElement>({
55
+ isActive,
56
+ onEscape: hasEscape ? () => {} : undefined,
57
+ });
58
+ return <div ref={containerRef}>{children}</div>;
59
+ }
60
+
61
+ describe('hasActiveFocusTrapEscape', () => {
62
+ it('is false with nothing mounted', () => {
63
+ expect(hasActiveFocusTrapEscape()).toBe(false);
64
+ });
65
+
66
+ it('is true for an active trap with an Escape handler', () => {
67
+ render(<Trap />);
68
+ expect(hasActiveFocusTrapEscape()).toBe(true);
69
+ });
70
+
71
+ it('is false for a trap with no Escape handler', () => {
72
+ render(<Trap hasEscape={false} />);
73
+ expect(hasActiveFocusTrapEscape()).toBe(false);
74
+ });
75
+
76
+ it('is false for an inactive trap', () => {
77
+ render(<Trap isActive={false} />);
78
+ expect(hasActiveFocusTrapEscape()).toBe(false);
79
+ });
80
+
81
+ it('is true for nested traps, and false again once both unmount', () => {
82
+ const {unmount} = render(
83
+ <Trap>
84
+ <Trap />
85
+ </Trap>,
86
+ );
87
+ expect(hasActiveFocusTrapEscape()).toBe(true);
88
+ unmount();
89
+ expect(hasActiveFocusTrapEscape()).toBe(false);
90
+ });
91
+
92
+ it('is true for an open Popover, which traps focus', () => {
93
+ render(
94
+ <Popover
95
+ isOpen={true}
96
+ onOpenChange={() => {}}
97
+ content="Popover body"
98
+ label="Popover">
99
+ <button type="button">Open</button>
100
+ </Popover>,
101
+ );
102
+ expect(hasActiveFocusTrapEscape()).toBe(true);
103
+ });
104
+
105
+ // The families below are all on the shared dismissal stack and none of them
106
+ // traps focus. Answering `true` for these is what broke the bottom sheet.
107
+ it('is false for an open Dialog', () => {
108
+ render(
109
+ <Dialog isOpen={true} onOpenChange={() => {}} aria-label="Dialog">
110
+ Body
111
+ </Dialog>,
112
+ );
113
+ expect(hasActiveFocusTrapEscape()).toBe(false);
114
+ });
115
+
116
+ it('is false for an open Lightbox', () => {
117
+ render(
118
+ <Lightbox
119
+ isOpen={true}
120
+ onOpenChange={() => {}}
121
+ media={{src: '/photo.jpg', alt: 'A photo'}}
122
+ />,
123
+ );
124
+ expect(hasActiveFocusTrapEscape()).toBe(false);
125
+ });
126
+
127
+ it('is false for an open MobileNav', () => {
128
+ render(
129
+ <MobileNav isOpen={true} onOpenChange={() => {}} label="Drawer">
130
+ <span>Nav</span>
131
+ </MobileNav>,
132
+ );
133
+ expect(hasActiveFocusTrapEscape()).toBe(false);
134
+ });
135
+
136
+ it('is false for a showing Tooltip', () => {
137
+ render(
138
+ <Tooltip content="Tip" isDefaultOpen={true}>
139
+ <button type="button">Trigger</button>
140
+ </Tooltip>,
141
+ );
142
+ expect(hasActiveFocusTrapEscape()).toBe(false);
143
+ });
144
+
145
+ it('is true for a Popover inside a Dialog, and false once the Popover closes', () => {
146
+ function Scene({isPopoverOpen}: {isPopoverOpen: boolean}) {
147
+ return (
148
+ <Dialog isOpen={true} onOpenChange={() => {}} aria-label="Dialog">
149
+ <Popover
150
+ isOpen={isPopoverOpen}
151
+ onOpenChange={() => {}}
152
+ content="Popover body"
153
+ label="Popover">
154
+ <button type="button">Open</button>
155
+ </Popover>
156
+ </Dialog>
157
+ );
158
+ }
159
+ const {rerender} = render(<Scene isPopoverOpen={true} />);
160
+ expect(hasActiveFocusTrapEscape()).toBe(true);
161
+
162
+ rerender(<Scene isPopoverOpen={false} />);
163
+ expect(hasActiveFocusTrapEscape()).toBe(false);
164
+ });
165
+ });