@astryxdesign/core 0.7.7-canary.fc68123 → 0.7.7

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 (240) hide show
  1. package/CHANGELOG.md +104 -0
  2. package/dist/AlertDialog/AlertDialog.d.ts +1 -4
  3. package/dist/AlertDialog/AlertDialog.d.ts.map +1 -1
  4. package/dist/AlertDialog/AlertDialog.js +6 -36
  5. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  6. package/dist/BottomSheet/BottomSheetPanel.js +4 -23
  7. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  8. package/dist/BottomSheet/useSheetGestures.js +1 -3
  9. package/dist/Button/Button.d.ts.map +1 -1
  10. package/dist/Button/Button.js +1 -17
  11. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  12. package/dist/CheckboxInput/CheckboxInput.js +2 -13
  13. package/dist/ComplexSelector/ComplexSelector.d.ts +1 -4
  14. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  15. package/dist/ComplexSelector/ComplexSelector.js +4 -14
  16. package/dist/ContextMenu/ContextMenu.js +2 -2
  17. package/dist/Dialog/Dialog.d.ts.map +1 -1
  18. package/dist/Dialog/Dialog.js +31 -7
  19. package/dist/Field/Field.js +2 -2
  20. package/dist/HoverCard/HoverCard.d.ts +3 -4
  21. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  22. package/dist/HoverCard/HoverCard.js +2 -27
  23. package/dist/HoverCard/useHoverCard.d.ts +4 -5
  24. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  25. package/dist/HoverCard/useHoverCard.js +31 -17
  26. package/dist/Icon/Icon.d.ts +1 -5
  27. package/dist/Icon/Icon.d.ts.map +1 -1
  28. package/dist/Icon/Icon.js +2 -5
  29. package/dist/Layer/usePressPin.d.ts +5 -17
  30. package/dist/Layer/usePressPin.d.ts.map +1 -1
  31. package/dist/Layer/usePressPin.js +12 -62
  32. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  33. package/dist/Lightbox/Lightbox.js +0 -18
  34. package/dist/PowerSearch/PowerSearch.d.ts +3 -36
  35. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  36. package/dist/PowerSearch/PowerSearch.js +127 -433
  37. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +1 -32
  38. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  39. package/dist/PowerSearch/PowerSearchEditPopover.js +6 -17
  40. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +3 -38
  41. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  42. package/dist/PowerSearch/PowerSearchValueEditor.js +61 -170
  43. package/dist/PowerSearch/formatFilterValue.d.ts +0 -7
  44. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  45. package/dist/PowerSearch/formatFilterValue.js +1 -11
  46. package/dist/RadioList/RadioList.d.ts.map +1 -1
  47. package/dist/RadioList/RadioList.js +2 -3
  48. package/dist/RadioList/RadioListItem.d.ts +1 -1
  49. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  50. package/dist/RadioList/RadioListItem.js +3 -5
  51. package/dist/Resizable/ResizeHandle.d.ts +1 -2
  52. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  53. package/dist/Resizable/ResizeHandle.js +77 -99
  54. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -1
  55. package/dist/SegmentedControl/useSegmentedSelectionMotion.js +3 -3
  56. package/dist/Slider/sliderTouchController.js +2 -2
  57. package/dist/Spinner/Spinner.d.ts +1 -1
  58. package/dist/Spinner/Spinner.d.ts.map +1 -1
  59. package/dist/Spinner/Spinner.js +58 -60
  60. package/dist/Switch/useSwitchTouch.js +4 -4
  61. package/dist/Table/BaseTable.d.ts.map +1 -1
  62. package/dist/Table/BaseTable.js +8 -29
  63. package/dist/TextInput/TextInput.d.ts +2 -2
  64. package/dist/TextInput/TextInput.d.ts.map +1 -1
  65. package/dist/TextInput/TextInput.js +7 -10
  66. package/dist/Toast/Toast.d.ts +1 -11
  67. package/dist/Toast/Toast.d.ts.map +1 -1
  68. package/dist/Toast/Toast.js +15 -25
  69. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  70. package/dist/Toast/ToastViewport.js +34 -94
  71. package/dist/Toast/types.d.ts +3 -9
  72. package/dist/Toast/types.d.ts.map +1 -1
  73. package/dist/Tooltip/useTooltip.d.ts +1 -19
  74. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  75. package/dist/Tooltip/useTooltip.js +53 -34
  76. package/dist/Typeahead/TypeaheadItem.d.ts +1 -2
  77. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  78. package/dist/astryx.css +6 -35
  79. package/dist/gestures/PressTracker.d.ts.map +1 -1
  80. package/dist/gestures/PressTracker.js +3 -4
  81. package/dist/hooks/actionGroupTracker.d.ts +1 -4
  82. package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
  83. package/dist/hooks/actionGroupTracker.js +3 -13
  84. package/dist/hooks/index.d.ts +0 -1
  85. package/dist/hooks/index.d.ts.map +1 -1
  86. package/dist/hooks/index.js +0 -1
  87. package/dist/hooks/useAttachment.d.ts +1 -1
  88. package/dist/hooks/useAttachment.js +1 -1
  89. package/dist/hooks/useInputStatusIcon.d.ts +1 -1
  90. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  91. package/dist/hooks/useInputStatusIcon.js +2 -2
  92. package/dist/hooks/useLongPress.d.ts +2 -6
  93. package/dist/hooks/useLongPress.d.ts.map +1 -1
  94. package/dist/hooks/useLongPress.js +15 -95
  95. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
  96. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +0 -6
  97. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  98. package/dist/i18n/generated-locales/en.generated.js +0 -30
  99. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  100. package/dist/i18n/generated-locales/pseudo.generated.js +0 -30
  101. package/dist/index.d.ts +0 -1
  102. package/dist/index.d.ts.map +1 -1
  103. package/dist/index.js +0 -4
  104. package/dist/motion/animatedLayout.d.ts.map +1 -1
  105. package/dist/motion/animatedLayout.js +6 -5
  106. package/dist/motion/animator.d.ts +14 -14
  107. package/dist/motion/animator.d.ts.map +1 -1
  108. package/dist/motion/animator.js +18 -41
  109. package/dist/utils/dateParser.d.ts.map +1 -1
  110. package/dist/utils/dateParser.js +0 -12
  111. package/dist/utils/focusReturn.d.ts +0 -15
  112. package/dist/utils/focusReturn.d.ts.map +1 -1
  113. package/dist/utils/focusReturn.js +0 -28
  114. package/dist/utils/interactionOverlay.stylex.d.ts +2 -3
  115. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  116. package/dist/utils/interactionOverlay.stylex.js +2 -3
  117. package/dist/utils/pressFeedback.d.ts.map +1 -1
  118. package/dist/utils/pressFeedback.js +6 -19
  119. package/locales/en.json +0 -120
  120. package/locales/pseudo.json +0 -90
  121. package/package.json +5 -10
  122. package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
  123. package/src/AlertDialog/AlertDialog.tsx +5 -37
  124. package/src/BottomSheet/BottomSheetPanel.tsx +3 -37
  125. package/src/BottomSheet/useSheetGestures.ts +1 -3
  126. package/src/Button/Button.tsx +4 -26
  127. package/src/CheckboxInput/CheckboxInput.doc.mjs +0 -18
  128. package/src/CheckboxInput/CheckboxInput.tsx +9 -36
  129. package/src/ComplexSelector/ComplexSelector.tsx +5 -20
  130. package/src/ContextMenu/ContextMenu.tsx +2 -2
  131. package/src/Dialog/Dialog.tsx +31 -10
  132. package/src/Field/Field.tsx +2 -2
  133. package/src/HoverCard/HoverCard.doc.mjs +2 -4
  134. package/src/HoverCard/HoverCard.tsx +4 -35
  135. package/src/HoverCard/useHoverCard.doc.mjs +36 -178
  136. package/src/HoverCard/useHoverCard.tsx +52 -46
  137. package/src/Icon/Icon.doc.mjs +8 -49
  138. package/src/Icon/Icon.tsx +7 -15
  139. package/src/Layer/usePressPin.ts +15 -81
  140. package/src/Lightbox/Lightbox.tsx +0 -18
  141. package/src/PowerSearch/PowerSearch.doc.mjs +5 -54
  142. package/src/PowerSearch/PowerSearch.tsx +155 -609
  143. package/src/PowerSearch/PowerSearchEditPopover.tsx +6 -28
  144. package/src/PowerSearch/PowerSearchValueEditor.tsx +38 -203
  145. package/src/PowerSearch/formatFilterValue.ts +1 -18
  146. package/src/RadioList/RadioList.tsx +2 -3
  147. package/src/RadioList/RadioListItem.tsx +3 -5
  148. package/src/Resizable/Resizable.doc.mjs +4 -5
  149. package/src/Resizable/ResizeHandle.tsx +109 -167
  150. package/src/SegmentedControl/useSegmentedSelectionMotion.ts +3 -6
  151. package/src/Slider/sliderTouchController.ts +2 -2
  152. package/src/Spinner/Spinner.tsx +63 -77
  153. package/src/Switch/useSwitchTouch.ts +4 -4
  154. package/src/Table/BaseTable.tsx +12 -46
  155. package/src/TextInput/TextInput.tsx +10 -11
  156. package/src/Toast/Toast.doc.mjs +3 -4
  157. package/src/Toast/Toast.tsx +32 -52
  158. package/src/Toast/ToastViewport.tsx +35 -121
  159. package/src/Toast/types.ts +3 -9
  160. package/src/Tooltip/useTooltip.doc.mjs +0 -24
  161. package/src/Tooltip/useTooltip.tsx +56 -61
  162. package/src/Typeahead/TypeaheadItem.doc.mjs +3 -6
  163. package/src/Typeahead/TypeaheadItem.tsx +1 -2
  164. package/src/gestures/PressTracker.ts +3 -4
  165. package/src/gestures/README.md +1 -7
  166. package/src/hooks/actionGroupTracker.ts +5 -20
  167. package/src/hooks/index.ts +0 -2
  168. package/src/hooks/useAttachment.ts +1 -1
  169. package/src/hooks/useInputStatusIcon.tsx +2 -3
  170. package/src/hooks/useLongPress.doc.mjs +2 -2
  171. package/src/hooks/useLongPress.ts +15 -136
  172. package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +0 -6
  173. package/src/i18n/generated-locales/en.generated.ts +0 -41
  174. package/src/i18n/generated-locales/pseudo.generated.ts +0 -42
  175. package/src/index.ts +0 -13
  176. package/src/motion/README.md +5 -9
  177. package/src/motion/animatedLayout.ts +4 -5
  178. package/src/motion/animator.ts +29 -61
  179. package/src/utils/dateParser.ts +0 -16
  180. package/src/utils/focusReturn.ts +0 -30
  181. package/src/utils/interactionOverlay.stylex.ts +2 -3
  182. package/src/utils/pressFeedback.ts +6 -19
  183. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +0 -100
  184. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +0 -1
  185. package/dist/PowerSearch/PowerSearchBottomSheet.js +0 -1913
  186. package/dist/PowerSearch/formatTokenValue.d.ts +0 -28
  187. package/dist/PowerSearch/formatTokenValue.d.ts.map +0 -1
  188. package/dist/PowerSearch/formatTokenValue.js +0 -160
  189. package/dist/PowerSearch/powerSearchSheetUtils.d.ts +0 -65
  190. package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +0 -1
  191. package/dist/PowerSearch/powerSearchSheetUtils.js +0 -168
  192. package/dist/animator/createAnimator.d.ts +0 -98
  193. package/dist/animator/createAnimator.d.ts.map +0 -1
  194. package/dist/animator/createAnimator.js +0 -259
  195. package/dist/hooks/pressGroupContext.d.ts +0 -6
  196. package/dist/hooks/pressGroupContext.d.ts.map +0 -1
  197. package/dist/hooks/pressGroupContext.js +0 -20
  198. package/dist/hooks/useActionGroupTracking.d.ts +0 -53
  199. package/dist/hooks/useActionGroupTracking.d.ts.map +0 -1
  200. package/dist/hooks/useActionGroupTracking.js +0 -174
  201. package/dist/hooks/useAnimator.d.ts +0 -41
  202. package/dist/hooks/useAnimator.d.ts.map +0 -1
  203. package/dist/hooks/useAnimator.js +0 -70
  204. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +0 -8
  205. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +0 -1
  206. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +0 -42
  207. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +0 -8
  208. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +0 -1
  209. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +0 -14
  210. package/dist/internal/indicatorPress.stylex.d.ts +0 -20
  211. package/dist/internal/indicatorPress.stylex.d.ts.map +0 -1
  212. package/dist/internal/indicatorPress.stylex.js +0 -26
  213. package/dist/motion/progress.d.ts +0 -88
  214. package/dist/motion/progress.d.ts.map +0 -1
  215. package/dist/motion/progress.js +0 -128
  216. package/dist/motion/uikit/alert.d.ts +0 -41
  217. package/dist/motion/uikit/alert.d.ts.map +0 -1
  218. package/dist/motion/uikit/alert.js +0 -43
  219. package/dist/privateAttributes/pressGroupItem.stylex.d.ts +0 -15
  220. package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +0 -1
  221. package/dist/privateAttributes/pressGroupItem.stylex.js +0 -23
  222. package/dist/utils/triggerFocus.d.ts +0 -36
  223. package/dist/utils/triggerFocus.d.ts.map +0 -1
  224. package/dist/utils/triggerFocus.js +0 -65
  225. package/src/PowerSearch/PowerSearchBottomSheet.tsx +0 -2515
  226. package/src/PowerSearch/formatTokenValue.ts +0 -215
  227. package/src/PowerSearch/powerSearchSheetUtils.ts +0 -224
  228. package/src/animator/createAnimator.doc.mjs +0 -153
  229. package/src/animator/createAnimator.ts +0 -324
  230. package/src/hooks/pressGroupContext.ts +0 -21
  231. package/src/hooks/useActionGroupTracking.ts +0 -224
  232. package/src/hooks/useAnimator.doc.mjs +0 -109
  233. package/src/hooks/useAnimator.ts +0 -67
  234. package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +0 -43
  235. package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +0 -15
  236. package/src/internal/indicatorPress.stylex.ts +0 -24
  237. package/src/motion/progress.ts +0 -155
  238. package/src/motion/uikit/alert.ts +0 -43
  239. package/src/privateAttributes/pressGroupItem.stylex.ts +0 -23
  240. package/src/utils/triggerFocus.ts +0 -80
