@astryxdesign/core 0.7.7 → 0.7.8-canary.36cde5e

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 (581) hide show
  1. package/dist/AlertDialog/AlertDialog.d.ts +4 -1
  2. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  3. package/dist/AlertDialog/AlertDialog.js +46 -6
  4. package/dist/AppShell/AppShell.d.ts.map +1 -1
  5. package/dist/AppShell/AppShell.js +5 -0
  6. package/dist/BottomSheet/BottomSheet.d.ts.map +1 -1
  7. package/dist/BottomSheet/BottomSheet.js +1 -0
  8. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  9. package/dist/BottomSheet/BottomSheetPanel.js +25 -4
  10. package/dist/BottomSheet/BottomSheetSwitcher.d.ts.map +1 -1
  11. package/dist/BottomSheet/BottomSheetSwitcher.js +5 -0
  12. package/dist/BottomSheet/useMobileKeyboard.d.ts.map +1 -1
  13. package/dist/BottomSheet/useMobileKeyboard.js +6 -0
  14. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  15. package/dist/BottomSheet/useSheetGestures.js +12 -1
  16. package/dist/Button/Button.d.ts.map +1 -1
  17. package/dist/Button/Button.js +17 -1
  18. package/dist/Calendar/Calendar.d.ts.map +1 -1
  19. package/dist/Calendar/Calendar.js +15 -16
  20. package/dist/Carousel/Carousel.d.ts.map +1 -1
  21. package/dist/Carousel/Carousel.js +2 -0
  22. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  23. package/dist/Chat/ChatComposerInput.js +4 -0
  24. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  25. package/dist/Chat/ChatMessageList.js +2 -1
  26. package/dist/Chat/useChatDictation.d.ts.map +1 -1
  27. package/dist/Chat/useChatDictation.js +2 -0
  28. package/dist/Chat/useChatNewMessages.js +1 -1
  29. package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
  30. package/dist/Chat/useChatStreamScroll.js +2 -0
  31. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  32. package/dist/Chat/useSpeechRecognition.js +3 -0
  33. package/dist/Chat/useTriggerMenu.js +1 -1
  34. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  35. package/dist/CheckboxInput/CheckboxInput.js +17 -12
  36. package/dist/CodeBlock/CodeBlock.d.ts +10 -1
  37. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  38. package/dist/CodeBlock/CodeBlock.js +28 -11
  39. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  40. package/dist/CommandPalette/CommandPalette.js +2 -0
  41. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  42. package/dist/CommandPalette/CommandPaletteItem.js +2 -0
  43. package/dist/ComplexSelector/ComplexSelector.d.ts +4 -1
  44. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  45. package/dist/ComplexSelector/ComplexSelector.js +14 -4
  46. package/dist/ContextMenu/ContextMenu.js +2 -2
  47. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  48. package/dist/DateInput/MonthScroller.js +5 -2
  49. package/dist/DateInput/PickerWheel.d.ts +19 -0
  50. package/dist/DateInput/PickerWheel.d.ts.map +1 -0
  51. package/dist/DateInput/PickerWheel.js +625 -0
  52. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  53. package/dist/DateInput/TouchDateField.js +1 -0
  54. package/dist/DateInput/Wheel.d.ts +18 -37
  55. package/dist/DateInput/Wheel.d.ts.map +1 -1
  56. package/dist/DateInput/Wheel.js +84 -113
  57. package/dist/DateInput/useOwnScrollGesture.d.ts +10 -0
  58. package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -1
  59. package/dist/DateInput/useOwnScrollGesture.js +16 -3
  60. package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -1
  61. package/dist/DateInput/usePointerDragScroll.js +2 -0
  62. package/dist/DateInput/useScrollSettle.d.ts.map +1 -1
  63. package/dist/DateInput/useScrollSettle.js +3 -0
  64. package/dist/DateInput/useWheelListbox.d.ts +59 -0
  65. package/dist/DateInput/useWheelListbox.d.ts.map +1 -0
  66. package/dist/DateInput/useWheelListbox.js +88 -0
  67. package/dist/DateInput/wheelOptions.d.ts +74 -0
  68. package/dist/DateInput/wheelOptions.d.ts.map +1 -0
  69. package/dist/DateInput/wheelOptions.js +98 -0
  70. package/dist/DateInput/wheelPhysics.d.ts +127 -0
  71. package/dist/DateInput/wheelPhysics.d.ts.map +1 -0
  72. package/dist/DateInput/wheelPhysics.js +341 -0
  73. package/dist/DateInput/wheelStrip.d.ts +92 -0
  74. package/dist/DateInput/wheelStrip.d.ts.map +1 -0
  75. package/dist/DateInput/wheelStrip.js +258 -0
  76. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  77. package/dist/DateTimeInput/TouchDateTimeField.js +2 -0
  78. package/dist/Dialog/Dialog.d.ts.map +1 -1
  79. package/dist/Dialog/Dialog.js +9 -32
  80. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  81. package/dist/Drawer/useDrawerDialogPresence.js +3 -0
  82. package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -1
  83. package/dist/DropdownMenu/useMenuOverflow.js +5 -0
  84. package/dist/Field/Field.js +2 -2
  85. package/dist/FieldStatus/useFieldStatusAnnouncement.d.ts.map +1 -1
  86. package/dist/FieldStatus/useFieldStatusAnnouncement.js +1 -0
  87. package/dist/FormLayout/FormLayout.d.ts +5 -1
  88. package/dist/FormLayout/FormLayout.d.ts.map +1 -1
  89. package/dist/HoverCard/HoverCard.d.ts +6 -4
  90. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  91. package/dist/HoverCard/HoverCard.js +48 -3
  92. package/dist/HoverCard/useHoverCard.d.ts +5 -4
  93. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  94. package/dist/HoverCard/useHoverCard.js +20 -33
  95. package/dist/Icon/Icon.d.ts +5 -1
  96. package/dist/Icon/Icon.d.ts.map +1 -1
  97. package/dist/Icon/Icon.js +5 -2
  98. package/dist/Item/useSwipeAction.d.ts.map +1 -1
  99. package/dist/Item/useSwipeAction.js +3 -0
  100. package/dist/Layer/modalOutlet.d.ts.map +1 -1
  101. package/dist/Layer/modalOutlet.js +2 -0
  102. package/dist/Layer/outsidePress.d.ts.map +1 -1
  103. package/dist/Layer/outsidePress.js +1 -0
  104. package/dist/Layer/useLayer.d.ts.map +1 -1
  105. package/dist/Layer/useLayer.js +3 -0
  106. package/dist/Layer/useLayerDismissal.d.ts.map +1 -1
  107. package/dist/Layer/useLayerDismissal.js +3 -0
  108. package/dist/Layer/usePressPin.d.ts +17 -5
  109. package/dist/Layer/usePressPin.d.ts.map +1 -1
  110. package/dist/Layer/usePressPin.js +62 -12
  111. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  112. package/dist/Layer/useTouchTrigger.js +3 -0
  113. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  114. package/dist/Lightbox/Lightbox.js +19 -0
  115. package/dist/MobileNav/MobileNav.d.ts +3 -2
  116. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  117. package/dist/MobileNav/MobileNav.js +9 -25
  118. package/dist/Outline/useOutlineFromDOM.d.ts.map +1 -1
  119. package/dist/Outline/useOutlineFromDOM.js +3 -0
  120. package/dist/Outline/useScrollSpy.d.ts.map +1 -1
  121. package/dist/Outline/useScrollSpy.js +3 -0
  122. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  123. package/dist/OverflowList/OverflowList.js +3 -0
  124. package/dist/Popover/Popover.d.ts.map +1 -1
  125. package/dist/Popover/Popover.js +6 -0
  126. package/dist/PowerSearch/PowerSearch.d.ts +43 -4
  127. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  128. package/dist/PowerSearch/PowerSearch.js +445 -134
  129. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +102 -0
  130. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -0
  131. package/dist/PowerSearch/PowerSearchBottomSheet.js +1919 -0
  132. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +35 -2
  133. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  134. package/dist/PowerSearch/PowerSearchEditPopover.js +25 -6
  135. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts +1 -1
  136. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts.map +1 -1
  137. package/dist/PowerSearch/PowerSearchFilterEditor.js +4 -2
  138. package/dist/PowerSearch/PowerSearchToken.d.ts +1 -1
  139. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  140. package/dist/PowerSearch/PowerSearchToken.js +7 -2
  141. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +38 -3
  142. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  143. package/dist/PowerSearch/PowerSearchValueEditor.js +193 -83
  144. package/dist/PowerSearch/formatFilterValue.d.ts +18 -6
  145. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  146. package/dist/PowerSearch/formatFilterValue.js +33 -12
  147. package/dist/PowerSearch/formatTokenValue.d.ts +28 -0
  148. package/dist/PowerSearch/formatTokenValue.d.ts.map +1 -0
  149. package/dist/PowerSearch/formatTokenValue.js +162 -0
  150. package/dist/PowerSearch/powerSearchDateZone.d.ts +21 -0
  151. package/dist/PowerSearch/powerSearchDateZone.d.ts.map +1 -0
  152. package/dist/PowerSearch/powerSearchDateZone.js +37 -0
  153. package/dist/PowerSearch/powerSearchSheetUtils.d.ts +65 -0
  154. package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +1 -0
  155. package/dist/PowerSearch/powerSearchSheetUtils.js +168 -0
  156. package/dist/PowerSearch/types.d.ts +2 -0
  157. package/dist/PowerSearch/types.d.ts.map +1 -1
  158. package/dist/ProgressBar/ProgressBarTouch.d.ts.map +1 -1
  159. package/dist/ProgressBar/ProgressBarTouch.js +2 -0
  160. package/dist/RadioList/RadioList.d.ts.map +1 -1
  161. package/dist/RadioList/RadioList.js +3 -2
  162. package/dist/RadioList/RadioListItem.d.ts +1 -1
  163. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  164. package/dist/RadioList/RadioListItem.js +5 -3
  165. package/dist/Resizable/ResizeHandle.d.ts +2 -1
  166. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  167. package/dist/Resizable/ResizeHandle.js +101 -77
  168. package/dist/Resizable/createResizable.d.ts +145 -0
  169. package/dist/Resizable/createResizable.d.ts.map +1 -0
  170. package/dist/Resizable/createResizable.js +575 -0
  171. package/dist/Resizable/useResizable.d.ts +3 -3
  172. package/dist/Resizable/useResizable.d.ts.map +1 -1
  173. package/dist/Resizable/useResizable.js +252 -459
  174. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -1
  175. package/dist/SegmentedControl/useSegmentedSelectionMotion.js +3 -3
  176. package/dist/SelectableCard/SelectableCard.d.ts +2 -0
  177. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  178. package/dist/SelectableCard/SelectableCard.js +36 -11
  179. package/dist/SelectableCard/selectableCardInput.d.ts +12 -0
  180. package/dist/SelectableCard/selectableCardInput.d.ts.map +1 -0
  181. package/dist/SelectableCard/selectableCardInput.js +20 -0
  182. package/dist/Selector/Selector.d.ts.map +1 -1
  183. package/dist/Selector/Selector.js +5 -8
  184. package/dist/Slider/sliderTouchController.js +2 -2
  185. package/dist/Spinner/Spinner.d.ts +1 -1
  186. package/dist/Spinner/Spinner.d.ts.map +1 -1
  187. package/dist/Spinner/Spinner.js +60 -58
  188. package/dist/Switch/Switch.d.ts.map +1 -1
  189. package/dist/Switch/Switch.js +4 -10
  190. package/dist/Switch/useSwitchTouch.js +4 -4
  191. package/dist/Table/BaseTable.d.ts.map +1 -1
  192. package/dist/Table/BaseTable.js +29 -8
  193. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  194. package/dist/Table/plugins/columnResize/useTableColumnResize.js +3 -1
  195. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  196. package/dist/Table/plugins/filtering/useTableFiltering.js +2 -1
  197. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  198. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +4 -0
  199. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  200. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +2 -0
  201. package/dist/TextInput/TextInput.d.ts +2 -2
  202. package/dist/TextInput/TextInput.d.ts.map +1 -1
  203. package/dist/TextInput/TextInput.js +10 -7
  204. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  205. package/dist/TimeInput/TimeInput.js +2 -0
  206. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  207. package/dist/TimeInput/TouchTimeField.js +2 -0
  208. package/dist/Timer/Timer.d.ts.map +1 -1
  209. package/dist/Timer/Timer.js +2 -0
  210. package/dist/Timestamp/Timestamp.js +1 -1
  211. package/dist/Toast/Toast.d.ts +11 -1
  212. package/dist/Toast/Toast.d.ts.map +1 -1
  213. package/dist/Toast/Toast.js +25 -15
  214. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  215. package/dist/Toast/ToastViewport.js +97 -34
  216. package/dist/Toast/types.d.ts +9 -3
  217. package/dist/Toast/types.d.ts.map +1 -1
  218. package/dist/Toast/useToast.d.ts.map +1 -1
  219. package/dist/Toast/useToast.js +1 -0
  220. package/dist/Tokenizer/Tokenizer.d.ts +49 -37
  221. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  222. package/dist/Tokenizer/Tokenizer.js +22 -19
  223. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +1 -1
  224. package/dist/Tokenizer/TokenizerBottomSheet.js +1 -1
  225. package/dist/Tokenizer/index.d.ts +1 -1
  226. package/dist/Tokenizer/index.d.ts.map +1 -1
  227. package/dist/Tooltip/useTooltip.d.ts +19 -1
  228. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  229. package/dist/Tooltip/useTooltip.js +34 -53
  230. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  231. package/dist/Typeahead/BaseTypeahead.js +27 -18
  232. package/dist/Typeahead/TypeaheadItem.d.ts +2 -1
  233. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  234. package/dist/animator/createAnimator.d.ts +98 -0
  235. package/dist/animator/createAnimator.d.ts.map +1 -0
  236. package/dist/animator/createAnimator.js +259 -0
  237. package/dist/astryx.css +39 -6
  238. package/dist/gestures/GestureHost.d.ts +16 -1
  239. package/dist/gestures/GestureHost.d.ts.map +1 -1
  240. package/dist/gestures/GestureHost.js +1 -1
  241. package/dist/gestures/PressTracker.d.ts.map +1 -1
  242. package/dist/gestures/PressTracker.js +4 -3
  243. package/dist/hooks/ModalAnnounceProvider.d.ts.map +1 -1
  244. package/dist/hooks/ModalAnnounceProvider.js +1 -0
  245. package/dist/hooks/actionGroupTracker.d.ts +4 -1
  246. package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
  247. package/dist/hooks/actionGroupTracker.js +13 -3
  248. package/dist/hooks/index.d.ts +1 -0
  249. package/dist/hooks/index.d.ts.map +1 -1
  250. package/dist/hooks/index.js +1 -0
  251. package/dist/hooks/longPressDetector.d.ts +66 -0
  252. package/dist/hooks/longPressDetector.d.ts.map +1 -0
  253. package/dist/hooks/longPressDetector.js +200 -0
  254. package/dist/hooks/pressGroupContext.d.ts +6 -0
  255. package/dist/hooks/pressGroupContext.d.ts.map +1 -0
  256. package/dist/hooks/pressGroupContext.js +20 -0
  257. package/dist/hooks/rootScrollStyles.d.ts +48 -0
  258. package/dist/hooks/rootScrollStyles.d.ts.map +1 -0
  259. package/dist/hooks/rootScrollStyles.js +207 -0
  260. package/dist/hooks/scrollLockTouchGuard.d.ts +13 -0
  261. package/dist/hooks/scrollLockTouchGuard.d.ts.map +1 -0
  262. package/dist/hooks/scrollLockTouchGuard.js +134 -0
  263. package/dist/hooks/scrollbarGutter.d.ts +4 -4
  264. package/dist/hooks/scrollbarGutter.d.ts.map +1 -1
  265. package/dist/hooks/scrollbarGutter.js +36 -23
  266. package/dist/hooks/useActionGroupTracking.d.ts +53 -0
  267. package/dist/hooks/useActionGroupTracking.d.ts.map +1 -0
  268. package/dist/hooks/useActionGroupTracking.js +174 -0
  269. package/dist/hooks/useAnimator.d.ts +41 -0
  270. package/dist/hooks/useAnimator.d.ts.map +1 -0
  271. package/dist/hooks/useAnimator.js +70 -0
  272. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  273. package/dist/hooks/useAnnounceRenderedText.js +1 -0
  274. package/dist/hooks/useAttachment.d.ts +1 -1
  275. package/dist/hooks/useAttachment.js +1 -1
  276. package/dist/hooks/useAutoMediaMode.d.ts.map +1 -1
  277. package/dist/hooks/useAutoMediaMode.js +1 -0
  278. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  279. package/dist/hooks/useBusyAnnouncement.js +2 -0
  280. package/dist/hooks/useDevWarning.d.ts.map +1 -1
  281. package/dist/hooks/useDevWarning.js +2 -0
  282. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  283. package/dist/hooks/useFocusTrap.js +2 -0
  284. package/dist/hooks/useGridFocus.d.ts +8 -5
  285. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  286. package/dist/hooks/useGridFocus.js +4 -3
  287. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  288. package/dist/hooks/useHotkeys.js +3 -0
  289. package/dist/hooks/useImageMode.d.ts.map +1 -1
  290. package/dist/hooks/useImageMode.js +3 -0
  291. package/dist/hooks/useInputStatusIcon.d.ts +1 -1
  292. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  293. package/dist/hooks/useInputStatusIcon.js +2 -2
  294. package/dist/hooks/useKeyboardHint.js +1 -1
  295. package/dist/hooks/useLongPress.d.ts +8 -9
  296. package/dist/hooks/useLongPress.d.ts.map +1 -1
  297. package/dist/hooks/useLongPress.js +23 -106
  298. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  299. package/dist/hooks/useMenuHover.js +2 -0
  300. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  301. package/dist/hooks/useMenuPress.js +3 -0
  302. package/dist/hooks/useOverflow.d.ts.map +1 -1
  303. package/dist/hooks/useOverflow.js +2 -1
  304. package/dist/hooks/usePressFeedback.d.ts.map +1 -1
  305. package/dist/hooks/usePressFeedback.js +1 -0
  306. package/dist/hooks/useResolvedRequired.d.ts +3 -0
  307. package/dist/hooks/useResolvedRequired.d.ts.map +1 -1
  308. package/dist/hooks/useResolvedRequired.js +3 -0
  309. package/dist/hooks/useScrollLock.d.ts +7 -9
  310. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  311. package/dist/hooks/useScrollLock.js +55 -48
  312. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  313. package/dist/hooks/useScrollableArea.js +5 -0
  314. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  315. package/dist/hooks/useStreamingText.js +3 -0
  316. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +8 -0
  317. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -0
  318. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +42 -0
  319. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
  320. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +6 -0
  321. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +8 -0
  322. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +1 -0
  323. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +14 -0
  324. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  325. package/dist/i18n/generated-locales/en.generated.js +30 -0
  326. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  327. package/dist/i18n/generated-locales/pseudo.generated.js +30 -0
  328. package/dist/index.d.ts +1 -0
  329. package/dist/index.d.ts.map +1 -1
  330. package/dist/index.js +4 -0
  331. package/dist/internal/indicatorPress.stylex.d.ts +20 -0
  332. package/dist/internal/indicatorPress.stylex.d.ts.map +1 -0
  333. package/dist/internal/indicatorPress.stylex.js +26 -0
  334. package/dist/internal/selectable-card.d.ts +21 -0
  335. package/dist/internal/selectable-card.d.ts.map +1 -0
  336. package/dist/internal/selectable-card.js +20 -0
  337. package/dist/internal/sheetDraft.d.ts +2 -2
  338. package/dist/internal/sheetDraft.js +2 -2
  339. package/dist/motion/animatedLayout.d.ts.map +1 -1
  340. package/dist/motion/animatedLayout.js +7 -7
  341. package/dist/motion/animator.d.ts +14 -14
  342. package/dist/motion/animator.d.ts.map +1 -1
  343. package/dist/motion/animator.js +45 -20
  344. package/dist/motion/progress.d.ts +88 -0
  345. package/dist/motion/progress.d.ts.map +1 -0
  346. package/dist/motion/progress.js +128 -0
  347. package/dist/motion/reducedMotion.d.ts.map +1 -1
  348. package/dist/motion/reducedMotion.js +3 -1
  349. package/dist/motion/uikit/alert.d.ts +41 -0
  350. package/dist/motion/uikit/alert.d.ts.map +1 -0
  351. package/dist/motion/uikit/alert.js +43 -0
  352. package/dist/motion/uikit/index.d.ts +4 -3
  353. package/dist/motion/uikit/index.d.ts.map +1 -1
  354. package/dist/motion/uikit/index.js +4 -3
  355. package/dist/motion/uikit/picker.d.ts +96 -0
  356. package/dist/motion/uikit/picker.d.ts.map +1 -0
  357. package/dist/motion/uikit/picker.js +117 -0
  358. package/dist/privateAttributes/pressGroupItem.stylex.d.ts +22 -0
  359. package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +1 -0
  360. package/dist/privateAttributes/pressGroupItem.stylex.js +36 -0
  361. package/dist/privateAttributes/reducedMotion.stylex.d.ts +23 -0
  362. package/dist/privateAttributes/reducedMotion.stylex.d.ts.map +1 -0
  363. package/dist/privateAttributes/reducedMotion.stylex.js +40 -0
  364. package/dist/theme/Theme.d.ts.map +1 -1
  365. package/dist/theme/Theme.js +29 -4
  366. package/dist/theme/motionKnobs.d.ts +4 -3
  367. package/dist/theme/motionKnobs.d.ts.map +1 -1
  368. package/dist/theme/motionKnobs.js +3 -2
  369. package/dist/theme/themeMotion.d.ts +6 -0
  370. package/dist/theme/themeMotion.d.ts.map +1 -1
  371. package/dist/theme/themeMotion.js +7 -0
  372. package/dist/utils/dateParser.d.ts.map +1 -1
  373. package/dist/utils/dateParser.js +12 -0
  374. package/dist/utils/focusReturn.d.ts +15 -0
  375. package/dist/utils/focusReturn.d.ts.map +1 -1
  376. package/dist/utils/focusReturn.js +28 -0
  377. package/dist/utils/interactionModality.d.ts.map +1 -1
  378. package/dist/utils/interactionModality.js +4 -0
  379. package/dist/utils/interactionOverlay.stylex.d.ts +3 -2
  380. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  381. package/dist/utils/interactionOverlay.stylex.js +3 -2
  382. package/dist/utils/plainDate.d.ts +8 -0
  383. package/dist/utils/plainDate.d.ts.map +1 -1
  384. package/dist/utils/plainDate.js +19 -0
  385. package/dist/utils/pressFeedback.d.ts.map +1 -1
  386. package/dist/utils/pressFeedback.js +20 -6
  387. package/dist/utils/triggerFocus.d.ts +36 -0
  388. package/dist/utils/triggerFocus.d.ts.map +1 -0
  389. package/dist/utils/triggerFocus.js +65 -0
  390. package/locales/en.json +120 -0
  391. package/locales/pseudo.json +90 -0
  392. package/package.json +14 -9
  393. package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
  394. package/src/AlertDialog/AlertDialog.tsx +46 -5
  395. package/src/AppShell/AppShell.tsx +4 -0
  396. package/src/BottomSheet/BottomSheet.tsx +1 -0
  397. package/src/BottomSheet/BottomSheetPanel.tsx +39 -3
  398. package/src/BottomSheet/BottomSheetSwitcher.tsx +5 -0
  399. package/src/BottomSheet/useMobileKeyboard.ts +4 -0
  400. package/src/BottomSheet/useSheetGestures.ts +10 -1
  401. package/src/Button/Button.tsx +26 -4
  402. package/src/Calendar/Calendar.tsx +36 -25
  403. package/src/Carousel/Carousel.tsx +1 -0
  404. package/src/Chat/ChatComposerInput.tsx +2 -0
  405. package/src/Chat/ChatMessageList.tsx +2 -1
  406. package/src/Chat/useChatDictation.ts +1 -0
  407. package/src/Chat/useChatNewMessages.ts +1 -1
  408. package/src/Chat/useChatStreamScroll.ts +2 -0
  409. package/src/Chat/useSpeechRecognition.ts +2 -0
  410. package/src/Chat/useTriggerMenu.tsx +1 -1
  411. package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -0
  412. package/src/CheckboxInput/CheckboxInput.tsx +38 -15
  413. package/src/CodeBlock/CodeBlock.doc.mjs +9 -1
  414. package/src/CodeBlock/CodeBlock.tsx +41 -4
  415. package/src/CommandPalette/CommandPalette.tsx +1 -0
  416. package/src/CommandPalette/CommandPaletteItem.tsx +1 -0
  417. package/src/ComplexSelector/ComplexSelector.tsx +20 -5
  418. package/src/ContextMenu/ContextMenu.tsx +2 -2
  419. package/src/DateInput/MonthScroller.tsx +8 -2
  420. package/src/DateInput/PickerWheel.tsx +765 -0
  421. package/src/DateInput/TouchDateField.tsx +1 -0
  422. package/src/DateInput/Wheel.tsx +94 -150
  423. package/src/DateInput/useOwnScrollGesture.ts +25 -3
  424. package/src/DateInput/usePointerDragScroll.ts +1 -0
  425. package/src/DateInput/useScrollSettle.ts +2 -0
  426. package/src/DateInput/useWheelListbox.ts +112 -0
  427. package/src/DateInput/wheelOptions.ts +155 -0
  428. package/src/DateInput/wheelPhysics.ts +406 -0
  429. package/src/DateInput/wheelStrip.ts +341 -0
  430. package/src/DateTimeInput/TouchDateTimeField.tsx +2 -0
  431. package/src/Dialog/Dialog.tsx +12 -32
  432. package/src/Drawer/useDrawerDialogPresence.ts +2 -0
  433. package/src/DropdownMenu/useMenuOverflow.ts +3 -0
  434. package/src/Field/Field.tsx +2 -2
  435. package/src/FieldStatus/useFieldStatusAnnouncement.ts +1 -0
  436. package/src/FormLayout/FormLayout.doc.mjs +181 -46
  437. package/src/FormLayout/FormLayout.tsx +5 -1
  438. package/src/HoverCard/HoverCard.doc.mjs +10 -8
  439. package/src/HoverCard/HoverCard.tsx +58 -6
  440. package/src/HoverCard/useHoverCard.doc.mjs +178 -36
  441. package/src/HoverCard/useHoverCard.tsx +49 -54
  442. package/src/Icon/Icon.doc.mjs +49 -8
  443. package/src/Icon/Icon.tsx +15 -7
  444. package/src/IconButton/IconButton.doc.mjs +141 -21
  445. package/src/Item/useSwipeAction.ts +2 -0
  446. package/src/Layer/modalOutlet.ts +2 -0
  447. package/src/Layer/outsidePress.ts +1 -0
  448. package/src/Layer/useLayer.tsx +2 -0
  449. package/src/Layer/useLayerDismissal.ts +2 -0
  450. package/src/Layer/usePressPin.ts +81 -15
  451. package/src/Layer/useTouchTrigger.ts +2 -0
  452. package/src/Lightbox/Lightbox.tsx +19 -0
  453. package/src/MobileNav/MobileNav.tsx +9 -30
  454. package/src/Outline/useOutlineFromDOM.ts +2 -0
  455. package/src/Outline/useScrollSpy.ts +2 -0
  456. package/src/OverflowList/OverflowList.tsx +2 -0
  457. package/src/Popover/Popover.tsx +4 -0
  458. package/src/PowerSearch/PowerSearch.doc.mjs +60 -8
  459. package/src/PowerSearch/PowerSearch.tsx +627 -157
  460. package/src/PowerSearch/PowerSearchBottomSheet.tsx +2525 -0
  461. package/src/PowerSearch/PowerSearchEditPopover.tsx +39 -6
  462. package/src/PowerSearch/PowerSearchFilterEditor.tsx +2 -0
  463. package/src/PowerSearch/PowerSearchToken.tsx +7 -0
  464. package/src/PowerSearch/PowerSearchValueEditor.tsx +244 -58
  465. package/src/PowerSearch/formatFilterValue.ts +55 -17
  466. package/src/PowerSearch/formatTokenValue.ts +222 -0
  467. package/src/PowerSearch/powerSearchDateZone.ts +64 -0
  468. package/src/PowerSearch/powerSearchSheetUtils.ts +224 -0
  469. package/src/PowerSearch/types.ts +2 -0
  470. package/src/ProgressBar/ProgressBarTouch.ts +2 -0
  471. package/src/RadioList/RadioList.tsx +3 -2
  472. package/src/RadioList/RadioListItem.tsx +5 -3
  473. package/src/Resizable/Resizable.doc.mjs +5 -4
  474. package/src/Resizable/ResizeHandle.tsx +169 -109
  475. package/src/Resizable/createResizable.ts +831 -0
  476. package/src/Resizable/useResizable.ts +292 -623
  477. package/src/SegmentedControl/useSegmentedSelectionMotion.ts +6 -3
  478. package/src/SelectableCard/SelectableCard.tsx +39 -10
  479. package/src/SelectableCard/selectableCardInput.ts +30 -0
  480. package/src/Selector/Selector.tsx +5 -12
  481. package/src/Slider/sliderTouchController.ts +2 -2
  482. package/src/Spinner/Spinner.tsx +77 -63
  483. package/src/Switch/Switch.tsx +2 -6
  484. package/src/Switch/useSwitchTouch.ts +4 -4
  485. package/src/Table/BaseTable.tsx +46 -12
  486. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +2 -1
  487. package/src/Table/plugins/filtering/useTableFiltering.tsx +1 -0
  488. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +4 -0
  489. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +2 -0
  490. package/src/TextInput/TextInput.tsx +11 -10
  491. package/src/TimeInput/TimeInput.tsx +2 -0
  492. package/src/TimeInput/TouchTimeField.tsx +2 -0
  493. package/src/Timer/Timer.tsx +1 -0
  494. package/src/Timestamp/Timestamp.tsx +1 -1
  495. package/src/Toast/Toast.doc.mjs +4 -3
  496. package/src/Toast/Toast.tsx +52 -32
  497. package/src/Toast/ToastViewport.tsx +123 -35
  498. package/src/Toast/types.ts +9 -3
  499. package/src/Toast/useToast.tsx +1 -0
  500. package/src/Tokenizer/Tokenizer.doc.mjs +19 -3
  501. package/src/Tokenizer/Tokenizer.tsx +73 -51
  502. package/src/Tokenizer/TokenizerBottomSheet.tsx +1 -1
  503. package/src/Tokenizer/index.ts +1 -0
  504. package/src/Tooltip/useTooltip.doc.mjs +24 -0
  505. package/src/Tooltip/useTooltip.tsx +61 -56
  506. package/src/Typeahead/BaseTypeahead.tsx +27 -17
  507. package/src/Typeahead/TypeaheadItem.doc.mjs +6 -3
  508. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  509. package/src/animator/createAnimator.doc.mjs +153 -0
  510. package/src/animator/createAnimator.ts +324 -0
  511. package/src/gestures/GestureHost.ts +1 -1
  512. package/src/gestures/PressTracker.ts +4 -3
  513. package/src/gestures/README.md +10 -4
  514. package/src/hooks/ModalAnnounceProvider.tsx +1 -0
  515. package/src/hooks/actionGroupTracker.ts +20 -5
  516. package/src/hooks/index.ts +2 -0
  517. package/src/hooks/longPressDetector.ts +273 -0
  518. package/src/hooks/pressGroupContext.ts +21 -0
  519. package/src/hooks/rootScrollStyles.ts +247 -0
  520. package/src/hooks/scrollLockTouchGuard.ts +182 -0
  521. package/src/hooks/scrollbarGutter.ts +41 -26
  522. package/src/hooks/useActionGroupTracking.ts +224 -0
  523. package/src/hooks/useAnimator.doc.mjs +109 -0
  524. package/src/hooks/useAnimator.ts +67 -0
  525. package/src/hooks/useAnnounceRenderedText.ts +1 -0
  526. package/src/hooks/useAttachment.ts +1 -1
  527. package/src/hooks/useAutoMediaMode.ts +1 -0
  528. package/src/hooks/useBusyAnnouncement.ts +2 -0
  529. package/src/hooks/useDevWarning.ts +2 -0
  530. package/src/hooks/useFocusTrap.ts +2 -0
  531. package/src/hooks/useGridFocus.doc.mjs +6 -6
  532. package/src/hooks/useGridFocus.ts +10 -7
  533. package/src/hooks/useHotkeys.ts +2 -0
  534. package/src/hooks/useImageMode.ts +2 -0
  535. package/src/hooks/useInputStatusIcon.tsx +3 -2
  536. package/src/hooks/useKeyboardHint.tsx +1 -1
  537. package/src/hooks/useLongPress.doc.mjs +2 -2
  538. package/src/hooks/useLongPress.ts +32 -122
  539. package/src/hooks/useMenuHover.ts +1 -0
  540. package/src/hooks/useMenuPress.ts +2 -0
  541. package/src/hooks/useOverflow.ts +2 -1
  542. package/src/hooks/usePressFeedback.ts +1 -0
  543. package/src/hooks/useResolvedRequired.ts +3 -0
  544. package/src/hooks/useScrollLock.doc.mjs +51 -12
  545. package/src/hooks/useScrollLock.ts +57 -60
  546. package/src/hooks/useScrollableArea.ts +4 -0
  547. package/src/hooks/useStreamingText.ts +2 -0
  548. package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +43 -0
  549. package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +6 -0
  550. package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +15 -0
  551. package/src/i18n/generated-locales/en.generated.ts +41 -0
  552. package/src/i18n/generated-locales/pseudo.generated.ts +42 -0
  553. package/src/index.ts +13 -0
  554. package/src/internal/indicatorPress.stylex.ts +24 -0
  555. package/src/internal/selectable-card.ts +21 -0
  556. package/src/internal/sheetDraft.ts +2 -2
  557. package/src/motion/MEASUREMENTS.md +18 -0
  558. package/src/motion/README.md +10 -5
  559. package/src/motion/animatedLayout.ts +10 -5
  560. package/src/motion/animator.ts +66 -31
  561. package/src/motion/progress.ts +155 -0
  562. package/src/motion/reducedMotion.ts +3 -1
  563. package/src/motion/uikit/alert.ts +43 -0
  564. package/src/motion/uikit/index.ts +4 -3
  565. package/src/motion/uikit/picker.ts +116 -0
  566. package/src/privateAttributes/pressGroupItem.stylex.ts +44 -0
  567. package/src/privateAttributes/reducedMotion.stylex.ts +45 -0
  568. package/src/theme/Theme.tsx +37 -3
  569. package/src/theme/motionKnobs.ts +4 -3
  570. package/src/theme/themeMotion.ts +7 -0
  571. package/src/utils/dateParser.ts +16 -0
  572. package/src/utils/focusReturn.ts +30 -0
  573. package/src/utils/interactionModality.ts +4 -0
  574. package/src/utils/interactionOverlay.stylex.ts +3 -2
  575. package/src/utils/plainDate.ts +21 -0
  576. package/src/utils/pressFeedback.ts +24 -6
  577. package/src/utils/triggerFocus.ts +80 -0
  578. package/dist/internal/touch-sheet.d.ts +0 -21
  579. package/dist/internal/touch-sheet.d.ts.map +0 -1
  580. package/dist/internal/touch-sheet.js +0 -19
  581. package/src/internal/touch-sheet.ts +0 -21
