@astryxdesign/core 0.7.7 → 0.7.8-canary.0d54fd3

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 (682) 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 +11 -3
  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 +18 -22
  20. package/dist/Calendar/getWeekdayHeaderNames.d.ts +16 -0
  21. package/dist/Calendar/getWeekdayHeaderNames.d.ts.map +1 -0
  22. package/dist/Calendar/getWeekdayHeaderNames.js +70 -0
  23. package/dist/Calendar/hooks/useCalendarDays.d.ts.map +1 -1
  24. package/dist/Calendar/hooks/useCalendarDays.js +2 -10
  25. package/dist/Calendar/{standaloneShortWeekdayNames.generated.d.ts → weekdayHeaderNames.generated.d.ts} +14 -14
  26. package/dist/Calendar/weekdayHeaderNames.generated.d.ts.map +1 -0
  27. package/dist/Calendar/{standaloneShortWeekdayNames.generated.js → weekdayHeaderNames.generated.js} +12 -12
  28. package/dist/Carousel/Carousel.d.ts.map +1 -1
  29. package/dist/Carousel/Carousel.js +2 -0
  30. package/dist/Chat/ChatComposerInput.d.ts.map +1 -1
  31. package/dist/Chat/ChatComposerInput.js +6 -1
  32. package/dist/Chat/ChatMessageList.d.ts.map +1 -1
  33. package/dist/Chat/ChatMessageList.js +2 -1
  34. package/dist/Chat/useChatDictation.d.ts.map +1 -1
  35. package/dist/Chat/useChatDictation.js +2 -0
  36. package/dist/Chat/useChatNewMessages.js +1 -1
  37. package/dist/Chat/useChatStreamScroll.d.ts.map +1 -1
  38. package/dist/Chat/useChatStreamScroll.js +2 -0
  39. package/dist/Chat/useSpeechRecognition.d.ts.map +1 -1
  40. package/dist/Chat/useSpeechRecognition.js +3 -0
  41. package/dist/Chat/useTriggerMenu.js +1 -1
  42. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  43. package/dist/CheckboxInput/CheckboxInput.js +17 -12
  44. package/dist/CheckboxList/CheckboxList.d.ts +8 -1
  45. package/dist/CheckboxList/CheckboxList.d.ts.map +1 -1
  46. package/dist/CheckboxList/CheckboxList.js +2 -0
  47. package/dist/CodeBlock/CodeBlock.d.ts +10 -1
  48. package/dist/CodeBlock/CodeBlock.d.ts.map +1 -1
  49. package/dist/CodeBlock/CodeBlock.js +28 -11
  50. package/dist/CommandPalette/CommandPalette.d.ts.map +1 -1
  51. package/dist/CommandPalette/CommandPalette.js +2 -0
  52. package/dist/CommandPalette/CommandPaletteItem.d.ts.map +1 -1
  53. package/dist/CommandPalette/CommandPaletteItem.js +2 -0
  54. package/dist/ComplexSelector/ComplexSelector.d.ts +4 -1
  55. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  56. package/dist/ComplexSelector/ComplexSelector.js +14 -4
  57. package/dist/ContextMenu/ContextMenu.js +2 -2
  58. package/dist/DateInput/MonthScroller.d.ts.map +1 -1
  59. package/dist/DateInput/MonthScroller.js +5 -2
  60. package/dist/DateInput/PickerWheel.d.ts +19 -0
  61. package/dist/DateInput/PickerWheel.d.ts.map +1 -0
  62. package/dist/DateInput/PickerWheel.js +625 -0
  63. package/dist/DateInput/TouchDateField.d.ts.map +1 -1
  64. package/dist/DateInput/TouchDateField.js +9 -30
  65. package/dist/DateInput/Wheel.d.ts +18 -37
  66. package/dist/DateInput/Wheel.d.ts.map +1 -1
  67. package/dist/DateInput/Wheel.js +84 -113
  68. package/dist/DateInput/useOwnScrollGesture.d.ts +10 -0
  69. package/dist/DateInput/useOwnScrollGesture.d.ts.map +1 -1
  70. package/dist/DateInput/useOwnScrollGesture.js +16 -3
  71. package/dist/DateInput/usePointerDragScroll.d.ts.map +1 -1
  72. package/dist/DateInput/usePointerDragScroll.js +2 -0
  73. package/dist/DateInput/useScrollSettle.d.ts.map +1 -1
  74. package/dist/DateInput/useScrollSettle.js +3 -0
  75. package/dist/DateInput/useWheelListbox.d.ts +59 -0
  76. package/dist/DateInput/useWheelListbox.d.ts.map +1 -0
  77. package/dist/DateInput/useWheelListbox.js +88 -0
  78. package/dist/DateInput/wheelOptions.d.ts +74 -0
  79. package/dist/DateInput/wheelOptions.d.ts.map +1 -0
  80. package/dist/DateInput/wheelOptions.js +98 -0
  81. package/dist/DateInput/wheelPhysics.d.ts +127 -0
  82. package/dist/DateInput/wheelPhysics.d.ts.map +1 -0
  83. package/dist/DateInput/wheelPhysics.js +341 -0
  84. package/dist/DateInput/wheelStrip.d.ts +92 -0
  85. package/dist/DateInput/wheelStrip.d.ts.map +1 -0
  86. package/dist/DateInput/wheelStrip.js +258 -0
  87. package/dist/DateTimeInput/TouchDateTimeField.d.ts.map +1 -1
  88. package/dist/DateTimeInput/TouchDateTimeField.js +10 -10
  89. package/dist/Dialog/Dialog.d.ts.map +1 -1
  90. package/dist/Dialog/Dialog.js +9 -32
  91. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  92. package/dist/Drawer/useDrawerDialogPresence.js +3 -0
  93. package/dist/DropdownMenu/useMenuOverflow.d.ts.map +1 -1
  94. package/dist/DropdownMenu/useMenuOverflow.js +5 -0
  95. package/dist/Field/Field.js +2 -2
  96. package/dist/FieldStatus/useFieldStatusAnnouncement.d.ts.map +1 -1
  97. package/dist/FieldStatus/useFieldStatusAnnouncement.js +1 -0
  98. package/dist/FormLayout/FormLayout.d.ts +5 -1
  99. package/dist/FormLayout/FormLayout.d.ts.map +1 -1
  100. package/dist/HoverCard/HoverCard.d.ts +6 -4
  101. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  102. package/dist/HoverCard/HoverCard.js +48 -3
  103. package/dist/HoverCard/useHoverCard.d.ts +5 -4
  104. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  105. package/dist/HoverCard/useHoverCard.js +20 -33
  106. package/dist/Icon/Icon.d.ts +5 -1
  107. package/dist/Icon/Icon.d.ts.map +1 -1
  108. package/dist/Icon/Icon.js +5 -2
  109. package/dist/InfoTip/InfoTip.d.ts +5 -5
  110. package/dist/InfoTip/InfoTip.d.ts.map +1 -1
  111. package/dist/InfoTip/InfoTip.js +58 -19
  112. package/dist/Item/useSwipeAction.d.ts.map +1 -1
  113. package/dist/Item/useSwipeAction.js +3 -0
  114. package/dist/Layer/modalOutlet.d.ts.map +1 -1
  115. package/dist/Layer/modalOutlet.js +2 -0
  116. package/dist/Layer/outsidePress.d.ts.map +1 -1
  117. package/dist/Layer/outsidePress.js +1 -0
  118. package/dist/Layer/useLayer.d.ts.map +1 -1
  119. package/dist/Layer/useLayer.js +4 -1
  120. package/dist/Layer/useLayerDismissal.d.ts.map +1 -1
  121. package/dist/Layer/useLayerDismissal.js +3 -0
  122. package/dist/Layer/useTouchTrigger.d.ts +13 -7
  123. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  124. package/dist/Layer/useTouchTrigger.js +20 -6
  125. package/dist/Layout/index.d.ts +1 -1
  126. package/dist/Layout/index.d.ts.map +1 -1
  127. package/dist/Layout/index.js +1 -1
  128. package/dist/Layout/layoutReset.js +1 -1
  129. package/dist/Layout/overlayPaddingReset.stylex.d.ts +68 -0
  130. package/dist/Layout/overlayPaddingReset.stylex.d.ts.map +1 -0
  131. package/dist/Layout/overlayPaddingReset.stylex.js +72 -0
  132. package/dist/Layout/padding.stylex.d.ts +5 -129
  133. package/dist/Layout/padding.stylex.d.ts.map +1 -1
  134. package/dist/Layout/padding.stylex.js +9 -143
  135. package/dist/Layout/paddingStyles.stylex.d.ts +83 -0
  136. package/dist/Layout/paddingStyles.stylex.d.ts.map +1 -0
  137. package/dist/Layout/paddingStyles.stylex.js +99 -0
  138. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  139. package/dist/Lightbox/Lightbox.js +20 -1
  140. package/dist/MobileNav/MobileNav.d.ts +3 -2
  141. package/dist/MobileNav/MobileNav.d.ts.map +1 -1
  142. package/dist/MobileNav/MobileNav.js +10 -26
  143. package/dist/MultiSelector/MultiSelector.d.ts.map +1 -1
  144. package/dist/MultiSelector/MultiSelector.js +2 -1
  145. package/dist/NumberInput/NumberInput.d.ts.map +1 -1
  146. package/dist/NumberInput/NumberInput.js +2 -1
  147. package/dist/Outline/useOutlineFromDOM.d.ts.map +1 -1
  148. package/dist/Outline/useOutlineFromDOM.js +3 -0
  149. package/dist/Outline/useScrollSpy.d.ts.map +1 -1
  150. package/dist/Outline/useScrollSpy.js +3 -0
  151. package/dist/OverflowList/OverflowList.d.ts.map +1 -1
  152. package/dist/OverflowList/OverflowList.js +3 -0
  153. package/dist/Popover/Popover.d.ts.map +1 -1
  154. package/dist/Popover/Popover.js +6 -0
  155. package/dist/Popover/usePopover.js +2 -2
  156. package/dist/PowerSearch/PowerSearch.d.ts +39 -4
  157. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  158. package/dist/PowerSearch/PowerSearch.js +441 -134
  159. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +102 -0
  160. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -0
  161. package/dist/PowerSearch/PowerSearchBottomSheet.js +1919 -0
  162. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +35 -2
  163. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  164. package/dist/PowerSearch/PowerSearchEditPopover.js +43 -10
  165. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts +1 -1
  166. package/dist/PowerSearch/PowerSearchFilterEditor.d.ts.map +1 -1
  167. package/dist/PowerSearch/PowerSearchFilterEditor.js +4 -2
  168. package/dist/PowerSearch/PowerSearchToken.d.ts +1 -1
  169. package/dist/PowerSearch/PowerSearchToken.d.ts.map +1 -1
  170. package/dist/PowerSearch/PowerSearchToken.js +3 -2
  171. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +38 -3
  172. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  173. package/dist/PowerSearch/PowerSearchValueEditor.js +273 -86
  174. package/dist/PowerSearch/formatFilterValue.d.ts +14 -7
  175. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  176. package/dist/PowerSearch/formatFilterValue.js +31 -23
  177. package/dist/PowerSearch/formatTokenValue.d.ts +28 -0
  178. package/dist/PowerSearch/formatTokenValue.d.ts.map +1 -0
  179. package/dist/PowerSearch/formatTokenValue.js +161 -0
  180. package/dist/PowerSearch/index.d.ts +1 -1
  181. package/dist/PowerSearch/index.d.ts.map +1 -1
  182. package/dist/PowerSearch/powerSearchDateZone.d.ts +25 -0
  183. package/dist/PowerSearch/powerSearchDateZone.d.ts.map +1 -0
  184. package/dist/PowerSearch/powerSearchDateZone.js +57 -0
  185. package/dist/PowerSearch/powerSearchSheetUtils.d.ts +65 -0
  186. package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +1 -0
  187. package/dist/PowerSearch/powerSearchSheetUtils.js +168 -0
  188. package/dist/PowerSearch/types.d.ts +8 -1
  189. package/dist/PowerSearch/types.d.ts.map +1 -1
  190. package/dist/ProgressBar/ProgressBarTouch.d.ts.map +1 -1
  191. package/dist/ProgressBar/ProgressBarTouch.js +2 -0
  192. package/dist/RadioList/RadioList.d.ts.map +1 -1
  193. package/dist/RadioList/RadioList.js +3 -2
  194. package/dist/RadioList/RadioListItem.d.ts +1 -1
  195. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  196. package/dist/RadioList/RadioListItem.js +5 -3
  197. package/dist/Resizable/ResizeHandle.d.ts +2 -1
  198. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  199. package/dist/Resizable/ResizeHandle.js +101 -77
  200. package/dist/Resizable/createResizable.d.ts +145 -0
  201. package/dist/Resizable/createResizable.d.ts.map +1 -0
  202. package/dist/Resizable/createResizable.js +575 -0
  203. package/dist/Resizable/useResizable.d.ts +3 -3
  204. package/dist/Resizable/useResizable.d.ts.map +1 -1
  205. package/dist/Resizable/useResizable.js +252 -459
  206. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -1
  207. package/dist/SegmentedControl/useSegmentedSelectionMotion.js +3 -3
  208. package/dist/SelectableCard/SelectableCard.d.ts +2 -0
  209. package/dist/SelectableCard/SelectableCard.d.ts.map +1 -1
  210. package/dist/SelectableCard/SelectableCard.js +36 -11
  211. package/dist/SelectableCard/selectableCardInput.d.ts +12 -0
  212. package/dist/SelectableCard/selectableCardInput.d.ts.map +1 -0
  213. package/dist/SelectableCard/selectableCardInput.js +20 -0
  214. package/dist/Selector/Selector.d.ts.map +1 -1
  215. package/dist/Selector/Selector.js +7 -9
  216. package/dist/SideNav/SideNav.d.ts.map +1 -1
  217. package/dist/SideNav/SideNav.js +36 -5
  218. package/dist/Slider/Slider.d.ts.map +1 -1
  219. package/dist/Slider/Slider.js +16 -11
  220. package/dist/Slider/sliderTouchController.js +2 -2
  221. package/dist/Spinner/Spinner.d.ts +1 -1
  222. package/dist/Spinner/Spinner.d.ts.map +1 -1
  223. package/dist/Spinner/Spinner.js +60 -58
  224. package/dist/Stepper/Stepper.d.ts.map +1 -1
  225. package/dist/Stepper/Stepper.js +10 -15
  226. package/dist/Switch/Switch.d.ts.map +1 -1
  227. package/dist/Switch/Switch.js +4 -10
  228. package/dist/Switch/useSwitchTouch.js +4 -4
  229. package/dist/Table/BaseTable.d.ts.map +1 -1
  230. package/dist/Table/BaseTable.js +29 -8
  231. package/dist/Table/plugins/columnResize/useTableColumnResize.d.ts.map +1 -1
  232. package/dist/Table/plugins/columnResize/useTableColumnResize.js +3 -1
  233. package/dist/Table/plugins/filtering/useTableFiltering.d.ts.map +1 -1
  234. package/dist/Table/plugins/filtering/useTableFiltering.js +2 -1
  235. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.d.ts.map +1 -1
  236. package/dist/Table/plugins/rowExpansion/useTableRowExpansion.js +4 -0
  237. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.d.ts.map +1 -1
  238. package/dist/Table/plugins/stickyColumns/useTableStickyColumns.js +2 -0
  239. package/dist/TextArea/TextArea.d.ts.map +1 -1
  240. package/dist/TextArea/TextArea.js +2 -1
  241. package/dist/TextInput/TextInput.d.ts +2 -2
  242. package/dist/TextInput/TextInput.d.ts.map +1 -1
  243. package/dist/TextInput/TextInput.js +12 -8
  244. package/dist/TimeInput/TimeInput.d.ts.map +1 -1
  245. package/dist/TimeInput/TimeInput.js +2 -0
  246. package/dist/TimeInput/TouchTimeField.d.ts.map +1 -1
  247. package/dist/TimeInput/TouchTimeField.js +2 -0
  248. package/dist/Timer/Timer.d.ts.map +1 -1
  249. package/dist/Timer/Timer.js +2 -0
  250. package/dist/Timestamp/Timestamp.js +1 -1
  251. package/dist/Timestamp/formatInstant.d.ts.map +1 -1
  252. package/dist/Timestamp/formatInstant.js +1 -23
  253. package/dist/Toast/Toast.d.ts +11 -1
  254. package/dist/Toast/Toast.d.ts.map +1 -1
  255. package/dist/Toast/Toast.js +25 -15
  256. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  257. package/dist/Toast/ToastViewport.js +97 -34
  258. package/dist/Toast/types.d.ts +9 -3
  259. package/dist/Toast/types.d.ts.map +1 -1
  260. package/dist/Toast/useToast.d.ts.map +1 -1
  261. package/dist/Toast/useToast.js +1 -0
  262. package/dist/Tokenizer/Tokenizer.d.ts +44 -46
  263. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  264. package/dist/Tokenizer/Tokenizer.js +20 -21
  265. package/dist/Tokenizer/TokenizerBottomSheet.d.ts +1 -1
  266. package/dist/Tokenizer/TokenizerBottomSheet.js +4 -6
  267. package/dist/Tokenizer/index.d.ts +1 -1
  268. package/dist/Tokenizer/index.d.ts.map +1 -1
  269. package/dist/Tooltip/Tooltip.d.ts +2 -23
  270. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  271. package/dist/Tooltip/Tooltip.js +5 -29
  272. package/dist/Tooltip/useTooltip.d.ts +23 -30
  273. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  274. package/dist/Tooltip/useTooltip.js +194 -108
  275. package/dist/Typeahead/BaseTypeahead.d.ts.map +1 -1
  276. package/dist/Typeahead/BaseTypeahead.js +27 -18
  277. package/dist/Typeahead/TypeaheadItem.d.ts +2 -1
  278. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  279. package/dist/animator/createAnimator.d.ts +98 -0
  280. package/dist/animator/createAnimator.d.ts.map +1 -0
  281. package/dist/animator/createAnimator.js +259 -0
  282. package/dist/astryx.css +41 -7
  283. package/dist/gestures/GestureHost.d.ts +16 -1
  284. package/dist/gestures/GestureHost.d.ts.map +1 -1
  285. package/dist/gestures/GestureHost.js +1 -1
  286. package/dist/gestures/PressTracker.d.ts.map +1 -1
  287. package/dist/gestures/PressTracker.js +4 -3
  288. package/dist/hooks/ModalAnnounceProvider.d.ts.map +1 -1
  289. package/dist/hooks/ModalAnnounceProvider.js +1 -0
  290. package/dist/hooks/actionGroupTracker.d.ts +4 -1
  291. package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
  292. package/dist/hooks/actionGroupTracker.js +13 -3
  293. package/dist/hooks/index.d.ts +1 -0
  294. package/dist/hooks/index.d.ts.map +1 -1
  295. package/dist/hooks/index.js +1 -0
  296. package/dist/hooks/longPressDetector.d.ts +66 -0
  297. package/dist/hooks/longPressDetector.d.ts.map +1 -0
  298. package/dist/hooks/longPressDetector.js +200 -0
  299. package/dist/hooks/pressGroupContext.d.ts +6 -0
  300. package/dist/hooks/pressGroupContext.d.ts.map +1 -0
  301. package/dist/hooks/pressGroupContext.js +20 -0
  302. package/dist/hooks/rootScrollStyles.d.ts +48 -0
  303. package/dist/hooks/rootScrollStyles.d.ts.map +1 -0
  304. package/dist/hooks/rootScrollStyles.js +207 -0
  305. package/dist/hooks/scrollLockTouchGuard.d.ts +13 -0
  306. package/dist/hooks/scrollLockTouchGuard.d.ts.map +1 -0
  307. package/dist/hooks/scrollLockTouchGuard.js +117 -0
  308. package/dist/hooks/scrollbarGutter.d.ts +4 -4
  309. package/dist/hooks/scrollbarGutter.d.ts.map +1 -1
  310. package/dist/hooks/scrollbarGutter.js +36 -23
  311. package/dist/hooks/useActionGroupTracking.d.ts +53 -0
  312. package/dist/hooks/useActionGroupTracking.d.ts.map +1 -0
  313. package/dist/hooks/useActionGroupTracking.js +174 -0
  314. package/dist/hooks/useAnimator.d.ts +41 -0
  315. package/dist/hooks/useAnimator.d.ts.map +1 -0
  316. package/dist/hooks/useAnimator.js +70 -0
  317. package/dist/hooks/useAnnounceRenderedText.d.ts.map +1 -1
  318. package/dist/hooks/useAnnounceRenderedText.js +1 -0
  319. package/dist/hooks/useAttachment.d.ts +1 -1
  320. package/dist/hooks/useAttachment.js +1 -1
  321. package/dist/hooks/useAutoMediaMode.d.ts.map +1 -1
  322. package/dist/hooks/useAutoMediaMode.js +1 -0
  323. package/dist/hooks/useBusyAnnouncement.d.ts.map +1 -1
  324. package/dist/hooks/useBusyAnnouncement.js +2 -0
  325. package/dist/hooks/useDevWarning.d.ts.map +1 -1
  326. package/dist/hooks/useDevWarning.js +2 -0
  327. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  328. package/dist/hooks/useFocusTrap.js +2 -0
  329. package/dist/hooks/useGridFocus.d.ts +8 -5
  330. package/dist/hooks/useGridFocus.d.ts.map +1 -1
  331. package/dist/hooks/useGridFocus.js +4 -3
  332. package/dist/hooks/useHotkeys.d.ts.map +1 -1
  333. package/dist/hooks/useHotkeys.js +3 -0
  334. package/dist/hooks/useImageMode.d.ts.map +1 -1
  335. package/dist/hooks/useImageMode.js +3 -0
  336. package/dist/hooks/useInputStatusIcon.d.ts +1 -1
  337. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  338. package/dist/hooks/useInputStatusIcon.js +2 -2
  339. package/dist/hooks/useIsomorphicLayoutEffect.d.ts +2 -2
  340. package/dist/hooks/useIsomorphicLayoutEffect.d.ts.map +1 -1
  341. package/dist/hooks/useKeyboardHint.js +1 -1
  342. package/dist/hooks/useLongPress.d.ts +8 -9
  343. package/dist/hooks/useLongPress.d.ts.map +1 -1
  344. package/dist/hooks/useLongPress.js +23 -106
  345. package/dist/hooks/useMenuHover.d.ts.map +1 -1
  346. package/dist/hooks/useMenuHover.js +2 -0
  347. package/dist/hooks/useMenuPress.d.ts.map +1 -1
  348. package/dist/hooks/useMenuPress.js +3 -0
  349. package/dist/hooks/useOverflow.d.ts.map +1 -1
  350. package/dist/hooks/useOverflow.js +2 -1
  351. package/dist/hooks/usePressFeedback.d.ts.map +1 -1
  352. package/dist/hooks/usePressFeedback.js +1 -0
  353. package/dist/hooks/useResolvedRequired.d.ts +3 -0
  354. package/dist/hooks/useResolvedRequired.d.ts.map +1 -1
  355. package/dist/hooks/useResolvedRequired.js +3 -0
  356. package/dist/hooks/useScrollLock.d.ts +8 -9
  357. package/dist/hooks/useScrollLock.d.ts.map +1 -1
  358. package/dist/hooks/useScrollLock.js +50 -48
  359. package/dist/hooks/useScrollableArea.d.ts.map +1 -1
  360. package/dist/hooks/useScrollableArea.js +5 -0
  361. package/dist/hooks/useStreamingText.d.ts.map +1 -1
  362. package/dist/hooks/useStreamingText.js +3 -0
  363. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +8 -0
  364. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -0
  365. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +42 -0
  366. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
  367. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +6 -0
  368. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +8 -0
  369. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +1 -0
  370. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +14 -0
  371. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  372. package/dist/i18n/generated-locales/en.generated.js +30 -0
  373. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  374. package/dist/i18n/generated-locales/pseudo.generated.js +30 -0
  375. package/dist/index.d.ts +1 -0
  376. package/dist/index.d.ts.map +1 -1
  377. package/dist/index.js +4 -0
  378. package/dist/internal/indicatorPress.stylex.d.ts +20 -0
  379. package/dist/internal/indicatorPress.stylex.d.ts.map +1 -0
  380. package/dist/internal/indicatorPress.stylex.js +26 -0
  381. package/dist/internal/selectable-card.d.ts +21 -0
  382. package/dist/internal/selectable-card.d.ts.map +1 -0
  383. package/dist/internal/selectable-card.js +20 -0
  384. package/dist/internal/sheetDraft.d.ts +2 -2
  385. package/dist/internal/sheetDraft.js +2 -2
  386. package/dist/motion/animatedLayout.d.ts +8 -0
  387. package/dist/motion/animatedLayout.d.ts.map +1 -1
  388. package/dist/motion/animatedLayout.js +246 -53
  389. package/dist/motion/animator.d.ts +14 -14
  390. package/dist/motion/animator.d.ts.map +1 -1
  391. package/dist/motion/animator.js +45 -26
  392. package/dist/motion/frameBlock.d.ts +14 -0
  393. package/dist/motion/frameBlock.d.ts.map +1 -0
  394. package/dist/motion/frameBlock.js +16 -0
  395. package/dist/motion/progress.d.ts +88 -0
  396. package/dist/motion/progress.d.ts.map +1 -0
  397. package/dist/motion/progress.js +128 -0
  398. package/dist/motion/reducedMotion.d.ts.map +1 -1
  399. package/dist/motion/reducedMotion.js +3 -1
  400. package/dist/motion/uikit/alert.d.ts +41 -0
  401. package/dist/motion/uikit/alert.d.ts.map +1 -0
  402. package/dist/motion/uikit/alert.js +43 -0
  403. package/dist/motion/uikit/index.d.ts +4 -3
  404. package/dist/motion/uikit/index.d.ts.map +1 -1
  405. package/dist/motion/uikit/index.js +4 -3
  406. package/dist/motion/uikit/picker.d.ts +96 -0
  407. package/dist/motion/uikit/picker.d.ts.map +1 -0
  408. package/dist/motion/uikit/picker.js +117 -0
  409. package/dist/privateAttributes/pressGroupItem.stylex.d.ts +22 -0
  410. package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +1 -0
  411. package/dist/privateAttributes/pressGroupItem.stylex.js +36 -0
  412. package/dist/privateAttributes/reducedMotion.stylex.d.ts +23 -0
  413. package/dist/privateAttributes/reducedMotion.stylex.d.ts.map +1 -0
  414. package/dist/privateAttributes/reducedMotion.stylex.js +40 -0
  415. package/dist/theme/Theme.d.ts.map +1 -1
  416. package/dist/theme/Theme.js +29 -4
  417. package/dist/theme/generateThemeRules.d.ts.map +1 -1
  418. package/dist/theme/generateThemeRules.js +14 -13
  419. package/dist/theme/motionKnobs.d.ts +4 -3
  420. package/dist/theme/motionKnobs.d.ts.map +1 -1
  421. package/dist/theme/motionKnobs.js +3 -2
  422. package/dist/theme/themeMotion.d.ts +6 -0
  423. package/dist/theme/themeMotion.d.ts.map +1 -1
  424. package/dist/theme/themeMotion.js +15 -2
  425. package/dist/theme/tokens.stylex.d.ts +3 -0
  426. package/dist/theme/tokens.stylex.d.ts.map +1 -1
  427. package/dist/theme/tokens.stylex.js +4 -1
  428. package/dist/utils/dateParser.d.ts.map +1 -1
  429. package/dist/utils/dateParser.js +12 -0
  430. package/dist/utils/disabledInteraction.d.ts +10 -2
  431. package/dist/utils/disabledInteraction.d.ts.map +1 -1
  432. package/dist/utils/disabledInteraction.js +16 -2
  433. package/dist/utils/focusReturn.d.ts +22 -25
  434. package/dist/utils/focusReturn.d.ts.map +1 -1
  435. package/dist/utils/focusReturn.js +36 -29
  436. package/dist/utils/index.d.ts +1 -1
  437. package/dist/utils/index.d.ts.map +1 -1
  438. package/dist/utils/index.js +1 -1
  439. package/dist/utils/interactionModality.d.ts.map +1 -1
  440. package/dist/utils/interactionModality.js +4 -0
  441. package/dist/utils/interactionOverlay.stylex.d.ts +3 -2
  442. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  443. package/dist/utils/interactionOverlay.stylex.js +3 -2
  444. package/dist/utils/isFocusDetached.d.ts +27 -0
  445. package/dist/utils/isFocusDetached.d.ts.map +1 -0
  446. package/dist/utils/isFocusDetached.js +32 -0
  447. package/dist/utils/plainDate.d.ts +31 -0
  448. package/dist/utils/plainDate.d.ts.map +1 -1
  449. package/dist/utils/plainDate.js +68 -4
  450. package/dist/utils/pressFeedback.d.ts.map +1 -1
  451. package/dist/utils/pressFeedback.js +20 -6
  452. package/dist/utils/triggerFocus.d.ts +36 -0
  453. package/dist/utils/triggerFocus.d.ts.map +1 -0
  454. package/dist/utils/triggerFocus.js +65 -0
  455. package/locales/en.json +120 -0
  456. package/locales/pseudo.json +90 -0
  457. package/package.json +14 -9
  458. package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
  459. package/src/AlertDialog/AlertDialog.tsx +46 -5
  460. package/src/AppShell/AppShell.tsx +13 -4
  461. package/src/BottomSheet/BottomSheet.tsx +1 -0
  462. package/src/BottomSheet/BottomSheetPanel.tsx +39 -3
  463. package/src/BottomSheet/BottomSheetSwitcher.tsx +5 -0
  464. package/src/BottomSheet/useMobileKeyboard.ts +4 -0
  465. package/src/BottomSheet/useSheetGestures.ts +10 -1
  466. package/src/Button/Button.tsx +26 -4
  467. package/src/Calendar/Calendar.tsx +40 -32
  468. package/src/Calendar/getWeekdayHeaderNames.ts +88 -0
  469. package/src/Calendar/hooks/useCalendarDays.ts +5 -10
  470. package/src/Calendar/{standaloneShortWeekdayNames.generated.ts → weekdayHeaderNames.generated.ts} +14 -14
  471. package/src/Carousel/Carousel.tsx +1 -0
  472. package/src/Chat/ChatComposerInput.tsx +4 -7
  473. package/src/Chat/ChatMessageList.tsx +2 -1
  474. package/src/Chat/useChatDictation.ts +1 -0
  475. package/src/Chat/useChatNewMessages.ts +1 -1
  476. package/src/Chat/useChatStreamScroll.ts +2 -0
  477. package/src/Chat/useSpeechRecognition.ts +2 -0
  478. package/src/Chat/useTriggerMenu.tsx +1 -1
  479. package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -0
  480. package/src/CheckboxInput/CheckboxInput.tsx +38 -15
  481. package/src/CheckboxList/CheckboxList.doc.mjs +7 -0
  482. package/src/CheckboxList/CheckboxList.tsx +9 -0
  483. package/src/CodeBlock/CodeBlock.doc.mjs +9 -1
  484. package/src/CodeBlock/CodeBlock.tsx +41 -4
  485. package/src/CommandPalette/CommandPalette.tsx +1 -0
  486. package/src/CommandPalette/CommandPaletteItem.tsx +1 -0
  487. package/src/ComplexSelector/ComplexSelector.tsx +20 -5
  488. package/src/ContextMenu/ContextMenu.tsx +2 -2
  489. package/src/DateInput/MonthScroller.tsx +8 -2
  490. package/src/DateInput/PickerWheel.tsx +765 -0
  491. package/src/DateInput/TouchDateField.tsx +6 -32
  492. package/src/DateInput/Wheel.tsx +94 -150
  493. package/src/DateInput/useOwnScrollGesture.ts +25 -3
  494. package/src/DateInput/usePointerDragScroll.ts +1 -0
  495. package/src/DateInput/useScrollSettle.ts +2 -0
  496. package/src/DateInput/useWheelListbox.ts +112 -0
  497. package/src/DateInput/wheelOptions.ts +155 -0
  498. package/src/DateInput/wheelPhysics.ts +406 -0
  499. package/src/DateInput/wheelStrip.ts +341 -0
  500. package/src/DateTimeInput/TouchDateTimeField.tsx +8 -13
  501. package/src/Dialog/Dialog.tsx +12 -32
  502. package/src/Drawer/useDrawerDialogPresence.ts +2 -0
  503. package/src/DropdownMenu/useMenuOverflow.ts +3 -0
  504. package/src/Field/Field.tsx +2 -2
  505. package/src/FieldStatus/useFieldStatusAnnouncement.ts +1 -0
  506. package/src/FormLayout/FormLayout.doc.mjs +181 -46
  507. package/src/FormLayout/FormLayout.tsx +5 -1
  508. package/src/HoverCard/HoverCard.doc.mjs +10 -8
  509. package/src/HoverCard/HoverCard.tsx +58 -6
  510. package/src/HoverCard/useHoverCard.doc.mjs +178 -36
  511. package/src/HoverCard/useHoverCard.tsx +49 -54
  512. package/src/Icon/Icon.doc.mjs +51 -10
  513. package/src/Icon/Icon.tsx +15 -7
  514. package/src/IconButton/IconButton.doc.mjs +141 -21
  515. package/src/InfoTip/InfoTip.tsx +72 -16
  516. package/src/Item/useSwipeAction.ts +2 -0
  517. package/src/Layer/modalOutlet.ts +2 -0
  518. package/src/Layer/outsidePress.ts +1 -0
  519. package/src/Layer/useLayer.tsx +3 -1
  520. package/src/Layer/useLayerDismissal.ts +2 -0
  521. package/src/Layer/useTouchTrigger.ts +19 -6
  522. package/src/Layout/index.ts +1 -1
  523. package/src/Layout/layoutReset.ts +1 -1
  524. package/src/Layout/overlayPaddingReset.stylex.ts +73 -0
  525. package/src/Layout/padding.stylex.ts +9 -133
  526. package/src/Layout/paddingStyles.stylex.ts +87 -0
  527. package/src/Lightbox/Lightbox.tsx +20 -1
  528. package/src/Lightbox/useLightbox.doc.mjs +167 -0
  529. package/src/MobileNav/MobileNav.tsx +10 -31
  530. package/src/MultiSelector/MultiSelector.tsx +2 -7
  531. package/src/NumberInput/NumberInput.tsx +2 -7
  532. package/src/Outline/useOutlineFromDOM.ts +2 -0
  533. package/src/Outline/useScrollSpy.ts +2 -0
  534. package/src/OverflowList/OverflowList.tsx +2 -0
  535. package/src/Popover/Popover.tsx +4 -0
  536. package/src/Popover/usePopover.tsx +2 -2
  537. package/src/PowerSearch/PowerSearch.doc.mjs +60 -8
  538. package/src/PowerSearch/PowerSearch.tsx +620 -157
  539. package/src/PowerSearch/PowerSearchBottomSheet.tsx +2525 -0
  540. package/src/PowerSearch/PowerSearchEditPopover.tsx +65 -9
  541. package/src/PowerSearch/PowerSearchFilterEditor.tsx +2 -0
  542. package/src/PowerSearch/PowerSearchToken.tsx +2 -0
  543. package/src/PowerSearch/PowerSearchValueEditor.tsx +340 -59
  544. package/src/PowerSearch/formatFilterValue.ts +49 -27
  545. package/src/PowerSearch/formatTokenValue.ts +220 -0
  546. package/src/PowerSearch/index.ts +5 -1
  547. package/src/PowerSearch/powerSearchDateZone.ts +95 -0
  548. package/src/PowerSearch/powerSearchSheetUtils.ts +224 -0
  549. package/src/PowerSearch/types.ts +8 -1
  550. package/src/ProgressBar/ProgressBarTouch.ts +2 -0
  551. package/src/RadioList/RadioList.tsx +3 -2
  552. package/src/RadioList/RadioListItem.tsx +5 -3
  553. package/src/Resizable/Resizable.doc.mjs +5 -4
  554. package/src/Resizable/ResizeHandle.tsx +169 -109
  555. package/src/Resizable/createResizable.ts +831 -0
  556. package/src/Resizable/useResizable.ts +292 -623
  557. package/src/SegmentedControl/useSegmentedSelectionMotion.ts +6 -3
  558. package/src/SelectableCard/SelectableCard.tsx +39 -10
  559. package/src/SelectableCard/selectableCardInput.ts +30 -0
  560. package/src/Selector/Selector.tsx +7 -19
  561. package/src/SideNav/SideNav.tsx +41 -5
  562. package/src/Slider/Slider.tsx +20 -11
  563. package/src/Slider/sliderTouchController.ts +2 -2
  564. package/src/Spinner/Spinner.tsx +77 -63
  565. package/src/Stepper/Stepper.tsx +10 -27
  566. package/src/Switch/Switch.tsx +2 -6
  567. package/src/Switch/useSwitchTouch.ts +4 -4
  568. package/src/Table/BaseTable.tsx +46 -12
  569. package/src/Table/plugins/columnResize/useTableColumnResize.tsx +2 -1
  570. package/src/Table/plugins/filtering/useTableFiltering.tsx +1 -0
  571. package/src/Table/plugins/rowExpansion/useTableRowExpansion.tsx +4 -0
  572. package/src/Table/plugins/stickyColumns/useTableStickyColumns.tsx +2 -0
  573. package/src/TextArea/TextArea.tsx +2 -7
  574. package/src/TextInput/TextInput.tsx +13 -17
  575. package/src/TimeInput/TimeInput.tsx +2 -0
  576. package/src/TimeInput/TouchTimeField.tsx +2 -0
  577. package/src/Timer/Timer.tsx +1 -0
  578. package/src/Timestamp/Timestamp.tsx +1 -1
  579. package/src/Timestamp/formatInstant.ts +1 -33
  580. package/src/Toast/Toast.doc.mjs +4 -3
  581. package/src/Toast/Toast.tsx +52 -32
  582. package/src/Toast/ToastViewport.tsx +123 -35
  583. package/src/Toast/types.ts +9 -3
  584. package/src/Toast/useToast.tsx +1 -0
  585. package/src/Tokenizer/Tokenizer.doc.mjs +10 -10
  586. package/src/Tokenizer/Tokenizer.tsx +61 -62
  587. package/src/Tokenizer/TokenizerBottomSheet.tsx +9 -11
  588. package/src/Tokenizer/index.ts +1 -0
  589. package/src/Tooltip/Tooltip.tsx +6 -42
  590. package/src/Tooltip/useTooltip.doc.mjs +24 -0
  591. package/src/Tooltip/useTooltip.tsx +237 -134
  592. package/src/Typeahead/BaseTypeahead.tsx +27 -17
  593. package/src/Typeahead/TypeaheadItem.doc.mjs +6 -3
  594. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  595. package/src/animator/createAnimator.doc.mjs +153 -0
  596. package/src/animator/createAnimator.ts +324 -0
  597. package/src/gestures/GestureHost.ts +1 -1
  598. package/src/gestures/PressTracker.ts +4 -3
  599. package/src/gestures/README.md +10 -4
  600. package/src/hooks/ModalAnnounceProvider.tsx +1 -0
  601. package/src/hooks/actionGroupTracker.ts +20 -5
  602. package/src/hooks/index.ts +2 -0
  603. package/src/hooks/longPressDetector.ts +273 -0
  604. package/src/hooks/pressGroupContext.ts +21 -0
  605. package/src/hooks/rootScrollStyles.ts +247 -0
  606. package/src/hooks/scrollLockTouchGuard.ts +149 -0
  607. package/src/hooks/scrollbarGutter.ts +41 -26
  608. package/src/hooks/useActionGroupTracking.ts +224 -0
  609. package/src/hooks/useAnimator.doc.mjs +109 -0
  610. package/src/hooks/useAnimator.ts +67 -0
  611. package/src/hooks/useAnnounceRenderedText.ts +1 -0
  612. package/src/hooks/useAttachment.ts +1 -1
  613. package/src/hooks/useAutoMediaMode.ts +1 -0
  614. package/src/hooks/useBusyAnnouncement.ts +2 -0
  615. package/src/hooks/useDevWarning.ts +2 -0
  616. package/src/hooks/useFocusTrap.ts +2 -0
  617. package/src/hooks/useGridFocus.doc.mjs +6 -6
  618. package/src/hooks/useGridFocus.ts +10 -7
  619. package/src/hooks/useHotkeys.ts +2 -0
  620. package/src/hooks/useImageMode.ts +2 -0
  621. package/src/hooks/useInputStatusIcon.tsx +3 -2
  622. package/src/hooks/useKeyboardHint.tsx +1 -1
  623. package/src/hooks/useLongPress.doc.mjs +2 -2
  624. package/src/hooks/useLongPress.ts +32 -122
  625. package/src/hooks/useMenuHover.ts +1 -0
  626. package/src/hooks/useMenuPress.ts +2 -0
  627. package/src/hooks/useOverflow.ts +2 -1
  628. package/src/hooks/usePressFeedback.ts +1 -0
  629. package/src/hooks/useResolvedRequired.ts +3 -0
  630. package/src/hooks/useScrollLock.doc.mjs +51 -12
  631. package/src/hooks/useScrollLock.ts +53 -60
  632. package/src/hooks/useScrollableArea.ts +4 -0
  633. package/src/hooks/useStreamingText.ts +2 -0
  634. package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +43 -0
  635. package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +6 -0
  636. package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +15 -0
  637. package/src/i18n/generated-locales/en.generated.ts +41 -0
  638. package/src/i18n/generated-locales/pseudo.generated.ts +42 -0
  639. package/src/index.ts +13 -0
  640. package/src/internal/indicatorPress.stylex.ts +24 -0
  641. package/src/internal/selectable-card.ts +21 -0
  642. package/src/internal/sheetDraft.ts +2 -2
  643. package/src/motion/MEASUREMENTS.md +18 -0
  644. package/src/motion/README.md +10 -5
  645. package/src/motion/animatedLayout.ts +323 -60
  646. package/src/motion/animator.ts +66 -37
  647. package/src/motion/frameBlock.ts +16 -0
  648. package/src/motion/progress.ts +155 -0
  649. package/src/motion/reducedMotion.ts +3 -1
  650. package/src/motion/uikit/alert.ts +43 -0
  651. package/src/motion/uikit/index.ts +4 -3
  652. package/src/motion/uikit/picker.ts +116 -0
  653. package/src/privateAttributes/pressGroupItem.stylex.ts +44 -0
  654. package/src/privateAttributes/reducedMotion.stylex.ts +45 -0
  655. package/src/theme/Theme.tsx +37 -3
  656. package/src/theme/generateThemeRules.ts +14 -12
  657. package/src/theme/motionKnobs.ts +4 -3
  658. package/src/theme/themeMotion.ts +17 -2
  659. package/src/theme/tokens.stylex.ts +2 -0
  660. package/src/utils/dateParser.ts +16 -0
  661. package/src/utils/disabledInteraction.ts +23 -2
  662. package/src/utils/focusReturn.ts +38 -31
  663. package/src/utils/index.ts +1 -1
  664. package/src/utils/interactionModality.ts +4 -0
  665. package/src/utils/interactionOverlay.stylex.ts +3 -2
  666. package/src/utils/isFocusDetached.ts +34 -0
  667. package/src/utils/plainDate.ts +80 -4
  668. package/src/utils/pressFeedback.ts +24 -6
  669. package/src/utils/triggerFocus.ts +80 -0
  670. package/dist/Calendar/getStandaloneShortWeekdayNames.d.ts +0 -14
  671. package/dist/Calendar/getStandaloneShortWeekdayNames.d.ts.map +0 -1
  672. package/dist/Calendar/getStandaloneShortWeekdayNames.js +0 -26
  673. package/dist/Calendar/standaloneShortWeekdayNames.generated.d.ts.map +0 -1
  674. package/dist/Layer/usePressPin.d.ts +0 -93
  675. package/dist/Layer/usePressPin.d.ts.map +0 -1
  676. package/dist/Layer/usePressPin.js +0 -363
  677. package/dist/internal/touch-sheet.d.ts +0 -21
  678. package/dist/internal/touch-sheet.d.ts.map +0 -1
  679. package/dist/internal/touch-sheet.js +0 -19
  680. package/src/Calendar/getStandaloneShortWeekdayNames.ts +0 -38
  681. package/src/Layer/usePressPin.ts +0 -510
  682. package/src/internal/touch-sheet.ts +0 -21