@@ -4,19 +4,16 @@
4
4
 
5
5
  /**
6
6
  * @file PowerSearch.tsx
7
- * @input PowerSearchConfig, filters, onChange; Tokenizer, Field parts, Token,
8
- * useAdaptivePresentation, and PowerSearchBottomSheet (lazy)
7
+ * @input PowerSearchConfig, filters, onChange
9
8
  * @output Structured filter bar with token-based filter management
10
9
  * @position Main component; forwards DOM ref and exposes tokenizer control via
11
- * handleRef. The experimental `presentation` option swaps the tokenizer
12
- * field and editor popover for one trigger that opens PowerSearchBottomSheet.
10
+ * handleRef
13
11
  *
14
12
  * SYNC: When modified, update:
15
13
  * - /packages/core/src/PowerSearch/index.ts
16
- * - /packages/core/src/PowerSearch/PowerSearchBottomSheet.tsx (sheet presentation)
17
14
  * - /packages/cli/assets/templates/blocks/components/PowerSearch/ (showcase blocks)
18
15
  */
19
- import React, { lazy, Suspense, useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from 'react';
16
+ import React, { useCallback, useEffect, useImperativeHandle, useMemo, useRef, useState } from 'react';
20
17
  import * as stylex from '@stylexjs/stylex';
21
18
  import { Tokenizer } from "../Tokenizer/index.js";
22
19
  import { TokenizerClearAllMessageContext } from "../Tokenizer/TokenizerClearAllMessageContext.js";
@@ -26,31 +23,22 @@ import { Token } from "../Token/index.js";
26
23
  import { TokenNamingContext } from "../Token/TokenNamingContext.js";
27
24
  import { Avatar } from "../Avatar/index.js";
28
25
  import { layerAnimations } from "../Layer/layerAnimations.stylex.js";
29
- import { Icon, renderIconSlot } from "../Icon/index.js";
30
- import { Field } from "../Field/Field.js";
31
- import { inputStatusBorderStyles, inputStatusFocusWithinStyles, inputStatusHoverShadowStyles, inputWrapperStyles } from "../Field/inputStyles.stylex.js";
26
+ import { Icon } from "../Icon/index.js";
32
27
  import { usePopover } from "../Popover/usePopover.js";
33
- import { useTooltip } from "../Tooltip/useTooltip.js";
34
28
  import "../Layer/layerViewportInset.stylex.js";
35
29
  import { layerViewportInset } from "../Layer/layerViewportInset.stylex.js";
36
30
  import { useAnnounce } from "../hooks/useAnnounce.js";
37
- import { useAdaptivePresentation } from "../hooks/useAdaptivePresentation.js";
38
- import { useDevWarning } from "../hooks/useDevWarning.js";
39
- import { useIsHydrating } from "../hooks/useIsHydrating.js";
40
31
  import "../theme/tokens.stylex.js";
41
- import { spacingVars, colorVars, sizeVars, typeScaleVars, typographyVars, fontWeightVars } from "../theme/tokens.stylex.js";
32
+ import { spacingVars, colorVars, typeScaleVars, fontWeightVars } from "../theme/tokens.stylex.js";
42
33
  import { useSize } from "../SizeContext/SizeContext.js";
43
- import { isFocusDetached } from "../utils/focusReturn.js";
44
- import { isRenderable } from "../utils/isRenderable.js";
45
34
  import { useInternalConfig } from "./useInternalConfig.js";
46
35
  import { usePowerSearchSource } from "./usePowerSearchSource.js";
47
- import { formatFilterValue } from "./formatFilterValue.js";
48
- import { NestedEditor, PowerSearchEditPopover } from "./PowerSearchEditPopover.js";
49
- import { buildRelativeDateOptions, PowerSearchValueEditor } from "./PowerSearchValueEditor.js";
36
+ import { formatFilterValue, formatDateAbsoluteCompact } from "./formatFilterValue.js";
37
+ import { PowerSearchEditPopover } from "./PowerSearchEditPopover.js";
50
38
  import { resolveOperatorLabel } from "./resolveOperatorLabel.js";
51
39
  import { themeProps } from "../utils/themeProps.js";
40
+ import { truncateCharacters } from "../utils/characters.js";
52
41
  import { useLocale } from "../i18n/useLocale.js";
53
- import { formatTokenValueText } from "./formatTokenValue.js";
54
42
  import { useMergedRefs } from "../hooks/useMergedRefs.js";
55
43
  import { registerEnglishFallback, useComponentTranslator } from "../i18n/useComponentTranslator.js";
56
44
  import english from "../i18n/generated-english/PowerSearch/PowerSearch.generated.js";
@@ -95,76 +83,106 @@ const popoverLayerStyles = {
95
83
  $$css: true
96
84
  }
97
85
  };
