@astryxdesign/core 0.7.1 → 0.7.2-canary.020e1fe

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 (377) hide show
  1. package/dist/AppShell/AppShell.d.ts.map +1 -1
  2. package/dist/AppShell/AppShell.js +40 -1
  3. package/dist/AspectRatio/AspectRatio.d.ts +6 -8
  4. package/dist/AspectRatio/AspectRatio.d.ts.map +1 -1
  5. package/dist/AspectRatio/AspectRatio.js +44 -3
  6. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  7. package/dist/Breadcrumbs/BreadcrumbItem.js +5 -2
  8. package/dist/Button/Button.d.ts.map +1 -1
  9. package/dist/Button/Button.js +38 -14
  10. package/dist/CheckboxInput/CheckboxInput.d.ts +1 -1
  11. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  12. package/dist/CheckboxInput/CheckboxInput.js +3 -1
  13. package/dist/CheckboxList/CheckboxListItem.d.ts +9 -1
  14. package/dist/CheckboxList/CheckboxListItem.d.ts.map +1 -1
  15. package/dist/CheckboxList/CheckboxListItem.js +4 -2
  16. package/dist/CommandPalette/CommandPaletteInput.d.ts +1 -1
  17. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  18. package/dist/CommandPalette/CommandPaletteInput.js +37 -5
  19. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  20. package/dist/ContextMenu/ContextMenu.js +5 -2
  21. package/dist/Dialog/Dialog.d.ts.map +1 -1
  22. package/dist/Dialog/Dialog.js +20 -8
  23. package/dist/Drawer/Drawer.d.ts +191 -0
  24. package/dist/Drawer/Drawer.d.ts.map +1 -0
  25. package/dist/Drawer/Drawer.js +382 -0
  26. package/dist/Drawer/DrawerHeader.d.ts +85 -0
  27. package/dist/Drawer/DrawerHeader.d.ts.map +1 -0
  28. package/dist/Drawer/DrawerHeader.js +134 -0
  29. package/dist/Drawer/index.d.ts +11 -0
  30. package/dist/Drawer/index.d.ts.map +1 -0
  31. package/dist/Drawer/index.js +11 -0
  32. package/dist/Drawer/useDrawerDialogPresence.d.ts +42 -0
  33. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -0
  34. package/dist/Drawer/useDrawerDialogPresence.js +236 -0
  35. package/dist/DropdownMenu/DropdownMenu.d.ts +1 -1
  36. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  37. package/dist/DropdownMenu/DropdownMenu.js +83 -11
  38. package/dist/DropdownMenu/DropdownMenuContext.d.ts +17 -0
  39. package/dist/DropdownMenu/DropdownMenuContext.d.ts.map +1 -1
  40. package/dist/DropdownMenu/DropdownMenuContext.js +21 -0
  41. package/dist/DropdownMenu/DropdownMenuDivider.d.ts +5 -3
  42. package/dist/DropdownMenu/DropdownMenuDivider.d.ts.map +1 -1
  43. package/dist/DropdownMenu/DropdownMenuDivider.js +7 -3
  44. package/dist/DropdownMenu/DropdownMenuGroup.d.ts +6 -4
  45. package/dist/DropdownMenu/DropdownMenuGroup.d.ts.map +1 -1
  46. package/dist/DropdownMenu/DropdownMenuGroup.js +4 -3
  47. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  48. package/dist/DropdownMenu/DropdownMenuSubMenu.js +19 -8
  49. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +24 -0
  50. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -0
  51. package/dist/DropdownMenu/lazyMenuBottomSheet.js +46 -0
  52. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  53. package/dist/EmptyState/EmptyState.js +4 -10
  54. package/dist/Field/Field.d.ts +1 -1
  55. package/dist/Field/Field.d.ts.map +1 -1
  56. package/dist/Field/Field.js +8 -4
  57. package/dist/Grid/GridSpan.d.ts.map +1 -1
  58. package/dist/Grid/GridSpan.js +1 -0
  59. package/dist/Heading/Heading.d.ts.map +1 -1
  60. package/dist/Heading/Heading.js +4 -2
  61. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  62. package/dist/HoverCard/useHoverCard.js +10 -2
  63. package/dist/Item/Item.d.ts +6 -2
  64. package/dist/Item/Item.d.ts.map +1 -1
  65. package/dist/Item/Item.js +19 -4
  66. package/dist/Layer/layerViewportInset.stylex.d.ts +6 -2
  67. package/dist/Layer/layerViewportInset.stylex.d.ts.map +1 -1
  68. package/dist/Layer/layerViewportInset.stylex.js +6 -2
  69. package/dist/Layer/useLayer.d.ts.map +1 -1
  70. package/dist/Layer/useLayer.js +13 -7
  71. package/dist/Layer/useLayerDismissal.d.ts +1 -1
  72. package/dist/Layer/useLayerDismissal.js +1 -1
  73. package/dist/Layout/container.stylex.d.ts +5 -5
  74. package/dist/Layout/container.stylex.js +4 -4
  75. package/dist/List/List.d.ts +46 -19
  76. package/dist/List/List.d.ts.map +1 -1
  77. package/dist/List/List.js +28 -10
  78. package/dist/List/ListContext.d.ts +8 -3
  79. package/dist/List/ListContext.d.ts.map +1 -1
  80. package/dist/List/ListContext.js +7 -2
  81. package/dist/List/ListItem.d.ts +13 -5
  82. package/dist/List/ListItem.d.ts.map +1 -1
  83. package/dist/List/ListItem.js +21 -8
  84. package/dist/List/index.d.ts +1 -1
  85. package/dist/List/index.d.ts.map +1 -1
  86. package/dist/Markdown/Markdown.d.ts.map +1 -1
  87. package/dist/Markdown/Markdown.js +8 -1
  88. package/dist/Markdown/plugins/frontmatter.d.ts.map +1 -1
  89. package/dist/Markdown/plugins/frontmatter.js +7 -3
  90. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  91. package/dist/MetadataList/MetadataList.js +5 -1
  92. package/dist/MetadataList/MetadataListContext.d.ts +1 -1
  93. package/dist/MetadataList/MetadataListContext.d.ts.map +1 -1
  94. package/dist/MobileNav/MobileNav.d.ts +9 -0
  95. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  96. package/dist/MobileNav/MobileNav.js +30 -3
  97. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  98. package/dist/MultiSelector/MultiSelector.js +22 -8
  99. package/dist/MultiSelector/OptionActions.a11y.chromium.spec.js +100 -2
  100. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  101. package/dist/MultiSelector/hooks.js +3 -1
  102. package/dist/Pagination/Pagination.d.ts +8 -5
  103. package/dist/Pagination/Pagination.d.ts.map +1 -1
  104. package/dist/Pagination/Pagination.js +21 -8
  105. package/dist/Popover/Popover.js +2 -2
  106. package/dist/PowerSearch/PowerSearch.js +1 -1
  107. package/dist/RadioList/RadioList.d.ts +1 -1
  108. package/dist/RadioList/RadioList.d.ts.map +1 -1
  109. package/dist/RadioList/RadioList.js +6 -2
  110. package/dist/RadioList/RadioListItem.d.ts +9 -1
  111. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  112. package/dist/RadioList/RadioListItem.js +2 -0
  113. package/dist/Selector/hooks.d.ts.map +1 -1
  114. package/dist/Selector/hooks.js +6 -2
  115. package/dist/SideNav/SideNavItem.d.ts +8 -1
  116. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  117. package/dist/SideNav/SideNavItem.js +71 -9
  118. package/dist/Switch/Switch.d.ts +1 -1
  119. package/dist/Switch/Switch.d.ts.map +1 -1
  120. package/dist/Switch/Switch.js +13 -1
  121. package/dist/TabList/TabMenu.d.ts +2 -2
  122. package/dist/TabList/TabMenu.d.ts.map +1 -1
  123. package/dist/TabList/TabMenu.js +6 -3
  124. package/dist/Text/Text.d.ts.map +1 -1
  125. package/dist/Text/Text.js +4 -2
  126. package/dist/Text/useTruncation.d.ts +7 -5
  127. package/dist/Text/useTruncation.d.ts.map +1 -1
  128. package/dist/Text/useTruncation.js +16 -5
  129. package/dist/ToggleButton/ToggleButton.d.ts +3 -2
  130. package/dist/ToggleButton/ToggleButton.d.ts.map +1 -1
  131. package/dist/ToggleButton/ToggleButton.js +12 -1
  132. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  133. package/dist/Tooltip/useTooltip.js +11 -0
  134. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  135. package/dist/TopNav/TopNavMegaMenu.js +3 -3
  136. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  137. package/dist/TopNav/TopNavMenu.js +3 -3
  138. package/dist/TreeList/TreeList.d.ts.map +1 -1
  139. package/dist/TreeList/TreeList.js +1 -0
  140. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  141. package/dist/TreeList/TreeListBranches.js +2 -2
  142. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  143. package/dist/TreeList/TreeListItem.js +57 -9
  144. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  145. package/dist/Typeahead/BaseTypeahead.js +26 -0
  146. package/dist/astryx.css +47 -13
  147. package/dist/hooks/useEntryAnimation.d.ts +2 -1
  148. package/dist/hooks/useEntryAnimation.d.ts.map +1 -1
  149. package/dist/hooks/useEntryAnimation.js +14 -12
  150. package/dist/hooks/useIsHydrating.d.ts +6 -0
  151. package/dist/hooks/useIsHydrating.d.ts.map +1 -0
  152. package/dist/hooks/useIsHydrating.js +30 -0
  153. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  154. package/dist/hooks/useMenuHover.js +18 -13
  155. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  156. package/dist/i18n/generated-locales/en.generated.js +112 -1
  157. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  158. package/dist/i18n/generated-locales/pseudo.generated.js +112 -1
  159. package/dist/index.d.ts +1 -0
  160. package/dist/index.d.ts.map +1 -1
  161. package/dist/index.js +1 -0
  162. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  163. package/dist/theme/derivedVarRegistry.js +0 -3
  164. package/dist/utils/focusOutline.stylex.d.ts +4 -0
  165. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  166. package/dist/utils/focusOutline.stylex.js +4 -0
  167. package/dist/utils/plainDate.d.ts.map +1 -1
  168. package/dist/utils/plainDate.js +15 -9
  169. package/dist/utils/sharedMutationObserver.d.ts +21 -0
  170. package/dist/utils/sharedMutationObserver.d.ts.map +1 -0
  171. package/dist/utils/sharedMutationObserver.js +69 -0
  172. package/locales/en.json +444 -0
  173. package/locales/pseudo.json +333 -0
  174. package/package.json +9 -4
  175. package/scripts/agent-doc-state.mjs +38 -0
  176. package/scripts/postinstall.mjs +1 -1
  177. package/src/AppShell/AppShell.tsx +45 -1
  178. package/src/AspectRatio/AspectRatio.test.tsx +44 -43
  179. package/src/AspectRatio/AspectRatio.tsx +38 -18
  180. package/src/AspectRatio/__tests__/AspectRatioFitLayers.a11y.browser.spec.ts +157 -0
  181. package/src/Avatar/Avatar.doc.mjs +5 -3
  182. package/src/AvatarGroup/AvatarGroup.doc.mjs +3 -2
  183. package/src/Breadcrumbs/BreadcrumbItem.tsx +4 -1
  184. package/src/Breadcrumbs/Breadcrumbs.test.tsx +30 -1
  185. package/src/Button/Button.doc.mjs +2 -2
  186. package/src/Button/Button.test.tsx +155 -9
  187. package/src/Button/Button.tsx +39 -16
  188. package/src/Button/__tests__/Button.a11y.known-failures.ts +1 -62
  189. package/src/Button/__tests__/Button.a11y.states.ts +0 -10
  190. package/src/Card/Card.doc.mjs +1 -1
  191. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +3 -1
  192. package/src/CheckboxInput/CheckboxInput.test.tsx +34 -0
  193. package/src/CheckboxInput/CheckboxInput.tsx +3 -1
  194. package/src/CheckboxList/CheckboxList.test.tsx +22 -0
  195. package/src/CheckboxList/CheckboxListItem.doc.mjs +16 -0
  196. package/src/CheckboxList/CheckboxListItem.tsx +10 -0
  197. package/src/Code/Code.doc.mjs +1 -0
  198. package/src/CommandPalette/CommandPalette.doc.mjs +2 -0
  199. package/src/CommandPalette/CommandPaletteInput.test.tsx +53 -4
  200. package/src/CommandPalette/CommandPaletteInput.tsx +33 -3
  201. package/src/CommandPalette/__tests__/CommandPaletteInputAudit.a11y.chromium.spec.ts +335 -0
  202. package/src/CommandPalette/__tests__/CommandPaletteItemAudit.a11y.chromium.spec.ts +292 -0
  203. package/src/ContextMenu/ContextMenu.doc.mjs +2 -3
  204. package/src/ContextMenu/ContextMenu.tsx +4 -1
  205. package/src/ContextMenu/__tests__/ContextMenuAudit.a11y.chromium.spec.ts +438 -0
  206. package/src/Dialog/Dialog.test.tsx +46 -0
  207. package/src/Dialog/Dialog.tsx +20 -7
  208. package/src/Dialog/__tests__/Dialog.a11y.known-failures.ts +0 -14
  209. package/src/Drawer/Drawer.doc.mjs +473 -0
  210. package/src/Drawer/Drawer.spec.md +357 -0
  211. package/src/Drawer/Drawer.test.tsx +1300 -0
  212. package/src/Drawer/Drawer.tsx +613 -0
  213. package/src/Drawer/DrawerDirection.test.tsx +127 -0
  214. package/src/Drawer/DrawerHeader.doc.mjs +293 -0
  215. package/src/Drawer/DrawerHeader.test.tsx +102 -0
  216. package/src/Drawer/DrawerHeader.tsx +235 -0
  217. package/src/Drawer/__tests__/DrawerAudit.a11y.chromium.spec.ts +401 -0
  218. package/src/Drawer/__tests__/DrawerHeaderAudit.a11y.chromium.spec.ts +297 -0
  219. package/src/Drawer/index.ts +13 -0
  220. package/src/Drawer/useDrawerDialogPresence.ts +284 -0
  221. package/src/DropdownMenu/DropdownMenu.ssr.test.tsx +57 -0
  222. package/src/DropdownMenu/DropdownMenu.test.tsx +79 -18
  223. package/src/DropdownMenu/DropdownMenu.tsx +83 -12
  224. package/src/DropdownMenu/DropdownMenuContext.tsx +24 -0
  225. package/src/DropdownMenu/DropdownMenuDivider.doc.mjs +2 -2
  226. package/src/DropdownMenu/DropdownMenuDivider.spec.md +192 -0
  227. package/src/DropdownMenu/DropdownMenuDivider.tsx +9 -5
  228. package/src/DropdownMenu/DropdownMenuGroup.doc.mjs +169 -10
  229. package/src/DropdownMenu/DropdownMenuGroup.tsx +6 -4
  230. package/src/DropdownMenu/DropdownMenuLazySheet.test.tsx +126 -0
  231. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +185 -0
  232. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +19 -5
  233. package/src/DropdownMenu/__tests__/DropdownMenuDividerAudit.a11y.chromium.spec.ts +280 -0
  234. package/src/DropdownMenu/__tests__/DropdownMenuGroupAudit.a11y.chromium.spec.ts +334 -0
  235. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +145 -0
  236. package/src/DropdownMenu/__tests__/Menu.a11y.known-failures.ts +26 -0
  237. package/src/DropdownMenu/__tests__/Menu.a11y.renders.tsx +65 -0
  238. package/src/DropdownMenu/__tests__/Menu.a11y.states.ts +138 -0
  239. package/src/DropdownMenu/__tests__/Menu.a11y.test.tsx +136 -0
  240. package/src/DropdownMenu/__tests__/warmMenuBottomSheet.tsx +43 -0
  241. package/src/DropdownMenu/lazyMenuBottomSheet.ts +71 -0
  242. package/src/EmptyState/EmptyState.doc.mjs +3 -2
  243. package/src/EmptyState/EmptyState.spec.md +189 -0
  244. package/src/EmptyState/EmptyState.test.tsx +74 -3
  245. package/src/EmptyState/EmptyState.tsx +4 -8
  246. package/src/Field/Field.doc.mjs +14 -8
  247. package/src/Field/Field.spec.md +217 -0
  248. package/src/Field/Field.test.tsx +60 -2
  249. package/src/Field/Field.tsx +17 -8
  250. package/src/Field/FieldLabel.doc.mjs +133 -26
  251. package/src/Field/FieldLabel.spec.md +172 -0
  252. package/src/Field/__tests__/FieldLabelAudit.a11y.chromium.spec.ts +296 -0
  253. package/src/Grid/GridSpan.tsx +3 -0
  254. package/src/Heading/Heading.test.tsx +57 -0
  255. package/src/Heading/Heading.tsx +6 -2
  256. package/src/HoverCard/HoverCard.test.tsx +58 -0
  257. package/src/HoverCard/useHoverCard.tsx +10 -2
  258. package/src/Icon/Icon.doc.mjs +36 -0
  259. package/src/IconButton/IconButton.doc.mjs +2 -2
  260. package/src/IconButton/IconButton.test.tsx +3 -1
  261. package/src/Item/Item.doc.mjs +12 -8
  262. package/src/Item/Item.spec.md +226 -0
  263. package/src/Item/Item.test.tsx +61 -0
  264. package/src/Item/Item.tsx +40 -4
  265. package/src/Layer/layerViewportInset.source-build.test.mjs +90 -0
  266. package/src/Layer/layerViewportInset.stylex.ts +6 -2
  267. package/src/Layer/layerViewportInset.test.ts +1 -0
  268. package/src/Layer/useLayer.tsx +24 -13
  269. package/src/Layer/useLayerDismissal.ts +1 -1
  270. package/src/Layout/LayoutHeader.doc.mjs +5 -0
  271. package/src/Layout/container.stylex.ts +6 -6
  272. package/src/List/List.doc.mjs +14 -1
  273. package/src/List/List.spec.md +129 -77
  274. package/src/List/List.test.tsx +163 -94
  275. package/src/List/List.tsx +74 -18
  276. package/src/List/ListContext.tsx +9 -3
  277. package/src/List/ListItem.doc.mjs +24 -5
  278. package/src/List/ListItem.tsx +56 -27
  279. package/src/List/index.ts +1 -1
  280. package/src/Markdown/Markdown.tsx +14 -1
  281. package/src/Markdown/plugins/frontmatter.test.tsx +25 -0
  282. package/src/Markdown/plugins/frontmatter.ts +7 -3
  283. package/src/MetadataList/MetadataList.doc.mjs +3 -3
  284. package/src/MetadataList/MetadataList.test.tsx +38 -0
  285. package/src/MetadataList/MetadataList.tsx +8 -1
  286. package/src/MetadataList/MetadataListContext.tsx +1 -1
  287. package/src/MobileNav/MobileNav.tsx +30 -3
  288. package/src/MobileNav/MobileNavCloseEdgeCases.test.tsx +173 -15
  289. package/src/MoreMenu/MoreMenu.test.tsx +5 -1
  290. package/src/MultiSelector/MultiSelector.test.tsx +159 -0
  291. package/src/MultiSelector/MultiSelector.tsx +40 -7
  292. package/src/MultiSelector/OptionActions.a11y.chromium.spec.ts +112 -2
  293. package/src/MultiSelector/hooks.ts +3 -1
  294. package/src/MultiSelector/useMultiCombobox.doc.mjs +267 -0
  295. package/src/Pagination/Pagination.doc.mjs +7 -7
  296. package/src/Pagination/Pagination.spec.md +9 -9
  297. package/src/Pagination/Pagination.test.tsx +242 -0
  298. package/src/Pagination/Pagination.tsx +27 -11
  299. package/src/Popover/Popover.test.tsx +2 -2
  300. package/src/Popover/Popover.tsx +4 -4
  301. package/src/PowerSearch/PowerSearch.test.tsx +85 -0
  302. package/src/PowerSearch/PowerSearch.tsx +2 -2
  303. package/src/ProgressBar/ProgressBar.doc.mjs +1 -0
  304. package/src/RadioList/RadioList.fr10.test.tsx +45 -2
  305. package/src/RadioList/RadioList.test.tsx +22 -0
  306. package/src/RadioList/RadioList.tsx +4 -1
  307. package/src/RadioList/RadioListItem.doc.mjs +16 -0
  308. package/src/RadioList/RadioListItem.tsx +10 -1
  309. package/src/Resizable/useResizable.doc.mjs +2 -0
  310. package/src/ScrollableArea/ScrollableArea.doc.mjs +1 -1
  311. package/src/Selector/hooks.ts +6 -2
  312. package/src/Selector/useCombobox.doc.mjs +237 -0
  313. package/src/SideNav/SideNav.spec.md +227 -0
  314. package/src/SideNav/SideNav.test.tsx +179 -0
  315. package/src/SideNav/SideNavItem.doc.mjs +2 -2
  316. package/src/SideNav/SideNavItem.tsx +96 -17
  317. package/src/Slider/Slider.spec.md +39 -18
  318. package/src/Spinner/Spinner.doc.mjs +1 -1
  319. package/src/Switch/Switch.test.tsx +49 -0
  320. package/src/Switch/Switch.tsx +11 -0
  321. package/src/TabList/TabList.spec.md +57 -44
  322. package/src/TabList/TabList.test.tsx +67 -0
  323. package/src/TabList/TabMenu.doc.mjs +4 -3
  324. package/src/TabList/TabMenu.tsx +7 -4
  325. package/src/Text/Text.test.tsx +57 -0
  326. package/src/Text/Text.tsx +6 -2
  327. package/src/Text/useTruncation.test.tsx +69 -0
  328. package/src/Text/useTruncation.ts +16 -5
  329. package/src/TimeInput/TimeInput.fr10.test.tsx +15 -0
  330. package/src/Timestamp/Timestamp.doc.mjs +1 -1
  331. package/src/ToggleButton/ToggleButton.test.tsx +95 -0
  332. package/src/ToggleButton/ToggleButton.tsx +12 -1
  333. package/src/ToggleButton/ToggleButtonGroup.doc.mjs +4 -0
  334. package/src/Tokenizer/Tokenizer.test.tsx +54 -1
  335. package/src/Toolbar/Toolbar.test.tsx +0 -8
  336. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +163 -0
  337. package/src/Toolbar/__tests__/Toolbar.a11y.renders.tsx +63 -0
  338. package/src/Toolbar/__tests__/Toolbar.a11y.states.ts +142 -0
  339. package/src/Toolbar/__tests__/Toolbar.a11y.test.tsx +126 -0
  340. package/src/Tooltip/Tooltip.test.tsx +31 -0
  341. package/src/Tooltip/useTooltip.test.tsx +13 -0
  342. package/src/Tooltip/useTooltip.tsx +11 -0
  343. package/src/TopNav/TopNavMegaMenu.test.tsx +22 -0
  344. package/src/TopNav/TopNavMegaMenu.tsx +7 -3
  345. package/src/TopNav/TopNavMenu.test.tsx +19 -0
  346. package/src/TopNav/TopNavMenu.tsx +11 -3
  347. package/src/TreeList/TreeList.doc.mjs +1 -0
  348. package/src/TreeList/TreeList.spec.md +29 -17
  349. package/src/TreeList/TreeList.test.tsx +327 -6
  350. package/src/TreeList/TreeList.tsx +5 -1
  351. package/src/TreeList/TreeListBranches.tsx +6 -0
  352. package/src/TreeList/TreeListItem.tsx +88 -13
  353. package/src/Typeahead/BaseTypeahead.tsx +26 -0
  354. package/src/Typeahead/Typeahead.test.tsx +260 -2
  355. package/src/docPropLiterals.test.ts +36 -10
  356. package/src/hooks/useEntryAnimation.doc.mjs +4 -4
  357. package/src/hooks/useEntryAnimation.ssr.test.tsx +143 -0
  358. package/src/hooks/useEntryAnimation.ts +15 -16
  359. package/src/hooks/useIsHydrating.test.tsx +70 -0
  360. package/src/hooks/useIsHydrating.ts +31 -0
  361. package/src/hooks/useMenuHover.ts +18 -13
  362. package/src/i18n/InternationalizationProvider.doc.mjs +8 -0
  363. package/src/i18n/InternationalizationProvider.spec.md +252 -0
  364. package/src/i18n/__tests__/InternationalizationProvider.test.tsx +128 -0
  365. package/src/i18n/generated-locales/en.generated.ts +121 -0
  366. package/src/i18n/generated-locales/pseudo.generated.ts +121 -0
  367. package/src/i18n/useTranslator.test.tsx +37 -0
  368. package/src/index.ts +1 -0
  369. package/src/postinstall.test.mjs +46 -0
  370. package/src/reset.css +0 -29
  371. package/src/theme/derivedVarRegistry.test.ts +7 -3
  372. package/src/theme/derivedVarRegistry.ts +0 -3
  373. package/src/utils/focusOutline.stylex.ts +4 -0
  374. package/src/utils/plainDate.test.ts +37 -1
  375. package/src/utils/plainDate.ts +15 -5
  376. package/src/utils/sharedMutationObserver.test.ts +53 -0
  377. package/src/utils/sharedMutationObserver.ts +78 -0