@@ -4,19 +4,25 @@
4
4
 
5
5
  /**
6
6
  * @file PowerSearch.tsx
7
- * @input PowerSearchConfig, filters, onChange
7
+ * @input PowerSearchConfig, filters, onChange; Tokenizer, Field parts, Token,
8
+ * useAdaptivePresentation, and PowerSearchBottomSheet (lazy)
8
9
  * @output Structured filter bar with token-based filter management
9
10
  * @position Main component; forwards DOM ref and exposes tokenizer control via
10
- * handleRef
11
+ * handleRef. The `presentation` prop swaps the tokenizer field and editor
12
+ * popover for one trigger that opens PowerSearchBottomSheet.
11
13
  *
12
14
  * SYNC: When modified, update:
13
15
  * - /packages/core/src/PowerSearch/index.ts
16
+ * - /packages/core/src/PowerSearch/PowerSearchBottomSheet.tsx (sheet presentation)
14
17
  * - /packages/cli/assets/templates/blocks/components/PowerSearch/ (showcase blocks)
15
18
  */
16
19
 
17
20
  import React, {
21
+ lazy,
22
+ Suspense,
18
23
  useCallback,
19
24
  useEffect,
25
+ useId,
20
26
  useImperativeHandle,
21
27
  useMemo,
22
28
  useRef,
@@ -37,30 +43,48 @@ import {Token} from '../Token';
37
43
  import {TokenNamingContext} from '../Token/TokenNamingContext';
38
44
  import {Avatar} from '../Avatar';
39
45
  import {layerAnimations} from '../Layer/layerAnimations.stylex';
40
- import {Icon} from '../Icon';
46
+ import {Icon, renderIconSlot} from '../Icon';
41
47
  import type {IconType} from '../Icon';
42
48
  import type {IconName} from '../Icon/globalIconRegistry';
43
49
  import type {InputStatus} from '../Field';
50
+ import {Field} from '../Field/Field';
51
+ import {
52
+ inputStatusBorderStyles,
53
+ inputStatusFocusWithinStyles,
54
+ inputStatusHoverShadowStyles,
55
+ inputWrapperStyles,
56
+ } from '../Field/inputStyles.stylex';
44
57
  import {usePopover} from '../Popover/usePopover';
58
+ import {useTooltip} from '../Tooltip/useTooltip';
45
59
  import {layerViewportInset} from '../Layer/layerViewportInset.stylex';
46
60
  import {useAnnounce} from '../hooks/useAnnounce';
61
+ import {
62
+ type AdaptivePresentation,
63
+ useAdaptivePresentation,
64
+ } from '../hooks/useAdaptivePresentation';
65
+ import {useDevWarning} from '../hooks/useDevWarning';
66
+ import {useIsHydrating} from '../hooks/useIsHydrating';
47
67
  import {
48
68
  spacingVars,
49
69
  colorVars,
70
+ sizeVars,
50
71
  typeScaleVars,
72
+ typographyVars,
51
73
  fontWeightVars,
52
74
  } from '../theme/tokens.stylex';
53
75
  import {useSize} from '../SizeContext/SizeContext';
76
+ import {isFocusDetached} from '../utils/isFocusDetached';
77
+ import {isRenderable} from '../utils/isRenderable';
54
78
  import {useInternalConfig} from './useInternalConfig';
55
79
  import {usePowerSearchSource} from './usePowerSearchSource';
80
+ import {formatFilterValue} from './formatFilterValue';
81
+ import {NestedEditor, PowerSearchEditPopover} from './PowerSearchEditPopover';
56
82
  import {
57
- formatFilterValue,
58
- formatDateAbsoluteCompact,
59
- } from './formatFilterValue';
60
- import {PowerSearchEditPopover} from './PowerSearchEditPopover';
83
+ buildRelativeDateOptions,
84
+ PowerSearchValueEditor,
85
+ } from './PowerSearchValueEditor';
61
86
  import {resolveOperatorLabel} from './resolveOperatorLabel';