@@ -6,16 +6,15 @@
6
6
  * @file useResizable.ts
7
7
  * @input Resize configuration (defaultSize, minSize, maxSize, snaps), with
8
8
  * removed pixel-bound aliases rejected even through assembled objects, and
9
- * collapse configuration (collapsible,
10
- * defaultIsCollapsed, isCollapsed)
11
- * @output Hook return: size, isCollapsed, collapse/expand/resize methods, props for handle
9
+ * collapse configuration (collapsible, defaultIsCollapsed, isCollapsed)
10
+ * @output Hook return: size, isCollapsed, collapse/expand/resize methods, props
11
+ * for handle, over the internal resize factory (createResizable)
12
12
  * @position Public hook; consumed by layout components via `resizable` prop
13
13
  */
14
- import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from 'react';
15
- import { observeResize } from "../utils/sharedResizeObserver.js";
14
+ import { useCallback, useReducer, useRef, useState, useSyncExternalStore } from 'react';
16
15
  import { useIsomorphicLayoutEffect } from "../hooks/useIsomorphicLayoutEffect.js";
17
- import { devWarn } from "../utils/devWarning.js";
18
- import { DEFAULT_COLLAPSED_SIZE, DEFAULT_MIN, DEFAULT_SIZE_FALLBACK, RESIZABLE_SIZE_GUIDANCE, SERVER_BASIS, clampSize, dependsOnBasis, loadPersistedState, measureContentBox, parseSize, persistState, resolveBound } from "./resizableModel.js";
16
+ import { createResizableAs, readInitialResizableState, readResizableInternals } from "./createResizable.js";
17
+ import { DEFAULT_COLLAPSED_SIZE } from "./resizableModel.js";
19
18
 