@@ -395,6 +395,63 @@
395
395
  "@astryx.listInput.announceAlreadyAtBoundary": {
396
396
  "defaultMessage": "⟦Ţĥíš {itemName} íš àłřéàðý {boundary, select, first {first} last {last} other {}}.⟧"
397
397
  },
398
+ "@astryx.diffViewer.label": {
399
+ "defaultMessage": "⟦Ð탃⟧"
400
+ },
401
+ "@astryx.diffViewer.renamedPath": {
402
+ "defaultMessage": "⟦{oldPath} → {newPath}⟧"
403
+ },
404
+ "@astryx.diffViewer.statusAdded": {
405
+ "defaultMessage": "⟦Àððéð⟧"
406
+ },
407
+ "@astryx.diffViewer.statusDeleted": {
408
+ "defaultMessage": "⟦Ðéłéţéð⟧"
409
+ },
410
+ "@astryx.diffViewer.statusRenamed": {
411
+ "defaultMessage": "⟦Řéñàɱéð⟧"
412
+ },
413
+ "@astryx.diffViewer.addedCount": {
414
+ "defaultMessage": "⟦+{count, number}⟧"
415
+ },
416
+ "@astryx.diffViewer.removedCount": {
417
+ "defaultMessage": "⟦−{count, number}⟧"
418
+ },
419
+ "@astryx.diffViewer.stats": {
420
+ "defaultMessage": "⟦{added, plural, one {# line added} other {# lines added}}, {removed, plural, one {# line removed} other {# lines removed}}⟧"
421
+ },
422
+ "@astryx.diffViewer.added": {
423
+ "defaultMessage": "⟦Àððéð⟧"
424
+ },
425
+ "@astryx.diffViewer.removed": {
426
+ "defaultMessage": "⟦Řéɱóṽéð⟧"
427
+ },
428
+ "@astryx.diffViewer.lineNumberButton": {
429
+ "defaultMessage": "⟦{side, select, old {Original line {line, number}} other {Changed line {line, number}}}⟧"
430
+ },
431
+ "@astryx.diffViewer.columnOldLine": {
432
+ "defaultMessage": "⟦Óříĝíñàł łíñé ñúɱƀéř⟧"
433
+ },
434
+ "@astryx.diffViewer.columnNewLine": {
435
+ "defaultMessage": "⟦Çĥàñĝéð łíñé ñúɱƀéř⟧"
436
+ },
437
+ "@astryx.diffViewer.columnChange": {
438
+ "defaultMessage": "⟦Çĥàñĝé⟧"
439
+ },
440
+ "@astryx.diffViewer.columnCode": {
441
+ "defaultMessage": "⟦Çóðé⟧"
442
+ },
443
+ "@astryx.diffViewer.columnOldCode": {
444
+ "defaultMessage": "⟦Óříĝíñàł çóðé⟧"
445
+ },
446
+ "@astryx.diffViewer.columnNewCode": {
447
+ "defaultMessage": "⟦Çĥàñĝéð çóðé⟧"
448
+ },
449
+ "@astryx.diffViewer.binary": {
450
+ "defaultMessage": "⟦Ɓíñàřý ƒíłé ñóţ šĥóŵñ⟧"
451
+ },
452
+ "@astryx.diffViewer.noChanges": {
453
+ "defaultMessage": "⟦Ñó çóñţéñţ çĥàñĝéš⟧"
454
+ },
398
455
  "@astryx.markdownHeadingLinks.copied": {
399
456
  "defaultMessage": "⟦Łíñķ çóþíéð⟧"
400
457
  },