62
87
  import {themeProps} from '../utils/themeProps';
63
- import {truncateCharacters} from '../utils/characters';
64
88
  import {useLocale} from '../i18n/useLocale';
65
89
  import type {Locale} from '../i18n/types';
66
90
  import type {SearchableItem} from '../Typeahead/types';
@@ -74,10 +98,14 @@ import type {
74
98
  PowerSearchHandle,
75
99
  FilterValue,
76
100
  OperatorValue,
77
- EnumItem,
78
101
  PowerSearchComponents,
79
102
  PowerSearchOperator,
80
103
  } from './types';
104
+ import type {
105
+ PowerSearchBottomSheetProps,
106
+ PowerSearchSheetEditors,
107
+ } from './PowerSearchBottomSheet';
108
+ import {formatTokenValueText} from './formatTokenValue';
81
109
 
82
110
  import {useMergedRefs} from '../hooks/useMergedRefs';
83
111
  import type {FieldStatusPlacement} from '../Field/fieldStatusPlacement';
@@ -150,130 +178,127 @@ const resultCountStyles = stylex.create({
150
178
  },
151
179
  });
152
180
 
153
- function truncateString(value: string, limit: number): string {
154
- // Same semantics as before — strings within limit + 3 pass through, longer
155
- // ones cut to limit + '...' — but counted in characters, not code units.
156
- return truncateCharacters(value, limit + 3, '...');
157
- }
181
+ // The sheet presentation's trigger field: the same control box as the
182
+ // tokenizer field, with display-only tokens and one button as its only tab
183
+ // stop.
184
+ const sheetTriggerSizeStyles = stylex.create({
185
+ sm: {minHeight: sizeVars['--size-element-sm']},
186
+ md: {minHeight: sizeVars['--size-element-md']},
187
+ lg: {minHeight: sizeVars['--size-element-lg']},
188
+ });
158
189
 
