@astryxdesign/core 0.4.5 → 0.4.6-canary.cea9ecd

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 (538) hide show
  1. package/CHANGELOG.md +134 -0
  2. package/dist/Avatar/Avatar.d.ts +10 -5
  3. package/dist/Avatar/Avatar.d.ts.map +1 -1
  4. package/dist/Avatar/Avatar.js +139 -30
  5. package/dist/Avatar/AvatarStatusDot.d.ts +2 -1
  6. package/dist/Avatar/AvatarStatusDot.d.ts.map +1 -1
  7. package/dist/Avatar/AvatarStatusDot.js +30 -4
  8. package/dist/Avatar/AvatarStatusLabelContext.d.ts +39 -0
  9. package/dist/Avatar/AvatarStatusLabelContext.d.ts.map +1 -0
  10. package/dist/Avatar/AvatarStatusLabelContext.js +41 -0
  11. package/dist/AvatarGroup/AvatarGroup.d.ts +3 -1
  12. package/dist/AvatarGroup/AvatarGroup.d.ts.map +1 -1
  13. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts.map +1 -1
  14. package/dist/AvatarGroup/AvatarGroupOverflow.js +15 -9
  15. package/dist/Blockquote/Blockquote.d.ts +4 -3
  16. package/dist/Blockquote/Blockquote.d.ts.map +1 -1
  17. package/dist/Blockquote/Blockquote.js +9 -10
  18. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  19. package/dist/BottomSheet/BottomSheetPanel.js +21 -5
  20. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  21. package/dist/Breadcrumbs/BreadcrumbItem.js +47 -34
  22. package/dist/Button/Button.d.ts.map +1 -1
  23. package/dist/Button/Button.js +7 -7
  24. package/dist/Calendar/Calendar.d.ts.map +1 -1
  25. package/dist/Calendar/Calendar.js +21 -12
  26. package/dist/Calendar/hooks/useCalendarNavigation.d.ts.map +1 -1
  27. package/dist/Calendar/hooks/useCalendarNavigation.js +8 -4
  28. package/dist/Calendar/styles.d.ts +2 -2
  29. package/dist/Calendar/styles.d.ts.map +1 -1
  30. package/dist/Calendar/styles.js +5 -5
  31. package/dist/Center/Center.d.ts +23 -1
  32. package/dist/Center/Center.d.ts.map +1 -1
  33. package/dist/Center/Center.js +12 -6
  34. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  35. package/dist/Chat/ChatComposer.js +3 -3
  36. package/dist/Chat/ChatComposerDrawer.d.ts.map +1 -1
  37. package/dist/Chat/ChatComposerDrawer.js +2 -2
  38. package/dist/Chat/ChatToolCalls.d.ts.map +1 -1
  39. package/dist/Chat/ChatToolCalls.js +2 -2
  40. package/dist/Chat/useChatDictation.d.ts +1 -1
  41. package/dist/Chat/useChatDictation.d.ts.map +1 -1
  42. package/dist/Chat/useSpeechRecognition.d.ts +1 -1
  43. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  44. package/dist/Chat/useSpeechRecognition.js +4 -3
  45. package/dist/Chat/useTriggerMenu.d.ts.map +1 -1
  46. package/dist/Chat/useTriggerMenu.js +2 -2
  47. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  48. package/dist/CheckboxInput/CheckboxInput.js +2 -2
  49. package/dist/Citation/Citation.d.ts.map +1 -1
  50. package/dist/Citation/Citation.js +5 -5
  51. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  52. package/dist/ClickableCard/ClickableCard.js +4 -4
  53. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  54. package/dist/CodeBlock/CodeBlock.js +1 -1
  55. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  56. package/dist/Collapsible/Collapsible.js +2 -2
  57. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  58. package/dist/CommandPalette/CommandPaletteItem.js +3 -3
  59. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  60. package/dist/ComplexSelector/ComplexSelector.js +6 -6
  61. package/dist/DateInput/DateInput.d.ts +31 -2
  62. package/dist/DateInput/DateInput.d.ts.map +1 -1
  63. package/dist/DateInput/DateInput.js +90 -22
  64. package/dist/DateInput/MonthScroller.d.ts +35 -0
  65. package/dist/DateInput/MonthScroller.d.ts.map +1 -0
  66. package/dist/DateInput/MonthScroller.js +658 -0
  67. package/dist/DateInput/MonthYearWheels.d.ts +24 -0
  68. package/dist/DateInput/MonthYearWheels.d.ts.map +1 -0
  69. package/dist/DateInput/MonthYearWheels.js +114 -0
  70. package/dist/DateInput/TouchDateField.d.ts +10 -0
  71. package/dist/DateInput/TouchDateField.d.ts.map +1 -0
  72. package/dist/DateInput/TouchDateField.js +810 -0
  73. package/dist/DateInput/Wheel.d.ts +41 -0
  74. package/dist/DateInput/Wheel.d.ts.map +1 -0
  75. package/dist/DateInput/Wheel.js +315 -0
  76. package/dist/DateInput/monthGeometry.d.ts +65 -0
  77. package/dist/DateInput/monthGeometry.d.ts.map +1 -0
  78. package/dist/DateInput/monthGeometry.js +98 -0
  79. package/dist/DateInput/tokens.stylex.d.ts +63 -0
  80. package/dist/DateInput/tokens.stylex.d.ts.map +1 -0
  81. package/dist/DateInput/tokens.stylex.js +74 -0
  82. package/dist/DateInput/useOwnScrollGesture.d.ts +41 -0
  83. package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -0
  84. package/dist/DateInput/useOwnScrollGesture.js +202 -0
  85. package/dist/DateInput/usePointerDragScroll.d.ts +15 -0
  86. package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -0
  87. package/dist/DateInput/usePointerDragScroll.js +216 -0
  88. package/dist/DateInput/useScrollSettle.d.ts +26 -0
  89. package/dist/DateInput/useScrollSettle.d.ts.map +1 -0
  90. package/dist/DateInput/useScrollSettle.js +149 -0
  91. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  92. package/dist/DateRangeInput/DateRangeInput.js +17 -14
  93. package/dist/DateTimeInput/DateTimeInput.d.ts.map +1 -1
  94. package/dist/DateTimeInput/DateTimeInput.js +17 -14
  95. package/dist/Dialog/Dialog.d.ts.map +1 -1
  96. package/dist/Dialog/Dialog.js +3 -3
  97. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts.map +1 -1
  98. package/dist/DropdownMenu/DropdownMenuCheckboxItem.js +2 -2
  99. package/dist/DropdownMenu/DropdownMenuItem.d.ts.map +1 -1
  100. package/dist/DropdownMenu/DropdownMenuItem.js +2 -2
  101. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  102. package/dist/DropdownMenu/DropdownMenuRadioItem.js +2 -2
  103. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  104. package/dist/DropdownMenu/DropdownMenuSubMenu.js +2 -2
  105. package/dist/Field/FieldLabel.d.ts.map +1 -1
  106. package/dist/Field/FieldLabel.js +4 -4
  107. package/dist/Field/InputClearButton.d.ts.map +1 -1
  108. package/dist/Field/InputClearButton.js +6 -0
  109. package/dist/Field/inputStyles.stylex.d.ts +1 -1
  110. package/dist/Field/inputStyles.stylex.d.ts.map +1 -1
  111. package/dist/Field/inputStyles.stylex.js +5 -5
  112. package/dist/FileInput/FileInput.d.ts.map +1 -1
  113. package/dist/FileInput/FileInput.js +6 -6
  114. package/dist/HoverCard/HoverCard.d.ts +13 -3
  115. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  116. package/dist/HoverCard/HoverCard.js +2 -0
  117. package/dist/HoverCard/index.d.ts +1 -1
  118. package/dist/HoverCard/index.d.ts.map +1 -1
  119. package/dist/HoverCard/useHoverCard.d.ts +17 -2
  120. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  121. package/dist/HoverCard/useHoverCard.js +78 -9
  122. package/dist/InputGroup/InputGroup.js +1 -1
  123. package/dist/Item/Item.d.ts +9 -1
  124. package/dist/Item/Item.d.ts.map +1 -1
  125. package/dist/Item/Item.js +52 -14
  126. package/dist/Layer/index.d.ts +4 -2
  127. package/dist/Layer/index.d.ts.map +1 -1
  128. package/dist/Layer/index.js +2 -0
  129. package/dist/Layer/useLayer.d.ts.map +1 -1
  130. package/dist/Layer/useLayer.js +3 -2
  131. package/dist/Layer/useTouchTrigger.d.ts +113 -0
  132. package/dist/Layer/useTouchTrigger.d.ts.map +1 -0
  133. package/dist/Layer/useTouchTrigger.js +241 -0
  134. package/dist/Layout/container.stylex.d.ts +4 -2
  135. package/dist/Layout/container.stylex.d.ts.map +1 -1
  136. package/dist/Layout/container.stylex.js +19 -11
  137. package/dist/Layout/index.d.ts +1 -0
  138. package/dist/Layout/index.d.ts.map +1 -1
  139. package/dist/Layout/index.js +4 -0
  140. package/dist/Layout/padding.stylex.d.ts +315 -12
  141. package/dist/Layout/padding.stylex.d.ts.map +1 -1
  142. package/dist/Layout/padding.stylex.js +389 -12
  143. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  144. package/dist/Lightbox/Lightbox.js +5 -4
  145. package/dist/Link/Link.d.ts.map +1 -1
  146. package/dist/Link/Link.js +6 -6
  147. package/dist/MetadataList/MetadataList.d.ts.map +1 -1
  148. package/dist/MetadataList/MetadataList.js +1 -1
  149. package/dist/MobileNav/MobileNav.d.ts +1 -0
  150. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  151. package/dist/MobileNav/MobileNav.js +24 -6
  152. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  153. package/dist/MultiSelector/MultiSelector.js +8 -8
  154. package/dist/NavItem/navItemStyles.stylex.d.ts +4 -4
  155. package/dist/NavItem/navItemStyles.stylex.d.ts.map +1 -1
  156. package/dist/NavItem/navItemStyles.stylex.js +4 -4
  157. package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
  158. package/dist/NavMenu/NavHeadingMenuItem.js +3 -3
  159. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  160. package/dist/NumberInput/NumberInput.js +36 -8
  161. package/dist/Outline/Outline.d.ts.map +1 -1
  162. package/dist/Outline/Outline.js +3 -3
  163. package/dist/Pagination/Pagination.d.ts.map +1 -1
  164. package/dist/Pagination/Pagination.js +2 -2
  165. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  166. package/dist/PowerSearch/PowerSearch.js +11 -12
  167. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  168. package/dist/PowerSearch/PowerSearchToken.js +3 -1
  169. package/dist/PowerSearch/formatFilterValue.d.ts +11 -2
  170. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  171. package/dist/PowerSearch/formatFilterValue.js +23 -8
  172. package/dist/RadioList/RadioListItem.d.ts +2 -2
  173. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  174. package/dist/RadioList/RadioListItem.js +70 -40
  175. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  176. package/dist/Resizable/ResizeHandle.js +7 -7
  177. package/dist/Section/Section.d.ts +36 -1
  178. package/dist/Section/Section.d.ts.map +1 -1
  179. package/dist/Section/Section.js +12 -2
  180. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  181. package/dist/SegmentedControl/SegmentedControlItem.js +7 -2
  182. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  183. package/dist/SelectableCard/SelectableCard.js +3 -3
  184. package/dist/Selector/Selector.d.ts +26 -1
  185. package/dist/Selector/Selector.d.ts.map +1 -1
  186. package/dist/Selector/Selector.js +93 -20
  187. package/dist/Selector/SelectorOption.d.ts +14 -1
  188. package/dist/Selector/SelectorOption.d.ts.map +1 -1
  189. package/dist/Selector/SelectorOption.js +6 -0
  190. package/dist/Selector/SelectorRowLayoutContext.d.ts +8 -0
  191. package/dist/Selector/SelectorRowLayoutContext.d.ts.map +1 -0
  192. package/dist/Selector/SelectorRowLayoutContext.js +27 -0
  193. package/dist/Selector/types.d.ts +1 -0
  194. package/dist/Selector/types.d.ts.map +1 -1
  195. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  196. package/dist/SideNav/SideNavHeading.js +4 -4
  197. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  198. package/dist/SideNav/SideNavItem.js +3 -3
  199. package/dist/Slider/Slider.d.ts.map +1 -1
  200. package/dist/Slider/Slider.js +7 -7
  201. package/dist/Stack/Stack.d.ts +23 -1
  202. package/dist/Stack/Stack.d.ts.map +1 -1
  203. package/dist/Stack/Stack.js +12 -6
  204. package/dist/Switch/Switch.d.ts.map +1 -1
  205. package/dist/Switch/Switch.js +2 -2
  206. package/dist/TabList/Tab.d.ts.map +1 -1
  207. package/dist/TabList/Tab.js +1 -1
  208. package/dist/TabList/TabMenu.d.ts.map +1 -1
  209. package/dist/TabList/TabMenu.js +3 -3
  210. package/dist/Table/TableRow.js +4 -4
  211. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  212. package/dist/Table/plugins/columnResize/useTableColumnResize.js +1 -1
  213. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  214. package/dist/Table/plugins/filtering/useTableFiltering.js +2 -2
  215. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts.map +1 -1
  216. package/dist/Table/plugins/groupedRows/useTableGroupedRows.js +2 -2
  217. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  218. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +2 -2
  219. package/dist/Table/plugins/sortable/useTableSortable.d.ts.map +1 -1
  220. package/dist/Table/plugins/sortable/useTableSortable.js +1 -1
  221. package/dist/Table/plugins/sortable/useTableSortableState.d.ts +5 -3
  222. package/dist/Table/plugins/sortable/useTableSortableState.d.ts.map +1 -1
  223. package/dist/Table/plugins/sortable/useTableSortableState.js +12 -9
  224. package/dist/Table/plugins/tree/useTableTreeData.d.ts.map +1 -1
  225. package/dist/Table/plugins/tree/useTableTreeData.js +3 -3
  226. package/dist/TextArea/TextArea.js +1 -1
  227. package/dist/TextInput/TextInput.js +1 -1
  228. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  229. package/dist/Thumbnail/Thumbnail.js +3 -3
  230. package/dist/TimeInput/TimeInput.js +2 -2
  231. package/dist/Timestamp/Timestamp.d.ts.map +1 -1
  232. package/dist/Timestamp/Timestamp.js +6 -4
  233. package/dist/Timestamp/formatInstant.d.ts +3 -2
  234. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  235. package/dist/Timestamp/formatInstant.js +8 -8
  236. package/dist/Timestamp/tooltipEntries.d.ts +2 -1
  237. package/dist/Timestamp/tooltipEntries.d.ts.map +1 -1
  238. package/dist/Timestamp/tooltipEntries.js +5 -3
  239. package/dist/Toast/Toast.d.ts +4 -3
  240. package/dist/Toast/Toast.d.ts.map +1 -1
  241. package/dist/Toast/Toast.js +10 -7
  242. package/dist/Token/Token.d.ts.map +1 -1
  243. package/dist/Token/Token.js +6 -6
  244. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  245. package/dist/Tokenizer/Tokenizer.js +1 -1
  246. package/dist/Tooltip/Tooltip.d.ts +16 -3
  247. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  248. package/dist/Tooltip/Tooltip.js +2 -0
  249. package/dist/Tooltip/index.d.ts +1 -1
  250. package/dist/Tooltip/index.d.ts.map +1 -1
  251. package/dist/Tooltip/useTooltip.d.ts +21 -2
  252. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  253. package/dist/Tooltip/useTooltip.js +71 -13
  254. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  255. package/dist/TopNav/TopNavHeading.js +4 -4
  256. package/dist/TopNav/TopNavItem.d.ts.map +1 -1
  257. package/dist/TopNav/TopNavItem.js +3 -3
  258. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  259. package/dist/TopNav/TopNavMegaMenu.js +2 -2
  260. package/dist/TopNav/TopNavMegaMenuItem.d.ts.map +1 -1
  261. package/dist/TopNav/TopNavMegaMenuItem.js +2 -2
  262. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  263. package/dist/TopNav/TopNavMenu.js +4 -4
  264. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  265. package/dist/TreeList/TreeListItem.js +7 -7
  266. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  267. package/dist/Typeahead/BaseTypeahead.js +2 -2
  268. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  269. package/dist/Typeahead/Typeahead.js +1 -1
  270. package/dist/astryx.css +124 -62
  271. package/dist/hooks/containerReveal.stylex.d.ts.map +1 -1
  272. package/dist/hooks/containerReveal.stylex.js +18 -18
  273. package/dist/hooks/scrollbarGutter.d.ts +28 -0
  274. package/dist/hooks/scrollbarGutter.d.ts.map +1 -0
  275. package/dist/hooks/scrollbarGutter.js +103 -0
  276. package/dist/hooks/useAutoMediaMode.d.ts +31 -0
  277. package/dist/hooks/useAutoMediaMode.d.ts.map +1 -0
  278. package/dist/hooks/useAutoMediaMode.js +201 -0
  279. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  280. package/dist/hooks/useInputStatusIcon.js +1 -1
  281. package/dist/hooks/useListFocus.d.ts +5 -2
  282. package/dist/hooks/useListFocus.d.ts.map +1 -1
  283. package/dist/hooks/useListFocus.js +12 -6
  284. package/dist/hooks/useScrollLock.d.ts +4 -0
  285. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  286. package/dist/hooks/useScrollLock.js +13 -1
  287. package/dist/i18n/InternationalizationContext.d.ts.map +1 -1
  288. package/dist/i18n/InternationalizationContext.js +2 -0
  289. package/dist/i18n/index.d.ts +6 -0
  290. package/dist/i18n/index.d.ts.map +1 -1
  291. package/dist/i18n/index.js +6 -0
  292. package/dist/i18n/useCollator.d.ts +12 -0
  293. package/dist/i18n/useCollator.d.ts.map +1 -0
  294. package/dist/i18n/useCollator.js +40 -0
  295. package/dist/i18n/useLocale.d.ts +3 -0
  296. package/dist/i18n/useLocale.d.ts.map +1 -0
  297. package/dist/i18n/useLocale.js +31 -0
  298. package/dist/theme/MediaTheme.d.ts +25 -5
  299. package/dist/theme/MediaTheme.d.ts.map +1 -1
  300. package/dist/theme/MediaTheme.js +31 -6
  301. package/dist/theme/defineTheme.d.ts +5 -0
  302. package/dist/theme/defineTheme.d.ts.map +1 -1
  303. package/dist/theme/defineTheme.js +5 -0
  304. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  305. package/dist/theme/derivedVarRegistry.js +7 -0
  306. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  307. package/dist/theme/generateThemeRules.js +66 -5
  308. package/dist/theme/index.d.ts +1 -1
  309. package/dist/theme/index.d.ts.map +1 -1
  310. package/dist/theme/syntax/index.d.ts +6 -0
  311. package/dist/theme/syntax/index.d.ts.map +1 -1
  312. package/dist/theme/syntax/index.js +7 -2
  313. package/dist/utils/dateParser.d.ts +4 -3
  314. package/dist/utils/dateParser.d.ts.map +1 -1
  315. package/dist/utils/dateParser.js +8 -8
  316. package/dist/utils/index.d.ts +1 -1
  317. package/dist/utils/index.d.ts.map +1 -1
  318. package/dist/utils/index.js +1 -1
  319. package/dist/utils/plainDate.d.ts +5 -2
  320. package/dist/utils/plainDate.d.ts.map +1 -1
  321. package/dist/utils/plainDate.js +20 -4
  322. package/locales/en.json +28 -0
  323. package/locales/pseudo.json +21 -0
  324. package/package.json +3 -3
  325. package/src/Avatar/Avatar.doc.mjs +10 -6
  326. package/src/Avatar/Avatar.test.tsx +219 -1
  327. package/src/Avatar/Avatar.tsx +179 -37
  328. package/src/Avatar/AvatarStatusDot.tsx +30 -4
  329. package/src/Avatar/AvatarStatusLabelContext.ts +47 -0
  330. package/src/AvatarGroup/AvatarGroup.doc.mjs +10 -6
  331. package/src/AvatarGroup/AvatarGroup.test.tsx +62 -0
  332. package/src/AvatarGroup/AvatarGroup.tsx +3 -1
  333. package/src/AvatarGroup/AvatarGroupOverflow.tsx +31 -8
  334. package/src/Banner/Banner.doc.mjs +2 -0
  335. package/src/Blockquote/Blockquote.doc.mjs +30 -7
  336. package/src/Blockquote/Blockquote.test.tsx +34 -3
  337. package/src/Blockquote/Blockquote.tsx +11 -9
  338. package/src/BottomSheet/BottomSheet.doc.mjs +3 -3
  339. package/src/BottomSheet/BottomSheet.test.tsx +24 -0
  340. package/src/BottomSheet/BottomSheetPanel.test.tsx +91 -0
  341. package/src/BottomSheet/BottomSheetPanel.tsx +58 -3
  342. package/src/Breadcrumbs/BreadcrumbItem.tsx +36 -23
  343. package/src/Breadcrumbs/Breadcrumbs.doc.mjs +26 -2
  344. package/src/Breadcrumbs/Breadcrumbs.test.tsx +31 -0
  345. package/src/Button/Button.tsx +12 -9
  346. package/src/Calendar/Calendar.tsx +15 -9
  347. package/src/Calendar/hooks/useCalendarNavigation.ts +6 -4
  348. package/src/Calendar/styles.ts +8 -5
  349. package/src/Center/Center.doc.mjs +48 -0
  350. package/src/Center/Center.test.tsx +158 -0
  351. package/src/Center/Center.tsx +50 -9
  352. package/src/Chat/ChatComposer.tsx +11 -5
  353. package/src/Chat/ChatComposerDrawer.tsx +4 -1
  354. package/src/Chat/ChatToolCalls.tsx +13 -4
  355. package/src/Chat/{useChatDictation.test.ts → useChatDictation.test.tsx} +29 -14
  356. package/src/Chat/useChatDictation.ts +1 -1
  357. package/src/Chat/useSpeechRecognition.ts +5 -3
  358. package/src/Chat/useTriggerMenu.tsx +4 -1
  359. package/src/CheckboxInput/CheckboxInput.tsx +5 -2
  360. package/src/Citation/Citation.test.tsx +6 -1
  361. package/src/Citation/Citation.tsx +11 -5
  362. package/src/ClickableCard/ClickableCard.tsx +7 -4
  363. package/src/CodeBlock/CodeBlock.tsx +4 -1
  364. package/src/Collapsible/Collapsible.tsx +5 -2
  365. package/src/CommandPalette/CommandPaletteItem.tsx +6 -3
  366. package/src/ComplexSelector/ComplexSelector.doc.mjs +10 -0
  367. package/src/ComplexSelector/ComplexSelector.tsx +14 -7
  368. package/src/DateInput/DateInput.test.tsx +17 -1
  369. package/src/DateInput/DateInput.tsx +93 -21
  370. package/src/DateInput/DateInputTouch.test.tsx +2582 -0
  371. package/src/DateInput/MonthScroller.tsx +878 -0
  372. package/src/DateInput/MonthYearWheels.tsx +147 -0
  373. package/src/DateInput/TouchDateField.tsx +1223 -0
  374. package/src/DateInput/Wheel.tsx +473 -0
  375. package/src/DateInput/monthGeometry.ts +118 -0
  376. package/src/DateInput/tokens.stylex.ts +99 -0
  377. package/src/DateInput/useOwnScrollGesture.ts +227 -0
  378. package/src/DateInput/usePointerDragScroll.ts +220 -0
  379. package/src/DateInput/useScrollSettle.ts +164 -0
  380. package/src/DateRangeInput/DateRangeInput.doc.mjs +1 -1
  381. package/src/DateRangeInput/DateRangeInput.tsx +31 -13
  382. package/src/DateTimeInput/DateTimeInput.tsx +25 -9
  383. package/src/Dialog/Dialog.test.tsx +24 -0
  384. package/src/Dialog/Dialog.tsx +3 -0
  385. package/src/DropdownMenu/DropdownMenuCheckboxItem.tsx +5 -2
  386. package/src/DropdownMenu/DropdownMenuItem.tsx +5 -2
  387. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +5 -2
  388. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +5 -2
  389. package/src/Field/Field.doc.mjs +2 -0
  390. package/src/Field/FieldLabel.tsx +9 -3
  391. package/src/Field/InputClearButton.test.tsx +110 -3
  392. package/src/Field/InputClearButton.tsx +38 -0
  393. package/src/Field/inputStyles.stylex.ts +17 -13
  394. package/src/FileInput/FileInput.tsx +15 -8
  395. package/src/FormLayout/FormLayout.doc.mjs +1 -1
  396. package/src/HoverCard/HoverCard.doc.mjs +18 -0
  397. package/src/HoverCard/HoverCard.test.tsx +189 -0
  398. package/src/HoverCard/HoverCard.tsx +22 -2
  399. package/src/HoverCard/index.ts +1 -0
  400. package/src/HoverCard/useHoverCard.doc.mjs +2 -0
  401. package/src/HoverCard/useHoverCard.tsx +103 -7
  402. package/src/InputGroup/InputGroup.tsx +1 -1
  403. package/src/Item/Item.doc.mjs +1 -0
  404. package/src/Item/Item.test.tsx +50 -0
  405. package/src/Item/Item.tsx +54 -6
  406. package/src/Layer/index.ts +10 -0
  407. package/src/Layer/useLayer.tsx +13 -2
  408. package/src/Layer/useTouchTrigger.test.ts +70 -0
  409. package/src/Layer/useTouchTrigger.ts +366 -0
  410. package/src/Layout/Layout.doc.mjs +18 -0
  411. package/src/Layout/container.stylex.ts +11 -3
  412. package/src/Layout/index.ts +4 -0
  413. package/src/Layout/overlayPaddingReset.test.tsx +222 -0
  414. package/src/Layout/padding.stylex.ts +192 -12
  415. package/src/Lightbox/Lightbox.tsx +11 -3
  416. package/src/Link/Link.tsx +9 -6
  417. package/src/MetadataList/MetadataList.tsx +4 -1
  418. package/src/MobileNav/MobileNav.tsx +61 -5
  419. package/src/MobileNav/MobileNavEntryAnimation.test.tsx +212 -0
  420. package/src/MobileNav/MobileNavScrollbarGutter.test.tsx +109 -0
  421. package/src/MultiSelector/MultiSelector.test.tsx +1 -1
  422. package/src/MultiSelector/MultiSelector.tsx +26 -10
  423. package/src/NavItem/navItemStyles.stylex.ts +7 -4
  424. package/src/NavMenu/NavHeadingMenuItem.tsx +6 -3
  425. package/src/NumberInput/NumberInput.doc.mjs +24 -0
  426. package/src/NumberInput/NumberInput.test.tsx +138 -0
  427. package/src/NumberInput/NumberInput.tsx +47 -8
  428. package/src/Outline/Outline.tsx +5 -2
  429. package/src/Pagination/Pagination.tsx +5 -2
  430. package/src/Popover/Popover.test.tsx +27 -1
  431. package/src/PowerSearch/PowerSearch.tsx +17 -8
  432. package/src/PowerSearch/PowerSearchToken.tsx +3 -0
  433. package/src/PowerSearch/formatFilterValue.test.ts +22 -2
  434. package/src/PowerSearch/formatFilterValue.ts +31 -6
  435. package/src/RadioList/RadioList.doc.mjs +1 -1
  436. package/src/RadioList/RadioList.test.tsx +170 -2
  437. package/src/RadioList/RadioListItem.tsx +88 -53
  438. package/src/Resizable/ResizeHandle.test.tsx +22 -0
  439. package/src/Resizable/ResizeHandle.tsx +25 -7
  440. package/src/Section/Section.doc.mjs +55 -0
  441. package/src/Section/Section.test.tsx +201 -4
  442. package/src/Section/Section.tsx +69 -0
  443. package/src/SegmentedControl/SegmentedControl.test.tsx +31 -0
  444. package/src/SegmentedControl/SegmentedControlItem.tsx +15 -3
  445. package/src/SelectableCard/SelectableCard.tsx +6 -3
  446. package/src/Selector/Selector.doc.mjs +16 -2
  447. package/src/Selector/Selector.test.tsx +525 -1
  448. package/src/Selector/Selector.tsx +180 -25
  449. package/src/Selector/SelectorOption.doc.mjs +7 -0
  450. package/src/Selector/SelectorOption.tsx +21 -0
  451. package/src/Selector/SelectorRowLayoutContext.ts +32 -0
  452. package/src/Selector/types.ts +4 -4
  453. package/src/SideNav/SideNavHeading.tsx +14 -5
  454. package/src/SideNav/SideNavItem.tsx +9 -3
  455. package/src/Slider/Slider.tsx +25 -6
  456. package/src/Stack/Stack.doc.mjs +72 -0
  457. package/src/Stack/Stack.test.tsx +156 -0
  458. package/src/Stack/Stack.tsx +50 -8
  459. package/src/Switch/Switch.tsx +5 -2
  460. package/src/TabList/Tab.tsx +4 -1
  461. package/src/TabList/TabMenu.tsx +9 -3
  462. package/src/Table/TableRow.tsx +4 -4
  463. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +6 -2
  464. package/src/Table/plugins/filtering/useTableFiltering.tsx +4 -1
  465. package/src/Table/plugins/groupedRows/useTableGroupedRows.tsx +10 -3
  466. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +6 -3
  467. package/src/Table/plugins/sortable/useTableSortable.tsx +4 -1
  468. package/src/Table/plugins/sortable/useTableSortableState.test.tsx +34 -0
  469. package/src/Table/plugins/sortable/useTableSortableState.tsx +26 -23
  470. package/src/Table/plugins/tree/useTableTreeData.tsx +10 -4
  471. package/src/TextArea/TextArea.doc.mjs +1 -1
  472. package/src/TextArea/TextArea.tsx +1 -1
  473. package/src/TextInput/TextInput.tsx +1 -1
  474. package/src/Thumbnail/Thumbnail.tsx +9 -3
  475. package/src/TimeInput/TimeInput.tsx +1 -1
  476. package/src/Timestamp/Timestamp.test.tsx +27 -7
  477. package/src/Timestamp/Timestamp.tsx +8 -4
  478. package/src/Timestamp/formatInstant.ts +9 -7
  479. package/src/Timestamp/tooltipEntries.test.ts +11 -6
  480. package/src/Timestamp/tooltipEntries.ts +6 -2
  481. package/src/Toast/Toast.tsx +9 -7
  482. package/src/Token/Token.tsx +14 -5
  483. package/src/Tokenizer/Tokenizer.tsx +4 -1
  484. package/src/Tooltip/Tooltip.doc.mjs +18 -0
  485. package/src/Tooltip/Tooltip.test.tsx +254 -1
  486. package/src/Tooltip/Tooltip.tsx +22 -2
  487. package/src/Tooltip/index.ts +1 -0
  488. package/src/Tooltip/useTooltip.doc.mjs +2 -0
  489. package/src/Tooltip/useTooltip.tsx +99 -21
  490. package/src/TopNav/TopNavHeading.tsx +13 -4
  491. package/src/TopNav/TopNavItem.tsx +6 -3
  492. package/src/TopNav/TopNavMegaMenu.tsx +5 -2
  493. package/src/TopNav/TopNavMegaMenuItem.tsx +5 -2
  494. package/src/TopNav/TopNavMenu.tsx +10 -4
  495. package/src/TreeList/TreeListItem.tsx +22 -7
  496. package/src/Typeahead/BaseTypeahead.tsx +5 -2
  497. package/src/Typeahead/Typeahead.tsx +4 -1
  498. package/src/hooks/containerReveal.stylex.ts +54 -18
  499. package/src/hooks/scrollbarGutter.test.ts +167 -0
  500. package/src/hooks/scrollbarGutter.ts +121 -0
  501. package/src/hooks/useAutoMediaMode.test.ts +109 -0
  502. package/src/hooks/useAutoMediaMode.ts +233 -0
  503. package/src/hooks/useInputStatusIcon.tsx +4 -1
  504. package/src/hooks/useListFocus.doc.mjs +2 -2
  505. package/src/hooks/useListFocus.test.tsx +65 -3
  506. package/src/hooks/useListFocus.ts +15 -7
  507. package/src/hooks/useScrollLock.doc.mjs +4 -4
  508. package/src/hooks/useScrollLock.test.ts +73 -0
  509. package/src/hooks/useScrollLock.ts +14 -0
  510. package/src/i18n/InternationalizationContext.ts +2 -0
  511. package/src/i18n/__tests__/e2e-powersearch.test.tsx +37 -1
  512. package/src/i18n/__tests__/useCollator.test.tsx +115 -0
  513. package/src/i18n/__tests__/useLocale.test.tsx +52 -0
  514. package/src/i18n/index.ts +6 -0
  515. package/src/i18n/useCollator.doc.mjs +84 -0
  516. package/src/i18n/useCollator.ts +44 -0
  517. package/src/i18n/useLocale.doc.mjs +70 -0
  518. package/src/i18n/useLocale.ts +34 -0
  519. package/src/i18n/useTranslator.doc.mjs +1 -1
  520. package/src/reset.css +9 -2
  521. package/src/reset.test.ts +22 -0
  522. package/src/theme/MediaTheme.doc.mjs +23 -4
  523. package/src/theme/MediaTheme.dom.test.tsx +97 -0
  524. package/src/theme/MediaTheme.tsx +42 -7
  525. package/src/theme/defineTheme.test.ts +9 -3
  526. package/src/theme/defineTheme.ts +5 -0
  527. package/src/theme/derivedVarRegistry.test.ts +19 -5
  528. package/src/theme/derivedVarRegistry.ts +4 -0
  529. package/src/theme/generateThemeRules.test.ts +118 -0
  530. package/src/theme/generateThemeRules.ts +83 -5
  531. package/src/theme/index.ts +1 -1
  532. package/src/theme/syntax/index.ts +6 -2
  533. package/src/theme/syntax/serverSafeSyntax.test.ts +68 -0
  534. package/src/utils/dateParser.test.ts +20 -0
  535. package/src/utils/dateParser.ts +14 -7
  536. package/src/utils/index.ts +2 -0
  537. package/src/utils/plainDate.test.ts +6 -0
  538. package/src/utils/plainDate.ts +21 -4