@@ -1231,5 +1288,281 @@
1231
1288
  },
1232
1289
  "@astryx.transferListSelector.triggerLabel": {
1233
1290
  "defaultMessage": "⟦{count, number} šéłéçţéð⟧"
1291
+ },
1292
+ "@astryx.emojiPicker.label": {
1293
+ "defaultMessage": "⟦Éɱóĵí⟧"
1294
+ },
1295
+ "@astryx.emojiPicker.searchLabel": {
1296
+ "defaultMessage": "⟦Šéàřçĥ éɱóĵí⟧"
1297
+ },
1298
+ "@astryx.emojiPicker.frequentlyUsed": {
1299
+ "defaultMessage": "⟦Ƒřéɋúéñţłý úšéð⟧"
1300
+ },
1301
+ "@astryx.emojiPicker.searchResults": {
1302
+ "defaultMessage": "⟦Šéàřçĥ řéšúłţš⟧"
1303
+ },
1304
+ "@astryx.emojiPicker.noResults": {
1305
+ "defaultMessage": "⟦Ñó éɱóĵí ɱàţçĥ “{query}”⟧"
1306
+ },
1307
+ "@astryx.emojiPicker.loading": {
1308
+ "defaultMessage": "⟦Łóàðíñĝ éɱóĵí⟧"
1309
+ },
1310
+ "@astryx.emojiPicker.loadFailed": {
1311
+ "defaultMessage": "⟦Ṁóřé éɱóĵí çóúłðñ'ţ ƀé łóàðéð.⟧"
1312
+ },
1313
+ "@astryx.emojiPicker.groupSmileysEmotion": {
1314
+ "defaultMessage": "⟦Šɱíłéýš & éɱóţíóñ⟧"
1315
+ },
1316
+ "@astryx.emojiPicker.groupPeopleBody": {
1317
+ "defaultMessage": "⟦Þéóþłé & ƀóðý⟧"
1318
+ },
1319
+ "@astryx.emojiPicker.groupAnimalsNature": {
1320
+ "defaultMessage": "⟦Àñíɱàłš & ñàţúřé⟧"
1321
+ },
1322
+ "@astryx.emojiPicker.groupFoodDrink": {
1323
+ "defaultMessage": "⟦Ƒóóð & ðříñķ⟧"
1324
+ },
1325
+ "@astryx.emojiPicker.groupTravelPlaces": {
1326
+ "defaultMessage": "⟦Ţřàṽéł & þłàçéš⟧"
1327
+ },
1328
+ "@astryx.emojiPicker.groupActivities": {
1329
+ "defaultMessage": "⟦Àçţíṽíţíéš⟧"
1330
+ },
1331
+ "@astryx.emojiPicker.groupObjects": {
1332
+ "defaultMessage": "⟦Óƀĵéçţš⟧"
1333
+ },
1334
+ "@astryx.emojiPicker.groupSymbols": {
1335
+ "defaultMessage": "⟦Šýɱƀółš⟧"
1336
+ },
1337
+ "@astryx.emojiPicker.groupFlags": {
1338
+ "defaultMessage": "⟦Ƒłàĝš⟧"
1339
+ },
1340
+ "@astryx.comments.retry": {
1341
+ "defaultMessage": "⟦Řéţřý⟧"
1342
+ },
1343
+ "@astryx.commentComposer.placeholder": {
1344
+ "defaultMessage": "⟦Ŵříţé à çóɱɱéñţ…⟧"
1345
+ },
1346
+ "@astryx.commentComposer.noAgents": {
1347
+ "defaultMessage": "⟦Ñó àĝéñţš⟧"
1348
+ },
1349
+ "@astryx.commentComposer.agents": {
1350
+ "defaultMessage": "⟦Àĝéñţš⟧"
1351
+ },
1352
+ "@astryx.commentComposer.uploadFailed": {
1353
+ "defaultMessage": "⟦Íɱàĝéš çóúłðñ'ţ ƀé àððéð⟧"
1354
+ },
1355
+ "@astryx.commentComposer.imagesOnly": {
1356
+ "defaultMessage": "⟦Óñłý íɱàĝé ƒíłéš çàñ ƀé àððéð⟧"
1357
+ },
1358
+ "@astryx.commentComposer.chooseImages": {
1359
+ "defaultMessage": "⟦Çĥóóšé íɱàĝéš⟧"
1360
+ },
1361
+ "@astryx.commentComposer.imageAlt": {
1362
+ "defaultMessage": "⟦Íɱàĝé àţţàçĥɱéñţ⟧"
1363
+ },
1364
+ "@astryx.commentComposer.removeQuote": {
1365
+ "defaultMessage": "⟦Řéɱóṽé ɋúóţéð ţéẋţ⟧"
1366
+ },
1367
+ "@astryx.commentComposer.attachImages": {
1368
+ "defaultMessage": "⟦Àţţàçĥ íɱàĝéš⟧"
1369
+ },
1370
+ "@astryx.commentComposer.addEmoji": {
1371
+ "defaultMessage": "⟦Àðð éɱóĵí⟧"
1372
+ },
1373
+ "@astryx.commentComposer.cancel": {
1374
+ "defaultMessage": "⟦Çàñçéł⟧"
1375
+ },
1376
+ "@astryx.comments.actionsLabel": {
1377
+ "defaultMessage": "⟦Àçţíóñš ƒóř {name}'š çóɱɱéñţ⟧"
1378
+ },
1379
+ "@astryx.comments.addReaction": {
1380
+ "defaultMessage": "⟦Àðð řéàçţíóñ⟧"
1381
+ },
1382
+ "@astryx.comments.agentBadge": {
1383
+ "defaultMessage": "⟦Àĝéñţ⟧"
1384
+ },
1385
+ "@astryx.comments.agentLogo": {
1386
+ "defaultMessage": "⟦{name} łóĝó⟧"
1387
+ },
1388
+ "@astryx.comments.chooseReaction": {
1389
+ "defaultMessage": "⟦Çĥóóšé à řéàçţíóñ⟧"
1390
+ },
1391
+ "@astryx.comments.copyLink": {
1392
+ "defaultMessage": "⟦Çóþý çóɱɱéñţ łíñķ⟧"
1393
+ },
1394
+ "@astryx.comments.currentVersion": {
1395
+ "defaultMessage": "⟦Çúřřéñţ ṽéřšíóñ⟧"
1396
+ },
1397
+ "@astryx.comments.delete": {
1398
+ "defaultMessage": "⟦Ðéłéţé⟧"
1399
+ },
1400
+ "@astryx.comments.deleteDescription": {
1401
+ "defaultMessage": "⟦Ðéłéţé {name}'š çóɱɱéñţ? Ţĥíš àçţíóñ çàññóţ ƀé úñðóñé.⟧"
1402
+ },
1403
+ "@astryx.comments.deleteFailed": {
1404
+ "defaultMessage": "⟦Ţĥíš çóɱɱéñţ çóúłðñ'ţ ƀé ðéłéţéð.⟧"
1405
+ },
1406
+ "@astryx.comments.deleteFailedRetry": {
1407
+ "defaultMessage": "⟦Ţĥíš çóɱɱéñţ çóúłðñ'ţ ƀé ðéłéţéð. Ţřý àĝàíñ.⟧"
1408
+ },
1409
+ "@astryx.comments.deleteTitle": {
1410
+ "defaultMessage": "⟦Ðéłéţé çóɱɱéñţ?⟧"
1411
+ },
1412
+ "@astryx.comments.edit": {
1413
+ "defaultMessage": "⟦Éðíţ⟧"
1414
+ },
1415
+ "@astryx.comments.editFailed": {
1416
+ "defaultMessage": "⟦Ýóúř éðíţ çóúłðñ'ţ ƀé šàṽéð.⟧"
1417
+ },
1418
+ "@astryx.comments.editPlaceholder": {
1419
+ "defaultMessage": "⟦Éðíţ çóɱɱéñţ⟧"
1420
+ },
1421
+ "@astryx.comments.edited": {
1422
+ "defaultMessage": "⟦Éðíţéð⟧"
1423
+ },
1424
+ "@astryx.comments.editingContext": {
1425
+ "defaultMessage": "⟦Éðíţíñĝ çóɱɱéñţ⟧"
1426
+ },
1427
+ "@astryx.comments.hideReplies": {
1428
+ "defaultMessage": "⟦Ĥíðé řéþłíéš⟧"
1429
+ },
1430
+ "@astryx.comments.historyEmptyDescription": {
1431
+ "defaultMessage": "⟦Ţĥíš çóɱɱéñţ ĥàš ñó éàřłíéř ṽéřšíóñš.⟧"
1432
+ },
1433
+ "@astryx.comments.historyEmptyTitle": {
1434
+ "defaultMessage": "⟦Ñó éðíţ ĥíšţóřý⟧"
1435
+ },
1436
+ "@astryx.comments.historyFailed": {
1437
+ "defaultMessage": "⟦Éðíţ ĥíšţóřý çóúłðñ'ţ łóàð⟧"
1438
+ },
1439
+ "@astryx.comments.historyLoadFailed": {
1440
+ "defaultMessage": "⟦Ţĥé çóɱɱéñţ'š éðíţ ĥíšţóřý çóúłðñ'ţ ƀé łóàðéð. Ţřý àĝàíñ.⟧"
1441
+ },
1442
+ "@astryx.comments.historyLoading": {
1443
+ "defaultMessage": "⟦Łóàðíñĝ éðíţ ĥíšţóřý⟧"
1444
+ },
1445
+ "@astryx.comments.historySubtitle": {
1446
+ "defaultMessage": "⟦Çóɱɱéñţ ƀý {name}⟧"
1447
+ },
1448
+ "@astryx.comments.historyTitle": {
1449
+ "defaultMessage": "⟦Éðíţ ĥíšţóřý⟧"
1450
+ },
1451
+ "@astryx.comments.linkCopied": {
1452
+ "defaultMessage": "⟦Çóɱɱéñţ łíñķ çóþíéð⟧"
1453
+ },
1454
+ "@astryx.comments.otherReactors": {
1455
+ "defaultMessage": "⟦{count, plural, one {# other} other {# others}}⟧"
1456
+ },
1457
+ "@astryx.comments.outdated": {
1458
+ "defaultMessage": "⟦Óúţðàţéð⟧"
1459
+ },
1460
+ "@astryx.comments.reactionCelebrate": {
1461
+ "defaultMessage": "⟦Çéłéƀřàţé⟧"
1462
+ },
1463
+ "@astryx.comments.reactionCount": {
1464
+ "defaultMessage": "⟦{reaction}: {count, number}⟧"
1465
+ },
1466
+ "@astryx.comments.reactionFailed": {
1467
+ "defaultMessage": "⟦Ýóúř řéàçţíóñ çóúłðñ'ţ ƀé šàṽéð.⟧"
1468
+ },
1469
+ "@astryx.comments.reactionLaugh": {
1470
+ "defaultMessage": "⟦Ĥàĥà⟧"
1471
+ },
1472
+ "@astryx.comments.reactionLike": {
1473
+ "defaultMessage": "⟦Łíķé⟧"
1474
+ },
1475
+ "@astryx.comments.reactionLove": {
1476
+ "defaultMessage": "⟦Łóṽé⟧"
1477
+ },
1478
+ "@astryx.comments.reactionSad": {
1479
+ "defaultMessage": "⟦Šàð⟧"
1480
+ },
1481
+ "@astryx.comments.reactionWow": {
1482
+ "defaultMessage": "⟦Ŵóŵ⟧"
1483
+ },
1484
+ "@astryx.comments.reopen": {
1485
+ "defaultMessage": "⟦Řéóþéñ⟧"
1486
+ },
1487
+ "@astryx.comments.reopenFailed": {
1488
+ "defaultMessage": "⟦Ţĥíš ţĥřéàð çóúłðñ'ţ ƀé řéóþéñéð.⟧"
1489
+ },
1490
+ "@astryx.comments.reply": {
1491
+ "defaultMessage": "⟦Řéþłý⟧"
1492
+ },
1493
+ "@astryx.comments.replyFailed": {
1494
+ "defaultMessage": "⟦Ýóúř řéþłý çóúłðñ'ţ ƀé þóšţéð.⟧"
1495
+ },
1496
+ "@astryx.comments.replyPlaceholder": {
1497
+ "defaultMessage": "⟦Řéþłý ţó {name}…⟧"
1498
+ },
1499
+ "@astryx.comments.replyingContext": {
1500
+ "defaultMessage": "⟦Řéþłýíñĝ ţó {name}⟧"
1501
+ },
1502
+ "@astryx.comments.resolve": {
1503
+ "defaultMessage": "⟦Ṁàřķ àš řéšółṽéð⟧"
1504
+ },
1505
+ "@astryx.comments.resolveFailed": {
1506
+ "defaultMessage": "⟦Ţĥíš ţĥřéàð çóúłðñ'ţ ƀé řéšółṽéð.⟧"
1507
+ },
1508
+ "@astryx.comments.resolved": {
1509
+ "defaultMessage": "⟦Řéšółṽéð⟧"
1510
+ },
1511
+ "@astryx.comments.resolvedBy": {
1512
+ "defaultMessage": "⟦Řéšółṽéð ƀý {name}⟧"
1513
+ },
1514
+ "@astryx.comments.retryFailed": {
1515
+ "defaultMessage": "⟦Řéţřýíñĝ ðíðñ'ţ ŵóřķ.⟧"
1516
+ },
1517
+ "@astryx.comments.sendFailed": {
1518
+ "defaultMessage": "⟦Çóúłðñ'ţ šéñð ţĥíš çóɱɱéñţ.⟧"
1519
+ },
1520
+ "@astryx.comments.threadLabel": {
1521
+ "defaultMessage": "⟦Ţĥřéàð ƀý {name}⟧"
1522
+ },
1523
+ "@astryx.comments.unread": {
1524
+ "defaultMessage": "⟦Ñéŵ⟧"
1525
+ },
1526
+ "@astryx.comments.unsavedDraft": {
1527
+ "defaultMessage": "⟦Úñšàṽéð ðřàƒţ. Ðíšɱíšš àĝàíñ ţó ðíšçàřð íţ.⟧"
1528
+ },
1529
+ "@astryx.comments.versionAuthor": {
1530
+ "defaultMessage": "⟦ƀý {name}⟧"
1531
+ },
1532
+ "@astryx.comments.viewHistory": {
1533
+ "defaultMessage": "⟦Ṽíéŵ éðíţ ĥíšţóřý⟧"
1534
+ },
1535
+ "@astryx.comments.viewReplies": {
1536
+ "defaultMessage": "⟦Ṽíéŵ {count, plural, one {# reply} other {# replies}}⟧"
1537
+ },
1538
+ "@astryx.comments.commentsLabel": {
1539
+ "defaultMessage": "⟦Ţĥřéàðš íñ {label}⟧"
1540
+ },
1541
+ "@astryx.comments.emptyDescription": {
1542
+ "defaultMessage": "⟦Šţàřţ ţĥé ðíšçúššíóñ ŵíţĥ à çóɱɱéñţ.⟧"
1543
+ },
1544
+ "@astryx.comments.emptyReadOnlyDescription": {
1545
+ "defaultMessage": "⟦Ţĥéřé íš ñó ðíšçúššíóñ óñ ţĥíš íţéɱ.⟧"
1546
+ },
1547
+ "@astryx.comments.emptyTitle": {
1548
+ "defaultMessage": "⟦Ñó çóɱɱéñţš ýéţ⟧"
1549
+ },
1550
+ "@astryx.comments.label": {
1551
+ "defaultMessage": "⟦Çóɱɱéñţš⟧"
1552
+ },
1553
+ "@astryx.comments.loadFailed": {
1554
+ "defaultMessage": "⟦Çóɱɱéñţš çóúłðñ'ţ łóàð⟧"
1555
+ },
1556
+ "@astryx.comments.loadOlder": {
1557
+ "defaultMessage": "⟦Łóàð éàřłíéř çóɱɱéñţš⟧"
1558
+ },
1559
+ "@astryx.comments.loading": {
1560
+ "defaultMessage": "⟦Łóàðíñĝ çóɱɱéñţš⟧"
1561
+ },
1562
+ "@astryx.comments.olderFailed": {
1563
+ "defaultMessage": "⟦Éàřłíéř çóɱɱéñţš çóúłðñ'ţ łóàð⟧"
1564
+ },
1565
+ "@astryx.comments.postFailed": {
1566
+ "defaultMessage": "⟦Ýóúř çóɱɱéñţ çóúłðñ'ţ ƀé þóšţéð.⟧"
1234
1567
  }