159
- function getEnumLabel(values: ReadonlyArray<EnumItem>, value: string): string {
160
- return values.find(v => v.value === value)?.label ?? value;
161
- }
190
+ const sheetTriggerStyles = stylex.create({
191
+ wrapper: {
192
+ position: 'relative',
193
+ flexWrap: 'nowrap',
194
+ gap: spacingVars['--spacing-1'],
195
+ height: 'auto',
196
+ cursor: {
197
+ default: 'pointer',
198
+ ':is([aria-disabled="true"])': 'default',
199
+ },
200
+ },
201
+ wrapperWithTokens: {
202
+ paddingBlock: `calc(${spacingVars['--spacing-1']} - 1px)`,
203
+ paddingInline: `calc(${spacingVars['--spacing-1']} - 1px)`,
204
+ },
205
+ contentSection: {
206
+ position: 'relative',
207
+ minWidth: 0,
208
+ flexGrow: 1,
209
+ display: 'flex',
210
+ alignItems: 'center',
211
+ flexWrap: 'wrap',
212
+ columnGap: spacingVars['--spacing-1'],
213
+ rowGap: `calc(${spacingVars['--spacing-1']} - 1px)`,
214
+ },
215
+ startIconWithTokens: {
216
+ marginInlineStart: `calc(${spacingVars['--spacing-2']} - ${spacingVars['--spacing-1']} + 1px)`,
217
+ },
218
+ // The only tab stop in the field. It stays visually borderless while the
219
+ // wrapper delegates taps on tokens and empty space to it.
220
+ trigger: {
221
+ appearance: 'none',
222
+ flex: '1 1 40px',
223
+ minWidth: '40px',
224
+ alignSelf: 'stretch',
225
+ display: 'flex',
226
+ alignItems: 'center',
227
+ paddingBlock: 0,
228
+ paddingInline: spacingVars['--spacing-1'],
229
+ margin: 0,
230
+ borderWidth: 0,
231
+ borderStyle: 'none',
232
+ backgroundColor: 'transparent',
233
+ color: colorVars['--color-text-secondary'],
234
+ fontFamily: typographyVars['--font-family-body'],
235
+ fontSize: typeScaleVars['--text-body-size'],
236
+ lineHeight: typeScaleVars['--text-body-leading'],
237
+ textAlign: 'start',
238
+ whiteSpace: 'nowrap',
239
+ cursor: {
240
+ default: 'pointer',
241
+ ':is([aria-disabled="true"])': 'default',
242
+ },
243
+ outline: 'none',
244
+ },
245
+ // Once a token is present the empty trigger covers the token lane instead
246
+ // of reserving 40px or wrapping onto an otherwise blank row.
247
+ triggerWithTokens: {
248
+ position: 'absolute',
249
+ inset: 0,
250
+ minWidth: 0,
251
+ padding: 0,
252
+ },
253
+ endSection: {
254
+ display: 'flex',
255
+ alignItems: 'center',
256
+ gap: spacingVars['--spacing-2'],
257
+ flexShrink: 0,
258
+ paddingInlineEnd: spacingVars['--spacing-1'],
259
+ },
260
+ });
261
+
262
+ // The sheet flow (three standalone sheets, the sheet editors) only
263
+ // renders for the bottom-sheet presentation. Loading it on demand keeps it out
264
+ // of pages whose PowerSearch stays a tokenizer field.
265
+ // One import promise, shared by the preload and the lazy element: the sheet
266
+ // presentation loads the flow's chunk as soon as it is active, so the first
267
+ // press does not wait for the network, while nothing of the flow is rendered
268
+ // until a press.
269
+ const loadPowerSearchBottomSheet = async () =>
270
+ import('./PowerSearchBottomSheet');
271
+ const LazyPowerSearchBottomSheet = lazy(async () =>
272
+ loadPowerSearchBottomSheet().then(module => ({
273
+ default: module.PowerSearchBottomSheet,
274
+ })),
275
+ );
276
+ // The value step reuses the popover presentation's editors, which this
277
+ // module already loads; see PowerSearchSheetEditors.
278
+ const SHEET_EDITORS: PowerSearchSheetEditors = {
279
+ NestedEditor,
280
+ PowerSearchValueEditor,
281
+ buildRelativeDateOptions,
282
+ };
162
283
 
