@astryxdesign/core 0.7.4 → 0.7.5-canary.0418c47

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 (1568) hide show
  1. package/README.md +12 -9
  2. package/dist/AlertDialog/AlertDialog.d.ts +2 -2
  3. package/dist/AlertDialog/AlertDialog.js +1 -1
  4. package/dist/AlertDialog/index.d.ts +4 -4
  5. package/dist/AlertDialog/useImperativeAlertDialog.d.ts +1 -1
  6. package/dist/AppShell/AppShell.d.ts +4 -4
  7. package/dist/AppShell/index.d.ts +4 -4
  8. package/dist/AspectRatio/AspectRatio.d.ts +1 -1
  9. package/dist/AspectRatio/index.d.ts +2 -2
  10. package/dist/Avatar/Avatar.d.ts +2 -2
  11. package/dist/Avatar/AvatarStatusDot.d.ts +2 -2
  12. package/dist/Avatar/AvatarStatusDot.js +2 -2
  13. package/dist/Avatar/index.d.ts +4 -4
  14. package/dist/AvatarGroup/AvatarGroup.d.ts +2 -2
  15. package/dist/AvatarGroup/AvatarGroupContext.d.ts +1 -1
  16. package/dist/AvatarGroup/AvatarGroupOverflow.d.ts +1 -1
  17. package/dist/AvatarGroup/index.d.ts +6 -6
  18. package/dist/Badge/Badge.d.ts +2 -2
  19. package/dist/Badge/Badge.d.ts.map +1 -1
  20. package/dist/Badge/Badge.js +18 -2
  21. package/dist/Badge/index.d.ts +2 -2
  22. package/dist/Banner/Banner.d.ts +5 -4
  23. package/dist/Banner/Banner.d.ts.map +1 -1
  24. package/dist/Banner/Banner.js +64 -9
  25. package/dist/Banner/index.d.ts +2 -2
  26. package/dist/Blockquote/Blockquote.d.ts +1 -1
  27. package/dist/Blockquote/index.d.ts +2 -2
  28. package/dist/BottomSheet/BottomSheet.d.ts +58 -10
  29. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  30. package/dist/BottomSheet/BottomSheet.js +435 -198
  31. package/dist/BottomSheet/BottomSheetHostContext.d.ts +8 -0
  32. package/dist/BottomSheet/BottomSheetHostContext.d.ts.map +1 -0
  33. package/dist/BottomSheet/BottomSheetHostContext.js +35 -0
  34. package/dist/BottomSheet/BottomSheetPanel.d.ts +12 -4
  35. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  36. package/dist/BottomSheet/BottomSheetPanel.js +76 -22
  37. package/dist/BottomSheet/BottomSheetSwitcher.d.ts +54 -15
  38. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  39. package/dist/BottomSheet/BottomSheetSwitcher.js +229 -27
  40. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts +8 -2
  41. package/dist/BottomSheet/BottomSheetSwitcherContext.d.ts.map +1 -1
  42. package/dist/BottomSheet/bottomSheetEscape.d.ts +3 -0
  43. package/dist/BottomSheet/bottomSheetEscape.d.ts.map +1 -0
  44. package/dist/BottomSheet/bottomSheetEscape.js +20 -0
  45. package/dist/BottomSheet/bottomSheetStack.d.ts +262 -0
  46. package/dist/BottomSheet/bottomSheetStack.d.ts.map +1 -0
  47. package/dist/BottomSheet/bottomSheetStack.js +1652 -0
  48. package/dist/BottomSheet/index.d.ts +4 -4
  49. package/dist/BottomSheet/useSheetGestures.d.ts +19 -3
  50. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  51. package/dist/BottomSheet/useSheetGestures.js +43 -14
  52. package/dist/Breadcrumbs/BreadcrumbItem.d.ts +4 -4
  53. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  54. package/dist/Breadcrumbs/BreadcrumbItem.js +5 -0
  55. package/dist/Breadcrumbs/Breadcrumbs.d.ts +2 -2
  56. package/dist/Breadcrumbs/index.d.ts +12 -12
  57. package/dist/Button/Button.d.ts +4 -4
  58. package/dist/Button/Button.d.ts.map +1 -1
  59. package/dist/Button/Button.js +18 -7
  60. package/dist/Button/index.d.ts +2 -2
  61. package/dist/ButtonGroup/ButtonGroup.d.ts +4 -4
  62. package/dist/ButtonGroup/index.d.ts +4 -4
  63. package/dist/Calendar/Calendar.d.ts +3 -3
  64. package/dist/Calendar/dayCellUtils.d.ts +1 -1
  65. package/dist/Calendar/getInitialFocusDate.d.ts +2 -2
  66. package/dist/Calendar/getStandaloneShortWeekdayNames.d.ts +1 -1
  67. package/dist/Calendar/hooks/index.d.ts +6 -6
  68. package/dist/Calendar/hooks/useCalendarConstraints.d.ts +2 -2
  69. package/dist/Calendar/hooks/useCalendarDays.d.ts +2 -2
  70. package/dist/Calendar/hooks/useCalendarNavigation.d.ts +2 -2
  71. package/dist/Calendar/index.d.ts +5 -5
  72. package/dist/Calendar/utils.d.ts +1 -1
  73. package/dist/Card/Card.d.ts +4 -4
  74. package/dist/Card/index.d.ts +2 -2
  75. package/dist/Carousel/Carousel.d.ts +2 -2
  76. package/dist/Carousel/index.d.ts +2 -2
  77. package/dist/Center/Center.d.ts +2 -2
  78. package/dist/Center/index.d.ts +2 -2
  79. package/dist/Chat/ChatComposer.d.ts +1 -1
  80. package/dist/Chat/ChatComposer.d.ts.map +1 -1
  81. package/dist/Chat/ChatComposer.js +25 -32
  82. package/dist/Chat/ChatComposerDrawer.d.ts +1 -1
  83. package/dist/Chat/ChatComposerInput.d.ts +4 -4
  84. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  85. package/dist/Chat/ChatComposerInput.js +55 -16
  86. package/dist/Chat/ChatDictationButton.d.ts +2 -2
  87. package/dist/Chat/ChatLayout.d.ts +1 -1
  88. package/dist/Chat/ChatLayoutScrollButton.d.ts +1 -1
  89. package/dist/Chat/ChatMessage.d.ts +2 -2
  90. package/dist/Chat/ChatMessageBubble.d.ts +2 -2
  91. package/dist/Chat/ChatMessageList.d.ts +3 -3
  92. package/dist/Chat/ChatMessageMetadata.d.ts +1 -1
  93. package/dist/Chat/ChatMessageMetadata.js +2 -2
  94. package/dist/Chat/ChatPastedTextToken.d.ts.map +1 -1
  95. package/dist/Chat/ChatPastedTextToken.js +7 -6
  96. package/dist/Chat/ChatSendButton.d.ts +1 -1
  97. package/dist/Chat/ChatSystemMessage.d.ts +1 -1
  98. package/dist/Chat/ChatTokenizedText.d.ts +2 -2
  99. package/dist/Chat/ChatToolCalls.d.ts +1 -1
  100. package/dist/Chat/ChatToolCalls.js +4 -4
  101. package/dist/Chat/index.d.ts +43 -43
  102. package/dist/Chat/useChatComposerTokens.d.ts +1 -1
  103. package/dist/Chat/useChatDictation.d.ts +1 -1
  104. package/dist/Chat/useChatPasteAsToken.d.ts +1 -1
  105. package/dist/Chat/useTriggerMenu.d.ts +2 -2
  106. package/dist/CheckboxInput/CheckboxInput.d.ts +4 -4
  107. package/dist/CheckboxInput/index.d.ts +2 -2
  108. package/dist/CheckboxList/CheckboxList.d.ts +4 -4
  109. package/dist/CheckboxList/CheckboxListItem.d.ts +2 -2
  110. package/dist/CheckboxList/index.d.ts +4 -4
  111. package/dist/Citation/Citation.d.ts +1 -1
  112. package/dist/Citation/index.d.ts +2 -2
  113. package/dist/ClickableCard/ClickableCard.d.ts +3 -3
  114. package/dist/ClickableCard/ClickableCard.d.ts.map +1 -1
  115. package/dist/ClickableCard/ClickableCard.js +10 -6
  116. package/dist/ClickableCard/index.d.ts +2 -2
  117. package/dist/Code/Code.d.ts +1 -1
  118. package/dist/Code/index.d.ts +1 -1
  119. package/dist/CodeBlock/CodeBlock.d.ts +27 -4
  120. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  121. package/dist/CodeBlock/CodeBlock.js +58 -19
  122. package/dist/CodeBlock/grammar.d.ts +134 -0
  123. package/dist/CodeBlock/grammar.d.ts.map +1 -0
  124. package/dist/CodeBlock/grammar.js +219 -0
  125. package/dist/CodeBlock/highlightRanges.d.ts +1 -1
  126. package/dist/CodeBlock/index.d.ts +10 -8
  127. package/dist/CodeBlock/index.d.ts.map +1 -1
  128. package/dist/CodeBlock/index.js +1 -0
  129. package/dist/CodeBlock/languages/dockerfile.d.ts +3 -0
  130. package/dist/CodeBlock/languages/dockerfile.d.ts.map +1 -0
  131. package/dist/CodeBlock/languages/dockerfile.js +45 -0
  132. package/dist/CodeBlock/languages/graphql.d.ts +3 -0
  133. package/dist/CodeBlock/languages/graphql.d.ts.map +1 -0
  134. package/dist/CodeBlock/languages/graphql.js +27 -0
  135. package/dist/CodeBlock/languages/java.d.ts +3 -0
  136. package/dist/CodeBlock/languages/java.d.ts.map +1 -0
  137. package/dist/CodeBlock/languages/java.js +24 -0
  138. package/dist/CodeBlock/languages/lua.d.ts +3 -0
  139. package/dist/CodeBlock/languages/lua.d.ts.map +1 -0
  140. package/dist/CodeBlock/languages/lua.js +21 -0
  141. package/dist/CodeBlock/languages/objective-c.d.ts +3 -0
  142. package/dist/CodeBlock/languages/objective-c.d.ts.map +1 -0
  143. package/dist/CodeBlock/languages/objective-c.js +27 -0
  144. package/dist/CodeBlock/languages/powershell.d.ts +3 -0
  145. package/dist/CodeBlock/languages/powershell.d.ts.map +1 -0
  146. package/dist/CodeBlock/languages/powershell.js +30 -0
  147. package/dist/CodeBlock/languages/ruby.d.ts +3 -0
  148. package/dist/CodeBlock/languages/ruby.d.ts.map +1 -0
  149. package/dist/CodeBlock/languages/ruby.js +24 -0
  150. package/dist/CodeBlock/languages/thrift.d.ts +3 -0
  151. package/dist/CodeBlock/languages/thrift.d.ts.map +1 -0
  152. package/dist/CodeBlock/languages/thrift.js +18 -0
  153. package/dist/CodeBlock/languages/toml.d.ts +3 -0
  154. package/dist/CodeBlock/languages/toml.d.ts.map +1 -0
  155. package/dist/CodeBlock/languages/toml.js +53 -0
  156. package/dist/CodeBlock/tokenizer.d.ts +8 -4
  157. package/dist/CodeBlock/tokenizer.d.ts.map +1 -1
  158. package/dist/CodeBlock/tokenizer.js +158 -8
  159. package/dist/Collapsible/Collapsible.d.ts +10 -3
  160. package/dist/Collapsible/Collapsible.d.ts.map +1 -1
  161. package/dist/Collapsible/Collapsible.js +84 -2
  162. package/dist/Collapsible/CollapsibleGroup.d.ts +2 -2
  163. package/dist/Collapsible/index.d.ts +7 -7
  164. package/dist/CommandPalette/CommandPalette.d.ts +2 -2
  165. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  166. package/dist/CommandPalette/CommandPalette.js +15 -1
  167. package/dist/CommandPalette/CommandPaletteContext.d.ts +1 -1
  168. package/dist/CommandPalette/CommandPaletteEmpty.d.ts +1 -1
  169. package/dist/CommandPalette/CommandPaletteEmpty.d.ts.map +1 -1
  170. package/dist/CommandPalette/CommandPaletteEmpty.js +1 -0
  171. package/dist/CommandPalette/CommandPaletteFooter.d.ts +1 -1
  172. package/dist/CommandPalette/CommandPaletteGroup.d.ts +1 -1
  173. package/dist/CommandPalette/CommandPaletteInput.d.ts +1 -1
  174. package/dist/CommandPalette/CommandPaletteInput.d.ts.map +1 -1
  175. package/dist/CommandPalette/CommandPaletteInput.js +14 -2
  176. package/dist/CommandPalette/CommandPaletteItem.d.ts +1 -1
  177. package/dist/CommandPalette/CommandPaletteList.d.ts +1 -1
  178. package/dist/CommandPalette/busyStartSettle.d.ts +4 -0
  179. package/dist/CommandPalette/busyStartSettle.d.ts.map +1 -0
  180. package/dist/CommandPalette/busyStartSettle.js +23 -0
  181. package/dist/CommandPalette/index.d.ts +16 -16
  182. package/dist/ComplexSelector/ComplexSelector.d.ts +25 -7
  183. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  184. package/dist/ComplexSelector/ComplexSelector.js +42 -7
  185. package/dist/ComplexSelector/index.d.ts +1 -1
  186. package/dist/ContextMenu/ContextMenu.d.ts +4 -4
  187. package/dist/ContextMenu/ContextMenu.d.ts.map +1 -1
  188. package/dist/ContextMenu/ContextMenu.js +48 -13
  189. package/dist/ContextMenu/index.d.ts +9 -9
  190. package/dist/DateInput/DateInput.d.ts +7 -7
  191. package/dist/DateInput/DateInput.d.ts.map +1 -1
  192. package/dist/DateInput/DateInput.js +12 -5
  193. package/dist/DateInput/MonthScroller.d.ts +1 -1
  194. package/dist/DateInput/NativeDateField.d.ts +1 -1
  195. package/dist/DateInput/NativeDateField.d.ts.map +1 -1
  196. package/dist/DateInput/NativeDateField.js +2 -1
  197. package/dist/DateInput/TouchDateField.d.ts +1 -1
  198. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  199. package/dist/DateInput/TouchDateField.js +2 -1
  200. package/dist/DateInput/Wheel.d.ts.map +1 -1
  201. package/dist/DateInput/Wheel.js +1 -1
  202. package/dist/DateInput/index.d.ts +2 -2
  203. package/dist/DateInput/monthGeometry.d.ts +1 -1
  204. package/dist/DateRangeInput/DateRangeInput.d.ts +6 -6
  205. package/dist/DateRangeInput/index.d.ts +2 -2
  206. package/dist/DateTimeInput/DateTimeInput.d.ts +6 -6
  207. package/dist/DateTimeInput/NativeDateSegment.d.ts +3 -3
  208. package/dist/DateTimeInput/NativeTimeSegment.d.ts +4 -4
  209. package/dist/DateTimeInput/TouchDateTimeField.d.ts +1 -1
  210. package/dist/DateTimeInput/index.d.ts +2 -2
  211. package/dist/Dialog/Dialog.d.ts +7 -3
  212. package/dist/Dialog/Dialog.d.ts.map +1 -1
  213. package/dist/Dialog/Dialog.js +20 -8
  214. package/dist/Dialog/DialogHeader.d.ts +1 -1
  215. package/dist/Dialog/index.d.ts +6 -6
  216. package/dist/Dialog/useImperativeDialog.d.ts +1 -1
  217. package/dist/Divider/Divider.d.ts +2 -2
  218. package/dist/Divider/index.d.ts +2 -2
  219. package/dist/Drawer/Drawer.d.ts +3 -3
  220. package/dist/Drawer/Drawer.d.ts.map +1 -1
  221. package/dist/Drawer/Drawer.js +18 -13
  222. package/dist/Drawer/DrawerHeader.d.ts +1 -1
  223. package/dist/Drawer/index.d.ts +4 -4
  224. package/dist/DropdownMenu/DropdownMenu.d.ts +5 -5
  225. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  226. package/dist/DropdownMenu/DropdownMenu.js +32 -20
  227. package/dist/DropdownMenu/DropdownMenuCheckboxItem.d.ts +2 -2
  228. package/dist/DropdownMenu/DropdownMenuDivider.d.ts +1 -1
  229. package/dist/DropdownMenu/DropdownMenuGroup.d.ts +1 -1
  230. package/dist/DropdownMenu/DropdownMenuItem.d.ts +2 -2
  231. package/dist/DropdownMenu/DropdownMenuItem.js +3 -3
  232. package/dist/DropdownMenu/DropdownMenuRadioGroup.d.ts +1 -1
  233. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts +12 -7
  234. package/dist/DropdownMenu/DropdownMenuRadioItem.d.ts.map +1 -1
  235. package/dist/DropdownMenu/DropdownMenuRadioItem.js +13 -5
  236. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts +8 -8
  237. package/dist/DropdownMenu/DropdownMenuSubMenu.d.ts.map +1 -1
  238. package/dist/DropdownMenu/DropdownMenuSubMenu.js +0 -3
  239. package/dist/DropdownMenu/MenuBottomSheet.d.ts +11 -4
  240. package/dist/DropdownMenu/MenuBottomSheet.d.ts.map +1 -1
  241. package/dist/DropdownMenu/MenuBottomSheet.js +35 -9
  242. package/dist/DropdownMenu/MenuBottomSheetActionList.d.ts +1 -1
  243. package/dist/DropdownMenu/MenuBottomSheetActionList.js +3 -3
  244. package/dist/DropdownMenu/index.d.ts +10 -10
  245. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts +4 -2
  246. package/dist/DropdownMenu/lazyMenuBottomSheet.d.ts.map +1 -1
  247. package/dist/DropdownMenu/lazyMenuBottomSheet.js +25 -3
  248. package/dist/DropdownMenu/menuBottomSheet.stylex.d.ts +23 -0
  249. package/dist/DropdownMenu/menuBottomSheet.stylex.d.ts.map +1 -0
  250. package/dist/DropdownMenu/menuBottomSheet.stylex.js +29 -0
  251. package/dist/DropdownMenu/menuItemHover.d.ts +3 -0
  252. package/dist/DropdownMenu/menuItemHover.d.ts.map +1 -1
  253. package/dist/DropdownMenu/menuItemHover.js +14 -1
  254. package/dist/DropdownMenu/renderDropdownItems.d.ts +1 -1
  255. package/dist/DropdownMenu/useMenuDrillIn.d.ts +1 -1
  256. package/dist/DropdownMenu/useMenuDrillIn.d.ts.map +1 -1
  257. package/dist/DropdownMenu/useMenuDrillIn.js +7 -5
  258. package/dist/EmptyState/EmptyState.d.ts +5 -3
  259. package/dist/EmptyState/EmptyState.d.ts.map +1 -1
  260. package/dist/EmptyState/EmptyState.js +6 -4
  261. package/dist/EmptyState/index.d.ts +2 -2
  262. package/dist/Field/Field.d.ts +5 -5
  263. package/dist/Field/Field.js +1 -1
  264. package/dist/Field/FieldLabel.d.ts +2 -2
  265. package/dist/Field/FieldLabel.js +1 -1
  266. package/dist/Field/PanelSearchInput.d.ts +10 -2
  267. package/dist/Field/PanelSearchInput.d.ts.map +1 -1
  268. package/dist/Field/PanelSearchInput.js +31 -22
  269. package/dist/Field/fieldInputFamily.testing.d.ts +1 -1
  270. package/dist/Field/fieldParts.d.ts +1 -1
  271. package/dist/Field/index.d.ts +10 -10
  272. package/dist/Field/inputDisabledFocus.d.ts +14 -0
  273. package/dist/Field/inputDisabledFocus.d.ts.map +1 -0
  274. package/dist/Field/inputDisabledFocus.js +19 -0
  275. package/dist/Field/inputStyles.stylex.d.ts +9 -9
  276. package/dist/Field/inputStyles.stylex.js +9 -9
  277. package/dist/FieldStatus/FieldStatus.d.ts +3 -3
  278. package/dist/FieldStatus/FieldStatus.d.ts.map +1 -1
  279. package/dist/FieldStatus/FieldStatus.js +7 -3
  280. package/dist/FieldStatus/index.d.ts +2 -2
  281. package/dist/FieldStatus/useFieldStatusAnnouncement.d.ts +1 -1
  282. package/dist/FileInput/FileInput.d.ts +4 -4
  283. package/dist/FileInput/FileInput.d.ts.map +1 -1
  284. package/dist/FileInput/FileInput.js +15 -9
  285. package/dist/FileInput/index.d.ts +2 -2
  286. package/dist/FormLayout/FormLayout.d.ts +2 -2
  287. package/dist/FormLayout/index.d.ts +4 -4
  288. package/dist/Grid/Grid.d.ts +3 -3
  289. package/dist/Grid/GridSpan.d.ts +1 -1
  290. package/dist/Grid/index.d.ts +4 -4
  291. package/dist/HStack/HStack.d.ts +2 -2
  292. package/dist/HStack/index.d.ts +1 -1
  293. package/dist/Heading/Heading.d.ts +4 -4
  294. package/dist/Heading/index.d.ts +1 -1
  295. package/dist/HoverCard/HoverCard.d.ts +4 -4
  296. package/dist/HoverCard/index.d.ts +4 -4
  297. package/dist/HoverCard/useHoverCard.d.ts +2 -2
  298. package/dist/Icon/Icon.d.ts +18 -6
  299. package/dist/Icon/Icon.d.ts.map +1 -1
  300. package/dist/Icon/Icon.js +55 -9
  301. package/dist/Icon/IconDefaultSizeContext.d.ts +1 -1
  302. package/dist/Icon/IconSize.stylex.d.ts +16 -11
  303. package/dist/Icon/IconSize.stylex.d.ts.map +1 -1
  304. package/dist/Icon/IconSize.stylex.js +27 -11
  305. package/dist/Icon/defaultIcons.d.ts +1 -1
  306. package/dist/Icon/globalIconRegistry.d.ts +69 -5
  307. package/dist/Icon/globalIconRegistry.d.ts.map +1 -1
  308. package/dist/Icon/globalIconRegistry.js +108 -24
  309. package/dist/Icon/index.d.ts +30 -6
  310. package/dist/Icon/index.d.ts.map +1 -1
  311. package/dist/Icon/index.js +24 -1
  312. package/dist/Icon/useIcon.d.ts +6 -2
  313. package/dist/Icon/useIcon.d.ts.map +1 -1
  314. package/dist/Icon/useIcon.js +5 -1
  315. package/dist/IconButton/IconButton.d.ts +1 -1
  316. package/dist/IconButton/index.d.ts +2 -2
  317. package/dist/Indicator/CheckIndicator.d.ts +1 -1
  318. package/dist/Indicator/CheckboxIndicator.d.ts +1 -1
  319. package/dist/Indicator/RadioIndicator.d.ts +1 -1
  320. package/dist/Indicator/index.d.ts +8 -8
  321. package/dist/Indicator/indicatorRegistry.d.ts +2 -2
  322. package/dist/Indicator/types.d.ts +1 -1
  323. package/dist/Indicator/useIndicator.d.ts +2 -2
  324. package/dist/InputGroup/InputGroup.d.ts +3 -3
  325. package/dist/InputGroup/InputGroup.d.ts.map +1 -1
  326. package/dist/InputGroup/InputGroup.js +46 -36
  327. package/dist/InputGroup/InputGroupInternalContext.d.ts +4 -0
  328. package/dist/InputGroup/InputGroupInternalContext.d.ts.map +1 -0
  329. package/dist/InputGroup/InputGroupInternalContext.js +15 -0
  330. package/dist/InputGroup/InputGroupText.d.ts +1 -1
  331. package/dist/InputGroup/InputGroupText.d.ts.map +1 -1
  332. package/dist/InputGroup/InputGroupText.js +2 -0
  333. package/dist/InputGroup/groupStyles.d.ts +9 -0
  334. package/dist/InputGroup/groupStyles.d.ts.map +1 -1
  335. package/dist/InputGroup/groupStyles.js +28 -14
  336. package/dist/InputGroup/index.d.ts +6 -6
  337. package/dist/InteractiveRoleContext/InteractiveRoleContext.d.ts +1 -1
  338. package/dist/InteractiveRoleContext/index.d.ts +1 -1
  339. package/dist/Item/Item.d.ts +1 -1
  340. package/dist/Item/Item.d.ts.map +1 -1
  341. package/dist/Item/Item.js +1 -1
  342. package/dist/Item/ItemSwipeLayer.d.ts +2 -2
  343. package/dist/Item/ItemSwipeLayer.d.ts.map +1 -1
  344. package/dist/Item/ItemSwipeLayer.js +3 -0
  345. package/dist/Item/index.d.ts +2 -2
  346. package/dist/Item/useSwipeAction.d.ts.map +1 -1
  347. package/dist/Item/useSwipeAction.js +60 -5
  348. package/dist/Kbd/Kbd.d.ts +3 -3
  349. package/dist/Kbd/Kbd.d.ts.map +1 -1
  350. package/dist/Kbd/Kbd.js +18 -11
  351. package/dist/Kbd/index.d.ts +2 -2
  352. package/dist/Layer/LayerProvider.d.ts +1 -1
  353. package/dist/Layer/index.d.ts +18 -18
  354. package/dist/Layer/layerAnimations.stylex.d.ts +9 -5
  355. package/dist/Layer/layerAnimations.stylex.d.ts.map +1 -1
  356. package/dist/Layer/layerAnimations.stylex.js +23 -10
  357. package/dist/Layer/layerInset.d.ts +1 -1
  358. package/dist/Layer/layerSlideRules.d.ts +63 -3
  359. package/dist/Layer/layerSlideRules.d.ts.map +1 -1
  360. package/dist/Layer/layerSlideRules.js +124 -3
  361. package/dist/Layer/layerStack.d.ts +12 -9
  362. package/dist/Layer/layerStack.d.ts.map +1 -1
  363. package/dist/Layer/layerStack.js +116 -53
  364. package/dist/Layer/modalOutlet.d.ts +44 -6
  365. package/dist/Layer/modalOutlet.d.ts.map +1 -1
  366. package/dist/Layer/modalOutlet.js +150 -14
  367. package/dist/Layer/preserveAnimations.d.ts +11 -0
  368. package/dist/Layer/preserveAnimations.d.ts.map +1 -0
  369. package/dist/Layer/preserveAnimations.js +245 -0
  370. package/dist/Layer/useLayer.d.ts +19 -2
  371. package/dist/Layer/useLayer.d.ts.map +1 -1
  372. package/dist/Layer/useLayer.js +500 -43
  373. package/dist/Layer/useLayerDismissal.d.ts +11 -8
  374. package/dist/Layer/useLayerDismissal.d.ts.map +1 -1
  375. package/dist/Layer/useLayerDismissal.js +8 -8
  376. package/dist/Layer/useTouchTrigger.d.ts +14 -1
  377. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  378. package/dist/Layer/useTouchTrigger.js +72 -17
  379. package/dist/Layout/Layout.d.ts +2 -2
  380. package/dist/Layout/Layout.d.ts.map +1 -1
  381. package/dist/Layout/Layout.js +4 -0
  382. package/dist/Layout/LayoutContent.d.ts +2 -2
  383. package/dist/Layout/LayoutContent.d.ts.map +1 -1
  384. package/dist/Layout/LayoutContent.js +2 -2
  385. package/dist/Layout/LayoutFooter.d.ts +2 -2
  386. package/dist/Layout/LayoutFooter.d.ts.map +1 -1
  387. package/dist/Layout/LayoutFooter.js +2 -1
  388. package/dist/Layout/LayoutHeader.d.ts +2 -2
  389. package/dist/Layout/LayoutHeader.d.ts.map +1 -1
  390. package/dist/Layout/LayoutHeader.js +2 -1
  391. package/dist/Layout/LayoutPanel.d.ts +3 -3
  392. package/dist/Layout/index.d.ts +29 -29
  393. package/dist/Layout/layoutEdges.stylex.d.ts +20 -0
  394. package/dist/Layout/layoutEdges.stylex.d.ts.map +1 -0
  395. package/dist/Layout/layoutEdges.stylex.js +28 -0
  396. package/dist/Layout/padding.stylex.d.ts +1 -1
  397. package/dist/Lightbox/Lightbox.d.ts +6 -3
  398. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  399. package/dist/Lightbox/Lightbox.js +111 -89
  400. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts +2 -0
  401. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.d.ts.map +1 -0
  402. package/dist/Lightbox/LightboxKeyboard.a11y.browser.spec.js +78 -0
  403. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts +2 -0
  404. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.d.ts.map +1 -0
  405. package/dist/Lightbox/LightboxViewport.a11y.browser.spec.js +65 -0
  406. package/dist/Lightbox/index.d.ts +4 -4
  407. package/dist/Lightbox/useLightbox.d.ts +1 -1
  408. package/dist/Link/Link.d.ts +3 -3
  409. package/dist/Link/LinkContext.d.ts +1 -1
  410. package/dist/Link/LinkProvider.d.ts +1 -1
  411. package/dist/Link/index.d.ts +8 -8
  412. package/dist/Link/useLinkComponent.d.ts +1 -1
  413. package/dist/List/List.d.ts +3 -3
  414. package/dist/List/ListItem.d.ts +2 -2
  415. package/dist/List/index.d.ts +4 -4
  416. package/dist/Markdown/Markdown.d.ts +15 -5
  417. package/dist/Markdown/Markdown.d.ts.map +1 -1
  418. package/dist/Markdown/Markdown.fr23.bench.js +3 -1
  419. package/dist/Markdown/Markdown.fr23.sampling.d.ts +16 -0
  420. package/dist/Markdown/Markdown.fr23.sampling.d.ts.map +1 -1
  421. package/dist/Markdown/Markdown.fr23.sampling.js +13 -4
  422. package/dist/Markdown/Markdown.js +23 -9
  423. package/dist/Markdown/MarkdownTable.a11y.chromium.spec.js +1 -0
  424. package/dist/Markdown/headingProjection.d.ts +3 -3
  425. package/dist/Markdown/index.d.ts +7 -7
  426. package/dist/Markdown/parser/index.d.ts +3 -3
  427. package/dist/Markdown/parser.d.ts +3 -3
  428. package/dist/Markdown/plugin-renderer/MarkdownPluginNodeRenderer.d.ts +1 -1
  429. package/dist/Markdown/plugin-renderer/index.d.ts +2 -2
  430. package/dist/Markdown/plugins/frontmatter.d.ts +2 -2
  431. package/dist/Markdown/plugins/headingLinks.d.ts +2 -2
  432. package/dist/Markdown/plugins/index.d.ts +14 -14
  433. package/dist/Markdown/plugins/protocol.d.ts +1 -1
  434. package/dist/Markdown/plugins/semanticFence.d.ts +2 -2
  435. package/dist/Markdown/plugins/softBreaks.d.ts +1 -1
  436. package/dist/Markdown/plugins/sourceDecoration.d.ts +2 -2
  437. package/dist/Markdown/plugins/sourceLines.d.ts +1 -1
  438. package/dist/Markdown/plugins/textTransform.d.ts +2 -2
  439. package/dist/Markdown/remark.d.ts +1 -1
  440. package/dist/Markdown/utils.d.ts +4 -4
  441. package/dist/MetadataList/MetadataList.d.ts +2 -2
  442. package/dist/MetadataList/MetadataListItem.d.ts +1 -1
  443. package/dist/MetadataList/index.d.ts +5 -5
  444. package/dist/MobileNav/MobileNav.d.ts +3 -2
  445. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  446. package/dist/MobileNav/MobileNav.js +46 -37
  447. package/dist/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.js +1 -0
  448. package/dist/MobileNav/MobileNavToggle.d.ts +1 -1
  449. package/dist/MobileNav/index.d.ts +4 -4
  450. package/dist/MoreMenu/MoreMenu.d.ts +4 -4
  451. package/dist/MoreMenu/index.d.ts +1 -1
  452. package/dist/MultiSelector/CreateRow.a11y.chromium.spec.js +1 -0
  453. package/dist/MultiSelector/MultiSelector.d.ts +8 -8
  454. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  455. package/dist/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.js +1 -0
  456. package/dist/MultiSelector/MultiSelector.js +21 -5
  457. package/dist/MultiSelector/OptionActions.a11y.chromium.spec.js +1 -0
  458. package/dist/MultiSelector/hooks.d.ts +1 -1
  459. package/dist/MultiSelector/index.d.ts +3 -3
  460. package/dist/MultiSelector/types.d.ts +1 -1
  461. package/dist/NavIcon/NavIcon.d.ts +1 -1
  462. package/dist/NavIcon/index.d.ts +2 -2
  463. package/dist/NavMenu/NavHeadingMenu.d.ts +2 -2
  464. package/dist/NavMenu/NavHeadingMenuItem.d.ts +2 -2
  465. package/dist/NavMenu/NavHeadingMenuItem.d.ts.map +1 -1
  466. package/dist/NavMenu/NavHeadingMenuItem.js +46 -7
  467. package/dist/NavMenu/index.d.ts +6 -6
  468. package/dist/NumberInput/NumberInput.d.ts +9 -9
  469. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  470. package/dist/NumberInput/NumberInput.js +61 -24
  471. package/dist/NumberInput/index.d.ts +2 -2
  472. package/dist/NumberInput/numberInputCommit.d.ts +1 -1
  473. package/dist/NumberInput/numberParser.d.ts +1 -1
  474. package/dist/Outline/Outline.d.ts +3 -3
  475. package/dist/Outline/index.d.ts +7 -7
  476. package/dist/Outline/parseOutlineFromMarkdown.d.ts +2 -2
  477. package/dist/Outline/useOutlineFromDOM.d.ts +1 -1
  478. package/dist/Outline/useOutlineFromMarkdown.d.ts +3 -3
  479. package/dist/Outline/useScrollSpy.d.ts +1 -1
  480. package/dist/OverflowList/OverflowList.d.ts +2 -2
  481. package/dist/OverflowList/index.d.ts +2 -2
  482. package/dist/Overlay/Overlay.d.ts +2 -2
  483. package/dist/Overlay/index.d.ts +5 -5
  484. package/dist/Overlay/useOverlay.d.ts +1 -1
  485. package/dist/Pagination/Pagination.d.ts +2 -2
  486. package/dist/Pagination/index.d.ts +2 -2
  487. package/dist/Popover/Popover.d.ts +44 -5
  488. package/dist/Popover/Popover.d.ts.map +1 -1
  489. package/dist/Popover/Popover.js +276 -44
  490. package/dist/Popover/index.d.ts +4 -4
  491. package/dist/Popover/index.d.ts.map +1 -1
  492. package/dist/Popover/lazyPopoverBottomSheet.d.ts +23 -0
  493. package/dist/Popover/lazyPopoverBottomSheet.d.ts.map +1 -0
  494. package/dist/Popover/lazyPopoverBottomSheet.js +40 -0
  495. package/dist/Popover/usePopover.d.ts +2 -2
  496. package/dist/Popover/usePopover.d.ts.map +1 -1
  497. package/dist/Popover/usePopover.js +11 -5
  498. package/dist/PowerSearch/PowerSearch.d.ts +5 -5
  499. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  500. package/dist/PowerSearch/PowerSearch.js +7 -5
  501. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +2 -2
  502. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts +1 -1
  503. package/dist/PowerSearch/PowerSearchToken.d.ts +1 -1
  504. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +2 -2
  505. package/dist/PowerSearch/formatFilterValue.d.ts +3 -3
  506. package/dist/PowerSearch/index.d.ts +8 -8
  507. package/dist/PowerSearch/resolveDateTimeRangePart.d.ts +1 -1
  508. package/dist/PowerSearch/resolveOperatorLabel.d.ts +2 -2
  509. package/dist/PowerSearch/types.d.ts +1 -1
  510. package/dist/PowerSearch/useInternalConfig.d.ts +1 -1
  511. package/dist/PowerSearch/usePowerSearchConfig.d.ts +1 -1
  512. package/dist/PowerSearch/usePowerSearchSource.d.ts +3 -3
  513. package/dist/PowerSearch/utils.d.ts +3 -3
  514. package/dist/ProgressBar/ProgressBar.d.ts +2 -2
  515. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  516. package/dist/ProgressBar/ProgressBar.js +8 -0
  517. package/dist/ProgressBar/index.d.ts +2 -2
  518. package/dist/RadioList/RadioList.d.ts +3 -3
  519. package/dist/RadioList/RadioListItem.d.ts +2 -2
  520. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  521. package/dist/RadioList/RadioListItem.js +10 -2
  522. package/dist/RadioList/index.d.ts +4 -4
  523. package/dist/Resizable/ResizeHandle.d.ts +2 -2
  524. package/dist/Resizable/index.d.ts +6 -6
  525. package/dist/Resizable/useResizable.d.ts +2 -2
  526. package/dist/Resizable/utils.d.ts +3 -3
  527. package/dist/ScrollableArea/ScrollableArea.d.ts +3 -3
  528. package/dist/ScrollableArea/ScrollableArea.d.ts.map +1 -1
  529. package/dist/ScrollableArea/ScrollableArea.js +1 -1
  530. package/dist/ScrollableArea/index.d.ts +4 -4
  531. package/dist/Section/Section.d.ts +3 -3
  532. package/dist/Section/index.d.ts +2 -2
  533. package/dist/SegmentedControl/SegmentedControl.d.ts +2 -2
  534. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -1
  535. package/dist/SegmentedControl/index.d.ts +5 -5
  536. package/dist/SelectableCard/SelectableCard.d.ts +8 -8
  537. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  538. package/dist/SelectableCard/SelectableCard.js +15 -11
  539. package/dist/SelectableCard/index.d.ts +2 -2
  540. package/dist/Selector/Selector.d.ts +8 -8
  541. package/dist/Selector/Selector.d.ts.map +1 -1
  542. package/dist/Selector/Selector.js +16 -5
  543. package/dist/Selector/SelectorOption.d.ts +1 -1
  544. package/dist/Selector/hooks.d.ts +1 -1
  545. package/dist/Selector/index.d.ts +4 -4
  546. package/dist/Selector/types.d.ts +1 -1
  547. package/dist/Selector/useSelectorPresentation.d.ts +2 -2
  548. package/dist/Selector/utils.d.ts +1 -1
  549. package/dist/SideNav/SideNav.d.ts +3 -3
  550. package/dist/SideNav/SideNavCollapseButton.d.ts +3 -3
  551. package/dist/SideNav/SideNavHeading.d.ts +2 -2
  552. package/dist/SideNav/SideNavHeading.d.ts.map +1 -1
  553. package/dist/SideNav/SideNavHeading.js +34 -0
  554. package/dist/SideNav/SideNavItem.d.ts +9 -5
  555. package/dist/SideNav/SideNavItem.d.ts.map +1 -1
  556. package/dist/SideNav/SideNavItem.js +36 -13
  557. package/dist/SideNav/SideNavSection.d.ts +1 -1
  558. package/dist/SideNav/index.d.ts +14 -14
  559. package/dist/SizeContext/index.d.ts +1 -1
  560. package/dist/Skeleton/Skeleton.d.ts +1 -1
  561. package/dist/Skeleton/Skeleton.d.ts.map +1 -1
  562. package/dist/Skeleton/Skeleton.js +12 -3
  563. package/dist/Skeleton/index.d.ts +2 -2
  564. package/dist/Slider/Slider.d.ts +3 -3
  565. package/dist/Slider/Slider.d.ts.map +1 -1
  566. package/dist/Slider/Slider.js +45 -12
  567. package/dist/Slider/index.d.ts +2 -2
  568. package/dist/Spinner/Spinner.d.ts +1 -1
  569. package/dist/Spinner/index.d.ts +2 -2
  570. package/dist/Stack/Stack.d.ts +3 -3
  571. package/dist/Stack/StackItem.d.ts +2 -2
  572. package/dist/Stack/index.d.ts +6 -6
  573. package/dist/Stack/stack.stylex.d.ts +1 -1
  574. package/dist/StatusDot/StatusDot.d.ts +2 -2
  575. package/dist/StatusDot/StatusDot.d.ts.map +1 -1
  576. package/dist/StatusDot/StatusDot.js +12 -0
  577. package/dist/StatusDot/index.d.ts +2 -2
  578. package/dist/Stepper/Step.d.ts +2 -2
  579. package/dist/Stepper/Step.d.ts.map +1 -1
  580. package/dist/Stepper/Step.js +10 -6
  581. package/dist/Stepper/Stepper.d.ts +2 -2
  582. package/dist/Stepper/index.d.ts +7 -7
  583. package/dist/Switch/Switch.d.ts +4 -4
  584. package/dist/Switch/Switch.d.ts.map +1 -1
  585. package/dist/Switch/Switch.js +5 -5
  586. package/dist/Switch/index.d.ts +2 -2
  587. package/dist/Switch/switch.markers.stylex.d.ts +7 -2
  588. package/dist/Switch/switch.markers.stylex.d.ts.map +1 -1
  589. package/dist/Switch/switch.markers.stylex.js +8 -3
  590. package/dist/TabList/Tab.d.ts +2 -2
  591. package/dist/TabList/Tab.d.ts.map +1 -1
  592. package/dist/TabList/Tab.js +5 -1
  593. package/dist/TabList/TabList.d.ts +3 -3
  594. package/dist/TabList/TabMenu.d.ts +2 -2
  595. package/dist/TabList/TabMenu.d.ts.map +1 -1
  596. package/dist/TabList/TabMenu.js +1 -0
  597. package/dist/TabList/index.d.ts +8 -8
  598. package/dist/Table/BaseTable.d.ts +1 -1
  599. package/dist/Table/Table.d.ts +1 -1
  600. package/dist/Table/TableBody.d.ts +1 -1
  601. package/dist/Table/TableCell.d.ts +3 -3
  602. package/dist/Table/TableCell.d.ts.map +1 -1
  603. package/dist/Table/TableCell.js +1 -0
  604. package/dist/Table/TableContext.d.ts +1 -1
  605. package/dist/Table/TableFooter.d.ts +1 -1
  606. package/dist/Table/TableHeader.d.ts +1 -1
  607. package/dist/Table/TableHeaderCell.d.ts +3 -3
  608. package/dist/Table/TableHeaderCell.d.ts.map +1 -1
  609. package/dist/Table/TableHeaderCell.js +1 -0
  610. package/dist/Table/TableRow.d.ts +2 -2
  611. package/dist/Table/TableSelectionToolbar.d.ts +2 -2
  612. package/dist/Table/columnUtils.d.ts +1 -1
  613. package/dist/Table/index.d.ts +54 -54
  614. package/dist/Table/plugins/columnResize/index.d.ts +2 -2
  615. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts +1 -1
  616. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  617. package/dist/Table/plugins/columnResize/useTableColumnResize.js +11 -2
  618. package/dist/Table/plugins/columnSettings/index.d.ts +4 -4
  619. package/dist/Table/plugins/columnSettings/useTableColumnSettings.d.ts +2 -2
  620. package/dist/Table/plugins/columnSettings/useTableColumnSettingsState.d.ts +1 -1
  621. package/dist/Table/plugins/filtering/index.d.ts +4 -4
  622. package/dist/Table/plugins/filtering/useTableFilterState.d.ts +1 -1
  623. package/dist/Table/plugins/filtering/useTableFiltering.d.ts +2 -2
  624. package/dist/Table/plugins/groupedRows/index.d.ts +2 -2
  625. package/dist/Table/plugins/groupedRows/useTableGroupedRows.d.ts +1 -1
  626. package/dist/Table/plugins/pagination/index.d.ts +3 -3
  627. package/dist/Table/plugins/pagination/useTablePagination.d.ts +1 -1
  628. package/dist/Table/plugins/rowExpansion/index.d.ts +2 -2
  629. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts +1 -1
  630. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  631. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +103 -4
  632. package/dist/Table/plugins/rowIndex/index.d.ts +2 -2
  633. package/dist/Table/plugins/rowIndex/useTableRowIndex.d.ts +1 -1
  634. package/dist/Table/plugins/rowStatus/index.d.ts +2 -2
  635. package/dist/Table/plugins/rowStatus/useTableRowStatus.d.ts +2 -2
  636. package/dist/Table/plugins/selection/index.d.ts +4 -4
  637. package/dist/Table/plugins/selection/useTableSelection.d.ts +1 -1
  638. package/dist/Table/plugins/selection/useTableSelectionState.d.ts +1 -1
  639. package/dist/Table/plugins/sortable/index.d.ts +4 -4
  640. package/dist/Table/plugins/sortable/useTableSortable.d.ts +1 -1
  641. package/dist/Table/plugins/sortable/useTableSortableState.d.ts +1 -1
  642. package/dist/Table/plugins/stickyColumns/index.d.ts +2 -2
  643. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts +1 -1
  644. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  645. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +233 -6
  646. package/dist/Table/plugins/tree/index.d.ts +4 -4
  647. package/dist/Table/plugins/tree/useTableTreeData.d.ts +1 -1
  648. package/dist/Table/plugins/tree/useTableTreeState.d.ts +1 -1
  649. package/dist/Table/rowDivider.d.ts +34 -0
  650. package/dist/Table/rowDivider.d.ts.map +1 -0
  651. package/dist/Table/rowDivider.js +118 -0
  652. package/dist/Table/tableContextMenu.d.ts +2 -2
  653. package/dist/Table/types.d.ts +3 -3
  654. package/dist/Table/useBaseTablePlugins.d.ts +1 -1
  655. package/dist/Table/useTableCellStyles.d.ts +2 -2
  656. package/dist/Table/utils.d.ts +2 -2
  657. package/dist/Text/Text.d.ts +3 -3
  658. package/dist/Text/index.d.ts +4 -4
  659. package/dist/TextArea/TextArea.d.ts +10 -8
  660. package/dist/TextArea/TextArea.d.ts.map +1 -1
  661. package/dist/TextArea/TextArea.js +15 -12
  662. package/dist/TextArea/index.d.ts +2 -2
  663. package/dist/TextInput/TextInput.d.ts +12 -10
  664. package/dist/TextInput/TextInput.d.ts.map +1 -1
  665. package/dist/TextInput/TextInput.js +35 -21
  666. package/dist/TextInput/index.d.ts +2 -2
  667. package/dist/Thumbnail/Thumbnail.d.ts +1 -1
  668. package/dist/Thumbnail/Thumbnail.d.ts.map +1 -1
  669. package/dist/Thumbnail/Thumbnail.js +45 -11
  670. package/dist/Thumbnail/index.d.ts +2 -2
  671. package/dist/TimeInput/TimeInput.d.ts +6 -6
  672. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  673. package/dist/TimeInput/TimeInput.js +12 -4
  674. package/dist/TimeInput/TouchTimeField.d.ts +1 -1
  675. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  676. package/dist/TimeInput/TouchTimeField.js +2 -1
  677. package/dist/TimeInput/index.d.ts +3 -3
  678. package/dist/Timer/Timer.d.ts +2 -2
  679. package/dist/Timer/index.d.ts +2 -2
  680. package/dist/Timestamp/Timestamp.d.ts +3 -3
  681. package/dist/Timestamp/TimestampHoverCard.d.ts +1 -1
  682. package/dist/Timestamp/formatInstant.d.ts +2 -2
  683. package/dist/Timestamp/formatRelativeTime.d.ts +1 -1
  684. package/dist/Timestamp/index.d.ts +3 -3
  685. package/dist/Timestamp/tooltipEntries.d.ts +2 -2
  686. package/dist/Toast/Toast.d.ts +2 -2
  687. package/dist/Toast/ToastContext.d.ts +1 -1
  688. package/dist/Toast/ToastViewport.d.ts +2 -2
  689. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  690. package/dist/Toast/ToastViewport.js +28 -2
  691. package/dist/Toast/index.d.ts +6 -6
  692. package/dist/Toast/useToast.d.ts +1 -1
  693. package/dist/ToggleButton/ToggleButton.d.ts +3 -3
  694. package/dist/ToggleButton/ToggleButtonGroup.d.ts +1 -1
  695. package/dist/ToggleButton/index.d.ts +4 -4
  696. package/dist/Token/Token.d.ts +2 -2
  697. package/dist/Token/TokenLink.d.ts +1 -1
  698. package/dist/Token/index.d.ts +2 -2
  699. package/dist/Tokenizer/Tokenizer.d.ts +77 -10
  700. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  701. package/dist/Tokenizer/Tokenizer.js +474 -85
  702. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +98 -0
  703. package/dist/Tokenizer/TokenizerBottomSheet.d.ts.map +1 -0
  704. package/dist/Tokenizer/TokenizerBottomSheet.js +721 -0
  705. package/dist/Tokenizer/index.d.ts +2 -2
  706. package/dist/Tokenizer/useEndLaneReserve.d.ts +3 -2
  707. package/dist/Tokenizer/useEndLaneReserve.d.ts.map +1 -1
  708. package/dist/Tokenizer/useEndLaneReserve.js +3 -2
  709. package/dist/Toolbar/Toolbar.d.ts +4 -4
  710. package/dist/Toolbar/index.d.ts +2 -2
  711. package/dist/Tooltip/Tooltip.d.ts +3 -3
  712. package/dist/Tooltip/index.d.ts +4 -4
  713. package/dist/Tooltip/useTooltip.d.ts +2 -2
  714. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  715. package/dist/Tooltip/useTooltip.js +9 -3
  716. package/dist/TopNav/TopNav.d.ts +1 -1
  717. package/dist/TopNav/TopNavHeading.d.ts +2 -2
  718. package/dist/TopNav/TopNavItem.d.ts +3 -3
  719. package/dist/TopNav/TopNavMegaMenu.d.ts +1 -1
  720. package/dist/TopNav/TopNavMegaMenu.d.ts.map +1 -1
  721. package/dist/TopNav/TopNavMegaMenu.js +4 -4
  722. package/dist/TopNav/TopNavMegaMenuFeaturedCard.d.ts +1 -1
  723. package/dist/TopNav/TopNavMegaMenuItem.d.ts +2 -2
  724. package/dist/TopNav/TopNavMenu.d.ts +1 -1
  725. package/dist/TopNav/index.d.ts +16 -16
  726. package/dist/TreeList/TreeList.d.ts +11 -26
  727. package/dist/TreeList/TreeList.d.ts.map +1 -1
  728. package/dist/TreeList/TreeList.js +175 -3
  729. package/dist/TreeList/TreeListItem.d.ts +8 -2
  730. package/dist/TreeList/TreeListItem.d.ts.map +1 -1
  731. package/dist/TreeList/TreeListItem.js +3 -1
  732. package/dist/TreeList/TreeListTypes.d.ts +1 -1
  733. package/dist/TreeList/index.d.ts +3 -3
  734. package/dist/Typeahead/BaseTypeahead.d.ts +2 -2
  735. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  736. package/dist/Typeahead/BaseTypeahead.js +16 -4
  737. package/dist/Typeahead/Typeahead.d.ts +7 -7
  738. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  739. package/dist/Typeahead/Typeahead.js +31 -14
  740. package/dist/Typeahead/TypeaheadItem.d.ts +2 -2
  741. package/dist/Typeahead/createStaticSource.d.ts +1 -1
  742. package/dist/Typeahead/index.d.ts +9 -9
  743. package/dist/Typeahead/utils.d.ts +3 -3
  744. package/dist/VStack/VStack.d.ts +2 -2
  745. package/dist/VStack/index.d.ts +1 -1
  746. package/dist/VisuallyHidden/VisuallyHidden.d.ts +24 -6
  747. package/dist/VisuallyHidden/VisuallyHidden.d.ts.map +1 -1
  748. package/dist/VisuallyHidden/VisuallyHidden.js +24 -5
  749. package/dist/VisuallyHidden/index.d.ts +2 -2
  750. package/dist/astryx.css +138 -51
  751. package/dist/gestures/GestureArena.d.ts +175 -0
  752. package/dist/gestures/GestureArena.d.ts.map +1 -0
  753. package/dist/gestures/GestureArena.js +816 -0
  754. package/dist/gestures/GestureRecognizer.d.ts +239 -0
  755. package/dist/gestures/GestureRecognizer.d.ts.map +1 -0
  756. package/dist/gestures/GestureRecognizer.js +487 -0
  757. package/dist/gestures/LongPressGestureRecognizer.d.ts +32 -0
  758. package/dist/gestures/LongPressGestureRecognizer.d.ts.map +1 -0
  759. package/dist/gestures/LongPressGestureRecognizer.js +135 -0
  760. package/dist/gestures/PanGestureRecognizer.d.ts +117 -0
  761. package/dist/gestures/PanGestureRecognizer.d.ts.map +1 -0
  762. package/dist/gestures/PanGestureRecognizer.js +349 -0
  763. package/dist/gestures/TapGestureRecognizer.d.ts +39 -0
  764. package/dist/gestures/TapGestureRecognizer.d.ts.map +1 -0
  765. package/dist/gestures/TapGestureRecognizer.js +151 -0
  766. package/dist/gestures/VelocityTracker.d.ts +51 -0
  767. package/dist/gestures/VelocityTracker.d.ts.map +1 -0
  768. package/dist/gestures/VelocityTracker.js +186 -0
  769. package/dist/gestures/geometry.d.ts +17 -0
  770. package/dist/gestures/geometry.d.ts.map +1 -0
  771. package/dist/gestures/geometry.js +55 -0
  772. package/dist/gestures/types.d.ts +139 -0
  773. package/dist/gestures/types.d.ts.map +1 -0
  774. package/dist/gestures/types.js +67 -0
  775. package/dist/hooks/AnnounceRenderedText.d.ts +17 -0
  776. package/dist/hooks/AnnounceRenderedText.d.ts.map +1 -0
  777. package/dist/hooks/AnnounceRenderedText.js +32 -0
  778. package/dist/hooks/ModalAnnounceProvider.d.ts +41 -0
  779. package/dist/hooks/ModalAnnounceProvider.d.ts.map +1 -0
  780. package/dist/hooks/ModalAnnounceProvider.js +133 -0
  781. package/dist/hooks/actionGroupTracker.d.ts +98 -0
  782. package/dist/hooks/actionGroupTracker.d.ts.map +1 -0
  783. package/dist/hooks/actionGroupTracker.js +338 -0
  784. package/dist/hooks/index.d.ts +54 -52
  785. package/dist/hooks/index.d.ts.map +1 -1
  786. package/dist/hooks/index.js +1 -0
  787. package/dist/hooks/modalAnnounce.d.ts +18 -0
  788. package/dist/hooks/modalAnnounce.d.ts.map +1 -0
  789. package/dist/hooks/modalAnnounce.js +382 -0
  790. package/dist/hooks/useAdaptivePresentation.d.ts +9 -1
  791. package/dist/hooks/useAdaptivePresentation.d.ts.map +1 -1
  792. package/dist/hooks/useAdaptivePresentation.js +33 -8
  793. package/dist/hooks/useAnimatedLayout.d.ts +42 -0
  794. package/dist/hooks/useAnimatedLayout.d.ts.map +1 -0
  795. package/dist/hooks/useAnimatedLayout.js +46 -0
  796. package/dist/hooks/useAnnounce.d.ts +132 -1
  797. package/dist/hooks/useAnnounce.d.ts.map +1 -1
  798. package/dist/hooks/useAnnounce.js +356 -27
  799. package/dist/hooks/useAnnounceRenderedText.d.ts +19 -2
  800. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  801. package/dist/hooks/useAnnounceRenderedText.js +52 -11
  802. package/dist/hooks/useAutoMediaMode.d.ts +1 -1
  803. package/dist/hooks/useBusyAnnouncement.d.ts +9 -5
  804. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  805. package/dist/hooks/useBusyAnnouncement.js +58 -46
  806. package/dist/hooks/useFocusTrap.d.ts +1 -1
  807. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  808. package/dist/hooks/useFocusTrap.js +57 -26
  809. package/dist/hooks/useInputContainer.d.ts +1 -1
  810. package/dist/hooks/useInputStatusIcon.d.ts +3 -3
  811. package/dist/hooks/useMenuPress.d.ts +5 -3
  812. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  813. package/dist/hooks/useMenuPress.js +58 -33
  814. package/dist/hooks/usePressFeedback.d.ts +1 -1
  815. package/dist/hooks/useScrollableArea.d.ts +1 -1
  816. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  817. package/dist/hooks/useScrollableArea.js +37 -5
  818. package/dist/i18n/InternationalizationContext.d.ts +2 -2
  819. package/dist/i18n/InternationalizationProvider.d.ts +1 -1
  820. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  821. package/dist/i18n/generated-locales/en.generated.js +33 -0
  822. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  823. package/dist/i18n/generated-locales/pseudo.generated.js +33 -0
  824. package/dist/i18n/index.d.ts +12 -12
  825. package/dist/i18n/resolve.d.ts +1 -1
  826. package/dist/i18n/useLocale.d.ts +1 -1
  827. package/dist/index.d.ts +111 -111
  828. package/dist/internal/tokenizer-presentation.d.ts +21 -0
  829. package/dist/internal/tokenizer-presentation.d.ts.map +1 -0
  830. package/dist/internal/tokenizer-presentation.js +21 -0
  831. package/dist/internal/touch.d.ts +26 -0
  832. package/dist/internal/touch.d.ts.map +1 -0
  833. package/dist/internal/touch.js +28 -0
  834. package/dist/motion/LayoutChangeSnapshot.d.ts +33 -0
  835. package/dist/motion/LayoutChangeSnapshot.d.ts.map +1 -0
  836. package/dist/motion/LayoutChangeSnapshot.js +37 -0
  837. package/dist/motion/animatedLayout.d.ts +94 -0
  838. package/dist/motion/animatedLayout.d.ts.map +1 -0
  839. package/dist/motion/animatedLayout.js +1096 -0
  840. package/dist/motion/animator.d.ts +240 -0
  841. package/dist/motion/animator.d.ts.map +1 -0
  842. package/dist/motion/animator.js +2203 -0
  843. package/dist/motion/bezier.d.ts +18 -0
  844. package/dist/motion/bezier.d.ts.map +1 -0
  845. package/dist/motion/bezier.js +60 -0
  846. package/dist/motion/coast.d.ts +61 -0
  847. package/dist/motion/coast.d.ts.map +1 -0
  848. package/dist/motion/coast.js +107 -0
  849. package/dist/motion/decay.d.ts +41 -0
  850. package/dist/motion/decay.d.ts.map +1 -0
  851. package/dist/motion/decay.js +90 -0
  852. package/dist/motion/projection.d.ts +36 -0
  853. package/dist/motion/projection.d.ts.map +1 -0
  854. package/dist/motion/projection.js +92 -0
  855. package/dist/motion/reducedMotion.d.ts +25 -0
  856. package/dist/motion/reducedMotion.d.ts.map +1 -0
  857. package/dist/motion/reducedMotion.js +85 -0
  858. package/dist/motion/reducedMotion.stylex.d.ts +19 -0
  859. package/dist/motion/reducedMotion.stylex.d.ts.map +1 -0
  860. package/dist/motion/reducedMotion.stylex.js +37 -0
  861. package/dist/motion/reducedMotionPlan.d.ts +89 -0
  862. package/dist/motion/reducedMotionPlan.d.ts.map +1 -0
  863. package/dist/motion/reducedMotionPlan.js +194 -0
  864. package/dist/motion/resolveSnapPoint.d.ts +52 -0
  865. package/dist/motion/resolveSnapPoint.d.ts.map +1 -0
  866. package/dist/motion/resolveSnapPoint.js +135 -0
  867. package/dist/motion/roleValue.d.ts +33 -0
  868. package/dist/motion/roleValue.d.ts.map +1 -0
  869. package/dist/motion/roleValue.js +84 -0
  870. package/dist/motion/roles.d.ts +79 -0
  871. package/dist/motion/roles.d.ts.map +1 -0
  872. package/dist/motion/roles.js +199 -0
  873. package/dist/motion/rubberBand.d.ts +20 -0
  874. package/dist/motion/rubberBand.d.ts.map +1 -0
  875. package/dist/motion/rubberBand.js +91 -0
  876. package/dist/motion/selectPage.d.ts +26 -0
  877. package/dist/motion/selectPage.d.ts.map +1 -0
  878. package/dist/motion/selectPage.js +55 -0
  879. package/dist/motion/spring.d.ts +193 -0
  880. package/dist/motion/spring.d.ts.map +1 -0
  881. package/dist/motion/spring.js +442 -0
  882. package/dist/motion/uikit/gestures.d.ts +642 -0
  883. package/dist/motion/uikit/gestures.d.ts.map +1 -0
  884. package/dist/motion/uikit/gestures.js +428 -0
  885. package/dist/motion/uikit/index.d.ts +24 -0
  886. package/dist/motion/uikit/index.d.ts.map +1 -0
  887. package/dist/motion/uikit/index.js +26 -0
  888. package/dist/motion/uikit/navigation.d.ts +54 -0
  889. package/dist/motion/uikit/navigation.d.ts.map +1 -0
  890. package/dist/motion/uikit/navigation.js +83 -0
  891. package/dist/motion/uikit/scroll.d.ts +116 -0
  892. package/dist/motion/uikit/scroll.d.ts.map +1 -0
  893. package/dist/motion/uikit/scroll.js +146 -0
  894. package/dist/motion/uikit/springs.d.ts +545 -0
  895. package/dist/motion/uikit/springs.d.ts.map +1 -0
  896. package/dist/motion/uikit/springs.js +548 -0
  897. package/dist/motion/uikit/timing.d.ts +202 -0
  898. package/dist/motion/uikit/timing.d.ts.map +1 -0
  899. package/dist/motion/uikit/timing.js +201 -0
  900. package/dist/reset.a11y.chromium.spec.js +1 -0
  901. package/dist/reset.until-found.a11y.browser.spec.js +1 -0
  902. package/dist/theme/Theme.d.ts +2 -2
  903. package/dist/theme/contrast.d.ts +1 -1
  904. package/dist/theme/declarationBoundary.d.ts +13 -0
  905. package/dist/theme/declarationBoundary.d.ts.map +1 -1
  906. package/dist/theme/declarationBoundary.js +264 -1
  907. package/dist/theme/defineTheme.d.ts +113 -22
  908. package/dist/theme/defineTheme.d.ts.map +1 -1
  909. package/dist/theme/defineTheme.js +66 -7
  910. package/dist/theme/derivedVarRegistry.d.ts.map +1 -1
  911. package/dist/theme/derivedVarRegistry.js +9 -0
  912. package/dist/theme/domainTokens/index.d.ts +6 -6
  913. package/dist/theme/generateThemeRules.d.ts +7 -3
  914. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  915. package/dist/theme/generateThemeRules.js +468 -24
  916. package/dist/theme/index.d.ts +31 -31
  917. package/dist/theme/index.d.ts.map +1 -1
  918. package/dist/theme/index.js +1 -1
  919. package/dist/theme/localTokens.d.ts +1 -1
  920. package/dist/theme/mergeComponents.d.ts +1 -1
  921. package/dist/theme/onMediaTokens.d.ts +1 -1
  922. package/dist/theme/resolveThemeValues.d.ts +7 -7
  923. package/dist/theme/statusColor.d.ts +48 -0
  924. package/dist/theme/statusColor.d.ts.map +1 -0
  925. package/dist/theme/statusColor.js +203 -0
  926. package/dist/theme/statusRoleDerivation.d.ts +11 -0
  927. package/dist/theme/statusRoleDerivation.d.ts.map +1 -0
  928. package/dist/theme/statusRoleDerivation.js +236 -0
  929. package/dist/theme/syntax/SyntaxTheme.d.ts +1 -1
  930. package/dist/theme/syntax/index.d.ts +7 -7
  931. package/dist/theme/syntax/presets.d.ts +1 -1
  932. package/dist/theme/themeAdaptations.d.ts +30 -6
  933. package/dist/theme/themeAdaptations.d.ts.map +1 -1
  934. package/dist/theme/themeAdaptations.js +30 -1
  935. package/dist/theme/themeRegistry.d.ts +1 -1
  936. package/dist/theme/tokens.d.ts +1 -1
  937. package/dist/theme/tokens.d.ts.map +1 -1
  938. package/dist/theme/tokens.js +16 -1
  939. package/dist/theme/tokens.stylex.d.ts +40 -2
  940. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  941. package/dist/theme/tokens.stylex.js +47 -2
  942. package/dist/theme/types.d.ts +1 -1
  943. package/dist/theme/useTheme.d.ts +6 -4
  944. package/dist/theme/useTheme.d.ts.map +1 -1
  945. package/dist/theme/useTheme.js +10 -4
  946. package/dist/utils/dateParser.d.ts +3 -3
  947. package/dist/utils/edgeAutoscroll.d.ts +53 -0
  948. package/dist/utils/edgeAutoscroll.d.ts.map +1 -0
  949. package/dist/utils/edgeAutoscroll.js +81 -0
  950. package/dist/utils/groupItems.d.ts +1 -1
  951. package/dist/utils/hitArea.d.ts +72 -0
  952. package/dist/utils/hitArea.d.ts.map +1 -0
  953. package/dist/utils/hitArea.js +681 -0
  954. package/dist/utils/index.d.ts +29 -29
  955. package/dist/utils/plainDate.d.ts +3 -3
  956. package/dist/utils/touchPresentation.d.ts +48 -0
  957. package/dist/utils/touchPresentation.d.ts.map +1 -0
  958. package/dist/utils/touchPresentation.js +133 -0
  959. package/locales/af-ZA.json +1 -1
  960. package/locales/ar-SA.json +1 -1
  961. package/locales/ca-ES.json +1 -1
  962. package/locales/cs-CZ.json +1 -1
  963. package/locales/da-DK.json +1 -1
  964. package/locales/de-DE.json +1 -1
  965. package/locales/el-GR.json +1 -1
  966. package/locales/en.json +132 -0
  967. package/locales/es-ES.json +1 -1
  968. package/locales/fi-FI.json +1 -1
  969. package/locales/fr-FR.json +1 -1
  970. package/locales/he-IL.json +1 -1
  971. package/locales/hu-HU.json +1 -1
  972. package/locales/it-IT.json +1 -1
  973. package/locales/ja-JP.json +1 -1
  974. package/locales/ko-KR.json +1 -1
  975. package/locales/nl-NL.json +1 -1
  976. package/locales/no-NO.json +1 -1
  977. package/locales/pl-PL.json +1 -1
  978. package/locales/pseudo.json +99 -0
  979. package/locales/pt-BR.json +1 -1
  980. package/locales/pt-PT.json +1 -1
  981. package/locales/ro-RO.json +1 -1
  982. package/locales/ru-RU.json +1 -1
  983. package/locales/sr-SP.json +1 -1
  984. package/locales/sv-SE.json +1 -1
  985. package/locales/tr-TR.json +1 -1
  986. package/locales/uk-UA.json +1 -1
  987. package/locales/vi-VN.json +1 -1
  988. package/locales/zh-CN.json +1 -1
  989. package/locales/zh-TW.json +1 -1
  990. package/package.json +61 -6
  991. package/src/AlertDialog/AlertDialog.tsx +1 -1
  992. package/src/AlertDialog/__tests__/AlertDialog.a11y.chromium.spec.ts +1 -0
  993. package/src/AppShell/AppShell.spec.md +337 -0
  994. package/src/AspectRatio/AspectRatio.spec.md +179 -0
  995. package/src/AspectRatio/__tests__/AspectRatioFitLayers.a11y.browser.spec.ts +1 -0
  996. package/src/Avatar/Avatar.spec.md +253 -0
  997. package/src/Avatar/AvatarStatusDot.spec.md +93 -79
  998. package/src/Avatar/AvatarStatusDot.test.tsx +22 -0
  999. package/src/Avatar/AvatarStatusDot.tsx +2 -2
  1000. package/src/AvatarGroup/AvatarGroup.spec.md +205 -0
  1001. package/src/AvatarGroup/AvatarGroupOverflow.spec.md +123 -120
  1002. package/src/Badge/Badge.doc.mjs +2 -1
  1003. package/src/Badge/Badge.spec.md +207 -0
  1004. package/src/Badge/Badge.test.tsx +13 -0
  1005. package/src/Badge/Badge.tsx +38 -2
  1006. package/src/Banner/Banner.spec.md +38 -27
  1007. package/src/Banner/Banner.test.tsx +118 -16
  1008. package/src/Banner/Banner.tsx +94 -7
  1009. package/src/Blockquote/Blockquote.spec.md +171 -0
  1010. package/src/BottomSheet/BottomSheet.doc.mjs +106 -24
  1011. package/src/BottomSheet/BottomSheet.spec.md +269 -40
  1012. package/src/BottomSheet/BottomSheet.test.tsx +491 -5
  1013. package/src/BottomSheet/BottomSheet.tsx +544 -145
  1014. package/src/BottomSheet/BottomSheetHostContext.ts +44 -0
  1015. package/src/BottomSheet/BottomSheetPanel.test.tsx +21 -10
  1016. package/src/BottomSheet/BottomSheetPanel.tsx +166 -57
  1017. package/src/BottomSheet/BottomSheetReplace.test.tsx +1526 -0
  1018. package/src/BottomSheet/BottomSheetStacking.announce.test.tsx +246 -0
  1019. package/src/BottomSheet/BottomSheetStacking.test.tsx +3184 -0
  1020. package/src/BottomSheet/BottomSheetSwitcher.doc.mjs +27 -31
  1021. package/src/BottomSheet/BottomSheetSwitcher.spec.md +138 -43
  1022. package/src/BottomSheet/BottomSheetSwitcher.tsx +275 -26
  1023. package/src/BottomSheet/BottomSheetSwitcherContext.ts +6 -0
  1024. package/src/BottomSheet/__tests__/BottomSheetDrag.a11y.chromium.spec.ts +1 -0
  1025. package/src/BottomSheet/__tests__/BottomSheetFocusReturn.a11y.browser.spec.ts +1 -0
  1026. package/src/BottomSheet/__tests__/BottomSheetKeyboard.a11y.browser.spec.ts +1 -0
  1027. package/src/BottomSheet/__tests__/BottomSheetNativeModal.a11y.browser.spec.ts +1 -0
  1028. package/src/BottomSheet/__tests__/BottomSheetPinchZoom.a11y.chromium.spec.ts +1 -0
  1029. package/src/BottomSheet/__tests__/BottomSheetToastOutlet.a11y.chromium.spec.ts +83 -0
  1030. package/src/BottomSheet/bottomSheetEscape.ts +21 -0
  1031. package/src/BottomSheet/bottomSheetStack.ts +2031 -0
  1032. package/src/BottomSheet/useSheetGestures.ts +68 -12
  1033. package/src/Breadcrumbs/BreadcrumbItem.spec.md +96 -59
  1034. package/src/Breadcrumbs/BreadcrumbItem.tsx +5 -0
  1035. package/src/Breadcrumbs/Breadcrumbs.spec.md +165 -0
  1036. package/src/Breadcrumbs/Breadcrumbs.test.tsx +22 -0
  1037. package/src/Breadcrumbs/__tests__/Breadcrumbs.a11y.chromium.spec.ts +1 -0
  1038. package/src/Button/Button.spec.md +322 -0
  1039. package/src/Button/Button.test.tsx +8 -1
  1040. package/src/Button/Button.tsx +36 -7
  1041. package/src/Button/__tests__/Button.a11y.chromium.spec.ts +1 -0
  1042. package/src/ButtonGroup/ButtonGroup.spec.md +218 -0
  1043. package/src/Calendar/__tests__/Calendar.a11y.chromium.spec.ts +1 -0
  1044. package/src/Card/Card.spec.md +205 -0
  1045. package/src/Carousel/__tests__/Carousel.a11y.chromium.spec.ts +1 -0
  1046. package/src/Chat/ChatComposer.test.tsx +54 -0
  1047. package/src/Chat/ChatComposer.tsx +41 -27
  1048. package/src/Chat/ChatComposerInput.test.tsx +165 -21
  1049. package/src/Chat/ChatComposerInput.tsx +73 -16
  1050. package/src/Chat/ChatMessageMetadata.tsx +1 -1
  1051. package/src/Chat/ChatPastedTextToken.test.tsx +71 -0
  1052. package/src/Chat/ChatPastedTextToken.tsx +8 -7
  1053. package/src/Chat/ChatToolCalls.tsx +5 -5
  1054. package/src/Chat/__tests__/ChatLayoutScrollButton.a11y.chromium.spec.ts +1 -0
  1055. package/src/Chat/__tests__/ChatLayoutScrollButtonSurface.a11y.chromium.spec.ts +1 -0
  1056. package/src/Chat/__tests__/ChatMessageList.a11y.chromium.spec.ts +1 -0
  1057. package/src/Chat/__tests__/ChatMessageMetadata.a11y.chromium.spec.ts +1 -0
  1058. package/src/Chat/__tests__/ChatSendButton.a11y.chromium.spec.ts +1 -0
  1059. package/src/Chat/__tests__/ChatSystemMessage.a11y.chromium.spec.ts +1 -0
  1060. package/src/Chat/__tests__/ChatTokenizedText.a11y.chromium.spec.ts +1 -0
  1061. package/src/Chat/__tests__/useChatStreamScroll.a11y.chromium.spec.ts +1 -0
  1062. package/src/CheckboxInput/CheckboxInput.spec.md +97 -66
  1063. package/src/CheckboxInput/__tests__/Checkbox.a11y.chromium.spec.ts +1 -0
  1064. package/src/CheckboxList/CheckboxList.spec.md +92 -78
  1065. package/src/CheckboxList/CheckboxListItem.spec.md +86 -60
  1066. package/src/CheckboxList/__tests__/CheckboxList.a11y.chromium.spec.ts +1 -0
  1067. package/src/ClickableCard/ClickableCard.doc.mjs +1 -2
  1068. package/src/ClickableCard/ClickableCard.test.tsx +14 -3
  1069. package/src/ClickableCard/ClickableCard.tsx +44 -28
  1070. package/src/Code/Code.spec.md +30 -32
  1071. package/src/CodeBlock/CodeBlock.doc.mjs +21 -4
  1072. package/src/CodeBlock/CodeBlock.spec.md +96 -61
  1073. package/src/CodeBlock/CodeBlock.test.tsx +97 -1
  1074. package/src/CodeBlock/CodeBlock.tsx +132 -22
  1075. package/src/CodeBlock/CodeLanguage.test.tsx +173 -0
  1076. package/src/CodeBlock/__tests__/CodeBlockCopyClearance.a11y.chromium.spec.ts +290 -0
  1077. package/src/CodeBlock/__tests__/CodeBlockLanguages.a11y.chromium.spec.ts +64 -0
  1078. package/src/CodeBlock/__tests__/CodeBlockOverflowStop.a11y.chromium.spec.ts +1 -0
  1079. package/src/CodeBlock/__tests__/DiffRowPaint.a11y.chromium.spec.ts +1 -0
  1080. package/src/CodeBlock/grammar.ts +291 -0
  1081. package/src/CodeBlock/index.ts +7 -0
  1082. package/src/CodeBlock/languages/dockerfile.ts +43 -0
  1083. package/src/CodeBlock/languages/graphql.ts +30 -0
  1084. package/src/CodeBlock/languages/java.ts +28 -0
  1085. package/src/CodeBlock/languages/lua.ts +21 -0
  1086. package/src/CodeBlock/languages/objective-c.ts +26 -0
  1087. package/src/CodeBlock/languages/powershell.ts +31 -0
  1088. package/src/CodeBlock/languages/ruby.ts +29 -0
  1089. package/src/CodeBlock/languages/thrift.ts +32 -0
  1090. package/src/CodeBlock/languages/toml.ts +36 -0
  1091. package/src/CodeBlock/languages.test.ts +402 -0
  1092. package/src/CodeBlock/tokenizer.ts +176 -16
  1093. package/src/CodeBlock/tokenizerBudget.test.ts +112 -0
  1094. package/src/Collapsible/Collapsible.doc.mjs +6 -0
  1095. package/src/Collapsible/Collapsible.spec.md +26 -23
  1096. package/src/Collapsible/Collapsible.tsx +121 -2
  1097. package/src/Collapsible/__tests__/Collapsible.a11y.chromium.spec.ts +1 -0
  1098. package/src/Collapsible/__tests__/CollapsibleGroup.a11y.chromium.spec.ts +1 -0
  1099. package/src/Collapsible/__tests__/CollapsibleGroupAccordion.a11y.chromium.spec.ts +1 -0
  1100. package/src/CommandPalette/CommandPalette.perf.test.ts +8 -4
  1101. package/src/CommandPalette/CommandPalette.tsx +17 -1
  1102. package/src/CommandPalette/CommandPaletteEmpty.doc.mjs +6 -3
  1103. package/src/CommandPalette/CommandPaletteEmpty.spec.md +190 -0
  1104. package/src/CommandPalette/CommandPaletteEmpty.tsx +4 -0
  1105. package/src/CommandPalette/CommandPaletteInput.tsx +21 -2
  1106. package/src/CommandPalette/__tests__/CommandPalette.a11y.chromium.spec.ts +1 -0
  1107. package/src/CommandPalette/__tests__/CommandPaletteEmptyAudit.a11y.chromium.spec.ts +715 -0
  1108. package/src/CommandPalette/__tests__/CommandPaletteFooter.a11y.chromium.spec.ts +1 -0
  1109. package/src/CommandPalette/__tests__/CommandPaletteInputAudit.a11y.chromium.spec.ts +1 -0
  1110. package/src/CommandPalette/__tests__/CommandPaletteItemAudit.a11y.chromium.spec.ts +1 -0
  1111. package/src/CommandPalette/busyStartSettle.ts +26 -0
  1112. package/src/ComplexSelector/ComplexSelector.doc.mjs +1 -1
  1113. package/src/ComplexSelector/ComplexSelector.focusableDisabled.test.tsx +1 -1
  1114. package/src/ComplexSelector/ComplexSelector.fr10.test.tsx +9 -9
  1115. package/src/ComplexSelector/ComplexSelector.spec.md +161 -107
  1116. package/src/ComplexSelector/ComplexSelector.test.tsx +236 -17
  1117. package/src/ComplexSelector/ComplexSelector.tsx +69 -4
  1118. package/src/ComplexSelector/__tests__/ComplexSelector.a11y.chromium.spec.ts +965 -0
  1119. package/src/ContextMenu/ContextMenu.doc.mjs +1 -1
  1120. package/src/ContextMenu/ContextMenu.spec.md +38 -30
  1121. package/src/ContextMenu/ContextMenu.test.tsx +189 -11
  1122. package/src/ContextMenu/ContextMenu.tsx +75 -17
  1123. package/src/ContextMenu/__tests__/ContextMenuAudit.a11y.chromium.spec.ts +1 -0
  1124. package/src/ContextMenu/__tests__/ContextMenuCursorAnchor.a11y.browser.spec.ts +1 -0
  1125. package/src/ContextMenu/__tests__/ContextMenuLongPress.a11y.chromium.spec.ts +117 -0
  1126. package/src/DateInput/DateInput.tsx +9 -4
  1127. package/src/DateInput/DateInputTouch.test.tsx +10 -1
  1128. package/src/DateInput/NativeDateField.tsx +2 -1
  1129. package/src/DateInput/TouchDateField.tsx +2 -1
  1130. package/src/DateInput/Wheel.tsx +4 -1
  1131. package/src/DateInput/__tests__/DateInputAudit.a11y.chromium.spec.ts +1 -0
  1132. package/src/DateInput/__tests__/WheelPinchZoom.a11y.chromium.spec.ts +171 -0
  1133. package/src/Dialog/Dialog.doc.mjs +201 -47
  1134. package/src/Dialog/Dialog.tsx +37 -10
  1135. package/src/Dialog/__tests__/Dialog.a11y.browser.spec.ts +1 -0
  1136. package/src/Dialog/__tests__/Dialog.a11y.chromium.spec.ts +1 -0
  1137. package/src/Dialog/__tests__/Dialog.reduced-motion.a11y.browser.spec.ts +191 -0
  1138. package/src/Divider/Divider.spec.md +79 -70
  1139. package/src/Drawer/Drawer.tsx +38 -35
  1140. package/src/Drawer/__tests__/DrawerAudit.a11y.chromium.spec.ts +1 -0
  1141. package/src/Drawer/__tests__/DrawerHeaderAudit.a11y.chromium.spec.ts +1 -0
  1142. package/src/DropdownMenu/DropdownMenu.spec.md +14 -6
  1143. package/src/DropdownMenu/DropdownMenu.ssr.test.tsx +44 -8
  1144. package/src/DropdownMenu/DropdownMenu.test.tsx +64 -5
  1145. package/src/DropdownMenu/DropdownMenu.tsx +47 -21
  1146. package/src/DropdownMenu/DropdownMenuItem.tsx +5 -5
  1147. package/src/DropdownMenu/DropdownMenuRadioItem.doc.mjs +5 -2
  1148. package/src/DropdownMenu/DropdownMenuRadioItem.spec.md +226 -0
  1149. package/src/DropdownMenu/DropdownMenuRadioItem.tsx +32 -16
  1150. package/src/DropdownMenu/DropdownMenuSelectable.test.tsx +158 -0
  1151. package/src/DropdownMenu/DropdownMenuSheetFirstOpen.test.tsx +72 -0
  1152. package/src/DropdownMenu/DropdownMenuSubMenu.doc.mjs +9 -0
  1153. package/src/DropdownMenu/DropdownMenuSubMenu.spec.md +225 -0
  1154. package/src/DropdownMenu/DropdownMenuSubMenu.test.tsx +105 -0
  1155. package/src/DropdownMenu/DropdownMenuSubMenu.tsx +6 -6
  1156. package/src/DropdownMenu/MenuBottomSheet.tsx +42 -7
  1157. package/src/DropdownMenu/MenuBottomSheetActionList.tsx +3 -3
  1158. package/src/DropdownMenu/__tests__/DropdownMenuDividerAudit.a11y.chromium.spec.ts +1 -0
  1159. package/src/DropdownMenu/__tests__/DropdownMenuDrillIn.a11y.chromium.spec.ts +1 -0
  1160. package/src/DropdownMenu/__tests__/DropdownMenuFocusReturn.a11y.browser.spec.ts +1 -0
  1161. package/src/DropdownMenu/__tests__/DropdownMenuGroupAudit.a11y.chromium.spec.ts +1 -0
  1162. package/src/DropdownMenu/__tests__/DropdownMenuItemAudit.a11y.chromium.spec.ts +1 -0
  1163. package/src/DropdownMenu/__tests__/DropdownMenuRadioGroupAudit.a11y.chromium.spec.ts +1 -0
  1164. package/src/DropdownMenu/__tests__/DropdownMenuRadioItemAudit.a11y.chromium.spec.ts +540 -0
  1165. package/src/DropdownMenu/__tests__/DropdownMenuSubMenuAudit.a11y.chromium.spec.ts +671 -0
  1166. package/src/DropdownMenu/__tests__/Menu.a11y.chromium.spec.ts +1 -0
  1167. package/src/DropdownMenu/__tests__/MenuButton.a11y.chromium.spec.ts +1 -0
  1168. package/src/DropdownMenu/__tests__/MenuHeaderFooter.a11y.chromium.spec.ts +1 -0
  1169. package/src/DropdownMenu/__tests__/MenuHoverFocus.a11y.chromium.spec.ts +238 -0
  1170. package/src/DropdownMenu/__tests__/MenuPinchZoom.a11y.chromium.spec.ts +1 -0
  1171. package/src/DropdownMenu/__tests__/MenuPress.a11y.chromium.spec.ts +1 -0
  1172. package/src/DropdownMenu/__tests__/SubMenuHeaderFooter.a11y.chromium.spec.ts +1 -0
  1173. package/src/DropdownMenu/lazyMenuBottomSheet.ts +28 -2
  1174. package/src/DropdownMenu/menuBottomSheet.stylex.ts +33 -0
  1175. package/src/DropdownMenu/menuItemHover.ts +13 -1
  1176. package/src/DropdownMenu/modules/useMenuPress.spec.md +90 -62
  1177. package/src/DropdownMenu/useMenuDrillIn.tsx +7 -5
  1178. package/src/EmptyState/EmptyState.announce.test.tsx +227 -0
  1179. package/src/EmptyState/EmptyState.doc.mjs +1 -1
  1180. package/src/EmptyState/EmptyState.spec.md +22 -14
  1181. package/src/EmptyState/EmptyState.test.tsx +8 -8
  1182. package/src/EmptyState/EmptyState.tsx +7 -5
  1183. package/src/Field/Field.tsx +1 -1
  1184. package/src/Field/FieldLabel.tsx +1 -1
  1185. package/src/Field/PanelSearchInput.tsx +23 -13
  1186. package/src/Field/__tests__/FieldLabelAudit.a11y.chromium.spec.ts +1 -0
  1187. package/src/Field/inputDisabledFocus.ts +28 -0
  1188. package/src/Field/inputStyles.stylex.ts +15 -15
  1189. package/src/FieldStatus/FieldStatus.test.tsx +12 -0
  1190. package/src/FieldStatus/FieldStatus.tsx +12 -3
  1191. package/src/FieldStatus/__tests__/StatusMessage.a11y.chromium.spec.ts +1 -0
  1192. package/src/FileInput/FileInput.test.tsx +78 -0
  1193. package/src/FileInput/FileInput.tsx +11 -9
  1194. package/src/Heading/Heading.spec.md +198 -0
  1195. package/src/HoverCard/HoverCard.test.tsx +93 -3
  1196. package/src/Icon/Icon.doc.mjs +53 -5
  1197. package/src/Icon/Icon.spec.md +40 -29
  1198. package/src/Icon/Icon.test.tsx +266 -9
  1199. package/src/Icon/Icon.tsx +51 -13
  1200. package/src/Icon/IconSize.stylex.ts +27 -11
  1201. package/src/Icon/globalIconRegistry.test.tsx +326 -3
  1202. package/src/Icon/globalIconRegistry.tsx +137 -36
  1203. package/src/Icon/index.ts +29 -1
  1204. package/src/Icon/useIcon.ts +5 -1
  1205. package/src/IconButton/IconButton.spec.md +197 -0
  1206. package/src/IconButton/IconButton.test.tsx +5 -2
  1207. package/src/InputGroup/InputGroup.spec.md +199 -0
  1208. package/src/InputGroup/InputGroup.test.tsx +120 -0
  1209. package/src/InputGroup/InputGroup.tsx +59 -52
  1210. package/src/InputGroup/InputGroupInternalContext.ts +15 -0
  1211. package/src/InputGroup/InputGroupText.spec.md +139 -0
  1212. package/src/InputGroup/InputGroupText.tsx +2 -0
  1213. package/src/InputGroup/groupStyles.ts +22 -11
  1214. package/src/Item/Item.test.tsx +118 -0
  1215. package/src/Item/Item.tsx +5 -3
  1216. package/src/Item/ItemSwipeLayer.tsx +9 -0
  1217. package/src/Item/__tests__/ItemSwipeActions.a11y.chromium.spec.ts +1 -0
  1218. package/src/Item/__tests__/ItemSwipePinchZoom.a11y.chromium.spec.ts +186 -0
  1219. package/src/Item/useSwipeAction.ts +71 -5
  1220. package/src/Kbd/Kbd.test.tsx +95 -0
  1221. package/src/Kbd/Kbd.tsx +30 -23
  1222. package/src/Layer/__tests__/LayerReducedMotion.a11y.chromium.spec.ts +176 -0
  1223. package/src/Layer/__tests__/TouchTrigger.a11y.chromium.spec.ts +200 -0
  1224. package/src/Layer/layerAnimations.stylex.ts +22 -2
  1225. package/src/Layer/layerDismissalInvariants.test.tsx +9 -0
  1226. package/src/Layer/layerSlideRules.ts +141 -8
  1227. package/src/Layer/layerStack.ts +129 -62
  1228. package/src/Layer/modalOutlet.ts +156 -15
  1229. package/src/Layer/preserveAnimations.ts +304 -0
  1230. package/src/Layer/useLayer.doc.mjs +1 -1
  1231. package/src/Layer/useLayer.test.tsx +743 -0
  1232. package/src/Layer/useLayer.tsx +592 -53
  1233. package/src/Layer/useLayerDismissal.test.tsx +85 -2
  1234. package/src/Layer/useLayerDismissal.ts +12 -9
  1235. package/src/Layer/useTouchTrigger.ts +95 -41
  1236. package/src/Layout/Layout.tsx +18 -0
  1237. package/src/Layout/LayoutContent.tsx +5 -14
  1238. package/src/Layout/LayoutFooter.tsx +2 -0
  1239. package/src/Layout/LayoutHeader.tsx +2 -0
  1240. package/src/Layout/__tests__/Layout.a11y.chromium.spec.ts +1 -0
  1241. package/src/Layout/layoutEdges.stylex.ts +25 -0
  1242. package/src/Lightbox/Lightbox.test.tsx +83 -0
  1243. package/src/Lightbox/Lightbox.tsx +149 -125
  1244. package/src/Lightbox/LightboxKeyboard.a11y.browser.spec.ts +78 -0
  1245. package/src/Lightbox/LightboxViewport.a11y.browser.spec.ts +70 -0
  1246. package/src/Link/Link.spec.md +229 -0
  1247. package/src/Link/LinkProvider.spec.md +167 -0
  1248. package/src/Link/__tests__/Link.a11y.chromium.spec.ts +1 -0
  1249. package/src/Link/__tests__/Link.navigation.a11y.chromium.spec.ts +1 -0
  1250. package/src/List/List.spec.md +90 -33
  1251. package/src/List/ListItem.doc.mjs +3 -3
  1252. package/src/Markdown/Markdown.codeLanguages.test.tsx +137 -0
  1253. package/src/Markdown/Markdown.doc.mjs +12 -0
  1254. package/src/Markdown/Markdown.fr23.bench.ts +3 -1
  1255. package/src/Markdown/Markdown.fr23.perf.test.ts +45 -3
  1256. package/src/Markdown/Markdown.fr23.sampling.ts +13 -4
  1257. package/src/Markdown/Markdown.spec.md +71 -59
  1258. package/src/Markdown/Markdown.tsx +32 -2
  1259. package/src/Markdown/MarkdownTable.a11y.chromium.spec.ts +1 -0
  1260. package/src/Markdown/__tests__/MarkdownNesting.a11y.chromium.spec.ts +1 -0
  1261. package/src/MobileNav/MobileNav.spec.md +161 -64
  1262. package/src/MobileNav/MobileNav.test.tsx +27 -10
  1263. package/src/MobileNav/MobileNav.tsx +51 -38
  1264. package/src/MobileNav/MobileNavPinchZoom.a11y.chromium.spec.ts +1 -0
  1265. package/src/MobileNav/__tests__/MobileNavWidth.a11y.chromium.spec.ts +103 -0
  1266. package/src/MoreMenu/MoreMenu.doc.mjs +2 -2
  1267. package/src/MoreMenu/MoreMenu.spec.md +88 -53
  1268. package/src/MultiSelector/CreateRow.a11y.chromium.spec.ts +1 -0
  1269. package/src/MultiSelector/MultiSelector.disabledFocus.a11y.chromium.spec.ts +1 -0
  1270. package/src/MultiSelector/MultiSelector.test.tsx +122 -10
  1271. package/src/MultiSelector/MultiSelector.tsx +24 -4
  1272. package/src/MultiSelector/OptionActions.a11y.chromium.spec.ts +1 -0
  1273. package/src/MultiSelector/__tests__/MultiSelector.a11y.chromium.spec.ts +1 -0
  1274. package/src/NavIcon/NavIcon.spec.md +66 -38
  1275. package/src/NavMenu/NavHeadingMenu.spec.md +100 -44
  1276. package/src/NavMenu/NavHeadingMenu.test.tsx +199 -1
  1277. package/src/NavMenu/NavHeadingMenuItem.tsx +54 -6
  1278. package/src/NumberInput/NumberInput.doc.mjs +6 -6
  1279. package/src/NumberInput/NumberInput.spec.md +248 -0
  1280. package/src/NumberInput/NumberInput.test.tsx +187 -14
  1281. package/src/NumberInput/NumberInput.tsx +86 -24
  1282. package/src/NumberInput/__tests__/NumberInput.a11y.chromium.spec.ts +1 -0
  1283. package/src/Pagination/Pagination.test.tsx +2 -2
  1284. package/src/Popover/Popover.doc.mjs +38 -2
  1285. package/src/Popover/Popover.spec.md +89 -10
  1286. package/src/Popover/Popover.test.tsx +340 -2
  1287. package/src/Popover/Popover.tsx +401 -35
  1288. package/src/Popover/PopoverPresentation.test.tsx +952 -0
  1289. package/src/Popover/__tests__/PopoverSecondDocument.a11y.chromium.spec.ts +205 -0
  1290. package/src/Popover/index.ts +5 -1
  1291. package/src/Popover/lazyPopoverBottomSheet.ts +57 -0
  1292. package/src/Popover/usePopover.tsx +11 -5
  1293. package/src/PowerSearch/PowerSearch.spec.md +423 -53
  1294. package/src/PowerSearch/PowerSearch.test.tsx +77 -1
  1295. package/src/PowerSearch/PowerSearch.tsx +7 -5
  1296. package/src/ProgressBar/ProgressBar.test.tsx +12 -0
  1297. package/src/ProgressBar/ProgressBar.tsx +18 -0
  1298. package/src/ProgressBar/__tests__/ProgressBar.a11y.chromium.spec.ts +1 -0
  1299. package/src/RadioList/RadioList.test.tsx +34 -7
  1300. package/src/RadioList/RadioListItem.press.source-build.test.mjs +80 -0
  1301. package/src/RadioList/RadioListItem.tsx +26 -12
  1302. package/src/RadioList/__tests__/RadioGroup.a11y.chromium.spec.ts +1 -0
  1303. package/src/Resizable/__tests__/ResizeHandle.a11y.chromium.spec.ts +1 -0
  1304. package/src/ScrollableArea/ScrollableArea.spec.md +6 -5
  1305. package/src/ScrollableArea/ScrollableArea.test.tsx +5 -0
  1306. package/src/ScrollableArea/ScrollableArea.tsx +4 -0
  1307. package/src/SelectableCard/SelectableCard.doc.mjs +7 -6
  1308. package/src/SelectableCard/SelectableCard.test.tsx +11 -1
  1309. package/src/SelectableCard/SelectableCard.tsx +49 -33
  1310. package/src/Selector/Selector.spec.md +12 -4
  1311. package/src/Selector/Selector.test.tsx +114 -8
  1312. package/src/Selector/Selector.tsx +19 -4
  1313. package/src/Selector/__tests__/EmptyStateAnnouncement.a11y.chromium.spec.ts +1 -0
  1314. package/src/Selector/__tests__/Listbox.a11y.chromium.spec.ts +1 -0
  1315. package/src/Selector/__tests__/Selector.a11y.chromium.spec.ts +1 -0
  1316. package/src/Selector/__tests__/Selector.combobox.a11y.chromium.spec.ts +1 -0
  1317. package/src/SideNav/SideNav.spec.md +51 -30
  1318. package/src/SideNav/SideNav.test.tsx +290 -25
  1319. package/src/SideNav/SideNavCollapseButton.spec.md +161 -0
  1320. package/src/SideNav/SideNavHeading.spec.md +219 -0
  1321. package/src/SideNav/SideNavHeading.tsx +41 -0
  1322. package/src/SideNav/SideNavItem.spec.md +246 -0
  1323. package/src/SideNav/SideNavItem.tsx +40 -9
  1324. package/src/SideNav/SideNavSection.spec.md +153 -0
  1325. package/src/Skeleton/Skeleton.spec.md +99 -42
  1326. package/src/Skeleton/Skeleton.test.tsx +108 -1
  1327. package/src/Skeleton/Skeleton.tsx +30 -2
  1328. package/src/Slider/Slider.test.tsx +172 -0
  1329. package/src/Slider/Slider.tsx +60 -12
  1330. package/src/Slider/__tests__/Slider.a11y.chromium.spec.ts +1 -0
  1331. package/src/Spinner/Spinner.spec.md +231 -0
  1332. package/src/StatusDot/StatusDot.spec.md +139 -51
  1333. package/src/StatusDot/StatusDot.test.tsx +13 -0
  1334. package/src/StatusDot/StatusDot.tsx +27 -0
  1335. package/src/Stepper/Step.spec.md +206 -0
  1336. package/src/Stepper/Step.tsx +19 -3
  1337. package/src/Stepper/Stepper.test.tsx +50 -0
  1338. package/src/Switch/Switch.focusRing.source-build.test.mjs +81 -0
  1339. package/src/Switch/Switch.tsx +11 -9
  1340. package/src/Switch/__tests__/Switch.a11y.chromium.spec.ts +1 -0
  1341. package/src/Switch/switch.markers.stylex.ts +7 -2
  1342. package/src/TabList/Tab.spec.md +201 -0
  1343. package/src/TabList/Tab.tsx +7 -1
  1344. package/src/TabList/TabList.doc.mjs +3 -3
  1345. package/src/TabList/TabMenu.spec.md +196 -0
  1346. package/src/TabList/TabMenu.tsx +2 -0
  1347. package/src/TabList/__tests__/TabListOverflow.interaction.browser.spec.ts +99 -0
  1348. package/src/TabList/__tests__/Tabs.a11y.chromium.spec.ts +1 -0
  1349. package/src/Table/Table.spec.md +54 -30
  1350. package/src/Table/TableCell.tsx +6 -0
  1351. package/src/Table/TableHeaderCell.tsx +2 -0
  1352. package/src/Table/__tests__/Table.a11y.chromium.spec.ts +129 -0
  1353. package/src/Table/__tests__/Table.a11y.contracts.ts +35 -0
  1354. package/src/Table/__tests__/Table.a11y.renders.tsx +112 -0
  1355. package/src/Table/__tests__/Table.a11y.states.ts +140 -0
  1356. package/src/Table/__tests__/Table.a11y.test.tsx +198 -0
  1357. package/src/Table/__tests__/TableMinWidth.a11y.chromium.spec.ts +1 -0
  1358. package/src/Table/__tests__/TableScroll.a11y.chromium.spec.ts +1 -0
  1359. package/src/Table/__tests__/TableStickyDividers.a11y.browser.spec.ts +560 -0
  1360. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +23 -8
  1361. package/src/Table/plugins/rowExpansion/useTableRowExpansion.test.tsx +91 -9
  1362. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +120 -5
  1363. package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.test.tsx +174 -0
  1364. package/src/Table/plugins/sortable/__tests__/useTableSortable.a11y.ts +86 -0
  1365. package/src/Table/plugins/sortable/useTableSortable.test.tsx +0 -12
  1366. package/src/Table/plugins/stickyColumns/useTableStickyColumns.test.tsx +51 -1
  1367. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +291 -12
  1368. package/src/Table/rowDivider.ts +154 -0
  1369. package/src/Text/Text.spec.md +114 -127
  1370. package/src/TextArea/TextArea.doc.mjs +6 -6
  1371. package/src/TextArea/TextArea.spec.md +164 -64
  1372. package/src/TextArea/TextArea.test.tsx +65 -6
  1373. package/src/TextArea/TextArea.tsx +27 -15
  1374. package/src/TextInput/TextInput.doc.mjs +8 -8
  1375. package/src/TextInput/TextInput.spec.md +258 -0
  1376. package/src/TextInput/TextInput.test.tsx +83 -10
  1377. package/src/TextInput/TextInput.tsx +46 -22
  1378. package/src/TextInput/__tests__/TextInput.a11y.chromium.spec.ts +1 -0
  1379. package/src/Thumbnail/Thumbnail.doc.mjs +1 -2
  1380. package/src/Thumbnail/Thumbnail.spec.md +244 -0
  1381. package/src/Thumbnail/Thumbnail.test.tsx +120 -7
  1382. package/src/Thumbnail/Thumbnail.tsx +77 -31
  1383. package/src/TimeInput/TimeInput.spec.md +273 -0
  1384. package/src/TimeInput/TimeInput.tsx +12 -4
  1385. package/src/TimeInput/TouchTimeField.tsx +2 -1
  1386. package/src/Timestamp/Timestamp.spec.md +252 -0
  1387. package/src/Toast/ToastViewport.modalHost.test.tsx +630 -5
  1388. package/src/Toast/ToastViewport.tsx +27 -2
  1389. package/src/ToggleButton/ToggleButton.spec.md +256 -0
  1390. package/src/ToggleButton/ToggleButtonGroup.spec.md +194 -0
  1391. package/src/ToggleButton/__tests__/ToggleButton.a11y.chromium.spec.ts +1 -0
  1392. package/src/Token/Token.spec.md +271 -0
  1393. package/src/Token/__tests__/TokenRemoveTarget.a11y.chromium.spec.ts +1 -0
  1394. package/src/Tokenizer/Tokenizer.props-type.test.tsx +126 -0
  1395. package/src/Tokenizer/Tokenizer.spec.md +312 -71
  1396. package/src/Tokenizer/Tokenizer.ssr.test.tsx +196 -0
  1397. package/src/Tokenizer/Tokenizer.test.tsx +70 -16
  1398. package/src/Tokenizer/Tokenizer.tsx +651 -113
  1399. package/src/Tokenizer/TokenizerBottomSheet.test.tsx +2719 -0
  1400. package/src/Tokenizer/TokenizerBottomSheet.tsx +957 -0
  1401. package/src/Tokenizer/__tests__/TokenizerEndLane.a11y.chromium.spec.ts +505 -0
  1402. package/src/Tokenizer/useEndLaneReserve.ts +3 -2
  1403. package/src/Toolbar/Toolbar.spec.md +101 -48
  1404. package/src/Toolbar/__tests__/Toolbar.a11y.chromium.spec.ts +1 -0
  1405. package/src/Tooltip/Tooltip.test.tsx +171 -3
  1406. package/src/Tooltip/__tests__/Tooltip.a11y.chromium.spec.ts +1 -0
  1407. package/src/Tooltip/__tests__/Tooltip.a11y.states.ts +2 -2
  1408. package/src/Tooltip/__tests__/TooltipFocusReturn.a11y.chromium.spec.ts +1 -0
  1409. package/src/Tooltip/__tests__/TooltipHoverBridge.a11y.chromium.spec.ts +1 -0
  1410. package/src/Tooltip/__tests__/TooltipTallContent.a11y.browser.spec.ts +646 -0
  1411. package/src/Tooltip/__tests__/TooltipTallContentTracking.a11y.browser.spec.ts +1162 -0
  1412. package/src/Tooltip/useTooltip.tsx +7 -2
  1413. package/src/TopNav/TopNav.spec.md +190 -0
  1414. package/src/TopNav/TopNavHeading.spec.md +204 -0
  1415. package/src/TopNav/TopNavItem.spec.md +189 -0
  1416. package/src/TopNav/TopNavMegaMenu.reduced-motion.source-build.test.mjs +83 -0
  1417. package/src/TopNav/TopNavMegaMenu.spec.md +190 -0
  1418. package/src/TopNav/TopNavMegaMenu.tsx +21 -4
  1419. package/src/TopNav/TopNavMegaMenuFeaturedCard.spec.md +150 -0
  1420. package/src/TopNav/TopNavMegaMenuItem.spec.md +155 -0
  1421. package/src/TopNav/TopNavMenu.spec.md +195 -0
  1422. package/src/TopNav/__tests__/TopNavMobileLongHeading.a11y.chromium.spec.ts +1 -0
  1423. package/src/TreeList/TreeList.doc.mjs +13 -0
  1424. package/src/TreeList/TreeList.spec.md +51 -35
  1425. package/src/TreeList/TreeList.tsx +234 -2
  1426. package/src/TreeList/TreeListItem.tsx +12 -2
  1427. package/src/TreeList/__tests__/TreeList.a11y.chromium.spec.ts +1 -0
  1428. package/src/TreeList/__tests__/TreeListRowNames.a11y.chromium.spec.ts +1 -0
  1429. package/src/Typeahead/BaseTypeahead.tsx +14 -2
  1430. package/src/Typeahead/Typeahead.test.tsx +114 -1
  1431. package/src/Typeahead/Typeahead.tsx +34 -16
  1432. package/src/VisuallyHidden/VisuallyHidden.doc.mjs +1 -1
  1433. package/src/VisuallyHidden/VisuallyHidden.spec.md +170 -0
  1434. package/src/VisuallyHidden/VisuallyHidden.test.tsx +39 -0
  1435. package/src/VisuallyHidden/VisuallyHidden.tsx +38 -5
  1436. package/src/__tests__/BusyOwnerAnnouncement.test.tsx +66 -5
  1437. package/src/__tests__/CardPress.a11y.chromium.spec.ts +353 -0
  1438. package/src/__tests__/DisabledTriggerFocus.a11y.chromium.spec.ts +2 -1
  1439. package/src/__tests__/PressedState.a11y.chromium.spec.ts +1 -0
  1440. package/src/__tests__/pressState.ts +43 -1
  1441. package/src/__tests__/unthemedLength.ts +34 -0
  1442. package/src/gestures/GestureArena.ts +966 -0
  1443. package/src/gestures/GestureRecognizer.ts +626 -0
  1444. package/src/gestures/LongPressGestureRecognizer.ts +186 -0
  1445. package/src/gestures/PanGestureRecognizer.ts +410 -0
  1446. package/src/gestures/TapGestureRecognizer.ts +192 -0
  1447. package/src/gestures/VelocityTracker.ts +194 -0
  1448. package/src/gestures/__tests__/LongPressGestureRecognizer.test.ts +141 -0
  1449. package/src/gestures/__tests__/PanGestureRecognizer.test.ts +327 -0
  1450. package/src/gestures/__tests__/TapGestureRecognizer.test.ts +154 -0
  1451. package/src/gestures/__tests__/VelocityTracker.test.ts +261 -0
  1452. package/src/gestures/__tests__/arena.test.ts +824 -0
  1453. package/src/gestures/__tests__/arenaContinuous.test.ts +207 -0
  1454. package/src/gestures/__tests__/arenaTapLongPress.test.ts +211 -0
  1455. package/src/gestures/__tests__/harness.ts +204 -0
  1456. package/src/gestures/geometry.ts +55 -0
  1457. package/src/gestures/types.ts +161 -0
  1458. package/src/hooks/AnnounceRenderedText.tsx +27 -0
  1459. package/src/hooks/ModalAnnounceProvider.tsx +155 -0
  1460. package/src/hooks/__tests__/MenuPressShadowRoot.a11y.chromium.spec.ts +98 -4
  1461. package/src/hooks/actionGroupTracker.exports.test.ts +28 -0
  1462. package/src/hooks/actionGroupTracker.test.ts +510 -0
  1463. package/src/hooks/actionGroupTracker.ts +449 -0
  1464. package/src/hooks/index.ts +6 -0
  1465. package/src/hooks/modalAnnounce.ts +439 -0
  1466. package/src/hooks/useAdaptivePresentation.ts +46 -9
  1467. package/src/hooks/useAnimatedLayout.doc.mjs +101 -0
  1468. package/src/hooks/useAnimatedLayout.ts +61 -0
  1469. package/src/hooks/useAnnounce.doc.mjs +4 -4
  1470. package/src/hooks/useAnnounce.modal.test.tsx +1291 -0
  1471. package/src/hooks/useAnnounce.test.tsx +64 -4
  1472. package/src/hooks/useAnnounce.ts +452 -28
  1473. package/src/hooks/useAnnounceRenderedText.adopters.test.tsx +226 -0
  1474. package/src/hooks/useAnnounceRenderedText.ts +81 -11
  1475. package/src/hooks/useBusyAnnouncement.adopters.test.tsx +69 -0
  1476. package/src/hooks/useBusyAnnouncement.test.tsx +112 -0
  1477. package/src/hooks/useBusyAnnouncement.ts +64 -54
  1478. package/src/hooks/useFocusTrap.doc.mjs +3 -3
  1479. package/src/hooks/useFocusTrap.test.tsx +135 -2
  1480. package/src/hooks/useFocusTrap.ts +59 -27
  1481. package/src/hooks/useMenuPress.doc.mjs +2 -2
  1482. package/src/hooks/useMenuPress.test.tsx +5 -2
  1483. package/src/hooks/useMenuPress.ts +72 -37
  1484. package/src/hooks/useScrollableArea.test.tsx +159 -0
  1485. package/src/hooks/useScrollableArea.ts +39 -5
  1486. package/src/i18n/generated-locales/en.generated.ts +35 -0
  1487. package/src/i18n/generated-locales/pseudo.generated.ts +37 -0
  1488. package/src/internal/tokenizer-presentation.test.ts +29 -0
  1489. package/src/internal/tokenizer-presentation.ts +25 -0
  1490. package/src/internal/touch.test.ts +44 -0
  1491. package/src/internal/touch.ts +41 -0
  1492. package/src/motion/LayoutChangeSnapshot.tsx +50 -0
  1493. package/src/motion/MEASUREMENTS.md +271 -0
  1494. package/src/motion/README.md +218 -0
  1495. package/src/motion/__tests__/animatedLayout.interaction.browser.spec.ts +1507 -0
  1496. package/src/motion/__tests__/animatedLayoutAdopters.interaction.browser.spec.ts +217 -0
  1497. package/src/motion/__tests__/animatedLayoutBundle.ts +17 -0
  1498. package/src/motion/animatedLayout.boundary.test.ts +139 -0
  1499. package/src/motion/animatedLayout.test.ts +965 -0
  1500. package/src/motion/animatedLayout.ts +1322 -0
  1501. package/src/motion/animatedLayoutAdopters.test.tsx +500 -0
  1502. package/src/motion/animator.test.ts +2653 -0
  1503. package/src/motion/animator.ts +2794 -0
  1504. package/src/motion/bezier.test.ts +52 -0
  1505. package/src/motion/bezier.ts +64 -0
  1506. package/src/motion/coast.test.ts +99 -0
  1507. package/src/motion/coast.ts +150 -0
  1508. package/src/motion/decay.test.ts +120 -0
  1509. package/src/motion/decay.ts +126 -0
  1510. package/src/motion/projection.test.ts +107 -0
  1511. package/src/motion/projection.ts +116 -0
  1512. package/src/motion/reducedMotion.stylex.ts +41 -0
  1513. package/src/motion/reducedMotion.test.ts +129 -0
  1514. package/src/motion/reducedMotion.ts +94 -0
  1515. package/src/motion/reducedMotionPlan.test.ts +182 -0
  1516. package/src/motion/reducedMotionPlan.ts +263 -0
  1517. package/src/motion/resolveSnapPoint.test.ts +189 -0
  1518. package/src/motion/resolveSnapPoint.ts +169 -0
  1519. package/src/motion/roleValue.ts +105 -0
  1520. package/src/motion/roles.test.ts +256 -0
  1521. package/src/motion/roles.ts +262 -0
  1522. package/src/motion/rubberBand.test.ts +88 -0
  1523. package/src/motion/rubberBand.ts +115 -0
  1524. package/src/motion/selectPage.test.ts +31 -0
  1525. package/src/motion/selectPage.ts +55 -0
  1526. package/src/motion/spring.test.ts +650 -0
  1527. package/src/motion/spring.ts +551 -0
  1528. package/src/motion/uikit/gestures.test.ts +89 -0
  1529. package/src/motion/uikit/gestures.ts +359 -0
  1530. package/src/motion/uikit/index.ts +80 -0
  1531. package/src/motion/uikit/navigation.ts +83 -0
  1532. package/src/motion/uikit/scroll.ts +141 -0
  1533. package/src/motion/uikit/springRows.test.ts +71 -0
  1534. package/src/motion/uikit/springs.ts +514 -0
  1535. package/src/motion/uikit/timing.ts +210 -0
  1536. package/src/motion/uikit/uikit.test.ts +364 -0
  1537. package/src/motion/uikit/values.test.ts +110 -0
  1538. package/src/reset.a11y.chromium.spec.ts +1 -0
  1539. package/src/reset.until-found.a11y.browser.spec.ts +1 -0
  1540. package/src/serverSafeComponents.test.ts +10 -0
  1541. package/src/tailwind-theme.css +51 -1
  1542. package/src/tailwind-theme.test.ts +51 -0
  1543. package/src/theme/Theme.test.tsx +28 -0
  1544. package/src/theme/__tests__/SpacingRootFontSize.a11y.chromium.spec.ts +1 -0
  1545. package/src/theme/declarationBoundary.ts +282 -1
  1546. package/src/theme/defineTheme.test.ts +529 -12
  1547. package/src/theme/defineTheme.ts +175 -19
  1548. package/src/theme/derivedVarRegistry.test.ts +28 -5
  1549. package/src/theme/derivedVarRegistry.ts +4 -0
  1550. package/src/theme/expandMotionScale.test.ts +17 -0
  1551. package/src/theme/generateThemeRules.ts +772 -35
  1552. package/src/theme/index.ts +3 -0
  1553. package/src/theme/onMediaTokens.test.ts +186 -0
  1554. package/src/theme/statusColor.ts +189 -0
  1555. package/src/theme/statusRoleDerivation.ts +289 -0
  1556. package/src/theme/themeAdaptations.test.ts +412 -0
  1557. package/src/theme/themeAdaptations.ts +43 -1
  1558. package/src/theme/tokens.stylex.ts +31 -2
  1559. package/src/theme/tokens.test.ts +96 -1
  1560. package/src/theme/tokens.ts +23 -1
  1561. package/src/theme/useTheme.ts +10 -4
  1562. package/src/utils/customPropertyArmLayering.test.ts +131 -0
  1563. package/src/utils/edgeAutoscroll.test.ts +192 -0
  1564. package/src/utils/edgeAutoscroll.ts +111 -0
  1565. package/src/utils/hitArea.test.ts +628 -0
  1566. package/src/utils/hitArea.ts +770 -0
  1567. package/src/utils/touchPresentation.test.ts +323 -0
  1568. package/src/utils/touchPresentation.ts +153 -0