1235
1568
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@astryxdesign/core",
3
- "version": "0.7.1",
3
+ "version": "0.7.2-canary.020e1fe",
4
4
  "displayName": "Astryx Core",
5
5
  "description": "The component library. Accessible, themeable React components with built-in spacing, dark mode, and StyleX styling.",
6
6
  "author": "Meta Open Source",
@@ -329,6 +329,11 @@
329
329
  "types": "./dist/Divider/index.d.ts",
330
330
  "default": "./dist/Divider/index.js"
331
331
  },
332
+ "./Drawer": {
333
+ "source": "./src/Drawer/index.ts",
334
+ "types": "./dist/Drawer/index.d.ts",
335
+ "default": "./dist/Drawer/index.js"
336
+ },
332
337
  "./DropdownMenu": {
333
338
  "source": "./src/DropdownMenu/index.ts",
334
339
  "types": "./dist/DropdownMenu/index.d.ts",
@@ -787,6 +792,8 @@
787
792
  "react-dom": ">=19.0.0"
788
793
  },
789
794
  "devDependencies": {
795
+ "@astryxdesign/a11y-spec": "0.7.2-canary.020e1fe",
796
+ "@astryxdesign/cli": "0.7.2-canary.020e1fe",
790
797
  "@babel/cli": "^7.29.7",
791
798
  "@babel/core": "^7.29.7",
792
799
  "@babel/preset-react": "^7.29.7",
@@ -797,9 +804,7 @@
797
804
  "@testing-library/jest-dom": "^6.6.0",
798
805
  "@testing-library/react": "^16.3.2",
799
806
  "@types/babel__core": "^7.20.5",
800
- "tailwindcss": "^4.3.2",
801
- "@astryxdesign/a11y-spec": "0.0.0",
802
- "@astryxdesign/cli": "0.7.1"
807
+ "tailwindcss": "^4.3.2"
803
808
  },