20
19
  // =============================================================================
21
20
  // Types
@@ -31,480 +30,72 @@ import { DEFAULT_COLLAPSED_SIZE, DEFAULT_MIN, DEFAULT_SIZE_FALLBACK, RESIZABLE_S
31
30
  * over the full ResizableRegionConfig.
32
31
  */
33
32
 
34
- /** A store that never changes on its own; the snapshot is re-read on render. */
35
- const noopSubscribe = () => () => {};
36
-
37
- // The window snapshots are module functions, so their identity is stable:
38
- // React re-reads a snapshot after the commit whenever getSnapshot is a new
39
- // function, and a window size read after the DOM changed forces a layout of
40
- // the whole page. With these, the window is read during render only.
41
-
42
- /** The viewport width, the basis without a container. */
43
- function readViewportBasis() {
44
- return typeof window === 'undefined' ? SERVER_BASIS : window.innerWidth;
45
- }
46
- function readServerBasis() {
47
- return SERVER_BASIS;
48
- }
49
-
50
- /** The window's extent along a horizontal hook's axis. */
51
- function readWindowWidth() {
52
- return typeof window === 'undefined' ? null : window.innerWidth;
53
- }
54
-
55
- /** The window's extent along a vertical hook's axis. */
56
- function readWindowHeight() {
57
- return typeof window === 'undefined' ? null : window.innerHeight;
58
- }
59
- function readNoWindowExtent() {
60
- return null;
61
- }
62
33
  // =============================================================================
63
- // Single-region hook
34
+ // Single-region hook: the configuration object, on the factory
64
35
  // =============================================================================
65
36
 
37
+ const EMPTY_SNAPS = [];
38
+
39
+ /**
40
+ * The configuration-object form: createResizable with no handle of its own,
41
+ * so the region's state has one copy, the factory's. The props it returns
42
+ * carry what the factory reports, and a ResizeHandle given them drives the
43
+ * factory's region through them.
44
+ */
66
45
  function useSingleResizable(config) {
67
46
  const {
68
- defaultSize,
69
- minSize,
70
- maxSize,
71
- containerRef,
72
- direction = 'horizontal',
73
- collapsible = false,
74
- collapsedSize = DEFAULT_COLLAPSED_SIZE,
75
- snaps: configuredSnaps,
76
- autoSaveId,
77
- defaultIsCollapsed,
78
- isCollapsed: controlledIsCollapsed,
79
- onSizeChange,
80
- onCollapseChange
81
- } = config;
82
- const emptySnapsRef = useRef([]);
83
- const snaps = configuredSnaps ?? emptySnapsRef.current;
84
- const rawMin = minSize;
85
- const rawMax = maxSize;
86
- const parsedDefault = parseSize(defaultSize);
87
- const parsedMin = parseSize(minSize);
88
- const parsedMax = parseSize(maxSize);
89
- const hasContainer = containerRef != null;
90
- const persisted = autoSaveId ? loadPersistedState(autoSaveId) : null;
91
- const initialDefaultRef = useRef(null);
92
- const [, setDefaultBasisCleanupTick] = useState(0);
93
- const defaultDependsOnBasis = dependsOnBasis(parsedDefault);
94
- const boundsDependOnBasis = dependsOnBasis(parsedMin) || dependsOnBasis(parsedMax);
95
- // A default needs a live container only until its initial pixel choice is
96
- // final. A persisted pixel choice wins without measuring the unused default.
97
- // Bounds are different: percentages keep following the basis so they can
98
- // re-clamp the selected pixel size.
99
- const defaultNeedsInitialBasis = persisted?.size == null && defaultDependsOnBasis && initialDefaultRef.current?.isFinal !== true;
100
- const observeContainerBasis = hasContainer && (boundsDependOnBasis || defaultNeedsInitialBasis);
101
- const observeViewportBasis = !hasContainer && boundsDependOnBasis;
102
-
103
- // The container basis, read through the shared observer. `useSyncExternalStore`
104
- // rather than an effect: the store IS the measurement, so there is no render
105
- // that paints before the basis is known and no `setState` in an effect.
106
- //
107
- // The subscription depends on the ELEMENT, not on the ref object. A ref is
108
- // stable across an element swap, so `containerRef.current` can become a
109
- // different node — a remount behind the same ref, a conditional branch, a
110
- // portal moving — without any input to this hook changing. Keyed on the ref,
111
- // the old detached node stayed observed (and a detached node measures 0,
112
- // which is how a replacement zeroed the bounds) and the new one was never
113
- // observed at all.
114
- const containerElementRef = useRef(null);
115
- // DOM ref changes are invisible to React. This state is only a version tick
116
- // while basis observation is active; the element itself lives in a ref so it
117
- // can be released without adding a cleanup render.
118
- const [, setContainerElementVersion] = useState(0);
119
- const containerBasisRef = useRef(null);
120
- const containerElement = observeContainerBasis ? containerElementRef.current : null;
121
-
122
- // Follow the ref only while some configuration needs its basis. A numeric-only
123
- // region never reads the ref. Once observation stops, drop both the element
124
- // and its measurement without a state update; a later percentage starts from
125
- // the ref's then-current element and a fresh basis.
126
- useIsomorphicLayoutEffect(() => {
127
- if (!observeContainerBasis) {
128
- containerElementRef.current = null;
129
- containerBasisRef.current = null;
130
- return;
131
- }
132
- const element = containerRef?.current ?? null;
133
- if (element !== containerElementRef.current) {
134
- containerBasisRef.current = null;
135
- containerElementRef.current = element;
136
- setContainerElementVersion(version => version + 1);
137
- }
138
- });
139
- const subscribeToContainer = useCallback(onStoreChange => {
140
- if (!observeContainerBasis || containerElement == null || containerElement !== containerRef?.current) {
141
- return () => {};
142
- }
143
- // Unsubscribe by callback: several regions share one container, and any
144
- // number of unrelated hooks may observe the same node.
145
- return observeResize(containerElement, entry => {
146
- containerBasisRef.current = measureContentBox(containerElement, direction, entry);
147
- onStoreChange();
148
- });
149
- }, [containerElement, observeContainerBasis, direction, containerRef]);
150
- const readContainerBasis = useCallback(() => {
151
- if (!observeContainerBasis || containerElement == null) {
152
- // An inactive subscription owns no current measurement. Clearing this is
153
- // important when a percentage bound is added later: the first active
154
- // render must measure the container as it is now, not clamp against the
155
- // last basis seen by a default-only subscription.
156
- containerBasisRef.current = null;
157
- return null;
158
- }
159
- // Cached in a ref so the snapshot is referentially stable between resizes;
160
- // returning a fresh measurement every call would loop the store.
161
- if (containerBasisRef.current == null) {
162
- containerBasisRef.current = measureContentBox(containerElement, direction);
163
- }
164
- return containerBasisRef.current;
165
- }, [containerElement, observeContainerBasis, direction]);
166
- const containerBasis = useSyncExternalStore(subscribeToContainer, readContainerBasis, () => null);
167
-
168
- // The viewport basis is always readable synchronously. Percentage-dependent
169
- // BOUNDS subscribe to later resizes (FR6); a default reads the initial
170
- // snapshot only, because it becomes a pixel choice immediately.
171
- const subscribeToViewport = useCallback(onStoreChange => {
172
- if (hasContainer || !observeViewportBasis || typeof window === 'undefined') {
173
- return () => {};
174
- }
175
- window.addEventListener('resize', onStoreChange);
176
- return () => window.removeEventListener('resize', onStoreChange);
177
- }, [hasContainer, observeViewportBasis]);
178
- const viewportBasis = useSyncExternalStore(subscribeToViewport, readViewportBasis, readServerBasis);
179
-
180
- // The window's extent along the hook's axis, for the REPORTED maximum of an
181
- // unbounded region (never for clamping). Read through the same store shape
182
- // so a server-rendered handle hydrates with no maximum and gains the real
183
- // one on the first client render, instead of a hydration mismatch. It takes
184
- // no resize subscription: an unbounded pixel region observes nothing
185
- // (component:Resizable Performance and resources).
186
- const windowExtent = useSyncExternalStore(noopSubscribe, direction === 'vertical' ? readWindowHeight : readWindowWidth, readNoWindowExtent);
187
-
188
- // With a container, its content box is the basis; without one, the released
189
- // viewport basis. Before a supplied container has been measured — the first
190
- // render, the server, and any moment it is display:none or detached — the
191
- // deterministic 1200px stands in, and the first real measurement replaces it.
192
- //
193
- // A zero measurement is not a measurement. A hidden or detached container
194
- // reports 0, and resolving `'50%'` against it produced a real maximum of 0:
195
- // the panel collapsed and, with `autoSaveId`, that 0 was written over a
196
- // perfectly good saved width. Treating 0 as unmeasured keeps the temporary
197
- // basis until the container is actually laid out (AST-010 Platform support).
198
- const needsContainerBasis = observeContainerBasis;
199
- const hasPositiveMeasurement = containerBasis != null && containerBasis > 0;
200
- const liveBasis = hasContainer ? hasPositiveMeasurement ? containerBasis : SERVER_BASIS : viewportBasis;
201
- const isBasisMeasured = needsContainerBasis ? hasPositiveMeasurement : true;
202
-
203
- // One stable basis per gesture. A container that resizes mid-drag would
204
- // otherwise move the bound under the pointer; the new basis applies once the
205
- // gesture ends.
206
- const gestureBasisRef = useRef(null);
207
- // Only forces the render that ends a gesture: it releases the frozen basis,
208
- // and its commit writes the size the gesture settled on.
209
- const [gestureTick, setGestureTick] = useState(0);
210
- void gestureTick;
211
- const basis = gestureBasisRef.current ?? liveBasis;
212
- // The frozen basis also marks a gesture in flight, from `_onResizeStart`
213
- // until `_onResizeEnd` or `_onResizeCancel`.
214
- const isGestureActive = gestureBasisRef.current != null;
215
- const didWarnMinRef = useRef(false);
216
- const didWarnMaxRef = useRef(false);
217
- const didWarnDefaultRef = useRef(false);
218
- const didWarnInvertedRef = useRef(false);
219
-
220
- // Bounds re-resolve from the live basis on every render — that is the whole
221
- // point of a percentage bound — and clamp the pixel selection below.
222
- const resolvedMin = resolveBound(rawMin, parsedMin, basis, DEFAULT_MIN, 'minSize', RESIZABLE_SIZE_GUIDANCE, didWarnMinRef);
223
- const resolvedMax = resolveBound(rawMax, parsedMax, basis, Infinity, 'maxSize', RESIZABLE_SIZE_GUIDANCE, didWarnMaxRef);
224
-
225
- // A basis-dependent default is resolved ONCE into a pixel size. Latched in a
226
- // ref (React's sanctioned lazy-init shape) rather than recomputed, because a
227
- // default that kept tracking its basis would be a second, responsive sizing
228
- // mode — the thing this API deliberately does not have.
229
- //
230
- // Not final while a supplied container is still unmeasured: that render used
231
- // the temporary 1200px stand-in, and the first real measurement replaces it.
232
- // Once final, a default-only subscription is removed. The correction is not a
233
- // user interaction, so it neither persists the placeholder nor fires
234
- // `onSizeChange`.
235
- if (initialDefaultRef.current == null || !initialDefaultRef.current.isFinal) {
236
- initialDefaultRef.current = {
237
- px: resolveBound(defaultSize, parsedDefault, basis, DEFAULT_SIZE_FALLBACK, 'defaultSize', RESIZABLE_SIZE_GUIDANCE, didWarnDefaultRef),
238
- isFinal: isBasisMeasured
239
- };
240
- }
241
- const initialDefaultPx = initialDefaultRef.current.px;
242
-
243
- // The size the user has settled on, or null while a container-relative
244
- // default is still waiting for its first positive measurement. Once that
245
- // basis is real, the default becomes an ordinary pixel selection — including
246
- // any clamp applied at initialization. Leaving it represented by `null`
247
- // allowed the raw default to be re-read later: 321px first clamped to 200px
248
- // in a 400px container, then revived to 321px when the container grew.
249
- //
250
- // Initialized outright whenever the basis is already real on the first
251
- // render — every pixel-only configuration, and the no-container percentage
252
- // path. Only a supplied container needs a measurement that does not exist
253
- // until after commit, so only it starts null. Initializing lazily in all
254
- // cases cost every legacy pixel-only mount a second render pass, because the
255
- // adjustment below then had to run on the first render to fill the value in.
256
- const [chosenSize, setChosenSize] = useState(() => {
257
- if (persisted?.size != null) {
258
- return persisted.size;
259
- }
260
- return isBasisMeasured ? clampSize(initialDefaultPx, resolvedMin, resolvedMax, snaps) : null;
261
- });
262
- if (hasContainer && !boundsDependOnBasis && isBasisMeasured && defaultNeedsInitialBasis && chosenSize != null) {
263
- // A programmatic resize may have selected pixels while the container was
264
- // still unmeasured, so chosenSize can already be non-null here. Force the
265
- // render that re-evaluates and removes the now-finished default subscription.
266
- setDefaultBasisCleanupTick(tick => tick + 1);
267
- }
268
- if (isBasisMeasured && chosenSize == null) {
269
- // The supplied container has now been measured, so the selection latched
270
- // against the temporary basis is replaced by one against the real one.
271
- // Render-phase adjustment is deliberate: React re-runs this render before
272
- // paint, so the corrected selection, paint, persistence, and ARIA all see
273
- // the same pixel value. It fires no interaction callback.
274
- setChosenSize(clampSize(initialDefaultPx, resolvedMin, resolvedMax, snaps));
275
- }
276
-
277
- // A re-resolved bound clamps the SELECTION, not just the paint. Deriving
278
- // alone was not enough: the stored choice survived, so a container that
279
- // shrank and grew again revived the pre-clamp size — measured 320px
280
- // reviving to 560px. The clamp has to be committed to be permanent.
281
- //
282
- // Adjusting state during render (React's documented shape for "a prop
283
- // changed, so state must follow") rather than in an effect: React re-runs
284
- // this render before painting, so nothing shows at the stale size, and no
285
- // interaction callback fires for what is only a layout correction (FR10).
286
- //
287
- // Held until the basis is final. Before a supplied container is measured the
288
- // bounds come from the temporary 1200px stand-in, and committing against
289
- // that would move a persisted size to fit a basis that was never real.
290
- const [committedBounds, setCommittedBounds] = useState({
291
- min: resolvedMin,
292
- max: resolvedMax
293
- });
294
- if (isBasisMeasured && gestureBasisRef.current == null && (committedBounds.min !== resolvedMin || committedBounds.max !== resolvedMax)) {
295
- setCommittedBounds({
296
- min: resolvedMin,
297
- max: resolvedMax
298
- });
299
- setChosenSize(current => current == null ? null : clampSize(current, resolvedMin, resolvedMax, snaps));
300
- }
301
-
302
- // Derived for paint, so the clamp above and the rendered size agree on the
303
- // very render that observes a new basis.
304
- const size = clampSize(chosenSize ?? initialDefaultPx, resolvedMin, resolvedMax, snaps);
305
- const [uncontrolledIsCollapsed, setUncontrolledIsCollapsed] = useState(() => persisted?.isCollapsed ?? defaultIsCollapsed ?? false);
306
- const isControlled = controlledIsCollapsed !== undefined;
307
- const isCollapsed = collapsible && (isControlled ? controlledIsCollapsed : uncontrolledIsCollapsed);
308
- const dragStartSizeRef = useRef(size);
309
-
310
- // Mirrors isCollapsed so the callbacks below read the live value instead of
311
- // the one their last render captured. Two cases reach them from a stale
312
- // closure: two imperative calls in one tick, and a drag — ResizeHandle
313
- // registers its pointermove listener once at pointer down, so a whole
314
- // gesture runs against one props snapshot.
315
- const isCollapsedRef = useRef(isCollapsed);
316
- isCollapsedRef.current = isCollapsed;
317
-
318
- // Controlled callers own the state; collapse() and a drag past the
319
- // threshold report through onCollapseChange and change nothing here.
320
- const setCollapsed = useCallback(value => {
321
- if (!isControlled) {
322
- isCollapsedRef.current = value;
323
- setUncontrolledIsCollapsed(value);
324
- }
325
- }, [isControlled]);
326
- useEffect(() => {
327
- if (resolvedMin > resolvedMax && !didWarnInvertedRef.current) {
328
- didWarnInvertedRef.current = true;
329
- devWarn('useResizable', `the resolved minimum (${resolvedMin}px) is above the resolved ` + `maximum (${resolvedMax}px). The maximum wins, as it always has.`);
330
- }
331
- }, [resolvedMin, resolvedMax]);
332
-
333
- // The size a gesture in flight has reached, for a region that unmounts
334
- // before the gesture ends.
335
- const pendingWriteRef = useRef(null);
336
- useEffect(() => {
337
- // Synchronizes the `autoSaveId` entry in localStorage with the size.
338
- // Nothing is written while the basis is still the temporary stand-in. The
339
- // size on such a render is a placeholder, and persisting it overwrites the
340
- // real saved size with a value derived from a basis that was never real
341
- // (AST-010 Platform support, FR9).
342
- if (!autoSaveId || !isBasisMeasured) {
343
- pendingWriteRef.current = null;
344
- return;
345
- }
346
- // Nor while a gesture is in flight. A drag commits a new size on every
347
- // pointer move, and each write reaches every other open document of the
348
- // origin as a `storage` event.
349
- if (isGestureActive) {
350
- pendingWriteRef.current = {
351
- key: autoSaveId,
352
- state: {
353
- size,
354
- isCollapsed
355
- }
356
- };
357
- return;
358
- }
359
- // A gesture's one write happens here, in the commit that applies its
360
- // release, not in the handler that ended it: this render is the first to
361
- // know the final size. A basis that changed mid-gesture applies only at
362
- // the release and can re-clamp the size (AST-010 FR7), and a move the
363
- // release arrived before renders together with it. The handler sees
364
- // neither.
365
- pendingWriteRef.current = null;
366
- persistState(autoSaveId, {
367
- size,
368
- isCollapsed
369
- });
370
- }, [size, isCollapsed, autoSaveId, isBasisMeasured, isGestureActive]);
371
-
372
- // A region that unmounts mid-gesture never commits a release, so the size
373
- // the gesture reached is written on the way out.
374
- useEffect(() => () => {
375
- const pending = pendingWriteRef.current;
376
- pendingWriteRef.current = null;
377
- if (pending != null) {
378
- persistState(pending.key, pending.state);
379
- }
380
- }, []);
381
- const collapse = useCallback(() => {
382
- // The already-collapsed guard keeps a repeated call from re-notifying a
383
- // transition that already happened.
384
- if (!collapsible || isCollapsedRef.current) {
385
- return;
386
- }
387
- setCollapsed(true);
388
- onCollapseChange?.(true);
389
- onSizeChange?.(0);
390
- }, [collapsible, setCollapsed, onCollapseChange, onSizeChange]);
391
- const expand = useCallback(() => {
392
- const wasCollapsed = isCollapsedRef.current;
393
- setCollapsed(false);
394
- if (wasCollapsed) {
395
- onCollapseChange?.(false);
396
- }
397
- onSizeChange?.(size);
398
- }, [setCollapsed, size, onCollapseChange, onSizeChange]);
399
- const resize = useCallback(newSize => {
400
- // An invalid programmatic size repairs nothing — it must not replace a
401
- // legal selection with NaN, which would then reach paint, storage and
402
- // `aria-valuenow`.
403
- if (!Number.isFinite(newSize) || newSize < 0) {
404
- devWarn('useResizable', `resize(${String(newSize)}) is not a pixel size. Keeping the ` + 'current size. Percentages configure the hook; they are not a ' + 'programmatic input.');
405
- return;
406
- }
407
- const clamped = clampSize(newSize, resolvedMin, resolvedMax, snaps);
408
- const wasCollapsed = isCollapsedRef.current;
409
- setChosenSize(clamped);
410
- setCollapsed(false);
411
- // Resizing out of the collapsed state is an implicit expand — notify
412
- // like the drag path does when it crosses back over the threshold.
413
- if (wasCollapsed) {
414
- onCollapseChange?.(false);
415
- }
416
- onSizeChange?.(clamped);
417
- }, [resolvedMin, resolvedMax, snaps, setCollapsed, onCollapseChange, onSizeChange]);
47
+ getResizable,
48
+ size,
49
+ isCollapsed,
50
+ snapshot,
51
+ collapse,
52
+ expand,
53
+ resize
54
+ } = useResizableController(config);
55
+ // The region's side of the handle's gesture, read at each input, so a whole
56
+ // drag reaches the factory as it is now.
57
+ const model = useCallback(() => {
58
+ const current = getResizable();
59
+ return current == null ? undefined : readResizableInternals(current)?.model;
60
+ }, [getResizable]);
418
61
  const onResizeStart = useCallback(() => {
419
- // Freeze the basis for the whole gesture so a container resizing mid-drag
420
- // cannot move the bound out from under the pointer.
421
- gestureBasisRef.current = liveBasis;
422
- dragStartSizeRef.current = isCollapsedRef.current ? 0 : size;
423
- }, [size, liveBasis]);
62
+ model()?.start();
63
+ }, [model]);
424
64
  const onResizeMove = useCallback(delta => {
425
- const raw = dragStartSizeRef.current + delta;
426
- if (collapsible && raw < collapsedSize) {
427
- if (!isCollapsedRef.current) {
428
- setCollapsed(true);
429
- onCollapseChange?.(true);
430
- onSizeChange?.(0);
431
- }
432
- return;
433
- }
434
- if (isCollapsedRef.current && raw >= collapsedSize) {
435
- setCollapsed(false);
436
- onCollapseChange?.(false);
437
- }
438
- const clamped = clampSize(raw, resolvedMin, resolvedMax, snaps);
439
- setChosenSize(clamped);
440
- onSizeChange?.(clamped);
441
- }, [collapsible, collapsedSize, setCollapsed, resolvedMin, resolvedMax, snaps, onSizeChange, onCollapseChange]);
442
-
443
- // Releasing the frozen basis needs a render to apply whatever the basis
444
- // became during the gesture; that render's commit writes the final size.
445
- const releaseGestureBasis = useCallback(() => {
446
- if (gestureBasisRef.current != null) {
447
- gestureBasisRef.current = null;
448
- setGestureTick(tick => tick + 1);
449
- }
450
- }, []);
65
+ model()?.move(delta);
66
+ }, [model]);
451
67
  const onResizeEnd = useCallback(() => {
452
- // Sizes are already committed during move; the basis is held, and the
453
- // commit that releases it writes the final size to storage.
454
- releaseGestureBasis();
455
- }, [releaseGestureBasis]);
456
-
457
- // A gesture that is cancelled rather than completed — pointercancel, a lost
458
- // capture, a handle unmounted mid-drag — is still over. It does not signal a
459
- // resize end (that is #5297's contract, and the sizes were committed during
460
- // move anyway), but the basis it froze has to come back, or every later
461
- // percentage bound stays pinned to the container size at grab time, and the
462
- // size it reached has to reach storage.
463
- const onResizeCancel = releaseGestureBasis;
464
-
465
- // The maximum a handle REPORTS (End uses only a configured maximum). A
466
- // configured maximum wins. Otherwise a measured extent stands in — the
467
- // container's content box while a percentage bound already observes it, or
468
- // the window's extent along the axis — and never drops below the current size, so
469
- // `aria-valuenow` can never exceed `aria-valuemax` (a saved, default, or
470
- // pre-resize size may already be larger than the window). An unobserved
471
- // container reports nothing: measuring it would add an observer to an
472
- // atomic pixel path.
473
- const measuredBasisForMax = hasContainer ? hasPositiveMeasurement && observeContainerBasis ? containerBasis : null : windowExtent;
474
- // Never below the announced value either: a collapsed pane announces the
475
- // resolved minimum as its value, so the stand-in floors there as well, and
476
- // `aria-valuemax` can never fall under `aria-valuemin`.
477
- const effectiveMaxPx = resolvedMax !== Infinity ? resolvedMax : measuredBasisForMax == null ? undefined : Math.max(measuredBasisForMax, isCollapsed ? resolvedMin : size);
68
+ model()?.end();
69
+ }, [model]);
70
+ const onResizeCancel = useCallback(() => {
71
+ model()?.cancel();
72
+ }, [model]);
478
73
  const props = {
479
- _size: isCollapsed ? 0 : size,
74
+ _size: size,
480
75
  _isCollapsed: isCollapsed,
481
76
  _onResizeStart: onResizeStart,
482
77
  _onResizeMove: onResizeMove,
483
78
  _onResizeEnd: onResizeEnd,
484
79
  _onResizeCancel: onResizeCancel,
485
- _minSizePx: resolvedMin,
486
- _maxSizePx: resolvedMax,
487
- _snaps: snaps,
488
- _collapsedSize: collapsedSize,
489
- _collapsible: collapsible,
490
- _direction: direction,
80
+ _minSizePx: snapshot.minPx,
81
+ _maxSizePx: snapshot.maxPx,
82
+ _snaps: config.snaps ?? EMPTY_SNAPS,
83
+ _collapsedSize: config.collapsedSize ?? DEFAULT_COLLAPSED_SIZE,
84
+ _collapsible: config.collapsible ?? false,
85
+ _direction: config.direction ?? 'horizontal',
491
86
  _isResizableProps: true
492
87
  };
