@astryxdesign/core 0.5.0 → 0.5.1-canary.046f6ea

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 (622) hide show
  1. package/CHANGELOG.md +222 -0
  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/AspectRatio/AspectRatio.d.ts +6 -6
  6. package/dist/Avatar/Avatar.d.ts +25 -1
  7. package/dist/Avatar/Avatar.d.ts.map +1 -1
  8. package/dist/Avatar/Avatar.js +43 -9
  9. package/dist/Avatar/index.d.ts +2 -2
  10. package/dist/Avatar/index.d.ts.map +1 -1
  11. package/dist/Avatar/index.js +1 -1
  12. package/dist/AvatarGroup/AvatarGroup.d.ts +9 -2
  13. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroup.js +5 -2
  15. package/dist/AvatarGroup/AvatarGroupContext.d.ts +2 -1
  16. package/dist/AvatarGroup/AvatarGroupContext.d.ts.map +1 -1
  17. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  18. package/dist/AvatarGroup/AvatarGroupOverflow.js +11 -7
  19. package/dist/Badge/Badge.d.ts.map +1 -1
  20. package/dist/Badge/Badge.js +26 -2
  21. package/dist/Banner/Banner.d.ts +10 -1
  22. package/dist/Banner/Banner.d.ts.map +1 -1
  23. package/dist/Banner/Banner.js +11 -2
  24. package/dist/Button/Button.d.ts.map +1 -1
  25. package/dist/Button/Button.js +8 -7
  26. package/dist/Calendar/Calendar.d.ts +4 -2
  27. package/dist/Calendar/Calendar.d.ts.map +1 -1
  28. package/dist/Calendar/Calendar.js +15 -21
  29. package/dist/Calendar/hooks/useCalendarDays.js +4 -6
  30. package/dist/Calendar/hooks/useCalendarNavigation.js +4 -6
  31. package/dist/Calendar/styles.d.ts +5 -20
  32. package/dist/Calendar/styles.d.ts.map +1 -1
  33. package/dist/Calendar/styles.js +15 -17
  34. package/dist/Card/Card.d.ts +12 -12
  35. package/dist/Card/Card.d.ts.map +1 -1
  36. package/dist/Card/Card.js +17 -9
  37. package/dist/Card/index.d.ts +35 -1
  38. package/dist/Card/index.d.ts.map +1 -1
  39. package/dist/Card/index.js +21 -1
  40. package/dist/Carousel/Carousel.d.ts.map +1 -1
  41. package/dist/Carousel/Carousel.js +108 -7
  42. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  43. package/dist/CheckboxInput/CheckboxInput.js +7 -1
  44. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  45. package/dist/CodeBlock/CodeBlock.js +15 -4
  46. package/dist/CodeBlock/highlightRanges.js +1 -1
  47. package/dist/CodeBlock/highlightStyles.js +13 -13
  48. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  49. package/dist/CommandPalette/CommandPaletteItem.js +2 -7
  50. package/dist/ComplexSelector/ComplexSelector.d.ts +10 -2
  51. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  52. package/dist/ComplexSelector/ComplexSelector.js +14 -7
  53. package/dist/DateInput/DateInput.d.ts +43 -0
  54. package/dist/DateInput/DateInput.d.ts.map +1 -1
  55. package/dist/DateInput/DateInput.js +22 -5
  56. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  57. package/dist/DateInput/MonthScroller.js +5 -3
  58. package/dist/DateInput/MonthYearWheels.d.ts.map +1 -1
  59. package/dist/DateInput/MonthYearWheels.js +6 -4
  60. package/dist/DateInput/NativeDateField.d.ts +10 -0
  61. package/dist/DateInput/NativeDateField.d.ts.map +1 -0
  62. package/dist/DateInput/NativeDateField.js +494 -0
  63. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  64. package/dist/DateInput/TouchDateField.js +52 -25
  65. package/dist/DateInput/Wheel.d.ts.map +1 -1
  66. package/dist/DateInput/Wheel.js +1 -0
  67. package/dist/DateInput/index.d.ts +1 -1
  68. package/dist/DateInput/index.d.ts.map +1 -1
  69. package/dist/DateInput/nativeDateSegments.d.ts +22 -0
  70. package/dist/DateInput/nativeDateSegments.d.ts.map +1 -0
  71. package/dist/DateInput/nativeDateSegments.js +111 -0
  72. package/dist/DateRangeInput/DateRangeInput.d.ts +4 -2
  73. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  74. package/dist/DateRangeInput/DateRangeInput.js +3 -5
  75. package/dist/DateTimeInput/DateTimeInput.d.ts +23 -24
  76. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  77. package/dist/DateTimeInput/DateTimeInput.js +35 -10
  78. package/dist/DateTimeInput/TouchDateTimeField.d.ts +6 -0
  79. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -0
  80. package/dist/DateTimeInput/TouchDateTimeField.js +1021 -0
  81. package/dist/Dialog/Dialog.d.ts +16 -2
  82. package/dist/Dialog/Dialog.d.ts.map +1 -1
  83. package/dist/Dialog/Dialog.js +28 -7
  84. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  85. package/dist/DropdownMenu/DropdownMenu.js +4 -13
  86. package/dist/Field/FieldLabel.d.ts.map +1 -1
  87. package/dist/Field/FieldLabel.js +9 -1
  88. package/dist/Field/InputClearButton.d.ts +9 -3
  89. package/dist/Field/InputClearButton.d.ts.map +1 -1
  90. package/dist/Field/InputClearButton.js +14 -3
  91. package/dist/Heading/Heading.d.ts.map +1 -1
  92. package/dist/Heading/Heading.js +0 -1
  93. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  94. package/dist/HoverCard/HoverCard.js +104 -3
  95. package/dist/HoverCard/useHoverCard.d.ts +14 -2
  96. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  97. package/dist/HoverCard/useHoverCard.js +7 -1
  98. package/dist/Icon/Icon.d.ts +4 -2
  99. package/dist/Icon/Icon.d.ts.map +1 -1
  100. package/dist/Icon/defaultIcons.d.ts +3 -2
  101. package/dist/Icon/defaultIcons.d.ts.map +1 -1
  102. package/dist/Icon/defaultIcons.js +7 -0
  103. package/dist/Icon/globalIconRegistry.d.ts +13 -0
  104. package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
  105. package/dist/Icon/globalIconRegistry.js +34 -6
  106. package/dist/Icon/index.d.ts +1 -1
  107. package/dist/Icon/index.d.ts.map +1 -1
  108. package/dist/Icon/useIcon.d.ts +5 -2
  109. package/dist/Icon/useIcon.d.ts.map +1 -1
  110. package/dist/Icon/useIcon.js +3 -0
  111. package/dist/Indicator/CheckboxIndicator.d.ts.map +1 -1
  112. package/dist/Indicator/CheckboxIndicator.js +6 -2
  113. package/dist/Item/Item.d.ts.map +1 -1
  114. package/dist/Item/Item.js +2 -2
  115. package/dist/Kbd/Kbd.d.ts.map +1 -1
  116. package/dist/Kbd/Kbd.js +2 -26
  117. package/dist/Layer/gestureCounter.d.ts +8 -0
  118. package/dist/Layer/gestureCounter.d.ts.map +1 -0
  119. package/dist/Layer/gestureCounter.js +53 -0
  120. package/dist/Layer/useLayer.d.ts +23 -13
  121. package/dist/Layer/useLayer.d.ts.map +1 -1
  122. package/dist/Layer/useLayer.js +146 -24
  123. package/dist/List/List.d.ts +1 -1
  124. package/dist/List/List.d.ts.map +1 -1
  125. package/dist/List/List.js +15 -4
  126. package/dist/Markdown/Markdown.d.ts +1 -1
  127. package/dist/Markdown/Markdown.d.ts.map +1 -1
  128. package/dist/Markdown/Markdown.js +20 -7
  129. package/dist/Markdown/parser.d.ts.map +1 -1
  130. package/dist/Markdown/parser.js +5 -3
  131. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  132. package/dist/MetadataList/MetadataListItem.d.ts.map +1 -1
  133. package/dist/MetadataList/MetadataListItem.js +4 -1
  134. package/dist/MultiSelector/MultiSelector.d.ts +18 -1
  135. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  136. package/dist/MultiSelector/MultiSelector.js +58 -11
  137. package/dist/MultiSelector/hooks.d.ts +7 -1
  138. package/dist/MultiSelector/hooks.d.ts.map +1 -1
  139. package/dist/MultiSelector/hooks.js +3 -2
  140. package/dist/NavIcon/NavIcon.d.ts.map +1 -1
  141. package/dist/NavIcon/NavIcon.js +5 -1
  142. package/dist/NavItem/navItemStyles.stylex.d.ts +0 -8
  143. package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
  144. package/dist/NavItem/navItemStyles.stylex.js +0 -2
  145. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  146. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  147. package/dist/NavMenu/NavHeadingMenu.js +7 -4
  148. package/dist/NumberInput/NumberInput.d.ts +6 -1
  149. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  150. package/dist/NumberInput/NumberInput.js +95 -126
  151. package/dist/NumberInput/numberInputCommit.d.ts +34 -0
  152. package/dist/NumberInput/numberInputCommit.d.ts.map +1 -0
  153. package/dist/NumberInput/numberInputCommit.js +71 -0
  154. package/dist/NumberInput/numberParser.d.ts +64 -0
  155. package/dist/NumberInput/numberParser.d.ts.map +1 -0
  156. package/dist/NumberInput/numberParser.js +350 -0
  157. package/dist/Outline/Outline.d.ts.map +1 -1
  158. package/dist/Outline/Outline.js +2 -3
  159. package/dist/OverflowList/OverflowList.d.ts +41 -1
  160. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  161. package/dist/OverflowList/OverflowList.js +43 -2
  162. package/dist/Popover/Popover.d.ts.map +1 -1
  163. package/dist/Popover/Popover.js +8 -14
  164. package/dist/Popover/usePopover.d.ts +15 -41
  165. package/dist/Popover/usePopover.d.ts.map +1 -1
  166. package/dist/Popover/usePopover.js +26 -7
  167. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchValueEditor.js +91 -18
  169. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  170. package/dist/PowerSearch/formatFilterValue.js +4 -2
  171. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  172. package/dist/ProgressBar/ProgressBar.js +18 -5
  173. package/dist/Resizable/useResizable.d.ts +19 -1
  174. package/dist/Resizable/useResizable.d.ts.map +1 -1
  175. package/dist/Resizable/useResizable.js +104 -38
  176. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  177. package/dist/SelectableCard/SelectableCard.js +9 -0
  178. package/dist/Selector/Selector.d.ts +18 -1
  179. package/dist/Selector/Selector.d.ts.map +1 -1
  180. package/dist/Selector/Selector.js +92 -21
  181. package/dist/Selector/hooks.d.ts +7 -1
  182. package/dist/Selector/hooks.d.ts.map +1 -1
  183. package/dist/Selector/hooks.js +3 -2
  184. package/dist/SideNav/SideNav.d.ts +6 -1
  185. package/dist/SideNav/SideNav.d.ts.map +1 -1
  186. package/dist/SideNav/SideNav.js +57 -27
  187. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  188. package/dist/SideNav/SideNavHeading.js +5 -4
  189. package/dist/SideNav/SideNavItem.d.ts +29 -4
  190. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  191. package/dist/SideNav/SideNavItem.js +75 -20
  192. package/dist/Slider/Slider.d.ts.map +1 -1
  193. package/dist/Slider/Slider.js +34 -2
  194. package/dist/Spinner/Spinner.d.ts +3 -1
  195. package/dist/Spinner/Spinner.d.ts.map +1 -1
  196. package/dist/Spinner/Spinner.js +199 -20
  197. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  198. package/dist/StatusDot/StatusDot.js +6 -1
  199. package/dist/Stepper/Step.d.ts.map +1 -1
  200. package/dist/Stepper/Step.js +7 -6
  201. package/dist/Switch/Switch.d.ts.map +1 -1
  202. package/dist/Switch/Switch.js +5 -1
  203. package/dist/Table/BaseTable.d.ts.map +1 -1
  204. package/dist/Table/BaseTable.js +6 -1
  205. package/dist/Table/Table.d.ts.map +1 -1
  206. package/dist/Table/Table.js +3 -6
  207. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  208. package/dist/Table/plugins/filtering/useTableFiltering.js +73 -4
  209. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +26 -0
  210. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  211. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +34 -3
  212. package/dist/Table/plugins/selection/useTableSelection.d.ts.map +1 -1
  213. package/dist/Table/plugins/selection/useTableSelection.js +25 -1
  214. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  215. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +3 -4
  216. package/dist/Text/Text.d.ts.map +1 -1
  217. package/dist/Text/Text.js +0 -1
  218. package/dist/TextArea/TextArea.d.ts.map +1 -1
  219. package/dist/TextArea/TextArea.js +13 -8
  220. package/dist/Timestamp/Timestamp.d.ts +1 -1
  221. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  222. package/dist/Timestamp/Timestamp.js +10 -18
  223. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  224. package/dist/Timestamp/formatInstant.js +10 -5
  225. package/dist/Toast/Toast.d.ts +17 -2
  226. package/dist/Toast/Toast.d.ts.map +1 -1
  227. package/dist/Toast/Toast.js +77 -11
  228. package/dist/Toast/ToastViewport.d.ts +1 -0
  229. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  230. package/dist/Toast/ToastViewport.js +76 -21
  231. package/dist/Toast/index.d.ts +1 -1
  232. package/dist/Toast/index.d.ts.map +1 -1
  233. package/dist/Toast/types.d.ts +38 -0
  234. package/dist/Toast/types.d.ts.map +1 -1
  235. package/dist/Toast/useToastGesture.d.ts +26 -0
  236. package/dist/Toast/useToastGesture.d.ts.map +1 -0
  237. package/dist/Toast/useToastGesture.js +223 -0
  238. package/dist/Token/Token.d.ts +1 -1
  239. package/dist/Token/Token.d.ts.map +1 -1
  240. package/dist/Token/Token.js +23 -12
  241. package/dist/Token/TokenLink.d.ts +1 -1
  242. package/dist/Token/TokenLink.d.ts.map +1 -1
  243. package/dist/Token/TokenLink.js +5 -2
  244. package/dist/Tokenizer/Tokenizer.d.ts +12 -1
  245. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  246. package/dist/Tokenizer/Tokenizer.js +31 -21
  247. package/dist/TopNav/TopNavHeading.js +2 -2
  248. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  249. package/dist/TopNav/TopNavItem.js +3 -3
  250. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  251. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  252. package/dist/TopNav/TopNavMegaMenu.js +30 -9
  253. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  254. package/dist/TopNav/TopNavMegaMenuItem.js +3 -3
  255. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  256. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavMenu.js +21 -6
  258. package/dist/TreeList/TreeList.d.ts +1 -1
  259. package/dist/TreeList/TreeList.d.ts.map +1 -1
  260. package/dist/TreeList/TreeList.js +7 -2
  261. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  262. package/dist/TreeList/TreeListItem.js +2 -2
  263. package/dist/Typeahead/BaseTypeahead.d.ts +33 -0
  264. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  265. package/dist/Typeahead/BaseTypeahead.js +51 -8
  266. package/dist/Typeahead/Typeahead.d.ts +8 -1
  267. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  268. package/dist/Typeahead/Typeahead.js +2 -0
  269. package/dist/Typeahead/TypeaheadItem.d.ts +1 -1
  270. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  271. package/dist/Typeahead/TypeaheadItem.js +7 -2
  272. package/dist/astryx.css +87 -22
  273. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  274. package/dist/hooks/useHotkeys.js +3 -25
  275. package/dist/hooks/useOverflow.d.ts.map +1 -1
  276. package/dist/hooks/useOverflow.js +14 -4
  277. package/dist/i18n/InternationalizationContext.d.ts +2 -0
  278. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  279. package/dist/i18n/InternationalizationContext.js +3 -1
  280. package/dist/i18n/InternationalizationProvider.d.ts.map +1 -1
  281. package/dist/i18n/InternationalizationProvider.js +3 -1
  282. package/dist/i18n/resolve.d.ts +1 -1
  283. package/dist/i18n/resolve.d.ts.map +1 -1
  284. package/dist/i18n/resolve.js +37 -38
  285. package/dist/i18n/useTranslator.d.ts.map +1 -1
  286. package/dist/i18n/useTranslator.js +2 -3
  287. package/dist/index.d.ts +1 -1
  288. package/dist/index.d.ts.map +1 -1
  289. package/dist/theme/Theme.d.ts.map +1 -1
  290. package/dist/theme/Theme.js +46 -10
  291. package/dist/theme/defineTheme.d.ts +9 -3
  292. package/dist/theme/defineTheme.d.ts.map +1 -1
  293. package/dist/theme/defineTheme.js +5 -0
  294. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  295. package/dist/theme/derivedVarRegistry.js +24 -4
  296. package/dist/theme/generateThemeRules.d.ts +21 -0
  297. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  298. package/dist/theme/generateThemeRules.js +26 -0
  299. package/dist/theme/syntax/tokens.d.ts +1 -1
  300. package/dist/theme/syntax/tokens.d.ts.map +1 -1
  301. package/dist/theme/syntax/tokens.js +5 -2
  302. package/dist/theme/useTheme.d.ts.map +1 -1
  303. package/dist/theme/useTheme.js +6 -7
  304. package/dist/utils/dateParser.d.ts +5 -8
  305. package/dist/utils/dateParser.d.ts.map +1 -1
  306. package/dist/utils/dateParser.js +10 -11
  307. package/dist/utils/focusOutline.stylex.d.ts +25 -0
  308. package/dist/utils/focusOutline.stylex.d.ts.map +1 -1
  309. package/dist/utils/focusOutline.stylex.js +15 -0
  310. package/dist/utils/interactionOverlay.stylex.d.ts +26 -0
  311. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -0
  312. package/dist/utils/interactionOverlay.stylex.js +42 -0
  313. package/dist/utils/isApplePlatform.d.ts +18 -0
  314. package/dist/utils/isApplePlatform.d.ts.map +1 -0
  315. package/dist/utils/isApplePlatform.js +37 -0
  316. package/dist/utils/plainDate.d.ts +11 -0
  317. package/dist/utils/plainDate.d.ts.map +1 -1
  318. package/dist/utils/plainDate.js +20 -4
  319. package/locales/af-ZA.json +7 -7
  320. package/locales/ar-SA.json +7 -7
  321. package/locales/ca-ES.json +6 -6
  322. package/locales/cs-CZ.json +7 -7
  323. package/locales/da-DK.json +7 -7
  324. package/locales/de-DE.json +7 -7
  325. package/locales/el-GR.json +7 -7
  326. package/locales/en.json +178 -6
  327. package/locales/es-ES.json +6 -6
  328. package/locales/fi-FI.json +7 -7
  329. package/locales/fr-FR.json +7 -7
  330. package/locales/he-IL.json +7 -7
  331. package/locales/hu-HU.json +7 -7
  332. package/locales/it-IT.json +7 -7
  333. package/locales/ja-JP.json +7 -7
  334. package/locales/ko-KR.json +7 -7
  335. package/locales/nl-NL.json +7 -7
  336. package/locales/no-NO.json +7 -7
  337. package/locales/pl-PL.json +7 -7
  338. package/locales/pseudo.json +130 -1
  339. package/locales/pt-BR.json +7 -7
  340. package/locales/pt-PT.json +7 -7
  341. package/locales/ro-RO.json +7 -7
  342. package/locales/ru-RU.json +7 -7
  343. package/locales/sr-SP.json +7 -7
  344. package/locales/sv-SE.json +7 -7
  345. package/locales/tr-TR.json +7 -7
  346. package/locales/uk-UA.json +7 -7
  347. package/locales/vi-VN.json +7 -7
  348. package/locales/zh-CN.json +7 -7
  349. package/locales/zh-TW.json +7 -7
  350. package/package.json +4 -5
  351. package/src/AlertDialog/AlertDialog.doc.mjs +114 -30
  352. package/src/AlertDialog/AlertDialog.test.tsx +211 -2
  353. package/src/AlertDialog/AlertDialog.tsx +62 -20
  354. package/src/AspectRatio/AspectRatio.doc.mjs +3 -3
  355. package/src/AspectRatio/AspectRatio.tsx +6 -6
  356. package/src/Avatar/Avatar.doc.mjs +12 -2
  357. package/src/Avatar/Avatar.test.tsx +80 -0
  358. package/src/Avatar/Avatar.tsx +64 -14
  359. package/src/Avatar/index.ts +2 -2
  360. package/src/AvatarGroup/AvatarGroup.doc.mjs +8 -2
  361. package/src/AvatarGroup/AvatarGroup.test.tsx +24 -0
  362. package/src/AvatarGroup/AvatarGroup.tsx +12 -4
  363. package/src/AvatarGroup/AvatarGroupContext.ts +5 -3
  364. package/src/AvatarGroup/AvatarGroupOverflow.tsx +12 -12
  365. package/src/Badge/Badge.doc.mjs +3 -2
  366. package/src/Badge/Badge.test.tsx +32 -3
  367. package/src/Badge/Badge.tsx +42 -1
  368. package/src/Banner/Banner.doc.mjs +9 -0
  369. package/src/Banner/Banner.test.tsx +76 -11
  370. package/src/Banner/Banner.tsx +21 -2
  371. package/src/Button/Button.doc.mjs +2 -1
  372. package/src/Button/Button.test.tsx +19 -4
  373. package/src/Button/Button.tsx +9 -29
  374. package/src/ButtonGroup/ButtonGroup.doc.mjs +2 -2
  375. package/src/ButtonGroup/ButtonGroup.test.tsx +13 -0
  376. package/src/Calendar/Calendar.doc.mjs +4 -4
  377. package/src/Calendar/Calendar.test.tsx +112 -0
  378. package/src/Calendar/Calendar.tsx +18 -16
  379. package/src/Calendar/hooks/useCalendarDays.ts +4 -4
  380. package/src/Calendar/hooks/useCalendarNavigation.ts +4 -4
  381. package/src/Calendar/styles.ts +48 -42
  382. package/src/Card/Card.doc.mjs +10 -7
  383. package/src/Card/Card.test.tsx +113 -19
  384. package/src/Card/Card.tsx +67 -89
  385. package/src/Card/index.ts +36 -1
  386. package/src/Carousel/Carousel.doc.mjs +3 -0
  387. package/src/Carousel/Carousel.test.tsx +360 -0
  388. package/src/Carousel/Carousel.tsx +116 -15
  389. package/src/CheckboxInput/CheckboxInput.doc.mjs +3 -1
  390. package/src/CheckboxInput/CheckboxInput.test.tsx +15 -0
  391. package/src/CheckboxInput/CheckboxInput.tsx +5 -0
  392. package/src/CheckboxList/CheckboxList.doc.mjs +1 -1
  393. package/src/CodeBlock/CodeBlock.doc.mjs +10 -4
  394. package/src/CodeBlock/CodeBlock.test.tsx +37 -0
  395. package/src/CodeBlock/CodeBlock.tsx +20 -4
  396. package/src/CodeBlock/highlightRanges.ts +1 -1
  397. package/src/CodeBlock/highlightStyles.ts +13 -13
  398. package/src/CommandPalette/CommandPaletteItem.tsx +2 -12
  399. package/src/ComplexSelector/ComplexSelector.doc.mjs +9 -2
  400. package/src/ComplexSelector/ComplexSelector.test.tsx +183 -0
  401. package/src/ComplexSelector/ComplexSelector.tsx +22 -12
  402. package/src/DateInput/DateInput.doc.mjs +17 -1
  403. package/src/DateInput/DateInput.test.tsx +9 -4
  404. package/src/DateInput/DateInput.tsx +54 -3
  405. package/src/DateInput/DateInputTouch.test.tsx +146 -32
  406. package/src/DateInput/MonthScroller.tsx +5 -1
  407. package/src/DateInput/MonthYearWheels.tsx +7 -4
  408. package/src/DateInput/NativeDateField.test.tsx +635 -0
  409. package/src/DateInput/NativeDateField.tsx +641 -0
  410. package/src/DateInput/TouchDateField.tsx +83 -33
  411. package/src/DateInput/Wheel.tsx +1 -0
  412. package/src/DateInput/index.ts +1 -0
  413. package/src/DateInput/nativeDateSegments.ts +127 -0
  414. package/src/DateRangeInput/DateRangeInput.doc.mjs +3 -3
  415. package/src/DateRangeInput/DateRangeInput.test.tsx +46 -0
  416. package/src/DateRangeInput/DateRangeInput.tsx +8 -13
  417. package/src/DateTimeInput/DateTimeInput.doc.mjs +39 -22
  418. package/src/DateTimeInput/DateTimeInput.test.tsx +76 -0
  419. package/src/DateTimeInput/DateTimeInput.tsx +54 -20
  420. package/src/DateTimeInput/DateTimeInputTouch.test.tsx +980 -0
  421. package/src/DateTimeInput/TouchDateTimeField.tsx +1437 -0
  422. package/src/Dialog/Dialog.test.tsx +185 -18
  423. package/src/Dialog/Dialog.tsx +35 -11
  424. package/src/DropdownMenu/DropdownMenu.test.tsx +44 -10
  425. package/src/DropdownMenu/DropdownMenu.tsx +4 -13
  426. package/src/Field/Field.doc.mjs +1 -1
  427. package/src/Field/FieldLabel.test.tsx +29 -0
  428. package/src/Field/FieldLabel.tsx +7 -0
  429. package/src/Field/InputClearButton.test.tsx +15 -1
  430. package/src/Field/InputClearButton.tsx +28 -4
  431. package/src/FieldStatus/FieldStatus.doc.mjs +1 -1
  432. package/src/FileInput/FileInput.doc.mjs +1 -1
  433. package/src/Heading/Heading.tsx +0 -1
  434. package/src/HoverCard/HoverCard.doc.mjs +8 -2
  435. package/src/HoverCard/HoverCard.test.tsx +154 -4
  436. package/src/HoverCard/HoverCard.tsx +137 -3
  437. package/src/HoverCard/useHoverCard.tsx +23 -3
  438. package/src/Icon/Icon.test.tsx +55 -1
  439. package/src/Icon/Icon.tsx +5 -3
  440. package/src/Icon/defaultIcons.tsx +11 -2
  441. package/src/Icon/globalIconRegistry.test.tsx +16 -3
  442. package/src/Icon/globalIconRegistry.tsx +37 -6
  443. package/src/Icon/index.ts +1 -0
  444. package/src/Icon/useIcon.ts +9 -2
  445. package/src/Indicator/CheckboxIndicator.tsx +14 -8
  446. package/src/Indicator/Indicator.doc.mjs +3 -1
  447. package/src/InputGroup/InputGroup.doc.mjs +1 -1
  448. package/src/Item/Item.tsx +2 -7
  449. package/src/Kbd/Kbd.test.tsx +0 -17
  450. package/src/Kbd/Kbd.tsx +2 -26
  451. package/src/Layer/gestureCounter.ts +57 -0
  452. package/src/Layer/useLayer.test.tsx +368 -16
  453. package/src/Layer/useLayer.tsx +208 -35
  454. package/src/Layout/__tests__/edgeCompensation.test.tsx +1 -1
  455. package/src/List/List.test.tsx +38 -0
  456. package/src/List/List.tsx +8 -1
  457. package/src/Markdown/Markdown.test.tsx +37 -0
  458. package/src/Markdown/Markdown.tsx +16 -5
  459. package/src/Markdown/parser.test.ts +33 -0
  460. package/src/Markdown/parser.ts +9 -3
  461. package/src/MetadataList/MetadataList.test.tsx +75 -2
  462. package/src/MetadataList/MetadataListItem.tsx +5 -2
  463. package/src/MultiSelector/MultiSelector.doc.mjs +23 -2
  464. package/src/MultiSelector/MultiSelector.test.tsx +205 -0
  465. package/src/MultiSelector/MultiSelector.tsx +103 -16
  466. package/src/MultiSelector/hooks.ts +9 -2
  467. package/src/NavIcon/NavIcon.doc.mjs +8 -2
  468. package/src/NavIcon/NavIcon.test.tsx +9 -0
  469. package/src/NavIcon/NavIcon.tsx +5 -1
  470. package/src/NavItem/navItemStyles.stylex.ts +0 -8
  471. package/src/NavMenu/NavHeadingMenu.test.tsx +30 -0
  472. package/src/NavMenu/NavHeadingMenu.tsx +7 -4
  473. package/src/NumberInput/NumberInput.doc.mjs +27 -8
  474. package/src/NumberInput/NumberInput.test.tsx +563 -8
  475. package/src/NumberInput/NumberInput.tsx +77 -131
  476. package/src/NumberInput/numberInputCommit.test.ts +72 -0
  477. package/src/NumberInput/numberInputCommit.ts +103 -0
  478. package/src/NumberInput/numberParser.docblock.test.ts +234 -0
  479. package/src/NumberInput/numberParser.test.ts +222 -0
  480. package/src/NumberInput/numberParser.ts +403 -0
  481. package/src/Outline/Outline.tsx +2 -4
  482. package/src/OverflowList/OverflowList.doc.mjs +102 -21
  483. package/src/OverflowList/OverflowList.test.tsx +550 -4
  484. package/src/OverflowList/OverflowList.tsx +100 -2
  485. package/src/Pagination/Pagination.test.tsx +3 -2
  486. package/src/Popover/Popover.doc.mjs +2 -2
  487. package/src/Popover/Popover.test.tsx +38 -0
  488. package/src/Popover/Popover.tsx +28 -66
  489. package/src/Popover/usePopover.tsx +44 -5
  490. package/src/PowerSearch/PowerSearch.doc.mjs +1 -1
  491. package/src/PowerSearch/PowerSearchEditPopover.test.tsx +87 -0
  492. package/src/PowerSearch/PowerSearchValueEditor.test.tsx +64 -0
  493. package/src/PowerSearch/PowerSearchValueEditor.tsx +109 -10
  494. package/src/PowerSearch/formatFilterValue.test.ts +16 -1
  495. package/src/PowerSearch/formatFilterValue.ts +2 -0
  496. package/src/ProgressBar/ProgressBar.doc.mjs +42 -6
  497. package/src/ProgressBar/ProgressBar.test.tsx +24 -0
  498. package/src/ProgressBar/ProgressBar.tsx +28 -8
  499. package/src/RadioList/RadioList.doc.mjs +1 -1
  500. package/src/Resizable/Resizable.doc.mjs +2 -2
  501. package/src/Resizable/useResizable.doc.mjs +21 -2
  502. package/src/Resizable/useResizable.test.ts +421 -0
  503. package/src/Resizable/useResizable.ts +133 -48
  504. package/src/SelectableCard/SelectableCard.doc.mjs +3 -0
  505. package/src/SelectableCard/SelectableCard.tsx +16 -0
  506. package/src/Selector/Selector.doc.mjs +15 -1
  507. package/src/Selector/Selector.source-build.test.mjs +65 -0
  508. package/src/Selector/Selector.test.tsx +301 -0
  509. package/src/Selector/Selector.tsx +145 -32
  510. package/src/Selector/hooks.ts +17 -2
  511. package/src/SideNav/SideNav.doc.mjs +2 -2
  512. package/src/SideNav/SideNav.test.tsx +1069 -6
  513. package/src/SideNav/SideNav.tsx +109 -38
  514. package/src/SideNav/SideNavHeading.tsx +5 -2
  515. package/src/SideNav/SideNavItem.doc.mjs +24 -3
  516. package/src/SideNav/SideNavItem.tsx +134 -44
  517. package/src/Slider/Slider.doc.mjs +2 -2
  518. package/src/Slider/Slider.test.tsx +106 -1
  519. package/src/Slider/Slider.tsx +52 -1
  520. package/src/Spinner/Spinner.doc.mjs +17 -5
  521. package/src/Spinner/Spinner.test.tsx +164 -0
  522. package/src/Spinner/Spinner.tsx +252 -22
  523. package/src/StatusDot/StatusDot.doc.mjs +8 -2
  524. package/src/StatusDot/StatusDot.test.tsx +9 -0
  525. package/src/StatusDot/StatusDot.tsx +7 -1
  526. package/src/Stepper/Step.doc.mjs +1 -1
  527. package/src/Stepper/Step.tsx +7 -14
  528. package/src/Switch/Switch.doc.mjs +3 -1
  529. package/src/Switch/Switch.test.tsx +10 -0
  530. package/src/Switch/Switch.tsx +3 -0
  531. package/src/Table/BaseTable.tsx +6 -1
  532. package/src/Table/Table.doc.mjs +5 -3
  533. package/src/Table/Table.tsx +3 -8
  534. package/src/Table/TableBody.doc.mjs +2 -2
  535. package/src/Table/TableFooter.doc.mjs +1 -1
  536. package/src/Table/TableHeader.doc.mjs +1 -1
  537. package/src/Table/plugins/filtering/useTableFiltering.test.tsx +44 -6
  538. package/src/Table/plugins/filtering/useTableFiltering.tsx +100 -4
  539. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +50 -4
  540. package/src/Table/plugins/selection/useTableSelection.test.tsx +62 -0
  541. package/src/Table/plugins/selection/useTableSelection.tsx +25 -2
  542. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +1 -2
  543. package/src/Table/useTableGroupedRows.doc.mjs +3 -3
  544. package/src/Table/useTablePagination.doc.mjs +1 -1
  545. package/src/Table/useTableSelection.doc.mjs +1 -1
  546. package/src/Text/Text.test.tsx +44 -0
  547. package/src/Text/Text.tsx +0 -1
  548. package/src/TextArea/TextArea.doc.mjs +13 -3
  549. package/src/TextArea/TextArea.test.tsx +11 -0
  550. package/src/TextArea/TextArea.tsx +34 -22
  551. package/src/TextInput/TextInput.doc.mjs +1 -1
  552. package/src/TimeInput/TimeInput.doc.mjs +1 -1
  553. package/src/Timestamp/Timestamp.test.tsx +89 -0
  554. package/src/Timestamp/Timestamp.tsx +8 -8
  555. package/src/Timestamp/formatInstant.ts +5 -0
  556. package/src/Toast/Toast.doc.mjs +213 -44
  557. package/src/Toast/Toast.tsx +118 -23
  558. package/src/Toast/ToastViewport.test.tsx +1434 -8
  559. package/src/Toast/ToastViewport.tsx +85 -14
  560. package/src/Toast/index.ts +2 -0
  561. package/src/Toast/types.ts +43 -5
  562. package/src/Toast/useToastGesture.ts +361 -0
  563. package/src/Token/Token.test.tsx +95 -0
  564. package/src/Token/Token.tsx +19 -17
  565. package/src/Token/TokenLink.tsx +12 -3
  566. package/src/Tokenizer/Tokenizer.doc.mjs +17 -4
  567. package/src/Tokenizer/Tokenizer.test.tsx +161 -0
  568. package/src/Tokenizer/Tokenizer.tsx +49 -24
  569. package/src/TopNav/TopNavHeading.tsx +2 -2
  570. package/src/TopNav/TopNavItem.tsx +3 -7
  571. package/src/TopNav/TopNavMegaMenu.test.tsx +104 -0
  572. package/src/TopNav/TopNavMegaMenu.tsx +47 -4
  573. package/src/TopNav/TopNavMegaMenuItem.tsx +10 -9
  574. package/src/TopNav/TopNavMenu.test.tsx +133 -1
  575. package/src/TopNav/TopNavMenu.tsx +38 -5
  576. package/src/TreeList/TreeList.test.tsx +49 -0
  577. package/src/TreeList/TreeList.tsx +7 -2
  578. package/src/TreeList/TreeListItem.tsx +2 -7
  579. package/src/Typeahead/BaseTypeahead.doc.mjs +13 -0
  580. package/src/Typeahead/BaseTypeahead.tsx +96 -6
  581. package/src/Typeahead/Typeahead.doc.mjs +7 -1
  582. package/src/Typeahead/Typeahead.test.tsx +154 -0
  583. package/src/Typeahead/Typeahead.tsx +9 -0
  584. package/src/Typeahead/TypeaheadItem.test.tsx +43 -0
  585. package/src/Typeahead/TypeaheadItem.tsx +8 -1
  586. package/src/hooks/useAnnounce.doc.mjs +96 -0
  587. package/src/hooks/useDevWarning.doc.mjs +96 -0
  588. package/src/hooks/useHotkeys.test.ts +0 -18
  589. package/src/hooks/useHotkeys.ts +3 -25
  590. package/src/hooks/useIndicatorFocusRing.doc.mjs +104 -0
  591. package/src/hooks/useInputStatusIcon.doc.mjs +142 -0
  592. package/src/hooks/useInteractiveRole.doc.mjs +119 -0
  593. package/src/hooks/useLongPress.doc.mjs +123 -0
  594. package/src/hooks/useOverflow.doc.mjs +58 -17
  595. package/src/hooks/useOverflow.ts +16 -4
  596. package/src/hooks/useTypeahead.doc.mjs +153 -0
  597. package/src/i18n/InternationalizationContext.ts +3 -0
  598. package/src/i18n/InternationalizationProvider.tsx +8 -1
  599. package/src/i18n/__tests__/resolve.test.ts +23 -1
  600. package/src/i18n/resolve.ts +46 -49
  601. package/src/i18n/useTranslator.ts +2 -7
  602. package/src/index.ts +2 -0
  603. package/src/raw-import.d.ts +14 -0
  604. package/src/theme/Theme.test.tsx +104 -2
  605. package/src/theme/Theme.tsx +49 -14
  606. package/src/theme/defineTheme.test.ts +23 -0
  607. package/src/theme/defineTheme.ts +12 -3
  608. package/src/theme/derivedVarRegistry.test.ts +87 -3
  609. package/src/theme/derivedVarRegistry.ts +23 -4
  610. package/src/theme/generateThemeRules.test.ts +99 -1
  611. package/src/theme/generateThemeRules.ts +28 -0
  612. package/src/theme/syntax/tokens.ts +5 -2
  613. package/src/theme/useTheme.test.tsx +10 -0
  614. package/src/theme/useTheme.ts +16 -10
  615. package/src/utils/dateParser.test.ts +34 -2
  616. package/src/utils/dateParser.ts +11 -14
  617. package/src/utils/focusOutline.stylex.ts +50 -0
  618. package/src/utils/interactionOverlay.stylex.ts +74 -0
  619. package/src/utils/isApplePlatform.test.ts +61 -0
  620. package/src/utils/isApplePlatform.ts +37 -0
  621. package/src/utils/plainDate.test.ts +46 -0
  622. package/src/utils/plainDate.ts +18 -3