804
809
  "dependencies": {
805
810
  "intl-messageformat": "^11.2.9"
@@ -106,6 +106,44 @@ export function isAstryxInitialized(targetDir = process.cwd()) {
106
106
  return false;
107
107
  }
108
108
 
109
+ /**
110
+ * Does an agent working in `startDir` already have the Astryx prompt in reach?
111
+ *
112
+ * Coding agents read the agent docs between the repository root and the folder
113
+ * they work in. So inside a git repository, init's block in any folder from
114
+ * `startDir` up to the repository root counts: a workspace package of a
115
+ * monorepo initialized at its root is set up. Outside a repository only
116
+ * `startDir` itself is checked, as {@link isAstryxInitialized} does. Both the
117
+ * per-command nudge and the postinstall nudges ask this.
118
+ *
119
+ * @param {string} [startDir=process.cwd()]
120
+ * @returns {boolean}
121
+ */
122
+ export function isAstryxPromptInReach(startDir = process.cwd()) {
123
+ const start = path.resolve(startDir);
124
+ const repositoryRoot = findRepositoryRoot(start);
125
+ if (!repositoryRoot) return isAstryxInitialized(start);
126
+ for (let dir = start; ; dir = path.dirname(dir)) {
127
+ if (isAstryxInitialized(dir)) return true;
128
+ if (dir === repositoryRoot) return false;
129
+ }
130
+ }
131
+
132
+ /**
133
+ * The nearest folder at or above `start` that holds `.git` (a folder, or the
134
+ * file a worktree uses), or null outside a repository.
135
+ * @param {string} start
136
+ * @returns {string | null}
137
+ */
138
+ function findRepositoryRoot(start) {
139
+ for (let dir = start; ; ) {
140
+ if (fs.existsSync(path.join(dir, '.git'))) return dir;
141
+ const parent = path.dirname(dir);
142
+ if (parent === dir) return null;
143
+ dir = parent;
144
+ }
145
+ }
146
+
109
147
  /**
110
148
  * The one-line next-step both postinstall nudges print. Kept here so layer 1
111
149
  * (core) and layer 2 (cli) can never word it differently.
@@ -45,7 +45,7 @@ async function main() {
45
45
  contract.shouldNudge({
46
46
  scriptPath: HERE,
47
47
  npmCommand: process.env.npm_command,
48
- isSetUp: contract.isAstryxInitialized(root),
48
+ isSetUp: contract.isAstryxPromptInReach(root),
49
49
  })
50
50
  ) {
51
51
  process.stdout.write(contract.SETUP_NUDGE);
@@ -43,6 +43,7 @@ import {LayoutHeader} from '../Layout/LayoutHeader';
43
43
  import {LayoutPanel} from '../Layout/LayoutPanel';
44
44
  import {LayoutContent} from '../Layout/LayoutContent';
45
45
  import {MobileNavToggle} from '../MobileNav/MobileNavToggle';
46
+ import {MAX_CLOSE_DELAY_MS as MOBILE_NAV_MAX_CLOSE_DELAY_MS} from '../MobileNav/MobileNav';
46
47
  import {SideNavRenderContext} from '../SideNav/SideNavRenderContext';
47
48
  import {TopNavRenderContext} from '../TopNav/TopNavRenderContext';
48
49
  import {TopNavMobileContentContext} from '../TopNav/TopNavMobileContentContext';
@@ -81,6 +82,20 @@ const ActivityWrapper = HasActivity
81
82
 
82
83
  const MAIN_CONTENT_ID = 'astryx-app-shell-main';
83
84
 
85
+ /**
86
+ * Extra time, on top of MobileNav's own worst-case close delay, that
87
+ * AppShell waits before flipping its `Activity` boundary to `'hidden'`.
88
+ *
89
+ * React's `Activity` hides its subtree with `display: none !important`
90
+ * synchronously in the same commit as the mode flip, and re-runs the
91
+ * cleanup of every effect inside it — which would otherwise clear
92
+ * MobileNav's own scheduled `dialog.close()` before it fires, or cut off
93
+ * its slide-out CSS transition before it plays (#5701). Waiting strictly
94
+ * longer than MobileNav's own cap, rather than the same duration, means
95
+ * this never turns into a race decided by browser timer-firing order.
96
+ */
97
+ const ACTIVITY_HIDE_BUFFER_MS = 50;
98
+
84
99
  // =============================================================================
85
100
  // Types
86
101
  // =============================================================================
@@ -525,6 +540,34 @@ export function AppShell({
525
540
  const [uncontrolledMobileOpen, setUncontrolledMobileOpen] = useState(false);
526
541
  const isMobileNavOpen = mobileNavConfig?.isOpen ?? uncontrolledMobileOpen;
527
542
 
543
+ // Holds the mobile nav's `Activity` boundary visible for a beat after a
544
+ // close, so MobileNav's own close effect gets a real chance to run its
545
+ // slide-out transition and schedule its delayed `dialog.close()` before
546
+ // Activity hides the subtree (#5701). Only the CLOSE is deferred: opening
547
+ // reads `isMobileNavOpen` directly below, so a controlled open is visible in
548
+ // the commit that carries it instead of one effect later.
549
+ const [isMobileNavCloseHeld, setIsMobileNavCloseHeld] =
550
+ useState(isMobileNavOpen);
551
+ // Arm the hold during render, from the open state itself, so no Effect has
552
+ // to copy props into state; the Effect below only owns the release timer.
553
+ if (isMobileNavOpen && !isMobileNavCloseHeld) {
554
+ setIsMobileNavCloseHeld(true);
555
+ }
556
+ useEffect(() => {
557
+ if (!HasActivity || isMobileNavOpen) {
558
+ return;
559
+ }
560
+ const delayMs = window.matchMedia('(prefers-reduced-motion: reduce)')
561
+ .matches
562
+ ? 0
563
+ : MOBILE_NAV_MAX_CLOSE_DELAY_MS + ACTIVITY_HIDE_BUFFER_MS;
564
+ const timeout = setTimeout(() => {
565
+ setIsMobileNavCloseHeld(false);
566
+ }, delayMs);
567
+ return () => clearTimeout(timeout);
568
+ }, [isMobileNavOpen]);
569
+ const isMobileNavActivityVisible = isMobileNavOpen || isMobileNavCloseHeld;
570
+
528
571
  const mobileNavOnOpenChange = mobileNavConfig?.onOpenChange;
529
572
  const setMobileNavOpen = useCallback(
530
573
  (open: boolean) => {
@@ -864,7 +907,8 @@ export function AppShell({
864
907
  !mobileNavDisabled &&
865
908
  mobileNavReactNode == null &&
866
909
  !mobileNavConfigContent && (
867
- <ActivityWrapper mode={isMobileNavOpen ? 'visible' : 'hidden'}>
910
+ <ActivityWrapper
911
+ mode={isMobileNavActivityVisible ? 'visible' : 'hidden'}>
868
912
  {/* SideNav drawer — always mounted so presence detection works.
869
913
  Hidden when TopNav owns the drawer (combined mode passes
870
914
  sideNav via TopNav's mobile content context instead). */}
@@ -9,7 +9,7 @@
9
9
  * SYNC: When AspectRatio.tsx changes, update tests to match new behavior
10
10
  */
11
11
 
12
- import {describe, it, expect, vi, beforeAll} from 'vitest';
12
+ import {describe, it, expect, vi} from 'vitest';
13
13
  import {render, screen} from '@testing-library/react';
14
14
  import {AspectRatio} from './AspectRatio';
15
15
 
@@ -230,9 +230,8 @@ describe('AspectRatio', () => {
230
230
  <img src="test.jpg" alt="Test" data-testid="image" />
231
231
  </AspectRatio>,
232
232
  );
233
- // The marker sits on the child's actual parent, so the reset.css
234
- // sizing rules are direct-child selectors with no dependence on
235
- // AspectRatio's internal structure.
233
+ // Earlier releases documented the marker, so it stays on the child's
234
+ // direct parent for product CSS that targets it.
236
235
  const wrapper = screen.getByTestId('image').parentElement;
237
236
  expect(wrapper).toHaveAttribute(
238
237
  'data-astryx-aspect-ratio-override',
@@ -274,8 +273,11 @@ describe('AspectRatio', () => {
274
273
  );
275
274
  const wrapper = screen.getByTestId('image').parentElement;
276
275
  expect(wrapper).not.toHaveAttribute('data-astryx-aspect-ratio-override');
277
- // Without the marker, none of the reset.css fit rules can match, so
278
- // existing self-styled children render exactly as before.
276
+ // Without fit the wrapper carries no child-sizing styles, so existing
277
+ // self-styled children render exactly as before.
278
+ expect(wrapper?.className).not.toContain('childFill');
279
+ expect(wrapper?.className).not.toContain('childCover');
280
+ expect(wrapper?.className).not.toContain('childContain');
279
281
  expect(screen.getByTestId('image')).not.toHaveAttribute('class');
280
282
  });
281
283
 
@@ -292,13 +294,37 @@ describe('AspectRatio', () => {
292
294
  </AspectRatio>,
293
295
  );
294
296
  const image = screen.getByTestId('image');
295
- // Fit styling is pure CSS (zero-specificity reset rules); the child's
296
- // own className/style pass through untouched and always win, so
297
- // children that already size themselves keep their behavior.
297
+ // Fit styling is a direct-child rule on the wrapper; the child's own
298
+ // className/style pass through untouched, and an inline style still
299
+ // wins over it.
298
300
  expect(image.className).toBe('consumer-class');
299
301
  expect(image.style.objectFit).toBe('contain');
300
302
  });
301
303
 
304
+ it('sizes the child from the wrapper with fit="cover"', () => {
305
+ render(
306
+ <AspectRatio ratio={16 / 9} fit="cover">
307
+ <img src="test.jpg" alt="Test" data-testid="image" />
308
+ </AspectRatio>,
309
+ );
310
+ const wrapper = screen.getByTestId('image').parentElement;
311
+ expect(wrapper?.className).toContain('childFill');
312
+ expect(wrapper?.className).toContain('childCover');
313
+ expect(wrapper?.className).not.toContain('childContain');
314
+ });
315
+
316
+ it('sizes the child from the wrapper with fit="contain"', () => {
317
+ render(
318
+ <AspectRatio ratio={16 / 9} fit="contain">
319
+ <img src="test.jpg" alt="Test" data-testid="image" />
320
+ </AspectRatio>,
321
+ );
322
+ const wrapper = screen.getByTestId('image').parentElement;
323
+ expect(wrapper?.className).toContain('childFill');
324
+ expect(wrapper?.className).toContain('childContain');
325
+ expect(wrapper?.className).not.toContain('childCover');
326
+ });
327
+
302
328
  it('centers the child via the wrapper with fit="center"', () => {
303
329
  render(
304
330
  <AspectRatio ratio={16 / 9} fit="center">
@@ -309,6 +335,7 @@ describe('AspectRatio', () => {
309
335
  expect(image).not.toHaveAttribute('class');
310
336
  const wrapper = image.parentElement;
311
337
  expect(wrapper?.className).toContain('childCenter');
338
+ expect(wrapper?.className).not.toContain('childFill');
312
339
  });
313
340
 
314
341
  it('does not center the wrapper for other fit values', () => {
@@ -353,45 +380,19 @@ describe('AspectRatio', () => {
353
380
  });
354
381
  });
355
382
 
356
- describe('reset.css fit baseline rules', () => {
357
- // The cover/contain child sizing ships as zero-specificity baseline
358
- // rules in reset.css keyed on the data-astryx-aspect-ratio-override
359
- // marker the component sets on the child's direct parent. These
360
- // assertions keep the stylesheet in sync with the component contract.
361
- let resetCSS: string;
362
-
363
- beforeAll(async () => {
383
+ describe('reset.css', () => {
384
+ it('carries no AspectRatio rules', async () => {
385
+ // fit ships with the component's StyleX styles in `astryx-base`. A
386
+ // rule in reset.css sits below the layer the documented Tailwind
387
+ // setups give preflight, whose `img, video { height: auto }` would
388
+ // undo the fill.
364
389
  const fs = await import('fs');
365
390
  const path = await import('path');
366
- resetCSS = fs.readFileSync(
391
+ const resetCSS = fs.readFileSync(
367
392
  path.resolve(__dirname, '../reset.css'),
368
393
  'utf-8',
369
394
  );
370
- });
371
-
372
- it('sizes the child to fill the box for cover and contain', () => {
373
- const fillMatch = resetCSS.match(
374
- /:where\(\[data-astryx-aspect-ratio-override="cover"\], \[data-astryx-aspect-ratio-override="contain"\]\)\s*>\s*:where\(\*\)\s*\{([^}]+)\}/,
375
- );
376
- expect(fillMatch).not.toBeNull();
377
- expect(fillMatch![1]).toContain('width: 100%');
378
- expect(fillMatch![1]).toContain('height: 100%');
379
- });
380
-
381
- it('crops media with object-fit: cover for fit="cover"', () => {
382
- const coverMatch = resetCSS.match(
383
- /:where\(\[data-astryx-aspect-ratio-override="cover"\]\)\s*>\s*:where\(img, video\)\s*\{([^}]+)\}/,
384
- );
385
- expect(coverMatch).not.toBeNull();
386
- expect(coverMatch![1]).toContain('object-fit: cover');
387
- });
388
-
389
- it('letterboxes media with object-fit: contain for fit="contain"', () => {
390
- const containMatch = resetCSS.match(
391
- /:where\(\[data-astryx-aspect-ratio-override="contain"\]\)\s*>\s*:where\(img, video\)\s*\{([^}]+)\}/,
392
- );
393
- expect(containMatch).not.toBeNull();
394
- expect(containMatch![1]).toContain('object-fit: contain');
395
+ expect(resetCSS).not.toContain('aspect-ratio-override');
395
396
  });
396
397
  });
397
398
  });