@@ -1 +1 @@
1
- {"version":3,"file":"containerReveal.stylex.d.ts","sourceRoot":"","sources":["../../src/hooks/containerReveal.stylex.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAU3C,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA2MjB,CAAC"}
1
+ {"version":3,"file":"containerReveal.stylex.d.ts","sourceRoot":"","sources":["../../src/hooks/containerReveal.stylex.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAU3C,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA+OjB,CAAC"}
@@ -29,30 +29,30 @@ const HOVER_DELAY = 'var(--_hover-delay, 0s)';
29
29
  export const styles = {
30
30
  container: {
31
31
  "--_hover-delay": "xhg274n",
32
- "--_reveal-opacity": "xct0gwe x1wblmmc xi33vf3 xi7d7de",
33
- "--_reveal-position": "xp0pj8v x106rhu xoa21yc xarvkxi",
34
- "--_reveal-delay": "x1xiarpw x1qamfbu x1mjsb9v x1pn63d7",
35
- "--_reveal-delay-reduced": "xdjmrzf x1g1w2pt x1z42dm xm1aeao",
36
- "--_conceal-opacity": "x1kgmhs9 xb9fdgj",
37
- "--_fade-delay": "x13l1x9d x1ho7nxo x1wfyzv7 x1hl81f0",
32
+ "--_reveal-opacity": "xct0gwe x2xrgwu xi33vf3 xi7d7de",
33
+ "--_reveal-position": "xp0pj8v x1or4zte xoa21yc xarvkxi",
34
+ "--_reveal-delay": "x1xiarpw xi1ebb6 x1mjsb9v x1pn63d7",
35
+ "--_reveal-delay-reduced": "xdjmrzf xvd8mm8 x1z42dm xm1aeao",
36
+ "--_conceal-opacity": "x1kgmhs9 x1316hva",
37
+ "--_fade-delay": "x13l1x9d x14nxqze x1wfyzv7 x1hl81f0",
38
38
  $$css: true
39
39
  },
40
40
  stateInactive: {
41
- "--_reveal-opacity": "xct0gwe xichi0p xi33vf3 xi7d7de",
42
- "--_reveal-position": "xp0pj8v x1sacq21 xoa21yc xarvkxi",
43
- "--_reveal-delay": "x1xiarpw x619wqp x1mjsb9v x1pn63d7",
44
- "--_reveal-delay-reduced": "xdjmrzf xfu6dsl x1z42dm xm1aeao",
45
- "--_conceal-opacity": "x1kgmhs9 xflzsy",
46
- "--_fade-delay": "x13l1x9d x3tau1w x1wfyzv7 x1hl81f0",
41
+ "--_reveal-opacity": "xct0gwe xfqgg65 xi33vf3 xi7d7de",
42
+ "--_reveal-position": "xp0pj8v x17ock8y xoa21yc xarvkxi",
43
+ "--_reveal-delay": "x1xiarpw x1tx49wl x1mjsb9v x1pn63d7",
44
+ "--_reveal-delay-reduced": "xdjmrzf xap96qf x1z42dm xm1aeao",
45
+ "--_conceal-opacity": "x1kgmhs9 xuzfaso",
46
+ "--_fade-delay": "x13l1x9d xq03417 x1wfyzv7 x1hl81f0",
47
47
  $$css: true
48
48
  },
49
49
  stateActive: {
50
- "--_reveal-opacity": "x5setjs x1wblmmc xi33vf3 xi7d7de",
51
- "--_reveal-position": "x1r6s5ct x106rhu xoa21yc xarvkxi",
52
- "--_reveal-delay": "x1dejzja xp1dr9k x1mjsb9v x1pn63d7",
53
- "--_reveal-delay-reduced": "xdjmrzf xfu6dsl x1z42dm xm1aeao",
54
- "--_conceal-opacity": "x9pmotm xb9fdgj",
55
- "--_fade-delay": "x13l1x9d x3tau1w x1wfyzv7 x1hl81f0",
50
+ "--_reveal-opacity": "x5setjs x2xrgwu xi33vf3 xi7d7de",
51
+ "--_reveal-position": "x1r6s5ct x1or4zte xoa21yc xarvkxi",
52
+ "--_reveal-delay": "x1dejzja x1t6fdr0 x1mjsb9v x1pn63d7",
53
+ "--_reveal-delay-reduced": "xdjmrzf xap96qf x1z42dm xm1aeao",
54
+ "--_conceal-opacity": "x9pmotm x1316hva",
55
+ "--_fade-delay": "x13l1x9d xq03417 x1wfyzv7 x1hl81f0",
56
56
  $$css: true
57
57
  },
58
58
  hoverDelay: delay => [{
@@ -0,0 +1,28 @@
1
+ export interface ScrollbarGutterHold {
2
+ /**
3
+ * Call once the lock's own styles are applied: measures whether the element
4
+ * grew anyway and, only then, pads the difference away.
5
+ */
6
+ settle(): void;
7
+ /** Call on unlock: restores everything this hold changed. */
8
+ release(): void;
9
+ }
10
+ /**
11
+ * Keeps `element`'s content box the width it is right now, across a scroll
12
+ * lock that is about to hide the document's scrollbar.
13
+ *
14
+ * Call it *before* applying the lock's styles, then {@link
15
+ * ScrollbarGutterHold.settle} immediately after, and {@link
16
+ * ScrollbarGutterHold.release} on unlock:
17
+ *
18
+ * ```
19
+ * const hold = holdScrollbarGutter(document.body);
20
+ * body.style.position = 'fixed';
21
+ * hold.settle();
22
+ * ```
23
+ *
24
+ * Overlay scrollbars (mobile, default macOS) take no layout space, so there is
25
+ * nothing to hold and nothing is touched.
26
+ */
27
+ export declare function holdScrollbarGutter(element: HTMLElement): ScrollbarGutterHold;
28
+ //# sourceMappingURL=scrollbarGutter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scrollbarGutter.d.ts","sourceRoot":"","sources":["../../src/hooks/scrollbarGutter.ts"],"names":[],"mappings":"AA8BA,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,MAAM,IAAI,IAAI,CAAC;IACf,6DAA6D;IAC7D,OAAO,IAAI,IAAI,CAAC;CACjB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,WAAW,GAAG,mBAAmB,CA+D7E"}
@@ -0,0 +1,103 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file scrollbarGutter.ts
5
+ * @input The element a scroll lock pins, plus live layout measurements
6
+ * @output Exports holdScrollbarGutter and the ScrollbarGutterHold it returns
7
+ * @position Internal hook utility; used by useScrollLock and MobileNav so that
8
+ * locking background scroll does not resize the layout viewport.
9
+ *
10
+ * Locking scroll hides the document's scrollbar. Where that scrollbar is a
11
+ * classic (space-taking) one — Windows/Linux desktop, and macOS set to
12
+ * "Always" show scroll bars — hiding it widens the layout viewport by the
13
+ * scrollbar's width and the whole page jumps sideways behind the overlay.
14
+ *
15
+ * The fix is `scrollbar-gutter: stable`, which holds the gutter open once the
16
+ * scrollbar goes away. Being a real layout change it holds `position: fixed`
17
+ * chrome (sticky headers, toast viewports) as well as in-flow content, which
18
+ * padding fundamentally cannot: fixed elements resolve against the viewport,
19
+ * not against the padded element.
20
+ *
21
+ * Padding is kept only as a fallback for engines without `scrollbar-gutter`
22
+ * (Safari shipped it in 18.2), and it is applied by measuring whether the
23
+ * element actually moved rather than by assuming it did.
24
+ */
25
+
26
+ const NOOP = {
27
+ settle() {},
28
+ release() {}
29
+ };
30
+ /**
31
+ * Keeps `element`'s content box the width it is right now, across a scroll
32
+ * lock that is about to hide the document's scrollbar.
33
+ *
34
+ * Call it *before* applying the lock's styles, then {@link
35
+ * ScrollbarGutterHold.settle} immediately after, and {@link
36
+ * ScrollbarGutterHold.release} on unlock:
37
+ *
38
+ * ```
39
+ * const hold = holdScrollbarGutter(document.body);
40
+ * body.style.position = 'fixed';
41
+ * hold.settle();
42
+ * ```
43
+ *
44
+ * Overlay scrollbars (mobile, default macOS) take no layout space, so there is
45
+ * nothing to hold and nothing is touched.
46
+ */
47
+ export function holdScrollbarGutter(element) {
48
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
49
+ return NOOP;
50
+ }
51
+ const root = document.documentElement;
52
+ const viewportWidth = root.clientWidth;
53
+
54
+ // 0 means "no layout to measure" (jsdom, and any non-visual environment),
55
+ // not "the scrollbar is as wide as the window".
56
+ if (viewportWidth === 0) {
57
+ return NOOP;
58
+ }
59
+ const previousGutter = root.style.scrollbarGutter;
60
+ const previousPadding = element.style.paddingRight;
61
+ const widthBefore = element.getBoundingClientRect().width;
62
+ let heldGutter = false;
63
+ let padded = false;
64
+ let settled = false;
65
+
66
+ // Only when a space-taking scrollbar is actually there. Holding the gutter
67
+ // open on a page that never had one would carve out 15px that was never
68
+ // reserved — the same shift, in the other direction.
69
+ if (window.innerWidth > viewportWidth) {
70
+ root.style.scrollbarGutter = 'stable';
71
+ heldGutter = true;
72
+ }
73
+ return {
74
+ settle() {
75
+ if (settled) {
76
+ return;
77
+ }
78
+ settled = true;
79
+
80
+ // What the lock actually did to this element, rather than what we
81
+ // assumed it would do. 0 on any engine where the gutter held — and on a
82
+ // page that already sets `scrollbar-gutter: stable` itself, where the
83
+ // scrollbar was never taking the space back.
84
+ const grew = element.getBoundingClientRect().width - widthBefore;
85
+ if (grew <= 0) {
86
+ return;
87
+ }
88
+ const existing = Number.parseFloat(window.getComputedStyle(element).paddingRight) || 0;
89
+ element.style.paddingRight = `${existing + grew}px`;
90
+ padded = true;
91
+ },
92
+ release() {
93
+ if (padded) {
94
+ element.style.paddingRight = previousPadding;
95
+ padded = false;
96
+ }
97
+ if (heldGutter) {
98
+ root.style.scrollbarGutter = previousGutter;
99
+ heldGutter = false;
100
+ }
101
+ }
102
+ };
103
+ }
@@ -0,0 +1,31 @@
1
+ import type { RefObject } from 'react';
2
+ import type { RGBA } from '../utils/color';
3
+ /** A surface luminance context, or `"off"` when no media context is wanted. */
4
+ export type DetectedMediaMode = 'dark' | 'light' | 'off';
5
+ /**
6
+ * Which media context a surface wants: `'off'` when its ambient text already
7
+ * reads on the surface, otherwise whichever on-color reads better. Pure — the
8
+ * DOM read is the caller's. Ties between the two sides go to dark, matching
9
+ * the convention that an inverted surface is usually the dark one.
10
+ *
11
+ * The `'off'` answer is the point of measuring at all. A surface that a theme
12
+ * calls inverted but paints pale does not want an inverted context; its own
13
+ * text is already correct for it, and forcing one is how white-on-pale-grey
14
+ * happens.
15
+ */
16
+ export declare function pickMediaMode(background: RGBA, ambient: RGBA | null, onDark: RGBA | null, onLight: RGBA | null): DetectedMediaMode | null;
17
+ /**
18
+ * Detect the media context for the element's surroundings.
19
+ *
20
+ * Measures `ref`'s PARENT, never `ref` itself: MediaTheme sets its media
21
+ * attribute on its own element, so measuring that would feed the decision
22
+ * back into its own input and let it oscillate. The parent owns the
23
+ * background and sits outside the media context, so both inputs stay
24
+ * independent of the result.
25
+ *
26
+ * Returns null until a measurement succeeds — on the server, before the
27
+ * layout effect runs, and whenever the backdrop is not knowable from CSS.
28
+ * The caller renders its fallback for those.
29
+ */
30
+ export declare function useAutoMediaMode(ref: RefObject<HTMLElement | null>, isEnabled: boolean): DetectedMediaMode | null;
31
+ //# sourceMappingURL=useAutoMediaMode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useAutoMediaMode.d.ts","sourceRoot":"","sources":["../../src/hooks/useAutoMediaMode.ts"],"names":[],"mappings":"AAoCA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AACrC,OAAO,KAAK,EAAC,IAAI,EAAC,MAAM,gBAAgB,CAAC;AAMzC,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,OAAO,GAAG,KAAK,CAAC;AAqFzD;;;;;;;;;;GAUG;AACH,wBAAgB,aAAa,CAC3B,UAAU,EAAE,IAAI,EAChB,OAAO,EAAE,IAAI,GAAG,IAAI,EACpB,MAAM,EAAE,IAAI,GAAG,IAAI,EACnB,OAAO,EAAE,IAAI,GAAG,IAAI,GACnB,iBAAiB,GAAG,IAAI,CAe1B;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAC9B,GAAG,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,EAClC,SAAS,EAAE,OAAO,GACjB,iBAAiB,GAAG,IAAI,CAsD1B"}
@@ -0,0 +1,201 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file useAutoMediaMode.ts
7
+ * @input Ref to the element whose backdrop should be measured
8
+ * @output 'dark' | 'light' | null (not yet measurable)
9
+ * @position INTERNAL — powers `MediaTheme mode="auto"`. Not exported from the
10
+ * package: MediaTheme is the supported surface for this behavior.
11
+ * Sibling to useImageMode, which answers the same question for images.
12
+ *
13
+ * Picks the media context a surface wants by measuring what the browser
14
+ * actually painted, rather than trusting a token's name.
15
+ *
16
+ * The bug it exists for: `--color-background-inverted` is not required to be
17
+ * inverted. A theme can define it as a pale grey, and a hardcoded
18
+ * `mode="dark"` then paints white text on it at 1.25:1. Because the surface
19
+ * colour is a runtime value and the mode is a compile-time guess, no amount
20
+ * of care in the component can catch that.
21
+ *
22
+ * The answer can also be `'off'`: when the surface's own ambient text already
23
+ * reads on it, the surface is not effectively inverted and does not want a
24
+ * media context. Verified in Chromium that this loses nothing on a surface
25
+ * that is chromatic but legible — the dark-mode error toast renders
26
+ * identically either way, because a dark page already resolves those tokens
27
+ * to the values the media context would install.
28
+ *
29
+ * @example
30
+ * ```
31
+ * // Inside MediaTheme; see its `mode="auto"`.
32
+ * const detected = useAutoMediaMode(ref, mode === 'auto');
33
+ * ```
34
+ */
35
+ import { useRef, useState } from 'react';
36
+ import { parseColor, formatColor } from "../utils/color.js";
37
+ import { contrastRatio, compositeOver } from "../theme/contrast.js";
38
+ import { useTheme } from "../theme/useTheme.js";
39
+ import { useIsomorphicLayoutEffect } from "./useIsomorphicLayoutEffect.js";
40
+
41
+ /** A surface luminance context, or `"off"` when no media context is wanted. */
42
+
43
+ /**
44
+ * Resolve token references to the colors they actually paint, by reading them
45
+ * back off a hidden probe.
46
+ *
47
+ * A custom property cannot simply be read: `getPropertyValue` returns the
48
+ * token's *specified* text, and Astryx tokens are `light-dark(a, b)` pairs
49
+ * that resolve only once used in a real property. The probe assigns each
50
+ * token to `color` and reads the computed value back, which the browser has
51
+ * resolved against the host's own color-scheme and any overrides.
52
+ *
53
+ * `display: none` keeps the probe out of layout — computed color still
54
+ * resolves — so this costs a style recalc and no reflow.
55
+ */
56
+ function resolvePaintedColors(host, tokens) {
57
+ const probe = document.createElement('span');
58
+ probe.style.display = 'none';
59
+ host.appendChild(probe);
60
+ try {
61
+ return tokens.map(token => {
62
+ probe.style.color = `var(${token})`;
63
+ return parseColor(getComputedStyle(probe).color);
64
+ });
65
+ } finally {
66
+ probe.remove();
67
+ }
68
+ }
69
+
70
+ /**
71
+ * The color actually behind an element: its own background if opaque,
72
+ * otherwise its translucent layers composited down onto the first opaque
73
+ * ancestor.
74
+ *
75
+ * Returns null when the paint is not knowable from CSS:
76
+ * - a `background-image` (gradient, photo, video poster) anywhere in the
77
+ * chain — its pixels need sampling, which is `useImageMode`'s job and
78
+ * needs CORS access the stylesheet cannot give us;
79
+ * - no opaque layer at all, where the paint is the browser canvas.
80
+ */
81
+ function resolveBackdrop(element) {
82
+ const layers = [];
83
+ let node = element;
84
+ while (node !== null) {
85
+ const style = getComputedStyle(node);
86
+ if (style.backgroundImage !== 'none') {
87
+ return null;
88
+ }
89
+ const color = parseColor(style.backgroundColor);
90
+ if (color !== null && color.a > 0) {
91
+ layers.push(color);
92
+ if (color.a >= 1) {
93
+ break;
94
+ }
95
+ }
96
+ node = node.parentElement;
97
+ }
98
+ const base = layers.pop();
99
+ if (base === undefined || base.a < 1) {
100
+ return null;
101
+ }
102
+ // layers is now top-first; composite downward so the topmost lands last.
103
+ return layers.reduceRight((backdrop, layer) => compositeOver(layer, backdrop), base);
104
+ }
105
+
106
+ /**
107
+ * Contrast at which a surface's own ambient text counts as reading well
108
+ * enough that no media context is wanted.
109
+ *
110
+ * WCAG's non-text / large-text line. It is deliberately low: this decides
111
+ * whether a surface is *effectively inverted*, not whether its text meets a
112
+ * standard. A pairing that clears 3:1 is one the theme is rendering
113
+ * successfully, and swapping in a media context there changes accent,
114
+ * overlays and borders for no legibility gain.
115
+ */
116
+ const AMBIENT_READS_AT = 3;
117
+
118
+ /**
119
+ * Which media context a surface wants: `'off'` when its ambient text already
120
+ * reads on the surface, otherwise whichever on-color reads better. Pure — the
121
+ * DOM read is the caller's. Ties between the two sides go to dark, matching
122
+ * the convention that an inverted surface is usually the dark one.
123
+ *
124
+ * The `'off'` answer is the point of measuring at all. A surface that a theme
125
+ * calls inverted but paints pale does not want an inverted context; its own
126
+ * text is already correct for it, and forcing one is how white-on-pale-grey
127
+ * happens.
128
+ */
129
+ export function pickMediaMode(background, ambient, onDark, onLight) {
130
+ if (onDark === null || onLight === null) {
131
+ return null;
132
+ }
133
+ if (ambient !== null && contrastRatio(ambient, background) >= AMBIENT_READS_AT) {
134
+ return 'off';
135
+ }
136
+ return contrastRatio(onDark, background) >= contrastRatio(onLight, background) ? 'dark' : 'light';
137
+ }
138
+
139
+ /**
140
+ * Detect the media context for the element's surroundings.
141
+ *
142
+ * Measures `ref`'s PARENT, never `ref` itself: MediaTheme sets its media
143
+ * attribute on its own element, so measuring that would feed the decision
144
+ * back into its own input and let it oscillate. The parent owns the
145
+ * background and sits outside the media context, so both inputs stay
146
+ * independent of the result.
147
+ *
148
+ * Returns null until a measurement succeeds — on the server, before the
149
+ * layout effect runs, and whenever the backdrop is not knowable from CSS.
150
+ * The caller renders its fallback for those.
151
+ */
152
+ export function useAutoMediaMode(ref, isEnabled) {
153
+ const [detected, setDetected] = useState(null);
154
+ // `tokens` is a stable reference unless the theme or color mode changes.
155
+ const {
156
+ tokens
157
+ } = useTheme();
158
+ const lastRef = useRef(null);
159
+
160
+ // Deliberately no dependency array. A surface's color is a painted value:
161
+ // it changes when a prop on some ancestor changes, and no dependency this
162
+ // hook could name would catch that (an earlier revision took a `watch`
163
+ // array and silently went stale whenever a caller forgot an entry). So the
164
+ // measurement re-runs whenever anything re-renders, and skips its own
165
+ // expensive half when nothing moved — see the early return below.
166
+ useIsomorphicLayoutEffect(() => {
167
+ const surface = ref.current?.parentElement ?? null;
168
+ if (!isEnabled || surface === null) {
169
+ return;
170
+ }
171
+ const background = resolveBackdrop(surface);
172
+ if (background === null) {
173
+ return;
174
+ }
175
+
176
+ // The backdrop walk above is a couple of getComputedStyle reads; the
177
+ // probe below appends a node and forces another style resolution. Skip
178
+ // it when neither the painted backdrop nor the theme has moved, which is
179
+ // the overwhelmingly common render.
180
+ const backgroundKey = formatColor(background);
181
+ const last = lastRef.current;
182
+ if (last !== null && last.background === backgroundKey && last.tokens === tokens) {
183
+ return;
184
+ }
185
+ lastRef.current = {
186
+ background: backgroundKey,
187
+ tokens
188
+ };
189
+ const [ambient, onDark, onLight] = resolvePaintedColors(surface, ['--color-text-primary', '--color-on-dark', '--color-on-light']);
190
+ const next = pickMediaMode(background, ambient, onDark, onLight);
191
+ if (next === null) {
192
+ return;
193
+ }
194
+
195
+ // eslint-disable-next-line @eslint-react/set-state-in-effect -- the mode is derived from painted DOM colors
196
+ setDetected(current => current === next ? current : next);
197
+ });
198
+
199
+ // A disabled hook must not answer with a value measured while it was on.
200
+ return isEnabled ? detected : null;
201
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"useInputStatusIcon.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputStatusIcon.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC,OAAO,EAAsB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAC3D,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAC,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AA2DjE,MAAM,WAAW,yBAAyB;IACxC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,yDAAyD;IACzD,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;;;;OAOG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,aAA0B,EAC1B,SAAiB,EACjB,IAAW,GACZ,EAAE,yBAAyB,GAAG,wBAAwB,CAwGtD"}
1
+ {"version":3,"file":"useInputStatusIcon.d.ts","sourceRoot":"","sources":["../../src/hooks/useInputStatusIcon.tsx"],"names":[],"mappings":"AAmCA,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,OAAO,CAAC;AAErC,OAAO,EAAsB,KAAK,QAAQ,EAAC,MAAM,SAAS,CAAC;AAC3D,OAAO,KAAK,EAAC,kBAAkB,EAAC,MAAM,4BAA4B,CAAC;AACnE,OAAO,KAAK,EAAC,WAAW,EAAkB,MAAM,gBAAgB,CAAC;AA8DjE,MAAM,WAAW,yBAAyB;IACxC,2DAA2D;IAC3D,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,yDAAyD;IACzD,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,IAAI,CAAC,EAAE,QAAQ,CAAC;CACjB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;;;OAKG;IACH,UAAU,EAAE,SAAS,CAAC;IACtB;;;;;;;OAOG;IACH,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,MAAM,EACN,aAA0B,EAC1B,SAAiB,EACjB,IAAW,GACZ,EAAE,yBAAyB,GAAG,wBAAwB,CAwGtD"}
@@ -68,7 +68,7 @@ const styles = {
68
68
  kmVPX3: "x1717udv",
69
69
  kogj98: "x1ghz6dp",
70
70
  kMwMTN: "x1heor9g",
71
- kkrTdU: "x1ypdohk",
71
+ kkrTdU: "x1ypdohk x16khyan",
72
72
  kfzvcC: "x67bb7w",
73
73
  kaIpWk: "xjspbzw",
74
74
  kInvED: "x7s97pk",
@@ -38,7 +38,9 @@ export interface UseListFocusOptions {
38
38
  */
39
39
  wrap?: boolean;
40
40
  /**
41
- * Callback when Escape key is pressed.
41
+ * Callback when Escape key is pressed. Supplying it also makes the list
42
+ * consume the key (`preventDefault`); without it Escape passes through to
43
+ * the surrounding layer.
42
44
  */
43
45
  onEscape?: () => void;
44
46
  /**
@@ -144,7 +146,8 @@ export interface UseListFocusReturn<T extends HTMLElement = HTMLElement> {
144
146
  * - ArrowUp/ArrowLeft: Move to previous item (wraps to last)
145
147
  * - Home: Move to first item
146
148
  * - End: Move to last item
147
- * - Escape: Custom callback (e.g., close menu)
149
+ * - Escape: runs `onEscape` and consumes the key. With no `onEscape` the key
150
+ * is left alone, so a surrounding layer can still dismiss on it.
148
151
  *
149
152
  * By default the hook only *moves* focus and leaves `tabindex` management to
150
153
  * the caller. Opt into {@link UseListFocusOptions.hasRovingTabIndex} for a hook
@@ -1 +1 @@
1
- {"version":3,"file":"useListFocus.d.ts","sourceRoot":"","sources":["../../src/hooks/useListFocus.ts"],"names":[],"mappings":"AAsBA;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;OAEG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,oBAAoB,CAAC;IAEnC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW;IACrE;;OAEG;IACH,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEnC;;OAEG;IACH,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC;IAEhD;;;;OAIG;IACH,WAAW,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAE3C;;OAEG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC;IAE1B;;OAEG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC;IAEzB;;;;;;OAMG;IACH,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,OAAO,CAAC;IAE/C;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,WAAW,EAAE,CAAC;CAC/B;AA+FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAC9D,OAAO,GAAE,mBAAwB,GAChC,kBAAkB,CAAC,CAAC,CAAC,CAwVvB"}
1
+ {"version":3,"file":"useListFocus.d.ts","sourceRoot":"","sources":["../../src/hooks/useListFocus.ts"],"names":[],"mappings":"AAwBA;;;;;GAKG;AACH,MAAM,MAAM,oBAAoB,GAAG,YAAY,GAAG,UAAU,GAAG,MAAM,CAAC;AAEtE;;GAEG;AACH,MAAM,WAAW,mBAAmB;IAClC;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IAEtB;;;;;;;;;;;;;;;;OAgBG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,IAAI,CAAC,EAAE,OAAO,CAAC;IAEf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,IAAI,CAAC;IAEtB;;;;OAIG;IACH,WAAW,CAAC,EAAE,oBAAoB,CAAC;IAEnC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,EAAE,OAAO,CAAC;IAEhB;;;;;;;;;;;;OAYG;IACH,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAE5B;;;;;;;;OAQG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,kBAAkB,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW;IACrE;;OAEG;IACH,OAAO,EAAE,KAAK,CAAC,SAAS,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAEnC;;OAEG;IACH,aAAa,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,IAAI,CAAC;IAEhD;;;;OAIG;IACH,WAAW,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,UAAU,KAAK,IAAI,CAAC;IAE3C;;OAEG;IACH,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAEnC;;OAEG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC;IAE1B;;OAEG;IACH,SAAS,EAAE,MAAM,OAAO,CAAC;IAEzB;;;;;;OAMG;IACH,SAAS,EAAE,CAAC,CAAC,EAAE,KAAK,CAAC,aAAa,KAAK,OAAO,CAAC;IAE/C;;;;;OAKG;IACH,QAAQ,EAAE,MAAM,WAAW,EAAE,CAAC;CAC/B;AA+FD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,WAAW,GAAG,WAAW,EAC9D,OAAO,GAAE,mBAAwB,GAChC,kBAAkB,CAAC,CAAC,CAAC,CA2VvB"}
@@ -14,6 +14,8 @@
14
14
  *
15
15
  * SYNC: When modified, update:
16
16
  * - /packages/core/src/hooks/index.ts
17
+ * - /packages/core/src/hooks/useListFocus.doc.mjs
18
+ * - /packages/core/src/hooks/useListFocus.test.tsx
17
19
  */
18
20
  import { useCallback, useRef } from 'react';
19
21
  import { isRtlElement } from "./isRtlElement.js";
@@ -127,7 +129,8 @@ function shouldDeferToCaret(target, key) {
127
129
  * - ArrowUp/ArrowLeft: Move to previous item (wraps to last)
128
130
  * - Home: Move to first item
129
131
  * - End: Move to last item
130
- * - Escape: Custom callback (e.g., close menu)
132
+ * - Escape: runs `onEscape` and consumes the key. With no `onEscape` the key
133
+ * is left alone, so a surrounding layer can still dismiss on it.
131
134
  *
132
135
  * By default the hook only *moves* focus and leaves `tabindex` management to
133
136
  * the caller. Opt into {@link UseListFocusOptions.hasRovingTabIndex} for a hook
@@ -380,12 +383,15 @@ export function useListFocus(options = {}) {
380
383
  return;
381
384
  }
382
385
 
383
- // Escape is handled regardless of orientation. Preserve the historical
384
- // behavior of always consuming Escape here (preventDefault) so consumers
385
- // that relied on it are unaffected.
386
+ // Escape is handled regardless of orientation, but only *consumed* when
387
+ // a handler asked for it: a list with no dismissal to perform must leave
388
+ // the key to whatever host layer does have one, and those defer to
389
+ // `defaultPrevented` (see `useFocusTrap`) or to the native popover.
386
390
  if (e.key === 'Escape') {
387
- e.preventDefault();
388
- onEscape?.();
391
+ if (onEscape) {
392
+ e.preventDefault();
393
+ onEscape();
394
+ }
389
395
  return;
390
396
  }
391
397
  const horizontal = orientation === 'horizontal' || orientation === 'both';
@@ -6,6 +6,10 @@
6
6
  * does not prevent body scroll behind modals. Restores scroll position
7
7
  * on unlock.
8
8
  *
9
+ * Pinning also hides the document's scrollbar, so the gutter that scrollbar
10
+ * occupied is held open for the duration of the lock — without it the page
11
+ * reflows sideways by ~15px the moment an overlay opens.
12
+ *
9
13
  * @example
10
14
  * ```
11
15
  * useScrollLock(isOpen);
@@ -1 +1 @@
1
- {"version":3,"file":"useScrollLock.d.ts","sourceRoot":"","sources":["../../src/hooks/useScrollLock.ts"],"names":[],"mappings":"AAgCA;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAiDrD"}
1
+ {"version":3,"file":"useScrollLock.d.ts","sourceRoot":"","sources":["../../src/hooks/useScrollLock.ts"],"names":[],"mappings":"AAmCA;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,OAAO,GAAG,IAAI,CAwDrD"}
@@ -13,8 +13,10 @@
13
13
  *
14
14
  * SYNC: When modified, update:
15
15
  * - /packages/core/src/hooks/index.ts
16
+ * - /packages/core/src/hooks/scrollbarGutter.ts
16
17
  */
17
18
  import { useEffect } from 'react';
19
+ import { holdScrollbarGutter } from "./scrollbarGutter.js";
18
20
  let lockCount = 0;
19
21
  let originalBodyState = null;
20
22
 
@@ -26,6 +28,10 @@ let originalBodyState = null;
26
28
  * does not prevent body scroll behind modals. Restores scroll position
27
29
  * on unlock.
28
30
  *
31
+ * Pinning also hides the document's scrollbar, so the gutter that scrollbar
32
+ * occupied is held open for the duration of the lock — without it the page
33
+ * reflows sideways by ~15px the moment an overlay opens.
34
+ *
29
35
  * @example
30
36
  * ```
31
37
  * useScrollLock(isOpen);
@@ -42,6 +48,9 @@ export function useScrollLock(isLocked) {
42
48
  if (lockCount === 0) {
43
49
  const scrollX = window.scrollX;
44
50
  const scrollY = window.scrollY;
51
+
52
+ // Taken before the pinning styles below hide the scrollbar.
53
+ const gutter = holdScrollbarGutter(body);
45
54
  originalBodyState = {
46
55
  scrollX,
47
56
  scrollY,
@@ -49,13 +58,15 @@ export function useScrollLock(isLocked) {
49
58
  position: body.style.position,
50
59
  top: body.style.top,
51
60
  left: body.style.left,
52
- right: body.style.right
61
+ right: body.style.right,
62
+ gutter
53
63
  };
54
64
  body.style.overflow = 'hidden';
55
65
  body.style.position = 'fixed';
56
66
  body.style.top = `-${scrollY}px`;
57
67
  body.style.left = '0';
58
68
  body.style.right = '0';
69
+ gutter.settle();
59
70
  }
60
71
  lockCount += 1;
61
72
  return () => {
@@ -70,6 +81,7 @@ export function useScrollLock(isLocked) {
70
81
  body.style.top = state.top;
71
82
  body.style.left = state.left;
72
83
  body.style.right = state.right;
84
+ state.gutter.release();
73
85
  window.scrollTo(state.scrollX, state.scrollY);
74
86
  };
75
87
  }, [isLocked]);
@@ -1 +1 @@
1
- {"version":3,"file":"InternationalizationContext.d.ts","sourceRoot":"","sources":["../../src/i18n/InternationalizationContext.ts"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAC,MAAM,SAAS,CAAC;AAEjE,MAAM,WAAW,gCAAgC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,KAAK,GAAG,KAAK,CAAC;IACzB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,2DAKpC,CAAC"}
1
+ {"version":3,"file":"InternationalizationContext.d.ts","sourceRoot":"","sources":["../../src/i18n/InternationalizationContext.ts"],"names":[],"mappings":"AAyBA,OAAO,KAAK,EAAC,MAAM,EAAE,gBAAgB,EAAE,SAAS,EAAC,MAAM,SAAS,CAAC;AAEjE,MAAM,WAAW,gCAAgC;IAC/C,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,KAAK,GAAG,KAAK,CAAC;IACzB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,2DAKpC,CAAC"}
@@ -16,6 +16,8 @@
16
16
  * - /packages/core/src/i18n/InternationalizationProvider.tsx
17
17
  * - /packages/core/src/i18n/t.client.ts
18
18
  * - /packages/core/src/i18n/useDirection.ts
19
+ * - /packages/core/src/i18n/useLocale.ts
20
+ * - /packages/core/src/i18n/useCollator.ts
19
21
  * - /packages/core/src/i18n/getLocaleDirection.ts
20
22
  * - /packages/core/src/i18n/index.ts
21
23
  */
@@ -8,12 +8,16 @@
8
8
  * The public API is deliberately small:
9
9
  * - InternationalizationProvider — provider component
10
10
  * - useTranslator — hook returning a translator function
11
+ * - useLocale — hook returning the provider locale
12
+ * - useCollator — provider-bound locale-aware comparison
11
13
  * - useDirection — hook returning the ambient text direction
12
14
  * - getLocaleDirection — server-safe locale → direction helper
13
15
  * - Translator — interface for consumer-injected runtimes
14
16
  *
15
17
  * SYNC: When modified, update these files to stay in sync:
16
18
  * - /packages/core/src/index.ts
19
+ * - /packages/core/src/i18n/useLocale.ts
20
+ * - /packages/core/src/i18n/useCollator.ts
17
21
  * - /packages/core/src/i18n/useDirection.ts
18
22
  * - /packages/core/src/i18n/getLocaleDirection.ts
19
23
  */
@@ -23,6 +27,8 @@ export { InternationalizationContext } from './InternationalizationContext';
23
27
  export type { InternationalizationContextValue } from './InternationalizationContext';
24
28
  export { useTranslator } from './useTranslator';
25
29
  export type { TranslatorFn } from './useTranslator';
30
+ export { useLocale } from './useLocale';
31
+ export { useCollator } from './useCollator';
26
32
  export { useDirection } from './useDirection';
27
33
  export { getLocaleDirection } from './getLocaleDirection';
28
34
  export type { Translator } from './translator';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,EAAC,4BAA4B,EAAC,MAAM,gCAAgC,CAAC;AAC5E,YAAY,EAAC,iCAAiC,EAAC,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAC,2BAA2B,EAAC,MAAM,+BAA+B,CAAC;AAC1E,YAAY,EAAC,gCAAgC,EAAC,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAC7C,YAAY,EACV,MAAM,EACN,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,SAAS,GACV,MAAM,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/i18n/index.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAC,4BAA4B,EAAC,MAAM,gCAAgC,CAAC;AAC5E,YAAY,EAAC,iCAAiC,EAAC,MAAM,gCAAgC,CAAC;AACtF,OAAO,EAAC,2BAA2B,EAAC,MAAM,+BAA+B,CAAC;AAC1E,YAAY,EAAC,gCAAgC,EAAC,MAAM,+BAA+B,CAAC;AACpF,OAAO,EAAC,aAAa,EAAC,MAAM,iBAAiB,CAAC;AAC9C,YAAY,EAAC,YAAY,EAAC,MAAM,iBAAiB,CAAC;AAClD,OAAO,EAAC,SAAS,EAAC,MAAM,aAAa,CAAC;AACtC,OAAO,EAAC,WAAW,EAAC,MAAM,eAAe,CAAC;AAC1C,OAAO,EAAC,YAAY,EAAC,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACxD,YAAY,EAAC,UAAU,EAAC,MAAM,cAAc,CAAC;AAC7C,YAAY,EACV,MAAM,EACN,OAAO,EACP,YAAY,EACZ,gBAAgB,EAChB,SAAS,GACV,MAAM,SAAS,CAAC"}