@@ -11,13 +11,20 @@
11
11
 
12
12
  import type {ReactNode} from 'react';
13
13
  import {useThemeName} from '../theme/useTheme';
14
- import {getIcon, type IconName} from './globalIconRegistry';
14
+ import {
15
+ getIcon,
16
+ type IconName,
17
+ type NamespacedIconName,
18
+ } from './globalIconRegistry';
15
19
 
16
20
  /**
17
21
  * Resolve a semantic icon name from the nearest Theme, falling back through
18
22
  * root theme registration, global icon overrides, and built-in defaults.
23
+ *
24
+ * Accepts a namespaced extension key (`'richtext:bold'`) as well as a built-in
25
+ * name; both resolve through the same registry.
19
26
  */
20
- export function useIcon(name: IconName): ReactNode {
27
+ export function useIcon(name: IconName | NamespacedIconName): ReactNode {
21
28
  const themeName = useThemeName();
22
29
  return getIcon(name, themeName);
23
30
  }
@@ -227,10 +227,13 @@ export function CheckboxIndicator({
227
227
  <>
228
228
  <svg
229
229
  viewBox="0 0 10 10"
230
- {...stylex.props(
231
- styles.checkmark,
232
- checkmarkSizeStyles[size],
233
- isChecked && styles.checkmarkVisible,
230
+ {...mergeProps(
231
+ themeProps('checkbox-indicator-check', {size}),
232
+ stylex.props(
233
+ styles.checkmark,
234
+ checkmarkSizeStyles[size],
235
+ isChecked && styles.checkmarkVisible,
236
+ ),
234
237
  )}>
235
238
  <path
236
239
  d="M8.5 2.5L4 7.5L1.5 5"
@@ -242,10 +245,13 @@ export function CheckboxIndicator({
242
245
  />
243
246
  </svg>
244
247
  <span
245
- {...stylex.props(
246
- styles.indeterminateMark,
247
- indeterminateSizeStyles[size],
248
- isIndeterminate && styles.indeterminateMarkVisible,
248
+ {...mergeProps(
249
+ themeProps('checkbox-indicator-dash', {size}),
250
+ stylex.props(
251
+ styles.indeterminateMark,
252
+ indeterminateSizeStyles[size],
253
+ isIndeterminate && styles.indeterminateMarkVisible,
254
+ ),
249
255
  )}
250
256
  />
251
257
  </>
@@ -6,7 +6,7 @@ export const docs = {
6
6
  name: 'Indicator',
7
7
  displayName: 'Indicator',
8
8
  group: 'Indicator',
9
- category: 'Data Input',
9
+ category: 'Form Controls',
10
10
  isHiddenFromOverview: true,
11
11
  keywords: [
12
12
  'indicator',
@@ -132,6 +132,8 @@ export const docs = {
132
132
  visualProps: ['size'],
133
133
  states: ['checked', 'disabled'],
134
134
  },
135
+ {className: 'astryx-checkbox-indicator-check', visualProps: ['size']},
136
+ {className: 'astryx-checkbox-indicator-dash', visualProps: ['size']},
135
137
  {
136
138
  className: 'astryx-radio-indicator',
137
139
  visualProps: ['size'],
@@ -6,7 +6,7 @@ export const docs = {
6
6
  name: 'InputGroup',
7
7
  displayName: 'Input Group',
8
8
  group: 'Field',
9
- category: 'Data Input',
9
+ category: 'Form Controls',
10
10
  isHiddenFromOverview: true,
11
11
  keywords: [
12
12
  'inputgroup',
package/src/Item/Item.tsx CHANGED
@@ -35,6 +35,7 @@ import {useClickableContainer} from '../hooks/useClickableContainer';
35
35
  import {useDevWarning} from '../hooks/useDevWarning';
36
36
  import {themeProps} from '../utils/themeProps';
37
37
  import {focusOutlineProps} from '../utils/focusOutline.stylex';
38
+ import {interactionOverlayStyles} from '../utils/interactionOverlay.stylex';
38
39
 
39
40
  // =============================================================================
40
41
  // Types
@@ -224,13 +225,6 @@ const styles = stylex.create({
224
225
  transitionProperty: 'background-color',
225
226
  transitionDuration: durationVars['--duration-fast-min'],
226
227
  transitionTimingFunction: easeVars['--ease-standard'],
227
- backgroundColor: {
228
- default: 'transparent',
229
- ':hover:where(:not(:disabled,[aria-disabled="true"]))': {
230
- '@media (hover: hover)': colorVars['--color-overlay-hover'],
231
- },
232
- ':active': colorVars['--color-overlay-pressed'],
233
- },
234
228
  },
235
229
  highlighted: {
236
230
  backgroundColor: colorVars['--color-overlay-hover'],
@@ -603,6 +597,7 @@ export function Item({
603
597
  densityStyles[density],
604
598
  align === 'start' && styles.alignStart,
605
599
  isInteractive && styles.interactive,
600
+ isInteractive && interactionOverlayStyles.backgroundColor,
606
601
  isHighlighted && styles.highlighted,
607
602
  isSelected && styles.selected,
608
603
  isDisabled && !hasParentRole && styles.disabled,
@@ -23,7 +23,6 @@ describe('Kbd', () => {
23
23
  value: originalPlatform,
24
24
  configurable: true,
25
25
  });
26
- delete (navigator as {userAgentData?: unknown}).userAgentData;
27
26
  });
28
27
 
29
28
  it('renders a single key', () => {
@@ -55,22 +54,6 @@ describe('Kbd', () => {
55
54
  expect(screen.getByText('\u2318')).toBeInTheDocument(); // \u2318
56
55
  });
57
56
 
58
- it('reads a blank userAgentData.platform as unknown, not as non-Mac', () => {
59
- // Builds that rewrite their client-hints identity expose the key with an
60
- // empty value; navigator.platform is the only surface left that answers.
61
- Object.defineProperty(navigator, 'userAgentData', {
62
- value: {platform: ''},
63
- configurable: true,
64
- });
65
- Object.defineProperty(navigator, 'platform', {
66
- value: 'MacIntel',
67
- configurable: true,
68
- });
69
-
70
- render(<Kbd keys="mod" />);
71
- expect(screen.getByText('\u2318')).toBeInTheDocument();
72
- });
73
-
74
57
  it('maps modifier keys to symbols', () => {
75
58
  render(<Kbd keys="ctrl+alt+shift+k" />);
76
59
  expect(screen.getByText('\u2303')).toBeInTheDocument(); // \u2303
package/src/Kbd/Kbd.tsx CHANGED
@@ -16,6 +16,7 @@
16
16
  import React, {useSyncExternalStore} from 'react';
17
17
  import * as stylex from '@stylexjs/stylex';
18
18
  import {mergeProps} from '../utils';
19
+ import {isApplePlatform} from '../utils/isApplePlatform';
19
20
  import type {BaseProps} from '../BaseProps';
20
21
  import {themeProps} from '../utils/themeProps';
21
22
  import {
@@ -122,31 +123,6 @@ function getServerPlatformSnapshot(): boolean {
122
123
  return false;
123
124
  }
124
125
 
125
- /**
126
- * Detects whether the current platform is macOS/iOS.
127
- * Prefers the User-Agent Client Hints API when it names a platform (modern
128
- * Chrome/Edge), falls back to navigator.platform (deprecated but universally
129
- * supported) when it is absent or blank.
130
- */
131
- function detectMac(): boolean {
132
- if (typeof navigator === 'undefined') {
133
- return false;
134
- }
135
- // Prefer User-Agent Client Hints API (not deprecated)
136
- const uaData = 'userAgentData' in navigator ? navigator.userAgentData : null;
137
- if (uaData && typeof uaData === 'object' && 'platform' in uaData) {
138
- const uaPlatform = (uaData as {platform?: unknown}).platform;
139
- // A blank platform is no answer, not a negative one. Builds that rewrite
140
- // their client-hints identity ship '', so fall through rather than
141
- // reading it as "not Apple".
142
- if (typeof uaPlatform === 'string' && uaPlatform.trim() !== '') {
143
- return /mac/i.test(uaPlatform);
144
- }
145
- }
146
- // Fallback: navigator.platform (deprecated but still shipped everywhere)
147
- return /Mac|iPhone|iPad|iPod/.test(navigator.platform ?? '');
148
- }
149
-
150
126
  export interface KbdProps extends BaseProps<HTMLSpanElement> {
151
127
  ref?: React.Ref<HTMLSpanElement>;
152
128
  /**
@@ -183,7 +159,7 @@ export interface KbdProps extends BaseProps<HTMLSpanElement> {
183
159
  export function Kbd({keys, ref, xstyle, className, style, ...rest}: KbdProps) {
184
160
  const isMac = useSyncExternalStore(
185
161
  subscribeToPlatformChanges,
186
- detectMac,
162
+ isApplePlatform,
187
163
  getServerPlatformSnapshot,
188
164
  );
189
165
 
@@ -0,0 +1,57 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file gestureCounter.ts
7
+ * @input Listens for pointerdown, keydown, and click on the document
8
+ * @output Exports the current gesture identity and whether its click has run
9
+ * @position Internal to Layer; used by useLayer to tell a click that belongs
10
+ * to a dismissing press from a fresh one
11
+ *
12
+ * A browser light-dismiss and the trigger's own click come from ONE press, and
13
+ * which of them React sees first is a race. Comparing timestamps against a
14
+ * window guesses; counting gestures does not. The counter advances on every
15
+ * new press or keystroke, so "the click from the gesture that dismissed the
16
+ * layer" is exactly "the click while the counter still reads what it read at
17
+ * the dismissal", no matter how long the main thread was blocked in between.
18
+ */
19
+
20
+ let gesture = 0;
21
+ let clickedGesture: number | null = null;
22
+ let isListening = false;
23
+
24
+ function advance() {
25
+ gesture += 1;
26
+ }
27
+
28
+ function markClicked() {
29
+ clickedGesture = gesture;
30
+ }
31
+
32
+ function listen() {
33
+ if (isListening || typeof document === 'undefined') {
34
+ return;
35
+ }
36
+ isListening = true;
37
+ // Capture phase: the count must advance before any handler reads it.
38
+ document.addEventListener('pointerdown', advance, true);
39
+ document.addEventListener('keydown', advance, true);
40
+ // Capture phase observes the click even when a consumer stops propagation.
41
+ document.addEventListener('click', markClicked, true);
42
+ }
43
+
44
+ /**
45
+ * Identifies the user gesture in flight. Two reads returning the same value
46
+ * happened within one press (or one keystroke).
47
+ */
48
+ export function currentGesture(): number {
49
+ listen();
50
+ return gesture;
51
+ }
52
+
53
+ /** Whether the click belonging to the current gesture already bubbled. */
54
+ export function currentGestureHasClicked(): boolean {
55
+ listen();
56
+ return clickedGesture === gesture;
57
+ }
@@ -10,13 +10,28 @@
10
10
  */
11
11
 
12
12
  import {describe, it, expect, vi, afterEach} from 'vitest';
13
- import {render, act, fireEvent, waitFor} from '@testing-library/react';
13
+ import {
14
+ render,
15
+ renderHook,
16
+ act,
17
+ fireEvent,
18
+ waitFor,
19
+ } from '@testing-library/react';
14
20
  import userEvent from '@testing-library/user-event';
15
- import {useLayer, getPositionTryFallbacks} from './useLayer';
21
+ import * as stylex from '@stylexjs/stylex';
22
+ import {
23
+ useKeepLayerOpenProps,
24
+ useLayer,
25
+ useLayerInternal,
26
+ getPositionTryFallbacks,
27
+ } from './useLayer';
28
+ import {typeScaleVars} from '../theme/tokens.stylex';
16
29
  import type {
17
30
  LayerPlacement,
18
31
  LayerAlignment,
19
32
  ContextRenderProps,
33
+ ContextLayerReturn,
34
+ FixedLayerReturn,
20
35
  } from './useLayer';
21
36
 
22
37
  function mockCSSStyleDeclaration(
@@ -137,6 +152,43 @@ function RelocatingOpenContextHostingHarness({
137
152
  );
138
153
  }
139
154
 
155
+ describe('useLayer identity', () => {
156
+ it('keeps the context ref and API object stable across rerenders', () => {
157
+ const {result, rerender} = renderHook(() => useLayer({mode: 'context'}));
158
+ const first = result.current;
159
+
160
+ rerender();
161
+
162
+ expect(result.current.ref).toBe(first.ref);
163
+ expect(result.current).toBe(first);
164
+ });
165
+
166
+ it('keeps the context ref stable when callbacks change', () => {
167
+ const firstOnShow = vi.fn();
168
+ const secondOnShow = vi.fn();
169
+ const {result, rerender} = renderHook(
170
+ ({onShow}: {onShow: () => void}) => useLayer({mode: 'context', onShow}),
171
+ {initialProps: {onShow: firstOnShow}},
172
+ );
173
+ const first = result.current;
174
+ const firstRef = result.current.ref;
175
+
176
+ rerender({onShow: secondOnShow});
177
+
178
+ expect(result.current).not.toBe(first);
179
+ expect(result.current.ref).toBe(firstRef);
180
+ });
181
+
182
+ it('keeps the fixed API object stable across rerenders', () => {
183
+ const {result, rerender} = renderHook(() => useLayer({mode: 'fixed'}));
184
+ const first = result.current;
185
+
186
+ rerender();
187
+
188
+ expect(result.current).toBe(first);
189
+ });
190
+ });
191
+
140
192
  describe('getPositionTryFallbacks (issue #3671)', () => {
141
193
  const FLIPS = 'flip-block, flip-inline, flip-block flip-inline';
142
194
 
@@ -500,20 +552,6 @@ describe('useLayer', () => {
500
552
  });
501
553
 
502
554
  describe('when the Popover API is supported', () => {
503
- it('declares body type instead of inheriting the host context', () => {
504
- const {container} = render(
505
- <div style={{fontSize: '30px', lineHeight: '3'}}>
506
- <LayerHarness onReady={() => {}} />
507
- </div>,
508
- );
509
-
510
- const layer = container.querySelector('[popover]') as HTMLElement;
511
- expect(layer).toHaveStyle({
512
- fontSize: 'var(--text-body-size)',
513
- lineHeight: 'var(--text-body-leading)',
514
- });
515
- });
516
-
517
555
  it('calls showPopover/hidePopover on show/hide', () => {
518
556
  const showSpy = vi.fn();
519
557
  const hideSpy = vi.fn();
@@ -614,6 +652,66 @@ async function openAndGetStyle(ui: React.ReactElement): Promise<string> {
614
652
  return popover?.getAttribute('style') ?? '';
615
653
  }
616
654
 
655
+ describe('typography baseline', () => {
656
+ const overrideStyles = stylex.create({
657
+ supporting: {fontSize: typeScaleVars['--text-supporting-size']},
658
+ });
659
+
660
+ function TypographyHarness({
661
+ ambientFontSize,
662
+ xstyle,
663
+ }: {
664
+ ambientFontSize: string;
665
+ xstyle?: ContextRenderProps['xstyle'];
666
+ }) {
667
+ const layer = useLayer({mode: 'context'});
668
+ return (
669
+ <div style={{fontSize: ambientFontSize, lineHeight: '3'}}>
670
+ <button type="button" ref={layer.ref} onClick={layer.show}>
671
+ trigger
672
+ </button>
673
+ {layer.render(<span>content</span>, {xstyle})}
674
+ </div>
675
+ );
676
+ }
677
+
678
+ async function openAndGetType(ui: React.ReactElement) {
679
+ const user = userEvent.setup();
680
+ const {container, getByRole} = render(ui);
681
+ await user.click(getByRole('button', {name: 'trigger'}));
682
+ const el = container.querySelector('[popover]') as HTMLElement;
683
+ const computed = window.getComputedStyle(el);
684
+ return {fontSize: computed.fontSize, lineHeight: computed.lineHeight};
685
+ }
686
+
687
+ // jsdom resolves no var() indirection, so the token reference is what the
688
+ // assertion can see — the point is that a declaration exists at all, since
689
+ // an absent one is exactly what let the ambient size through.
690
+ it.each(['13px', '20px'])(
691
+ 'takes the body role rather than the surrounding %s',
692
+ async ambientFontSize => {
693
+ expect(
694
+ await openAndGetType(
695
+ <TypographyHarness ambientFontSize={ambientFontSize} />,
696
+ ),
697
+ ).toEqual({
698
+ fontSize: 'var(--text-body-size)',
699
+ lineHeight: 'var(--text-body-leading)',
700
+ });
701
+ },
702
+ );
703
+
704
+ it('still lets a consumer xstyle set its own size', async () => {
705
+ const {fontSize} = await openAndGetType(
706
+ <TypographyHarness
707
+ ambientFontSize="13px"
708
+ xstyle={overrideStyles.supporting}
709
+ />,
710
+ );
711
+ expect(fontSize).toBe('var(--text-supporting-size)');
712
+ });
713
+ });
714
+
617
715
  describe('useLayer context positioning', () => {
618
716
  // The mapping uses the self-* logical keyword family, so the emitted
619
717
  // string is direction-independent by construction: the browser resolves
@@ -873,3 +971,257 @@ describe('useLayer context positioning', () => {
873
971
  expect(style).not.toContain('position-anchor');
874
972
  });
875
973
  });
974
+
975
+ describe('useLayer public return types', () => {
976
+ it('keeps dismissal helpers internal', () => {
977
+ const contextHasKeepOpenProps: 'keepOpenProps' extends keyof ContextLayerReturn
978
+ ? true
979
+ : false = false;
980
+ const fixedHasKeepOpenProps: 'keepOpenProps' extends keyof FixedLayerReturn
981
+ ? true
982
+ : false = false;
983
+ const contextHasGuard: 'wasJustDismissed' extends keyof ContextLayerReturn
984
+ ? true
985
+ : false = false;
986
+ const fixedHasGuard: 'wasJustDismissed' extends keyof FixedLayerReturn
987
+ ? true
988
+ : false = false;
989
+
990
+ expect(contextHasKeepOpenProps).toBe(false);
991
+ expect(fixedHasKeepOpenProps).toBe(false);
992
+ expect(contextHasGuard).toBe(false);
993
+ expect(fixedHasGuard).toBe(false);
994
+ });
995
+ });
996
+
997
+ describe('internal keep-open props (controls on the trigger, #5004)', () => {
998
+ function ClearableTriggerHarness() {
999
+ const layer = useLayer({mode: 'context'});
1000
+ const keepOpenProps = useKeepLayerOpenProps(layer.id, layer.isOpen);
1001
+ return (
1002
+ <>
1003
+ <button type="button" ref={layer.ref} onClick={layer.show}>
1004
+ Trigger
1005
+ </button>
1006
+ <button type="button" {...keepOpenProps}>
1007
+ Clear
1008
+ </button>
1009
+ {layer.render(<span>Layer content</span>, {placement: 'below'})}
1010
+ </>
1011
+ );
1012
+ }
1013
+
1014
+ it('names the control an invoker for the duration of the press', async () => {
1015
+ const user = userEvent.setup();
1016
+ const {container, getByRole} = render(<ClearableTriggerHarness />);
1017
+ const clear = getByRole('button', {name: 'Clear'});
1018
+
1019
+ await user.click(getByRole('button', {name: 'Trigger'}));
1020
+ const popover = container.querySelector('[popover]') as HTMLElement;
1021
+
1022
+ await user.pointer({keys: '[MouseLeft>]', target: clear});
1023
+ expect(clear.getAttribute('popovertarget')).toBe(popover.id);
1024
+
1025
+ await user.pointer({keys: '[/MouseLeft]', target: clear});
1026
+ expect(clear).not.toHaveAttribute('popovertarget');
1027
+ });
1028
+
1029
+ it('takes the invoker off when the press ends in pointercancel', async () => {
1030
+ const user = userEvent.setup();
1031
+ const {container, getByRole} = render(<ClearableTriggerHarness />);
1032
+ const clear = getByRole('button', {name: 'Clear'});
1033
+
1034
+ await user.click(getByRole('button', {name: 'Trigger'}));
1035
+ const popover = container.querySelector('[popover]') as HTMLElement;
1036
+
1037
+ await user.pointer({keys: '[MouseLeft>]', target: clear});
1038
+ expect(clear.getAttribute('popovertarget')).toBe(popover.id);
1039
+
1040
+ // A touch the browser claims — for a scroll, for the platform's long-press
1041
+ // menu — ends here, and no pointerup ever arrives.
1042
+ await act(async () => {
1043
+ document.dispatchEvent(new Event('pointercancel'));
1044
+ await new Promise(resolve => {
1045
+ window.setTimeout(resolve, 0);
1046
+ });
1047
+ });
1048
+
1049
+ expect(clear).not.toHaveAttribute('popovertarget');
1050
+ });
1051
+
1052
+ it('leaves the control alone while the layer is closed', async () => {
1053
+ const user = userEvent.setup();
1054
+ const {getByRole} = render(<ClearableTriggerHarness />);
1055
+ const clear = getByRole('button', {name: 'Clear'});
1056
+
1057
+ await user.click(clear);
1058
+
1059
+ expect(clear).not.toHaveAttribute('popovertarget');
1060
+ });
1061
+
1062
+ it("cancels the invoker's own toggle so the press cannot close the layer", async () => {
1063
+ const user = userEvent.setup();
1064
+ const {container, getByRole} = render(<ClearableTriggerHarness />);
1065
+ await user.click(getByRole('button', {name: 'Trigger'}));
1066
+ const popover = container.querySelector('[popover]') as HTMLElement;
1067
+ const clear = getByRole('button', {name: 'Clear'});
1068
+
1069
+ const click = new MouseEvent('click', {bubbles: true, cancelable: true});
1070
+ await act(async () => {
1071
+ clear.setAttribute('popovertarget', popover.id);
1072
+ clear.dispatchEvent(click);
1073
+ });
1074
+
1075
+ expect(click.defaultPrevented).toBe(true);
1076
+ expect(clear).not.toHaveAttribute('popovertarget');
1077
+ });
1078
+ });
1079
+
1080
+ describe('wasJustDismissed (light dismiss vs. the trigger click, #5004)', () => {
1081
+ function GuardedTriggerHarness() {
1082
+ const layer = useLayerInternal({mode: 'context'});
1083
+ return (
1084
+ <>
1085
+ <button
1086
+ type="button"
1087
+ ref={layer.ref}
1088
+ onClick={() => {
1089
+ if (layer.wasJustDismissed()) {
1090
+ return;
1091
+ }
1092
+ if (layer.isOpen) {
1093
+ layer.hide();
1094
+ } else {
1095
+ layer.show();
1096
+ }
1097
+ }}>
1098
+ Trigger
1099
+ </button>
1100
+ <span data-testid="state">{layer.isOpen ? 'open' : 'closed'}</span>
1101
+ {layer.render(<span>Layer content</span>, {placement: 'below'})}
1102
+ </>
1103
+ );
1104
+ }
1105
+
1106
+ /**
1107
+ * The browser closing the layer itself: it hides the element and queues a
1108
+ * `toggle` event, which is what reaches React — before the click, on the
1109
+ * engines that lose the race.
1110
+ */
1111
+ function lightDismiss(container: HTMLElement) {
1112
+ const popover = container.querySelector('[popover]') as HTMLElement;
1113
+ act(() => {
1114
+ popover.dispatchEvent(
1115
+ Object.assign(new Event('toggle'), {
1116
+ oldState: 'open',
1117
+ newState: 'closed',
1118
+ }),
1119
+ );
1120
+ });
1121
+ }
1122
+
1123
+ it('absorbs the trigger click that follows a light dismiss', async () => {
1124
+ const user = userEvent.setup();
1125
+ const {container, getByRole, getByTestId} = render(
1126
+ <GuardedTriggerHarness />,
1127
+ );
1128
+ const trigger = getByRole('button', {name: 'Trigger'});
1129
+
1130
+ await user.click(trigger);
1131
+ expect(getByTestId('state')).toHaveTextContent('open');
1132
+
1133
+ // The next press reaches the browser dismissal before its click.
1134
+ fireEvent.pointerDown(trigger);
1135
+ lightDismiss(container);
1136
+ fireEvent.click(trigger);
1137
+
1138
+ expect(getByTestId('state')).toHaveTextContent('closed');
1139
+ });
1140
+
1141
+ it('acts on a deliberate second press', async () => {
1142
+ const user = userEvent.setup();
1143
+ const {container, getByRole, getByTestId} = render(
1144
+ <GuardedTriggerHarness />,
1145
+ );
1146
+ const trigger = getByRole('button', {name: 'Trigger'});
1147
+
1148
+ await user.click(trigger);
1149
+ fireEvent.pointerDown(trigger);
1150
+ lightDismiss(container);
1151
+ fireEvent.click(trigger);
1152
+ // A press of its own — a new gesture, however soon it lands.
1153
+ await user.click(trigger);
1154
+
1155
+ expect(getByTestId('state')).toHaveTextContent('open');
1156
+ });
1157
+
1158
+ it('leaves a programmatic hide unguarded', async () => {
1159
+ const user = userEvent.setup();
1160
+ const {getByRole, getByTestId} = render(<GuardedTriggerHarness />);
1161
+ const trigger = getByRole('button', {name: 'Trigger'});
1162
+
1163
+ // Three presses with no browser-initiated close between them.
1164
+ await user.click(trigger);
1165
+ await user.click(trigger);
1166
+ await user.click(trigger);
1167
+
1168
+ expect(getByTestId('state')).toHaveTextContent('open');
1169
+ });
1170
+
1171
+ it('acts on a synthesized click after a stopped click-first dismissal', async () => {
1172
+ const user = userEvent.setup();
1173
+ const {container, getByRole, getByTestId} = render(
1174
+ <GuardedTriggerHarness />,
1175
+ );
1176
+ const trigger = getByRole('button', {name: 'Trigger'});
1177
+
1178
+ await user.click(trigger);
1179
+ fireEvent.pointerDown(document.body);
1180
+ document.body.addEventListener('click', event => event.stopPropagation(), {
1181
+ once: true,
1182
+ });
1183
+ fireEvent.click(document.body);
1184
+ lightDismiss(container);
1185
+ expect(getByTestId('state')).toHaveTextContent('closed');
1186
+
1187
+ // Chromium delivers the dismissing click before the queued toggle. A later
1188
+ // bare click is a new activation even though it has no pointerdown.
1189
+ act(() => {
1190
+ trigger.click();
1191
+ });
1192
+
1193
+ expect(getByTestId('state')).toHaveTextContent('open');
1194
+ });
1195
+
1196
+ /** A trigger that calls show()/hide() directly, checking nothing. */
1197
+ function PlainTriggerHarness() {
1198
+ const layer = useLayerInternal({mode: 'context'});
1199
+ return (
1200
+ <>
1201
+ <button
1202
+ type="button"
1203
+ ref={layer.ref}
1204
+ onClick={() => (layer.isOpen ? layer.hide() : layer.show())}>
1205
+ Trigger
1206
+ </button>
1207
+ <span data-testid="state">{layer.isOpen ? 'open' : 'closed'}</span>
1208
+ {layer.render(<span>Layer content</span>, {placement: 'below'})}
1209
+ </>
1210
+ );
1211
+ }
1212
+
1213
+ it('absorbs the click for a trigger that never calls wasJustDismissed', async () => {
1214
+ const user = userEvent.setup();
1215
+ const {container, getByRole, getByTestId} = render(<PlainTriggerHarness />);
1216
+ const trigger = getByRole('button', {name: 'Trigger'});
1217
+
1218
+ await user.click(trigger);
1219
+ expect(getByTestId('state')).toHaveTextContent('open');
1220
+
1221
+ fireEvent.pointerDown(trigger);
1222
+ lightDismiss(container);
1223
+ fireEvent.click(trigger);
1224
+
1225
+ expect(getByTestId('state')).toHaveTextContent('closed');
1226
+ });
1227
+ });