@astryxdesign/core 0.7.5-canary.fccd771 → 0.7.5

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 (1346) hide show
  1. package/CHANGELOG.md +211 -10
  2. package/README.md +15 -12
  3. package/dist/AlertDialog/AlertDialog.js +1 -1
  4. package/dist/AppShell/AppShell.d.ts +0 -22
  5. package/dist/AppShell/AppShell.d.ts.map +1 -1
  6. package/dist/AppShell/AppShell.js +155 -1
  7. package/dist/Avatar/AvatarStatusDot.js +2 -2
  8. package/dist/Badge/Badge.d.ts.map +1 -1
  9. package/dist/Badge/Badge.js +18 -2
  10. package/dist/Banner/Banner.d.ts +1 -0
  11. package/dist/Banner/Banner.d.ts.map +1 -1
  12. package/dist/Banner/Banner.js +64 -9
  13. package/dist/BottomSheet/BottomSheet.d.ts +53 -5
  14. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  15. package/dist/BottomSheet/BottomSheet.js +435 -198
  16. package/dist/BottomSheet/BottomSheetHostContext.d.ts +8 -0
  17. package/dist/BottomSheet/BottomSheetHostContext.d.ts.map +1 -0
  18. package/dist/BottomSheet/BottomSheetHostContext.js +35 -0
  19. package/dist/BottomSheet/BottomSheetPanel.d.ts +9 -1
  20. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  21. package/dist/BottomSheet/BottomSheetPanel.js +77 -23
  22. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +53 -14
  23. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  24. package/dist/BottomSheet/BottomSheetSwitcher.js +229 -27
  25. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +6 -0
  26. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -1
  27. package/dist/BottomSheet/bottomSheetEscape.d.ts +3 -0
  28. package/dist/BottomSheet/bottomSheetEscape.d.ts.map +1 -0
  29. package/dist/BottomSheet/bottomSheetEscape.js +20 -0
  30. package/dist/BottomSheet/bottomSheetStack.d.ts +262 -0
  31. package/dist/BottomSheet/bottomSheetStack.d.ts.map +1 -0
  32. package/dist/BottomSheet/bottomSheetStack.js +1675 -0
  33. package/dist/BottomSheet/useSheetGestures.d.ts +19 -3
  34. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  35. package/dist/BottomSheet/useSheetGestures.js +43 -14
  36. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  37. package/dist/Breadcrumbs/BreadcrumbItem.js +36 -3
  38. package/dist/Button/Button.d.ts.map +1 -1
  39. package/dist/Button/Button.js +18 -7
  40. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  41. package/dist/Chat/ChatComposer.js +25 -32
  42. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  43. package/dist/Chat/ChatComposerInput.js +55 -16
  44. package/dist/Chat/ChatMessageMetadata.js +2 -2
  45. package/dist/Chat/ChatPastedTextToken.d.ts.map +1 -1
  46. package/dist/Chat/ChatPastedTextToken.js +7 -6
  47. package/dist/Chat/ChatToolCalls.js +4 -4
  48. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  49. package/dist/ClickableCard/ClickableCard.js +10 -6
  50. package/dist/CodeBlock/CodeBlock.d.ts +25 -2
  51. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  52. package/dist/CodeBlock/CodeBlock.js +58 -19
  53. package/dist/CodeBlock/grammar.d.ts +134 -0
  54. package/dist/CodeBlock/grammar.d.ts.map +1 -0
  55. package/dist/CodeBlock/grammar.js +219 -0
  56. package/dist/CodeBlock/index.d.ts +2 -0
  57. package/dist/CodeBlock/index.d.ts.map +1 -1
  58. package/dist/CodeBlock/index.js +1 -0
  59. package/dist/CodeBlock/languages/dockerfile.d.ts +3 -0
  60. package/dist/CodeBlock/languages/dockerfile.d.ts.map +1 -0
  61. package/dist/CodeBlock/languages/dockerfile.js +45 -0
  62. package/dist/CodeBlock/languages/graphql.d.ts +3 -0
  63. package/dist/CodeBlock/languages/graphql.d.ts.map +1 -0
  64. package/dist/CodeBlock/languages/graphql.js +27 -0
  65. package/dist/CodeBlock/languages/java.d.ts +3 -0
  66. package/dist/CodeBlock/languages/java.d.ts.map +1 -0
  67. package/dist/CodeBlock/languages/java.js +24 -0
  68. package/dist/CodeBlock/languages/lua.d.ts +3 -0
  69. package/dist/CodeBlock/languages/lua.d.ts.map +1 -0
  70. package/dist/CodeBlock/languages/lua.js +21 -0
  71. package/dist/CodeBlock/languages/objective-c.d.ts +3 -0
  72. package/dist/CodeBlock/languages/objective-c.d.ts.map +1 -0
  73. package/dist/CodeBlock/languages/objective-c.js +27 -0
  74. package/dist/CodeBlock/languages/powershell.d.ts +3 -0
  75. package/dist/CodeBlock/languages/powershell.d.ts.map +1 -0
  76. package/dist/CodeBlock/languages/powershell.js +30 -0
  77. package/dist/CodeBlock/languages/ruby.d.ts +3 -0
  78. package/dist/CodeBlock/languages/ruby.d.ts.map +1 -0
  79. package/dist/CodeBlock/languages/ruby.js +24 -0
  80. package/dist/CodeBlock/languages/thrift.d.ts +3 -0
  81. package/dist/CodeBlock/languages/thrift.d.ts.map +1 -0
  82. package/dist/CodeBlock/languages/thrift.js +18 -0
  83. package/dist/CodeBlock/languages/toml.d.ts +3 -0
  84. package/dist/CodeBlock/languages/toml.d.ts.map +1 -0
  85. package/dist/CodeBlock/languages/toml.js +53 -0
  86. package/dist/CodeBlock/tokenizer.d.ts +8 -4
  87. package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
  88. package/dist/CodeBlock/tokenizer.js +158 -8
  89. package/dist/Collapsible/Collapsible.d.ts +8 -1
  90. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  91. package/dist/Collapsible/Collapsible.js +84 -2
  92. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  93. package/dist/CommandPalette/CommandPalette.js +15 -1
  94. package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
  95. package/dist/CommandPalette/CommandPaletteEmpty.js +1 -0
  96. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  97. package/dist/CommandPalette/CommandPaletteInput.js +14 -2
  98. package/dist/CommandPalette/busyStartSettle.d.ts +4 -0
  99. package/dist/CommandPalette/busyStartSettle.d.ts.map +1 -0
  100. package/dist/CommandPalette/busyStartSettle.js +23 -0
  101. package/dist/ComplexSelector/ComplexSelector.d.ts +20 -2
  102. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  103. package/dist/ComplexSelector/ComplexSelector.js +42 -7
  104. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  105. package/dist/ContextMenu/ContextMenu.js +48 -13
  106. package/dist/DateInput/DateInput.d.ts.map +1 -1
  107. package/dist/DateInput/DateInput.js +12 -5
  108. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  109. package/dist/DateInput/NativeDateField.js +2 -1
  110. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  111. package/dist/DateInput/TouchDateField.js +2 -1
  112. package/dist/DateInput/Wheel.d.ts.map +1 -1
  113. package/dist/DateInput/Wheel.js +1 -1
  114. package/dist/Dialog/Dialog.d.ts +4 -0
  115. package/dist/Dialog/Dialog.d.ts.map +1 -1
  116. package/dist/Dialog/Dialog.js +20 -8
  117. package/dist/Drawer/Drawer.d.ts.map +1 -1
  118. package/dist/Drawer/Drawer.js +18 -13
  119. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  120. package/dist/DropdownMenu/DropdownMenu.js +34 -30
  121. package/dist/DropdownMenu/DropdownMenuGroup.d.ts +7 -4
  122. package/dist/DropdownMenu/DropdownMenuGroup.d.ts.map +1 -1
  123. package/dist/DropdownMenu/DropdownMenuGroup.js +10 -4
  124. package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
  125. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +10 -5
  126. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  127. package/dist/DropdownMenu/DropdownMenuRadioItem.js +13 -5
  128. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +6 -6
  129. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  130. package/dist/DropdownMenu/DropdownMenuSubMenu.js +0 -3
  131. package/dist/DropdownMenu/MenuBottomSheet.d.ts +11 -4
  132. package/dist/DropdownMenu/MenuBottomSheet.d.ts.map +1 -1
  133. package/dist/DropdownMenu/MenuBottomSheet.js +35 -9
  134. package/dist/DropdownMenu/MenuBottomSheetActionList.js +3 -3
  135. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +2 -0
  136. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  137. package/dist/DropdownMenu/lazyMenuBottomSheet.js +25 -3
  138. package/dist/DropdownMenu/menuBottomSheet.stylex.d.ts +23 -0
  139. package/dist/DropdownMenu/menuBottomSheet.stylex.d.ts.map +1 -0
  140. package/dist/DropdownMenu/menuBottomSheet.stylex.js +29 -0
  141. package/dist/DropdownMenu/menuItemHover.d.ts +3 -0
  142. package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -1
  143. package/dist/DropdownMenu/menuItemHover.js +14 -1
  144. package/dist/DropdownMenu/menuTouchAction.stylex.d.ts +25 -0
  145. package/dist/DropdownMenu/menuTouchAction.stylex.d.ts.map +1 -0
  146. package/dist/DropdownMenu/menuTouchAction.stylex.js +29 -0
  147. package/dist/DropdownMenu/useMenuDrillIn.d.ts.map +1 -1
  148. package/dist/DropdownMenu/useMenuDrillIn.js +7 -5
  149. package/dist/EmptyState/EmptyState.d.ts +4 -2
  150. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  151. package/dist/EmptyState/EmptyState.js +6 -4
  152. package/dist/Field/Field.js +1 -1
  153. package/dist/Field/FieldLabel.js +1 -1
  154. package/dist/Field/PanelSearchInput.d.ts +9 -1
  155. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  156. package/dist/Field/PanelSearchInput.js +31 -22
  157. package/dist/Field/inputDisabledFocus.d.ts +14 -0
  158. package/dist/Field/inputDisabledFocus.d.ts.map +1 -0
  159. package/dist/Field/inputDisabledFocus.js +19 -0
  160. package/dist/Field/inputStyles.stylex.d.ts +9 -9
  161. package/dist/Field/inputStyles.stylex.js +9 -9
  162. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  163. package/dist/FieldStatus/FieldStatus.js +7 -3
  164. package/dist/FileInput/FileInput.d.ts.map +1 -1
  165. package/dist/FileInput/FileInput.js +22 -12
  166. package/dist/Icon/Icon.d.ts +37 -5
  167. package/dist/Icon/Icon.d.ts.map +1 -1
  168. package/dist/Icon/Icon.js +65 -11
  169. package/dist/Icon/IconSize.stylex.d.ts +16 -11
  170. package/dist/Icon/IconSize.stylex.d.ts.map +1 -1
  171. package/dist/Icon/IconSize.stylex.js +27 -11
  172. package/dist/Icon/globalIconRegistry.d.ts +71 -4
  173. package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
  174. package/dist/Icon/globalIconRegistry.js +163 -23
  175. package/dist/Icon/index.d.ts +26 -2
  176. package/dist/Icon/index.d.ts.map +1 -1
  177. package/dist/Icon/index.js +24 -1
  178. package/dist/Icon/useIcon.d.ts +5 -1
  179. package/dist/Icon/useIcon.d.ts.map +1 -1
  180. package/dist/Icon/useIcon.js +5 -1
  181. package/dist/InputGroup/InputGroup.d.ts +1 -1
  182. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  183. package/dist/InputGroup/InputGroup.js +46 -36
  184. package/dist/InputGroup/InputGroupInternalContext.d.ts +4 -0
  185. package/dist/InputGroup/InputGroupInternalContext.d.ts.map +1 -0
  186. package/dist/InputGroup/InputGroupInternalContext.js +15 -0
  187. package/dist/InputGroup/InputGroupText.d.ts.map +1 -1
  188. package/dist/InputGroup/InputGroupText.js +2 -0
  189. package/dist/InputGroup/groupStyles.d.ts +9 -0
  190. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  191. package/dist/InputGroup/groupStyles.js +28 -14
  192. package/dist/Item/Item.d.ts +5 -1
  193. package/dist/Item/Item.d.ts.map +1 -1
  194. package/dist/Item/Item.js +23 -7
  195. package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.d.ts +2 -0
  196. package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.d.ts.map +1 -0
  197. package/dist/Item/ItemMarkerColumns.a11y.chromium.spec.js +132 -0
  198. package/dist/Item/ItemMarkerColumnsContext.d.ts +14 -0
  199. package/dist/Item/ItemMarkerColumnsContext.d.ts.map +1 -0
  200. package/dist/Item/ItemMarkerColumnsContext.js +18 -0
  201. package/dist/Item/ItemSwipeLayer.d.ts.map +1 -1
  202. package/dist/Item/ItemSwipeLayer.js +3 -0
  203. package/dist/Item/useSwipeAction.d.ts.map +1 -1
  204. package/dist/Item/useSwipeAction.js +60 -5
  205. package/dist/Kbd/Kbd.d.ts +2 -2
  206. package/dist/Kbd/Kbd.d.ts.map +1 -1
  207. package/dist/Kbd/Kbd.js +18 -11
  208. package/dist/Layer/layerAnimations.stylex.d.ts +9 -5
  209. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  210. package/dist/Layer/layerAnimations.stylex.js +23 -10
  211. package/dist/Layer/layerSlideRules.d.ts +62 -2
  212. package/dist/Layer/layerSlideRules.d.ts.map +1 -1
  213. package/dist/Layer/layerSlideRules.js +124 -3
  214. package/dist/Layer/layerStack.d.ts +12 -9
  215. package/dist/Layer/layerStack.d.ts.map +1 -1
  216. package/dist/Layer/layerStack.js +116 -53
  217. package/dist/Layer/modalOutlet.d.ts +44 -6
  218. package/dist/Layer/modalOutlet.d.ts.map +1 -1
  219. package/dist/Layer/modalOutlet.js +150 -14
  220. package/dist/Layer/preserveAnimations.d.ts +11 -0
  221. package/dist/Layer/preserveAnimations.d.ts.map +1 -0
  222. package/dist/Layer/preserveAnimations.js +245 -0
  223. package/dist/Layer/useLayer.d.ts +19 -2
  224. package/dist/Layer/useLayer.d.ts.map +1 -1
  225. package/dist/Layer/useLayer.js +531 -44
  226. package/dist/Layer/useLayerDismissal.d.ts +10 -7
  227. package/dist/Layer/useLayerDismissal.d.ts.map +1 -1
  228. package/dist/Layer/useLayerDismissal.js +8 -8
  229. package/dist/Layer/useTouchTrigger.d.ts +14 -1
  230. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  231. package/dist/Layer/useTouchTrigger.js +72 -17
  232. package/dist/Layout/Layout.d.ts.map +1 -1
  233. package/dist/Layout/Layout.js +4 -0
  234. package/dist/Layout/LayoutContent.d.ts.map +1 -1
  235. package/dist/Layout/LayoutContent.js +2 -2
  236. package/dist/Layout/LayoutFooter.d.ts.map +1 -1
  237. package/dist/Layout/LayoutFooter.js +2 -1
  238. package/dist/Layout/LayoutHeader.d.ts.map +1 -1
  239. package/dist/Layout/LayoutHeader.js +2 -1
  240. package/dist/Layout/layoutEdges.stylex.d.ts +20 -0
  241. package/dist/Layout/layoutEdges.stylex.d.ts.map +1 -0
  242. package/dist/Layout/layoutEdges.stylex.js +28 -0
  243. package/dist/Lightbox/Lightbox.d.ts +5 -2
  244. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  245. package/dist/Lightbox/Lightbox.js +111 -89
  246. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts +2 -0
  247. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts.map +1 -0
  248. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.js +78 -0
  249. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts +2 -0
  250. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts.map +1 -0
  251. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +65 -0
  252. package/dist/List/List.d.ts +2 -1
  253. package/dist/List/List.d.ts.map +1 -1
  254. package/dist/List/List.js +9 -2
  255. package/dist/List/ListContext.d.ts +16 -4
  256. package/dist/List/ListContext.d.ts.map +1 -1
  257. package/dist/List/ListContext.js +10 -5
  258. package/dist/List/ListItem.d.ts +7 -1
  259. package/dist/List/ListItem.d.ts.map +1 -1
  260. package/dist/List/ListItem.js +52 -8
  261. package/dist/List/ListMarkers.a11y.chromium.spec.d.ts +2 -0
  262. package/dist/List/ListMarkers.a11y.chromium.spec.d.ts.map +1 -0
  263. package/dist/List/ListMarkers.a11y.chromium.spec.js +677 -0
  264. package/dist/Markdown/Markdown.d.ts +11 -1
  265. package/dist/Markdown/Markdown.d.ts.map +1 -1
  266. package/dist/Markdown/Markdown.fr23.bench.js +3 -1
  267. package/dist/Markdown/Markdown.fr23.sampling.d.ts +16 -0
  268. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -1
  269. package/dist/Markdown/Markdown.fr23.sampling.js +13 -4
  270. package/dist/Markdown/Markdown.js +41 -14
  271. package/dist/Markdown/MarkdownTable.a11y.chromium.spec.js +1 -0
  272. package/dist/MobileNav/MobileNav.d.ts +2 -1
  273. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  274. package/dist/MobileNav/MobileNav.js +46 -37
  275. package/dist/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.js +1 -0
  276. package/dist/MobileNav/MobileNavToggle.d.ts +7 -3
  277. package/dist/MobileNav/MobileNavToggle.d.ts.map +1 -1
  278. package/dist/MobileNav/MobileNavToggle.js +11 -3
  279. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +53 -6
  280. package/dist/MultiSelector/MultiSelector.d.ts +1 -1
  281. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  282. package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.js +1 -0
  283. package/dist/MultiSelector/MultiSelector.js +21 -5
  284. package/dist/MultiSelector/OptionActions.a11y.chromium.spec.js +1 -0
  285. package/dist/NavMenu/NavHeadingMenu.d.ts +1 -1
  286. package/dist/NavMenu/NavHeadingMenu.d.ts.map +1 -1
  287. package/dist/NavMenu/NavHeadingMenu.js +29 -5
  288. package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
  289. package/dist/NavMenu/NavHeadingMenuItem.js +51 -7
  290. package/dist/NavMenu/NavMenuContext.d.ts +9 -0
  291. package/dist/NavMenu/NavMenuContext.d.ts.map +1 -1
  292. package/dist/NavMenu/NavMenuContext.js +9 -0
  293. package/dist/NumberInput/NumberInput.d.ts +4 -4
  294. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  295. package/dist/NumberInput/NumberInput.js +61 -24
  296. package/dist/Overlay/Overlay.d.ts +3 -3
  297. package/dist/Overlay/Overlay.d.ts.map +1 -1
  298. package/dist/Overlay/Overlay.js +12 -5
  299. package/dist/Popover/Popover.d.ts +41 -2
  300. package/dist/Popover/Popover.d.ts.map +1 -1
  301. package/dist/Popover/Popover.js +276 -44
  302. package/dist/Popover/index.d.ts +1 -1
  303. package/dist/Popover/index.d.ts.map +1 -1
  304. package/dist/Popover/lazyPopoverBottomSheet.d.ts +23 -0
  305. package/dist/Popover/lazyPopoverBottomSheet.d.ts.map +1 -0
  306. package/dist/Popover/lazyPopoverBottomSheet.js +40 -0
  307. package/dist/Popover/usePopover.d.ts.map +1 -1
  308. package/dist/Popover/usePopover.js +11 -5
  309. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  310. package/dist/PowerSearch/PowerSearch.js +7 -5
  311. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  312. package/dist/ProgressBar/ProgressBar.js +8 -0
  313. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  314. package/dist/RadioList/RadioListItem.js +10 -2
  315. package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
  316. package/dist/ScrollableArea/ScrollableArea.js +1 -1
  317. package/dist/SegmentedControl/SegmentedControl.d.ts +1 -1
  318. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  319. package/dist/SegmentedControl/SegmentedControl.js +6 -2
  320. package/dist/SelectableCard/SelectableCard.d.ts +5 -5
  321. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  322. package/dist/SelectableCard/SelectableCard.js +15 -11
  323. package/dist/Selector/Selector.d.ts.map +1 -1
  324. package/dist/Selector/Selector.js +27 -8
  325. package/dist/Selector/hooks.d.ts +52 -6
  326. package/dist/Selector/hooks.d.ts.map +1 -1
  327. package/dist/Selector/hooks.js +145 -2
  328. package/dist/SideNav/SideNav.d.ts.map +1 -1
  329. package/dist/SideNav/SideNav.js +58 -2
  330. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  331. package/dist/SideNav/SideNavHeading.js +79 -3
  332. package/dist/SideNav/SideNavItem.d.ts +5 -1
  333. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  334. package/dist/SideNav/SideNavItem.js +36 -13
  335. package/dist/SideNav/railMotion.d.ts +54 -0
  336. package/dist/SideNav/railMotion.d.ts.map +1 -0
  337. package/dist/SideNav/railMotion.js +253 -0
  338. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  339. package/dist/Skeleton/Skeleton.js +12 -3
  340. package/dist/Slider/Slider.d.ts.map +1 -1
  341. package/dist/Slider/Slider.js +52 -15
  342. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  343. package/dist/StatusDot/StatusDot.js +12 -0
  344. package/dist/Stepper/Step.d.ts.map +1 -1
  345. package/dist/Stepper/Step.js +10 -6
  346. package/dist/Switch/Switch.d.ts.map +1 -1
  347. package/dist/Switch/Switch.js +5 -5
  348. package/dist/Switch/switch.markers.stylex.d.ts +7 -2
  349. package/dist/Switch/switch.markers.stylex.d.ts.map +1 -1
  350. package/dist/Switch/switch.markers.stylex.js +8 -3
  351. package/dist/TabList/Tab.d.ts.map +1 -1
  352. package/dist/TabList/Tab.js +5 -1
  353. package/dist/TabList/TabMenu.d.ts.map +1 -1
  354. package/dist/TabList/TabMenu.js +25 -3
  355. package/dist/Table/TableCell.d.ts.map +1 -1
  356. package/dist/Table/TableCell.js +5 -1
  357. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  358. package/dist/Table/TableHeaderCell.js +1 -0
  359. package/dist/Table/TableRow.d.ts.map +1 -1
  360. package/dist/Table/TableRow.js +3 -0
  361. package/dist/Table/glidingDivider.d.ts +96 -0
  362. package/dist/Table/glidingDivider.d.ts.map +1 -0
  363. package/dist/Table/glidingDivider.js +275 -0
  364. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  365. package/dist/Table/plugins/columnResize/useTableColumnResize.js +11 -2
  366. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +8 -0
  367. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  368. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +374 -13
  369. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  370. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +244 -6
  371. package/dist/Table/rowDivider.d.ts +34 -0
  372. package/dist/Table/rowDivider.d.ts.map +1 -0
  373. package/dist/Table/rowDivider.js +118 -0
  374. package/dist/TextArea/TextArea.d.ts +6 -4
  375. package/dist/TextArea/TextArea.d.ts.map +1 -1
  376. package/dist/TextArea/TextArea.js +15 -12
  377. package/dist/TextInput/TextInput.d.ts +7 -5
  378. package/dist/TextInput/TextInput.d.ts.map +1 -1
  379. package/dist/TextInput/TextInput.js +43 -22
  380. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  381. package/dist/Thumbnail/Thumbnail.js +45 -11
  382. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  383. package/dist/TimeInput/TimeInput.js +12 -4
  384. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  385. package/dist/TimeInput/TouchTimeField.js +2 -1
  386. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  387. package/dist/Toast/ToastViewport.js +62 -6
  388. package/dist/Tokenizer/Tokenizer.d.ts +71 -4
  389. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  390. package/dist/Tokenizer/Tokenizer.js +430 -45
  391. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +98 -0
  392. package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -0
  393. package/dist/Tokenizer/TokenizerBottomSheet.js +721 -0
  394. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  395. package/dist/Tooltip/useTooltip.js +9 -3
  396. package/dist/TopNav/TopNavHeading.d.ts.map +1 -1
  397. package/dist/TopNav/TopNavHeading.js +26 -0
  398. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  399. package/dist/TopNav/TopNavMegaMenu.js +4 -4
  400. package/dist/TopNav/TopNavMenu.d.ts.map +1 -1
  401. package/dist/TopNav/TopNavMenu.js +32 -4
  402. package/dist/TreeList/TreeList.d.ts +8 -23
  403. package/dist/TreeList/TreeList.d.ts.map +1 -1
  404. package/dist/TreeList/TreeList.js +175 -3
  405. package/dist/TreeList/TreeListBranches.d.ts.map +1 -1
  406. package/dist/TreeList/TreeListBranches.js +7 -5
  407. package/dist/TreeList/TreeListItem.d.ts +7 -1
  408. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  409. package/dist/TreeList/TreeListItem.js +5 -3
  410. package/dist/Typeahead/BaseTypeahead.d.ts +1 -1
  411. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  412. package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.d.ts +2 -0
  413. package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.d.ts.map +1 -0
  414. package/dist/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.js +118 -0
  415. package/dist/Typeahead/BaseTypeahead.js +27 -11
  416. package/dist/Typeahead/Typeahead.d.ts +1 -1
  417. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  418. package/dist/Typeahead/Typeahead.js +31 -14
  419. package/dist/astryx.css +164 -41
  420. package/dist/gestures/GestureArena.d.ts +175 -0
  421. package/dist/gestures/GestureArena.d.ts.map +1 -0
  422. package/dist/gestures/GestureArena.js +816 -0
  423. package/dist/gestures/GestureRecognizer.d.ts +239 -0
  424. package/dist/gestures/GestureRecognizer.d.ts.map +1 -0
  425. package/dist/gestures/GestureRecognizer.js +487 -0
  426. package/dist/gestures/LongPressGestureRecognizer.d.ts +32 -0
  427. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -0
  428. package/dist/gestures/LongPressGestureRecognizer.js +135 -0
  429. package/dist/gestures/PanGestureRecognizer.d.ts +117 -0
  430. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -0
  431. package/dist/gestures/PanGestureRecognizer.js +349 -0
  432. package/dist/gestures/TapGestureRecognizer.d.ts +39 -0
  433. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -0
  434. package/dist/gestures/TapGestureRecognizer.js +151 -0
  435. package/dist/gestures/VelocityTracker.d.ts +51 -0
  436. package/dist/gestures/VelocityTracker.d.ts.map +1 -0
  437. package/dist/gestures/VelocityTracker.js +186 -0
  438. package/dist/gestures/geometry.d.ts +17 -0
  439. package/dist/gestures/geometry.d.ts.map +1 -0
  440. package/dist/gestures/geometry.js +55 -0
  441. package/dist/gestures/types.d.ts +139 -0
  442. package/dist/gestures/types.d.ts.map +1 -0
  443. package/dist/gestures/types.js +67 -0
  444. package/dist/hooks/AnnounceRenderedText.d.ts +17 -0
  445. package/dist/hooks/AnnounceRenderedText.d.ts.map +1 -0
  446. package/dist/hooks/AnnounceRenderedText.js +32 -0
  447. package/dist/hooks/ModalAnnounceProvider.d.ts +41 -0
  448. package/dist/hooks/ModalAnnounceProvider.d.ts.map +1 -0
  449. package/dist/hooks/ModalAnnounceProvider.js +133 -0
  450. package/dist/hooks/actionGroupTracker.d.ts +98 -0
  451. package/dist/hooks/actionGroupTracker.d.ts.map +1 -0
  452. package/dist/hooks/actionGroupTracker.js +338 -0
  453. package/dist/hooks/index.d.ts +2 -0
  454. package/dist/hooks/index.d.ts.map +1 -1
  455. package/dist/hooks/index.js +1 -0
  456. package/dist/hooks/menuPressOnItems.d.ts +19 -0
  457. package/dist/hooks/menuPressOnItems.d.ts.map +1 -0
  458. package/dist/hooks/menuPressOnItems.js +32 -0
  459. package/dist/hooks/modalAnnounce.d.ts +18 -0
  460. package/dist/hooks/modalAnnounce.d.ts.map +1 -0
  461. package/dist/hooks/modalAnnounce.js +382 -0
  462. package/dist/hooks/scrollGeometry.d.ts +28 -0
  463. package/dist/hooks/scrollGeometry.d.ts.map +1 -1
  464. package/dist/hooks/scrollGeometry.js +36 -2
  465. package/dist/hooks/useAdaptivePresentation.d.ts +9 -1
  466. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
  467. package/dist/hooks/useAdaptivePresentation.js +33 -8
  468. package/dist/hooks/useAnimatedLayout.d.ts +42 -0
  469. package/dist/hooks/useAnimatedLayout.d.ts.map +1 -0
  470. package/dist/hooks/useAnimatedLayout.js +46 -0
  471. package/dist/hooks/useAnnounce.d.ts +132 -1
  472. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  473. package/dist/hooks/useAnnounce.js +356 -27
  474. package/dist/hooks/useAnnounceRenderedText.d.ts +19 -2
  475. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  476. package/dist/hooks/useAnnounceRenderedText.js +52 -11
  477. package/dist/hooks/useBusyAnnouncement.d.ts +9 -5
  478. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  479. package/dist/hooks/useBusyAnnouncement.js +58 -46
  480. package/dist/hooks/useFocusTrap.d.ts +1 -1
  481. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  482. package/dist/hooks/useFocusTrap.js +57 -26
  483. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  484. package/dist/hooks/useMenuHover.js +6 -2
  485. package/dist/hooks/useMenuPress.d.ts +4 -2
  486. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  487. package/dist/hooks/useMenuPress.js +58 -33
  488. package/dist/hooks/usePressFeedback.d.ts +5 -2
  489. package/dist/hooks/usePressFeedback.d.ts.map +1 -1
  490. package/dist/hooks/usePressFeedback.js +5 -2
  491. package/dist/hooks/useScrollableArea.d.ts +5 -0
  492. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  493. package/dist/hooks/useScrollableArea.js +104 -11
  494. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  495. package/dist/i18n/generated-locales/en.generated.js +33 -0
  496. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  497. package/dist/i18n/generated-locales/pseudo.generated.js +33 -0
  498. package/dist/internal/tokenizer-presentation.d.ts +21 -0
  499. package/dist/internal/tokenizer-presentation.d.ts.map +1 -0
  500. package/dist/internal/tokenizer-presentation.js +21 -0
  501. package/dist/internal/touch.d.ts +26 -0
  502. package/dist/internal/touch.d.ts.map +1 -0
  503. package/dist/internal/touch.js +28 -0
  504. package/dist/motion/LayoutChangeSnapshot.d.ts +33 -0
  505. package/dist/motion/LayoutChangeSnapshot.d.ts.map +1 -0
  506. package/dist/motion/LayoutChangeSnapshot.js +37 -0
  507. package/dist/motion/animatedLayout.d.ts +190 -0
  508. package/dist/motion/animatedLayout.d.ts.map +1 -0
  509. package/dist/motion/animatedLayout.js +1502 -0
  510. package/dist/motion/animator.d.ts +240 -0
  511. package/dist/motion/animator.d.ts.map +1 -0
  512. package/dist/motion/animator.js +2203 -0
  513. package/dist/motion/bezier.d.ts +18 -0
  514. package/dist/motion/bezier.d.ts.map +1 -0
  515. package/dist/motion/bezier.js +60 -0
  516. package/dist/motion/coast.d.ts +61 -0
  517. package/dist/motion/coast.d.ts.map +1 -0
  518. package/dist/motion/coast.js +107 -0
  519. package/dist/motion/decay.d.ts +41 -0
  520. package/dist/motion/decay.d.ts.map +1 -0
  521. package/dist/motion/decay.js +90 -0
  522. package/dist/motion/projection.d.ts +36 -0
  523. package/dist/motion/projection.d.ts.map +1 -0
  524. package/dist/motion/projection.js +92 -0
  525. package/dist/motion/reducedMotion.d.ts +25 -0
  526. package/dist/motion/reducedMotion.d.ts.map +1 -0
  527. package/dist/motion/reducedMotion.js +85 -0
  528. package/dist/motion/reducedMotion.stylex.d.ts +19 -0
  529. package/dist/motion/reducedMotion.stylex.d.ts.map +1 -0
  530. package/dist/motion/reducedMotion.stylex.js +37 -0
  531. package/dist/motion/reducedMotionPlan.d.ts +89 -0
  532. package/dist/motion/reducedMotionPlan.d.ts.map +1 -0
  533. package/dist/motion/reducedMotionPlan.js +194 -0
  534. package/dist/motion/resolveSnapPoint.d.ts +52 -0
  535. package/dist/motion/resolveSnapPoint.d.ts.map +1 -0
  536. package/dist/motion/resolveSnapPoint.js +135 -0
  537. package/dist/motion/roleValue.d.ts +33 -0
  538. package/dist/motion/roleValue.d.ts.map +1 -0
  539. package/dist/motion/roleValue.js +84 -0
  540. package/dist/motion/roles.d.ts +79 -0
  541. package/dist/motion/roles.d.ts.map +1 -0
  542. package/dist/motion/roles.js +199 -0
  543. package/dist/motion/rubberBand.d.ts +20 -0
  544. package/dist/motion/rubberBand.d.ts.map +1 -0
  545. package/dist/motion/rubberBand.js +91 -0
  546. package/dist/motion/selectPage.d.ts +26 -0
  547. package/dist/motion/selectPage.d.ts.map +1 -0
  548. package/dist/motion/selectPage.js +55 -0
  549. package/dist/motion/spring.d.ts +193 -0
  550. package/dist/motion/spring.d.ts.map +1 -0
  551. package/dist/motion/spring.js +442 -0
  552. package/dist/motion/transientCopy.d.ts +33 -0
  553. package/dist/motion/transientCopy.d.ts.map +1 -0
  554. package/dist/motion/transientCopy.js +314 -0
  555. package/dist/motion/uikit/gestures.d.ts +642 -0
  556. package/dist/motion/uikit/gestures.d.ts.map +1 -0
  557. package/dist/motion/uikit/gestures.js +428 -0
  558. package/dist/motion/uikit/index.d.ts +24 -0
  559. package/dist/motion/uikit/index.d.ts.map +1 -0
  560. package/dist/motion/uikit/index.js +26 -0
  561. package/dist/motion/uikit/navigation.d.ts +54 -0
  562. package/dist/motion/uikit/navigation.d.ts.map +1 -0
  563. package/dist/motion/uikit/navigation.js +83 -0
  564. package/dist/motion/uikit/scroll.d.ts +116 -0
  565. package/dist/motion/uikit/scroll.d.ts.map +1 -0
  566. package/dist/motion/uikit/scroll.js +146 -0
  567. package/dist/motion/uikit/springs.d.ts +545 -0
  568. package/dist/motion/uikit/springs.d.ts.map +1 -0
  569. package/dist/motion/uikit/springs.js +548 -0
  570. package/dist/motion/uikit/timing.d.ts +202 -0
  571. package/dist/motion/uikit/timing.d.ts.map +1 -0
  572. package/dist/motion/uikit/timing.js +201 -0
  573. package/dist/reset.a11y.chromium.spec.js +1 -0
  574. package/dist/reset.until-found.a11y.browser.spec.js +1 -0
  575. package/dist/theme/declarationBoundary.d.ts +13 -0
  576. package/dist/theme/declarationBoundary.d.ts.map +1 -1
  577. package/dist/theme/declarationBoundary.js +264 -1
  578. package/dist/theme/defineTheme.d.ts +111 -11
  579. package/dist/theme/defineTheme.d.ts.map +1 -1
  580. package/dist/theme/defineTheme.js +97 -7
  581. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  582. package/dist/theme/derivedVarRegistry.js +9 -0
  583. package/dist/theme/generateThemeRules.d.ts +6 -2
  584. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  585. package/dist/theme/generateThemeRules.js +468 -24
  586. package/dist/theme/index.d.ts +2 -2
  587. package/dist/theme/index.d.ts.map +1 -1
  588. package/dist/theme/index.js +1 -1
  589. package/dist/theme/statusColor.d.ts +48 -0
  590. package/dist/theme/statusColor.d.ts.map +1 -0
  591. package/dist/theme/statusColor.js +203 -0
  592. package/dist/theme/statusRoleDerivation.d.ts +11 -0
  593. package/dist/theme/statusRoleDerivation.d.ts.map +1 -0
  594. package/dist/theme/statusRoleDerivation.js +236 -0
  595. package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
  596. package/dist/theme/syntax/SyntaxTheme.js +1 -1
  597. package/dist/theme/syntax/defineSyntaxTheme.js +1 -1
  598. package/dist/theme/syntax/presets.d.ts +1 -1
  599. package/dist/theme/syntax/presets.js +1 -1
  600. package/dist/theme/syntax/tokens.d.ts +1 -1
  601. package/dist/theme/syntax/tokens.js +1 -1
  602. package/dist/theme/themeAdaptations.d.ts +25 -1
  603. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  604. package/dist/theme/themeAdaptations.js +30 -1
  605. package/dist/theme/tokens.d.ts.map +1 -1
  606. package/dist/theme/tokens.js +16 -1
  607. package/dist/theme/tokens.stylex.d.ts +42 -2
  608. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  609. package/dist/theme/tokens.stylex.js +54 -3
  610. package/dist/theme/useTheme.d.ts +4 -2
  611. package/dist/theme/useTheme.d.ts.map +1 -1
  612. package/dist/theme/useTheme.js +10 -4
  613. package/dist/utils/edgeAutoscroll.d.ts +53 -0
  614. package/dist/utils/edgeAutoscroll.d.ts.map +1 -0
  615. package/dist/utils/edgeAutoscroll.js +81 -0
  616. package/dist/utils/hitArea.d.ts +72 -0
  617. package/dist/utils/hitArea.d.ts.map +1 -0
  618. package/dist/utils/hitArea.js +681 -0
  619. package/dist/utils/interactionOverlay.stylex.d.ts +4 -1
  620. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  621. package/dist/utils/interactionOverlay.stylex.js +4 -1
  622. package/dist/utils/pressFeedback.d.ts +5 -1
  623. package/dist/utils/pressFeedback.d.ts.map +1 -1
  624. package/dist/utils/pressFeedback.js +285 -54
  625. package/dist/utils/pressGesture.d.ts +13 -1
  626. package/dist/utils/pressGesture.d.ts.map +1 -1
  627. package/dist/utils/pressGesture.js +40 -1
  628. package/dist/utils/touchPresentation.d.ts +48 -0
  629. package/dist/utils/touchPresentation.d.ts.map +1 -0
  630. package/dist/utils/touchPresentation.js +133 -0
  631. package/locales/af-ZA.json +1 -1
  632. package/locales/ar-SA.json +1 -1
  633. package/locales/ca-ES.json +1 -1
  634. package/locales/cs-CZ.json +1 -1
  635. package/locales/da-DK.json +1 -1
  636. package/locales/de-DE.json +1 -1
  637. package/locales/el-GR.json +1 -1
  638. package/locales/en.json +132 -0
  639. package/locales/es-ES.json +1 -1
  640. package/locales/fi-FI.json +1 -1
  641. package/locales/fr-FR.json +1 -1
  642. package/locales/he-IL.json +1 -1
  643. package/locales/hu-HU.json +1 -1
  644. package/locales/it-IT.json +1 -1
  645. package/locales/ja-JP.json +1 -1
  646. package/locales/ko-KR.json +1 -1
  647. package/locales/nl-NL.json +1 -1
  648. package/locales/no-NO.json +1 -1
  649. package/locales/pl-PL.json +1 -1
  650. package/locales/pseudo.json +99 -0
  651. package/locales/pt-BR.json +1 -1
  652. package/locales/pt-PT.json +1 -1
  653. package/locales/ro-RO.json +1 -1
  654. package/locales/ru-RU.json +1 -1
  655. package/locales/sr-SP.json +1 -1
  656. package/locales/sv-SE.json +1 -1
  657. package/locales/tr-TR.json +1 -1
  658. package/locales/uk-UA.json +1 -1
  659. package/locales/vi-VN.json +1 -1
  660. package/locales/zh-CN.json +1 -1
  661. package/locales/zh-TW.json +1 -1
  662. package/package.json +63 -8
  663. package/src/AlertDialog/AlertDialog.spec.md +85 -31
  664. package/src/AlertDialog/AlertDialog.tsx +1 -1
  665. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +1 -0
  666. package/src/AppShell/AppShell.spec.md +334 -0
  667. package/src/AppShell/AppShell.tsx +170 -2
  668. package/src/AspectRatio/AspectRatio.spec.md +179 -0
  669. package/src/AspectRatio/__tests__/AspectRatioFitLayers.a11y.browser.spec.ts +1 -0
  670. package/src/Avatar/Avatar.spec.md +253 -0
  671. package/src/Avatar/AvatarStatusDot.spec.md +93 -79
  672. package/src/Avatar/AvatarStatusDot.test.tsx +22 -0
  673. package/src/Avatar/AvatarStatusDot.tsx +2 -2
  674. package/src/AvatarGroup/AvatarGroup.spec.md +205 -0
  675. package/src/AvatarGroup/AvatarGroupOverflow.spec.md +123 -120
  676. package/src/Badge/Badge.spec.md +207 -0
  677. package/src/Badge/Badge.test.tsx +13 -0
  678. package/src/Badge/Badge.tsx +38 -2
  679. package/src/Banner/Banner.spec.md +41 -28
  680. package/src/Banner/Banner.test.tsx +118 -16
  681. package/src/Banner/Banner.tsx +94 -7
  682. package/src/Blockquote/Blockquote.spec.md +171 -0
  683. package/src/BottomSheet/BottomSheet.doc.mjs +106 -24
  684. package/src/BottomSheet/BottomSheet.spec.md +271 -40
  685. package/src/BottomSheet/BottomSheet.test.tsx +491 -5
  686. package/src/BottomSheet/BottomSheet.tsx +544 -145
  687. package/src/BottomSheet/BottomSheetHostContext.ts +44 -0
  688. package/src/BottomSheet/BottomSheetPanel.test.tsx +73 -19
  689. package/src/BottomSheet/BottomSheetPanel.tsx +178 -63
  690. package/src/BottomSheet/BottomSheetReplace.test.tsx +1638 -0
  691. package/src/BottomSheet/BottomSheetStacking.announce.test.tsx +246 -0
  692. package/src/BottomSheet/BottomSheetStacking.test.tsx +3184 -0
  693. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +27 -31
  694. package/src/BottomSheet/BottomSheetSwitcher.spec.md +138 -43
  695. package/src/BottomSheet/BottomSheetSwitcher.tsx +275 -26
  696. package/src/BottomSheet/BottomSheetSwitcherContext.ts +6 -0
  697. package/src/BottomSheet/__tests__/BottomSheetDrag.a11y.chromium.spec.ts +1 -0
  698. package/src/BottomSheet/__tests__/BottomSheetFocusReturn.a11y.browser.spec.ts +1 -0
  699. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +4 -1
  700. package/src/BottomSheet/__tests__/BottomSheetNativeModal.a11y.browser.spec.ts +1 -0
  701. package/src/BottomSheet/__tests__/BottomSheetPinchZoom.a11y.chromium.spec.ts +1 -0
  702. package/src/BottomSheet/__tests__/BottomSheetToastOutlet.a11y.chromium.spec.ts +83 -0
  703. package/src/BottomSheet/bottomSheetEscape.ts +21 -0
  704. package/src/BottomSheet/bottomSheetStack.ts +2054 -0
  705. package/src/BottomSheet/useSheetGestures.ts +68 -12
  706. package/src/Breadcrumbs/BreadcrumbItem.spec.md +104 -60
  707. package/src/Breadcrumbs/BreadcrumbItem.tsx +30 -1
  708. package/src/Breadcrumbs/Breadcrumbs.spec.md +165 -0
  709. package/src/Breadcrumbs/Breadcrumbs.test.tsx +90 -0
  710. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +1 -0
  711. package/src/Button/Button.spec.md +322 -0
  712. package/src/Button/Button.test.tsx +8 -1
  713. package/src/Button/Button.tsx +36 -7
  714. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +1 -0
  715. package/src/ButtonGroup/ButtonGroup.spec.md +220 -0
  716. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +1 -0
  717. package/src/Card/Card.spec.md +205 -0
  718. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +1 -0
  719. package/src/Center/Center.spec.md +104 -124
  720. package/src/Chat/ChatComposer.test.tsx +54 -0
  721. package/src/Chat/ChatComposer.tsx +41 -27
  722. package/src/Chat/ChatComposerInput.test.tsx +165 -21
  723. package/src/Chat/ChatComposerInput.tsx +73 -16
  724. package/src/Chat/ChatMessageMetadata.tsx +1 -1
  725. package/src/Chat/ChatPastedTextToken.test.tsx +71 -0
  726. package/src/Chat/ChatPastedTextToken.tsx +8 -7
  727. package/src/Chat/ChatToolCalls.tsx +5 -5
  728. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +22 -4
  729. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +1 -0
  730. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +1 -0
  731. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +1 -0
  732. package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1 -0
  733. package/src/Chat/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +1 -0
  734. package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +1 -0
  735. package/src/Chat/__tests__/useChatStreamScroll.a11y.chromium.spec.ts +1 -0
  736. package/src/CheckboxInput/CheckboxInput.spec.md +97 -66
  737. package/src/CheckboxInput/__tests__/Checkbox.a11y.chromium.spec.ts +1 -0
  738. package/src/CheckboxList/CheckboxList.spec.md +92 -78
  739. package/src/CheckboxList/CheckboxListItem.spec.md +86 -60
  740. package/src/CheckboxList/__tests__/CheckboxList.a11y.chromium.spec.ts +1 -0
  741. package/src/ClickableCard/ClickableCard.doc.mjs +1 -2
  742. package/src/ClickableCard/ClickableCard.spec.md +124 -128
  743. package/src/ClickableCard/ClickableCard.test.tsx +14 -3
  744. package/src/ClickableCard/ClickableCard.tsx +44 -28
  745. package/src/Code/Code.spec.md +30 -32
  746. package/src/CodeBlock/CodeBlock.doc.mjs +21 -4
  747. package/src/CodeBlock/CodeBlock.spec.md +96 -61
  748. package/src/CodeBlock/CodeBlock.test.tsx +97 -1
  749. package/src/CodeBlock/CodeBlock.tsx +132 -22
  750. package/src/CodeBlock/CodeLanguage.test.tsx +173 -0
  751. package/src/CodeBlock/__tests__/CodeBlockCopyClearance.a11y.chromium.spec.ts +290 -0
  752. package/src/CodeBlock/__tests__/CodeBlockLanguages.a11y.chromium.spec.ts +64 -0
  753. package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +1 -0
  754. package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +1 -0
  755. package/src/CodeBlock/grammar.ts +291 -0
  756. package/src/CodeBlock/index.ts +7 -0
  757. package/src/CodeBlock/languages/dockerfile.ts +43 -0
  758. package/src/CodeBlock/languages/graphql.ts +30 -0
  759. package/src/CodeBlock/languages/java.ts +28 -0
  760. package/src/CodeBlock/languages/lua.ts +21 -0
  761. package/src/CodeBlock/languages/objective-c.ts +26 -0
  762. package/src/CodeBlock/languages/powershell.ts +31 -0
  763. package/src/CodeBlock/languages/ruby.ts +29 -0
  764. package/src/CodeBlock/languages/thrift.ts +32 -0
  765. package/src/CodeBlock/languages/toml.ts +36 -0
  766. package/src/CodeBlock/languages.test.ts +402 -0
  767. package/src/CodeBlock/tokenizer.ts +176 -16
  768. package/src/CodeBlock/tokenizerBudget.test.ts +112 -0
  769. package/src/Collapsible/Collapsible.doc.mjs +6 -0
  770. package/src/Collapsible/Collapsible.spec.md +26 -23
  771. package/src/Collapsible/Collapsible.tsx +121 -2
  772. package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +1 -0
  773. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.chromium.spec.ts +1 -0
  774. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +1 -0
  775. package/src/CommandPalette/CommandPalette.perf.test.ts +8 -4
  776. package/src/CommandPalette/CommandPalette.tsx +17 -1
  777. package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +6 -3
  778. package/src/CommandPalette/CommandPaletteEmpty.spec.md +190 -0
  779. package/src/CommandPalette/CommandPaletteEmpty.tsx +4 -0
  780. package/src/CommandPalette/CommandPaletteInput.tsx +21 -2
  781. package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +1 -0
  782. package/src/CommandPalette/__tests__/CommandPaletteEmptyAudit.a11y.chromium.spec.ts +715 -0
  783. package/src/CommandPalette/__tests__/CommandPaletteFooter.a11y.chromium.spec.ts +3 -2
  784. package/src/CommandPalette/__tests__/CommandPaletteInputAudit.a11y.chromium.spec.ts +1 -0
  785. package/src/CommandPalette/__tests__/CommandPaletteItemAudit.a11y.chromium.spec.ts +1 -0
  786. package/src/CommandPalette/busyStartSettle.ts +26 -0
  787. package/src/ComplexSelector/ComplexSelector.doc.mjs +1 -1
  788. package/src/ComplexSelector/ComplexSelector.focusableDisabled.test.tsx +1 -1
  789. package/src/ComplexSelector/ComplexSelector.fr10.test.tsx +9 -9
  790. package/src/ComplexSelector/ComplexSelector.spec.md +161 -107
  791. package/src/ComplexSelector/ComplexSelector.test.tsx +236 -17
  792. package/src/ComplexSelector/ComplexSelector.tsx +69 -4
  793. package/src/ComplexSelector/__tests__/ComplexSelector.a11y.chromium.spec.ts +965 -0
  794. package/src/ContextMenu/ContextMenu.doc.mjs +1 -1
  795. package/src/ContextMenu/ContextMenu.spec.md +38 -30
  796. package/src/ContextMenu/ContextMenu.test.tsx +189 -11
  797. package/src/ContextMenu/ContextMenu.tsx +75 -17
  798. package/src/ContextMenu/__tests__/ContextMenuAudit.a11y.chromium.spec.ts +1 -0
  799. package/src/ContextMenu/__tests__/ContextMenuCursorAnchor.a11y.browser.spec.ts +1 -0
  800. package/src/ContextMenu/__tests__/ContextMenuLongPress.a11y.chromium.spec.ts +117 -0
  801. package/src/DateInput/DateInput.tsx +9 -4
  802. package/src/DateInput/DateInputTouch.test.tsx +10 -1
  803. package/src/DateInput/NativeDateField.tsx +2 -1
  804. package/src/DateInput/TouchDateField.tsx +2 -1
  805. package/src/DateInput/Wheel.tsx +4 -1
  806. package/src/DateInput/__tests__/DateInputAudit.a11y.chromium.spec.ts +1 -0
  807. package/src/DateInput/__tests__/WheelPinchZoom.a11y.chromium.spec.ts +171 -0
  808. package/src/Dialog/Dialog.doc.mjs +201 -47
  809. package/src/Dialog/Dialog.spec.md +20 -4
  810. package/src/Dialog/Dialog.tsx +37 -10
  811. package/src/Dialog/__tests__/Dialog.a11y.browser.spec.ts +1 -0
  812. package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +1 -0
  813. package/src/Dialog/__tests__/Dialog.reduced-motion.a11y.browser.spec.ts +252 -0
  814. package/src/Divider/Divider.spec.md +79 -70
  815. package/src/Drawer/Drawer.tsx +38 -35
  816. package/src/Drawer/__tests__/DrawerAudit.a11y.chromium.spec.ts +1 -0
  817. package/src/Drawer/__tests__/DrawerHeaderAudit.a11y.chromium.spec.ts +1 -0
  818. package/src/DropdownMenu/DropdownMenu.spec.md +14 -6
  819. package/src/DropdownMenu/DropdownMenu.ssr.test.tsx +44 -8
  820. package/src/DropdownMenu/DropdownMenu.test.tsx +107 -5
  821. package/src/DropdownMenu/DropdownMenu.tsx +51 -34
  822. package/src/DropdownMenu/DropdownMenuGroup.doc.mjs +2 -2
  823. package/src/DropdownMenu/DropdownMenuGroup.tsx +12 -6
  824. package/src/DropdownMenu/DropdownMenuItem.tsx +5 -5
  825. package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +5 -2
  826. package/src/DropdownMenu/DropdownMenuRadioItem.spec.md +226 -0
  827. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +32 -16
  828. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +158 -0
  829. package/src/DropdownMenu/DropdownMenuSheetFirstOpen.test.tsx +72 -0
  830. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +9 -0
  831. package/src/DropdownMenu/DropdownMenuSubMenu.spec.md +225 -0
  832. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +105 -0
  833. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +6 -6
  834. package/src/DropdownMenu/MenuBottomSheet.tsx +42 -7
  835. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +3 -3
  836. package/src/DropdownMenu/__tests__/DropdownMenuDividerAudit.a11y.chromium.spec.ts +1 -0
  837. package/src/DropdownMenu/__tests__/DropdownMenuDrillIn.a11y.chromium.spec.ts +1 -0
  838. package/src/DropdownMenu/__tests__/DropdownMenuFocusReturn.a11y.browser.spec.ts +1 -0
  839. package/src/DropdownMenu/__tests__/DropdownMenuGroupAudit.a11y.chromium.spec.ts +1 -0
  840. package/src/DropdownMenu/__tests__/DropdownMenuItemAudit.a11y.chromium.spec.ts +1 -0
  841. package/src/DropdownMenu/__tests__/DropdownMenuRadioGroupAudit.a11y.chromium.spec.ts +1 -0
  842. package/src/DropdownMenu/__tests__/DropdownMenuRadioItemAudit.a11y.chromium.spec.ts +540 -0
  843. package/src/DropdownMenu/__tests__/DropdownMenuSubMenuAudit.a11y.chromium.spec.ts +671 -0
  844. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +1 -0
  845. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +1 -0
  846. package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +1 -0
  847. package/src/DropdownMenu/__tests__/MenuHoverFocus.a11y.chromium.spec.ts +238 -0
  848. package/src/DropdownMenu/__tests__/MenuPinchZoom.a11y.chromium.spec.ts +1 -0
  849. package/src/DropdownMenu/__tests__/MenuPress.a11y.chromium.spec.ts +1 -0
  850. package/src/DropdownMenu/__tests__/SubMenuHeaderFooter.a11y.chromium.spec.ts +1 -0
  851. package/src/DropdownMenu/lazyMenuBottomSheet.ts +28 -2
  852. package/src/DropdownMenu/menuBottomSheet.stylex.ts +33 -0
  853. package/src/DropdownMenu/menuItemHover.ts +13 -1
  854. package/src/DropdownMenu/menuTouchAction.stylex.ts +28 -0
  855. package/src/DropdownMenu/modules/useMenuPress.spec.md +90 -62
  856. package/src/DropdownMenu/useMenuDrillIn.tsx +7 -5
  857. package/src/EmptyState/EmptyState.announce.test.tsx +227 -0
  858. package/src/EmptyState/EmptyState.doc.mjs +1 -1
  859. package/src/EmptyState/EmptyState.spec.md +22 -14
  860. package/src/EmptyState/EmptyState.test.tsx +8 -8
  861. package/src/EmptyState/EmptyState.tsx +7 -5
  862. package/src/Field/Field.spec.md +57 -48
  863. package/src/Field/Field.tsx +1 -1
  864. package/src/Field/FieldLabel.spec.md +70 -59
  865. package/src/Field/FieldLabel.tsx +1 -1
  866. package/src/Field/PanelSearchInput.tsx +23 -13
  867. package/src/Field/__tests__/FieldLabelAudit.a11y.chromium.spec.ts +1 -0
  868. package/src/Field/inputDisabledFocus.ts +28 -0
  869. package/src/Field/inputStyles.stylex.ts +15 -15
  870. package/src/FieldStatus/FieldStatus.test.tsx +12 -0
  871. package/src/FieldStatus/FieldStatus.tsx +12 -3
  872. package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +1 -0
  873. package/src/FileInput/FileInput.doc.mjs +1 -1
  874. package/src/FileInput/FileInput.test.tsx +102 -0
  875. package/src/FileInput/FileInput.tsx +18 -12
  876. package/src/FormLayout/FormLayout.spec.md +69 -51
  877. package/src/Grid/Grid.spec.md +72 -69
  878. package/src/Grid/GridSpan.spec.md +158 -0
  879. package/src/Heading/Heading.spec.md +198 -0
  880. package/src/HoverCard/HoverCard.spec.md +244 -0
  881. package/src/HoverCard/HoverCard.test.tsx +93 -3
  882. package/src/Icon/Icon.doc.mjs +67 -5
  883. package/src/Icon/Icon.test.tsx +548 -9
  884. package/src/Icon/Icon.tsx +79 -15
  885. package/src/Icon/IconSize.stylex.ts +27 -11
  886. package/src/Icon/globalIconRegistry.test.tsx +395 -3
  887. package/src/Icon/globalIconRegistry.tsx +184 -36
  888. package/src/Icon/index.ts +29 -1
  889. package/src/Icon/useIcon.ts +5 -1
  890. package/src/IconButton/IconButton.spec.md +197 -0
  891. package/src/IconButton/IconButton.test.tsx +5 -2
  892. package/src/InputGroup/InputGroup.spec.md +199 -0
  893. package/src/InputGroup/InputGroup.test.tsx +120 -0
  894. package/src/InputGroup/InputGroup.tsx +59 -52
  895. package/src/InputGroup/InputGroupInternalContext.ts +15 -0
  896. package/src/InputGroup/InputGroupText.spec.md +139 -0
  897. package/src/InputGroup/InputGroupText.tsx +2 -0
  898. package/src/InputGroup/groupStyles.ts +22 -11
  899. package/src/Item/Item.test.tsx +158 -1
  900. package/src/Item/Item.tsx +42 -7
  901. package/src/Item/ItemMarkerColumns.a11y.chromium.spec.ts +211 -0
  902. package/src/Item/ItemMarkerColumnsContext.tsx +20 -0
  903. package/src/Item/ItemSwipeLayer.tsx +9 -0
  904. package/src/Item/__tests__/ItemSwipeActions.a11y.chromium.spec.ts +1 -0
  905. package/src/Item/__tests__/ItemSwipePinchZoom.a11y.chromium.spec.ts +186 -0
  906. package/src/Item/useSwipeAction.ts +71 -5
  907. package/src/Kbd/Kbd.test.tsx +95 -0
  908. package/src/Kbd/Kbd.tsx +30 -23
  909. package/src/Layer/LayerProvider.spec.md +149 -0
  910. package/src/Layer/__tests__/LayerReducedMotion.a11y.chromium.spec.ts +176 -0
  911. package/src/Layer/__tests__/TouchTrigger.a11y.chromium.spec.ts +200 -0
  912. package/src/Layer/layerAnimations.stylex.ts +22 -2
  913. package/src/Layer/layerDismissalInvariants.test.tsx +9 -0
  914. package/src/Layer/layerSlideRules.ts +141 -8
  915. package/src/Layer/layerStack.ts +129 -62
  916. package/src/Layer/modalOutlet.ts +156 -15
  917. package/src/Layer/preserveAnimations.ts +304 -0
  918. package/src/Layer/useLayer.doc.mjs +1 -1
  919. package/src/Layer/useLayer.test.tsx +850 -0
  920. package/src/Layer/useLayer.tsx +644 -58
  921. package/src/Layer/useLayerDismissal.test.tsx +85 -2
  922. package/src/Layer/useLayerDismissal.ts +12 -9
  923. package/src/Layer/useTouchTrigger.ts +95 -41
  924. package/src/Layout/Layout.tsx +18 -0
  925. package/src/Layout/LayoutContent.tsx +5 -14
  926. package/src/Layout/LayoutFooter.tsx +2 -0
  927. package/src/Layout/LayoutHeader.tsx +2 -0
  928. package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +1 -0
  929. package/src/Layout/layoutEdges.stylex.ts +25 -0
  930. package/src/Lightbox/Lightbox.spec.md +9 -8
  931. package/src/Lightbox/Lightbox.test.tsx +83 -0
  932. package/src/Lightbox/Lightbox.tsx +149 -125
  933. package/src/Lightbox/LightboxKeyboard.a11y.browser.spec.ts +78 -0
  934. package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +70 -0
  935. package/src/Link/Link.spec.md +229 -0
  936. package/src/Link/LinkProvider.spec.md +167 -0
  937. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +1 -0
  938. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +1 -0
  939. package/src/List/List.spec.md +113 -34
  940. package/src/List/List.tsx +13 -1
  941. package/src/List/ListContext.tsx +19 -5
  942. package/src/List/ListItem.doc.mjs +3 -3
  943. package/src/List/ListItem.tsx +97 -28
  944. package/src/List/ListMarkers.a11y.chromium.spec.ts +904 -0
  945. package/src/Markdown/Markdown.codeLanguages.test.tsx +137 -0
  946. package/src/Markdown/Markdown.doc.mjs +12 -0
  947. package/src/Markdown/Markdown.fr23.bench.ts +3 -1
  948. package/src/Markdown/Markdown.fr23.perf.test.ts +45 -3
  949. package/src/Markdown/Markdown.fr23.sampling.ts +13 -4
  950. package/src/Markdown/Markdown.spec.md +71 -59
  951. package/src/Markdown/Markdown.test.tsx +50 -0
  952. package/src/Markdown/Markdown.tsx +61 -8
  953. package/src/Markdown/MarkdownTable.a11y.chromium.spec.ts +1 -0
  954. package/src/Markdown/__tests__/MarkdownNesting.a11y.chromium.spec.ts +1 -0
  955. package/src/MobileNav/MobileNav.doc.mjs +2 -2
  956. package/src/MobileNav/MobileNav.spec.md +161 -64
  957. package/src/MobileNav/MobileNav.test.tsx +27 -10
  958. package/src/MobileNav/MobileNav.tsx +51 -38
  959. package/src/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.ts +1 -0
  960. package/src/MobileNav/MobileNavToggle.test.tsx +63 -0
  961. package/src/MobileNav/MobileNavToggle.tsx +13 -5
  962. package/src/MobileNav/__tests__/MobileNavWidth.a11y.chromium.spec.ts +103 -0
  963. package/src/MoreMenu/MoreMenu.doc.mjs +2 -2
  964. package/src/MoreMenu/MoreMenu.spec.md +88 -53
  965. package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +67 -9
  966. package/src/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.ts +1 -0
  967. package/src/MultiSelector/MultiSelector.test.tsx +122 -10
  968. package/src/MultiSelector/MultiSelector.tsx +24 -4
  969. package/src/MultiSelector/OptionActions.a11y.chromium.spec.ts +1 -0
  970. package/src/MultiSelector/__tests__/MultiSelector.a11y.chromium.spec.ts +1 -0
  971. package/src/NavIcon/NavIcon.spec.md +66 -38
  972. package/src/NavMenu/NavHeadingMenu.spec.md +104 -46
  973. package/src/NavMenu/NavHeadingMenu.test.tsx +276 -2
  974. package/src/NavMenu/NavHeadingMenu.tsx +42 -4
  975. package/src/NavMenu/NavHeadingMenuItem.tsx +60 -6
  976. package/src/NavMenu/NavMenuContext.tsx +11 -0
  977. package/src/NavMenu/__tests__/NavMenusSlideSelection.a11y.chromium.spec.ts +137 -0
  978. package/src/NumberInput/NumberInput.doc.mjs +6 -6
  979. package/src/NumberInput/NumberInput.spec.md +248 -0
  980. package/src/NumberInput/NumberInput.test.tsx +187 -14
  981. package/src/NumberInput/NumberInput.tsx +86 -24
  982. package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +1 -0
  983. package/src/Overlay/Overlay.doc.mjs +2 -2
  984. package/src/Overlay/Overlay.test.tsx +72 -4
  985. package/src/Overlay/Overlay.tsx +18 -8
  986. package/src/Pagination/Pagination.test.tsx +2 -2
  987. package/src/Popover/Popover.doc.mjs +38 -2
  988. package/src/Popover/Popover.spec.md +90 -11
  989. package/src/Popover/Popover.test.tsx +340 -2
  990. package/src/Popover/Popover.tsx +401 -35
  991. package/src/Popover/PopoverPresentation.test.tsx +952 -0
  992. package/src/Popover/__tests__/PopoverSecondDocument.a11y.chromium.spec.ts +205 -0
  993. package/src/Popover/index.ts +5 -1
  994. package/src/Popover/lazyPopoverBottomSheet.ts +57 -0
  995. package/src/Popover/usePopover.tsx +11 -5
  996. package/src/PowerSearch/PowerSearch.spec.md +423 -53
  997. package/src/PowerSearch/PowerSearch.test.tsx +77 -1
  998. package/src/PowerSearch/PowerSearch.tsx +7 -5
  999. package/src/ProgressBar/ProgressBar.test.tsx +12 -0
  1000. package/src/ProgressBar/ProgressBar.tsx +18 -0
  1001. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +1 -0
  1002. package/src/RadioList/RadioList.spec.md +227 -0
  1003. package/src/RadioList/RadioList.test.tsx +34 -7
  1004. package/src/RadioList/RadioListItem.press.source-build.test.mjs +80 -0
  1005. package/src/RadioList/RadioListItem.spec.md +223 -0
  1006. package/src/RadioList/RadioListItem.tsx +26 -12
  1007. package/src/RadioList/__tests__/RadioGroup.a11y.chromium.spec.ts +1 -0
  1008. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +1 -0
  1009. package/src/ScrollableArea/ScrollableArea.spec.md +6 -5
  1010. package/src/ScrollableArea/ScrollableArea.test.tsx +5 -0
  1011. package/src/ScrollableArea/ScrollableArea.tsx +4 -0
  1012. package/src/Section/Section.spec.md +102 -44
  1013. package/src/SegmentedControl/SegmentedControl.spec.md +162 -53
  1014. package/src/SegmentedControl/SegmentedControl.test.tsx +46 -0
  1015. package/src/SegmentedControl/SegmentedControl.tsx +7 -3
  1016. package/src/SegmentedControl/SegmentedControlItem.spec.md +206 -0
  1017. package/src/SelectableCard/SelectableCard.doc.mjs +7 -6
  1018. package/src/SelectableCard/SelectableCard.spec.md +230 -0
  1019. package/src/SelectableCard/SelectableCard.test.tsx +11 -1
  1020. package/src/SelectableCard/SelectableCard.tsx +49 -33
  1021. package/src/Selector/Selector.sheetActiveDescendant.test.tsx +95 -0
  1022. package/src/Selector/Selector.spec.md +12 -4
  1023. package/src/Selector/Selector.test.tsx +114 -8
  1024. package/src/Selector/Selector.tsx +30 -6
  1025. package/src/Selector/__tests__/ComboboxField.a11y.chromium.spec.ts +458 -0
  1026. package/src/Selector/__tests__/EmptyStateAnnouncement.a11y.chromium.spec.ts +1 -0
  1027. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +1 -0
  1028. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +1 -0
  1029. package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +1 -0
  1030. package/src/Selector/hooks.ts +234 -10
  1031. package/src/Selector/useCombobox.doc.mjs +156 -9
  1032. package/src/Selector/useCombobox.public.test.tsx +89 -0
  1033. package/src/Selector/useCombobox.test.tsx +444 -0
  1034. package/src/SideNav/SideNav.spec.md +50 -30
  1035. package/src/SideNav/SideNav.test.tsx +425 -25
  1036. package/src/SideNav/SideNav.tsx +85 -1
  1037. package/src/SideNav/SideNavCollapseButton.spec.md +161 -0
  1038. package/src/SideNav/SideNavHeading.spec.md +226 -0
  1039. package/src/SideNav/SideNavHeading.tsx +102 -6
  1040. package/src/SideNav/SideNavItem.spec.md +246 -0
  1041. package/src/SideNav/SideNavItem.tsx +40 -9
  1042. package/src/SideNav/SideNavRailMotion.test.tsx +620 -0
  1043. package/src/SideNav/SideNavSection.spec.md +153 -0
  1044. package/src/SideNav/__tests__/SideNavRailMotion.interaction.browser.spec.ts +417 -0
  1045. package/src/SideNav/railMotion.ts +315 -0
  1046. package/src/Skeleton/Skeleton.spec.md +99 -42
  1047. package/src/Skeleton/Skeleton.test.tsx +108 -1
  1048. package/src/Skeleton/Skeleton.tsx +30 -2
  1049. package/src/Slider/Slider.fr10.test.tsx +34 -0
  1050. package/src/Slider/Slider.test.tsx +172 -0
  1051. package/src/Slider/Slider.tsx +70 -14
  1052. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +1 -0
  1053. package/src/Spinner/Spinner.spec.md +231 -0
  1054. package/src/Stack/Stack.spec.md +104 -56
  1055. package/src/StatusDot/StatusDot.spec.md +139 -51
  1056. package/src/StatusDot/StatusDot.test.tsx +13 -0
  1057. package/src/StatusDot/StatusDot.tsx +27 -0
  1058. package/src/Stepper/Step.spec.md +206 -0
  1059. package/src/Stepper/Step.tsx +19 -3
  1060. package/src/Stepper/Stepper.test.tsx +50 -0
  1061. package/src/Switch/Switch.focusRing.source-build.test.mjs +81 -0
  1062. package/src/Switch/Switch.spec.md +150 -66
  1063. package/src/Switch/Switch.tsx +11 -9
  1064. package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +1 -0
  1065. package/src/Switch/switch.markers.stylex.ts +7 -2
  1066. package/src/TabList/Tab.spec.md +201 -0
  1067. package/src/TabList/Tab.tsx +7 -1
  1068. package/src/TabList/TabList.doc.mjs +3 -3
  1069. package/src/TabList/TabList.test.tsx +27 -0
  1070. package/src/TabList/TabMenu.spec.md +198 -0
  1071. package/src/TabList/TabMenu.tsx +24 -1
  1072. package/src/TabList/__tests__/TabListOverflow.interaction.browser.spec.ts +99 -0
  1073. package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +1 -0
  1074. package/src/Table/Table.spec.md +54 -30
  1075. package/src/Table/TableCell.tsx +9 -0
  1076. package/src/Table/TableHeaderCell.tsx +2 -0
  1077. package/src/Table/TableRow.tsx +3 -0
  1078. package/src/Table/__tests__/Table.a11y.chromium.spec.ts +129 -0
  1079. package/src/Table/__tests__/Table.a11y.contracts.ts +35 -0
  1080. package/src/Table/__tests__/Table.a11y.renders.tsx +112 -0
  1081. package/src/Table/__tests__/Table.a11y.states.ts +140 -0
  1082. package/src/Table/__tests__/Table.a11y.test.tsx +198 -0
  1083. package/src/Table/__tests__/TableMinWidth.a11y.chromium.spec.ts +1 -0
  1084. package/src/Table/__tests__/TableRowGlide.a11y.browser.spec.ts +382 -0
  1085. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +1 -0
  1086. package/src/Table/__tests__/TableStickyDividers.a11y.browser.spec.ts +560 -0
  1087. package/src/Table/glidingDivider.ts +336 -0
  1088. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +23 -8
  1089. package/src/Table/plugins/rowExpansion/useTableRowExpansion.glide.test.tsx +280 -0
  1090. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +91 -9
  1091. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +471 -10
  1092. package/src/Table/plugins/rowStatus/useTableRowStatus.spec.md +4 -4
  1093. package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.test.tsx +174 -0
  1094. package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.ts +86 -0
  1095. package/src/Table/plugins/sortable/useTableSortable.test.tsx +0 -12
  1096. package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +51 -1
  1097. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +312 -12
  1098. package/src/Table/rowDivider.ts +154 -0
  1099. package/src/Table/useTableRowExpansion.doc.mjs +8 -0
  1100. package/src/Text/Text.spec.md +114 -127
  1101. package/src/TextArea/TextArea.doc.mjs +6 -6
  1102. package/src/TextArea/TextArea.spec.md +164 -64
  1103. package/src/TextArea/TextArea.test.tsx +65 -6
  1104. package/src/TextArea/TextArea.tsx +27 -15
  1105. package/src/TextInput/TextInput.doc.mjs +8 -8
  1106. package/src/TextInput/TextInput.spec.md +260 -0
  1107. package/src/TextInput/TextInput.test.tsx +126 -10
  1108. package/src/TextInput/TextInput.tsx +57 -23
  1109. package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +1 -0
  1110. package/src/Thumbnail/Thumbnail.doc.mjs +1 -2
  1111. package/src/Thumbnail/Thumbnail.spec.md +244 -0
  1112. package/src/Thumbnail/Thumbnail.test.tsx +120 -7
  1113. package/src/Thumbnail/Thumbnail.tsx +77 -31
  1114. package/src/TimeInput/TimeInput.spec.md +273 -0
  1115. package/src/TimeInput/TimeInput.tsx +12 -4
  1116. package/src/TimeInput/TouchTimeField.tsx +2 -1
  1117. package/src/Timestamp/Timestamp.spec.md +252 -0
  1118. package/src/Toast/Toast.spec.md +300 -0
  1119. package/src/Toast/ToastViewport.modalHost.test.tsx +630 -5
  1120. package/src/Toast/ToastViewport.test.tsx +137 -0
  1121. package/src/Toast/ToastViewport.tsx +63 -6
  1122. package/src/ToggleButton/ToggleButton.spec.md +256 -0
  1123. package/src/ToggleButton/ToggleButtonGroup.spec.md +195 -0
  1124. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +1 -0
  1125. package/src/Token/Token.spec.md +271 -0
  1126. package/src/Token/__tests__/TokenRemoveTarget.a11y.chromium.spec.ts +1 -0
  1127. package/src/Tokenizer/Tokenizer.props-type.test.tsx +126 -0
  1128. package/src/Tokenizer/Tokenizer.spec.md +313 -72
  1129. package/src/Tokenizer/Tokenizer.ssr.test.tsx +196 -0
  1130. package/src/Tokenizer/Tokenizer.test.tsx +44 -8
  1131. package/src/Tokenizer/Tokenizer.tsx +586 -41
  1132. package/src/Tokenizer/TokenizerBottomSheet.test.tsx +2719 -0
  1133. package/src/Tokenizer/TokenizerBottomSheet.tsx +957 -0
  1134. package/src/Tokenizer/__tests__/TokenizerEndLane.a11y.chromium.spec.ts +61 -27
  1135. package/src/Toolbar/Toolbar.spec.md +103 -49
  1136. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +1 -0
  1137. package/src/Tooltip/Tooltip.spec.md +161 -36
  1138. package/src/Tooltip/Tooltip.test.tsx +171 -3
  1139. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +1 -0
  1140. package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +2 -2
  1141. package/src/Tooltip/__tests__/TooltipFocusReturn.a11y.chromium.spec.ts +1 -0
  1142. package/src/Tooltip/__tests__/TooltipHoverBridge.a11y.chromium.spec.ts +1 -0
  1143. package/src/Tooltip/__tests__/TooltipTallContent.a11y.browser.spec.ts +673 -0
  1144. package/src/Tooltip/__tests__/TooltipTallContentTracking.a11y.browser.spec.ts +1162 -0
  1145. package/src/Tooltip/useTooltip.tsx +7 -2
  1146. package/src/TopNav/TopNav.spec.md +190 -0
  1147. package/src/TopNav/TopNav.test.tsx +89 -0
  1148. package/src/TopNav/TopNavHeading.spec.md +211 -0
  1149. package/src/TopNav/TopNavHeading.tsx +35 -2
  1150. package/src/TopNav/TopNavItem.spec.md +189 -0
  1151. package/src/TopNav/TopNavMegaMenu.reduced-motion.source-build.test.mjs +83 -0
  1152. package/src/TopNav/TopNavMegaMenu.spec.md +190 -0
  1153. package/src/TopNav/TopNavMegaMenu.tsx +21 -4
  1154. package/src/TopNav/TopNavMegaMenuFeaturedCard.spec.md +150 -0
  1155. package/src/TopNav/TopNavMegaMenuItem.spec.md +155 -0
  1156. package/src/TopNav/TopNavMenu.spec.md +202 -0
  1157. package/src/TopNav/TopNavMenu.test.tsx +65 -1
  1158. package/src/TopNav/TopNavMenu.tsx +30 -1
  1159. package/src/TopNav/__tests__/TopNavMobileLongHeading.a11y.chromium.spec.ts +1 -0
  1160. package/src/TreeList/TreeList.doc.mjs +13 -0
  1161. package/src/TreeList/TreeList.spec.md +54 -35
  1162. package/src/TreeList/TreeList.tsx +234 -2
  1163. package/src/TreeList/TreeListBranches.tsx +8 -6
  1164. package/src/TreeList/TreeListItem.tsx +12 -6
  1165. package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +19 -6
  1166. package/src/TreeList/__tests__/TreeListGuideAlignment.interaction.browser.spec.ts +127 -0
  1167. package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +1 -0
  1168. package/src/Typeahead/BaseTypeahead.emptyState.a11y.chromium.spec.ts +138 -0
  1169. package/src/Typeahead/BaseTypeahead.test.tsx +201 -4
  1170. package/src/Typeahead/BaseTypeahead.tsx +26 -10
  1171. package/src/Typeahead/Typeahead.test.tsx +114 -1
  1172. package/src/Typeahead/Typeahead.tsx +34 -16
  1173. package/src/VisuallyHidden/VisuallyHidden.spec.md +170 -0
  1174. package/src/__tests__/BusyOwnerAnnouncement.test.tsx +66 -5
  1175. package/src/__tests__/CardPress.a11y.chromium.spec.ts +353 -0
  1176. package/src/__tests__/DisabledTriggerFocus.a11y.chromium.spec.ts +2 -1
  1177. package/src/__tests__/PressModality.a11y.chromium.spec.ts +392 -0
  1178. package/src/__tests__/PressedState.a11y.chromium.spec.ts +1 -0
  1179. package/src/__tests__/pressState.ts +43 -1
  1180. package/src/__tests__/unthemedLength.ts +34 -0
  1181. package/src/gestures/GestureArena.ts +966 -0
  1182. package/src/gestures/GestureRecognizer.ts +626 -0
  1183. package/src/gestures/LongPressGestureRecognizer.ts +186 -0
  1184. package/src/gestures/PanGestureRecognizer.ts +410 -0
  1185. package/src/gestures/TapGestureRecognizer.ts +192 -0
  1186. package/src/gestures/VelocityTracker.ts +194 -0
  1187. package/src/gestures/__tests__/LongPressGestureRecognizer.test.ts +141 -0
  1188. package/src/gestures/__tests__/PanGestureRecognizer.test.ts +327 -0
  1189. package/src/gestures/__tests__/TapGestureRecognizer.test.ts +154 -0
  1190. package/src/gestures/__tests__/VelocityTracker.streams.test.ts +243 -0
  1191. package/src/gestures/__tests__/VelocityTracker.test.ts +261 -0
  1192. package/src/gestures/__tests__/arena.test.ts +824 -0
  1193. package/src/gestures/__tests__/arenaContinuous.test.ts +207 -0
  1194. package/src/gestures/__tests__/arenaTapLongPress.test.ts +211 -0
  1195. package/src/gestures/__tests__/fixtures/pointer-streams/README.md +82 -0
  1196. package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-fling.json +130 -0
  1197. package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-slow.json +860 -0
  1198. package/src/gestures/__tests__/fixtures/pointer-streams/android-chromium-stop-release.json +357 -0
  1199. package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-fling.json +66 -0
  1200. package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-slow.json +268 -0
  1201. package/src/gestures/__tests__/fixtures/pointer-streams/android-firefox-stop-release.json +128 -0
  1202. package/src/gestures/__tests__/fixtures/pointer-streams/capture.html +123 -0
  1203. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-fling.json +64 -0
  1204. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-slow.json +268 -0
  1205. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-mouse-stop-release.json +124 -0
  1206. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-fling.json +64 -0
  1207. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-slow.json +268 -0
  1208. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-pen-stop-release.json +124 -0
  1209. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-fling.json +84 -0
  1210. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-slow.json +381 -0
  1211. package/src/gestures/__tests__/fixtures/pointer-streams/desktop-chromium-touch-stop-release.json +171 -0
  1212. package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-fling.json +45 -0
  1213. package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-slow.json +101 -0
  1214. package/src/gestures/__tests__/fixtures/pointer-streams/ios-safari-stop-release.json +130 -0
  1215. package/src/gestures/__tests__/harness.ts +204 -0
  1216. package/src/gestures/geometry.ts +55 -0
  1217. package/src/gestures/types.ts +161 -0
  1218. package/src/hooks/AnnounceRenderedText.tsx +27 -0
  1219. package/src/hooks/ModalAnnounceProvider.tsx +155 -0
  1220. package/src/hooks/__tests__/MenuPressShadowRoot.a11y.chromium.spec.ts +98 -4
  1221. package/src/hooks/__tests__/menuLinkClicks.ts +71 -0
  1222. package/src/hooks/actionGroupTracker.exports.test.ts +28 -0
  1223. package/src/hooks/actionGroupTracker.test.ts +510 -0
  1224. package/src/hooks/actionGroupTracker.ts +449 -0
  1225. package/src/hooks/index.ts +6 -0
  1226. package/src/hooks/menuPressOnItems.ts +40 -0
  1227. package/src/hooks/modalAnnounce.ts +439 -0
  1228. package/src/hooks/scrollGeometry.ts +71 -4
  1229. package/src/hooks/useAdaptivePresentation.ts +46 -9
  1230. package/src/hooks/useAnimatedLayout.doc.mjs +101 -0
  1231. package/src/hooks/useAnimatedLayout.ts +61 -0
  1232. package/src/hooks/useAnnounce.doc.mjs +4 -4
  1233. package/src/hooks/useAnnounce.modal.test.tsx +1291 -0
  1234. package/src/hooks/useAnnounce.test.tsx +64 -4
  1235. package/src/hooks/useAnnounce.ts +452 -28
  1236. package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +226 -0
  1237. package/src/hooks/useAnnounceRenderedText.ts +81 -11
  1238. package/src/hooks/useBusyAnnouncement.adopters.test.tsx +69 -0
  1239. package/src/hooks/useBusyAnnouncement.test.tsx +112 -0
  1240. package/src/hooks/useBusyAnnouncement.ts +64 -54
  1241. package/src/hooks/useFocusTrap.doc.mjs +3 -3
  1242. package/src/hooks/useFocusTrap.test.tsx +135 -2
  1243. package/src/hooks/useFocusTrap.ts +59 -27
  1244. package/src/hooks/useMenuHover.ts +6 -2
  1245. package/src/hooks/useMenuPress.doc.mjs +2 -2
  1246. package/src/hooks/useMenuPress.test.tsx +5 -2
  1247. package/src/hooks/useMenuPress.ts +72 -37
  1248. package/src/hooks/usePressFeedback.doc.mjs +4 -4
  1249. package/src/hooks/usePressFeedback.ts +5 -2
  1250. package/src/hooks/useScrollableArea.test.tsx +344 -3
  1251. package/src/hooks/useScrollableArea.ts +120 -12
  1252. package/src/i18n/generated-locales/en.generated.ts +35 -0
  1253. package/src/i18n/generated-locales/pseudo.generated.ts +37 -0
  1254. package/src/internal/tokenizer-presentation.test.ts +29 -0
  1255. package/src/internal/tokenizer-presentation.ts +25 -0
  1256. package/src/internal/touch.test.ts +44 -0
  1257. package/src/internal/touch.ts +41 -0
  1258. package/src/motion/LayoutChangeSnapshot.tsx +50 -0
  1259. package/src/motion/MEASUREMENTS.md +271 -0
  1260. package/src/motion/README.md +218 -0
  1261. package/src/motion/__tests__/animatedLayout.interaction.browser.spec.ts +1613 -0
  1262. package/src/motion/__tests__/animatedLayoutAdopters.interaction.browser.spec.ts +217 -0
  1263. package/src/motion/__tests__/animatedLayoutBundle.ts +17 -0
  1264. package/src/motion/animatedLayout.boundary.test.ts +155 -0
  1265. package/src/motion/animatedLayout.swap.test.ts +827 -0
  1266. package/src/motion/animatedLayout.test.ts +1154 -0
  1267. package/src/motion/animatedLayout.ts +1801 -0
  1268. package/src/motion/animatedLayoutAdopters.test.tsx +500 -0
  1269. package/src/motion/animator.test.ts +2653 -0
  1270. package/src/motion/animator.ts +2794 -0
  1271. package/src/motion/bezier.test.ts +52 -0
  1272. package/src/motion/bezier.ts +64 -0
  1273. package/src/motion/coast.test.ts +99 -0
  1274. package/src/motion/coast.ts +150 -0
  1275. package/src/motion/decay.test.ts +120 -0
  1276. package/src/motion/decay.ts +126 -0
  1277. package/src/motion/projection.test.ts +107 -0
  1278. package/src/motion/projection.ts +116 -0
  1279. package/src/motion/reducedMotion.stylex.ts +41 -0
  1280. package/src/motion/reducedMotion.test.ts +129 -0
  1281. package/src/motion/reducedMotion.ts +94 -0
  1282. package/src/motion/reducedMotionPlan.test.ts +182 -0
  1283. package/src/motion/reducedMotionPlan.ts +263 -0
  1284. package/src/motion/resolveSnapPoint.test.ts +189 -0
  1285. package/src/motion/resolveSnapPoint.ts +169 -0
  1286. package/src/motion/roleValue.ts +105 -0
  1287. package/src/motion/roles.test.ts +256 -0
  1288. package/src/motion/roles.ts +262 -0
  1289. package/src/motion/rubberBand.test.ts +88 -0
  1290. package/src/motion/rubberBand.ts +115 -0
  1291. package/src/motion/selectPage.test.ts +31 -0
  1292. package/src/motion/selectPage.ts +55 -0
  1293. package/src/motion/spring.test.ts +650 -0
  1294. package/src/motion/spring.ts +551 -0
  1295. package/src/motion/transientCopy.ts +374 -0
  1296. package/src/motion/uikit/gestures.test.ts +89 -0
  1297. package/src/motion/uikit/gestures.ts +359 -0
  1298. package/src/motion/uikit/index.ts +80 -0
  1299. package/src/motion/uikit/navigation.ts +83 -0
  1300. package/src/motion/uikit/scroll.ts +141 -0
  1301. package/src/motion/uikit/springRows.test.ts +71 -0
  1302. package/src/motion/uikit/springs.ts +514 -0
  1303. package/src/motion/uikit/timing.ts +210 -0
  1304. package/src/motion/uikit/uikit.test.ts +364 -0
  1305. package/src/motion/uikit/values.test.ts +110 -0
  1306. package/src/reset.a11y.chromium.spec.ts +1 -0
  1307. package/src/reset.until-found.a11y.browser.spec.ts +1 -0
  1308. package/src/serverSafeComponents.test.ts +10 -0
  1309. package/src/tailwind-theme.css +51 -1
  1310. package/src/tailwind-theme.test.ts +51 -0
  1311. package/src/theme/Theme.test.tsx +28 -0
  1312. package/src/theme/__tests__/SpacingRootFontSize.a11y.chromium.spec.ts +1 -0
  1313. package/src/theme/declarationBoundary.ts +282 -1
  1314. package/src/theme/defineTheme.test.ts +529 -12
  1315. package/src/theme/defineTheme.ts +231 -19
  1316. package/src/theme/derivedVarRegistry.test.ts +34 -5
  1317. package/src/theme/derivedVarRegistry.ts +4 -0
  1318. package/src/theme/expandMotionScale.test.ts +17 -0
  1319. package/src/theme/extensibleAxes.test.ts +74 -29
  1320. package/src/theme/generateThemeRules.ts +772 -35
  1321. package/src/theme/index.ts +3 -0
  1322. package/src/theme/onMediaTokens.test.ts +186 -0
  1323. package/src/theme/statusColor.ts +189 -0
  1324. package/src/theme/statusRoleDerivation.ts +289 -0
  1325. package/src/theme/syntax/SyntaxTheme.tsx +1 -1
  1326. package/src/theme/syntax/defineSyntaxTheme.ts +1 -1
  1327. package/src/theme/syntax/presets.ts +1 -1
  1328. package/src/theme/syntax/tokens.ts +1 -1
  1329. package/src/theme/themeAdaptations.test.ts +412 -0
  1330. package/src/theme/themeAdaptations.ts +43 -1
  1331. package/src/theme/tokens.stylex.ts +36 -2
  1332. package/src/theme/tokens.test.ts +111 -1
  1333. package/src/theme/tokens.ts +23 -1
  1334. package/src/theme/useTheme.ts +10 -4
  1335. package/src/utils/customPropertyArmLayering.test.ts +131 -0
  1336. package/src/utils/edgeAutoscroll.test.ts +192 -0
  1337. package/src/utils/edgeAutoscroll.ts +111 -0
  1338. package/src/utils/hitArea.test.ts +628 -0
  1339. package/src/utils/hitArea.ts +770 -0
  1340. package/src/utils/interactionOverlay.stylex.ts +4 -1
  1341. package/src/utils/pressFeedback.test.ts +310 -2
  1342. package/src/utils/pressFeedback.ts +306 -54
  1343. package/src/utils/pressGesture.test.ts +50 -0
  1344. package/src/utils/pressGesture.ts +40 -2
  1345. package/src/utils/touchPresentation.test.ts +323 -0
  1346. package/src/utils/touchPresentation.ts +153 -0