493
88
  collapseControls.set(props, {
494
89
  collapse,
495
90
  expand
496
91
  });
497
- // Without a configured maximum the basis stands in — only when it is a
498
- // real measurement (an observed container, or the window), never the
499
- // temporary 1200px placeholder (component:Resizable Performance: atomic
500
- // pixel paths add no observer, so an unobserved container stays unknown).
501
- // The released no-container basis is the window WIDTH on both axes; a
502
- // vertical region's reported maximum reads the window height instead.
503
- if (effectiveMaxPx != null) {
504
- effectiveMaxima.set(props, effectiveMaxPx);
92
+ // Without a configured maximum a measured extent stands in, only once it
93
+ // is a real measurement (an observed container, or the window).
94
+ if (snapshot.effectiveMaxPx != null) {
95
+ effectiveMaxima.set(props, snapshot.effectiveMaxPx);
505
96
  }
506
97
  return {
507
- size: isCollapsed ? 0 : size,
98
+ size,
508
99
  isCollapsed,
509
100
  collapse,
510
101
  expand,
@@ -601,6 +192,208 @@ export function getCollapseControls(props) {
601
192
 
602
193
  /** Removed keys must fail even when a variable bypasses excess-property checks. */
603
194
 
195
+ // =============================================================================
196
+ // The resize factory in React
197
+ // =============================================================================
198
+
199
+ /**
200
+ * The factory a hook holds, and one store over it for React. It follows the
201
+ * factory the slot holds now and reads the snapshot that factory reports.
202
+ * Before there is one, it reads the state the region starts in. A reading
203
+ * equal in every part to the last one is the last one. So a mount that
204
+ * settles where it started renders once.
205
+ */
206
+
207
+ function sameSnapshot(a, b) {
208
+ return a.size === b.size && a.isCollapsed === b.isCollapsed && a.expandedSize === b.expandedSize && a.minPx === b.minPx && a.maxPx === b.maxPx && a.effectiveMaxPx === b.effectiveMaxPx;
209
+ }
210
+ function createSlot(initial) {
211
+ let current = null;
212
+ let last = initial;
213
+ const listeners = new Set();
214
+ let stopFactory = null;
215
+ const notify = () => {
216
+ for (const listener of [...listeners]) {
217
+ listener();
218
+ }
219
+ };
220
+ const follow = () => {
221
+ stopFactory?.();
222
+ stopFactory = null;
223
+ if (current != null && listeners.size > 0) {
224
+ const {
225
+ resizable
226
+ } = current;
227
+ const channel = readResizableInternals(resizable);
228
+ stopFactory = channel != null ? channel.subscribeSnapshot(notify) : resizable.subscribe(notify);
229
+ }
230
+ };
231
+ return {
232
+ get: () => current,
233
+ set(next) {
234
+ current = next;
235
+ follow();
236
+ notify();
237
+ },
238
+ subscribe(listener) {
239
+ listeners.add(listener);
240
+ if (listeners.size === 1) {
241
+ follow();
242
+ }
243
+ return () => {
244
+ listeners.delete(listener);
245
+ if (listeners.size === 0) {
246
+ stopFactory?.();
247
+ stopFactory = null;
248
+ }
249
+ };
250
+ },
251
+ read() {
252
+ if (current == null) {
253
+ return last;
254
+ }
255
+ const {
256
+ resizable
257
+ } = current;
258
+ // A stand-in controller without the internal channel reports only its
259
+ // size and collapse state.
260
+ const next = readResizableInternals(resizable)?.snapshot() ?? {
261
+ ...initial,
262
+ size: resizable.size,
263
+ isCollapsed: resizable.isCollapsed,
264
+ expandedSize: resizable.size
265
+ };
266
+ if (!sameSnapshot(last, next)) {
267
+ last = next;
268
+ }
269
+ return last;
270
+ }
271
+ };
272
+ }
273
+
274
+ /** What the hook renders from its factory. */
275
+
276
+ /**
277
+ * createResizable in React, with nothing of its own. It creates the factory as
278
+ * it mounts, passes later options through `update` and returns what the
279
+ * factory reports.
280
+ * Before its first commit (the server, the first render, a hydrating render)
281
+ * it returns the state the factory starts in. While it is unmounted or an
282
+ * `<Activity>` hides it, the factory lets go of the page and keeps the region.
283
+ * So collapse, expand and resize apply and report whenever they are called, as
284
+ * React state did. A call before the first commit starts the factory early.
285
+ *
286
+ * A controlled `isCollapsed` is read from the options in the render that
287
+ * passes it, before `update` reaches the factory. So the size and collapse
288
+ * state a parent renders land in the same commit as the state its
289
+ * `onCollapseChange` set.
290
+ */
291
+ function useResizableController(options) {
292
+ const optionsRef = useRef(options);
293
+ optionsRef.current = options;
294
+ const [slot] = useState(() => createSlot(readInitialResizableState(options)));
295
+ const [serverInitial] = useState(() => readInitialResizableState(options, 'server'));
296
+ // The hook keeps one factory. After an unmount or an `<Activity>` hide, the
297
+ // same factory takes the page back (`resume`).
298
+ const follow = useCallback(() => {
299
+ const entry = slot.get();
300
+ if (entry != null) {
301
+ readResizableInternals(entry.resizable)?.resume();
302
+ return;
303
+ }
304
+ const passed = optionsRef.current;
305
+ const resizable = createResizableAs('useResizable', passed);
306
+ slot.set({
307
+ resizable,
308
+ passed
309
+ });
310
+ }, [slot]);
311
+ useIsomorphicLayoutEffect(() => {
312
+ follow();
313
+ });
314
+ // On unmount, or when an `<Activity>` hides the component, the factory lets
315
+ // go of the page and keeps the region. Calls meanwhile apply, and a reveal
316
+ // goes on from where the region stands. A stand-in without the internal
317
+ // channel goes.
318
+ useIsomorphicLayoutEffect(() => () => {
319
+ const entry = slot.get();
320
+ if (entry == null) {
321
+ return;
322
+ }
323
+ const channel = readResizableInternals(entry.resizable);
324
+ if (channel != null) {
325
+ channel.suspend();
326
+ } else {
327
+ slot.set(null);
328
+ entry.resizable.destroy();
329
+ }
330
+ }, [slot]);
331
+ // The factory, a store outside React: each new options object reaches it
332
+ // through update().
333
+ useIsomorphicLayoutEffect(() => {
334
+ const entry = slot.get();
335
+ if (entry != null && options !== entry.passed) {
336
+ entry.passed = options;
337
+ entry.resizable.update(options);
338
+ }
339
+ }, [slot, options]);
340
+ // A container swapped behind `containerRef` with the same options: the
341
+ // factory follows it at each commit, as it follows new options.
342
+ useIsomorphicLayoutEffect(() => {
343
+ const entry = slot.get();
344
+ if (entry != null) {
345
+ readResizableInternals(entry.resizable)?.syncContainer();
346
+ }
347
+ });
348
+ const snapshot = useSyncExternalStore(slot.subscribe, slot.read, () => serverInitial);
349
+ // When an `<Activity>` shows this component, React subscribes to the slot
350
+ // again but does not read it. The factory resumes and reports in that same
351
+ // commit. Render again with what it reports.
352
+ const [, rerender] = useReducer(count => count + 1, 0);
353
+ useIsomorphicLayoutEffect(() => {
354
+ if (slot.read() !== snapshot) {
355
+ rerender();
356
+ }
357
+ });
358
+ const isControlled = options.isCollapsed !== undefined;
359
+ const isCollapsed = isControlled ? (options.collapsible ?? false) && Boolean(options.isCollapsed) : snapshot.isCollapsed;
360
+ const size = isControlled ? isCollapsed ? 0 : snapshot.expandedSize : snapshot.size;
361
+ const getResizable = useCallback(() => slot.get()?.resizable ?? null, [slot]);
362
+ // A call before the first commit, from a child's layout effect say, starts
363
+ // the factory now. The factory stays off the page until that commit.
364
+ const ensureResizable = useCallback(() => {
365
+ const entry = slot.get();
366
+ if (entry != null) {
367
+ return entry.resizable;
368
+ }
369
+ const passed = optionsRef.current;
370
+ const resizable = createResizableAs('useResizable', passed);
371
+ readResizableInternals(resizable)?.suspend();
372
+ slot.set({
373
+ resizable,
374
+ passed
375
+ });
376
+ return resizable;
377
+ }, [slot]);
378
+ const collapse = useCallback(() => {
379
+ ensureResizable().collapse();
380
+ }, [ensureResizable]);
381
+ const expand = useCallback(() => {
382
+ ensureResizable().expand();
383
+ }, [ensureResizable]);
384
+ const resize = useCallback(next => {
385
+ ensureResizable().resize(next);
386
+ }, [ensureResizable]);
387
+ return {
388
+ snapshot,
389
+ getResizable,
390
+ size,
391
+ isCollapsed,
392
+ collapse,
393
+ expand,
394
+ resize
395
+ };
396
+ }
604
397
  export function useResizable(config) {
605
398
  if ('regions' in config) {
606
399
  // eslint-disable-next-line @eslint-react/rules-of-hooks, react-compiler/react-compiler -- branch is determined by call-site type (stable per call site)