163
284
  /**
164
- * The visible text of a filter token's value. The token renders it, and the
165
- * token's remove button and editor dialog are named by the same text.
285
+ * Hosts the lazily loaded sheet flow. Renders nothing on the server or in the
286
+ * render that hydrates server HTML: a lazy component that has not loaded yet
287
+ * would leave server markup incomplete and abort hydration. The closed flow
288
+ * has no visible markup, so it first renders right after hydration.
166
289
  */
167
- function tokenValueText(
168
- operatorValue: OperatorValue,
169
- filterValue: FilterValue,
170
- maxLength: number,
171
- locale: Locale,
172
- ): string | null {
173
- switch (filterValue.type) {
174
- case 'empty':
175
- return null;
176
-
177
- case 'string':
178
- return truncateString(filterValue.value, maxLength);
179
-
180
- case 'integer':
181
- case 'float':
182
- return String(filterValue.value);
183
-
184
- case 'enum':
185
- if (operatorValue.type === 'enum') {
186
- return truncateString(
187
- getEnumLabel(operatorValue.values, filterValue.value),
188
- maxLength,
189
- );
190
- }
191
- return truncateString(filterValue.value, maxLength);
192
-
193
- case 'string_list': {
194
- const items = filterValue.value;
195
- if (items.length === 0) {
196
- return null;
197
- }
198
- if (items.length === 1) {
199
- return truncateString(items[0], maxLength);
200
- }
201
- const totalLength = items.reduce((sum, s) => sum + s.length, 0);
202
- if (totalLength > maxLength) {
203
- return `${items.length} items`;
204
- }
205
- return items.join(', ');
206
- }
207
-
208
- case 'enum_list': {
209
- const items = filterValue.value;
210
- if (items.length === 0) {
211
- return null;
212
- }
213
- if (operatorValue.type === 'enum_list') {
214
- const labels = items.map(v => getEnumLabel(operatorValue.values, v));
215
- if (labels.length === 1) {
216
- return truncateString(labels[0], maxLength);
217
- }
218
- const totalLength = labels.reduce((sum, s) => sum + s.length, 0);
219
- if (totalLength > maxLength) {
220
- return `${labels.length} items`;
221
- }
222
- return labels.join(', ');
223
- }
224
- if (items.length === 1) {
225
- return truncateString(items[0], maxLength);
226
- }
227
- return `${items.length} items`;
228
- }
229
-
230
- case 'entity_list': {
231
- const entities = filterValue.value;
232
- if (entities.length === 0) {
233
- return null;
234
- }
235
- if (entities.length === 1) {
236
- return truncateString(entities[0].label, maxLength);
237
- }
238
- const totalLength = entities.reduce((sum, e) => sum + e.label.length, 0);
239
- if (totalLength > maxLength) {
240
- return `${entities.length} items`;
241
- }
242
- return entities.map(e => e.label).join(', ');
243
- }
244
-
245
- case 'time':
246
- return filterValue.value;
247
-
248
- case 'date_absolute':
249
- return truncateString(
250
- formatDateAbsoluteCompact(filterValue.unixSeconds, locale),
251
- maxLength,
252
- );
253
-
254
- case 'date_relative':
255
- return truncateString(filterValue.value, maxLength);
256
-
257
- case 'date_range':
258
- return 'date range';
259
-
260
- case 'custom':
261
- if (operatorValue.type === 'custom') {
262
- return truncateString(
263
- operatorValue.getString(filterValue.value),
264
- maxLength,
265
- );
266
- }
267
- return filterValue.value;
268
-
269
- case 'nested': {
270
- const count = filterValue.value.length;
271
- return count === 1 ? '1 filter' : `${count} filters`;
272
- }
273
-
274
- default:
275
- return null;
290
+ function PowerSearchSheetHost(
291
+ props: Omit<PowerSearchBottomSheetProps, 'editors'>,
292
+ ) {
293
+ const isHydrating = useIsHydrating();
294
+ if (isHydrating) {
295
+ return null;
276
296
  }
297
+ return (
298
+ <Suspense fallback={null}>
299
+ <LazyPowerSearchBottomSheet {...props} editors={SHEET_EDITORS} />
300
+ </Suspense>
301
+ );
277
302
  }
278
303
 
279
304
  function PowerSearchTokenValue({text}: {text: string}) {
@@ -356,7 +381,13 @@ export interface PowerSearchProps extends Omit<
356
381
  maxSearchResults?: number;
357
382
  /** Label for the save button in edit popover. @default 'Apply' */
358
383
  popoverSaveButtonLabel?: string;
359
- /** Timezone ID for date formatting. */
384
+ /**
385
+ * IANA zone a date-only `date_absolute` value, and each absolute part of a
386
+ * `date_range`, is read and written in: the token, the label and the editor
387
+ * show its day there, and a picked day stores as that midnight. Unset, a
388
+ * day is its UTC day. A `date_absolute` with `isDateOnly: false` shows and
389
+ * edits its date and time in it; unset, in the viewer's zone.
390
+ */
360
391
  timezoneID?: string;
361
392
  /**
362
393
  * Controls how tokens overflow when the container is too narrow.
@@ -388,8 +419,34 @@ export interface PowerSearchProps extends Omit<
388
419
  * Keys are operator value types (e.g. 'string', 'enum', 'date_absolute').
389
420
  */
390
421
  components?: PowerSearchComponents;
422
+ /**
423
+ * How the field presents filter editing.
424
+ * - `'popover'`: the tokenizer field with its typeahead and the editor
425
+ * popover, on every device.
426
+ * - `'bottom-sheet'`: the whole field is one trigger showing display-only
427
+ * filter tokens; it opens a stack of sheets. Filters lists the filters
428
+ * as rows that edit or remove one, with Add filter, Done, and Clear
429
+ * all, which asks first and keeps read-only filters. Add filter opens
430
+ * above it with the fields (or the content search with inline
431
+ * suggestions), and a value step opens above that, stages operator →
432
+ * value, and confirms from its footer. Dismissing a step reveals the
433
+ * one beneath. Suited to compact touch screens, where the editor
434
+ * popover competes with the software keyboard.
435
+ * - `'adaptive'`: the bottom sheet on compact coarse-pointer screens,
436
+ * otherwise the popover — the same resolution Selector uses. The server
437
+ * render and the hydrating render are the popover.
438
+ *
439
+ * In the sheet presentation `menuWidth` and `tokenOverflowBehavior` have
440
+ * no surface to act on and warn in development. Pass `'popover'` to keep
441
+ * the tokenizer field and the editor popover on every device.
442
+ * @default 'adaptive'
443
+ */
444
+ presentation?: PowerSearchPresentation;
391
445
  }
392
446
 
447
+ /** How PowerSearch presents filter editing; see `PowerSearchProps.presentation`. */
448
+ export type PowerSearchPresentation = AdaptivePresentation;
449
+
393
450
  // =============================================================================
394
451
  // State
395
452
  // =============================================================================
@@ -524,6 +581,7 @@ export function PowerSearch({
524
581
  className,
525
582
  style,
526
583
  components: componentOverrides,
584
+ presentation = 'adaptive',
527
585
  }: PowerSearchProps) {
528
586
  const size = useSize(sizeProp, 'md');
529
587
  const config = useInternalConfig(configProp);
@@ -537,6 +595,100 @@ export function PowerSearch({
537
595
  popoverSaveButtonLabelFromProps ?? t('@astryx.powersearch.editor.apply');
538
596
  const tokenizerRef = useRef<TokenizerHandle>(null);
539
597
 
598
+ const resolvedPresentation = useAdaptivePresentation(presentation);
599
+ const [isSheetOpen, setIsSheetOpen] = useState(false);
600
+ // Latched for the flow's lifetime: the flow stays presented after it closes
601
+ // until the sheets have run their exit and handed focus back to the trigger.
602
+ // Without the latch, `adaptive` resolving to `popover` mid-session (a phone
603
+ // turned to landscape) would unmount the sheets and the trigger they return
604
+ // focus to in the same render, dropping focus to the page body.
605
+ const [isSheetPresented, setIsSheetPresented] = useState(false);
606
+ const isSheetPresentation =
607
+ isSheetOpen || isSheetPresented || resolvedPresentation === 'bottom-sheet';
608
+ const triggerRef = useRef<HTMLButtonElement>(null);
609
+ // `hasAutoFocus` applies only to the control the field first mounts. A
610
+ // presentation swap remounts the control (combobox input or trigger), and
611
+ // React's `autoFocus` on the new one would pull focus from wherever on the
612
+ // page it was; the roots' callback refs hand over the focus the field held
613
+ // instead. A field that never swaps keeps `autoFocus` on every render, so a
614
+ // Dialog that keeps it mounted still finds its `data-autofocus` on open.
615
+ const [autoFocusState, setAutoFocusState] = useState({
616
+ presentation: isSheetPresentation,
617
+ isFirstControl: true,
618
+ });
619
+ if (autoFocusState.presentation !== isSheetPresentation) {
620
+ setAutoFocusState({
621
+ presentation: isSheetPresentation,
622
+ isFirstControl: false,
623
+ });
624
+ }
625
+ const autoFocusOnMount =
626
+ hasAutoFocus &&
627
+ autoFocusState.isFirstControl &&
628
+ autoFocusState.presentation === isSheetPresentation;
629
+ // A focus the swap moves continues the same visit to the field: the
630
+ // control that held focus is gone (no blur fires for a removed element), so
631
+ // the caller is told of neither a blur nor a new focus.
632
+ const isSwapFocusRef = useRef(false);
633
+ const focusAfterSwap = useCallback((control: {focus(): void} | null) => {
634
+ if (control == null) {
635
+ return;
636
+ }
637
+ isSwapFocusRef.current = true;
638
+ try {
639
+ control.focus();
640
+ } finally {
641
+ isSwapFocusRef.current = false;
642
+ }
643
+ }, []);
644
+ const handleFieldFocus = useCallback(
645
+ (event: React.FocusEvent) => {
646
+ if (!isSwapFocusRef.current) {
647
+ onFocus?.(event);
648
+ }
649
+ },
650
+ [onFocus],
651
+ );
652
+ const handleFieldBlur = useCallback(
653
+ (event: React.FocusEvent) => {
654
+ onBlur?.(event);
655
+ },
656
+ [onBlur],
657
+ );
658
+ // While the flow is open, the sheet announces its own content from inside
659
+ // its dialog; this component announces only with the flow closed, and
660
+ // `useAnnounce` routes those messages by where the field is — into a Dialog
661
+ // or modal Drawer that holds it, or the shared channel when no modal does.
662
+ // A result count that changed during the flow's exit is spoken once the
663
+ // flow has fully closed and focus is back on the trigger: the closing
664
+ // dialog stays modal through its exit, so neither its region nor the
665
+ // page-body channel is heard before.
666
+ const afterCloseResultCountRef = useRef<string | null>(null);
667
+ const triggerId = useId();
668
+ const triggerLabelId = useId();
669
+ const triggerContentId = useId();
670
+ const statusMessageId = useId();
671
+ // A field that becomes disabled cannot keep its flow open, and must not
672
+ // reopen it when re-enabled. Adjusted in the
673
+ // render that sees the change, not an effect, so no frame shows both.
674
+ const [wasDisabled, setWasDisabled] = useState(isDisabled);
675
+ if (isDisabled !== wasDisabled) {
676
+ setWasDisabled(isDisabled);
677
+ if (isDisabled && isSheetOpen) {
678
+ setIsSheetOpen(false);
679
+ }
680
+ }
681
+ useDevWarning(
682
+ 'PowerSearch',
683
+ '`menuWidth` has no surface in the bottom-sheet presentation: the sheet flow has no typeahead popover to size. Pass `presentation="popover"` to keep the popover on every device, or leave it out.',
684
+ isSheetPresentation && menuWidth != null,
685
+ );
686
+ useDevWarning(
687
+ 'PowerSearch',
688
+ '`tokenOverflowBehavior` has no surface in the bottom-sheet presentation: the trigger wraps its display-only tokens. Pass `presentation="popover"` to keep the tokenizer field on every device, or leave it out.',
689
+ isSheetPresentation && tokenOverflowBehavior != null,
690
+ );
691
+
540
692
  const [popoverState, setPopoverStateRaw] = useState<PopoverState>({
541
693
  type: 'idle',
542
694
  });
@@ -552,7 +704,7 @@ export function PowerSearch({
552
704
  const operatorLabel = operator ? resolveOperatorLabel(operator, t) : '';
553
705
  const label = `${fieldLabel}: ${operatorLabel}`.trim();
554
706
  const value = operator
555
- ? tokenValueText(
707
+ ? formatTokenValueText(
556
708
  operator.value,
557
709
  filter.value,
558
710
  Math.max(
@@ -560,11 +712,14 @@ export function PowerSearch({
560
712
  10,
561
713
  ),
562
714
  locale,
715
+ undefined,
716
+ undefined,
717
+ timezoneID,
563
718
  )
564
719
  : null;
565
720
  return {label, value, full: value != null ? `${label} ${value}` : label};
566
721
  },
567
- [config, maxTokenLength, t, locale],
722
+ [config, maxTokenLength, t, locale, timezoneID],
568
723
  );
569
724
  // The built-in token being edited. A token from a `components` override
570
725
  // names itself, so its editor keeps the plain popover.
@@ -581,9 +736,21 @@ export function PowerSearch({
581
736
  componentOverrides?.[editedOperator.value.type]?.Token == null
582
737
  ? editedFilter
583
738
  : undefined;
739
+ // Whether the editor popover is open, for the hand-off below, which runs
740
+ // in the commit that swaps presentations.
741
+ const isPopoverOpenRef = useRef(false);
742
+ // When `adaptive` flips to the sheet while the editor popover is open (a
743
+ // phone rotated), the editing ends with the popover: its state returns to
744
+ // idle (through the raw setter, since the tokenizer input is gone), in the
745
+ // render that sees the swap, so a later switch back does not reopen a stale
746
+ // editor.
747
+ if (isSheetPresentation && popoverState.type !== 'idle') {
748
+ setPopoverStateRaw({type: 'idle'});
749
+ }
584
750
 
585
751
  // Layer for positioning the edit popover anchored to the tokenizer
586
752
  const handleLayerHide = useCallback(() => {
753
+ isPopoverOpenRef.current = false;
587
754
  setPopoverStateRaw({type: 'idle'});
588
755
  }, []);
589
756
 
@@ -604,9 +771,54 @@ export function PowerSearch({
604
771
  : undefined,
605
772
  });
606
773
 
774
+ // A presentation swap removes the focused control, so the other
775
+ // presentation's primary control (the combobox input or the trigger) takes
776
+ // focus and focus never falls to the page body. Each presentation keys its
777
+ // root, so a swap mounts a new root. The detaching root notes that it held
778
+ // focus, which also covers an input focused by server-rendered `autofocus`
779
+ // before hydration. The editor popover is portaled outside the root, so an
780
+ // open editor counts as held focus. The attaching root gives focus to its
781
+ // primary control when focus has fallen to the page body; the sheet root
782
+ // also hides a popover layer left open.
783
+ const isFocusPendingHandOffRef = useRef(false);
784
+ const hidePopover = popover.hide;
785
+ const handOffFocusRef = useCallback(
786
+ (node: HTMLDivElement | null) => {
787
+ if (node == null) {
788
+ return;
789
+ }
790
+ const trigger = triggerRef.current;
791
+ const isSheetRoot = trigger != null && node.contains(trigger);
792
+ // The sheet presentation preloads the flow's chunk, so the first press
793
+ // opens without waiting for the network; nothing renders.
794
+ if (isSheetRoot) {
795
+ void loadPowerSearchBottomSheet();
796
+ }
797
+ if (isSheetRoot && isPopoverOpenRef.current) {
798
+ isPopoverOpenRef.current = false;
799
+ hidePopover();
800
+ }
801
+ const takesFocus = isFocusPendingHandOffRef.current;
802
+ isFocusPendingHandOffRef.current = false;
803
+ if (takesFocus && isFocusDetached(node.ownerDocument)) {
804
+ focusAfterSwap(isSheetRoot ? trigger : tokenizerRef.current);
805
+ }
806
+ return () => {
807
+ if (
808
+ node.contains(node.ownerDocument.activeElement) ||
809
+ isPopoverOpenRef.current
810
+ ) {
811
+ isFocusPendingHandOffRef.current = true;
812
+ }
813
+ };
814
+ },
815
+ [focusAfterSwap, hidePopover],
816
+ );
817
+
607
818
  // Wrapper that manages layer visibility and tokenizer focus alongside state
608
819
  const setPopoverState = useCallback(
609
820
  (state: PopoverState) => {
821
+ isPopoverOpenRef.current = state.type !== 'idle';
610
822
  setPopoverStateRaw(state);
611
823
  if (state.type !== 'idle') {
612
824
  // Schedule after the current frame so React can render the popover
@@ -623,13 +835,22 @@ export function PowerSearch({
623
835
  [popover],
624
836
  );
625
837
 
626
- // Expose imperative handle
838
+ // Expose imperative handle; in the sheet presentation the trigger is the
839
+ // field's focusable control.
627
840
  useImperativeHandle(handleRef, () => ({
628
841
  focusTypeahead() {
629
- tokenizerRef.current?.focus();
842
+ if (isSheetPresentation) {
843
+ triggerRef.current?.focus();
844
+ } else {
845
+ tokenizerRef.current?.focus();
846
+ }
630
847
  },
631
848
  blurTypeahead() {
632
- tokenizerRef.current?.blur();
849
+ if (isSheetPresentation) {
850
+ triggerRef.current?.blur();
851
+ } else {
852
+ tokenizerRef.current?.blur();
853
+ }
633
854
  },
634
855
  }));
635
856
 
@@ -833,10 +1054,12 @@ export function PowerSearch({
833
1054
  setPopoverState({type: 'idle'});
834
1055
  }, [setPopoverState]);
835
1056
 
836
- // Custom token renderer
837
- // Custom token renderer
838
- const renderToken = useCallback(
839
- (item: PowerSearchItem, onRemove: () => void) => {
1057
+ // Token renderer for both presentations. Given `onRemove`, the token is
1058
+ // the tokenizer field's: click edits, × removes. Without it (the sheet
1059
+ // presentation's trigger) the token is display-only; the field as a whole
1060
+ // opens the flow.
1061
+ const renderFilterToken = useCallback(
1062
+ (item: PowerSearchItem, onRemove: (() => void) | undefined) => {
840
1063
  const auxData = item.auxiliaryData;
841
1064
  const filterIndex = auxData?.filterIndex ?? -1;
842
1065
  const filter = filterIndex >= 0 ? filters[filterIndex] : undefined;
@@ -846,7 +1069,8 @@ export function PowerSearch({
846
1069
  ? config.getOperator(auxData.fieldKey, auxData.operatorKey)
847
1070
  : undefined;
848
1071
 
849
- const canInteract = !isReadOnly && !isDisabled && !filter?.isReadOnly;
1072
+ const canInteract =
1073
+ onRemove != null && !isReadOnly && !isDisabled && !filter?.isReadOnly;
850
1074
  const handleClick = canInteract
851
1075
  ? () => handleTokenClick(filterIndex)
852
1076
  : undefined;
@@ -868,6 +1092,7 @@ export function PowerSearch({
868
1092
  onClick={handleClick}
869
1093
  onRemove={handleRemove}
870
1094
  isDisabled={isDisabled}
1095
+ timezoneID={timezoneID}
871
1096
  />
872
1097
  );
873
1098
  }
@@ -944,6 +1169,7 @@ export function PowerSearch({
944
1169
  );
945
1170
  },
946
1171
  [
1172
+ timezoneID,
947
1173
  filters,
948
1174
  config,
949
1175
  configProp,
@@ -959,6 +1185,12 @@ export function PowerSearch({
959
1185
  ],
960
1186
  );
961
1187
 
1188
+ const renderToken = useCallback(
1189
+ (item: PowerSearchItem, onRemove: () => void) =>
1190
+ renderFilterToken(item, onRemove),
1191
+ [renderFilterToken],
1192
+ );
1193
+
962
1194
  // Custom typeahead item renderer — adds field icon and description
963
1195
  const renderItem = useCallback(
964
1196
  (item: PowerSearchItem) => {
@@ -1032,6 +1264,7 @@ export function PowerSearch({
1032
1264
  onCancel={handlePopoverCancel}
1033
1265
  saveButtonLabel={popoverSaveButtonLabel}
1034
1266
  isReadOnly={isReadOnly}
1267
+ timezoneID={timezoneID}
1035
1268
  />
1036
1269
  );
1037
1270
  }
@@ -1047,9 +1280,11 @@ export function PowerSearch({
1047
1280
  saveButtonLabel={popoverSaveButtonLabel}
1048
1281
  maxMenuItems={maxOperatorMenuItems}
1049
1282
  isReadOnly={isReadOnly}
1283
+ timezoneID={timezoneID}
1050
1284
  />
1051
1285
  );
1052
1286
  }, [
1287
+ timezoneID,
1053
1288
  popoverPartialFilter,
1054
1289
  popoverState,
1055
1290
  EditorOverride,
@@ -1076,13 +1311,18 @@ export function PowerSearch({
1076
1311
  return resultCount;
1077
1312
  }, [resultCount, t]);
1078
1313
 
1079
- // Announce result-count changes to screen readers through a polite live
1080
- // region, mirroring the way Typeahead announces its dropdown result count.
1081
- // The count is otherwise only shown visually and stays silent to assistive
1082
- // tech. Only a change after mount is spoken: the guard compares against the
1083
- // last announced text rather than a mounted flag, so StrictMode's effect
1084
- // replay (which resets a flag and would speak the count present on mount
1085
- // unprompted) announces nothing until the count changes.
1314
+ // This Effect synchronizes a polite live region with the result count,
1315
+ // mirroring the way Typeahead announces its dropdown result count: the count
1316
+ // is otherwise only shown visually and stays silent to assistive tech. The
1317
+ // region follows where the field is: the modal that holds the field (a
1318
+ // Dialog, a modal Drawer), else the shared channel. While a sheet of the flow is open the sheet itself announces the
1319
+ // count from inside its dialog, and this Effect stays quiet. Only a
1320
+ // change after mount is spoken — the count present on mount is not
1321
+ // announced unprompted — and the guard compares against the last announced
1322
+ // text rather than a mounted flag, so StrictMode's effect replay announces
1323
+ // nothing either. A change that lands while the flow is closing waits for
1324
+ // the trigger focus, since the dialog is still modal through its exit. The
1325
+ // announcement acquires no resource, so there is no cleanup.
1086
1326
  const announce = useAnnounce();
1087
1327
  // PowerSearch words its Clear all as its record does; the field announces
1088
1328
  // these words instead of Tokenizer's (component:Tokenizer AR7).
@@ -1095,15 +1335,20 @@ export function PowerSearch({
1095
1335
  [hasReadOnlyFilter, t],
1096
1336
  );
1097
1337
  const announcedResultCountRef = useRef(resultCountText);
1338
+ const isSheetExiting = isSheetPresented && !isSheetOpen;
1098
1339
  useEffect(() => {
1099
1340
  if (resultCountText === announcedResultCountRef.current) {
1100
1341
  return;
1101
1342
  }
1102
1343
  announcedResultCountRef.current = resultCountText;
1103
1344
  if (resultCountText != null) {
1104
- announce(resultCountText);
1345
+ if (isSheetExiting) {
1346
+ afterCloseResultCountRef.current = resultCountText;
1347
+ } else if (!isSheetOpen) {
1348
+ announce(resultCountText);
1349
+ }
1105
1350
  }
1106
- }, [resultCountText, announce]);
1351
+ }, [resultCountText, announce, isSheetExiting, isSheetOpen]);
1107
1352
 
1108
1353
  // Build combined endContent from resultCount + endContent props
1109
1354
  const combinedEndContent = useMemo((): React.ReactNode => {
@@ -1124,14 +1369,231 @@ export function PowerSearch({
1124
1369
  return resultCountNode || endContent || undefined;
1125
1370
  }, [resultCountText, endContent]);
1126
1371
 
1372
+ // ------------------------------------------------------- sheet trigger --
1373
+
1374
+ // Disabled-reason tooltip for the sheet trigger. Disabled controls swallow
1375
+ // pointer events, so the listeners attach to the field's control box; the
1376
+ // trigger stays perceivable through aria-disabled.
1377
+ const showsDisabledMessage = isDisabled && !!disabledMessage;
1378
+ const disabledMessageTooltip = useTooltip({
1379
+ placement: 'above',
1380
+ focusTrigger: 'always',
1381
+ isEnabled: isSheetPresentation && showsDisabledMessage,
1382
+ });
1383
+ const rootRef = useMergedRefs(
1384
+ ref,
1385
+ popover.triggerRef as React.Ref<HTMLDivElement>,
1386
+ handOffFocusRef,
1387
+ );
1388
+
1389
+ const openSheet = useCallback(() => {
1390
+ if (isDisabled) {
1391
+ return;
1392
+ }
1393
+ // The flow restores focus to the element that was active when it opened;
1394
+ // make sure that is the trigger even for a tap on a token.
1395
+ triggerRef.current?.focus({preventScroll: true});
1396
+ setIsSheetPresented(true);
1397
+ setIsSheetOpen(true);
1398
+ }, [isDisabled]);
1399
+
1400
+ // The field's end lane — the result count and `endContent` — sits outside
1401
+ // the trigger button: a caller's action button there keeps its own tab stop
1402
+ // and taps, and an interactive control must not nest in a component
1403
+ // button, so a tap on it must not open the flow.
1404
+ const endLaneRef = useRef<HTMLDivElement>(null);
1405
+ const handleTriggerWrapperClick = useCallback(
1406
+ (event: React.MouseEvent<HTMLDivElement>) => {
1407
+ // Tokens are display-only; a tap on them or the empty space around them
1408
+ // opens the flow. The trigger button handles its own click, and the end
1409
+ // lane handles its own.
1410
+ if (
1411
+ event.target instanceof Node &&
1412
+ (triggerRef.current?.contains(event.target) ||
1413
+ endLaneRef.current?.contains(event.target))
1414
+ ) {
1415
+ return;
1416
+ }
1417
+ openSheet();
1418
+ },
1419
+ [openSheet],
1420
+ );
1421
+
1422
+ const handleTriggerFocusWithin = useCallback(
1423
+ (event: React.FocusEvent<HTMLDivElement>) => {
1424
+ // The flow focuses the trigger only after its exit completes; that focus
1425
+ // is the signal that the retained sheets can leave. If the resolution
1426
+ // moved to the popover meanwhile, the tokenizer input takes over the
1427
+ // focus once it mounts (the hand-off above).
1428
+ if (!isSheetOpen && isSheetPresented) {
1429
+ setIsSheetPresented(false);
1430
+ // The dialogs have closed: the page-body channel is exposed again.
1431
+ const resultCount = afterCloseResultCountRef.current;
1432
+ afterCloseResultCountRef.current = null;
1433
+ if (resultCount != null) {
1434
+ announce(resultCount);
1435
+ }
1436
+ }
1437
+ if (
1438
+ !(event.relatedTarget instanceof Node) ||
1439
+ !event.currentTarget.contains(event.relatedTarget)
1440
+ ) {
1441
+ handleFieldFocus(event);
1442
+ }
1443
+ },
1444
+ [announce, handleFieldFocus, isSheetOpen, isSheetPresented],
1445
+ );
1446
+ const handleTriggerBlurWithin = useCallback(
1447
+ (event: React.FocusEvent<HTMLDivElement>) => {
1448
+ if (
1449
+ !(event.relatedTarget instanceof Node) ||
1450
+ !event.currentTarget.contains(event.relatedTarget)
1451
+ ) {
1452
+ handleFieldBlur(event);
1453
+ }
1454
+ },
1455
+ [handleFieldBlur],
1456
+ );
1457
+
1458
+ if (isSheetPresentation) {
1459
+ const triggerDescribedBy =
1460
+ [
1461
+ status?.message ? statusMessageId : null,
1462
+ showsDisabledMessage ? disabledMessageTooltip.describedBy : null,
1463
+ ]
1464
+ .filter(Boolean)
1465
+ .join(' ') || undefined;
1466
+
1467
+ return (
1468
+ <div key="sheet" ref={rootRef} {...themeProps('power-search')}>
1469
+ <Field
1470
+ label={label}
1471
+ isLabelHidden={isLabelHidden}
1472
+ inputID={triggerId}
1473
+ labelID={triggerLabelId}
1474
+ isDisabled={isDisabled}
1475
+ status={
1476
+ status
1477
+ ? {
1478
+ type: status.type,
1479
+ message: status.message,
1480
+ messageID: status.message ? statusMessageId : undefined,
1481
+ }
1482
+ : undefined
1483
+ }
1484
+ statusVariant={statusVariant}
1485
+ xstyle={xstyle}
1486
+ className={className}
1487
+ style={style}>
1488
+ <div
1489
+ ref={disabledMessageTooltip.ref}
1490
+ onClick={handleTriggerWrapperClick}
1491
+ onFocus={handleTriggerFocusWithin}
1492
+ onBlur={handleTriggerBlurWithin}
1493
+ aria-disabled={isDisabled ? true : undefined}
1494
+ {...stylex.props(
1495
+ inputWrapperStyles.base,
1496
+ sheetTriggerStyles.wrapper,
1497
+ filters.length > 0 && sheetTriggerStyles.wrapperWithTokens,
1498
+ sheetTriggerSizeStyles[size],
1499
+ isDisabled && inputWrapperStyles.disabled,
1500
+ status && inputStatusBorderStyles[status.type],
1501
+ status &&
1502
+ !isDisabled &&
1503
+ inputStatusHoverShadowStyles[status.type],
1504
+ status && inputStatusFocusWithinStyles[status.type],
1505
+ )}>
1506
+ {/* The trigger's name is the label plus everything visible here:
1507
+ the placeholder, or the tokens, so speech input can say what
1508
+ it sees and assistive technology hears the selected filters
1509
+ (WCAG 2.5.3). */}
1510
+ <div
1511
+ id={triggerContentId}
1512
+ {...stylex.props(sheetTriggerStyles.contentSection)}>
1513
+ {isRenderable(startIcon as React.ReactNode) && (
1514
+ <span
1515
+ {...stylex.props(
1516
+ filters.length > 0 &&
1517
+ sheetTriggerStyles.startIconWithTokens,
1518
+ )}>
1519
+ {renderIconSlot(startIcon, {size: 'sm', color: 'secondary'})}
1520
+ </span>
1521
+ )}
1522
+ {tokenizerValue.map(item => (
1523
+ <React.Fragment key={item.id}>
1524
+ {renderFilterToken(item, undefined)}
1525
+ </React.Fragment>
1526
+ ))}
1527
+ <button
1528
+ type="button"
1529
+ id={triggerId}
1530
+ ref={triggerRef}
1531
+ // The field's primary control: `data-testid` lands here, as it
1532
+ // lands on the combobox input in the popover presentation.
1533
+ data-testid={testId}
1534
+ autoFocus={autoFocusOnMount}
1535
+ onClick={openSheet}
1536
+ aria-disabled={isDisabled ? true : undefined}
1537
+ aria-haspopup="dialog"
1538
+ aria-expanded={isSheetOpen}
1539
+ aria-labelledby={`${triggerLabelId} ${triggerContentId}`}
1540
+ aria-describedby={triggerDescribedBy}
1541
+ {...stylex.props(
1542
+ sheetTriggerStyles.trigger,
1543
+ filters.length > 0 && sheetTriggerStyles.triggerWithTokens,
1544
+ )}>
1545
+ {filters.length === 0 ? placeholder : null}
1546
+ </button>
1547
+ </div>
1548
+ {(endContent || isRenderable(resultCountText)) && (
1549
+ <div
1550
+ ref={endLaneRef}
1551
+ {...stylex.props(sheetTriggerStyles.endSection)}>
1552
+ {isRenderable(resultCountText) && (
1553
+ <span {...stylex.props(resultCountStyles.text)}>
1554
+ {resultCountText}
1555
+ </span>
1556
+ )}
1557
+ {endContent}
1558
+ </div>
1559
+ )}
1560
+ </div>
1561
+ {showsDisabledMessage &&
1562
+ disabledMessageTooltip.renderTooltip(disabledMessage)}
1563
+ </Field>
1564
+ {/* Mounted from the press until the flow's exit has completed and
1565
+ focus is back on the trigger (`isSheetPresented`): at rest the
1566
+ field renders its trigger alone — no closed dialogs, rows, search
1567
+ field or editors in the DOM. */}
1568
+ {(isSheetOpen || isSheetPresented) && (
1569
+ <PowerSearchSheetHost
1570
+ isOpen={isSheetOpen}
1571
+ onOpenChange={setIsSheetOpen}
1572
+ finalFocusRef={triggerRef}
1573
+ resultCountText={resultCountText}
1574
+ config={config}
1575
+ configProp={configProp}
1576
+ filters={filters}
1577
+ onChange={onChange}
1578
+ searchSource={searchSource}
1579
+ placeholder={placeholder}
1580
+ isReadOnly={isReadOnly}
1581
+ isDisabled={isDisabled}
1582
+ hasClear={hasClear}
1583
+ maxOperatorMenuItems={maxOperatorMenuItems}
1584
+ timezoneID={timezoneID}
1585
+ maxSearchResults={maxSearchResults}
1586
+ saveButtonLabel={popoverSaveButtonLabelFromProps}
1587
+ components={componentOverrides}
1588
+ />
1589
+ )}
1590
+ </div>
1591
+ );
1592
+ }
1593
+
1127
1594
  return (
1128
1595
  <>
1129
- <div
1130
- ref={useMergedRefs(
1131
- ref,
1132
- popover.triggerRef as React.Ref<HTMLDivElement>,
1133
- )}
1134
- {...themeProps('power-search')}>
1596
+ <div key="popover" ref={rootRef} {...themeProps('power-search')}>
1135
1597
  {/* The field's Clear all announces PowerSearch's own words
1136
1598
  (component:PowerSearch; component:Tokenizer AR7). */}
1137
1599
  <TokenizerClearAllMessageContext value={clearAllMessage}>
@@ -1148,7 +1610,7 @@ export function PowerSearch({
1148
1610
  maxMenuItems={MAX_BROWSE_MENU_ITEMS}
1149
1611
  menuWidth={menuWidth}
1150
1612
  placeholder={filters.length === 0 ? placeholder : ''}
1151
- hasAutoFocus={hasAutoFocus}
1613
+ hasAutoFocus={autoFocusOnMount}
1152
1614
  hasClear={hasClear && !isReadOnly}
1153
1615
  startIcon={startIcon}
1154
1616
  endContent={combinedEndContent}
@@ -1160,12 +1622,13 @@ export function PowerSearch({
1160
1622
  debounceMs={0}
1161
1623
  status={status}
1162
1624
  statusVariant={statusVariant}
1163
- onFocus={onFocus}
1164
- onBlur={onBlur}
1625
+ onFocus={handleFieldFocus}
1626
+ onBlur={handleFieldBlur}
1165
1627
  containerXstyle={xstyle}
1166
1628
  containerClassName={className}
1167
1629
  containerStyle={style}
1168
1630
  data-testid={testId}
1631
+ presentation="popover"
1169
1632
  />
1170
1633
  </TokenizerItemRemovableContext>
1171
1634
  </TokenizerClearAllMessageContext>