98
- // The sheet presentation's trigger field: the same control box as the
99
- // tokenizer field, with display-only tokens and one button as its only tab
100
- // stop.
101
- const sheetTriggerSizeStyles = {
102
- sm: {
103
- kAzted: "x1gdqauq",
104
- $$css: true
105
- },
106
- md: {
107
- kAzted: "x1uogy3y",
108
- $$css: true
109
- },
110
- lg: {
111
- kAzted: "x1xf4nls",
112
- $$css: true
113
- }
114
- };
115
- const sheetTriggerStyles = {
116
- wrapper: {
117
- kVAEAm: "x1n2onr6",
118
- kwnvtZ: "xozqiw3",
119
- kOIVth: "xzye2dw",
120
- kZKoxP: "xt7dq6l",
121
- kkrTdU: "x1ypdohk xvivl9a",
122
- $$css: true
123
- },
124
- wrapperWithTokens: {
125
- k8WAf4: "x1x7cmac",
126
- kg3NbH: "xx2oswg",
127
- $$css: true
128
- }
129
- };
130
-
131
- // The sheet flow (three standalone sheets, the sheet editors) only
132
- // renders for the bottom-sheet presentation. Loading it on demand keeps it out
133
- // of pages whose PowerSearch stays a tokenizer field.
134
- // One import promise, shared by the preload and the lazy element: the sheet
135
- // presentation loads the flow's chunk as soon as it is active, so the first
136
- // press does not wait for the network, while nothing of the flow is rendered
137
- // until a press.
138
- const loadPowerSearchBottomSheet = async () => import("./PowerSearchBottomSheet.js");
139
- const LazyPowerSearchBottomSheet = /*#__PURE__*/lazy(async () => loadPowerSearchBottomSheet().then(module => ({
140
- default: module.PowerSearchBottomSheet
141
- })));
142
- // The value step reuses the popover presentation's editors, which this
143
- // module already loads; see PowerSearchSheetEditors.
144
- const SHEET_EDITORS = {
145
- NestedEditor,
146
- PowerSearchValueEditor,
147
- buildRelativeDateOptions
148
- };
86
+ function truncateString(value, limit) {
87
+ // Same semantics as before — strings within limit + 3 pass through, longer
88
+ // ones cut to limit + '...' — but counted in characters, not code units.
89
+ return truncateCharacters(value, limit + 3, '...');
90
+ }
91
+ function getEnumLabel(values, value) {
92
+ return values.find(v => v.value === value)?.label ?? value;
93
+ }
149
94
 