@@ -0,0 +1,2794 @@
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';
138
+ import {solveSpring, toSpring, type SpringDescription} from './spring';
139
+ import {reducedMotionCrossFade} from './uikit/timing';
140
+ import {planReducedMotion, type ReducedMotionView} from './reducedMotionPlan';
141
+
142
+ /**
143
+ * A value the animator can drive.
144
+ */
145
+ export type MotionProperty =
146
+ 'x' | 'y' | 'rotate' | 'scaleX' | 'scaleY' | 'opacity';
147
+
148
+ /**
149
+ * Values by property; `scale` sets `scaleX` and `scaleY` together.
150
+ */
151
+ export type MotionValues = Partial<Record<MotionProperty | 'scale', number>>;
152
+
153
+ /**
154
+ * A spring and the velocity it starts with.
155
+ */
156
+ export interface SpringTransition {
157
+ /** The spring, in any vocabulary of the constants table. */
158
+ spring: SpringDescription;
159
+ /**
160
+ * Initial velocities in units per second (px/s, deg/s, 1/s), for example a
161
+ * gesture's release velocity. A property without one keeps the velocity it
162
+ * has on screen.
163
+ */
164
+ velocity?: MotionValues;
165
+ }
166
+
167
+ /**
168
+ * Options of `animate` and `play`: the spring, a release velocity, the Reduced
169
+ * Motion handling.
170
+ */
171
+ export interface AnimateOptions {
172
+ /**
173
+ * Start time on the document timeline (ms, `performance.now()` clock).
174
+ * Defaults to now. Pass one value to several animators to put their
175
+ * animations on one clock.
176
+ */
177
+ at?: number;
178
+ /**
179
+ * The call starts from the release of a touch drag (a sheet let go, a swipe
180
+ * back released). Under Reduced Motion it then cross-fades whatever the
181
+ * primary pointer (design:reduced-motion DR2), where another call on a
182
+ * fine primary pointer completes at once (DR3). The gesture host knows;
183
+ * nothing is inferred from the last pointer.
184
+ */
185
+ touchRelease?: boolean;
186
+ /**
187
+ * Which way the substituted cross-fade goes when the call's own opacity
188
+ * does not say (a sheet slides in or out without fading): `'entrance'`
189
+ * lands the travel at once and fades the opacity in from 0; `'exit'` fades
190
+ * it out in place, then lands the travel and returns the opacity to its
191
+ * value. The call's targets stay the end state; without Reduced Motion this
192
+ * changes nothing.
193
+ */
194
+ crossfadeAs?: 'entrance' | 'exit';
195
+ }
196
+
197
+ /**
198
+ * Any closed-form curve to play on the compositor (`Animator.play`, and a
199
+ * release's coast through `Animator.decay`): a spring chasing a moving
200
+ * target, a piecewise curve, a fitted UIKit curve. Times are seconds from
201
+ * the curve's start; the value at `duration` is the end state. Start it at
202
+ * the property's presentation value (`get`) to continue without a jump.
203
+ */
204
+ export interface MotionCurve {
205
+ /** Length, s. */
206
+ readonly duration: number;
207
+ /** Value `t` seconds after the start (0 ≤ t ≤ duration). */
208
+ at(t: number): number;
209
+ /** Velocity `t` seconds after the start, units/s. */
210
+ velocity(t: number): number;
211
+ /**
212
+ * A transition started on release rather than a throw's momentum (a
213
+ * spring back from past an edge): under Reduce Motion it is no coast and
214
+ * cross-fades like `animate` (`design:reduced-motion` DR2).
215
+ */
216
+ readonly isTransition?: boolean;
217
+ }
218
+
219
+ /**
220
+ * Options of `createAnimator`.
221
+ */
222
+ export interface AnimatorOptions {
223
+ /** Starting values; identity by default. Never read from the DOM. */
224
+ initial?: MotionValues;
225
+ /** Clock in ms on the document timeline's time base. */
226
+ now?: () => number;
227
+ /**
228
+ * Runs a callback in the next animation frame; `requestAnimationFrame` by
229
+ * default. A call from rest reads the start the browser gave it there.
230
+ */
231
+ requestFrame?: (callback: () => void) => void;
232
+ }
233
+
234
+ /**
235
+ * One `animate` / `decay` call's animations.
236
+ */
237
+ export interface MotionHandle {
238
+ /** The properties this call drives. */
239
+ readonly properties: ReadonlyArray<MotionProperty>;
240
+ /**
241
+ * True when every property reached the end of this call's curve, false
242
+ * as soon as any of them is retargeted, stopped or set before that.
243
+ */
244
+ readonly finished: Promise<boolean>;
245
+ /**
246
+ * When the motion started on the document timeline (ms): for a call from
247
+ * rest, the time the browser committed it (a block before the first frame
248
+ * moves it later); otherwise the call time, or `at`.
249
+ */
250
+ readonly started: Promise<number>;
251
+ /** Presentation value of a property at `time` (default now). */
252
+ value(property: MotionProperty, time?: number): number;
253
+ /** Presentation velocity of a property at `time`, units/s. */
254
+ velocity(property: MotionProperty, time?: number): number;
255
+ /** New targets for this call's properties, keeping their velocity. */
256
+ retarget(
257
+ to: MotionValues,
258
+ transition?: SpringTransition,
259
+ options?: AnimateOptions,
260
+ ): MotionHandle;
261
+ /** Freezes this call's properties at their presentation values. */
262
+ stop(): void;
263
+ }
264
+
265
+ /**
266
+ * A compositor animator bound to one element (see the file header).
267
+ */
268
+ export interface Animator {
269
+ /**
270
+ * What Reduced Motion makes of a call on this element right now:
271
+ * `'off'` (motion plays), `'crossfade'` (an opacity-only fade: a coarse
272
+ * pointer, or `touchRelease`) or `'instant'` (any other pointer). For
273
+ * feedback that has no fade of its own (a press lift, a lens chasing the
274
+ * finger): skip it unless `'off'`.
275
+ */
276
+ reducedMotion(options?: {
277
+ touchRelease?: boolean;
278
+ }): 'off' | 'crossfade' | 'instant';
279
+ /** The element the animator writes to, if attached. */
280
+ readonly element: HTMLElement | null;
281
+ /**
282
+ * Attaches (or detaches, with null) the element. Attaching writes the
283
+ * current state and resumes running curves from now.
284
+ */
285
+ attach(element: HTMLElement | null): void;
286
+ /** Presentation value at `time` (default now), from the curve. */
287
+ get(property: MotionProperty | 'scale', time?: number): number;
288
+ /** Presentation velocity at `time` (default now), units/s. */
289
+ getVelocity(property: MotionProperty | 'scale', time?: number): number;
290
+ /**
291
+ * Puts values in place now, ending their animations: the per-frame write
292
+ * of a drag (one style write per channel, no animation when nothing else
293
+ * on the channel is moving).
294
+ */
295
+ set(values: MotionValues): void;
296
+ /** Springs to `to` from the presentation values. */
297
+ animate(
298
+ to: MotionValues,
299
+ transition: SpringTransition,
300
+ options?: AnimateOptions,
301
+ ): MotionHandle;
302
+ /**
303
+ * Plays given curves (`scale` drives both axes), baked like a spring:
304
+ * presentation values, velocities, `stop`, `finished` and the shared
305
+ * clock work the same, and a later `animate` starts from the curve's
306
+ * value and velocity. Reduced Motion treats a curve that moves x, y, rotate
307
+ * or scale as travel, which the policy replaces (design:reduced-motion: a
308
+ * cross-fade after a touch, an immediate change otherwise). Its handle has
309
+ * no spring of its own: `retarget` needs one.
310
+ */
311
+ play(
312
+ curves: Partial<Record<MotionProperty | 'scale', MotionCurve>>,
313
+ options?: AnimateOptions,
314
+ ): MotionHandle;
315
+ /**
316
+ * Plays momentum curves as given, on the translate axes only: a released
317
+ * scroll view's coast and edge bounce, which `coast()` (coast.ts) builds
318
+ * from a finger's release velocity. Under Reduce Motion momentum keeps
319
+ * its motion: it continues a throw, direct movement (design:reduced-motion
320
+ * DR2, DEC-2). A curve marked `isTransition` (coast()'s spring back from
321
+ * past an edge) is a transition and plays through the Reduce Motion
322
+ * policy, as `animate` does. Anything else (a fade, a slide a tap starts)
323
+ * is a transition too: play it with `play` or `animate`. Pass
324
+ * `touchRelease` when a touch drag's release starts it, so a spring back
325
+ * cross-fades on any pointer (DR2). Only a surface that coasts imports the
326
+ * coast math and the scroll table.
327
+ */
328
+ decay(
329
+ curves: Partial<Record<'x' | 'y', MotionCurve>>,
330
+ options?: Pick<AnimateOptions, 'at' | 'touchRelease'>,
331
+ ): MotionHandle;
332
+ /**
333
+ * Moves properties by the given amounts at once, as when a layout shift
334
+ * moves the element under them: a property moving on a spring keeps its
335
+ * spring, velocity and target (the curve restarts from the shifted value);
336
+ * any other moving curve shifts whole, its end included; a resting
337
+ * property takes the offset and stays.
338
+ */
339
+ rebase(deltas: MotionValues, options?: Pick<AnimateOptions, 'at'>): void;
340
+ /** Freezes properties (all by default) at their presentation values. */
341
+ stop(properties?: ReadonlyArray<MotionProperty | 'scale'>): void;
342
+ /**
343
+ * Resolves once none of `properties` (every property by default) is moving:
344
+ * after the last curve ends, whoever started it, retargets included.
345
+ */
346
+ atRest(properties?: ReadonlyArray<MotionProperty | 'scale'>): Promise<void>;
347
+ /** Cancels everything and detaches. */
348
+ dispose(): void;
349
+ }
350
+
351
+ // ---------------------------------------------------------------------------
352
+ // Curves
353
+ // ---------------------------------------------------------------------------
354
+
355
+ interface Segment {
356
+ /**
357
+ * Start on the document timeline, ms. A call started from rest moves it to
358
+ * the time the browser committed the animation (StartGroup).
359
+ */
360
+ start: number;
361
+ /** Length in ms (finite). */
362
+ readonly duration: number;
363
+ /** Value from the end on. */
364
+ readonly target: number;
365
+ /** Value `t` ms after the start (0 ≤ t ≤ duration). */
366
+ at(t: number): number;
367
+ /** Velocity `t` ms after the start, units/s. */
368
+ speed(t: number): number;
369
+ /** Times (ms after the start) where the value jumps; `at` is right-continuous. */
370
+ readonly jumps: ReadonlyArray<number>;
371
+ /** A Reduce Motion fade: an interruption finishes it instead of freezing it. */
372
+ readonly isFade?: true;
373
+ readonly owner: HandleState;
374
+ /** The call's start group while its start waits for the commit. */
375
+ group?: StartGroup;
376
+ /** The spring driving it, when one does (`rebase` keeps it). */
377
+ spring?: SpringDescription;
378
+ }
379
+
380
+ /**
381
+ * A call started from rest. Its animations are created without a start time,
382
+ * so the browser starts them when it commits them, as Core Animation starts
383
+ * an animation at its transaction's commit: a main-thread block before that
384
+ * frame delays the motion instead of skipping into it. Until then the curves
385
+ * read from the call time; once the browser's start is known they move to it.
386
+ */
387
+ interface StartGroup {
388
+ readonly provisional: number;
389
+ readonly segments: Segment[];
390
+ readonly animations: Animation[];
391
+ readonly channels: Set<Channel>;
392
+ resolved: boolean;
393
+ /** A later call in the same task that took over its curves. */
394
+ adoptedBy?: StartGroup;
395
+ readonly resolve: (start: number) => void;
396
+ readonly started: Promise<number>;
397
+ }
398
+
399
+ /** An atRest() call waiting for its curves to end. */
400
+ interface RestWait {
401
+ timer: ReturnType<typeof setTimeout> | null;
402
+ settle: () => void;
403
+ }
404
+
405
+ interface HandleState {
406
+ resolve: (finished: boolean) => void;
407
+ settled: boolean;
408
+ timer: ReturnType<typeof setTimeout> | null;
409
+ }
410
+
411
+ /**
412
+ * Reduced Motion travel that lands with a plain style write while the
413
+ * element is fully transparent (never an animated transform), then, in a
414
+ * dip, the fade back in.
415
+ */
416
+ interface Landing {
417
+ readonly owner: HandleState;
418
+ /** ms after the call's start. */
419
+ readonly at: number;
420
+ readonly values: Map<MotionProperty, number>;
421
+ /**
422
+ * The fade back in that follows the landing (a dip); `isBorrowed` when it
423
+ * returns to the stylesheet's opacity, which owns it again once it ends.
424
+ */
425
+ fadeIn: {
426
+ readonly to: number;
427
+ readonly ms: number;
428
+ readonly isBorrowed?: boolean;
429
+ } | null;
430
+ /** The opacity written with the landing (an exit by role). */
431
+ restore: number | null;
432
+ /**
433
+ * The restore returns to the stylesheet's opacity (an exit by role on a
434
+ * surface no call owns opacity on): the stylesheet owns it again.
435
+ */
436
+ restoreIsBorrowed?: boolean;
437
+ /** Earlier calls whose landings this one carries: they land with it. */
438
+ readonly carried: HandleState[];
439
+ /** Whose move each value is: a carried value keeps its own call. */
440
+ readonly owners: Map<MotionProperty, HandleState>;
441
+ timer: ReturnType<typeof setTimeout> | null;
442
+ /** When it is due on the document timeline, once the call has started. */
443
+ due: number | null;
444
+ }
445
+
446
+ /** What Reduced Motion makes of a call: its segments, and any landing. */
447
+ interface ReducedPlan {
448
+ readonly next: Partial<Record<MotionProperty, Segment | null>>;
449
+ /** Values that stay where they are until the landing writes them. */
450
+ readonly holds: Partial<Record<MotionProperty, number>>;
451
+ readonly landing: Omit<
452
+ Landing,
453
+ 'owner' | 'timer' | 'carried' | 'owners' | 'due'
454
+ > | null;
455
+ /** The stylesheet opacity a dip borrowed (no call owns opacity). */
456
+ readonly borrowed?: number | null;
457
+ }
458
+
459
+ const PROPERTIES: ReadonlyArray<MotionProperty> = [
460
+ 'x',
461
+ 'y',
462
+ 'rotate',
463
+ 'scaleX',
464
+ 'scaleY',
465
+ 'opacity',
466
+ ];
467
+
468
+ /** The axes momentum moves: `decay` takes only these (DR2, DEC-2). */
469
+ const DECAY_PROPERTIES: ReadonlyArray<'x' | 'y'> = ['x', 'y'];
470
+
471
+ const IDENTITY: Record<MotionProperty, number> = {
472
+ x: 0,
473
+ y: 0,
474
+ rotate: 0,
475
+ scaleX: 1,
476
+ scaleY: 1,
477
+ opacity: 1,
478
+ };
479
+
480
+ /**
481
+ * Within this of its target a curve is over (in the property's own unit). A
482
+ * curve built outside the animator (a progress curve) settles where a call
483
+ * would with this as its epsilon.
484
+ */
485
+ export const SETTLE_THRESHOLD: Record<MotionProperty, number> = {
486
+ x: 0.05,
487
+ y: 0.05,
488
+ rotate: 0.01,
489
+ scaleX: 0.0001,
490
+ scaleY: 0.0001,
491
+ opacity: 0.001,
492
+ };
493
+
494
+ /** Keyframes are added until linear interpolation is within this. */
495
+ const SAMPLE_TOLERANCE: Record<MotionProperty, number> = {
496
+ x: 0.05,
497
+ y: 0.05,
498
+ rotate: 0.02,
499
+ scaleX: 0.0002,
500
+ scaleY: 0.0002,
501
+ opacity: 0.002,
502
+ };
503
+
504
+ /** A curve that has not settled by then (an undamped spring) snaps. */
505
+ const MAX_DURATION_MS = 30_000;
506
+ /** Above this many keyframes the tolerance is relaxed. */
507
+ const MAX_KEYFRAMES = 1200;
508
+ /**
509
+ * The keyframes hold the end state this long after a curve ends. An engine
510
+ * whose compositor ends an animation while the main thread is blocked falls
511
+ * back to the value its main thread last committed, mid-flight (WebKit); the
512
+ * hold keeps the end state on screen through such a block. The main thread
513
+ * drops the animation as soon as it runs after the curve's end.
514
+ */
515
+ export const END_HOLD_MS = 5000;
516
+
517
+ /** How often a paused animation is looked at again for retiring, ms. */
518
+ const RETIRE_RECHECK_MS = 100;
519
+
520
+ /** How long an element stays promoted after its last motion, ms. */
521
+ export const PROMOTION_LINGER_MS = 500;
522
+
523
+ type Channel = 'translate' | 'rotate' | 'scale' | 'opacity';
524
+
525
+ const CHANNELS: Record<Channel, ReadonlyArray<MotionProperty>> = {
526
+ translate: ['x', 'y'],
527
+ rotate: ['rotate'],
528
+ scale: ['scaleX', 'scaleY'],
529
+ opacity: ['opacity'],
530
+ };
531
+
532
+ const CHANNEL_OF: Record<MotionProperty, Channel> = {
533
+ x: 'translate',
534
+ y: 'translate',
535
+ rotate: 'rotate',
536
+ scaleX: 'scale',
537
+ scaleY: 'scale',
538
+ opacity: 'opacity',
539
+ };
540
+
541
+ function round(value: number, digits: number): number {
542
+ return Number(value.toFixed(digits));
543
+ }
544
+
545
+ function format(
546
+ channel: Channel,
547
+ value: (property: MotionProperty) => number,
548
+ ): string {
549
+ switch (channel) {
550
+ case 'translate':
551
+ return `${round(value('x'), 3)}px ${round(value('y'), 3)}px`;
552
+ case 'rotate':
553
+ return `${round(value('rotate'), 4)}deg`;
554
+ case 'scale':
555
+ return `${round(value('scaleX'), 5)} ${round(value('scaleY'), 5)}`;
556
+ case 'opacity':
557
+ return `${round(Math.min(1, Math.max(0, value('opacity'))), 4)}`;
558
+ }
559
+ }
560
+
561
+ const shared = new WeakMap<HTMLElement, Animator>();
562
+
563
+ /**
564
+ * The one animator for `element`, created on
565
+ * first use. Code that animates one element from several places (a swipe on
566
+ * x, a removal on y) shares it, so their curves compose in one `translate`
567
+ * track and retargeting one axis leaves the other on its curve; two
568
+ * animators on one element would overwrite each other. `options` apply
569
+ * when it is created; later calls get the same animator. Never `attach` it
570
+ * elsewhere or `dispose` it: it lives as long as the element.
571
+ */
572
+ export function animatorFor(
573
+ element: HTMLElement,
574
+ options: AnimatorOptions = {},
575
+ ): Animator {
576
+ let animator = shared.get(element);
577
+ if (animator == null) {
578
+ animator = createAnimator(element, options);
579
+ shared.set(element, animator);
580
+ }
581
+ return animator;
582
+ }
583
+
584
+ /**
585
+ * The inline text for a channel: `format`, except that an identity transform
586
+ * is written `none`. Any other value, `translate: 0px 0px` included, makes
587
+ * the element the containing block of its `position: fixed` descendants and
588
+ * a stacking context, so a motion back to identity would leave a fixed child
589
+ * moved with its parent; Mobile Safari also lets no finger scroll a list
590
+ * inside an element left at `scale: 1`. At rest the identity leaves the
591
+ * element entirely when its stylesheet agrees (`releaseIdentity`).
592
+ */
593
+ function inlineText(
594
+ channel: Channel,
595
+ value: (property: MotionProperty) => number,
596
+ ): string {
597
+ const at = (property: MotionProperty, identity: number, digits: number) =>
598
+ round(value(property), digits) === identity;
599
+ switch (channel) {
600
+ case 'translate':
601
+ return at('x', 0, 3) && at('y', 0, 3) ? 'none' : format(channel, value);
602
+ case 'rotate':
603
+ return at('rotate', 0, 4) ? 'none' : format(channel, value);
604
+ case 'scale':
605
+ return at('scaleX', 1, 5) && at('scaleY', 1, 5)
606
+ ? 'none'
607
+ : format(channel, value);
608
+ case 'opacity':
609
+ return format(channel, value);
610
+ }
611
+ }
612
+
613
+ /** What `inlineText` writes for each channel at identity. */
614
+ const IDENTITY_TEXT: Record<Channel, string> = {
615
+ translate: 'none',
616
+ rotate: 'none',
617
+ scale: 'none',
618
+ opacity: '1',
619
+ };
620
+
621
+ /** Whether a computed value (or an unset one) is the channel's identity. */
622
+ function isIdentityText(channel: Channel, text: string): boolean {
623
+ const value = text.trim();
624
+ if (value === '' || value === 'none') {
625
+ return true;
626
+ }
627
+ const numbers = value.split(/\s+/).map(part => Number.parseFloat(part));
628
+ if (numbers.some(number => !Number.isFinite(number))) {
629
+ return false;
630
+ }
631
+ const identity = channel === 'scale' || channel === 'opacity' ? 1 : 0;
632
+ return numbers.every(number => Math.abs(number - identity) < 1e-6);
633
+ }
634
+
635
+ function expand(values: MotionValues): Partial<Record<MotionProperty, number>> {
636
+ const out: Partial<Record<MotionProperty, number>> = {};
637
+ for (const [key, value] of Object.entries(values)) {
638
+ if (value == null || !Number.isFinite(value)) {
639
+ continue;
640
+ }
641
+ if (key === 'scale') {
642
+ out.scaleX ??= value;
643
+ out.scaleY ??= value;
644
+ } else if ((PROPERTIES as ReadonlyArray<string>).includes(key)) {
645
+ out[key as MotionProperty] = value;
646
+ }
647
+ }
648
+ return out;
649
+ }
650
+
651
+ function defaultNow(): number {
652
+ return typeof performance === 'undefined' ? Date.now() : performance.now();
653
+ }
654
+
655
+ /**
656
+ * Whether the user asked for reduced motion (`prefers-reduced-motion:
657
+ * reduce`), read at the moment of the call: the preference the animator uses
658
+ * by default for its Reduce Motion substitution. A component never reads it
659
+ * to pick a curve of its own: its motion settings do not override the
660
+ * policy (design:reduced-motion DR4); `animator.reducedMotion()` or
661
+ * `reducedMotionFade()` gives the policy's answer. False without a window
662
+ * (server rendering).
663
+ */
664
+ export function defaultPrefersReducedMotion(): boolean {
665
+ return (
666
+ typeof window !== 'undefined' &&
667
+ typeof window.matchMedia === 'function' &&
668
+ window.matchMedia('(prefers-reduced-motion: reduce)').matches
669
+ );
670
+ }
671
+
672
+ /** Whether the primary pointer is coarse: `(pointer: coarse)`. */
673
+ export function defaultIsCoarsePointer(): boolean {
674
+ return (
675
+ typeof window !== 'undefined' &&
676
+ typeof window.matchMedia === 'function' &&
677
+ window.matchMedia('(pointer: coarse)').matches
678
+ );
679
+ }
680
+
681
+ /**
682
+ * The transition `decay` hands a Reduce Motion transition curve to: under
683
+ * Reduce Motion `animate` plays no spring (a cross-fade, or at once), so the
684
+ * spring itself is never solved.
685
+ */
686
+ const REDUCED_TRANSITION: SpringTransition = {
687
+ spring: {duration: 0.5, bounce: 0},
688
+ };
689
+
690
+ /**
691
+ * Creates an animator for `element` (or for an element attached later).
692
+ *
693
+ * @example
694
+ * ```
695
+ * const animator = createAnimator(sheet);
696
+ * // finger lifts at 1200 px/s heading for the detent at 0:
697
+ * animator.animate({y: 0}, {spring: springs.sheetDetent, velocity: {y: 1200}});
698
+ * // the finger lands again: where is it right now?
699
+ * const y = animator.get('y', event.timeStamp);
700
+ * animator.stop(['y']);
701
+ * ```
702
+ */
703
+ export function createAnimator(
704
+ element: HTMLElement | null,
705
+ options: AnimatorOptions = {},
706
+ ): Animator {
707
+ const now = options.now ?? defaultNow;
708
+ const requestFrame =
709
+ options.requestFrame ??
710
+ (typeof requestAnimationFrame === 'function'
711
+ ? (callback: () => void) => {
712
+ requestAnimationFrame(() => callback());
713
+ }
714
+ : null);
715
+ // Reduced Motion reads the person's settings and nothing else: no option
716
+ // overrides them (design:reduced-motion DR4).
717
+ const prefersReducedMotion = defaultPrefersReducedMotion;
718
+ const isCoarsePointer = defaultIsCoarsePointer;
719
+ const resting: Record<MotionProperty, number> = {
720
+ ...IDENTITY,
721
+ ...expand(options.initial ?? {}),
722
+ };
723
+ const segments = new Map<MotionProperty, Segment>();
724
+ const running = new Map<Channel, Animation>();
725
+ /** Drops a finished, still-filling animation once the main thread runs. */
726
+ const retireTimers = new Map<Channel, ReturnType<typeof setTimeout>>();
727
+ const touched = new Set<Channel>();
728
+ /**
729
+ * The stylesheet's opacity a Reduce Motion dip borrowed because no call
730
+ * owned opacity; the dip runs from and back to it, then hands it back.
731
+ */
732
+ let borrowedOpacity: number | null = null;
733
+ let target: HTMLElement | null = null;
734
+ /** Calls from rest whose start still waits for the browser's commit. */
735
+ const pendingGroups = new Set<StartGroup>();
736
+ /** atRest() calls still waiting; dispose settles them. */
737
+ const restWaits = new Set<RestWait>();
738
+ /** A detach that settles as an unmount at the end of the task, unless an attach follows. */
739
+ let unmountQueued = false;
740
+ /**
741
+ * The node the latest attach(null) detached, while its unmount is pending:
742
+ * a waiting Reduce Motion move lands there, so that node is left visible
743
+ * where it was going.
744
+ */
745
+ let lastDetached: HTMLElement | null = null;
746
+ /** Runs `write` with the pending unmount's node as the target. */
747
+ const onLastDetached = (write: () => void) => {
748
+ const current = target;
749
+ target = target ?? lastDetached;
750
+ try {
751
+ write();
752
+ } finally {
753
+ target = current;
754
+ }
755
+ };
756
+ /** The call being committed, when it starts from rest. */
757
+ let callGroup: StartGroup | null = null;
758
+ /** Channels promoted to the element's compositing layer (will-change). */
759
+ const promoted = new Set<Channel>();
760
+ /** The element's own inline will-change, restored when promotion ends. */
761
+ let ownWillChange: string | null = null;
762
+ /** The stylesheet's will-change when there is no inline value. */
763
+ let sheetWillChange = '';
764
+ let demoteTimer: ReturnType<typeof setTimeout> | null = null;
765
+ /** Channels whose identity the last node held inline (see `attach`). */
766
+ let heldIdentity = new Set<Channel>();
767
+
768
+ // -- reading the curves ---------------------------------------------------
769
+
770
+ const segmentAt = (
771
+ property: MotionProperty,
772
+ time: number,
773
+ ): Segment | null => {
774
+ const segment = segments.get(property);
775
+ if (segment == null) {
776
+ return null;
777
+ }
778
+ if (time >= segment.start + segment.duration) {
779
+ return null;
780
+ }
781
+ return segment;
782
+ };
783
+
784
+ /**
785
+ * A curve whose call the browser has not started yet: still at its start
786
+ * on screen (valueAt), already moving in the model (velocityAt).
787
+ */
788
+ const isHeld = (segment: Segment) =>
789
+ segment.group != null && !segment.group.resolved;
790
+
791
+ /** The curve itself at `time`: what the keyframes play. */
792
+ const curveAt = (property: MotionProperty, time: number): number => {
793
+ const segment = segments.get(property);
794
+ if (segment == null) {
795
+ return resting[property];
796
+ }
797
+ if (time >= segment.start + segment.duration) {
798
+ return segment.target;
799
+ }
800
+ return segment.at(Math.max(0, time - segment.start));
801
+ };
802
+
803
+ /**
804
+ * The value on screen at `time`. A curve the browser has not started is at
805
+ * its start up to now; a later time reads the curve from its provisional
806
+ * start, the model's best guess until the browser's start moves it (a
807
+ * companion that samples a curve ahead follows its shape).
808
+ */
809
+ const valueAt = (property: MotionProperty, time: number): number => {
810
+ const segment = segments.get(property);
811
+ if (segment != null && isHeld(segment) && time <= now()) {
812
+ // Nothing has moved on screen until the browser starts the call.
813
+ return segment.at(0);
814
+ }
815
+ return curveAt(property, time);
816
+ };
817
+
818
+ const velocityAt = (property: MotionProperty, time: number): number => {
819
+ const held = segments.get(property);
820
+ if (held != null && isHeld(held)) {
821
+ // Still at its start on screen, but moving in the model: a retarget
822
+ // carries the velocity the curve has reached by now, so a flick whose
823
+ // moves all land before the browser starts any keeps its speed.
824
+ return held.speed(Math.max(0, time - held.start));
825
+ }
826
+ const segment = segmentAt(property, time);
827
+ if (segment == null || time < segment.start) {
828
+ return 0;
829
+ }
830
+ return segment.speed(time - segment.start);
831
+ };
832
+
833
+ // The curve just before a jump at absolute time `time`.
834
+ const valueBefore = (property: MotionProperty, time: number): number =>
835
+ curveAt(property, time - 1e-6);
836
+
837
+ // -- writing --------------------------------------------------------------
838
+
839
+ const finalValue = (property: MotionProperty): number =>
840
+ segments.get(property)?.target ?? resting[property];
841
+
842
+ const writeInline = (
843
+ channel: Channel,
844
+ value: (property: MotionProperty) => number,
845
+ ) => {
846
+ if (target == null) {
847
+ return;
848
+ }
849
+ touched.add(channel);
850
+ const text = inlineText(channel, value);
851
+ if (text === IDENTITY_TEXT[channel]) {
852
+ // Identity leaves the element when nothing else would move it.
853
+ target.style.setProperty(channel, text);
854
+ releaseIdentity(channel);
855
+ } else {
856
+ target.style.setProperty(channel, text);
857
+ }
858
+ };
859
+
860
+ const sampleTimes = (
861
+ property: MotionProperty,
862
+ from: number,
863
+ to: number,
864
+ tolerance: number,
865
+ ): number[] => {
866
+ const segment = segments.get(property);
867
+ if (segment == null) {
868
+ return [];
869
+ }
870
+ const begin = Math.max(from, segment.start);
871
+ const end = Math.min(to, segment.start + segment.duration);
872
+ if (end <= begin) {
873
+ return [];
874
+ }
875
+ const times: number[] = [begin];
876
+ const value = (t: number) => curveAt(property, t);
877
+ const breaks = segment.jumps
878
+ .map(j => segment.start + j)
879
+ .filter(t => t > begin && t < end);
880
+ const edges = [begin, ...breaks, end];
881
+ for (let e = 0; e + 1 < edges.length; e++) {
882
+ const a = edges[e];
883
+ const b = edges[e + 1];
884
+ // A 120 Hz grid, each interval split until the chord is within the
885
+ // tolerance at its quarter points.
886
+ const steps = Math.max(1, Math.ceil((b - a) / (1000 / 120)));
887
+ const split = (t0: number, t1: number, depth: number) => {
888
+ const v0 = value(t0);
889
+ const v1 =
890
+ t1 === b && breaks.includes(b) ? valueBefore(property, b) : value(t1);
891
+ let worst = 0;
892
+ for (const f of [0.25, 0.5, 0.75]) {
893
+ const t = t0 + (t1 - t0) * f;
894
+ worst = Math.max(worst, Math.abs(value(t) - (v0 + (v1 - v0) * f)));
895
+ }
896
+ if (worst > tolerance && depth < 10 && t1 - t0 > 0.25) {
897
+ const mid = (t0 + t1) / 2;
898
+ split(t0, mid, depth + 1);
899
+ split(mid, t1, depth + 1);
900
+ } else {
901
+ times.push(t1);
902
+ }
903
+ };
904
+ for (let i = 0; i < steps; i++) {
905
+ split(a + ((b - a) * i) / steps, a + ((b - a) * (i + 1)) / steps, 0);
906
+ }
907
+ }
908
+ return times;
909
+ };
910
+
911
+ const rebuild = (channel: Channel, time: number) => {
912
+ const previous = running.get(channel);
913
+ running.delete(channel);
914
+ clearTimeout(retireTimers.get(channel));
915
+ retireTimers.delete(channel);
916
+ // The element's inline style holds the end state, so its old animation
917
+ // can go first.
918
+ previous?.cancel();
919
+ const properties = CHANNELS[channel];
920
+ // Settled curves become resting values.
921
+ for (const property of properties) {
922
+ const segment = segments.get(property);
923
+ if (segment != null && time >= segment.start + segment.duration) {
924
+ resting[property] = segment.target;
925
+ segments.delete(property);
926
+ }
927
+ }
928
+ writeInline(channel, finalValue);
929
+ const moving = properties.filter(p => segments.has(p));
930
+ if (target == null || typeof target.animate !== 'function') {
931
+ previous?.cancel();
932
+ return;
933
+ }
934
+ if (moving.length === 0) {
935
+ return;
936
+ }
937
+ // A channel rebuilt by an explicit call (set, rebase, a retarget of
938
+ // another axis) while one of its curves still waits for the browser's
939
+ // start keeps that start: no explicit start for this animation.
940
+ const waiting =
941
+ callGroup ??
942
+ moving
943
+ .map(p => (segments.get(p) as Segment).group)
944
+ .find(group => group != null && !group.resolved) ??
945
+ null;
946
+ // The keyframes start where the animation will: at the waiting call's
947
+ // own time, which its start moves to the browser's (resolveGroup), so a
948
+ // write later in the task keeps the screen on the model's clock.
949
+ const from = waiting?.provisional ?? time;
950
+ const end = Math.min(
951
+ from + MAX_DURATION_MS,
952
+ Math.max(
953
+ ...moving.map(
954
+ p =>
955
+ (segments.get(p) as Segment).start +
956
+ (segments.get(p) as Segment).duration,
957
+ ),
958
+ ),
959
+ );
960
+ if (end <= from) {
961
+ return;
962
+ }
963
+ if (callGroup != null) {
964
+ // A curve of an earlier call still waiting for its first frame is
965
+ // rebaked here: it starts with this call's commit.
966
+ for (const property of moving) {
967
+ const segment = segments.get(property) as Segment;
968
+ const group = segment.group;
969
+ if (group != null && group !== callGroup && !group.resolved) {
970
+ const index = group.segments.indexOf(segment);
971
+ if (index >= 0) {
972
+ group.segments.splice(index, 1);
973
+ }
974
+ group.adoptedBy = callGroup;
975
+ segment.group = callGroup;
976
+ // Re-dated to this call's time: it starts at the commit too, not
977
+ // the work between the two calls into its curve.
978
+ segment.start += callGroup.provisional - group.provisional;
979
+ callGroup.segments.push(segment);
980
+ }
981
+ }
982
+ }
983
+ const collect = (scale: number) => {
984
+ const times = new Set<number>([from, end]);
985
+ for (const property of moving) {
986
+ for (const t of sampleTimes(
987
+ property,
988
+ from,
989
+ end,
990
+ SAMPLE_TOLERANCE[property] * scale,
991
+ )) {
992
+ times.add(t);
993
+ }
994
+ }
995
+ return times;
996
+ };
997
+ let scale = 1;
998
+ let all = collect(scale);
999
+ while (all.size > MAX_KEYFRAMES && scale < 64) {
1000
+ scale *= 2;
1001
+ all = collect(scale);
1002
+ }
1003
+ // Jumps become two keyframes at one offset: the value just before, then
1004
+ // the value after. A jump on the last frame (fade out, then move) too.
1005
+ const jumpTimes = new Set<number>();
1006
+ for (const property of moving) {
1007
+ const segment = segments.get(property) as Segment;
1008
+ for (const j of segment.jumps) {
1009
+ const t = segment.start + j;
1010
+ if (t > from && t <= end) {
1011
+ jumpTimes.add(t);
1012
+ all.add(t);
1013
+ }
1014
+ }
1015
+ }
1016
+ const times = [...all].sort((a, b) => a - b);
1017
+ const span = end - from + END_HOLD_MS;
1018
+ const keyframes: Keyframe[] = [];
1019
+ for (const t of times) {
1020
+ const offset = (t - from) / span;
1021
+ if (jumpTimes.has(t)) {
1022
+ keyframes.push({
1023
+ offset,
1024
+ [channel]: format(channel, p => valueBefore(p, t)),
1025
+ });
1026
+ }
1027
+ keyframes.push({
1028
+ offset,
1029
+ [channel]: format(channel, p =>
1030
+ t >= end ? finalValue(p) : curveAt(p, t),
1031
+ ),
1032
+ });
1033
+ }
1034
+ keyframes.push({offset: 1, [channel]: format(channel, finalValue)});
1035
+ promote(channel);
1036
+ const animation = target.animate(keyframes, {
1037
+ duration: span,
1038
+ // The last keyframes hold the end state (END_HOLD_MS); filling both
1039
+ // ways also keeps it where an engine honors the fill on its compositor.
1040
+ // The main thread drops the animation once it runs after the end; the
1041
+ // inline style already holds the same values, so that changes no pixel.
1042
+ fill: 'both',
1043
+ easing: 'linear',
1044
+ });
1045
+ if (waiting != null) {
1046
+ // From rest: no start time, so the browser starts the animation when
1047
+ // it commits it (StartGroup); the keyframes are sampled from `from`,
1048
+ // the call's own start.
1049
+ waiting.animations.push(animation);
1050
+ waiting.channels.add(channel);
1051
+ // A cancel before the first frame rejects its ready promise.
1052
+ (animation as Partial<Animation>).ready?.catch(() => {});
1053
+ } else {
1054
+ // One clock: the keyframes were sampled from `time`.
1055
+ animation.startTime = time;
1056
+ }
1057
+ running.set(channel, animation);
1058
+ previous?.cancel();
1059
+ scheduleRetire(channel, animation, end);
1060
+ };
1061
+
1062
+ /**
1063
+ * Once the main thread runs after the curve's end, the animation leaves the
1064
+ * running state: the element's inline style already shows the end values.
1065
+ */
1066
+ const scheduleRetire = (
1067
+ channel: Channel,
1068
+ animation: Animation,
1069
+ end: number,
1070
+ ) => {
1071
+ clearTimeout(retireTimers.get(channel));
1072
+ const retire = () => {
1073
+ retireTimers.delete(channel);
1074
+ if (running.get(channel) !== animation) {
1075
+ return;
1076
+ }
1077
+ // Paused or sought (a sampler holding it): retire when its own time
1078
+ // reaches the curve's end, never from the wall clock.
1079
+ const remaining = remainingCurve(animation);
1080
+ if (remaining != null && remaining > 0) {
1081
+ retireTimers.set(
1082
+ channel,
1083
+ setTimeout(
1084
+ retire,
1085
+ animation.playState === 'paused' ? RETIRE_RECHECK_MS : remaining,
1086
+ ),
1087
+ );
1088
+ return;
1089
+ }
1090
+ running.delete(channel);
1091
+ animation.cancel();
1092
+ releaseIdentity(channel);
1093
+ flushReleases();
1094
+ };
1095
+ retireTimers.set(channel, setTimeout(retire, Math.max(0, end - now())));
1096
+ };
1097
+
1098
+ /** The element's own (stylesheet) opacity, read once when a dip starts. */
1099
+ const ownOpacity = (): number => {
1100
+ const view = target?.ownerDocument.defaultView;
1101
+ const value =
1102
+ target == null
1103
+ ? NaN
1104
+ : Number.parseFloat(
1105
+ view?.getComputedStyle(target).getPropertyValue('opacity') ?? '',
1106
+ );
1107
+ return Number.isFinite(value) ? Math.min(1, Math.max(0, value)) : 1;
1108
+ };
1109
+
1110
+ /**
1111
+ * Whether the animator holds an opacity of its own on the element: an inline
1112
+ * value it wrote (a `set` over a stylesheet that hides or dims it). A dip
1113
+ * returns to that value.
1114
+ */
1115
+ const writesOwnOpacity = (): boolean =>
1116
+ (target?.style.getPropertyValue('opacity') ?? '') !== '';
1117
+
1118
+ /** Gives the element's opacity back to its stylesheet: its inline value goes. */
1119
+ const releaseOwnOpacity = () => {
1120
+ target?.style.removeProperty('opacity');
1121
+ };
1122
+
1123
+ /**
1124
+ * Lands every Reduce Motion move still waiting, at once, on the current
1125
+ * element: its travel, and the opacity its fade was heading to (the
1126
+ * stylesheet's again for a borrowed one). Its calls settle `finished`.
1127
+ */
1128
+ const landPending = (finished: boolean) => {
1129
+ if (landings.size === 0) {
1130
+ return;
1131
+ }
1132
+ const changed = new Set<MotionProperty>();
1133
+ let handedBack = false;
1134
+ for (const landing of [...landings]) {
1135
+ endLanding(landing);
1136
+ for (const [property, value] of landing.values) {
1137
+ segments.delete(property);
1138
+ resting[property] = value;
1139
+ changed.add(property);
1140
+ }
1141
+ if (landing.fadeIn != null || landing.restore != null) {
1142
+ const borrowed =
1143
+ landing.fadeIn?.isBorrowed === true ||
1144
+ landing.restoreIsBorrowed === true;
1145
+ segments.delete('opacity');
1146
+ resting.opacity = borrowed
1147
+ ? IDENTITY.opacity
1148
+ : (landing.fadeIn?.to ?? landing.restore ?? IDENTITY.opacity);
1149
+ changed.add('opacity');
1150
+ if (borrowed) {
1151
+ borrowedOpacity = null;
1152
+ handedBack = true;
1153
+ }
1154
+ }
1155
+ for (const owner of [landing.owner, ...landing.carried]) {
1156
+ carriedOwners.delete(owner);
1157
+ if (!owner.settled) {
1158
+ settle(owner, finished);
1159
+ }
1160
+ }
1161
+ }
1162
+ commit(changed, now());
1163
+ if (handedBack) {
1164
+ // The stylesheet owns its opacity again: no value stays inline.
1165
+ releaseOwnOpacity();
1166
+ }
1167
+ };
1168
+
1169
+ /**
1170
+ * Ends a borrowed dip on the element it ran on: the stylesheet owns its
1171
+ * opacity again (an unmount or a new element never keeps the borrow).
1172
+ */
1173
+ const handBackBorrow = () => {
1174
+ if (borrowedOpacity == null) {
1175
+ return;
1176
+ }
1177
+ borrowedOpacity = null;
1178
+ segments.delete('opacity');
1179
+ resting.opacity = IDENTITY.opacity;
1180
+ releaseOwnOpacity();
1181
+ };
1182
+
1183
+ /**
1184
+ * A channel at identity with no animation of its own leaves the element:
1185
+ * its inline value is removed, unless the stylesheet would then move the
1186
+ * element, in which case the identity stays inline. Runs when such a value
1187
+ * is written and again when a motion ends.
1188
+ */
1189
+ const releaseIdentity = (channel: Channel) => {
1190
+ if (target == null || running.has(channel)) {
1191
+ return;
1192
+ }
1193
+ if (channel === 'opacity' && borrowedOpacity != null) {
1194
+ if ([...landings].some(landing => landing.fadeIn?.isBorrowed === true)) {
1195
+ // At the bottom of the dip, before it lands and fades back in.
1196
+ return;
1197
+ }
1198
+ // A dip on the stylesheet's opacity ended: the stylesheet owns it again.
1199
+ borrowedOpacity = null;
1200
+ segments.delete('opacity');
1201
+ resting.opacity = IDENTITY.opacity;
1202
+ releaseOwnOpacity();
1203
+ return;
1204
+ }
1205
+ if (target.style.getPropertyValue(channel) !== IDENTITY_TEXT[channel]) {
1206
+ return;
1207
+ }
1208
+ // Read with every other channel the same commit leaves at identity: one
1209
+ // style read for the element, not one per channel (flushReleases).
1210
+ releasing.add(channel);
1211
+ if (!releaseQueued) {
1212
+ releaseQueued = true;
1213
+ queueMicrotask(flushReleases);
1214
+ }
1215
+ };
1216
+
1217
+ /** Channels left at identity whose stylesheet value is still to be read. */
1218
+ const releasing = new Set<Channel>();
1219
+ let releaseQueued = false;
1220
+
1221
+ /**
1222
+ * Removes the identity values written since the last flush, reads the
1223
+ * stylesheet once for all of them, and puts back the ones it would move:
1224
+ * a single forced style read per element and commit, where a read per
1225
+ * channel used to force one each.
1226
+ */
1227
+ const flushReleases = () => {
1228
+ releaseQueued = false;
1229
+ const element = target;
1230
+ const channels = [...releasing].filter(
1231
+ channel =>
1232
+ !running.has(channel) &&
1233
+ element?.style.getPropertyValue(channel) === IDENTITY_TEXT[channel],
1234
+ );
1235
+ releasing.clear();
1236
+ if (element == null || channels.length === 0) {
1237
+ return;
1238
+ }
1239
+ for (const channel of channels) {
1240
+ element.style.removeProperty(channel);
1241
+ }
1242
+ const style = element.ownerDocument.defaultView?.getComputedStyle(element);
1243
+ for (const channel of channels) {
1244
+ const underneath = style?.getPropertyValue(channel);
1245
+ if (underneath != null && !isIdentityText(channel, underneath)) {
1246
+ element.style.setProperty(channel, IDENTITY_TEXT[channel]);
1247
+ }
1248
+ }
1249
+ };
1250
+
1251
+ /**
1252
+ * Curve time an animation still has to play on its own clock (its keyframes
1253
+ * hold the end for END_HOLD_MS after the curve), or null where the engine
1254
+ * does not report it; a paused animation always has some left.
1255
+ */
1256
+ const remainingCurve = (animation: Animation): number | null => {
1257
+ const timing = animation.effect?.getTiming?.();
1258
+ const current = animation.currentTime;
1259
+ if (timing == null || current == null) {
1260
+ return animation.playState === 'paused' ? Infinity : null;
1261
+ }
1262
+ const left = Number(timing.duration) - END_HOLD_MS - Number(current);
1263
+ return animation.playState === 'paused' ? Math.max(left, 1) : left;
1264
+ };
1265
+
1266
+ // -- promotion -------------------------------------------------------------
1267
+
1268
+ /** Writes the promoted channels as will-change. */
1269
+ const writePromotion = (element: HTMLElement) => {
1270
+ const list = [...promoted].join(', ');
1271
+ if (list === '') {
1272
+ element.style.willChange = ownWillChange ?? '';
1273
+ ownWillChange = null;
1274
+ return;
1275
+ }
1276
+ if (ownWillChange == null) {
1277
+ ownWillChange = element.style.willChange;
1278
+ // Without an inline value, the stylesheet's reasons stay alongside the
1279
+ // promotion's (read once, as the promotion starts).
1280
+ sheetWillChange =
1281
+ ownWillChange === ''
1282
+ ? (element.ownerDocument.defaultView
1283
+ ?.getComputedStyle(element)
1284
+ .getPropertyValue('will-change') ?? '')
1285
+ : '';
1286
+ }
1287
+ const base = ownWillChange !== '' ? ownWillChange : sheetWillChange;
1288
+ const own = base === 'auto' ? '' : base;
1289
+ const reasons = own
1290
+ .split(',')
1291
+ .map(reason => reason.trim())
1292
+ .filter(reason => reason !== '' && !promoted.has(reason as Channel));
1293
+ element.style.willChange = [...reasons, ...promoted].join(', ');
1294
+ };
1295
+
1296
+ /**
1297
+ * Gives the element a compositing layer for
1298
+ * `channel` from the task that starts the motion: Mobile Safari runs an
1299
+ * animation whose start time is set from script on its compositor at its
1300
+ * first commit only if the element already has a layer.
1301
+ */
1302
+ const promote = (channel: Channel) => {
1303
+ if (target == null) {
1304
+ return;
1305
+ }
1306
+ if (!promoted.has(channel)) {
1307
+ promoted.add(channel);
1308
+ writePromotion(target);
1309
+ }
1310
+ scheduleDemote();
1311
+ };
1312
+
1313
+ /** Ends promotion PROMOTION_LINGER_MS after the last motion ends. */
1314
+ const scheduleDemote = () => {
1315
+ if (demoteTimer != null) {
1316
+ clearTimeout(demoteTimer);
1317
+ }
1318
+ let end = now();
1319
+ for (const segment of segments.values()) {
1320
+ end = Math.max(end, segment.start + segment.duration);
1321
+ }
1322
+ demoteTimer = setTimeout(
1323
+ () => {
1324
+ demoteTimer = null;
1325
+ const time = now();
1326
+ const moving = [...segments.values()].some(
1327
+ segment => time < segment.start + segment.duration,
1328
+ );
1329
+ if (moving || pendingGroups.size > 0) {
1330
+ scheduleDemote();
1331
+ return;
1332
+ }
1333
+ demote();
1334
+ },
1335
+ Math.max(0, end - now()) + PROMOTION_LINGER_MS,
1336
+ );
1337
+ };
1338
+
1339
+ const demote = () => {
1340
+ if (demoteTimer != null) {
1341
+ clearTimeout(demoteTimer);
1342
+ demoteTimer = null;
1343
+ }
1344
+ if (promoted.size === 0) {
1345
+ return;
1346
+ }
1347
+ promoted.clear();
1348
+ if (target != null) {
1349
+ writePromotion(target);
1350
+ }
1351
+ };
1352
+
1353
+ // -- starting from rest ---------------------------------------------------
1354
+
1355
+ /**
1356
+ * A call starts from rest when nothing on the channels it drives is moving
1357
+ * (a curve still waiting for its first frame counts as rest) and nothing
1358
+ * pins its clock (`at`). Returns its start group, or null for an explicit
1359
+ * start.
1360
+ */
1361
+ const beginGroup = (
1362
+ time: number,
1363
+ properties: Iterable<MotionProperty>,
1364
+ at: number | undefined,
1365
+ ): StartGroup | null => {
1366
+ if (target == null || typeof target.animate !== 'function') {
1367
+ return null;
1368
+ }
1369
+ const channels = new Set<Channel>();
1370
+ for (const property of properties) {
1371
+ channels.add(CHANNEL_OF[property]);
1372
+ }
1373
+ if (at != null) {
1374
+ // An explicit clock is the caller's, except a clock no later than a
1375
+ // call from rest on these channels still waiting for the browser's
1376
+ // start (an event timestamp, such as a drop's, for the reorder that
1377
+ // rebases it): the new call joins that call, and the browser's start
1378
+ // moves both. A later clock is a later call, often a frame or more
1379
+ // later while the browser has not started the first: it keeps its own
1380
+ // clock, since joining would sample its curve from the earlier call's
1381
+ // time and hold its first value for the gap.
1382
+ for (const channel of channels) {
1383
+ for (const property of CHANNELS[channel]) {
1384
+ const group = segments.get(property)?.group;
1385
+ if (group != null && !group.resolved && at <= group.provisional) {
1386
+ return group;
1387
+ }
1388
+ }
1389
+ }
1390
+ return null;
1391
+ }
1392
+ for (const channel of channels) {
1393
+ for (const property of CHANNELS[channel]) {
1394
+ const segment = segments.get(property);
1395
+ if (
1396
+ segment != null &&
1397
+ time < segment.start + segment.duration &&
1398
+ (segment.group == null || segment.group.resolved)
1399
+ ) {
1400
+ return null;
1401
+ }
1402
+ }
1403
+ }
1404
+ let resolve: (start: number) => void = () => {};
1405
+ const started = new Promise<number>(r => {
1406
+ resolve = r;
1407
+ });
1408
+ return {
1409
+ provisional: time,
1410
+ segments: [],
1411
+ animations: [],
1412
+ channels: new Set(),
1413
+ resolved: false,
1414
+ resolve,
1415
+ started,
1416
+ };
1417
+ };
1418
+
1419
+ /** Commits a call's changes, from rest when it has a start group. */
1420
+ const commitCall = (
1421
+ group: StartGroup | null,
1422
+ owner: HandleState,
1423
+ changed: MotionProperty[],
1424
+ time: number,
1425
+ ) => {
1426
+ if (group != null) {
1427
+ for (const property of changed) {
1428
+ const segment = segments.get(property);
1429
+ if (segment != null && segment.owner === owner) {
1430
+ segment.group = group;
1431
+ group.segments.push(segment);
1432
+ }
1433
+ }
1434
+ }
1435
+ callGroup = group;
1436
+ try {
1437
+ commit(changed, time);
1438
+ } finally {
1439
+ callGroup = null;
1440
+ }
1441
+ if (group == null) {
1442
+ return;
1443
+ }
1444
+ if (group.animations.length === 0) {
1445
+ resolveGroup(group, group.provisional); // nothing to start
1446
+ return;
1447
+ }
1448
+ pendingGroups.add(group);
1449
+ for (const animation of group.animations) {
1450
+ // A cancel before the first frame rejects each one's ready promise.
1451
+ (animation as Partial<Animation>).ready?.catch(() => {});
1452
+ }
1453
+ const ready = (group.animations[0] as Partial<Animation>).ready;
1454
+ if (ready == null || typeof ready.then !== 'function') {
1455
+ resolveGroup(group, group.provisional); // no pending start to wait for
1456
+ return;
1457
+ }
1458
+ // The browser sets the start: at the frame that commits the animations,
1459
+ // or when its compositor starts them (Chromium). Read it in that first
1460
+ // frame, ahead of anything that might pause or seek the animations, and
1461
+ // when `ready` settles.
1462
+ requestFrame?.(() => syncGroup(group));
1463
+ ready.then(
1464
+ () => syncGroup(group),
1465
+ () => settleCancelled(group),
1466
+ );
1467
+ };
1468
+
1469
+ /**
1470
+ * A call whose first animation was cancelled before its first frame: if a
1471
+ * later call in the same task took over its curves, it starts with that
1472
+ * call; otherwise it never started.
1473
+ */
1474
+ const settleCancelled = (group: StartGroup) => {
1475
+ if (group.resolved) {
1476
+ return;
1477
+ }
1478
+ let adopter = group.adoptedBy;
1479
+ while (adopter?.adoptedBy != null) {
1480
+ adopter = adopter.adoptedBy;
1481
+ }
1482
+ if (adopter != null && adopter !== group) {
1483
+ void adopter.started.then(start => resolveGroup(group, start));
1484
+ return;
1485
+ }
1486
+ // A same-task write replaced the animation the call waited on: the call
1487
+ // still starts with the browser's start of the ones that remain.
1488
+ if (awaitStart(group)) {
1489
+ return;
1490
+ }
1491
+ resolveGroup(group, group.provisional);
1492
+ };
1493
+
1494
+ /**
1495
+ * Waits for the browser's start of a call through one of its animations
1496
+ * still playing; false when none is left to wait on.
1497
+ */
1498
+ const awaitStart = (group: StartGroup): boolean => {
1499
+ const live = group.animations.find(
1500
+ animation => animation.playState !== 'idle',
1501
+ );
1502
+ const ready = (live as Partial<Animation> | undefined)?.ready;
1503
+ if (ready == null || typeof ready.then !== 'function') {
1504
+ return false;
1505
+ }
1506
+ ready.then(
1507
+ () => syncGroup(group),
1508
+ () => settleCancelled(group),
1509
+ );
1510
+ return true;
1511
+ };
1512
+
1513
+ const syncGroup = (group: StartGroup) => {
1514
+ if (group.resolved) {
1515
+ return;
1516
+ }
1517
+ for (const animation of group.animations) {
1518
+ if (animation.startTime != null) {
1519
+ resolveGroup(group, Number(animation.startTime));
1520
+ return;
1521
+ }
1522
+ }
1523
+ // Finished from outside before the browser started it (a sampler's
1524
+ // finish() on a held animation): nothing is left to wait on, so the call
1525
+ // keeps its own clock, and a later call on an explicit clock does not
1526
+ // join it and wait for a start that never comes.
1527
+ if (
1528
+ group.animations.length > 0 &&
1529
+ group.animations.every(
1530
+ animation =>
1531
+ animation.playState === 'finished' || animation.playState === 'idle',
1532
+ ) &&
1533
+ group.animations.some(animation => animation.playState === 'finished')
1534
+ ) {
1535
+ resolveGroup(group, group.provisional);
1536
+ return;
1537
+ }
1538
+ // No start yet (paused before its first frame by a harness or a page,
1539
+ // or resumed with play() and still pending): neither `ready` nor the
1540
+ // first frame will look again, so keep looking each frame until the call
1541
+ // has a start, or its animations finish (its own clock) or are cancelled.
1542
+ if (
1543
+ group.animations.some(
1544
+ animation =>
1545
+ animation.startTime == null && animation.playState !== 'idle',
1546
+ )
1547
+ ) {
1548
+ requestFrame?.(() => syncGroup(group));
1549
+ }
1550
+ };
1551
+
1552
+ /** Reads the start of every call whose first frame has been committed. */
1553
+ const syncPending = () => {
1554
+ for (const group of pendingGroups) {
1555
+ syncGroup(group);
1556
+ }
1557
+ syncFinished();
1558
+ };
1559
+
1560
+ /**
1561
+ * An animation finished from outside (a test utility's or devtools'
1562
+ * `finish()`) shows its end state while the model still reads its curve:
1563
+ * the curve ends now in the model too, so the next call starts from what
1564
+ * is on screen.
1565
+ */
1566
+ const syncFinished = () => {
1567
+ for (const [channel, animation] of running) {
1568
+ if (animation.playState !== 'finished') {
1569
+ continue;
1570
+ }
1571
+ const time = now();
1572
+ for (const property of CHANNELS[channel]) {
1573
+ const segment = segments.get(property);
1574
+ if (segment == null || time >= segment.start + segment.duration) {
1575
+ continue;
1576
+ }
1577
+ segments.delete(property);
1578
+ resting[property] = segment.target;
1579
+ }
1580
+ }
1581
+ };
1582
+
1583
+ /** Moves a call from rest onto the time the browser started it. */
1584
+ const resolveGroup = (group: StartGroup, start: number) => {
1585
+ if (group.resolved) {
1586
+ return;
1587
+ }
1588
+ group.resolved = true;
1589
+ pendingGroups.delete(group);
1590
+ for (const animation of group.animations) {
1591
+ // One clock for the whole call; a cancelled one stays cancelled (a
1592
+ // start time would play it again).
1593
+ if (animation.startTime == null && animation.playState !== 'idle') {
1594
+ animation.startTime = start;
1595
+ }
1596
+ }
1597
+ const delta = start - group.provisional;
1598
+ if (delta !== 0) {
1599
+ for (const segment of group.segments) {
1600
+ segment.start += delta;
1601
+ }
1602
+ for (const channel of group.channels) {
1603
+ const animation = running.get(channel);
1604
+ if (animation == null || !group.animations.includes(animation)) {
1605
+ continue;
1606
+ }
1607
+ const ends = CHANNELS[channel].flatMap(p => {
1608
+ const segment = segments.get(p);
1609
+ return segment == null ? [] : [segment.start + segment.duration];
1610
+ });
1611
+ if (ends.length > 0) {
1612
+ scheduleRetire(channel, animation, Math.max(...ends));
1613
+ }
1614
+ }
1615
+ for (const owner of new Set(group.segments.map(s => s.owner))) {
1616
+ if (owner.settled || owner.timer == null) {
1617
+ continue;
1618
+ }
1619
+ clearTimeout(owner.timer);
1620
+ const ends = group.segments
1621
+ .filter(segment => segment.owner === owner)
1622
+ .map(segment => segment.start + segment.duration);
1623
+ owner.timer = setTimeout(
1624
+ () => {
1625
+ owner.timer = null;
1626
+ settle(owner, true);
1627
+ },
1628
+ Math.max(0, Math.max(start, ...ends) - now()),
1629
+ );
1630
+ }
1631
+ }
1632
+ group.resolve(start);
1633
+ };
1634
+
1635
+ // -- handles --------------------------------------------------------------
1636
+
1637
+ const lastSpring = new WeakMap<HandleState, SpringDescription>();
1638
+
1639
+ const interrupt = (property: MotionProperty, time: number) => {
1640
+ cancelLanding(property);
1641
+ const segment = segments.get(property);
1642
+ if (segment == null) {
1643
+ return;
1644
+ }
1645
+ if (
1646
+ time < segment.start + segment.duration &&
1647
+ !carriedOwners.has(segment.owner)
1648
+ ) {
1649
+ settle(segment.owner, false);
1650
+ }
1651
+ };
1652
+
1653
+ const settle = (owner: HandleState, finished: boolean) => {
1654
+ if (owner.settled) {
1655
+ return;
1656
+ }
1657
+ owner.settled = true;
1658
+ if (owner.timer != null) {
1659
+ clearTimeout(owner.timer);
1660
+ owner.timer = null;
1661
+ }
1662
+ owner.resolve(finished);
1663
+ };
1664
+
1665
+ const makeHandle = (
1666
+ owner: HandleState,
1667
+ properties: MotionProperty[],
1668
+ finished: Promise<boolean>,
1669
+ time: number,
1670
+ group: StartGroup | null = null,
1671
+ ): MotionHandle => {
1672
+ const ends = properties.map(p => {
1673
+ const segment = segments.get(p);
1674
+ return segment != null && segment.owner === owner
1675
+ ? segment.start + segment.duration
1676
+ : time;
1677
+ });
1678
+ const end = Math.max(time, ...ends);
1679
+ if (properties.length === 0 || end <= time) {
1680
+ settle(owner, true);
1681
+ } else {
1682
+ // Interruptions settle false as they happen (interrupt); reaching the
1683
+ // end untouched is completion.
1684
+ owner.timer = setTimeout(
1685
+ () => {
1686
+ owner.timer = null;
1687
+ settle(owner, true);
1688
+ },
1689
+ Math.max(0, end - now()),
1690
+ );
1691
+ }
1692
+ const handle: MotionHandle = {
1693
+ properties,
1694
+ finished,
1695
+ started: group?.started ?? Promise.resolve(time),
1696
+ value: (property, at = now()) => {
1697
+ syncPending();
1698
+ return valueAt(property, at);
1699
+ },
1700
+ velocity: (property, at = now()) => {
1701
+ syncPending();
1702
+ return velocityAt(property, at);
1703
+ },
1704
+ retarget: (to, transition, retargetOptions) => {
1705
+ const spring = transition?.spring ?? lastSpring.get(owner);
1706
+ if (spring == null) {
1707
+ throw new Error('animator: retarget needs a spring');
1708
+ }
1709
+ return animator.animate(to, {...transition, spring}, retargetOptions);
1710
+ },
1711
+ // The call's own curves, and its travel still waiting to land under
1712
+ // Reduce Motion: a catch freezes both where they are on screen
1713
+ // (AST-094 FR6), travel first so the fade's landing no longer carries
1714
+ // it, as `animator.stop()` does.
1715
+ stop: () =>
1716
+ animator.stop(
1717
+ PROPERTIES.filter(
1718
+ p =>
1719
+ properties.includes(p) &&
1720
+ (segments.get(p)?.owner === owner ||
1721
+ [...landings].some(
1722
+ landing =>
1723
+ landing.values.has(p) &&
1724
+ (landing.owners.get(p) ?? landing.owner) === owner,
1725
+ )),
1726
+ ),
1727
+ ),
1728
+ };
1729
+ return handle;
1730
+ };
1731
+
1732
+ const newOwner = (): {owner: HandleState; finished: Promise<boolean>} => {
1733
+ let resolve: (finished: boolean) => void = () => {};
1734
+ const finished = new Promise<boolean>(r => {
1735
+ resolve = r;
1736
+ });
1737
+ return {owner: {resolve, settled: false, timer: null}, finished};
1738
+ };
1739
+
1740
+ // -- segment factories ------------------------------------------------------
1741
+
1742
+ const springSegment = (
1743
+ owner: HandleState,
1744
+ property: MotionProperty,
1745
+ start: number,
1746
+ to: number,
1747
+ spring: SpringDescription,
1748
+ velocity: number,
1749
+ ): Segment | null => {
1750
+ const from = valueAt(property, start);
1751
+ if (from === to && velocity === 0) {
1752
+ return null;
1753
+ }
1754
+ const curve = solveSpring(toSpring(spring), {from, to, velocity});
1755
+ const duration = Math.min(
1756
+ MAX_DURATION_MS,
1757
+ curve.settleTime(SETTLE_THRESHOLD[property]) * 1000,
1758
+ );
1759
+ return {
1760
+ start,
1761
+ duration,
1762
+ target: to,
1763
+ at: t => curve.value(t / 1000),
1764
+ speed: t => curve.velocity(t / 1000),
1765
+ jumps: [],
1766
+ owner,
1767
+ spring,
1768
+ };
1769
+ };
1770
+
1771
+ const fadeSegment = (
1772
+ owner: HandleState,
1773
+ start: number,
1774
+ stops: ReadonlyArray<{at: number; value: number}>,
1775
+ jumps: ReadonlyArray<number> = [],
1776
+ ): Segment => {
1777
+ const ease = cubicBezier(reducedMotionCrossFade.curve);
1778
+ const duration = stops[stops.length - 1].at;
1779
+ const at = (t: number) => {
1780
+ for (let i = 0; i + 1 < stops.length; i++) {
1781
+ const a = stops[i];
1782
+ const b = stops[i + 1];
1783
+ if (t < b.at || i + 2 === stops.length) {
1784
+ if (b.at === a.at) {
1785
+ return b.value;
1786
+ }
1787
+ const p = Math.min(1, Math.max(0, (t - a.at) / (b.at - a.at)));
1788
+ return a.value + (b.value - a.value) * ease(p);
1789
+ }
1790
+ }
1791
+ return stops[stops.length - 1].value;
1792
+ };
1793
+ return {
1794
+ start,
1795
+ duration,
1796
+ target: stops[stops.length - 1].value,
1797
+ at,
1798
+ speed: t =>
1799
+ ((at(t + 0.5) - at(Math.max(0, t - 0.5))) / (t >= 0.5 ? 1 : 0.5 + t)) *
1800
+ 1000,
1801
+ jumps,
1802
+ owner,
1803
+ isFade: true,
1804
+ };
1805
+ };
1806
+
1807
+ // -- the animator -----------------------------------------------------------
1808
+
1809
+ const commit = (changed: Iterable<MotionProperty>, time: number) => {
1810
+ const channels = new Set<Channel>();
1811
+ for (const property of changed) {
1812
+ channels.add(CHANNEL_OF[property]);
1813
+ }
1814
+ if (channels.has('opacity')) {
1815
+ borrowedOpacity = null;
1816
+ }
1817
+ for (const channel of channels) {
1818
+ rebuild(channel, time);
1819
+ }
1820
+ flushReleases();
1821
+ };
1822
+
1823
+ /** Reduced Motion landings still waiting for the element to be transparent. */
1824
+ const landings = new Set<Landing>();
1825
+ /** Calls a later call's landing carries: an interrupt does not settle them. */
1826
+ const carriedOwners = new Set<HandleState>();
1827
+
1828
+ /**
1829
+ * A later write to `property` takes it from any landing. A write to opacity
1830
+ * decides what shows, so a landing still waiting writes its travel at once
1831
+ * rather than never, and its calls settle as interrupted.
1832
+ */
1833
+ const cancelLanding = (property: MotionProperty) => {
1834
+ for (const landing of [...landings]) {
1835
+ if (property === 'opacity') {
1836
+ endLanding(landing);
1837
+ landNow(landing);
1838
+ } else if (landing.values.delete(property)) {
1839
+ // Set or stopped before it landed: the call whose move it was did
1840
+ // not finish (a carried value is an earlier call's).
1841
+ const moved = landing.owners.get(property) ?? landing.owner;
1842
+ landing.owners.delete(property);
1843
+ if (!moved.settled) {
1844
+ settle(moved, false);
1845
+ }
1846
+ }
1847
+ }
1848
+ };
1849
+
1850
+ const landNow = (landing: Landing) => {
1851
+ const changed: MotionProperty[] = [];
1852
+ for (const [property, value] of landing.values) {
1853
+ segments.delete(property);
1854
+ resting[property] = value;
1855
+ changed.push(property);
1856
+ }
1857
+ if (changed.length > 0) {
1858
+ commit(changed, now());
1859
+ }
1860
+ for (const owner of [landing.owner, ...landing.carried]) {
1861
+ carriedOwners.delete(owner);
1862
+ if (!owner.settled) {
1863
+ settle(owner, false);
1864
+ }
1865
+ }
1866
+ };
1867
+
1868
+ /**
1869
+ * A later Reduced Motion call that lands too carries the landings still
1870
+ * waiting: their travel lands with its own, which wins where both move a
1871
+ * property, and their calls settle when it lands. So two calls in one
1872
+ * frame (a drag cancel's position and scale) both land.
1873
+ */
1874
+ const adoptLandings = (
1875
+ plan: NonNullable<ReducedPlan['landing']>,
1876
+ properties: ReadonlyArray<MotionProperty>,
1877
+ ): {carried: HandleState[]; owners: Map<MotionProperty, HandleState>} => {
1878
+ const carried: HandleState[] = [];
1879
+ const owners = new Map<MotionProperty, HandleState>();
1880
+ for (const landing of [...landings]) {
1881
+ for (const [property, value] of landing.values) {
1882
+ const moved = landing.owners.get(property) ?? landing.owner;
1883
+ if (!properties.includes(property) && !plan.values.has(property)) {
1884
+ plan.values.set(property, value);
1885
+ owners.set(property, moved);
1886
+ } else if (!moved.settled) {
1887
+ // This call takes the property over: the earlier move never lands.
1888
+ settle(moved, false);
1889
+ }
1890
+ }
1891
+ carried.push(landing.owner, ...landing.carried);
1892
+ endLanding(landing);
1893
+ }
1894
+ for (const owner of carried) {
1895
+ carriedOwners.add(owner);
1896
+ }
1897
+ return {carried, owners};
1898
+ };
1899
+
1900
+ /** Where opacity is heading: past a waiting landing's fade back in. */
1901
+ const opacityHeading = (): number => {
1902
+ let to = finalValue('opacity');
1903
+ for (const landing of landings) {
1904
+ if (landing.fadeIn != null) {
1905
+ to = landing.fadeIn.to;
1906
+ } else if (landing.restore != null) {
1907
+ to = landing.restore;
1908
+ }
1909
+ }
1910
+ return to;
1911
+ };
1912
+
1913
+ const endLanding = (landing: Landing) => {
1914
+ if (landing.timer != null) {
1915
+ clearTimeout(landing.timer);
1916
+ }
1917
+ landings.delete(landing);
1918
+ };
1919
+
1920
+ /** Arms a landing from the call's start (the browser's, for a call from rest). */
1921
+ const scheduleLanding = (
1922
+ owner: HandleState,
1923
+ started: Promise<number>,
1924
+ plan: NonNullable<ReducedPlan['landing']>,
1925
+ adopted: ReturnType<typeof adoptLandings> | null,
1926
+ ) => {
1927
+ const owners = new Map<MotionProperty, HandleState>();
1928
+ for (const property of plan.values.keys()) {
1929
+ owners.set(property, adopted?.owners.get(property) ?? owner);
1930
+ }
1931
+ const landing: Landing = {
1932
+ ...plan,
1933
+ owner,
1934
+ carried: adopted?.carried ?? [],
1935
+ owners,
1936
+ timer: null,
1937
+ due: null,
1938
+ };
1939
+ landings.add(landing);
1940
+ // The handle settles when the landing (and its fade back in) is done.
1941
+ if (owner.timer != null) {
1942
+ clearTimeout(owner.timer);
1943
+ owner.timer = null;
1944
+ }
1945
+ void started.then(start => {
1946
+ if (!landings.has(landing)) {
1947
+ return;
1948
+ }
1949
+ landing.due = start + landing.at;
1950
+ landing.timer = setTimeout(
1951
+ () => land(landing),
1952
+ Math.max(0, landing.due - now()),
1953
+ );
1954
+ });
1955
+ };
1956
+
1957
+ /**
1958
+ * Writes the travel while the element is transparent: a plain style write,
1959
+ * never an animation (DR2: opacity only), so it is never shown in the wrong
1960
+ * place. In a dip the fade back in starts from here and takes what is left
1961
+ * of the cross-fade, so the dip ends when it was due even when a busy main
1962
+ * thread runs this timer late; past the whole fade back in (over 100 ms
1963
+ * late) the element appears at once where it landed.
1964
+ */
1965
+ const land = (landing: Landing) => {
1966
+ landings.delete(landing);
1967
+ landing.timer = null;
1968
+ const time = now();
1969
+ const changed: MotionProperty[] = [];
1970
+ for (const [property, value] of landing.values) {
1971
+ segments.delete(property);
1972
+ resting[property] = value;
1973
+ changed.push(property);
1974
+ }
1975
+ let end = time;
1976
+ if (landing.fadeIn != null) {
1977
+ // The fade back in takes what is left of the cross-fade: a timer that
1978
+ // a busy main thread runs late shortens it, so the dip still ends
1979
+ // when it was due (design:reduced-motion DR2, 200 ms or less), and the
1980
+ // element is never shown before it lands.
1981
+ const late = landing.due == null ? 0 : Math.max(0, time - landing.due);
1982
+ const ms = Math.max(1, landing.fadeIn.ms - late);
1983
+ segments.set(
1984
+ 'opacity',
1985
+ fadeSegment(landing.owner, time, [
1986
+ {at: 0, value: valueAt('opacity', time)},
1987
+ {at: ms, value: landing.fadeIn.to},
1988
+ ]),
1989
+ );
1990
+ changed.push('opacity');
1991
+ end = time + ms;
1992
+ } else if (landing.restore != null) {
1993
+ segments.delete('opacity');
1994
+ resting.opacity =
1995
+ landing.restoreIsBorrowed === true ? IDENTITY.opacity : landing.restore;
1996
+ changed.push('opacity');
1997
+ }
1998
+ commit(changed, time);
1999
+ if (landing.restoreIsBorrowed === true) {
2000
+ // The stylesheet owns its opacity again.
2001
+ releaseOwnOpacity();
2002
+ }
2003
+ if (landing.fadeIn?.isBorrowed === true) {
2004
+ // The fade back in returns to the stylesheet's opacity: it owns it
2005
+ // again once the fade ends (releaseIdentity).
2006
+ borrowedOpacity = landing.fadeIn.to;
2007
+ }
2008
+ // The calls it carries are done: their travel has landed.
2009
+ for (const carried of landing.carried) {
2010
+ carriedOwners.delete(carried);
2011
+ if (!carried.settled) {
2012
+ settle(carried, true);
2013
+ }
2014
+ }
2015
+ const {owner} = landing;
2016
+ if (owner.settled) {
2017
+ return;
2018
+ }
2019
+ if (end <= time) {
2020
+ settle(owner, true);
2021
+ } else {
2022
+ owner.timer = setTimeout(
2023
+ () => {
2024
+ owner.timer = null;
2025
+ settle(owner, true);
2026
+ },
2027
+ Math.max(0, end - now()),
2028
+ );
2029
+ }
2030
+ };
2031
+
2032
+ /**
2033
+ * A call that sets a value still waiting to land takes it over: the earlier
2034
+ * move never lands, and its call settles interrupted. Once nothing waiting
2035
+ * is left, a call that names its own opacity replaces an earlier fade back
2036
+ * in or restore too, so a caught dismissal fades straight back up instead
2037
+ * of dipping. Whatever still waits is carried by the new plan.
2038
+ */
2039
+ const takeOverLandings = (
2040
+ properties: ReadonlyArray<MotionProperty>,
2041
+ namesOpacity: boolean,
2042
+ ) => {
2043
+ for (const property of properties) {
2044
+ if (property !== 'opacity') {
2045
+ cancelLanding(property);
2046
+ }
2047
+ }
2048
+ if (!namesOpacity) {
2049
+ // A dip left with nothing to land (a move taken back) fades straight
2050
+ // back in from where it is, rather than finishing its dip.
2051
+ for (const landing of [...landings]) {
2052
+ if (landing.values.size === 0 && landing.fadeIn != null) {
2053
+ endLanding(landing);
2054
+ land(landing);
2055
+ }
2056
+ }
2057
+ return;
2058
+ }
2059
+ for (const landing of [...landings]) {
2060
+ // A waiting call that named its own opacity loses it to this call: it
2061
+ // never reaches that opacity, so it settles interrupted even though its
2062
+ // travel still lands.
2063
+ for (const owner of [landing.owner, ...landing.carried]) {
2064
+ if (namedOpacity.has(owner) && !owner.settled) {
2065
+ settle(owner, false);
2066
+ }
2067
+ }
2068
+ if (landing.values.size > 0) {
2069
+ continue;
2070
+ }
2071
+ endLanding(landing);
2072
+ if (
2073
+ landing.fadeIn?.isBorrowed === true ||
2074
+ landing.restoreIsBorrowed === true
2075
+ ) {
2076
+ // The call's own opacity owns it now, not the stylesheet's.
2077
+ borrowedOpacity = null;
2078
+ }
2079
+ for (const owner of [landing.owner, ...landing.carried]) {
2080
+ carriedOwners.delete(owner);
2081
+ if (!owner.settled) {
2082
+ settle(owner, false);
2083
+ }
2084
+ }
2085
+ }
2086
+ };
2087
+
2088
+ /** Reduce Motion calls that named their own opacity. */
2089
+ const namedOpacity = new WeakSet<HandleState>();
2090
+
2091
+ /**
2092
+ * Where opacity was heading before a call took the waiting landings over:
2093
+ * an entrance by role that catches an exit fades back to what the exit
2094
+ * would have restored.
2095
+ */
2096
+ let headingBeforeTakeOver: number | null = null;
2097
+
2098
+ /** What the Reduce Motion planner reads of this animator. */
2099
+ const planView: ReducedMotionView = {
2100
+ valueAt,
2101
+ opacityHeading: () => headingBeforeTakeOver ?? opacityHeading(),
2102
+ ownOpacity: () => ownOpacity(),
2103
+ writesOwnOpacity: () => writesOwnOpacity(),
2104
+ get borrowedOpacity() {
2105
+ return borrowedOpacity;
2106
+ },
2107
+ get hasOpacityCurve() {
2108
+ return segments.has('opacity');
2109
+ },
2110
+ get restingOpacity() {
2111
+ return resting.opacity;
2112
+ },
2113
+ get hasPendingLanding() {
2114
+ return landings.size > 0;
2115
+ },
2116
+ };
2117
+
2118
+ /**
2119
+ * Reduced Motion (see the file header): the planner's plan
2120
+ * (reducedMotionPlan.ts) as this call's segments.
2121
+ */
2122
+ const reducedMotion = (
2123
+ owner: HandleState,
2124
+ time: number,
2125
+ targets: Partial<Record<MotionProperty, number>>,
2126
+ properties: MotionProperty[],
2127
+ fade: boolean,
2128
+ role?: 'entrance' | 'exit',
2129
+ ): ReducedPlan => {
2130
+ const heading = opacityHeading();
2131
+ // An entrance or an exit by role drives the opacity as a named one does.
2132
+ takeOverLandings(properties, targets.opacity != null || role != null);
2133
+ if (targets.opacity != null) {
2134
+ namedOpacity.add(owner);
2135
+ }
2136
+ headingBeforeTakeOver = heading;
2137
+ let plan: ReturnType<typeof planReducedMotion>;
2138
+ try {
2139
+ plan = planReducedMotion(planView, time, targets, properties, fade, role);
2140
+ } finally {
2141
+ headingBeforeTakeOver = null;
2142
+ }
2143
+ const next: Partial<Record<MotionProperty, Segment | null>> = {};
2144
+ for (const property of plan.atOnce) {
2145
+ next[property] = null;
2146
+ }
2147
+ if (plan.opacityFade != null) {
2148
+ next.opacity = fadeSegment(owner, time, plan.opacityFade);
2149
+ }
2150
+ return {
2151
+ next,
2152
+ holds: plan.holds,
2153
+ landing: plan.landing,
2154
+ borrowed: plan.borrowed,
2155
+ };
2156
+ };
2157
+
2158
+ const animator: Animator = {
2159
+ get element() {
2160
+ return target;
2161
+ },
2162
+
2163
+ reducedMotion(reducedOptions = {}) {
2164
+ if (!prefersReducedMotion()) {
2165
+ return 'off';
2166
+ }
2167
+ return isCoarsePointer() || reducedOptions.touchRelease === true
2168
+ ? 'crossfade'
2169
+ : 'instant';
2170
+ },
2171
+
2172
+ attach(next) {
2173
+ if (next === target) {
2174
+ return;
2175
+ }
2176
+ if (next == null) {
2177
+ // Unmount, unless a node replaces this one in the same task (React's
2178
+ // replacement order: attach(null), then the new node): nothing is
2179
+ // left to animate, so at the end of the task every other handle
2180
+ // settles as interrupted, every atRest() wait settles and no
2181
+ // completion timer outlives the element, as in dispose()
2182
+ // (architecture:react-component-runtime INV5). A replacement keeps
2183
+ // them all: the motion goes on on the new node.
2184
+ lastDetached = target;
2185
+ if (!unmountQueued) {
2186
+ unmountQueued = true;
2187
+ queueMicrotask(() => {
2188
+ if (!unmountQueued) {
2189
+ return;
2190
+ }
2191
+ unmountQueued = false;
2192
+ // A Reduce Motion move still waiting lands where it was going, as
2193
+ // in dispose(), on the node just detached too: a dip's fade out
2194
+ // left its low opacity inline there, so a later attach of that
2195
+ // node (a Suspense or Activity reveal) shows it landed and
2196
+ // visible. Its calls settle as interrupted.
2197
+ onLastDetached(() => {
2198
+ landPending(false);
2199
+ // The landing's commit rebuilt every channel it touched on the
2200
+ // detached node, any axis still moving included: leave that
2201
+ // node with no animation, timer or promotion.
2202
+ for (const animation of running.values()) {
2203
+ animation.cancel();
2204
+ }
2205
+ running.clear();
2206
+ for (const timer of retireTimers.values()) {
2207
+ clearTimeout(timer);
2208
+ }
2209
+ retireTimers.clear();
2210
+ demote();
2211
+ });
2212
+ lastDetached = null;
2213
+ const time = now();
2214
+ for (const property of PROPERTIES) {
2215
+ interrupt(property, time);
2216
+ }
2217
+ for (const wait of [...restWaits]) {
2218
+ wait.settle();
2219
+ }
2220
+ });
2221
+ }
2222
+ } else {
2223
+ // A node in place of the one just detached: no unmount.
2224
+ unmountQueued = false;
2225
+ lastDetached = null;
2226
+ }
2227
+ // After the landing's commit, which can promote the element again.
2228
+ demote();
2229
+ const isOpacityBorrowed =
2230
+ borrowedOpacity != null ||
2231
+ [...landings].some(landing => landing.restoreIsBorrowed === true);
2232
+ for (const animation of running.values()) {
2233
+ animation.cancel();
2234
+ }
2235
+ running.clear();
2236
+ for (const timer of retireTimers.values()) {
2237
+ clearTimeout(timer);
2238
+ }
2239
+ retireTimers.clear();
2240
+ if (isOpacityBorrowed) {
2241
+ // A running borrowed dip (or an exit by role returning to the
2242
+ // stylesheet) stays in the model through any attach, so a pending
2243
+ // move still lands while the element is invisible; only the
2244
+ // outgoing element gets its stylesheet's opacity back.
2245
+ releaseOwnOpacity();
2246
+ }
2247
+ // Identities the outgoing node holds inline over a stylesheet that
2248
+ // differs, kept through a detach for the node that comes next.
2249
+ if (target != null) {
2250
+ const outgoing = target;
2251
+ heldIdentity = new Set(
2252
+ (Object.keys(CHANNELS) as Channel[]).filter(
2253
+ channel =>
2254
+ outgoing.style.getPropertyValue(channel) ===
2255
+ IDENTITY_TEXT[channel],
2256
+ ),
2257
+ );
2258
+ }
2259
+ const held = heldIdentity;
2260
+ target = next;
2261
+ if (target == null) {
2262
+ return;
2263
+ }
2264
+ heldIdentity = new Set();
2265
+ const time = now();
2266
+ // A borrowed dip that ended while detached hands the opacity back
2267
+ // instead of writing the borrowed value inline.
2268
+ const dip = segments.get('opacity');
2269
+ if (
2270
+ borrowedOpacity != null &&
2271
+ (dip == null || time >= dip.start + dip.duration)
2272
+ ) {
2273
+ borrowedOpacity = null;
2274
+ segments.delete('opacity');
2275
+ resting.opacity = IDENTITY.opacity;
2276
+ }
2277
+ for (const channel of Object.keys(CHANNELS) as Channel[]) {
2278
+ const properties = CHANNELS[channel];
2279
+ const isDefault = properties.every(
2280
+ p => !segments.has(p) && resting[p] === IDENTITY[p],
2281
+ );
2282
+ if (!isDefault) {
2283
+ rebuild(channel, time);
2284
+ } else if (held.has(channel)) {
2285
+ // An identity the animator held inline over a stylesheet that
2286
+ // differs goes onto the new node too (writeInline keeps it only
2287
+ // where the new node's stylesheet still differs).
2288
+ writeInline(channel, property => resting[property]);
2289
+ }
2290
+ }
2291
+ flushReleases();
2292
+ },
2293
+
2294
+ get(property, time = now()) {
2295
+ syncPending();
2296
+ return valueAt(property === 'scale' ? 'scaleX' : property, time);
2297
+ },
2298
+
2299
+ getVelocity(property, time = now()) {
2300
+ syncPending();
2301
+ return velocityAt(property === 'scale' ? 'scaleX' : property, time);
2302
+ },
2303
+
2304
+ set(values) {
2305
+ syncPending();
2306
+ const time = now();
2307
+ const next = expand(values);
2308
+ for (const [property, value] of Object.entries(next) as [
2309
+ MotionProperty,
2310
+ number,
2311
+ ][]) {
2312
+ interrupt(property, time);
2313
+ segments.delete(property);
2314
+ resting[property] = value;
2315
+ }
2316
+ // Direct manipulation: the layer makes each write a composite only.
2317
+ for (const property of Object.keys(next) as MotionProperty[]) {
2318
+ promote(CHANNEL_OF[property]);
2319
+ }
2320
+ commit(Object.keys(next) as MotionProperty[], time);
2321
+ },
2322
+
2323
+ animate(to, transition, animateOptions = {}) {
2324
+ syncPending();
2325
+ const time = animateOptions.at ?? now();
2326
+ const targets = expand(to);
2327
+ const velocities = expand(transition.velocity ?? {});
2328
+ const {owner, finished} = newOwner();
2329
+ lastSpring.set(owner, transition.spring);
2330
+ const properties = Object.keys(targets) as MotionProperty[];
2331
+ const next: Partial<Record<MotionProperty, Segment | null>> = {};
2332
+ let plan: ReducedPlan | null = null;
2333
+
2334
+ if (prefersReducedMotion()) {
2335
+ plan = reducedMotion(
2336
+ owner,
2337
+ time,
2338
+ targets,
2339
+ properties,
2340
+ isCoarsePointer() || animateOptions.touchRelease === true,
2341
+ animateOptions.crossfadeAs,
2342
+ );
2343
+ Object.assign(next, plan.next);
2344
+ } else {
2345
+ for (const property of properties) {
2346
+ const velocity = velocities[property] ?? velocityAt(property, time);
2347
+ next[property] = springSegment(
2348
+ owner,
2349
+ property,
2350
+ time,
2351
+ targets[property] as number,
2352
+ transition.spring,
2353
+ velocity,
2354
+ );
2355
+ }
2356
+ }
2357
+
2358
+ const group = beginGroup(
2359
+ time,
2360
+ Object.keys(next) as MotionProperty[],
2361
+ animateOptions.at,
2362
+ );
2363
+ const adopted =
2364
+ plan?.landing != null
2365
+ ? adoptLandings(plan.landing, Object.keys(next) as MotionProperty[])
2366
+ : null;
2367
+ const changed: MotionProperty[] = [];
2368
+ for (const [property, segment] of Object.entries(next) as [
2369
+ MotionProperty,
2370
+ Segment | null,
2371
+ ][]) {
2372
+ interrupt(property, time);
2373
+ changed.push(property);
2374
+ if (segment == null) {
2375
+ // Read before the segment goes: valueAt falls back to resting.
2376
+ const value =
2377
+ plan?.holds[property] ??
2378
+ targets[property] ??
2379
+ valueAt(property, time);
2380
+ segments.delete(property);
2381
+ resting[property] = value;
2382
+ } else {
2383
+ segments.set(property, segment);
2384
+ }
2385
+ }
2386
+ commitCall(group, owner, changed, time);
2387
+ if (plan?.borrowed != null) {
2388
+ // The dip's own commit cleared it; the borrow lasts the dip.
2389
+ borrowedOpacity = plan.borrowed;
2390
+ }
2391
+ const handle = makeHandle(owner, changed, finished, time, group);
2392
+ if (plan?.landing != null) {
2393
+ scheduleLanding(owner, handle.started, plan.landing, adopted);
2394
+ }
2395
+ return handle;
2396
+ },
2397
+
2398
+ play(curves, playOptions = {}) {
2399
+ syncPending();
2400
+ const time = playOptions.at ?? now();
2401
+ const {owner, finished} = newOwner();
2402
+ const byProperty: Partial<Record<MotionProperty, MotionCurve>> = {};
2403
+ // `scale` first, so an explicit `scaleX` or `scaleY` beside it wins.
2404
+ const entries = (
2405
+ Object.entries(curves) as [
2406
+ MotionProperty | 'scale',
2407
+ MotionCurve | undefined,
2408
+ ][]
2409
+ ).sort(([a], [b]) => Number(b === 'scale') - Number(a === 'scale'));
2410
+ for (const [key, curve] of entries) {
2411
+ if (curve == null) {
2412
+ continue;
2413
+ }
2414
+ if (!Number.isFinite(curve.duration) || curve.duration < 0) {
2415
+ throw new RangeError(
2416
+ `animator: a curve needs a finite duration ≥ 0 (got ${curve.duration})`,
2417
+ );
2418
+ }
2419
+ for (const property of expandList([key])) {
2420
+ byProperty[property] = curve;
2421
+ }
2422
+ }
2423
+ const properties = Object.keys(byProperty) as MotionProperty[];
2424
+ const targets: Partial<Record<MotionProperty, number>> = {};
2425
+ for (const property of properties) {
2426
+ const curve = byProperty[property] as MotionCurve;
2427
+ targets[property] = curve.at(curve.duration);
2428
+ }
2429
+ const plan = prefersReducedMotion()
2430
+ ? reducedMotion(
2431
+ owner,
2432
+ time,
2433
+ targets,
2434
+ properties,
2435
+ isCoarsePointer() || playOptions.touchRelease === true,
2436
+ playOptions.crossfadeAs,
2437
+ )
2438
+ : null;
2439
+ const next: Partial<Record<MotionProperty, Segment | null>> = {
2440
+ ...plan?.next,
2441
+ };
2442
+ for (const property of properties) {
2443
+ if (property in next) {
2444
+ continue;
2445
+ }
2446
+ const curve = byProperty[property] as MotionCurve;
2447
+ next[property] =
2448
+ curve.duration === 0
2449
+ ? null
2450
+ : {
2451
+ start: time,
2452
+ duration: Math.min(MAX_DURATION_MS, curve.duration * 1000),
2453
+ target: targets[property] as number,
2454
+ at: t => curve.at(t / 1000),
2455
+ speed: t => curve.velocity(t / 1000),
2456
+ jumps: [],
2457
+ owner,
2458
+ };
2459
+ }
2460
+ const group = beginGroup(
2461
+ time,
2462
+ Object.keys(next) as MotionProperty[],
2463
+ playOptions.at,
2464
+ );
2465
+ const adopted =
2466
+ plan?.landing != null
2467
+ ? adoptLandings(plan.landing, Object.keys(next) as MotionProperty[])
2468
+ : null;
2469
+ const changed: MotionProperty[] = [];
2470
+ for (const [property, segment] of Object.entries(next) as [
2471
+ MotionProperty,
2472
+ Segment | null,
2473
+ ][]) {
2474
+ interrupt(property, time);
2475
+ changed.push(property);
2476
+ if (segment == null) {
2477
+ // Read before the segment goes: valueAt falls back to resting.
2478
+ const value =
2479
+ plan?.holds[property] ??
2480
+ targets[property] ??
2481
+ valueAt(property, time);
2482
+ segments.delete(property);
2483
+ resting[property] = value;
2484
+ } else {
2485
+ segments.set(property, segment);
2486
+ }
2487
+ }
2488
+ commitCall(group, owner, changed, time);
2489
+ if (plan?.borrowed != null) {
2490
+ // The dip's own commit cleared it; the borrow lasts the dip.
2491
+ borrowedOpacity = plan.borrowed;
2492
+ }
2493
+ const handle = makeHandle(owner, changed, finished, time, group);
2494
+ if (plan?.landing != null) {
2495
+ scheduleLanding(owner, handle.started, plan.landing, adopted);
2496
+ }
2497
+ return handle;
2498
+ },
2499
+
2500
+ decay(curves, decayOptions = {}) {
2501
+ syncPending();
2502
+ const time = decayOptions.at ?? now();
2503
+ // Under Reduce Motion only momentum keeps moving (DR2, DEC-2): a curve
2504
+ // that is a transition plays as `animate` does, a cross-fade or at once.
2505
+ const reduce = prefersReducedMotion();
2506
+ const transitions: MotionValues = {};
2507
+ for (const property of DECAY_PROPERTIES) {
2508
+ const curve = curves[property];
2509
+ if (reduce && curve?.isTransition === true) {
2510
+ transitions[property] = curve.at(curve.duration);
2511
+ }
2512
+ }
2513
+ const transitioned =
2514
+ Object.keys(transitions).length > 0
2515
+ ? animator.animate(transitions, REDUCED_TRANSITION, {
2516
+ at: time,
2517
+ touchRelease: decayOptions.touchRelease,
2518
+ })
2519
+ : null;
2520
+ const {owner, finished} = newOwner();
2521
+ // Momentum moves the translate axes only (DR2's throw exception).
2522
+ const properties = DECAY_PROPERTIES.filter(
2523
+ property =>
2524
+ curves[property] != null && transitions[property] === undefined,
2525
+ );
2526
+ if (transitioned != null && properties.length === 0) {
2527
+ return transitioned;
2528
+ }
2529
+ const group = beginGroup(time, properties, decayOptions.at);
2530
+ for (const property of properties) {
2531
+ const curve = curves[property] as MotionCurve;
2532
+ interrupt(property, time);
2533
+ if (!(curve.duration > 0)) {
2534
+ segments.delete(property);
2535
+ resting[property] = curve.at(0);
2536
+ continue;
2537
+ }
2538
+ segments.set(property, {
2539
+ start: time,
2540
+ duration: Math.min(MAX_DURATION_MS, curve.duration * 1000),
2541
+ target: curve.at(curve.duration),
2542
+ at: t => curve.at(t / 1000),
2543
+ speed: t => curve.velocity(t / 1000),
2544
+ jumps: [],
2545
+ owner,
2546
+ });
2547
+ }
2548
+ commitCall(group, owner, properties, time);
2549
+ const handle = makeHandle(owner, properties, finished, time, group);
2550
+ if (transitioned == null) {
2551
+ return handle;
2552
+ }
2553
+ // One handle for the whole release: the cross-faded axes too.
2554
+ const faded = transitioned;
2555
+ const owns = (property: MotionProperty) =>
2556
+ faded.properties.includes(property);
2557
+ return {
2558
+ ...handle,
2559
+ properties: [...handle.properties, ...faded.properties],
2560
+ started: Promise.all([handle.started, faded.started]).then(
2561
+ ([coasting]) => coasting,
2562
+ ),
2563
+ finished: Promise.all([handle.finished, faded.finished]).then(
2564
+ ([coasted, done]) => coasted && done,
2565
+ ),
2566
+ value: (property, at) =>
2567
+ owns(property)
2568
+ ? faded.value(property, at)
2569
+ : handle.value(property, at),
2570
+ velocity: (property, at) =>
2571
+ owns(property)
2572
+ ? faded.velocity(property, at)
2573
+ : handle.velocity(property, at),
2574
+ stop: () => {
2575
+ handle.stop();
2576
+ faded.stop();
2577
+ },
2578
+ };
2579
+ },
2580
+
2581
+ stop(properties) {
2582
+ syncPending();
2583
+ const time = now();
2584
+ const list = properties == null ? PROPERTIES : expandList(properties);
2585
+ const changed: MotionProperty[] = [];
2586
+ // A borrowed dip, or an exit by role that returns to the stylesheet.
2587
+ const wasBorrowed =
2588
+ borrowedOpacity != null ||
2589
+ [...landings].some(landing => landing.restoreIsBorrowed === true);
2590
+ // Read before the landings go: a dip's fade back in, an exit's restore.
2591
+ const heading = opacityHeading();
2592
+ for (const property of list) {
2593
+ cancelLanding(property);
2594
+ const segment = segments.get(property);
2595
+ if (segment == null) {
2596
+ continue;
2597
+ }
2598
+ // A Reduce Motion fade is never left half done: it finishes, and a
2599
+ // dip on the stylesheet's opacity hands that opacity back.
2600
+ const value = !segment.isFade
2601
+ ? valueAt(property, time)
2602
+ : wasBorrowed
2603
+ ? IDENTITY.opacity
2604
+ : heading;
2605
+ interrupt(property, time);
2606
+ segments.delete(property);
2607
+ resting[property] = value;
2608
+ changed.push(property);
2609
+ }
2610
+ commit(changed, time);
2611
+ if (wasBorrowed && changed.includes('opacity')) {
2612
+ releaseOwnOpacity();
2613
+ }
2614
+ },
2615
+
2616
+ rebase(deltas, rebaseOptions = {}) {
2617
+ syncPending();
2618
+ const time = rebaseOptions.at ?? now();
2619
+ const changed: MotionProperty[] = [];
2620
+ const owners = new Set<HandleState>();
2621
+ for (const [property, delta] of Object.entries(expand(deltas)) as [
2622
+ MotionProperty,
2623
+ number,
2624
+ ][]) {
2625
+ if (delta === 0) {
2626
+ continue;
2627
+ }
2628
+ changed.push(property);
2629
+ const segment = segmentAt(property, time);
2630
+ if (segment == null) {
2631
+ resting[property] = valueAt(property, time) + delta;
2632
+ segments.delete(property);
2633
+ continue;
2634
+ }
2635
+ owners.add(segment.owner);
2636
+ // A curve still waiting for the browser's start stays in its call:
2637
+ // it starts with that call's commit.
2638
+ const group =
2639
+ segment.group != null && !segment.group.resolved
2640
+ ? segment.group
2641
+ : undefined;
2642
+ const replace = (next: Segment) => {
2643
+ if (group != null) {
2644
+ const index = group.segments.indexOf(segment);
2645
+ if (index >= 0) {
2646
+ group.segments[index] = next;
2647
+ } else {
2648
+ group.segments.push(next);
2649
+ }
2650
+ }
2651
+ segments.set(property, next);
2652
+ };
2653
+ if (segment.spring != null) {
2654
+ const from = valueAt(property, time) + delta;
2655
+ const velocity = velocityAt(property, time);
2656
+ const curve = solveSpring(toSpring(segment.spring), {
2657
+ from,
2658
+ to: segment.target,
2659
+ velocity,
2660
+ });
2661
+ replace({
2662
+ start: group?.provisional ?? time,
2663
+ ...(group != null ? {group} : {}),
2664
+ duration: Math.min(
2665
+ MAX_DURATION_MS,
2666
+ curve.settleTime(SETTLE_THRESHOLD[property]) * 1000,
2667
+ ),
2668
+ target: segment.target,
2669
+ at: t => curve.value(t / 1000),
2670
+ speed: t => curve.velocity(t / 1000),
2671
+ jumps: [],
2672
+ owner: segment.owner,
2673
+ spring: segment.spring,
2674
+ });
2675
+ } else {
2676
+ replace({
2677
+ ...segment,
2678
+ target: segment.target + delta,
2679
+ at: t => segment.at(t) + delta,
2680
+ });
2681
+ }
2682
+ }
2683
+ commit(changed, time);
2684
+ // The handles that own the rebased curves finish at their new ends.
2685
+ for (const owner of owners) {
2686
+ if (owner.settled || owner.timer == null) {
2687
+ continue;
2688
+ }
2689
+ clearTimeout(owner.timer);
2690
+ let end = time;
2691
+ for (const segment of segments.values()) {
2692
+ if (segment.owner === owner) {
2693
+ end = Math.max(end, segment.start + segment.duration);
2694
+ }
2695
+ }
2696
+ owner.timer = setTimeout(
2697
+ () => {
2698
+ owner.timer = null;
2699
+ settle(owner, true);
2700
+ },
2701
+ Math.max(0, end - now()),
2702
+ );
2703
+ }
2704
+ },
2705
+
2706
+ async atRest(properties) {
2707
+ const list = properties == null ? PROPERTIES : expandList(properties);
2708
+ return new Promise<void>(resolve => {
2709
+ const wait: RestWait = {timer: null, settle: () => {}};
2710
+ const done = () => {
2711
+ if (wait.timer != null) {
2712
+ clearTimeout(wait.timer);
2713
+ }
2714
+ restWaits.delete(wait);
2715
+ resolve();
2716
+ };
2717
+ wait.settle = done;
2718
+ restWaits.add(wait);
2719
+ const check = () => {
2720
+ wait.timer = null;
2721
+ syncPending();
2722
+ const time = now();
2723
+ let end = time;
2724
+ for (const property of list) {
2725
+ const segment = segments.get(property);
2726
+ if (segment != null) {
2727
+ end = Math.max(end, segment.start + segment.duration);
2728
+ }
2729
+ }
2730
+ if (landings.size > 0) {
2731
+ // A Reduced Motion landing is still to come.
2732
+ wait.timer = setTimeout(check, 16);
2733
+ } else if (end <= time) {
2734
+ done();
2735
+ } else {
2736
+ // A retarget or a later start moves the end: look again then.
2737
+ wait.timer = setTimeout(check, end - time);
2738
+ }
2739
+ };
2740
+ check();
2741
+ });
2742
+ },
2743
+
2744
+ dispose() {
2745
+ // A Reduce Motion move still waiting to land is written at its end
2746
+ // state, so the element is left visible where it was going (the node
2747
+ // just detached, when an unmount is pending); its call and the calls
2748
+ // it carries settle as interrupted.
2749
+ if (target == null && unmountQueued) {
2750
+ target = lastDetached;
2751
+ }
2752
+ lastDetached = null;
2753
+ unmountQueued = false;
2754
+ landPending(false);
2755
+ // Nothing moves any more: every atRest() wait settles.
2756
+ for (const wait of [...restWaits]) {
2757
+ wait.settle();
2758
+ }
2759
+ const time = now();
2760
+ for (const property of PROPERTIES) {
2761
+ interrupt(property, time);
2762
+ }
2763
+ for (const animation of running.values()) {
2764
+ animation.cancel();
2765
+ }
2766
+ running.clear();
2767
+ for (const timer of retireTimers.values()) {
2768
+ clearTimeout(timer);
2769
+ }
2770
+ retireTimers.clear();
2771
+ handBackBorrow();
2772
+ demote();
2773
+ target = null;
2774
+ },
2775
+ };
2776
+
2777
+ animator.attach(element);
2778
+ return animator;
2779
+ }
2780
+
2781
+ function expandList(
2782
+ properties: ReadonlyArray<MotionProperty | 'scale'>,
2783
+ ): MotionProperty[] {
2784
+ const out = new Set<MotionProperty>();
2785
+ for (const property of properties) {
2786
+ if (property === 'scale') {
2787
+ out.add('scaleX');
2788
+ out.add('scaleY');
2789
+ } else {
2790
+ out.add(property);
2791
+ }
2792
+ }
2793
+ return [...out];
2794
+ }