@@ -0,0 +1,2203 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ /**
4
+ * @file animator.ts
5
+ * @input An element, target values, and a spring, momentum curves (coast.ts)
6
+ * or any closed-form curve
7
+ * @output Exports `createAnimator`: a compositor animator for translate,
8
+ * rotate, scale and opacity, with presentation values and velocities read
9
+ * from the analytic curves, velocity-preserving retargeting, freeze-in-place
10
+ * `stop`, completion promises, a shared clock, and UIKit's Reduced Motion
11
+ * substitution; plus its option, handle and transition types
12
+ * @position Motion foundation (DOM). Internal to core: components use it for
13
+ * every touch-presentation animation; not exported from the package entry
14
+ *
15
+ * HOW IT RUNS
16
+ *
17
+ * Each animated value (x, y, rotate, scaleX, scaleY, opacity) follows a
18
+ * closed-form curve: a spring (spring.ts), momentum curves its caller built (a
19
+ * UIScrollView coast with an edge bounce, coast.ts), a curve handed to `play` (a spring chasing a moving
20
+ * target, a fitted UIKit curve), or a Reduced Motion cross-fade. The curves are baked into
21
+ * Web Animations keyframes on the individual transform properties (`translate`,
22
+ * `rotate`, `scale`) and `opacity`, sampled adaptively until linear
23
+ * interpolation between keyframes is within a fraction of a pixel, and played
24
+ * with `easing: linear`. The browser then runs them on its compositor: they
25
+ * keep advancing every frame while JavaScript is busy (`spec:AST-094` FR5).
26
+ *
27
+ * Why keyframes and not one `linear()` easing: measured in Chromium, both
28
+ * forms are composited and equally precise for the same samples, but WebKit's
29
+ * Core Animation path refuses to accelerate an effect whose easing is
30
+ * `linear()` with points (KeyframeEffect::canBeAccelerated) unless its newer
31
+ * threaded animations are on, so on older iOS Safari a `linear()` spring would
32
+ * run on the main thread. Linear segments between keyframes map directly onto
33
+ * a Core Animation keyframe animation. Why the individual properties and not
34
+ * `transform`: each can be animated, retargeted or driven by a finger on its
35
+ * own (a drag writes `translate` while `scale` keeps springing), with no
36
+ * additive composition, which neither engine composites.
37
+ *
38
+ * The page never reads the DOM to know where something is: `get` and
39
+ * `getVelocity` evaluate the curves at a time on the document timeline's
40
+ * clock (`performance.now()` by default), so a finger can grab anything
41
+ * mid-flight from the value on screen, and a new target starts from the
42
+ * current value with the current velocity (`spec:AST-094` FR6). A gesture's release velocity
43
+ * can be handed in explicitly instead.
44
+ *
45
+ * End state without a flicker frame: the element's inline style always holds
46
+ * the values the animations END on, and the keyframes hold that end state for
47
+ * a while after the curve ends (END_HOLD_MS). The main thread drops a finished
48
+ * animation as soon as it runs after the curve's end; the inline style already
49
+ * shows the same values, so nothing moves. The hold matters when the curve
50
+ * ends during a main-thread block: WebKit's compositor ends an animation by
51
+ * falling back to the value its main thread last committed, which is
52
+ * mid-flight.
53
+ *
54
+ * Start time: a call that starts from rest (nothing on its channels moving,
55
+ * no `options.at`) gets no start time, so the browser starts it when it
56
+ * commits it, as Core Animation starts an animation at its transaction's
57
+ * commit: a main-thread block before that frame delays the motion instead of
58
+ * skipping into it. Everything the call starts, and every
59
+ * call from rest in the same task, starts at that one time, which
60
+ * `handle.started` reports. A call that continues motion on
61
+ * screen (a retarget, a catch) keeps an explicit start at the call time, or
62
+ * `options.at` to line several animators up, so the new curve continues
63
+ * from the frame on screen. Keyframes are sampled from the call's start, so
64
+ * a value that keeps moving through a rebuild stays on its curve to the
65
+ * frame.
66
+ *
67
+ * WebKit starts an animation created just before a block at its last frame
68
+ * time before the block, so there the motion still skips into its curve;
69
+ * Chromium starts it after the block.
70
+ *
71
+ * Promotion: Mobile Safari runs an animation whose start time is set from
72
+ * script on its compositor at its first commit only if the element already
73
+ * has a compositing layer; without one, a block right after that commit
74
+ * freezes it (iOS 26.2 simulator: 2 of 7 runs kept moving). Every animation
75
+ * the animator creates, and every `set`, therefore promotes its channels in
76
+ * the same task: inline `will-change` on the element, merged with the
77
+ * element's own. That is enough (5 of 5, and 4 of 4 through the animator);
78
+ * promotion ends PROMOTION_LINGER_MS after the last motion.
79
+ *
80
+ * Known limits, iOS Safari (measured on the iOS 26.2 simulator):
81
+ * - a block in the task that starts a motion delays it: it starts when the
82
+ * browser commits it, after the block;
83
+ * - an animation created in the task that first displays a dialog stays on
84
+ * the main thread: start it in the next animation frame;
85
+ * - after a long block, an animation frame's timestamp is when the frame was
86
+ * due, so passing it as `at` starts the curve in the past: keep the default
87
+ * clock;
88
+ * - WebKit does not promote the siblings a moving layer will cross, so a
89
+ * moving layer below content can paint over it: give it `z-index: -1`
90
+ * inside a parent with `isolation: isolate`;
91
+ * - a tap-driven start can show its first moving frame two to four frames
92
+ * into the curve (simulator, not yet confirmed on a device).
93
+ *
94
+ * Reduced Motion (design:reduced-motion): with `prefers-reduced-motion:
95
+ * reduce`, every `animate` and `play` (travel or opacity, on a spring or any
96
+ * curve) is replaced, and nothing moves, scales or springs. The planner
97
+ * (reducedMotionPlan.ts) decides what each call becomes; the animator
98
+ * applies the plan and runs its landings:
99
+ * - on a coarse primary pointer, or for a call started by a touch drag's
100
+ * release on any pointer (`touchRelease`), it becomes (DR2) an
101
+ * opacity-only cross-fade of `timing.reducedMotionCrossFadeMs` (200 ms)
102
+ * on `timing.curves.move`:
103
+ * - entering (opacity rises from 0 in the same call, or `crossfadeAs:
104
+ * 'entrance'`): lands in its new place at once and fades in;
105
+ * - leaving (opacity falls to 0, or `crossfadeAs: 'exit'`): fades out in
106
+ * place, then lands;
107
+ * - an opacity change alone: fades to its value;
108
+ * - otherwise: dips (fades out, lands, fades back in);
109
+ * travel lands with a plain style write while the element is transparent,
110
+ * never as an animated transform; a busy main thread only keeps it
111
+ * transparent longer, and a dip fades back in from the landing; a later
112
+ * call that lands too carries a landing still waiting (two calls in one
113
+ * frame land together), and a later opacity change lands it at once;
114
+ * - on any other primary pointer (DR3) it completes at once.
115
+ * No call option and no theme value lengthens the fade or keeps travel (DR4):
116
+ * the fade's length is not a theme role.
117
+ *
118
+ * Momentum under Reduce Motion (`design:reduced-motion` DR2, DEC-2): a
119
+ * decay's momentum continues the velocity a finger handed it on release
120
+ * (UIScrollView's coast after a flick, with its bounce at an edge), so it
121
+ * keeps its motion, as native momentum does: it is direct movement, not a
122
+ * transition. A curve marked `isTransition` (coast()'s spring back from past
123
+ * an edge), like a spring a component starts on release toward a target it
124
+ * picks (a detent, a page), is a transition: it plays through the Reduce
125
+ * Motion policy above, a cross-fade on a coarse pointer or after a touch
126
+ * release (`touchRelease`) and at once elsewhere (DR2, DR3).
127
+ *
128
+ * SSR-safe: nothing touches `window` or `document` at module scope, and an
129
+ * animator created without an element only keeps state until one is attached.
130
+ *
131
+ * SYNC: When modified, update:
132
+ * - /packages/core/src/motion/animator.test.ts
133
+ * - /packages/core/src/motion/reducedMotionPlan.ts (the Reduce Motion plan)
134
+ * - /packages/core/src/motion/README.md
135
+ */
136
+
137
+ import { cubicBezier } from "./bezier.js";
138
+ import { solveSpring, toSpring } from "./spring.js";
139
+ import { reducedMotionCrossFade } from "./uikit/timing.js";
140
+ import { planReducedMotion } from "./reducedMotionPlan.js";
141
+
142
+ /**
143
+ * A value the animator can drive.
144
+ */
145
+
146
+ /**
147
+ * Values by property; `scale` sets `scaleX` and `scaleY` together.
148
+ */
149
+
150
+ /**
151
+ * A spring and the velocity it starts with.
152
+ */
153
+
154
+ /**
155
+ * Options of `animate` and `play`: the spring, a release velocity, the Reduced
156
+ * Motion handling.
157
+ */
158
+
159
+ /**
160
+ * Any closed-form curve to play on the compositor (`Animator.play`, and a
161
+ * release's coast through `Animator.decay`): a spring chasing a moving
162
+ * target, a piecewise curve, a fitted UIKit curve. Times are seconds from
163
+ * the curve's start; the value at `duration` is the end state. Start it at
164
+ * the property's presentation value (`get`) to continue without a jump.
165
+ */
166
+
167
+ /**
168
+ * Options of `createAnimator`.
169
+ */
170
+
171
+ /**
172
+ * One `animate` / `decay` call's animations.
173
+ */
174
+
175
+ /**
176
+ * A compositor animator bound to one element (see the file header).
177
+ */
178
+
179
+ // ---------------------------------------------------------------------------
180
+ // Curves
181
+ // ---------------------------------------------------------------------------
182
+
183
+ /**
184
+ * A call started from rest. Its animations are created without a start time,
185
+ * so the browser starts them when it commits them, as Core Animation starts
186
+ * an animation at its transaction's commit: a main-thread block before that
187
+ * frame delays the motion instead of skipping into it. Until then the curves
188
+ * read from the call time; once the browser's start is known they move to it.
189
+ */
190
+
191
+ /** An atRest() call waiting for its curves to end. */
192
+
193
+ /**
194
+ * Reduced Motion travel that lands with a plain style write while the
195
+ * element is fully transparent (never an animated transform), then, in a
196
+ * dip, the fade back in.
197
+ */
198
+
199
+ /** What Reduced Motion makes of a call: its segments, and any landing. */
200
+
201
+ const PROPERTIES = ['x', 'y', 'rotate', 'scaleX', 'scaleY', 'opacity'];
202
+
203
+ /** The axes momentum moves: `decay` takes only these (DR2, DEC-2). */
204
+ const DECAY_PROPERTIES = ['x', 'y'];
205
+ const IDENTITY = {
206
+ x: 0,
207
+ y: 0,
208
+ rotate: 0,
209
+ scaleX: 1,
210
+ scaleY: 1,
211
+ opacity: 1
212
+ };
213
+
214
+ /**
215
+ * Within this of its target a curve is over (in the property's own unit). A
216
+ * curve built outside the animator (a progress curve) settles where a call
217
+ * would with this as its epsilon.
218
+ */
219
+ export const SETTLE_THRESHOLD = {
220
+ x: 0.05,
221
+ y: 0.05,
222
+ rotate: 0.01,
223
+ scaleX: 0.0001,
224
+ scaleY: 0.0001,
225
+ opacity: 0.001
226
+ };
227
+
228
+ /** Keyframes are added until linear interpolation is within this. */
229
+ const SAMPLE_TOLERANCE = {
230
+ x: 0.05,
231
+ y: 0.05,
232
+ rotate: 0.02,
233
+ scaleX: 0.0002,
234
+ scaleY: 0.0002,
235
+ opacity: 0.002
236
+ };
237
+
238
+ /** A curve that has not settled by then (an undamped spring) snaps. */
239
+ const MAX_DURATION_MS = 30_000;
240
+ /** Above this many keyframes the tolerance is relaxed. */
241
+ const MAX_KEYFRAMES = 1200;
242
+ /**
243
+ * The keyframes hold the end state this long after a curve ends. An engine
244
+ * whose compositor ends an animation while the main thread is blocked falls
245
+ * back to the value its main thread last committed, mid-flight (WebKit); the
246
+ * hold keeps the end state on screen through such a block. The main thread
247
+ * drops the animation as soon as it runs after the curve's end.
248
+ */
249
+ export const END_HOLD_MS = 5000;
250
+
251
+ /** How often a paused animation is looked at again for retiring, ms. */
252
+ const RETIRE_RECHECK_MS = 100;
253
+
254
+ /** How long an element stays promoted after its last motion, ms. */
255
+ export const PROMOTION_LINGER_MS = 500;
256
+ const CHANNELS = {
257
+ translate: ['x', 'y'],
258
+ rotate: ['rotate'],
259
+ scale: ['scaleX', 'scaleY'],
260
+ opacity: ['opacity']
261
+ };
262
+ const CHANNEL_OF = {
263
+ x: 'translate',
264
+ y: 'translate',
265
+ rotate: 'rotate',
266
+ scaleX: 'scale',
267
+ scaleY: 'scale',
268
+ opacity: 'opacity'
269
+ };
270
+ function round(value, digits) {
271
+ return Number(value.toFixed(digits));
272
+ }
273
+ function format(channel, value) {
274
+ switch (channel) {
275
+ case 'translate':
276
+ return `${round(value('x'), 3)}px ${round(value('y'), 3)}px`;
277
+ case 'rotate':
278
+ return `${round(value('rotate'), 4)}deg`;
279
+ case 'scale':
280
+ return `${round(value('scaleX'), 5)} ${round(value('scaleY'), 5)}`;
281
+ case 'opacity':
282
+ return `${round(Math.min(1, Math.max(0, value('opacity'))), 4)}`;
283
+ }
284
+ }
285
+ const shared = new WeakMap();
286
+
287
+ /**
288
+ * The one animator for `element`, created on
289
+ * first use. Code that animates one element from several places (a swipe on
290
+ * x, a removal on y) shares it, so their curves compose in one `translate`
291
+ * track and retargeting one axis leaves the other on its curve; two
292
+ * animators on one element would overwrite each other. `options` apply
293
+ * when it is created; later calls get the same animator. Never `attach` it
294
+ * elsewhere or `dispose` it: it lives as long as the element.
295
+ */
296
+ export function animatorFor(element, options = {}) {
297
+ let animator = shared.get(element);
298
+ if (animator == null) {
299
+ animator = createAnimator(element, options);
300
+ shared.set(element, animator);
301
+ }
302
+ return animator;
303
+ }
304
+
305
+ /**
306
+ * The inline text for a channel: `format`, except that an identity transform
307
+ * is written `none`. Any other value, `translate: 0px 0px` included, makes
308
+ * the element the containing block of its `position: fixed` descendants and
309
+ * a stacking context, so a motion back to identity would leave a fixed child
310
+ * moved with its parent; Mobile Safari also lets no finger scroll a list
311
+ * inside an element left at `scale: 1`. At rest the identity leaves the
312
+ * element entirely when its stylesheet agrees (`releaseIdentity`).
313
+ */
314
+ function inlineText(channel, value) {
315
+ const at = (property, identity, digits) => round(value(property), digits) === identity;
316
+ switch (channel) {
317
+ case 'translate':
318
+ return at('x', 0, 3) && at('y', 0, 3) ? 'none' : format(channel, value);
319
+ case 'rotate':
320
+ return at('rotate', 0, 4) ? 'none' : format(channel, value);
321
+ case 'scale':
322
+ return at('scaleX', 1, 5) && at('scaleY', 1, 5) ? 'none' : format(channel, value);
323
+ case 'opacity':
324
+ return format(channel, value);
325
+ }
326
+ }
327
+
328
+ /** What `inlineText` writes for each channel at identity. */
329
+ const IDENTITY_TEXT = {
330
+ translate: 'none',
331
+ rotate: 'none',
332
+ scale: 'none',
333
+ opacity: '1'
334
+ };
335
+
336
+ /** Whether a computed value (or an unset one) is the channel's identity. */
337
+ function isIdentityText(channel, text) {
338
+ const value = text.trim();
339
+ if (value === '' || value === 'none') {
340
+ return true;
341
+ }
342
+ const numbers = value.split(/\s+/).map(part => Number.parseFloat(part));
343
+ if (numbers.some(number => !Number.isFinite(number))) {
344
+ return false;
345
+ }
346
+ const identity = channel === 'scale' || channel === 'opacity' ? 1 : 0;
347
+ return numbers.every(number => Math.abs(number - identity) < 1e-6);
348
+ }
349
+ function expand(values) {
350
+ const out = {};
351
+ for (const [key, value] of Object.entries(values)) {
352
+ if (value == null || !Number.isFinite(value)) {
353
+ continue;
354
+ }
355
+ if (key === 'scale') {
356
+ out.scaleX ??= value;
357
+ out.scaleY ??= value;
358
+ } else if (PROPERTIES.includes(key)) {
359
+ out[key] = value;
360
+ }
361
+ }
362
+ return out;
363
+ }
364
+ function defaultNow() {
365
+ return typeof performance === 'undefined' ? Date.now() : performance.now();
366
+ }
367
+
368
+ /**
369
+ * Whether the user asked for reduced motion (`prefers-reduced-motion:
370
+ * reduce`), read at the moment of the call: the preference the animator uses
371
+ * by default for its Reduce Motion substitution. A component never reads it
372
+ * to pick a curve of its own: its motion settings do not override the
373
+ * policy (design:reduced-motion DR4); `animator.reducedMotion()` or
374
+ * `reducedMotionFade()` gives the policy's answer. False without a window
375
+ * (server rendering).
376
+ */
377
+ export function defaultPrefersReducedMotion() {
378
+ return typeof window !== 'undefined' && typeof window.matchMedia === 'function' && window.matchMedia('(prefers-reduced-motion: reduce)').matches;
379
+ }
380
+
381
+ /** Whether the primary pointer is coarse: `(pointer: coarse)`. */
382
+ export function defaultIsCoarsePointer() {
383
+ return typeof window !== 'undefined' && typeof window.matchMedia === 'function' && window.matchMedia('(pointer: coarse)').matches;
384
+ }
385
+
386
+ /**
387
+ * The transition `decay` hands a Reduce Motion transition curve to: under
388
+ * Reduce Motion `animate` plays no spring (a cross-fade, or at once), so the
389
+ * spring itself is never solved.
390
+ */
391
+ const REDUCED_TRANSITION = {
392
+ spring: {
393
+ duration: 0.5,
394
+ bounce: 0
395
+ }
396
+ };
397
+
398
+ /**
399
+ * Creates an animator for `element` (or for an element attached later).
400
+ *
401
+ * @example
402
+ * ```
403
+ * const animator = createAnimator(sheet);
404
+ * // finger lifts at 1200 px/s heading for the detent at 0:
405
+ * animator.animate({y: 0}, {spring: springs.sheetDetent, velocity: {y: 1200}});
406
+ * // the finger lands again: where is it right now?
407
+ * const y = animator.get('y', event.timeStamp);
408
+ * animator.stop(['y']);
409
+ * ```
410
+ */
411
+ export function createAnimator(element, options = {}) {
412
+ const now = options.now ?? defaultNow;
413
+ const requestFrame = options.requestFrame ?? (typeof requestAnimationFrame === 'function' ? callback => {
414
+ requestAnimationFrame(() => callback());
415
+ } : null);
416
+ // Reduced Motion reads the person's settings and nothing else: no option
417
+ // overrides them (design:reduced-motion DR4).
418
+ const prefersReducedMotion = defaultPrefersReducedMotion;
419
+ const isCoarsePointer = defaultIsCoarsePointer;
420
+ const resting = {
421
+ ...IDENTITY,
422
+ ...expand(options.initial ?? {})
423
+ };
424
+ const segments = new Map();
425
+ const running = new Map();
426
+ /** Drops a finished, still-filling animation once the main thread runs. */
427
+ const retireTimers = new Map();
428
+ const touched = new Set();
429
+ /**
430
+ * The stylesheet's opacity a Reduce Motion dip borrowed because no call
431
+ * owned opacity; the dip runs from and back to it, then hands it back.
432
+ */
433
+ let borrowedOpacity = null;
434
+ let target = null;
435
+ /** Calls from rest whose start still waits for the browser's commit. */
436
+ const pendingGroups = new Set();
437
+ /** atRest() calls still waiting; dispose settles them. */
438
+ const restWaits = new Set();
439
+ /** A detach that settles as an unmount at the end of the task, unless an attach follows. */
440
+ let unmountQueued = false;
441
+ /**
442
+ * The node the latest attach(null) detached, while its unmount is pending:
443
+ * a waiting Reduce Motion move lands there, so that node is left visible
444
+ * where it was going.
445
+ */
446
+ let lastDetached = null;
447
+ /** Runs `write` with the pending unmount's node as the target. */
448
+ const onLastDetached = write => {
449
+ const current = target;
450
+ target = target ?? lastDetached;
451
+ try {
452
+ write();
453
+ } finally {
454
+ target = current;
455
+ }
456
+ };
457
+ /** The call being committed, when it starts from rest. */
458
+ let callGroup = null;
459
+ /** Channels promoted to the element's compositing layer (will-change). */
460
+ const promoted = new Set();
461
+ /** The element's own inline will-change, restored when promotion ends. */
462
+ let ownWillChange = null;
463
+ /** The stylesheet's will-change when there is no inline value. */
464
+ let sheetWillChange = '';
465
+ let demoteTimer = null;
466
+ /** Channels whose identity the last node held inline (see `attach`). */
467
+ let heldIdentity = new Set();
468
+
469
+ // -- reading the curves ---------------------------------------------------
470
+
471
+ const segmentAt = (property, time) => {
472
+ const segment = segments.get(property);
473
+ if (segment == null) {
474
+ return null;
475
+ }
476
+ if (time >= segment.start + segment.duration) {
477
+ return null;
478
+ }
479
+ return segment;
480
+ };
481
+
482
+ /**
483
+ * A curve whose call the browser has not started yet: still at its start
484
+ * on screen (valueAt), already moving in the model (velocityAt).
485
+ */
486
+ const isHeld = segment => segment.group != null && !segment.group.resolved;
487
+
488
+ /** The curve itself at `time`: what the keyframes play. */
489
+ const curveAt = (property, time) => {
490
+ const segment = segments.get(property);
491
+ if (segment == null) {
492
+ return resting[property];
493
+ }
494
+ if (time >= segment.start + segment.duration) {
495
+ return segment.target;
496
+ }
497
+ return segment.at(Math.max(0, time - segment.start));
498
+ };
499
+
500
+ /**
501
+ * The value on screen at `time`. A curve the browser has not started is at
502
+ * its start up to now; a later time reads the curve from its provisional
503
+ * start, the model's best guess until the browser's start moves it (a
504
+ * companion that samples a curve ahead follows its shape).
505
+ */
506
+ const valueAt = (property, time) => {
507
+ const segment = segments.get(property);
508
+ if (segment != null && isHeld(segment) && time <= now()) {
509
+ // Nothing has moved on screen until the browser starts the call.
510
+ return segment.at(0);
511
+ }
512
+ return curveAt(property, time);
513
+ };
514
+ const velocityAt = (property, time) => {
515
+ const held = segments.get(property);
516
+ if (held != null && isHeld(held)) {
517
+ // Still at its start on screen, but moving in the model: a retarget
518
+ // carries the velocity the curve has reached by now, so a flick whose
519
+ // moves all land before the browser starts any keeps its speed.
520
+ return held.speed(Math.max(0, time - held.start));
521
+ }
522
+ const segment = segmentAt(property, time);
523
+ if (segment == null || time < segment.start) {
524
+ return 0;
525
+ }
526
+ return segment.speed(time - segment.start);
527
+ };
528
+
529
+ // The curve just before a jump at absolute time `time`.
530
+ const valueBefore = (property, time) => curveAt(property, time - 1e-6);
531
+
532
+ // -- writing --------------------------------------------------------------
533
+
534
+ const finalValue = property => segments.get(property)?.target ?? resting[property];
535
+ const writeInline = (channel, value) => {
536
+ if (target == null) {
537
+ return;
538
+ }
539
+ touched.add(channel);
540
+ const text = inlineText(channel, value);
541
+ if (text === IDENTITY_TEXT[channel]) {
542
+ // Identity leaves the element when nothing else would move it.
543
+ target.style.setProperty(channel, text);
544
+ releaseIdentity(channel);
545
+ } else {
546
+ target.style.setProperty(channel, text);
547
+ }
548
+ };
549
+ const sampleTimes = (property, from, to, tolerance) => {
550
+ const segment = segments.get(property);
551
+ if (segment == null) {
552
+ return [];
553
+ }
554
+ const begin = Math.max(from, segment.start);
555
+ const end = Math.min(to, segment.start + segment.duration);
556
+ if (end <= begin) {
557
+ return [];
558
+ }
559
+ const times = [begin];
560
+ const value = t => curveAt(property, t);
561
+ const breaks = segment.jumps.map(j => segment.start + j).filter(t => t > begin && t < end);
562
+ const edges = [begin, ...breaks, end];
563
+ for (let e = 0; e + 1 < edges.length; e++) {
564
+ const a = edges[e];
565
+ const b = edges[e + 1];
566
+ // A 120 Hz grid, each interval split until the chord is within the
567
+ // tolerance at its quarter points.
568
+ const steps = Math.max(1, Math.ceil((b - a) / (1000 / 120)));
569
+ const split = (t0, t1, depth) => {
570
+ const v0 = value(t0);
571
+ const v1 = t1 === b && breaks.includes(b) ? valueBefore(property, b) : value(t1);
572
+ let worst = 0;
573
+ for (const f of [0.25, 0.5, 0.75]) {
574
+ const t = t0 + (t1 - t0) * f;
575
+ worst = Math.max(worst, Math.abs(value(t) - (v0 + (v1 - v0) * f)));
576
+ }
577
+ if (worst > tolerance && depth < 10 && t1 - t0 > 0.25) {
578
+ const mid = (t0 + t1) / 2;
579
+ split(t0, mid, depth + 1);
580
+ split(mid, t1, depth + 1);
581
+ } else {
582
+ times.push(t1);
583
+ }
584
+ };
585
+ for (let i = 0; i < steps; i++) {
586
+ split(a + (b - a) * i / steps, a + (b - a) * (i + 1) / steps, 0);
587
+ }
588
+ }
589
+ return times;
590
+ };
591
+ const rebuild = (channel, time) => {
592
+ const previous = running.get(channel);
593
+ running.delete(channel);
594
+ clearTimeout(retireTimers.get(channel));
595
+ retireTimers.delete(channel);
596
+ // The element's inline style holds the end state, so its old animation
597
+ // can go first.
598
+ previous?.cancel();
599
+ const properties = CHANNELS[channel];
600
+ // Settled curves become resting values.
601
+ for (const property of properties) {
602
+ const segment = segments.get(property);
603
+ if (segment != null && time >= segment.start + segment.duration) {
604
+ resting[property] = segment.target;
605
+ segments.delete(property);
606
+ }
607
+ }
608
+ writeInline(channel, finalValue);
609
+ const moving = properties.filter(p => segments.has(p));
610
+ if (target == null || typeof target.animate !== 'function') {
611
+ previous?.cancel();
612
+ return;
613
+ }
614
+ if (moving.length === 0) {
615
+ return;
616
+ }
617
+ // A channel rebuilt by an explicit call (set, rebase, a retarget of
618
+ // another axis) while one of its curves still waits for the browser's
619
+ // start keeps that start: no explicit start for this animation.
620
+ const waiting = callGroup ?? moving.map(p => segments.get(p).group).find(group => group != null && !group.resolved) ?? null;
621
+ // The keyframes start where the animation will: at the waiting call's
622
+ // own time, which its start moves to the browser's (resolveGroup), so a
623
+ // write later in the task keeps the screen on the model's clock.
624
+ const from = waiting?.provisional ?? time;
625
+ const end = Math.min(from + MAX_DURATION_MS, Math.max(...moving.map(p => segments.get(p).start + segments.get(p).duration)));
626
+ if (end <= from) {
627
+ return;
628
+ }
629
+ if (callGroup != null) {
630
+ // A curve of an earlier call still waiting for its first frame is
631
+ // rebaked here: it starts with this call's commit.
632
+ for (const property of moving) {
633
+ const segment = segments.get(property);
634
+ const group = segment.group;
635
+ if (group != null && group !== callGroup && !group.resolved) {
636
+ const index = group.segments.indexOf(segment);
637
+ if (index >= 0) {
638
+ group.segments.splice(index, 1);
639
+ }
640
+ group.adoptedBy = callGroup;
641
+ segment.group = callGroup;
642
+ // Re-dated to this call's time: it starts at the commit too, not
643
+ // the work between the two calls into its curve.
644
+ segment.start += callGroup.provisional - group.provisional;
645
+ callGroup.segments.push(segment);
646
+ }
647
+ }
648
+ }
649
+ const collect = scale => {
650
+ const times = new Set([from, end]);
651
+ for (const property of moving) {
652
+ for (const t of sampleTimes(property, from, end, SAMPLE_TOLERANCE[property] * scale)) {
653
+ times.add(t);
654
+ }
655
+ }
656
+ return times;
657
+ };
658
+ let scale = 1;
659
+ let all = collect(scale);
660
+ while (all.size > MAX_KEYFRAMES && scale < 64) {
661
+ scale *= 2;
662
+ all = collect(scale);
663
+ }
664
+ // Jumps become two keyframes at one offset: the value just before, then
665
+ // the value after. A jump on the last frame (fade out, then move) too.
666
+ const jumpTimes = new Set();
667
+ for (const property of moving) {
668
+ const segment = segments.get(property);
669
+ for (const j of segment.jumps) {
670
+ const t = segment.start + j;
671
+ if (t > from && t <= end) {
672
+ jumpTimes.add(t);
673
+ all.add(t);
674
+ }
675
+ }
676
+ }
677
+ const times = [...all].sort((a, b) => a - b);
678
+ const span = end - from + END_HOLD_MS;
679
+ const keyframes = [];
680
+ for (const t of times) {
681
+ const offset = (t - from) / span;
682
+ if (jumpTimes.has(t)) {
683
+ keyframes.push({
684
+ offset,
685
+ [channel]: format(channel, p => valueBefore(p, t))
686
+ });
687
+ }
688
+ keyframes.push({
689
+ offset,
690
+ [channel]: format(channel, p => t >= end ? finalValue(p) : curveAt(p, t))
691
+ });
692
+ }
693
+ keyframes.push({
694
+ offset: 1,
695
+ [channel]: format(channel, finalValue)
696
+ });
697
+ promote(channel);
698
+ const animation = target.animate(keyframes, {
699
+ duration: span,
700
+ // The last keyframes hold the end state (END_HOLD_MS); filling both
701
+ // ways also keeps it where an engine honors the fill on its compositor.
702
+ // The main thread drops the animation once it runs after the end; the
703
+ // inline style already holds the same values, so that changes no pixel.
704
+ fill: 'both',
705
+ easing: 'linear'
706
+ });
707
+ if (waiting != null) {
708
+ // From rest: no start time, so the browser starts the animation when
709
+ // it commits it (StartGroup); the keyframes are sampled from `from`,
710
+ // the call's own start.
711
+ waiting.animations.push(animation);
712
+ waiting.channels.add(channel);
713
+ // A cancel before the first frame rejects its ready promise.
714
+ animation.ready?.catch(() => {});
715
+ } else {
716
+ // One clock: the keyframes were sampled from `time`.
717
+ animation.startTime = time;
718
+ }
719
+ running.set(channel, animation);
720
+ previous?.cancel();
721
+ scheduleRetire(channel, animation, end);
722
+ };
723
+
724
+ /**
725
+ * Once the main thread runs after the curve's end, the animation leaves the
726
+ * running state: the element's inline style already shows the end values.
727
+ */
728
+ const scheduleRetire = (channel, animation, end) => {
729
+ clearTimeout(retireTimers.get(channel));
730
+ const retire = () => {
731
+ retireTimers.delete(channel);
732
+ if (running.get(channel) !== animation) {
733
+ return;
734
+ }
735
+ // Paused or sought (a sampler holding it): retire when its own time
736
+ // reaches the curve's end, never from the wall clock.
737
+ const remaining = remainingCurve(animation);
738
+ if (remaining != null && remaining > 0) {
739
+ retireTimers.set(channel, setTimeout(retire, animation.playState === 'paused' ? RETIRE_RECHECK_MS : remaining));
740
+ return;
741
+ }
742
+ running.delete(channel);
743
+ animation.cancel();
744
+ releaseIdentity(channel);
745
+ flushReleases();
746
+ };
747
+ retireTimers.set(channel, setTimeout(retire, Math.max(0, end - now())));
748
+ };
749
+
750
+ /** The element's own (stylesheet) opacity, read once when a dip starts. */
751
+ const ownOpacity = () => {
752
+ const view = target?.ownerDocument.defaultView;
753
+ const value = target == null ? NaN : Number.parseFloat(view?.getComputedStyle(target).getPropertyValue('opacity') ?? '');
754
+ return Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : 1;
755
+ };
756
+
757
+ /**
758
+ * Whether the animator holds an opacity of its own on the element: an inline
759
+ * value it wrote (a `set` over a stylesheet that hides or dims it). A dip
760
+ * returns to that value.
761
+ */
762
+ const writesOwnOpacity = () => (target?.style.getPropertyValue('opacity') ?? '') !== '';
763
+
764
+ /** Gives the element's opacity back to its stylesheet: its inline value goes. */
765
+ const releaseOwnOpacity = () => {
766
+ target?.style.removeProperty('opacity');
767
+ };
768
+
769
+ /**
770
+ * Lands every Reduce Motion move still waiting, at once, on the current
771
+ * element: its travel, and the opacity its fade was heading to (the
772
+ * stylesheet's again for a borrowed one). Its calls settle `finished`.
773
+ */
774
+ const landPending = finished => {
775
+ if (landings.size === 0) {
776
+ return;
777
+ }
778
+ const changed = new Set();
779
+ let handedBack = false;
780
+ for (const landing of [...landings]) {
781
+ endLanding(landing);
782
+ for (const [property, value] of landing.values) {
783
+ segments.delete(property);
784
+ resting[property] = value;
785
+ changed.add(property);
786
+ }
787
+ if (landing.fadeIn != null || landing.restore != null) {
788
+ const borrowed = landing.fadeIn?.isBorrowed === true || landing.restoreIsBorrowed === true;
789
+ segments.delete('opacity');
790
+ resting.opacity = borrowed ? IDENTITY.opacity : landing.fadeIn?.to ?? landing.restore ?? IDENTITY.opacity;
791
+ changed.add('opacity');
792
+ if (borrowed) {
793
+ borrowedOpacity = null;
794
+ handedBack = true;
795
+ }
796
+ }
797
+ for (const owner of [landing.owner, ...landing.carried]) {
798
+ carriedOwners.delete(owner);
799
+ if (!owner.settled) {
800
+ settle(owner, finished);
801
+ }
802
+ }
803
+ }
804
+ commit(changed, now());
805
+ if (handedBack) {
806
+ // The stylesheet owns its opacity again: no value stays inline.
807
+ releaseOwnOpacity();
808
+ }
809
+ };
810
+
811
+ /**
812
+ * Ends a borrowed dip on the element it ran on: the stylesheet owns its
813
+ * opacity again (an unmount or a new element never keeps the borrow).
814
+ */
815
+ const handBackBorrow = () => {
816
+ if (borrowedOpacity == null) {
817
+ return;
818
+ }
819
+ borrowedOpacity = null;
820
+ segments.delete('opacity');
821
+ resting.opacity = IDENTITY.opacity;
822
+ releaseOwnOpacity();
823
+ };
824
+
825
+ /**
826
+ * A channel at identity with no animation of its own leaves the element:
827
+ * its inline value is removed, unless the stylesheet would then move the
828
+ * element, in which case the identity stays inline. Runs when such a value
829
+ * is written and again when a motion ends.
830
+ */
831
+ const releaseIdentity = channel => {
832
+ if (target == null || running.has(channel)) {
833
+ return;
834
+ }
835
+ if (channel === 'opacity' && borrowedOpacity != null) {
836
+ if ([...landings].some(landing => landing.fadeIn?.isBorrowed === true)) {
837
+ // At the bottom of the dip, before it lands and fades back in.
838
+ return;
839
+ }
840
+ // A dip on the stylesheet's opacity ended: the stylesheet owns it again.
841
+ borrowedOpacity = null;
842
+ segments.delete('opacity');
843
+ resting.opacity = IDENTITY.opacity;
844
+ releaseOwnOpacity();
845
+ return;
846
+ }
847
+ if (target.style.getPropertyValue(channel) !== IDENTITY_TEXT[channel]) {
848
+ return;
849
+ }
850
+ // Read with every other channel the same commit leaves at identity: one
851
+ // style read for the element, not one per channel (flushReleases).
852
+ releasing.add(channel);
853
+ if (!releaseQueued) {
854
+ releaseQueued = true;
855
+ queueMicrotask(flushReleases);
856
+ }
857
+ };
858
+
859
+ /** Channels left at identity whose stylesheet value is still to be read. */
860
+ const releasing = new Set();
861
+ let releaseQueued = false;
862
+
863
+ /**
864
+ * Removes the identity values written since the last flush, reads the
865
+ * stylesheet once for all of them, and puts back the ones it would move:
866
+ * a single forced style read per element and commit, where a read per
867
+ * channel used to force one each.
868
+ */
869
+ const flushReleases = () => {
870
+ releaseQueued = false;
871
+ const element = target;
872
+ const channels = [...releasing].filter(channel => !running.has(channel) && element?.style.getPropertyValue(channel) === IDENTITY_TEXT[channel]);
873
+ releasing.clear();
874
+ if (element == null || channels.length === 0) {
875
+ return;
876
+ }
877
+ for (const channel of channels) {
878
+ element.style.removeProperty(channel);
879
+ }
880
+ const style = element.ownerDocument.defaultView?.getComputedStyle(element);
881
+ for (const channel of channels) {
882
+ const underneath = style?.getPropertyValue(channel);
883
+ if (underneath != null && !isIdentityText(channel, underneath)) {
884
+ element.style.setProperty(channel, IDENTITY_TEXT[channel]);
885
+ }
886
+ }
887
+ };
888
+
889
+ /**
890
+ * Curve time an animation still has to play on its own clock (its keyframes
891
+ * hold the end for END_HOLD_MS after the curve), or null where the engine
892
+ * does not report it; a paused animation always has some left.
893
+ */
894
+ const remainingCurve = animation => {
895
+ const timing = animation.effect?.getTiming?.();
896
+ const current = animation.currentTime;
897
+ if (timing == null || current == null) {
898
+ return animation.playState === 'paused' ? Infinity : null;
899
+ }
900
+ const left = Number(timing.duration) - END_HOLD_MS - Number(current);
901
+ return animation.playState === 'paused' ? Math.max(left, 1) : left;
902
+ };
903
+
904
+ // -- promotion -------------------------------------------------------------
905
+
906
+ /** Writes the promoted channels as will-change. */
907
+ const writePromotion = element => {
908
+ const list = [...promoted].join(', ');
909
+ if (list === '') {
910
+ element.style.willChange = ownWillChange ?? '';
911
+ ownWillChange = null;
912
+ return;
913
+ }
914
+ if (ownWillChange == null) {
915
+ ownWillChange = element.style.willChange;
916
+ // Without an inline value, the stylesheet's reasons stay alongside the
917
+ // promotion's (read once, as the promotion starts).
918
+ sheetWillChange = ownWillChange === '' ? element.ownerDocument.defaultView?.getComputedStyle(element).getPropertyValue('will-change') ?? '' : '';
919
+ }
920
+ const base = ownWillChange !== '' ? ownWillChange : sheetWillChange;
921
+ const own = base === 'auto' ? '' : base;
922
+ const reasons = own.split(',').map(reason => reason.trim()).filter(reason => reason !== '' && !promoted.has(reason));
923
+ element.style.willChange = [...reasons, ...promoted].join(', ');
924
+ };
925
+
926
+ /**
927
+ * Gives the element a compositing layer for
928
+ * `channel` from the task that starts the motion: Mobile Safari runs an
929
+ * animation whose start time is set from script on its compositor at its
930
+ * first commit only if the element already has a layer.
931
+ */
932
+ const promote = channel => {
933
+ if (target == null) {
934
+ return;
935
+ }
936
+ if (!promoted.has(channel)) {
937
+ promoted.add(channel);
938
+ writePromotion(target);
939
+ }
940
+ scheduleDemote();
941
+ };
942
+
943
+ /** Ends promotion PROMOTION_LINGER_MS after the last motion ends. */
944
+ const scheduleDemote = () => {
945
+ if (demoteTimer != null) {
946
+ clearTimeout(demoteTimer);
947
+ }
948
+ let end = now();
949
+ for (const segment of segments.values()) {
950
+ end = Math.max(end, segment.start + segment.duration);
951
+ }
952
+ demoteTimer = setTimeout(() => {
953
+ demoteTimer = null;
954
+ const time = now();
955
+ const moving = [...segments.values()].some(segment => time < segment.start + segment.duration);
956
+ if (moving || pendingGroups.size > 0) {
957
+ scheduleDemote();
958
+ return;
959
+ }
960
+ demote();
961
+ }, Math.max(0, end - now()) + PROMOTION_LINGER_MS);
962
+ };
963
+ const demote = () => {
964
+ if (demoteTimer != null) {
965
+ clearTimeout(demoteTimer);
966
+ demoteTimer = null;
967
+ }
968
+ if (promoted.size === 0) {
969
+ return;
970
+ }
971
+ promoted.clear();
972
+ if (target != null) {
973
+ writePromotion(target);
974
+ }
975
+ };
976
+
977
+ // -- starting from rest ---------------------------------------------------
978
+
979
+ /**
980
+ * A call starts from rest when nothing on the channels it drives is moving
981
+ * (a curve still waiting for its first frame counts as rest) and nothing
982
+ * pins its clock (`at`). Returns its start group, or null for an explicit
983
+ * start.
984
+ */
985
+ const beginGroup = (time, properties, at) => {
986
+ if (target == null || typeof target.animate !== 'function') {
987
+ return null;
988
+ }
989
+ const channels = new Set();
990
+ for (const property of properties) {
991
+ channels.add(CHANNEL_OF[property]);
992
+ }
993
+ if (at != null) {
994
+ // An explicit clock is the caller's, except a clock no later than a
995
+ // call from rest on these channels still waiting for the browser's
996
+ // start (an event timestamp, such as a drop's, for the reorder that
997
+ // rebases it): the new call joins that call, and the browser's start
998
+ // moves both. A later clock is a later call, often a frame or more
999
+ // later while the browser has not started the first: it keeps its own
1000
+ // clock, since joining would sample its curve from the earlier call's
1001
+ // time and hold its first value for the gap.
1002
+ for (const channel of channels) {
1003
+ for (const property of CHANNELS[channel]) {
1004
+ const group = segments.get(property)?.group;
1005
+ if (group != null && !group.resolved && at <= group.provisional) {
1006
+ return group;
1007
+ }
1008
+ }
1009
+ }
1010
+ return null;
1011
+ }
1012
+ for (const channel of channels) {
1013
+ for (const property of CHANNELS[channel]) {
1014
+ const segment = segments.get(property);
1015
+ if (segment != null && time < segment.start + segment.duration && (segment.group == null || segment.group.resolved)) {
1016
+ return null;
1017
+ }
1018
+ }
1019
+ }
1020
+ let resolve = () => {};
1021
+ const started = new Promise(r => {
1022
+ resolve = r;
1023
+ });
1024
+ return {
1025
+ provisional: time,
1026
+ segments: [],
1027
+ animations: [],
1028
+ channels: new Set(),
1029
+ resolved: false,
1030
+ resolve,
1031
+ started
1032
+ };
1033
+ };
1034
+
1035
+ /** Commits a call's changes, from rest when it has a start group. */
1036
+ const commitCall = (group, owner, changed, time) => {
1037
+ if (group != null) {
1038
+ for (const property of changed) {
1039
+ const segment = segments.get(property);
1040
+ if (segment != null && segment.owner === owner) {
1041
+ segment.group = group;
1042
+ group.segments.push(segment);
1043
+ }
1044
+ }
1045
+ }
1046
+ callGroup = group;
1047
+ try {
1048
+ commit(changed, time);
1049
+ } finally {
1050
+ callGroup = null;
1051
+ }
1052
+ if (group == null) {
1053
+ return;
1054
+ }
1055
+ if (group.animations.length === 0) {
1056
+ resolveGroup(group, group.provisional); // nothing to start
1057
+ return;
1058
+ }
1059
+ pendingGroups.add(group);
1060
+ for (const animation of group.animations) {
1061
+ // A cancel before the first frame rejects each one's ready promise.
1062
+ animation.ready?.catch(() => {});
1063
+ }
1064
+ const ready = group.animations[0].ready;
1065
+ if (ready == null || typeof ready.then !== 'function') {
1066
+ resolveGroup(group, group.provisional); // no pending start to wait for
1067
+ return;
1068
+ }
1069
+ // The browser sets the start: at the frame that commits the animations,
1070
+ // or when its compositor starts them (Chromium). Read it in that first
1071
+ // frame, ahead of anything that might pause or seek the animations, and
1072
+ // when `ready` settles.
1073
+ requestFrame?.(() => syncGroup(group));
1074
+ ready.then(() => syncGroup(group), () => settleCancelled(group));
1075
+ };
1076
+
1077
+ /**
1078
+ * A call whose first animation was cancelled before its first frame: if a
1079
+ * later call in the same task took over its curves, it starts with that
1080
+ * call; otherwise it never started.
1081
+ */
1082
+ const settleCancelled = group => {
1083
+ if (group.resolved) {
1084
+ return;
1085
+ }
1086
+ let adopter = group.adoptedBy;
1087
+ while (adopter?.adoptedBy != null) {
1088
+ adopter = adopter.adoptedBy;
1089
+ }
1090
+ if (adopter != null && adopter !== group) {
1091
+ void adopter.started.then(start => resolveGroup(group, start));
1092
+ return;
1093
+ }
1094
+ // A same-task write replaced the animation the call waited on: the call
1095
+ // still starts with the browser's start of the ones that remain.
1096
+ if (awaitStart(group)) {
1097
+ return;
1098
+ }
1099
+ resolveGroup(group, group.provisional);
1100
+ };
1101
+
1102
+ /**
1103
+ * Waits for the browser's start of a call through one of its animations
1104
+ * still playing; false when none is left to wait on.
1105
+ */
1106
+ const awaitStart = group => {
1107
+ const live = group.animations.find(animation => animation.playState !== 'idle');
1108
+ const ready = live?.ready;
1109
+ if (ready == null || typeof ready.then !== 'function') {
1110
+ return false;
1111
+ }
1112
+ ready.then(() => syncGroup(group), () => settleCancelled(group));
1113
+ return true;
1114
+ };
1115
+ const syncGroup = group => {
1116
+ if (group.resolved) {
1117
+ return;
1118
+ }
1119
+ for (const animation of group.animations) {
1120
+ if (animation.startTime != null) {
1121
+ resolveGroup(group, Number(animation.startTime));
1122
+ return;
1123
+ }
1124
+ }
1125
+ // Finished from outside before the browser started it (a sampler's
1126
+ // finish() on a held animation): nothing is left to wait on, so the call
1127
+ // keeps its own clock, and a later call on an explicit clock does not
1128
+ // join it and wait for a start that never comes.
1129
+ if (group.animations.length > 0 && group.animations.every(animation => animation.playState === 'finished' || animation.playState === 'idle') && group.animations.some(animation => animation.playState === 'finished')) {
1130
+ resolveGroup(group, group.provisional);
1131
+ return;
1132
+ }
1133
+ // No start yet (paused before its first frame by a harness or a page,
1134
+ // or resumed with play() and still pending): neither `ready` nor the
1135
+ // first frame will look again, so keep looking each frame until the call
1136
+ // has a start, or its animations finish (its own clock) or are cancelled.
1137
+ if (group.animations.some(animation => animation.startTime == null && animation.playState !== 'idle')) {
1138
+ requestFrame?.(() => syncGroup(group));
1139
+ }
1140
+ };
1141
+
1142
+ /** Reads the start of every call whose first frame has been committed. */
1143
+ const syncPending = () => {
1144
+ for (const group of pendingGroups) {
1145
+ syncGroup(group);
1146
+ }
1147
+ syncFinished();
1148
+ };
1149
+
1150
+ /**
1151
+ * An animation finished from outside (a test utility's or devtools'
1152
+ * `finish()`) shows its end state while the model still reads its curve:
1153
+ * the curve ends now in the model too, so the next call starts from what
1154
+ * is on screen.
1155
+ */
1156
+ const syncFinished = () => {
1157
+ for (const [channel, animation] of running) {
1158
+ if (animation.playState !== 'finished') {
1159
+ continue;
1160
+ }
1161
+ const time = now();
1162
+ for (const property of CHANNELS[channel]) {
1163
+ const segment = segments.get(property);
1164
+ if (segment == null || time >= segment.start + segment.duration) {
1165
+ continue;
1166
+ }
1167
+ segments.delete(property);
1168
+ resting[property] = segment.target;
1169
+ }
1170
+ }
1171
+ };
1172
+
1173
+ /** Moves a call from rest onto the time the browser started it. */
1174
+ const resolveGroup = (group, start) => {
1175
+ if (group.resolved) {
1176
+ return;
1177
+ }
1178
+ group.resolved = true;
1179
+ pendingGroups.delete(group);
1180
+ for (const animation of group.animations) {
1181
+ // One clock for the whole call; a cancelled one stays cancelled (a
1182
+ // start time would play it again).
1183
+ if (animation.startTime == null && animation.playState !== 'idle') {
1184
+ animation.startTime = start;
1185
+ }
1186
+ }
1187
+ const delta = start - group.provisional;
1188
+ if (delta !== 0) {
1189
+ for (const segment of group.segments) {
1190
+ segment.start += delta;
1191
+ }
1192
+ for (const channel of group.channels) {
1193
+ const animation = running.get(channel);
1194
+ if (animation == null || !group.animations.includes(animation)) {
1195
+ continue;
1196
+ }
1197
+ const ends = CHANNELS[channel].flatMap(p => {
1198
+ const segment = segments.get(p);
1199
+ return segment == null ? [] : [segment.start + segment.duration];
1200
+ });
1201
+ if (ends.length > 0) {
1202
+ scheduleRetire(channel, animation, Math.max(...ends));
1203
+ }
1204
+ }
1205
+ for (const owner of new Set(group.segments.map(s => s.owner))) {
1206
+ if (owner.settled || owner.timer == null) {
1207
+ continue;
1208
+ }
1209
+ clearTimeout(owner.timer);
1210
+ const ends = group.segments.filter(segment => segment.owner === owner).map(segment => segment.start + segment.duration);
1211
+ owner.timer = setTimeout(() => {
1212
+ owner.timer = null;
1213
+ settle(owner, true);
1214
+ }, Math.max(0, Math.max(start, ...ends) - now()));
1215
+ }
1216
+ }
1217
+ group.resolve(start);
1218
+ };
1219
+
1220
+ // -- handles --------------------------------------------------------------
1221
+
1222
+ const lastSpring = new WeakMap();
1223
+ const interrupt = (property, time) => {
1224
+ cancelLanding(property);
1225
+ const segment = segments.get(property);
1226
+ if (segment == null) {
1227
+ return;
1228
+ }
1229
+ if (time < segment.start + segment.duration && !carriedOwners.has(segment.owner)) {
1230
+ settle(segment.owner, false);
1231
+ }
1232
+ };
1233
+ const settle = (owner, finished) => {
1234
+ if (owner.settled) {
1235
+ return;
1236
+ }
1237
+ owner.settled = true;
1238
+ if (owner.timer != null) {
1239
+ clearTimeout(owner.timer);
1240
+ owner.timer = null;
1241
+ }
1242
+ owner.resolve(finished);
1243
+ };
1244
+ const makeHandle = (owner, properties, finished, time, group = null) => {
1245
+ const ends = properties.map(p => {
1246
+ const segment = segments.get(p);
1247
+ return segment != null && segment.owner === owner ? segment.start + segment.duration : time;
1248
+ });
1249
+ const end = Math.max(time, ...ends);
1250
+ if (properties.length === 0 || end <= time) {
1251
+ settle(owner, true);
1252
+ } else {
1253
+ // Interruptions settle false as they happen (interrupt); reaching the
1254
+ // end untouched is completion.
1255
+ owner.timer = setTimeout(() => {
1256
+ owner.timer = null;
1257
+ settle(owner, true);
1258
+ }, Math.max(0, end - now()));
1259
+ }
1260
+ const handle = {
1261
+ properties,
1262
+ finished,
1263
+ started: group?.started ?? Promise.resolve(time),
1264
+ value: (property, at = now()) => {
1265
+ syncPending();
1266
+ return valueAt(property, at);
1267
+ },
1268
+ velocity: (property, at = now()) => {
1269
+ syncPending();
1270
+ return velocityAt(property, at);
1271
+ },
1272
+ retarget: (to, transition, retargetOptions) => {
1273
+ const spring = transition?.spring ?? lastSpring.get(owner);
1274
+ if (spring == null) {
1275
+ throw new Error('animator: retarget needs a spring');
1276
+ }
1277
+ return animator.animate(to, {
1278
+ ...transition,
1279
+ spring
1280
+ }, retargetOptions);
1281
+ },
1282
+ // The call's own curves, and its travel still waiting to land under
1283
+ // Reduce Motion: a catch freezes both where they are on screen
1284
+ // (AST-094 FR6), travel first so the fade's landing no longer carries
1285
+ // it, as `animator.stop()` does.
1286
+ stop: () => animator.stop(PROPERTIES.filter(p => properties.includes(p) && (segments.get(p)?.owner === owner || [...landings].some(landing => landing.values.has(p) && (landing.owners.get(p) ?? landing.owner) === owner))))
1287
+ };
1288
+ return handle;
1289
+ };
1290
+ const newOwner = () => {
1291
+ let resolve = () => {};
1292
+ const finished = new Promise(r => {
1293
+ resolve = r;
1294
+ });
1295
+ return {
1296
+ owner: {
1297
+ resolve,
1298
+ settled: false,
1299
+ timer: null
1300
+ },
1301
+ finished
1302
+ };
1303
+ };
1304
+
1305
+ // -- segment factories ------------------------------------------------------
1306
+
1307
+ const springSegment = (owner, property, start, to, spring, velocity) => {
1308
+ const from = valueAt(property, start);
1309
+ if (from === to && velocity === 0) {
1310
+ return null;
1311
+ }
1312
+ const curve = solveSpring(toSpring(spring), {
1313
+ from,
1314
+ to,
1315
+ velocity
1316
+ });
1317
+ const duration = Math.min(MAX_DURATION_MS, curve.settleTime(SETTLE_THRESHOLD[property]) * 1000);
1318
+ return {
1319
+ start,
1320
+ duration,
1321
+ target: to,
1322
+ at: t => curve.value(t / 1000),
1323
+ speed: t => curve.velocity(t / 1000),
1324
+ jumps: [],
1325
+ owner,
1326
+ spring
1327
+ };
1328
+ };
1329
+ const fadeSegment = (owner, start, stops, jumps = []) => {
1330
+ const ease = cubicBezier(reducedMotionCrossFade.curve);
1331
+ const duration = stops[stops.length - 1].at;
1332
+ const at = t => {
1333
+ for (let i = 0; i + 1 < stops.length; i++) {
1334
+ const a = stops[i];
1335
+ const b = stops[i + 1];
1336
+ if (t < b.at || i + 2 === stops.length) {
1337
+ if (b.at === a.at) {
1338
+ return b.value;
1339
+ }
1340
+ const p = Math.min(1, Math.max(0, (t - a.at) / (b.at - a.at)));
1341
+ return a.value + (b.value - a.value) * ease(p);
1342
+ }
1343
+ }
1344
+ return stops[stops.length - 1].value;
1345
+ };
1346
+ return {
1347
+ start,
1348
+ duration,
1349
+ target: stops[stops.length - 1].value,
1350
+ at,
1351
+ speed: t => (at(t + 0.5) - at(Math.max(0, t - 0.5))) / (t >= 0.5 ? 1 : 0.5 + t) * 1000,
1352
+ jumps,
1353
+ owner,
1354
+ isFade: true
1355
+ };
1356
+ };
1357
+
1358
+ // -- the animator -----------------------------------------------------------
1359
+
1360
+ const commit = (changed, time) => {
1361
+ const channels = new Set();
1362
+ for (const property of changed) {
1363
+ channels.add(CHANNEL_OF[property]);
1364
+ }
1365
+ if (channels.has('opacity')) {
1366
+ borrowedOpacity = null;
1367
+ }
1368
+ for (const channel of channels) {
1369
+ rebuild(channel, time);
1370
+ }
1371
+ flushReleases();
1372
+ };
1373
+
1374
+ /** Reduced Motion landings still waiting for the element to be transparent. */
1375
+ const landings = new Set();
1376
+ /** Calls a later call's landing carries: an interrupt does not settle them. */
1377
+ const carriedOwners = new Set();
1378
+
1379
+ /**
1380
+ * A later write to `property` takes it from any landing. A write to opacity
1381
+ * decides what shows, so a landing still waiting writes its travel at once
1382
+ * rather than never, and its calls settle as interrupted.
1383
+ */
1384
+ const cancelLanding = property => {
1385
+ for (const landing of [...landings]) {
1386
+ if (property === 'opacity') {
1387
+ endLanding(landing);
1388
+ landNow(landing);
1389
+ } else if (landing.values.delete(property)) {
1390
+ // Set or stopped before it landed: the call whose move it was did
1391
+ // not finish (a carried value is an earlier call's).
1392
+ const moved = landing.owners.get(property) ?? landing.owner;
1393
+ landing.owners.delete(property);
1394
+ if (!moved.settled) {
1395
+ settle(moved, false);
1396
+ }
1397
+ }
1398
+ }
1399
+ };
1400
+ const landNow = landing => {
1401
+ const changed = [];
1402
+ for (const [property, value] of landing.values) {
1403
+ segments.delete(property);
1404
+ resting[property] = value;
1405
+ changed.push(property);
1406
+ }
1407
+ if (changed.length > 0) {
1408
+ commit(changed, now());
1409
+ }
1410
+ for (const owner of [landing.owner, ...landing.carried]) {
1411
+ carriedOwners.delete(owner);
1412
+ if (!owner.settled) {
1413
+ settle(owner, false);
1414
+ }
1415
+ }
1416
+ };
1417
+
1418
+ /**
1419
+ * A later Reduced Motion call that lands too carries the landings still
1420
+ * waiting: their travel lands with its own, which wins where both move a
1421
+ * property, and their calls settle when it lands. So two calls in one
1422
+ * frame (a drag cancel's position and scale) both land.
1423
+ */
1424
+ const adoptLandings = (plan, properties) => {
1425
+ const carried = [];
1426
+ const owners = new Map();
1427
+ for (const landing of [...landings]) {
1428
+ for (const [property, value] of landing.values) {
1429
+ const moved = landing.owners.get(property) ?? landing.owner;
1430
+ if (!properties.includes(property) && !plan.values.has(property)) {
1431
+ plan.values.set(property, value);
1432
+ owners.set(property, moved);
1433
+ } else if (!moved.settled) {
1434
+ // This call takes the property over: the earlier move never lands.
1435
+ settle(moved, false);
1436
+ }
1437
+ }
1438
+ carried.push(landing.owner, ...landing.carried);
1439
+ endLanding(landing);
1440
+ }
1441
+ for (const owner of carried) {
1442
+ carriedOwners.add(owner);
1443
+ }
1444
+ return {
1445
+ carried,
1446
+ owners
1447
+ };
1448
+ };
1449
+
1450
+ /** Where opacity is heading: past a waiting landing's fade back in. */
1451
+ const opacityHeading = () => {
1452
+ let to = finalValue('opacity');
1453
+ for (const landing of landings) {
1454
+ if (landing.fadeIn != null) {
1455
+ to = landing.fadeIn.to;
1456
+ } else if (landing.restore != null) {
1457
+ to = landing.restore;
1458
+ }
1459
+ }
1460
+ return to;
1461
+ };
1462
+ const endLanding = landing => {
1463
+ if (landing.timer != null) {
1464
+ clearTimeout(landing.timer);
1465
+ }
1466
+ landings.delete(landing);
1467
+ };
1468
+
1469
+ /** Arms a landing from the call's start (the browser's, for a call from rest). */
1470
+ const scheduleLanding = (owner, started, plan, adopted) => {
1471
+ const owners = new Map();
1472
+ for (const property of plan.values.keys()) {
1473
+ owners.set(property, adopted?.owners.get(property) ?? owner);
1474
+ }
1475
+ const landing = {
1476
+ ...plan,
1477
+ owner,
1478
+ carried: adopted?.carried ?? [],
1479
+ owners,
1480
+ timer: null,
1481
+ due: null
1482
+ };
1483
+ landings.add(landing);
1484
+ // The handle settles when the landing (and its fade back in) is done.
1485
+ if (owner.timer != null) {
1486
+ clearTimeout(owner.timer);
1487
+ owner.timer = null;
1488
+ }
1489
+ void started.then(start => {
1490
+ if (!landings.has(landing)) {
1491
+ return;
1492
+ }
1493
+ landing.due = start + landing.at;
1494
+ landing.timer = setTimeout(() => land(landing), Math.max(0, landing.due - now()));
1495
+ });
1496
+ };
1497
+
1498
+ /**
1499
+ * Writes the travel while the element is transparent: a plain style write,
1500
+ * never an animation (DR2: opacity only), so it is never shown in the wrong
1501
+ * place. In a dip the fade back in starts from here and takes what is left
1502
+ * of the cross-fade, so the dip ends when it was due even when a busy main
1503
+ * thread runs this timer late; past the whole fade back in (over 100 ms
1504
+ * late) the element appears at once where it landed.
1505
+ */
1506
+ const land = landing => {
1507
+ landings.delete(landing);
1508
+ landing.timer = null;
1509
+ const time = now();
1510
+ const changed = [];
1511
+ for (const [property, value] of landing.values) {
1512
+ segments.delete(property);
1513
+ resting[property] = value;
1514
+ changed.push(property);
1515
+ }
1516
+ let end = time;
1517
+ if (landing.fadeIn != null) {
1518
+ // The fade back in takes what is left of the cross-fade: a timer that
1519
+ // a busy main thread runs late shortens it, so the dip still ends
1520
+ // when it was due (design:reduced-motion DR2, 200 ms or less), and the
1521
+ // element is never shown before it lands.
1522
+ const late = landing.due == null ? 0 : Math.max(0, time - landing.due);
1523
+ const ms = Math.max(1, landing.fadeIn.ms - late);
1524
+ segments.set('opacity', fadeSegment(landing.owner, time, [{
1525
+ at: 0,
1526
+ value: valueAt('opacity', time)
1527
+ }, {
1528
+ at: ms,
1529
+ value: landing.fadeIn.to
1530
+ }]));
1531
+ changed.push('opacity');
1532
+ end = time + ms;
1533
+ } else if (landing.restore != null) {
1534
+ segments.delete('opacity');
1535
+ resting.opacity = landing.restoreIsBorrowed === true ? IDENTITY.opacity : landing.restore;
1536
+ changed.push('opacity');
1537
+ }
1538
+ commit(changed, time);
1539
+ if (landing.restoreIsBorrowed === true) {
1540
+ // The stylesheet owns its opacity again.
1541
+ releaseOwnOpacity();
1542
+ }
1543
+ if (landing.fadeIn?.isBorrowed === true) {
1544
+ // The fade back in returns to the stylesheet's opacity: it owns it
1545
+ // again once the fade ends (releaseIdentity).
1546
+ borrowedOpacity = landing.fadeIn.to;
1547
+ }
1548
+ // The calls it carries are done: their travel has landed.
1549
+ for (const carried of landing.carried) {
1550
+ carriedOwners.delete(carried);
1551
+ if (!carried.settled) {
1552
+ settle(carried, true);
1553
+ }
1554
+ }
1555
+ const {
1556
+ owner
1557
+ } = landing;
1558
+ if (owner.settled) {
1559
+ return;
1560
+ }
1561
+ if (end <= time) {
1562
+ settle(owner, true);
1563
+ } else {
1564
+ owner.timer = setTimeout(() => {
1565
+ owner.timer = null;
1566
+ settle(owner, true);
1567
+ }, Math.max(0, end - now()));
1568
+ }
1569
+ };
1570
+
1571
+ /**
1572
+ * A call that sets a value still waiting to land takes it over: the earlier
1573
+ * move never lands, and its call settles interrupted. Once nothing waiting
1574
+ * is left, a call that names its own opacity replaces an earlier fade back
1575
+ * in or restore too, so a caught dismissal fades straight back up instead
1576
+ * of dipping. Whatever still waits is carried by the new plan.
1577
+ */
1578
+ const takeOverLandings = (properties, namesOpacity) => {
1579
+ for (const property of properties) {
1580
+ if (property !== 'opacity') {
1581
+ cancelLanding(property);
1582
+ }
1583
+ }
1584
+ if (!namesOpacity) {
1585
+ // A dip left with nothing to land (a move taken back) fades straight
1586
+ // back in from where it is, rather than finishing its dip.
1587
+ for (const landing of [...landings]) {
1588
+ if (landing.values.size === 0 && landing.fadeIn != null) {
1589
+ endLanding(landing);
1590
+ land(landing);
1591
+ }
1592
+ }
1593
+ return;
1594
+ }
1595
+ for (const landing of [...landings]) {
1596
+ // A waiting call that named its own opacity loses it to this call: it
1597
+ // never reaches that opacity, so it settles interrupted even though its
1598
+ // travel still lands.
1599
+ for (const owner of [landing.owner, ...landing.carried]) {
1600
+ if (namedOpacity.has(owner) && !owner.settled) {
1601
+ settle(owner, false);
1602
+ }
1603
+ }
1604
+ if (landing.values.size > 0) {
1605
+ continue;
1606
+ }
1607
+ endLanding(landing);
1608
+ if (landing.fadeIn?.isBorrowed === true || landing.restoreIsBorrowed === true) {
1609
+ // The call's own opacity owns it now, not the stylesheet's.
1610
+ borrowedOpacity = null;
1611
+ }
1612
+ for (const owner of [landing.owner, ...landing.carried]) {
1613
+ carriedOwners.delete(owner);
1614
+ if (!owner.settled) {
1615
+ settle(owner, false);
1616
+ }
1617
+ }
1618
+ }
1619
+ };
1620
+
1621
+ /** Reduce Motion calls that named their own opacity. */
1622
+ const namedOpacity = new WeakSet();
1623
+
1624
+ /**
1625
+ * Where opacity was heading before a call took the waiting landings over:
1626
+ * an entrance by role that catches an exit fades back to what the exit
1627
+ * would have restored.
1628
+ */
1629
+ let headingBeforeTakeOver = null;
1630
+
1631
+ /** What the Reduce Motion planner reads of this animator. */
1632
+ const planView = {
1633
+ valueAt,
1634
+ opacityHeading: () => headingBeforeTakeOver ?? opacityHeading(),
1635
+ ownOpacity: () => ownOpacity(),
1636
+ writesOwnOpacity: () => writesOwnOpacity(),
1637
+ get borrowedOpacity() {
1638
+ return borrowedOpacity;
1639
+ },
1640
+ get hasOpacityCurve() {
1641
+ return segments.has('opacity');
1642
+ },
1643
+ get restingOpacity() {
1644
+ return resting.opacity;
1645
+ },
1646
+ get hasPendingLanding() {
1647
+ return landings.size > 0;
1648
+ }
1649
+ };
1650
+
1651
+ /**
1652
+ * Reduced Motion (see the file header): the planner's plan
1653
+ * (reducedMotionPlan.ts) as this call's segments.
1654
+ */
1655
+ const reducedMotion = (owner, time, targets, properties, fade, role) => {
1656
+ const heading = opacityHeading();
1657
+ // An entrance or an exit by role drives the opacity as a named one does.
1658
+ takeOverLandings(properties, targets.opacity != null || role != null);
1659
+ if (targets.opacity != null) {
1660
+ namedOpacity.add(owner);
1661
+ }
1662
+ headingBeforeTakeOver = heading;
1663
+ let plan;
1664
+ try {
1665
+ plan = planReducedMotion(planView, time, targets, properties, fade, role);
1666
+ } finally {
1667
+ headingBeforeTakeOver = null;
1668
+ }
1669
+ const next = {};
1670
+ for (const property of plan.atOnce) {
1671
+ next[property] = null;
1672
+ }
1673
+ if (plan.opacityFade != null) {
1674
+ next.opacity = fadeSegment(owner, time, plan.opacityFade);
1675
+ }
1676
+ return {
1677
+ next,
1678
+ holds: plan.holds,
1679
+ landing: plan.landing,
1680
+ borrowed: plan.borrowed
1681
+ };
1682
+ };
1683
+ const animator = {
1684
+ get element() {
1685
+ return target;
1686
+ },
1687
+ reducedMotion(reducedOptions = {}) {
1688
+ if (!prefersReducedMotion()) {
1689
+ return 'off';
1690
+ }
1691
+ return isCoarsePointer() || reducedOptions.touchRelease === true ? 'crossfade' : 'instant';
1692
+ },
1693
+ attach(next) {
1694
+ if (next === target) {
1695
+ return;
1696
+ }
1697
+ if (next == null) {
1698
+ // Unmount, unless a node replaces this one in the same task (React's
1699
+ // replacement order: attach(null), then the new node): nothing is
1700
+ // left to animate, so at the end of the task every other handle
1701
+ // settles as interrupted, every atRest() wait settles and no
1702
+ // completion timer outlives the element, as in dispose()
1703
+ // (architecture:react-component-runtime INV5). A replacement keeps
1704
+ // them all: the motion goes on on the new node.
1705
+ lastDetached = target;
1706
+ if (!unmountQueued) {
1707
+ unmountQueued = true;
1708
+ queueMicrotask(() => {
1709
+ if (!unmountQueued) {
1710
+ return;
1711
+ }
1712
+ unmountQueued = false;
1713
+ // A Reduce Motion move still waiting lands where it was going, as
1714
+ // in dispose(), on the node just detached too: a dip's fade out
1715
+ // left its low opacity inline there, so a later attach of that
1716
+ // node (a Suspense or Activity reveal) shows it landed and
1717
+ // visible. Its calls settle as interrupted.
1718
+ onLastDetached(() => {
1719
+ landPending(false);
1720
+ // The landing's commit rebuilt every channel it touched on the
1721
+ // detached node, any axis still moving included: leave that
1722
+ // node with no animation, timer or promotion.
1723
+ for (const animation of running.values()) {
1724
+ animation.cancel();
1725
+ }
1726
+ running.clear();
1727
+ for (const timer of retireTimers.values()) {
1728
+ clearTimeout(timer);
1729
+ }
1730
+ retireTimers.clear();
1731
+ demote();
1732
+ });
1733
+ lastDetached = null;
1734
+ const time = now();
1735
+ for (const property of PROPERTIES) {
1736
+ interrupt(property, time);
1737
+ }
1738
+ for (const wait of [...restWaits]) {
1739
+ wait.settle();
1740
+ }
1741
+ });
1742
+ }
1743
+ } else {
1744
+ // A node in place of the one just detached: no unmount.
1745
+ unmountQueued = false;
1746
+ lastDetached = null;
1747
+ }
1748
+ // After the landing's commit, which can promote the element again.
1749
+ demote();
1750
+ const isOpacityBorrowed = borrowedOpacity != null || [...landings].some(landing => landing.restoreIsBorrowed === true);
1751
+ for (const animation of running.values()) {
1752
+ animation.cancel();
1753
+ }
1754
+ running.clear();
1755
+ for (const timer of retireTimers.values()) {
1756
+ clearTimeout(timer);
1757
+ }
1758
+ retireTimers.clear();
1759
+ if (isOpacityBorrowed) {
1760
+ // A running borrowed dip (or an exit by role returning to the
1761
+ // stylesheet) stays in the model through any attach, so a pending
1762
+ // move still lands while the element is invisible; only the
1763
+ // outgoing element gets its stylesheet's opacity back.
1764
+ releaseOwnOpacity();
1765
+ }
1766
+ // Identities the outgoing node holds inline over a stylesheet that
1767
+ // differs, kept through a detach for the node that comes next.
1768
+ if (target != null) {
1769
+ const outgoing = target;
1770
+ heldIdentity = new Set(Object.keys(CHANNELS).filter(channel => outgoing.style.getPropertyValue(channel) === IDENTITY_TEXT[channel]));
1771
+ }
1772
+ const held = heldIdentity;
1773
+ target = next;
1774
+ if (target == null) {
1775
+ return;
1776
+ }
1777
+ heldIdentity = new Set();
1778
+ const time = now();
1779
+ // A borrowed dip that ended while detached hands the opacity back
1780
+ // instead of writing the borrowed value inline.
1781
+ const dip = segments.get('opacity');
1782
+ if (borrowedOpacity != null && (dip == null || time >= dip.start + dip.duration)) {
1783
+ borrowedOpacity = null;
1784
+ segments.delete('opacity');
1785
+ resting.opacity = IDENTITY.opacity;
1786
+ }
1787
+ for (const channel of Object.keys(CHANNELS)) {
1788
+ const properties = CHANNELS[channel];
1789
+ const isDefault = properties.every(p => !segments.has(p) && resting[p] === IDENTITY[p]);
1790
+ if (!isDefault) {
1791
+ rebuild(channel, time);
1792
+ } else if (held.has(channel)) {
1793
+ // An identity the animator held inline over a stylesheet that
1794
+ // differs goes onto the new node too (writeInline keeps it only
1795
+ // where the new node's stylesheet still differs).
1796
+ writeInline(channel, property => resting[property]);
1797
+ }
1798
+ }
1799
+ flushReleases();
1800
+ },
1801
+ get(property, time = now()) {
1802
+ syncPending();
1803
+ return valueAt(property === 'scale' ? 'scaleX' : property, time);
1804
+ },
1805
+ getVelocity(property, time = now()) {
1806
+ syncPending();
1807
+ return velocityAt(property === 'scale' ? 'scaleX' : property, time);
1808
+ },
1809
+ set(values) {
1810
+ syncPending();
1811
+ const time = now();
1812
+ const next = expand(values);
1813
+ for (const [property, value] of Object.entries(next)) {
1814
+ interrupt(property, time);
1815
+ segments.delete(property);
1816
+ resting[property] = value;
1817
+ }
1818
+ // Direct manipulation: the layer makes each write a composite only.
1819
+ for (const property of Object.keys(next)) {
1820
+ promote(CHANNEL_OF[property]);
1821
+ }
1822
+ commit(Object.keys(next), time);
1823
+ },
1824
+ animate(to, transition, animateOptions = {}) {
1825
+ syncPending();
1826
+ const time = animateOptions.at ?? now();
1827
+ const targets = expand(to);
1828
+ const velocities = expand(transition.velocity ?? {});
1829
+ const {
1830
+ owner,
1831
+ finished
1832
+ } = newOwner();
1833
+ lastSpring.set(owner, transition.spring);
1834
+ const properties = Object.keys(targets);
1835
+ const next = {};
1836
+ let plan = null;
1837
+ if (prefersReducedMotion()) {
1838
+ plan = reducedMotion(owner, time, targets, properties, isCoarsePointer() || animateOptions.touchRelease === true, animateOptions.crossfadeAs);
1839
+ Object.assign(next, plan.next);
1840
+ } else {
1841
+ for (const property of properties) {
1842
+ const velocity = velocities[property] ?? velocityAt(property, time);
1843
+ next[property] = springSegment(owner, property, time, targets[property], transition.spring, velocity);
1844
+ }
1845
+ }
1846
+ const group = beginGroup(time, Object.keys(next), animateOptions.at);
1847
+ const adopted = plan?.landing != null ? adoptLandings(plan.landing, Object.keys(next)) : null;
1848
+ const changed = [];
1849
+ for (const [property, segment] of Object.entries(next)) {
1850
+ interrupt(property, time);
1851
+ changed.push(property);
1852
+ if (segment == null) {
1853
+ // Read before the segment goes: valueAt falls back to resting.
1854
+ const value = plan?.holds[property] ?? targets[property] ?? valueAt(property, time);
1855
+ segments.delete(property);
1856
+ resting[property] = value;
1857
+ } else {
1858
+ segments.set(property, segment);
1859
+ }
1860
+ }
1861
+ commitCall(group, owner, changed, time);
1862
+ if (plan?.borrowed != null) {
1863
+ // The dip's own commit cleared it; the borrow lasts the dip.
1864
+ borrowedOpacity = plan.borrowed;
1865
+ }
1866
+ const handle = makeHandle(owner, changed, finished, time, group);
1867
+ if (plan?.landing != null) {
1868
+ scheduleLanding(owner, handle.started, plan.landing, adopted);
1869
+ }
1870
+ return handle;
1871
+ },
1872
+ play(curves, playOptions = {}) {
1873
+ syncPending();
1874
+ const time = playOptions.at ?? now();
1875
+ const {
1876
+ owner,
1877
+ finished
1878
+ } = newOwner();
1879
+ const byProperty = {};
1880
+ // `scale` first, so an explicit `scaleX` or `scaleY` beside it wins.
1881
+ const entries = Object.entries(curves).sort(([a], [b]) => Number(b === 'scale') - Number(a === 'scale'));
1882
+ for (const [key, curve] of entries) {
1883
+ if (curve == null) {
1884
+ continue;
1885
+ }
1886
+ if (!Number.isFinite(curve.duration) || curve.duration < 0) {
1887
+ throw new RangeError(`animator: a curve needs a finite duration ≥ 0 (got ${curve.duration})`);
1888
+ }
1889
+ for (const property of expandList([key])) {
1890
+ byProperty[property] = curve;
1891
+ }
1892
+ }
1893
+ const properties = Object.keys(byProperty);
1894
+ const targets = {};
1895
+ for (const property of properties) {
1896
+ const curve = byProperty[property];
1897
+ targets[property] = curve.at(curve.duration);
1898
+ }
1899
+ const plan = prefersReducedMotion() ? reducedMotion(owner, time, targets, properties, isCoarsePointer() || playOptions.touchRelease === true, playOptions.crossfadeAs) : null;
1900
+ const next = {
1901
+ ...plan?.next
1902
+ };
1903
+ for (const property of properties) {
1904
+ if (property in next) {
1905
+ continue;
1906
+ }
1907
+ const curve = byProperty[property];
1908
+ next[property] = curve.duration === 0 ? null : {
1909
+ start: time,
1910
+ duration: Math.min(MAX_DURATION_MS, curve.duration * 1000),
1911
+ target: targets[property],
1912
+ at: t => curve.at(t / 1000),
1913
+ speed: t => curve.velocity(t / 1000),
1914
+ jumps: [],
1915
+ owner
1916
+ };
1917
+ }
1918
+ const group = beginGroup(time, Object.keys(next), playOptions.at);
1919
+ const adopted = plan?.landing != null ? adoptLandings(plan.landing, Object.keys(next)) : null;
1920
+ const changed = [];
1921
+ for (const [property, segment] of Object.entries(next)) {
1922
+ interrupt(property, time);
1923
+ changed.push(property);
1924
+ if (segment == null) {
1925
+ // Read before the segment goes: valueAt falls back to resting.
1926
+ const value = plan?.holds[property] ?? targets[property] ?? valueAt(property, time);
1927
+ segments.delete(property);
1928
+ resting[property] = value;
1929
+ } else {
1930
+ segments.set(property, segment);
1931
+ }
1932
+ }
1933
+ commitCall(group, owner, changed, time);
1934
+ if (plan?.borrowed != null) {
1935
+ // The dip's own commit cleared it; the borrow lasts the dip.
1936
+ borrowedOpacity = plan.borrowed;
1937
+ }
1938
+ const handle = makeHandle(owner, changed, finished, time, group);
1939
+ if (plan?.landing != null) {
1940
+ scheduleLanding(owner, handle.started, plan.landing, adopted);
1941
+ }
1942
+ return handle;
1943
+ },
1944
+ decay(curves, decayOptions = {}) {
1945
+ syncPending();
1946
+ const time = decayOptions.at ?? now();
1947
+ // Under Reduce Motion only momentum keeps moving (DR2, DEC-2): a curve
1948
+ // that is a transition plays as `animate` does, a cross-fade or at once.
1949
+ const reduce = prefersReducedMotion();
1950
+ const transitions = {};
1951
+ for (const property of DECAY_PROPERTIES) {
1952
+ const curve = curves[property];
1953
+ if (reduce && curve?.isTransition === true) {
1954
+ transitions[property] = curve.at(curve.duration);
1955
+ }
1956
+ }
1957
+ const transitioned = Object.keys(transitions).length > 0 ? animator.animate(transitions, REDUCED_TRANSITION, {
1958
+ at: time,
1959
+ touchRelease: decayOptions.touchRelease
1960
+ }) : null;
1961
+ const {
1962
+ owner,
1963
+ finished
1964
+ } = newOwner();
1965
+ // Momentum moves the translate axes only (DR2's throw exception).
1966
+ const properties = DECAY_PROPERTIES.filter(property => curves[property] != null && transitions[property] === undefined);
1967
+ if (transitioned != null && properties.length === 0) {
1968
+ return transitioned;
1969
+ }
1970
+ const group = beginGroup(time, properties, decayOptions.at);
1971
+ for (const property of properties) {
1972
+ const curve = curves[property];
1973
+ interrupt(property, time);
1974
+ if (!(curve.duration > 0)) {
1975
+ segments.delete(property);
1976
+ resting[property] = curve.at(0);
1977
+ continue;
1978
+ }
1979
+ segments.set(property, {
1980
+ start: time,
1981
+ duration: Math.min(MAX_DURATION_MS, curve.duration * 1000),
1982
+ target: curve.at(curve.duration),
1983
+ at: t => curve.at(t / 1000),
1984
+ speed: t => curve.velocity(t / 1000),
1985
+ jumps: [],
1986
+ owner
1987
+ });
1988
+ }
1989
+ commitCall(group, owner, properties, time);
1990
+ const handle = makeHandle(owner, properties, finished, time, group);
1991
+ if (transitioned == null) {
1992
+ return handle;
1993
+ }
1994
+ // One handle for the whole release: the cross-faded axes too.
1995
+ const faded = transitioned;
1996
+ const owns = property => faded.properties.includes(property);
1997
+ return {
1998
+ ...handle,
1999
+ properties: [...handle.properties, ...faded.properties],
2000
+ started: Promise.all([handle.started, faded.started]).then(([coasting]) => coasting),
2001
+ finished: Promise.all([handle.finished, faded.finished]).then(([coasted, done]) => coasted && done),
2002
+ value: (property, at) => owns(property) ? faded.value(property, at) : handle.value(property, at),
2003
+ velocity: (property, at) => owns(property) ? faded.velocity(property, at) : handle.velocity(property, at),
2004
+ stop: () => {
2005
+ handle.stop();
2006
+ faded.stop();
2007
+ }
2008
+ };
2009
+ },
2010
+ stop(properties) {
2011
+ syncPending();
2012
+ const time = now();
2013
+ const list = properties == null ? PROPERTIES : expandList(properties);
2014
+ const changed = [];
2015
+ // A borrowed dip, or an exit by role that returns to the stylesheet.
2016
+ const wasBorrowed = borrowedOpacity != null || [...landings].some(landing => landing.restoreIsBorrowed === true);
2017
+ // Read before the landings go: a dip's fade back in, an exit's restore.
2018
+ const heading = opacityHeading();
2019
+ for (const property of list) {
2020
+ cancelLanding(property);
2021
+ const segment = segments.get(property);
2022
+ if (segment == null) {
2023
+ continue;
2024
+ }
2025
+ // A Reduce Motion fade is never left half done: it finishes, and a
2026
+ // dip on the stylesheet's opacity hands that opacity back.
2027
+ const value = !segment.isFade ? valueAt(property, time) : wasBorrowed ? IDENTITY.opacity : heading;
2028
+ interrupt(property, time);
2029
+ segments.delete(property);
2030
+ resting[property] = value;
2031
+ changed.push(property);
2032
+ }
2033
+ commit(changed, time);
2034
+ if (wasBorrowed && changed.includes('opacity')) {
2035
+ releaseOwnOpacity();
2036
+ }
2037
+ },
2038
+ rebase(deltas, rebaseOptions = {}) {
2039
+ syncPending();
2040
+ const time = rebaseOptions.at ?? now();
2041
+ const changed = [];
2042
+ const owners = new Set();
2043
+ for (const [property, delta] of Object.entries(expand(deltas))) {
2044
+ if (delta === 0) {
2045
+ continue;
2046
+ }
2047
+ changed.push(property);
2048
+ const segment = segmentAt(property, time);
2049
+ if (segment == null) {
2050
+ resting[property] = valueAt(property, time) + delta;
2051
+ segments.delete(property);
2052
+ continue;
2053
+ }
2054
+ owners.add(segment.owner);
2055
+ // A curve still waiting for the browser's start stays in its call:
2056
+ // it starts with that call's commit.
2057
+ const group = segment.group != null && !segment.group.resolved ? segment.group : undefined;
2058
+ const replace = next => {
2059
+ if (group != null) {
2060
+ const index = group.segments.indexOf(segment);
2061
+ if (index >= 0) {
2062
+ group.segments[index] = next;
2063
+ } else {
2064
+ group.segments.push(next);
2065
+ }
2066
+ }
2067
+ segments.set(property, next);
2068
+ };
2069
+ if (segment.spring != null) {
2070
+ const from = valueAt(property, time) + delta;
2071
+ const velocity = velocityAt(property, time);
2072
+ const curve = solveSpring(toSpring(segment.spring), {
2073
+ from,
2074
+ to: segment.target,
2075
+ velocity
2076
+ });
2077
+ replace({
2078
+ start: group?.provisional ?? time,
2079
+ ...(group != null ? {
2080
+ group
2081
+ } : {}),
2082
+ duration: Math.min(MAX_DURATION_MS, curve.settleTime(SETTLE_THRESHOLD[property]) * 1000),
2083
+ target: segment.target,
2084
+ at: t => curve.value(t / 1000),
2085
+ speed: t => curve.velocity(t / 1000),
2086
+ jumps: [],
2087
+ owner: segment.owner,
2088
+ spring: segment.spring
2089
+ });
2090
+ } else {
2091
+ replace({
2092
+ ...segment,
2093
+ target: segment.target + delta,
2094
+ at: t => segment.at(t) + delta
2095
+ });
2096
+ }
2097
+ }
2098
+ commit(changed, time);
2099
+ // The handles that own the rebased curves finish at their new ends.
2100
+ for (const owner of owners) {
2101
+ if (owner.settled || owner.timer == null) {
2102
+ continue;
2103
+ }
2104
+ clearTimeout(owner.timer);
2105
+ let end = time;
2106
+ for (const segment of segments.values()) {
2107
+ if (segment.owner === owner) {
2108
+ end = Math.max(end, segment.start + segment.duration);
2109
+ }
2110
+ }
2111
+ owner.timer = setTimeout(() => {
2112
+ owner.timer = null;
2113
+ settle(owner, true);
2114
+ }, Math.max(0, end - now()));
2115
+ }
2116
+ },
2117
+ async atRest(properties) {
2118
+ const list = properties == null ? PROPERTIES : expandList(properties);
2119
+ return new Promise(resolve => {
2120
+ const wait = {
2121
+ timer: null,
2122
+ settle: () => {}
2123
+ };
2124
+ const done = () => {
2125
+ if (wait.timer != null) {
2126
+ clearTimeout(wait.timer);
2127
+ }
2128
+ restWaits.delete(wait);
2129
+ resolve();
2130
+ };
2131
+ wait.settle = done;
2132
+ restWaits.add(wait);
2133
+ const check = () => {
2134
+ wait.timer = null;
2135
+ syncPending();
2136
+ const time = now();
2137
+ let end = time;
2138
+ for (const property of list) {
2139
+ const segment = segments.get(property);
2140
+ if (segment != null) {
2141
+ end = Math.max(end, segment.start + segment.duration);
2142
+ }
2143
+ }
2144
+ if (landings.size > 0) {
2145
+ // A Reduced Motion landing is still to come.
2146
+ wait.timer = setTimeout(check, 16);
2147
+ } else if (end <= time) {
2148
+ done();
2149
+ } else {
2150
+ // A retarget or a later start moves the end: look again then.
2151
+ wait.timer = setTimeout(check, end - time);
2152
+ }
2153
+ };
2154
+ check();
2155
+ });
2156
+ },
2157
+ dispose() {
2158
+ // A Reduce Motion move still waiting to land is written at its end
2159
+ // state, so the element is left visible where it was going (the node
2160
+ // just detached, when an unmount is pending); its call and the calls
2161
+ // it carries settle as interrupted.
2162
+ if (target == null && unmountQueued) {
2163
+ target = lastDetached;
2164
+ }
2165
+ lastDetached = null;
2166
+ unmountQueued = false;
2167
+ landPending(false);
2168
+ // Nothing moves any more: every atRest() wait settles.
2169
+ for (const wait of [...restWaits]) {
2170
+ wait.settle();
2171
+ }
2172
+ const time = now();
2173
+ for (const property of PROPERTIES) {
2174
+ interrupt(property, time);
2175
+ }
2176
+ for (const animation of running.values()) {
2177
+ animation.cancel();
2178
+ }
2179
+ running.clear();
2180
+ for (const timer of retireTimers.values()) {
2181
+ clearTimeout(timer);
2182
+ }
2183
+ retireTimers.clear();
2184
+ handBackBorrow();
2185
+ demote();
2186
+ target = null;
2187
+ }
2188
+ };
2189
+ animator.attach(element);
2190
+ return animator;
2191
+ }
2192
+ function expandList(properties) {
2193
+ const out = new Set();
2194
+ for (const property of properties) {
2195
+ if (property === 'scale') {
2196
+ out.add('scaleX');
2197
+ out.add('scaleY');
2198
+ } else {
2199
+ out.add(property);
2200
+ }
2201
+ }
2202
+ return [...out];
2203
+ }