150
95
  /**
151
- * Hosts the lazily loaded sheet flow. Renders nothing on the server or in the
152
- * render that hydrates server HTML: a lazy component that has not loaded yet
153
- * would leave server markup incomplete and abort hydration. The closed flow
154
- * has no visible markup, so it first renders right after hydration.
96
+ * The visible text of a filter token's value. The token renders it, and the
97
+ * token's remove button and editor dialog are named by the same text.
155
98
  */
156
- function PowerSearchSheetHost(props) {
157
- const isHydrating = useIsHydrating();
158
- if (isHydrating) {
159
- return null;
99
+ function tokenValueText(operatorValue, filterValue, maxLength, locale) {
100
+ switch (filterValue.type) {
101
+ case 'empty':
102
+ return null;
103
+ case 'string':
104
+ return truncateString(filterValue.value, maxLength);
105
+ case 'integer':
106
+ case 'float':
107
+ return String(filterValue.value);
108
+ case 'enum':
109
+ if (operatorValue.type === 'enum') {
110
+ return truncateString(getEnumLabel(operatorValue.values, filterValue.value), maxLength);
111
+ }
112
+ return truncateString(filterValue.value, maxLength);
113
+ case 'string_list':
114
+ {
115
+ const items = filterValue.value;
116
+ if (items.length === 0) {
117
+ return null;
118
+ }
119
+ if (items.length === 1) {
120
+ return truncateString(items[0], maxLength);
121
+ }
122
+ const totalLength = items.reduce((sum, s) => sum + s.length, 0);
123
+ if (totalLength > maxLength) {
124
+ return `${items.length} items`;
125
+ }
126
+ return items.join(', ');
127
+ }
128
+ case 'enum_list':
129
+ {
130
+ const items = filterValue.value;
131
+ if (items.length === 0) {
132
+ return null;
133
+ }
134
+ if (operatorValue.type === 'enum_list') {
135
+ const labels = items.map(v => getEnumLabel(operatorValue.values, v));
136
+ if (labels.length === 1) {
137
+ return truncateString(labels[0], maxLength);
138
+ }
139
+ const totalLength = labels.reduce((sum, s) => sum + s.length, 0);
140
+ if (totalLength > maxLength) {
141
+ return `${labels.length} items`;
142
+ }
143
+ return labels.join(', ');
144
+ }
145
+ if (items.length === 1) {
146
+ return truncateString(items[0], maxLength);
147
+ }
148
+ return `${items.length} items`;
149
+ }
150
+ case 'entity_list':
151
+ {
152
+ const entities = filterValue.value;
153
+ if (entities.length === 0) {
154
+ return null;
155
+ }
156
+ if (entities.length === 1) {
157
+ return truncateString(entities[0].label, maxLength);
158
+ }
159
+ const totalLength = entities.reduce((sum, e) => sum + e.label.length, 0);
160
+ if (totalLength > maxLength) {
161
+ return `${entities.length} items`;
162
+ }
163
+ return entities.map(e => e.label).join(', ');
164
+ }
165
+ case 'time':
166
+ return filterValue.value;
167
+ case 'date_absolute':
168
+ return truncateString(formatDateAbsoluteCompact(filterValue.unixSeconds, locale), maxLength);
169
+ case 'date_relative':
170
+ return truncateString(filterValue.value, maxLength);
171
+ case 'date_range':
172
+ return 'date range';
173
+ case 'custom':
174
+ if (operatorValue.type === 'custom') {
175
+ return truncateString(operatorValue.getString(filterValue.value), maxLength);
176
+ }
177
+ return filterValue.value;
178
+ case 'nested':
179
+ {
180
+ const count = filterValue.value.length;
181
+ return count === 1 ? '1 filter' : `${count} filters`;
182
+ }
183
+ default:
184
+ return null;
160
185
  }
161
- return /*#__PURE__*/_jsx(Suspense, {
162
- fallback: null,
163
- children: /*#__PURE__*/_jsx(LazyPowerSearchBottomSheet, {
164
- ...props,
165
- editors: SHEET_EDITORS
166
- })
167
- });
168
186
  }
169
187
  function PowerSearchTokenValue({
170
188
  text
@@ -296,8 +314,7 @@ export function PowerSearch({
296
314
  xstyle,
297
315
  className,
298
316
  style,
299
- components: componentOverrides,
300
- experimental
317
+ components: componentOverrides
301
318
  }) {
302
319
  const size = useSize(sizeProp, 'md');
303
320
  const config = useInternalConfig(configProp);
@@ -308,87 +325,6 @@ export function PowerSearch({
308
325
  const placeholder = placeholderFromProps ?? t('@astryx.powersearch.placeholder');
309
326
  const popoverSaveButtonLabel = popoverSaveButtonLabelFromProps ?? t('@astryx.powersearch.editor.apply');
310
327
  const tokenizerRef = useRef(null);
311
-
312
- // Experimental presentation. `adaptive`
313
- // resolves through the policy the selection controls share; an open flow
314
- // keeps its presentation until it closes, so a resolution change mid-task
315
- // cannot pull the surface out from under the person.
316
- const presentation = experimental?.presentation ?? 'popover';
317
- const resolvedPresentation = useAdaptivePresentation(presentation);
318
- const [isSheetOpen, setIsSheetOpen] = useState(false);
319
- // Latched for the flow's lifetime: the flow stays presented after it closes
320
- // until the sheets have run their exit and handed focus back to the trigger.
321
- // Without the latch, `adaptive` resolving to `popover` mid-session (a phone
322
- // turned to landscape) would unmount the sheets and the trigger they return
323
- // focus to in the same render, dropping focus to the page body.
324
- const [isSheetPresented, setIsSheetPresented] = useState(false);
325
- const isSheetPresentation = isSheetOpen || isSheetPresented || resolvedPresentation === 'bottom-sheet';
326
- const triggerRef = useRef(null);
327
- // `hasAutoFocus` applies only to the control the field first mounts. A
328
- // presentation swap remounts the control (combobox input or trigger), and
329
- // React's `autoFocus` on the new one would pull focus from wherever on the
330
- // page it was; the roots' callback refs hand over the focus the field held
331
- // instead. A field that never swaps keeps `autoFocus` on every render, so a
332
- // Dialog that keeps it mounted still finds its `data-autofocus` on open.
333
- const [autoFocusState, setAutoFocusState] = useState({
334
- presentation: isSheetPresentation,
335
- isFirstControl: true
336
- });
337
- if (autoFocusState.presentation !== isSheetPresentation) {
338
- setAutoFocusState({
339
- presentation: isSheetPresentation,
340
- isFirstControl: false
341
- });
342
- }
343
- const autoFocusOnMount = hasAutoFocus && autoFocusState.isFirstControl && autoFocusState.presentation === isSheetPresentation;
344
- // A focus the swap moves continues the same visit to the field: the
345
- // control that held focus is gone (no blur fires for a removed element), so
346
- // the caller is told of neither a blur nor a new focus.
347
- const isSwapFocusRef = useRef(false);
348
- const focusAfterSwap = useCallback(control => {
349
- if (control == null) {
350
- return;
351
- }
352
- isSwapFocusRef.current = true;
353
- try {
354
- control.focus();
355
- } finally {
356
- isSwapFocusRef.current = false;
357
- }
358
- }, []);
359
- const handleFieldFocus = useCallback(event => {
360
- if (!isSwapFocusRef.current) {
361
- onFocus?.(event);
362
- }
363
- }, [onFocus]);
364
- const handleFieldBlur = useCallback(event => {
365
- onBlur?.(event);
366
- }, [onBlur]);
367
- // While the flow is open, the sheet announces its own content from inside
368
- // its dialog; this component announces only with the flow closed, and
369
- // `useAnnounce` routes those messages by where the field is — into a Dialog
370
- // or modal Drawer that holds it, or the shared channel when no modal does.
371
- // A result count that changed during the flow's exit is spoken once the
372
- // flow has fully closed and focus is back on the trigger: the closing
373
- // dialog stays modal through its exit, so neither its region nor the
374
- // page-body channel is heard before.
375
- const afterCloseResultCountRef = useRef(null);
376
- const triggerId = useId();
377
- const triggerLabelId = useId();
378
- const triggerContentId = useId();
379
- const statusMessageId = useId();
380
- // A field that becomes disabled cannot keep its flow open, and must not
381
- // reopen it when re-enabled. Adjusted in the
382
- // render that sees the change, not an effect, so no frame shows both.
383
- const [wasDisabled, setWasDisabled] = useState(isDisabled);
384
- if (isDisabled !== wasDisabled) {
385
- setWasDisabled(isDisabled);
386
- if (isDisabled && isSheetOpen) {
387
- setIsSheetOpen(false);
388
- }
389
- }
390
- useDevWarning('PowerSearch', '`menuWidth` has no surface in the bottom-sheet presentation: the sheet flow has no typeahead popover to size. Scope it to the popover presentation or leave it out.', isSheetPresentation && menuWidth != null);
391
- useDevWarning('PowerSearch', '`tokenOverflowBehavior` has no surface in the bottom-sheet presentation: the trigger wraps its display-only tokens. Scope it to the popover presentation or leave it out.', isSheetPresentation && tokenOverflowBehavior != null);
392
328
  const [popoverState, setPopoverStateRaw] = useState({
393
329
  type: 'idle'
394
330
  });
@@ -402,7 +338,7 @@ export function PowerSearch({
402
338
  const fieldLabel = field?.label ?? '';
403
339
  const operatorLabel = operator ? resolveOperatorLabel(operator, t) : '';
404
340
  const label = `${fieldLabel}: ${operatorLabel}`.trim();
405
- const value = operator ? formatTokenValueText(operator.value, filter.value, Math.max(maxTokenLength - fieldLabel.length - operatorLabel.length, 10), locale) : null;
341
+ const value = operator ? tokenValueText(operator.value, filter.value, Math.max(maxTokenLength - fieldLabel.length - operatorLabel.length, 10), locale) : null;
406
342
  return {
407
343
  label,
408
344
  value,
@@ -414,23 +350,9 @@ export function PowerSearch({
414
350
  const editedFilter = popoverState.type === 'editing' ? filters[popoverState.filterIndex] : undefined;
415
351
  const editedOperator = editedFilter != null ? config.getOperator(editedFilter.field, editedFilter.operator) : undefined;
416
352
  const editedBuiltInFilter = editedOperator == null || componentOverrides?.[editedOperator.value.type]?.Token == null ? editedFilter : undefined;
417
- // Whether the editor popover is open, for the hand-off below, which runs
418
- // in the commit that swaps presentations.
419
- const isPopoverOpenRef = useRef(false);
420
- // When `adaptive` flips to the sheet while the editor popover is open (a
421
- // phone rotated), the editing ends with the popover: its state returns to
422
- // idle (through the raw setter, since the tokenizer input is gone), in the
423
- // render that sees the swap, so a later switch back does not reopen a stale
424
- // editor.
425
- if (isSheetPresentation && popoverState.type !== 'idle') {
426
- setPopoverStateRaw({
427
- type: 'idle'
428
- });
429
- }
430
353
 
431
354
  // Layer for positioning the edit popover anchored to the tokenizer
432
355
  const handleLayerHide = useCallback(() => {
433
- isPopoverOpenRef.current = false;
434
356
  setPopoverStateRaw({
435
357
  type: 'idle'
436
358
  });
@@ -449,47 +371,8 @@ export function PowerSearch({
449
371
  dialogLabel: editedBuiltInFilter != null ? tokenText(editedBuiltInFilter).full : undefined
450
372
  });
451
373
 
452
- // A presentation swap removes the focused control, so the other
453
- // presentation's primary control (the combobox input or the trigger) takes
454
- // focus and focus never falls to the page body. Each presentation keys its
455
- // root, so a swap mounts a new root. The detaching root notes that it held
456
- // focus, which also covers an input focused by server-rendered `autofocus`
457
- // before hydration. The editor popover is portaled outside the root, so an
458
- // open editor counts as held focus. The attaching root gives focus to its
459
- // primary control when focus has fallen to the page body; the sheet root
460
- // also hides a popover layer left open.
461
- const isFocusPendingHandOffRef = useRef(false);
462
- const hidePopover = popover.hide;
463
- const handOffFocusRef = useCallback(node => {
464
- if (node == null) {
465
- return;
466
- }
467
- const trigger = triggerRef.current;
468
- const isSheetRoot = trigger != null && node.contains(trigger);
469
- // The sheet presentation preloads the flow's chunk, so the first press
470
- // opens without waiting for the network; nothing renders.
471
- if (isSheetRoot) {
472
- void loadPowerSearchBottomSheet();
473
- }
474
- if (isSheetRoot && isPopoverOpenRef.current) {
475
- isPopoverOpenRef.current = false;
476
- hidePopover();
477
- }
478
- const takesFocus = isFocusPendingHandOffRef.current;
479
- isFocusPendingHandOffRef.current = false;
480
- if (takesFocus && isFocusDetached(node.ownerDocument)) {
481
- focusAfterSwap(isSheetRoot ? trigger : tokenizerRef.current);
482
- }
483
- return () => {
484
- if (node.contains(node.ownerDocument.activeElement) || isPopoverOpenRef.current) {
485
- isFocusPendingHandOffRef.current = true;
486
- }
487
- };
488
- }, [focusAfterSwap, hidePopover]);
489
-
490
374
  // Wrapper that manages layer visibility and tokenizer focus alongside state
491
375
  const setPopoverState = useCallback(state => {
492
- isPopoverOpenRef.current = state.type !== 'idle';
493
376
  setPopoverStateRaw(state);
494
377
  if (state.type !== 'idle') {
495
378
  // Schedule after the current frame so React can render the popover
@@ -504,22 +387,13 @@ export function PowerSearch({
504
387
  }
505
388
  }, [popover]);
506
389
 
507
- // Expose imperative handle; in the sheet presentation the trigger is the
508
- // field's focusable control.
390
+ // Expose imperative handle
509
391
  useImperativeHandle(handleRef, () => ({
510
392
  focusTypeahead() {
511
- if (isSheetPresentation) {
512
- triggerRef.current?.focus();
513
- } else {
514
- tokenizerRef.current?.focus();
515
- }
393
+ tokenizerRef.current?.focus();
516
394
  },
517
395
  blurTypeahead() {
518
- if (isSheetPresentation) {
519
- triggerRef.current?.blur();
520
- } else {
521
- tokenizerRef.current?.blur();
522
- }
396
+ tokenizerRef.current?.blur();
523
397
  }
524
398
  }));
525
399
 
@@ -680,17 +554,15 @@ export function PowerSearch({
680
554
  });
681
555
  }, [setPopoverState]);
682
556
 
683
- // Token renderer for both presentations. Given `onRemove`, the token is
684
- // the tokenizer field's: click edits, × removes. Without it (the sheet
685
- // presentation's trigger) the token is display-only; the field as a whole
686
- // opens the flow.
687
- const renderFilterToken = useCallback((item, onRemove) => {
557
+ // Custom token renderer
558
+ // Custom token renderer
559
+ const renderToken = useCallback((item, onRemove) => {
688
560
  const auxData = item.auxiliaryData;
689
561
  const filterIndex = auxData?.filterIndex ?? -1;
690
562
  const filter = filterIndex >= 0 ? filters[filterIndex] : undefined;
691
563
  const field = auxData ? config.getField(auxData.fieldKey) : undefined;
692
564
  const operator = auxData?.operatorKey ? config.getOperator(auxData.fieldKey, auxData.operatorKey) : undefined;
693
- const canInteract = onRemove != null && !isReadOnly && !isDisabled && !filter?.isReadOnly;
565
+ const canInteract = !isReadOnly && !isDisabled && !filter?.isReadOnly;
694
566
  const handleClick = canInteract ? () => handleTokenClick(filterIndex) : undefined;
695
567
  const handleRemove = canInteract ? onRemove : undefined;
696
568
 
@@ -764,7 +636,6 @@ export function PowerSearch({
764
636
  })
765
637
  });
766
638
  }, [filters, config, configProp, maxTokenLength, size, isReadOnly, isDisabled, handleTokenClick, componentOverrides, t, popoverState, tokenText]);
767
- const renderToken = useCallback((item, onRemove) => renderFilterToken(item, onRemove), [renderFilterToken]);
768
639
 
769
640
  // Custom typeahead item renderer — adds field icon and description
770
641
  const renderItem = useCallback(item => {
@@ -852,38 +723,28 @@ export function PowerSearch({
852
723
  return resultCount;
853
724
  }, [resultCount, t]);
854
725
 
855
- // This Effect synchronizes a polite live region with the result count,
856
- // mirroring the way Typeahead announces its dropdown result count: the count
857
- // is otherwise only shown visually and stays silent to assistive tech. The
858
- // region follows where the field is: the modal that holds the field (a
859
- // Dialog, a modal Drawer), else the shared channel. While a sheet of the flow is open the sheet itself announces the
860
- // count from inside its dialog, and this Effect stays quiet. Only a
861
- // change after mount is spoken — the count present on mount is not
862
- // announced unprompted — and the guard compares against the last announced
863
- // text rather than a mounted flag, so StrictMode's effect replay announces
864
- // nothing either. A change that lands while the flow is closing waits for
865
- // the trigger focus, since the dialog is still modal through its exit. The
866
- // announcement acquires no resource, so there is no cleanup.
726
+ // Announce result-count changes to screen readers through a polite live
727
+ // region, mirroring the way Typeahead announces its dropdown result count.
728
+ // The count is otherwise only shown visually and stays silent to assistive
729
+ // tech. Only a change after mount is spoken: the guard compares against the
730
+ // last announced text rather than a mounted flag, so StrictMode's effect
731
+ // replay (which resets a flag and would speak the count present on mount
732
+ // unprompted) announces nothing until the count changes.
867
733
  const announce = useAnnounce();
868
734
  // PowerSearch words its Clear all as its record does; the field announces
869
735
  // these words instead of Tokenizer's (component:Tokenizer AR7).
870
736
  const hasReadOnlyFilter = filters.some(filter => filter.isReadOnly);
871
737
  const clearAllMessage = useMemo(() => hasReadOnlyFilter ? t('@astryx.powersearch.editableFiltersRemoved') : t('@astryx.powersearch.allFiltersRemoved'), [hasReadOnlyFilter, t]);
872
738
  const announcedResultCountRef = useRef(resultCountText);
873
- const isSheetExiting = isSheetPresented && !isSheetOpen;
874
739
  useEffect(() => {
875
740
  if (resultCountText === announcedResultCountRef.current) {
876
741
  return;
877
742
  }
878
743
  announcedResultCountRef.current = resultCountText;
879
744
  if (resultCountText != null) {
880
- if (isSheetExiting) {
881
- afterCloseResultCountRef.current = resultCountText;
882
- } else if (!isSheetOpen) {
883
- announce(resultCountText);
884
- }
745
+ announce(resultCountText);
885
746
  }
886
- }, [resultCountText, announce, isSheetExiting, isSheetOpen]);
747
+ }, [resultCountText, announce]);
887
748
 
888
749
  // Build combined endContent from resultCount + endContent props
889
750
  const combinedEndContent = useMemo(() => {
@@ -902,176 +763,9 @@ export function PowerSearch({
902
763
  }
903
764
  return resultCountNode || endContent || undefined;
904
765
  }, [resultCountText, endContent]);
905
-
906
- // ------------------------------------------------------- sheet trigger --
907
-
908
- // Disabled-reason tooltip for the sheet trigger. Disabled controls swallow
909
- // pointer events, so the listeners attach to the field's control box; the
910
- // trigger stays perceivable through aria-disabled.
911
- const showsDisabledMessage = isDisabled && !!disabledMessage;
912
- const disabledMessageTooltip = useTooltip({
913
- placement: 'above',
914
- focusTrigger: 'always',
915
- isEnabled: isSheetPresentation && showsDisabledMessage
916
- });
917
- const rootRef = useMergedRefs(ref, popover.triggerRef, handOffFocusRef);
918
- const openSheet = useCallback(() => {
919
- if (isDisabled) {
920
- return;
921
- }
922
- // The flow restores focus to the element that was active when it opened;
923
- // make sure that is the trigger even for a tap on a token.
924
- triggerRef.current?.focus({
925
- preventScroll: true
926
- });
927
- setIsSheetPresented(true);
928
- setIsSheetOpen(true);
929
- }, [isDisabled]);
930
-
931
- // The field's end lane — the result count and `endContent` — sits outside
932
- // the trigger button: a caller's action button there keeps its own tab stop
933
- // and taps, and an interactive control must not nest in a component
934
- // button, so a tap on it must not open the flow.
935
- const endLaneRef = useRef(null);
936
- const handleTriggerWrapperClick = useCallback(event => {
937
- // Tokens are display-only; a tap on them or the empty space around them
938
- // opens the flow. The trigger button handles its own click, and the end
939
- // lane handles its own.
940
- if (event.target instanceof Node && (triggerRef.current?.contains(event.target) || endLaneRef.current?.contains(event.target))) {
941
- return;
942
- }
943
- openSheet();
944
- }, [openSheet]);
945
- const handleTriggerFocusWithin = useCallback(event => {
946
- // The flow focuses the trigger only after its exit completes; that focus
947
- // is the signal that the retained sheets can leave. If the resolution
948
- // moved to the popover meanwhile, the tokenizer input takes over the
949
- // focus once it mounts (the hand-off above).
950
- if (!isSheetOpen && isSheetPresented) {
951
- setIsSheetPresented(false);
952
- // The dialogs have closed: the page-body channel is exposed again.
953
- const resultCount = afterCloseResultCountRef.current;
954
- afterCloseResultCountRef.current = null;
955
- if (resultCount != null) {
956
- announce(resultCount);
957
- }
958
- }
959
- if (!(event.relatedTarget instanceof Node) || !event.currentTarget.contains(event.relatedTarget)) {
960
- handleFieldFocus(event);
961
- }
962
- }, [announce, handleFieldFocus, isSheetOpen, isSheetPresented]);
963
- const handleTriggerBlurWithin = useCallback(event => {
964
- if (!(event.relatedTarget instanceof Node) || !event.currentTarget.contains(event.relatedTarget)) {
965
- handleFieldBlur(event);
966
- }
967
- }, [handleFieldBlur]);
968
- if (isSheetPresentation) {
969
- const triggerDescribedBy = [status?.message ? statusMessageId : null, showsDisabledMessage ? disabledMessageTooltip.describedBy : null].filter(Boolean).join(' ') || undefined;
970
- return /*#__PURE__*/_jsxs("div", {
971
- ref: rootRef,
972
- ...themeProps('power-search'),
973
- children: [/*#__PURE__*/_jsxs(Field, {
974
- label: label,
975
- isLabelHidden: isLabelHidden,
976
- inputID: triggerId,
977
- labelID: triggerLabelId,
978
- isDisabled: isDisabled,
979
- status: status ? {
980
- type: status.type,
981
- message: status.message,
982
- messageID: status.message ? statusMessageId : undefined
983
- } : undefined,
984
- statusVariant: statusVariant,
985
- xstyle: xstyle,
986
- className: className,
987
- style: style,
988
- children: [/*#__PURE__*/_jsxs("div", {
989
- ref: disabledMessageTooltip.ref,
990
- onClick: handleTriggerWrapperClick,
991
- onFocus: handleTriggerFocusWithin,
992
- onBlur: handleTriggerBlurWithin,
993
- "aria-disabled": isDisabled ? true : undefined,
994
- ...stylex.props(inputWrapperStyles.base, sheetTriggerStyles.wrapper, filters.length > 0 && sheetTriggerStyles.wrapperWithTokens, sheetTriggerSizeStyles[size], isDisabled && inputWrapperStyles.disabled, status && inputStatusBorderStyles[status.type], status && !isDisabled && inputStatusHoverShadowStyles[status.type], status && inputStatusFocusWithinStyles[status.type]),
995
- children: [/*#__PURE__*/_jsxs("div", {
996
- id: triggerContentId,
997
- ...{
998
- className: "x1n2onr6 xeuugli x1iyjqo2 x78zum5 x6s0dn4 x1a02dak x1lfs0n9 xajebq8"
999
- },
1000
- children: [isRenderable(startIcon) && /*#__PURE__*/_jsx("span", {
1001
- ...{
1002
- 0: {},
1003
- 1: {
1004
- className: "x1xrm450"
1005
- }
1006
- }[!!(filters.length > 0) << 0],
1007
- children: renderIconSlot(startIcon, {
1008
- size: 'sm',
1009
- color: 'secondary'
1010
- })
1011
- }), tokenizerValue.map(item => /*#__PURE__*/_jsx(React.Fragment, {
1012
- children: renderFilterToken(item, undefined)
1013
- }, item.id)), /*#__PURE__*/_jsx("button", {
1014
- type: "button",
1015
- id: triggerId,
1016
- ref: triggerRef
1017
- // The field's primary control: `data-testid` lands here, as it
1018
- // lands on the combobox input in the popover presentation.
1019
- ,
1020
- "data-testid": testId,
1021
- autoFocus: autoFocusOnMount,
1022
- onClick: openSheet,
1023
- "aria-disabled": isDisabled ? true : undefined,
1024
- "aria-haspopup": "dialog",
1025
- "aria-expanded": isSheetOpen,
1026
- "aria-labelledby": `${triggerLabelId} ${triggerContentId}`,
1027
- "aria-describedby": triggerDescribedBy,
1028
- ...{
1029
- 0: {
1030
- className: "xjyslct xfoc8du x1fns5xo xkh2ocl x78zum5 x6s0dn4 xt970qd x7a5moj x1ghz6dp xc342km xng3xce xjbqb8w xv1l7n4 x9ynric xjm74w1 xw6l6zx x1yc453h xuxw1ft x1ypdohk xvivl9a x1a2a7pz"
1031
- },
1032
- 1: {
1033
- className: "xjyslct xfoc8du xkh2ocl x78zum5 x6s0dn4 xt970qd x7a5moj x1ghz6dp xc342km xng3xce xjbqb8w xv1l7n4 x9ynric xjm74w1 xw6l6zx x1yc453h xuxw1ft x1ypdohk xvivl9a x1a2a7pz x10l6tqk x10a8y8t xeuugli x1717udv"
1034
- }
1035
- }[!!(filters.length > 0) << 0],
1036
- children: filters.length === 0 ? placeholder : null
1037
- })]
1038
- }), (endContent || isRenderable(resultCountText)) && /*#__PURE__*/_jsxs("div", {
1039
- ref: endLaneRef,
1040
- ...{
1041
- className: "x78zum5 x6s0dn4 x1txdalj x2lah0s x1nryj5t"
1042
- },
1043
- children: [isRenderable(resultCountText) && /*#__PURE__*/_jsx("span", {
1044
- ...{
1045
- className: "x141an7d x1ltkj2j xv1l7n4 xuxw1ft"
1046
- },
1047
- children: resultCountText
1048
- }), endContent]
1049
- })]
1050
- }), showsDisabledMessage && disabledMessageTooltip.renderTooltip(disabledMessage)]
1051
- }), (isSheetOpen || isSheetPresented) && /*#__PURE__*/_jsx(PowerSearchSheetHost, {
1052
- isOpen: isSheetOpen,
1053
- onOpenChange: setIsSheetOpen,
1054
- finalFocusRef: triggerRef,
1055
- resultCountText: resultCountText,
1056
- config: config,
1057
- configProp: configProp,
1058
- filters: filters,
1059
- onChange: onChange,
1060
- searchSource: searchSource,
1061
- placeholder: placeholder,
1062
- isReadOnly: isReadOnly,
1063
- isDisabled: isDisabled,
1064
- hasClear: hasClear,
1065
- maxOperatorMenuItems: maxOperatorMenuItems,
1066
- maxSearchResults: maxSearchResults,
1067
- saveButtonLabel: popoverSaveButtonLabelFromProps,
1068
- components: componentOverrides
1069
- })]
1070
- }, "sheet");
1071
- }
1072
766
  return /*#__PURE__*/_jsxs(_Fragment, {
1073
767
  children: [/*#__PURE__*/_jsx("div", {
1074
- ref: rootRef,
768
+ ref: useMergedRefs(ref, popover.triggerRef),
1075
769
  ...themeProps('power-search'),
1076
770
  children: /*#__PURE__*/_jsx(TokenizerClearAllMessageContext, {
1077
771
  value: clearAllMessage,
@@ -1089,7 +783,7 @@ export function PowerSearch({
1089
783
  maxMenuItems: MAX_BROWSE_MENU_ITEMS,
1090
784
  menuWidth: menuWidth,
1091
785
  placeholder: filters.length === 0 ? placeholder : '',
1092
- hasAutoFocus: autoFocusOnMount,
786
+ hasAutoFocus: hasAutoFocus,
1093
787
  hasClear: hasClear && !isReadOnly,
1094
788
  startIcon: startIcon,
1095
789
  endContent: combinedEndContent,
@@ -1101,8 +795,8 @@ export function PowerSearch({
1101
795
  debounceMs: 0,
1102
796
  status: status,
1103
797
  statusVariant: statusVariant,
1104
- onFocus: handleFieldFocus,
1105
- onBlur: handleFieldBlur,
798
+ onFocus: onFocus,
799
+ onBlur: onBlur,
1106
800
  containerXstyle: xstyle,
1107
801
  containerClassName: className,
1108
802
  containerStyle: style,
@@ -1110,7 +804,7 @@ export function PowerSearch({
1110
804
  })
1111
805
  })
1112
806
  })
1113
- }, "popover"), popover.render(popoverContent, {
807
+ }), popover.render(popoverContent, {
1114
808
  placement: 'below',
1115
809
  alignment: 'start',
1116
810
  offset: spacingVars['--spacing-1'],