@astryxdesign/core 0.7.7-canary.ae97fa8 → 0.7.7-canary.b377b21

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 (228) 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 +36 -6
  4. package/dist/BottomSheet/BottomSheetPanel.d.ts.map +1 -1
  5. package/dist/BottomSheet/BottomSheetPanel.js +22 -3
  6. package/dist/BottomSheet/useSheetGestures.d.ts.map +1 -1
  7. package/dist/BottomSheet/useSheetGestures.js +3 -1
  8. package/dist/Button/Button.d.ts.map +1 -1
  9. package/dist/Button/Button.js +17 -1
  10. package/dist/CheckboxInput/CheckboxInput.d.ts.map +1 -1
  11. package/dist/CheckboxInput/CheckboxInput.js +13 -2
  12. package/dist/ComplexSelector/ComplexSelector.d.ts +4 -1
  13. package/dist/ComplexSelector/ComplexSelector.d.ts.map +1 -1
  14. package/dist/ComplexSelector/ComplexSelector.js +14 -4
  15. package/dist/ContextMenu/ContextMenu.js +2 -2
  16. package/dist/Dialog/Dialog.d.ts.map +1 -1
  17. package/dist/Dialog/Dialog.js +7 -31
  18. package/dist/Field/Field.js +2 -2
  19. package/dist/HoverCard/HoverCard.d.ts +4 -3
  20. package/dist/HoverCard/HoverCard.d.ts.map +1 -1
  21. package/dist/HoverCard/useHoverCard.d.ts +5 -4
  22. package/dist/HoverCard/useHoverCard.d.ts.map +1 -1
  23. package/dist/HoverCard/useHoverCard.js +17 -31
  24. package/dist/Icon/Icon.d.ts +5 -1
  25. package/dist/Icon/Icon.d.ts.map +1 -1
  26. package/dist/Icon/Icon.js +5 -2
  27. package/dist/Layer/usePressPin.d.ts +17 -5
  28. package/dist/Layer/usePressPin.d.ts.map +1 -1
  29. package/dist/Layer/usePressPin.js +62 -12
  30. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  31. package/dist/Lightbox/Lightbox.js +18 -0
  32. package/dist/PowerSearch/PowerSearch.d.ts +36 -3
  33. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  34. package/dist/PowerSearch/PowerSearch.js +433 -127
  35. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts +100 -0
  36. package/dist/PowerSearch/PowerSearchBottomSheet.d.ts.map +1 -0
  37. package/dist/PowerSearch/PowerSearchBottomSheet.js +1913 -0
  38. package/dist/PowerSearch/PowerSearchEditPopover.d.ts +32 -1
  39. package/dist/PowerSearch/PowerSearchEditPopover.d.ts.map +1 -1
  40. package/dist/PowerSearch/PowerSearchEditPopover.js +17 -6
  41. package/dist/PowerSearch/PowerSearchValueEditor.d.ts +38 -3
  42. package/dist/PowerSearch/PowerSearchValueEditor.d.ts.map +1 -1
  43. package/dist/PowerSearch/PowerSearchValueEditor.js +170 -61
  44. package/dist/PowerSearch/formatFilterValue.d.ts +7 -0
  45. package/dist/PowerSearch/formatFilterValue.d.ts.map +1 -1
  46. package/dist/PowerSearch/formatFilterValue.js +11 -1
  47. package/dist/PowerSearch/formatTokenValue.d.ts +28 -0
  48. package/dist/PowerSearch/formatTokenValue.d.ts.map +1 -0
  49. package/dist/PowerSearch/formatTokenValue.js +160 -0
  50. package/dist/PowerSearch/powerSearchSheetUtils.d.ts +65 -0
  51. package/dist/PowerSearch/powerSearchSheetUtils.d.ts.map +1 -0
  52. package/dist/PowerSearch/powerSearchSheetUtils.js +168 -0
  53. package/dist/RadioList/RadioList.d.ts.map +1 -1
  54. package/dist/RadioList/RadioList.js +3 -2
  55. package/dist/RadioList/RadioListItem.d.ts +1 -1
  56. package/dist/RadioList/RadioListItem.d.ts.map +1 -1
  57. package/dist/RadioList/RadioListItem.js +5 -3
  58. package/dist/Resizable/ResizeHandle.d.ts +2 -1
  59. package/dist/Resizable/ResizeHandle.d.ts.map +1 -1
  60. package/dist/Resizable/ResizeHandle.js +99 -77
  61. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -1
  62. package/dist/SegmentedControl/useSegmentedSelectionMotion.js +3 -3
  63. package/dist/Slider/sliderTouchController.js +2 -2
  64. package/dist/Spinner/Spinner.d.ts +1 -1
  65. package/dist/Spinner/Spinner.d.ts.map +1 -1
  66. package/dist/Spinner/Spinner.js +60 -58
  67. package/dist/Switch/useSwitchTouch.js +4 -4
  68. package/dist/Table/BaseTable.d.ts.map +1 -1
  69. package/dist/Table/BaseTable.js +29 -8
  70. package/dist/TextInput/TextInput.d.ts +2 -2
  71. package/dist/TextInput/TextInput.d.ts.map +1 -1
  72. package/dist/TextInput/TextInput.js +10 -7
  73. package/dist/Toast/Toast.d.ts +11 -1
  74. package/dist/Toast/Toast.d.ts.map +1 -1
  75. package/dist/Toast/Toast.js +25 -15
  76. package/dist/Toast/ToastViewport.d.ts.map +1 -1
  77. package/dist/Toast/ToastViewport.js +94 -34
  78. package/dist/Toast/types.d.ts +9 -3
  79. package/dist/Toast/types.d.ts.map +1 -1
  80. package/dist/Tooltip/useTooltip.d.ts +19 -1
  81. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  82. package/dist/Tooltip/useTooltip.js +34 -53
  83. package/dist/Typeahead/TypeaheadItem.d.ts +2 -1
  84. package/dist/Typeahead/TypeaheadItem.d.ts.map +1 -1
  85. package/dist/animator/createAnimator.d.ts +98 -0
  86. package/dist/animator/createAnimator.d.ts.map +1 -0
  87. package/dist/animator/createAnimator.js +259 -0
  88. package/dist/astryx.css +35 -6
  89. package/dist/gestures/PressTracker.d.ts.map +1 -1
  90. package/dist/gestures/PressTracker.js +4 -3
  91. package/dist/hooks/actionGroupTracker.d.ts +4 -1
  92. package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
  93. package/dist/hooks/actionGroupTracker.js +13 -3
  94. package/dist/hooks/index.d.ts +1 -0
  95. package/dist/hooks/index.d.ts.map +1 -1
  96. package/dist/hooks/index.js +1 -0
  97. package/dist/hooks/pressGroupContext.d.ts +6 -0
  98. package/dist/hooks/pressGroupContext.d.ts.map +1 -0
  99. package/dist/hooks/pressGroupContext.js +20 -0
  100. package/dist/hooks/useActionGroupTracking.d.ts +53 -0
  101. package/dist/hooks/useActionGroupTracking.d.ts.map +1 -0
  102. package/dist/hooks/useActionGroupTracking.js +174 -0
  103. package/dist/hooks/useAnimator.d.ts +41 -0
  104. package/dist/hooks/useAnimator.d.ts.map +1 -0
  105. package/dist/hooks/useAnimator.js +70 -0
  106. package/dist/hooks/useAttachment.d.ts +1 -1
  107. package/dist/hooks/useAttachment.js +1 -1
  108. package/dist/hooks/useInputStatusIcon.d.ts +1 -1
  109. package/dist/hooks/useInputStatusIcon.d.ts.map +1 -1
  110. package/dist/hooks/useInputStatusIcon.js +2 -2
  111. package/dist/hooks/useLongPress.d.ts +6 -2
  112. package/dist/hooks/useLongPress.d.ts.map +1 -1
  113. package/dist/hooks/useLongPress.js +95 -15
  114. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts +8 -0
  115. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.d.ts.map +1 -0
  116. package/dist/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.js +42 -0
  117. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.d.ts.map +1 -1
  118. package/dist/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.js +6 -0
  119. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts +8 -0
  120. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.d.ts.map +1 -0
  121. package/dist/i18n/generated-english/PowerSearch/formatTokenValue.generated.js +14 -0
  122. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  123. package/dist/i18n/generated-locales/en.generated.js +30 -0
  124. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  125. package/dist/i18n/generated-locales/pseudo.generated.js +30 -0
  126. package/dist/index.d.ts +1 -0
  127. package/dist/index.d.ts.map +1 -1
  128. package/dist/index.js +4 -0
  129. package/dist/internal/indicatorPress.stylex.d.ts +20 -0
  130. package/dist/internal/indicatorPress.stylex.d.ts.map +1 -0
  131. package/dist/internal/indicatorPress.stylex.js +26 -0
  132. package/dist/motion/animator.d.ts +14 -14
  133. package/dist/motion/animator.d.ts.map +1 -1
  134. package/dist/motion/animator.js +41 -18
  135. package/dist/motion/uikit/alert.d.ts +41 -0
  136. package/dist/motion/uikit/alert.d.ts.map +1 -0
  137. package/dist/motion/uikit/alert.js +43 -0
  138. package/dist/privateAttributes/pressGroupItem.stylex.d.ts +15 -0
  139. package/dist/privateAttributes/pressGroupItem.stylex.d.ts.map +1 -0
  140. package/dist/privateAttributes/pressGroupItem.stylex.js +23 -0
  141. package/dist/utils/focusReturn.d.ts +15 -0
  142. package/dist/utils/focusReturn.d.ts.map +1 -1
  143. package/dist/utils/focusReturn.js +28 -0
  144. package/dist/utils/interactionOverlay.stylex.d.ts +3 -2
  145. package/dist/utils/interactionOverlay.stylex.d.ts.map +1 -1
  146. package/dist/utils/interactionOverlay.stylex.js +3 -2
  147. package/dist/utils/pressFeedback.d.ts.map +1 -1
  148. package/dist/utils/pressFeedback.js +19 -6
  149. package/dist/utils/triggerFocus.d.ts +36 -0
  150. package/dist/utils/triggerFocus.d.ts.map +1 -0
  151. package/dist/utils/triggerFocus.js +65 -0
  152. package/locales/en.json +120 -0
  153. package/locales/pseudo.json +90 -0
  154. package/package.json +9 -4
  155. package/src/AlertDialog/AlertDialog.doc.mjs +2 -2
  156. package/src/AlertDialog/AlertDialog.tsx +37 -5
  157. package/src/BottomSheet/BottomSheetPanel.tsx +33 -3
  158. package/src/BottomSheet/useSheetGestures.ts +3 -1
  159. package/src/Button/Button.tsx +26 -4
  160. package/src/CheckboxInput/CheckboxInput.doc.mjs +18 -0
  161. package/src/CheckboxInput/CheckboxInput.tsx +36 -9
  162. package/src/ComplexSelector/ComplexSelector.tsx +20 -5
  163. package/src/ContextMenu/ContextMenu.tsx +2 -2
  164. package/src/Dialog/Dialog.tsx +10 -31
  165. package/src/Field/Field.tsx +2 -2
  166. package/src/HoverCard/HoverCard.doc.mjs +4 -2
  167. package/src/HoverCard/HoverCard.tsx +4 -3
  168. package/src/HoverCard/useHoverCard.doc.mjs +178 -36
  169. package/src/HoverCard/useHoverCard.tsx +46 -52
  170. package/src/Icon/Icon.doc.mjs +49 -8
  171. package/src/Icon/Icon.tsx +15 -7
  172. package/src/Layer/usePressPin.ts +81 -15
  173. package/src/Lightbox/Lightbox.tsx +18 -0
  174. package/src/PowerSearch/PowerSearch.doc.mjs +54 -5
  175. package/src/PowerSearch/PowerSearch.tsx +609 -155
  176. package/src/PowerSearch/PowerSearchBottomSheet.tsx +2515 -0
  177. package/src/PowerSearch/PowerSearchEditPopover.tsx +28 -6
  178. package/src/PowerSearch/PowerSearchValueEditor.tsx +203 -38
  179. package/src/PowerSearch/formatFilterValue.ts +18 -1
  180. package/src/PowerSearch/formatTokenValue.ts +215 -0
  181. package/src/PowerSearch/powerSearchSheetUtils.ts +224 -0
  182. package/src/RadioList/RadioList.tsx +3 -2
  183. package/src/RadioList/RadioListItem.tsx +5 -3
  184. package/src/Resizable/Resizable.doc.mjs +5 -4
  185. package/src/Resizable/ResizeHandle.tsx +167 -109
  186. package/src/SegmentedControl/useSegmentedSelectionMotion.ts +6 -3
  187. package/src/Slider/sliderTouchController.ts +2 -2
  188. package/src/Spinner/Spinner.tsx +77 -63
  189. package/src/Switch/useSwitchTouch.ts +4 -4
  190. package/src/Table/BaseTable.tsx +46 -12
  191. package/src/TextInput/TextInput.tsx +11 -10
  192. package/src/Toast/Toast.doc.mjs +4 -3
  193. package/src/Toast/Toast.tsx +52 -32
  194. package/src/Toast/ToastViewport.tsx +121 -35
  195. package/src/Toast/types.ts +9 -3
  196. package/src/Tooltip/useTooltip.doc.mjs +24 -0
  197. package/src/Tooltip/useTooltip.tsx +61 -56
  198. package/src/Typeahead/TypeaheadItem.doc.mjs +6 -3
  199. package/src/Typeahead/TypeaheadItem.tsx +2 -1
  200. package/src/animator/createAnimator.doc.mjs +153 -0
  201. package/src/animator/createAnimator.ts +324 -0
  202. package/src/gestures/PressTracker.ts +4 -3
  203. package/src/gestures/README.md +7 -1
  204. package/src/hooks/actionGroupTracker.ts +20 -5
  205. package/src/hooks/index.ts +2 -0
  206. package/src/hooks/pressGroupContext.ts +21 -0
  207. package/src/hooks/useActionGroupTracking.ts +224 -0
  208. package/src/hooks/useAnimator.doc.mjs +109 -0
  209. package/src/hooks/useAnimator.ts +67 -0
  210. package/src/hooks/useAttachment.ts +1 -1
  211. package/src/hooks/useInputStatusIcon.tsx +3 -2
  212. package/src/hooks/useLongPress.doc.mjs +2 -2
  213. package/src/hooks/useLongPress.ts +136 -15
  214. package/src/i18n/generated-english/PowerSearch/PowerSearchBottomSheet.generated.ts +43 -0
  215. package/src/i18n/generated-english/PowerSearch/PowerSearchValueEditor.generated.ts +6 -0
  216. package/src/i18n/generated-english/PowerSearch/formatTokenValue.generated.ts +15 -0
  217. package/src/i18n/generated-locales/en.generated.ts +41 -0
  218. package/src/i18n/generated-locales/pseudo.generated.ts +42 -0
  219. package/src/index.ts +13 -0
  220. package/src/internal/indicatorPress.stylex.ts +24 -0
  221. package/src/motion/README.md +8 -5
  222. package/src/motion/animator.ts +61 -29
  223. package/src/motion/uikit/alert.ts +43 -0
  224. package/src/privateAttributes/pressGroupItem.stylex.ts +23 -0
  225. package/src/utils/focusReturn.ts +30 -0
  226. package/src/utils/interactionOverlay.stylex.ts +3 -2
  227. package/src/utils/pressFeedback.ts +19 -6
  228. package/src/utils/triggerFocus.ts +80 -0
@@ -11,7 +11,8 @@
11
11
  * SYNC: When modified, update:
12
12
  * - /packages/core/src/HoverCard/index.ts
13
13
  */
14
- import { useCallback, useEffect, useRef } from 'react';
14
+ import { useCallback, useEffect, useRef, useState } from 'react';
15
+ import { createTriggerFocusGate } from "../utils/triggerFocus.js";
15
16
  import * as stylex from '@stylexjs/stylex';
16
17
  import { useLayer } from "../Layer/useLayer.js";
17
18
  import { useTouchTrigger } from "../Layer/useTouchTrigger.js";
@@ -33,35 +34,13 @@ const styles = {
33
34
  };
34
35
 
35
36
  /**
36
- * Focus trigger behavior for hover cards
37
+ * When focus on the trigger opens the hover card
37
38
  */
38
39
 
39
40
  /**
40
41
  * Touch trigger behavior for hover cards
41
42
  */
42
43
 
43
- /**
44
- * Check if an element is naturally focusable
45
- */
46
- function isFocusable(element) {
47
- // Elements with explicit tabindex
48
- if (element.hasAttribute('tabindex')) {
49
- return element.tabIndex >= 0;
50
- }
51
-
52
- // Naturally focusable elements
53
- const focusableTags = ['A', 'BUTTON', 'INPUT', 'SELECT', 'TEXTAREA'];
54
- if (focusableTags.includes(element.tagName)) {
55
- return !element.disabled;
56
- }
57
-
58
- // Elements with contenteditable
59
- if (element.isContentEditable) {
60
- return true;
61
- }
62
- return false;
63
- }
64
-
65
44
  /**
66
45
  * Hook for hover card behavior with hover/focus triggers.
67
46
  *
@@ -220,8 +199,12 @@ export function useHoverCard(options = {}) {
220
199
  const handlePointerDown = useCallback(event => {
221
200
  handleTouchPointerDown(event);
222
201
  }, [handleTouchPointerDown]);
223
- const handleFocusIn = useCallback(() => {
224
- if (!isEnabled) {
202
+
203
+ // Under `auto`, whether focus counts is decided when it arrives, and a
204
+ // focus that counted still hides on blur (utils/triggerFocus.ts).
205
+ const [focusGate] = useState(createTriggerFocusGate);
206
+ const handleFocusIn = useCallback(e => {
207
+ if (!focusGate.focusIn(e, focusTrigger) || !isEnabled) {
225
208
  return;
226
209
  }
227
210
  // A tap focuses the trigger it activates. Opening on that focus would
@@ -237,8 +220,11 @@ export function useHoverCard(options = {}) {
237
220
  }
238
221
  clearTimeouts();
239
222
  showLayer();
240
- }, [isEnabled, isTouchInteraction, clearTimeouts, showLayer]);
223
+ }, [focusGate, focusTrigger, isEnabled, isTouchInteraction, clearTimeouts, showLayer]);
241
224
  const handleFocusOut = useCallback(e => {
225
+ if (!focusGate.focusOut(e, focusTrigger)) {
226
+ return;
227
+ }
242
228
  // Check if focus is moving to the hover card content
243
229
  const relatedTarget = e.relatedTarget;
244
230
  const popoverElement = document.getElementById(layerId);
@@ -247,7 +233,7 @@ export function useHoverCard(options = {}) {
247
233
  return;
248
234
  }
249
235
  scheduleHide();
250
- }, [layerId, scheduleHide]);
236
+ }, [focusGate, focusTrigger, layerId, scheduleHide]);
251
237
 
252
238
  // Escape dismissal (WCAG 1.4.13) goes through the shared layer stack: a
253
239
  // visible card is the top-most layer, so it takes the press and consumes it.
@@ -329,9 +315,9 @@ export function useHoverCard(options = {}) {
329
315
  el.addEventListener('mouseleave', handleMouseLeave);
330
316
  el.addEventListener('pointerdown', handlePointerDown);
331
317
 
332
- // Attach focus listeners based on focusTrigger option
333
- const shouldAttachFocus = focusTrigger === 'always' || focusTrigger === 'auto' && isFocusable(el);
334
- if (shouldAttachFocus) {
318
+ // Focus listeners unless focus never opens the card; `auto` decides
319
+ // per event (utils/triggerFocus.ts).
320
+ if (focusTrigger !== 'never') {
335
321
  el.addEventListener('focusin', handleFocusIn);
336
322
  el.addEventListener('focusout', handleFocusOut);
337
323
  }
@@ -105,7 +105,11 @@ export type IconType = ComponentType<SVGProps<SVGSVGElement>>;
105
105
  * Extends SVGProps to allow passing additional SVG attributes (used when icon is a component).
106
106
  */
107
107
  export interface IconProps extends Omit<SVGProps<SVGSVGElement>, 'ref' | 'color'> {
108
- /** Ref forwarded to the root element */
108
+ /**
109
+ * Ref to the rendered SVG element when `icon` is an icon component. A
110
+ * semantic or namespaced name renders inside an internal wrapper, and the
111
+ * ref is not attached.
112
+ */
109
113
  ref?: React.Ref<SVGSVGElement>;
110
114
  /**
111
115
  * Icon to render. Can be:
@@ -1 +1 @@
1
- {"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/Icon/Icon.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC/D,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAInD,OAAO,KAAK,EAAC,QAAQ,EAAE,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,SAAS,CAAC;AAIzC,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAEhE,YAAY,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAiDhD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8Df,CAAC;AAMH,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,SAAU,SAAQ,IAAI,CACrC,QAAQ,CAAC,aAAa,CAAC,EACvB,KAAK,GAAG,OAAO,CAChB;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;;;OAMG;IACH,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,kBAAkB,CAAC;IAC/C;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AAyBD;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,KAAiB,EACjB,IAAI,EAAE,QAAQ,EACd,OAAO,EACP,KAAK,EACL,GAAG,EACH,SAAS,EACT,KAAK,EACL,MAAM,EACN,GAAG,KAAK,EACT,EAAE,SAAS,qBAoDX;yBA/De,IAAI;;;AA2IpB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,QAAQ,EAChC,KAAK,CAAC,EAAE;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAC,GAC3C,KAAK,CAAC,SAAS,CAYjB"}
1
+ {"version":3,"file":"Icon.d.ts","sourceRoot":"","sources":["../../src/Icon/Icon.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,EAAC,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAC,MAAM,OAAO,CAAC;AAC/D,OAAO,KAAK,MAAM,MAAM,kBAAkB,CAAC;AAC3C,OAAO,KAAK,EAAC,YAAY,EAAC,MAAM,kBAAkB,CAAC;AAInD,OAAO,KAAK,EAAC,QAAQ,EAAE,kBAAkB,EAAC,MAAM,sBAAsB,CAAC;AACvE,OAAO,KAAK,EAAC,WAAW,EAAC,MAAM,SAAS,CAAC;AAIzC,OAAO,EAAiB,KAAK,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAEhE,YAAY,EAAC,QAAQ,EAAC,MAAM,mBAAmB,CAAC;AAiDhD,QAAA,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA8Df,CAAC;AAMH,MAAM,MAAM,SAAS,GAAG,MAAM,OAAO,WAAW,CAAC;AAEjD;;;GAGG;AACH,MAAM,MAAM,QAAQ,GAAG,aAAa,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC,CAAC;AAE9D;;;GAGG;AACH,MAAM,WAAW,SAAU,SAAQ,IAAI,CACrC,QAAQ,CAAC,aAAa,CAAC,EACvB,KAAK,GAAG,OAAO,CAChB;IACC;;;;OAIG;IACH,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC/B;;;;;;OAMG;IACH,IAAI,EAAE,QAAQ,GAAG,QAAQ,GAAG,kBAAkB,CAAC;IAC/C;;;OAGG;IACH,KAAK,CAAC,EAAE,SAAS,CAAC;IAClB;;;;;;;;;;;;OAYG;IACH,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB;;;;;;;;;;;;;;;OAeG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA4BG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;;;;;;;;OAWG;IACH,MAAM,CAAC,EAAE,YAAY,CAAC;CACvB;AA6BD;;;;;;;GAOG;AACH,wBAAgB,IAAI,CAAC,EACnB,IAAI,EACJ,KAAiB,EACjB,IAAI,EAAE,QAAQ,EACd,OAAO,EACP,KAAK,EACL,GAAG,EACH,SAAS,EACT,KAAK,EACL,MAAM,EACN,GAAG,KAAK,EACT,EAAE,SAAS,qBAoDX;yBA/De,IAAI;;;AA2IpB;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,IAAI,EAAE,KAAK,CAAC,SAAS,GAAG,QAAQ,EAChC,KAAK,CAAC,EAAE;IAAC,IAAI,CAAC,EAAE,QAAQ,CAAC;IAAC,KAAK,CAAC,EAAE,SAAS,CAAA;CAAC,GAC3C,KAAK,CAAC,SAAS,CAYjB"}
package/dist/Icon/Icon.js CHANGED
@@ -193,7 +193,9 @@ const colorStyles = {
193
193
  *
194
194
  * - Non-empty `label` → meaningful image: `role="img"` + `aria-label`, and no
195
195
  * `aria-hidden` (an `aria-hidden` element is removed from the accessibility
196
- * tree, so its accessible name would be ignored).
196
+ * tree, so its accessible name would be ignored). Icon passes
197
+ * `aria-hidden: undefined`. Many icon components, such as Heroicons, write
198
+ * `aria-hidden="true"` unless a prop replaces it.
197
199
  * - Omitted or empty `label` → decorative default: `aria-hidden="true"`.
198
200
  *
199
201
  * The result is spread BEFORE `{...props}` in both render modes so an explicit
@@ -202,7 +204,8 @@ const colorStyles = {
202
204
  function getIconA11yProps(label) {
203
205
  return label != null && label !== '' ? {
204
206
  role: 'img',
205
- 'aria-label': label
207
+ 'aria-label': label,
208
+ 'aria-hidden': undefined
206
209
  } : {
207
210
  'aria-hidden': 'true'
208
211
  };
@@ -2,8 +2,9 @@
2
2
  * @file usePressPin.ts
3
3
  * @input A hover layer's trigger, open state, show and hide, and its
4
4
  * `triggerBehavior` and `touchTrigger` options
5
- * @output usePressPin, the press toggle that pins a hover layer open;
6
- * isPressPinTrigger; stopPressPinClick; the LayerTriggerBehavior type
5
+ * @output usePressPin, the press toggle that pins a hover layer open, and
6
+ * the app hold behind useTooltip's show() and hide(); isPressPinTrigger;
7
+ * stopPressPinClick; the LayerTriggerBehavior type
7
8
  * @position Core-internal: one call per hover layer, useTooltip's. It owns
8
9
  * the layer's touch trigger, so the host makes no second touch-trigger call.
9
10
  *
@@ -66,8 +67,18 @@ export interface UsePressPinReturn {
66
67
  isHeldOpen: () => boolean;
67
68
  /** Wires the trigger element, or unwires it with `null`. */
68
69
  attach: (element: HTMLElement | null) => void;
69
- /** Drops the pin: Escape, or a hide that came from elsewhere. */
70
+ /** Drops the pin and the app hold: Escape, or a hide from elsewhere. */
70
71
  unpin: () => void;
72
+ /**
73
+ * The app's `show()`: shows the layer and holds it open, as a pin does,
74
+ * until `release`, Escape, a press outside, or focus leaving the trigger
75
+ * and the layer. A controlled layer reports the request instead.
76
+ */
77
+ hold: () => void;
78
+ /** The app's `hide()`: drops the hold and hides the layer. */
79
+ release: () => void;
80
+ /** Whether the app's `show()` holds the layer open now. */
81
+ isAppHeld: () => boolean;
71
82
  /**
72
83
  * While pinned, focus moving onto an element outside the trigger and the
73
84
  * layer closes it. Returns whether the pin decided. The pin calls it for its
@@ -75,8 +86,9 @@ export interface UsePressPinReturn {
75
86
  */
76
87
  handleFocusLeave: (event: FocusEvent) => boolean;
77
88
  /**
78
- * Whether the layer shows pinned on a wired trigger. The host then announces
79
- * its rendered text, unless the layer has a `label`.
89
+ * Whether the layer shows pinned on a wired trigger, or held by the app's
90
+ * `show()`. The host then announces its rendered text, unless the layer has
91
+ * a `label`.
80
92
  */
81
93
  isPinShown: boolean;
82
94
  /** The layer's touch trigger (useTouchTriggerInternal), wired to the pin. */
@@ -1 +1 @@
1
- {"version":3,"file":"usePressPin.d.ts","sourceRoot":"","sources":["../../src/Layer/usePressPin.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;GAYG;AAEH,OAAO,EAKL,KAAK,UAAU,IAAI,eAAe,EAClC,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAE3B;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAKzD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAI9D;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAM3D;AAED,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,eAAe,EAAE,oBAAoB,CAAC;IACtC,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,mCAAmC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,sEAAsE;IACtE,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,YAAY,EAAE,iBAAiB,CAAC;IAChC,iEAAiE;IACjE,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,eAAe,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,OAAO,CAAC;IAC1D;;;;OAIG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,4DAA4D;IAC5D,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,iEAAiE;IACjE,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC;IACjD;;;OAGG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,KAAK,EAAE,IAAI,CACT,qBAAqB,EACnB,mBAAmB,GACnB,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,cAAc,CACjB,CAAC;CACH;AAwBD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CA+V1E"}
1
+ {"version":3,"file":"usePressPin.d.ts","sourceRoot":"","sources":["../../src/Layer/usePressPin.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAKL,KAAK,UAAU,IAAI,eAAe,EAClC,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AAIf,OAAO,EAEL,KAAK,iBAAiB,EACtB,KAAK,qBAAqB,EAC3B,MAAM,mBAAmB,CAAC;AAE3B;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,UAAU,GAAG,QAAQ,CAAC;AAKzD;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAI9D;AAED,0EAA0E;AAC1E,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAM3D;AAED,MAAM,WAAW,kBAAkB;IACjC,qCAAqC;IACrC,eAAe,EAAE,oBAAoB,CAAC;IACtC,oDAAoD;IACpD,SAAS,EAAE,OAAO,CAAC;IACnB,mEAAmE;IACnE,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,mCAAmC;IACnC,WAAW,EAAE,OAAO,CAAC;IACrB,sCAAsC;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAC;IAClB,0CAA0C;IAC1C,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,2BAA2B;IAC3B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,sEAAsE;IACtE,MAAM,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAClC,2FAA2F;IAC3F,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,YAAY,EAAE,iBAAiB,CAAC;IAChC,iEAAiE;IACjE,UAAU,EAAE,SAAS,CAAC,WAAW,GAAG,IAAI,CAAC,CAAC;CAC3C;AAED,MAAM,WAAW,iBAAiB;IAChC,+EAA+E;IAC/E,eAAe,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,OAAO,CAAC;IAC1D;;;;OAIG;IACH,UAAU,EAAE,MAAM,OAAO,CAAC;IAC1B,4DAA4D;IAC5D,MAAM,EAAE,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAC;IAC9C,wEAAwE;IACxE,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB;;;;OAIG;IACH,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,2DAA2D;IAC3D,SAAS,EAAE,MAAM,OAAO,CAAC;IACzB;;;;OAIG;IACH,gBAAgB,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC;IACjD;;;;OAIG;IACH,UAAU,EAAE,OAAO,CAAC;IACpB,6EAA6E;IAC7E,KAAK,EAAE,IAAI,CACT,qBAAqB,EACnB,mBAAmB,GACnB,oBAAoB,GACpB,oBAAoB,GACpB,mBAAmB,GACnB,cAAc,CACjB,CAAC;CACH;AAwBD;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,iBAAiB,CAqZ1E"}
@@ -6,8 +6,9 @@
6
6
  * @file usePressPin.ts
7
7
  * @input A hover layer's trigger, open state, show and hide, and its
8
8
  * `triggerBehavior` and `touchTrigger` options
9
- * @output usePressPin, the press toggle that pins a hover layer open;
10
- * isPressPinTrigger; stopPressPinClick; the LayerTriggerBehavior type
9
+ * @output usePressPin, the press toggle that pins a hover layer open, and
10
+ * the app hold behind useTooltip's show() and hide(); isPressPinTrigger;
11
+ * stopPressPinClick; the LayerTriggerBehavior type
11
12
  * @position Core-internal: one call per hover layer, useTooltip's. It owns
12
13
  * the layer's touch trigger, so the host makes no second touch-trigger call.
13
14
  *
@@ -94,8 +95,19 @@ export function usePressPin(options) {
94
95
  setIsPinnedState(next);
95
96
  }, []);
96
97
 
98
+ // The app's show() holds the layer on any trigger, in any mode.
99
+ const isAppHeldRef = useRef(false);
100
+ const [isAppHeldState, setIsAppHeldState] = useState(false);
101
+ const setAppHeld = useCallback(next => {
102
+ isAppHeldRef.current = next;
103
+ setIsAppHeldState(next);
104
+ }, []);
105
+
97
106
  // The last offered element lets a `triggerBehavior` change rewire it.
98
107
  const triggerRef = useRef(null);
108
+ // Every offered trigger, in any mode, so focus leaving ends a pin or an
109
+ // app hold.
110
+ const focusTargetRef = useRef(null);
99
111
  const offeredRef = useRef(null);
100
112
  // A primitive: re-attaching the same trigger renders nothing.
101
113
  const [offeredKind, setOfferedKind] = useState('none');
@@ -106,6 +118,13 @@ export function usePressPin(options) {
106
118
  // a pinned layer through the pin, so the pin drops with it.
107
119
  const hideFromTouch = useCallback(() => {
108
120
  const current = optionsRef.current;
121
+ if (isAppHeldRef.current) {
122
+ setAppHeld(false);
123
+ if (current.isOpen !== undefined) {
124
+ current.report(false);
125
+ return;
126
+ }
127
+ }
109
128
  if (current.triggerBehavior === 'toggle' && triggerRef.current != null) {
110
129
  if (current.isOpen !== undefined) {
111
130
  current.report(false);
@@ -116,7 +135,7 @@ export function usePressPin(options) {
116
135
  }
117
136
  }
118
137
  current.hide();
119
- }, [setPinned]);
138
+ }, [setPinned, setAppHeld]);
120
139
  const {
121
140
  isTouchPointerRef,
122
141
  isTouchInteraction,
@@ -138,13 +157,14 @@ export function usePressPin(options) {
138
157
  const close = useCallback(() => {
139
158
  const current = optionsRef.current;
140
159
  clearTapOpen();
160
+ setAppHeld(false);
141
161
  if (current.isOpen !== undefined) {
142
162
  current.report(false);
143
163
  return;
144
164
  }
145
165
  setPinned(false);
146
166
  current.hide();
147
- }, [setPinned, clearTapOpen]);
167
+ }, [setPinned, setAppHeld, clearTapOpen]);
148
168
  const announceName = useCallback(() => {
149
169
  const current = optionsRef.current;
150
170
  const name = current.label?.trim() ?? '';
@@ -233,6 +253,9 @@ export function usePressPin(options) {
233
253
  }, [pressFromKey]);
234
254
  const isHeldOpen = useCallback(() => {
235
255
  const current = optionsRef.current;
256
+ if (isAppHeldRef.current && current.isLayerOpen) {
257
+ return current.isOpen !== false;
258
+ }
236
259
  if (current.triggerBehavior !== 'toggle' || triggerRef.current == null) {
237
260
  return false;
238
261
  }
@@ -245,7 +268,7 @@ export function usePressPin(options) {
245
268
  return false;
246
269
  }
247
270
  const next = event.relatedTarget;
248
- const trigger = triggerRef.current;
271
+ const trigger = focusTargetRef.current;
249
272
  // Focus that leaves for no element is a press's to decide. The trigger
250
273
  // can sit in another document, so the check uses its own window.
251
274
  const view = trigger?.ownerDocument.defaultView;
@@ -260,6 +283,8 @@ export function usePressPin(options) {
260
283
  return true;
261
284
  }, [isHeldOpen, close]);
262
285
  const unwire = useCallback(() => {
286
+ focusTargetRef.current?.removeEventListener('focusout', handleFocusLeave);
287
+ focusTargetRef.current = null;
263
288
  const previous = triggerRef.current;
264
289
  if (previous == null) {
265
290
  return;
@@ -267,7 +292,6 @@ export function usePressPin(options) {
267
292
  previous.removeEventListener('click', handlePress);
268
293
  previous.removeEventListener('keydown', handleKeyDown);
269
294
  previous.removeEventListener('keyup', handleKeyUp);
270
- previous.removeEventListener('focusout', handleFocusLeave);
271
295
  const own = ownStateRef.current;
272
296
  if (own != null) {
273
297
  restoreAttribute(previous, 'aria-expanded', own.expanded);
@@ -290,10 +314,14 @@ export function usePressPin(options) {
290
314
  mode: current.triggerBehavior
291
315
  };
292
316
  unwire();
293
- if (element == null || current.triggerBehavior !== 'toggle') {
317
+ if (element == null) {
294
318
  return;
295
319
  }
296
- if (!isPressPinTrigger(element)) {
320
+ // Its own focus-leave listener, in any mode: `focusTrigger="never"`
321
+ // attaches none, and an app hold needs it on any trigger.
322
+ element.addEventListener('focusout', handleFocusLeave);
323
+ focusTargetRef.current = element;
324
+ if (current.triggerBehavior !== 'toggle' || !isPressPinTrigger(element)) {
297
325
  return;
298
326
  }
299
327
  element.addEventListener('click', handlePress);
@@ -301,8 +329,6 @@ export function usePressPin(options) {
301
329
  element.addEventListener('keydown', handleKeyDown);
302
330
  element.addEventListener('keyup', handleKeyUp);
303
331
  }
304
- // Its own focus-leave listener: `focusTrigger="never"` attaches none.
305
- element.addEventListener('focusout', handleFocusLeave);
306
332
  ownStateRef.current = {
307
333
  expanded: element.getAttribute('aria-expanded'),
308
334
  controls: element.getAttribute('aria-controls')
@@ -328,7 +354,28 @@ export function usePressPin(options) {
328
354
  if (isPinnedRef.current) {
329
355
  setPinned(false);
330
356
  }
331
- }, [setPinned]);
357
+ if (isAppHeldRef.current) {
358
+ setAppHeld(false);
359
+ }
360
+ }, [setPinned, setAppHeld]);
361
+ const hold = useCallback(() => {
362
+ const current = optionsRef.current;
363
+ if (!current.isEnabled) {
364
+ return;
365
+ }
366
+ setAppHeld(true);
367
+ armOutsideDismiss();
368
+ announceName();
369
+ if (current.isOpen !== undefined) {
370
+ current.report(true);
371
+ return;
372
+ }
373
+ current.show();
374
+ }, [setAppHeld, armOutsideDismiss, announceName]);
375
+ const release = useCallback(() => {
376
+ close();
377
+ }, [close]);
378
+ const isAppHeld = useCallback(() => isAppHeldRef.current, []);
332
379
 
333
380
  // Each path that hides a pinned layer drops the pin itself, so a layer that
334
381
  // does not show is never reported expanded.
@@ -344,12 +391,15 @@ export function usePressPin(options) {
344
391
  writeAttribute(trigger, 'aria-expanded', isExpanded ? 'true' : 'false');
345
392
  writeAttribute(trigger, 'aria-controls', isLayerOpen ? layerId : null);
346
393
  });
347
- const isPinShown = isToggleMode && isWired && isExpanded;
394
+ const isPinShown = isToggleMode && isWired && isExpanded || isAppHeldState && isLayerOpen && isOpen !== false;
348
395
  return {
349
396
  isToggleTrigger,
350
397
  isHeldOpen,
351
398
  attach,
352
399
  unpin,
400
+ hold,
401
+ release,
402
+ isAppHeld,
353
403
  handleFocusLeave,
354
404
  isPinShown,
355
405
  touch: {
@@ -1 +1 @@
1
- {"version":3,"file":"Lightbox.d.ts","sourceRoot":"","sources":["../../src/Lightbox/Lightbox.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAsB5C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAC;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IACjE,+CAA+C;IAC/C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,KAAK,EAAE,aAAa,GAAG,aAAa,EAAE,CAAC;IACvC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAmKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,QAAQ,CAAC,EACvB,MAAM,EACN,YAAY,EACZ,KAAK,EACL,KAAK,EAAE,eAAe,EACtB,YAAgB,EAChB,aAAa,EACb,OAAe,EACf,WAAmB,EACnB,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,GAAG,KAAK,EACT,EAAE,aAAa,sCAsdf;yBAtee,QAAQ"}
1
+ {"version":3,"file":"Lightbox.d.ts","sourceRoot":"","sources":["../../src/Lightbox/Lightbox.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAOL,KAAK,SAAS,EACf,MAAM,OAAO,CAAC;AASf,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAuB5C;;GAEG;AACH,MAAM,MAAM,iBAAiB,GAAG,OAAO,GAAG,OAAO,CAAC;AAElD;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,uBAAuB;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,gEAAgE;IAChE,GAAG,EAAE,MAAM,CAAC;IACZ,iDAAiD;IACjD,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB;;;OAGG;IACH,IAAI,CAAC,EAAE,iBAAiB,CAAC;CAC1B;AAED,MAAM,WAAW,aAAc,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IACjE,+CAA+C;IAC/C,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAChB;;;OAGG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC;;;OAGG;IACH,KAAK,EAAE,aAAa,GAAG,aAAa,EAAE,CAAC;IACvC;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;OAEG;IACH,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAmKD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,QAAQ,CAAC,EACvB,MAAM,EACN,YAAY,EACZ,KAAK,EACL,KAAK,EAAE,eAAe,EACtB,YAAgB,EAChB,aAAa,EACb,OAAe,EACf,WAAmB,EACnB,MAAM,EACN,SAAS,EACT,KAAK,EACL,GAAG,EACH,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,GAAG,KAAK,EACT,EAAE,aAAa,sCAuef;yBAvfe,QAAQ"}
@@ -42,6 +42,7 @@ import { isRtlElement } from "../hooks/isRtlElement.js";
42
42
  import { registerEnglishFallback, useComponentTranslator } from "../i18n/useComponentTranslator.js";
43
43
  import english from "../i18n/generated-english/Lightbox/Lightbox.generated.js";
44
44
  import { isRenderable } from "../utils/isRenderable.js";
45
+ import { prepareFocusReturnOnRemoval } from "../utils/focusReturn.js";
45
46
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
46
47
  registerEnglishFallback(english);
47
48
  /**
@@ -326,6 +327,23 @@ export function Lightbox({
326
327
  }
327
328
  }
328
329
  }, [isOpen, hasItem]);
330
+
331
+ // A viewer that unmounts while open (rendered only while open, or removed
332
+ // with the rest of a view) never runs the close branch above. Focus the
333
+ // removal lost goes back to the opener while the opener is still on the
334
+ // page.
335
+ useEffect(() => {
336
+ const dialog = dialogRef.current;
337
+ if (dialog == null) {
338
+ return;
339
+ }
340
+ const returnFocusOnRemoval = prepareFocusReturnOnRemoval(dialog);
341
+ return () => {
342
+ if (dialog.open) {
343
+ returnFocusOnRemoval(triggerElementRef.current);
344
+ }
345
+ };
346
+ }, [hasItem]);
329
347
  const handleClose = useCallback(() => {
330
348
  onOpenChange(false);
331
349
  }, [onOpenChange]);
@@ -1,12 +1,15 @@
1
1
  /**
2
2
  * @file PowerSearch.tsx
3
- * @input PowerSearchConfig, filters, onChange
3
+ * @input PowerSearchConfig, filters, onChange; Tokenizer, Field parts, Token,
4
+ * useAdaptivePresentation, and PowerSearchBottomSheet (lazy)
4
5
  * @output Structured filter bar with token-based filter management
5
6
  * @position Main component; forwards DOM ref and exposes tokenizer control via
6
- * handleRef
7
+ * handleRef. The experimental `presentation` option swaps the tokenizer
8
+ * field and editor popover for one trigger that opens PowerSearchBottomSheet.
7
9
  *
8
10
  * SYNC: When modified, update:
9
11
  * - /packages/core/src/PowerSearch/index.ts
12
+ * - /packages/core/src/PowerSearch/PowerSearchBottomSheet.tsx (sheet presentation)
10
13
  * - /packages/cli/assets/templates/blocks/components/PowerSearch/ (showcase blocks)
11
14
  */
12
15
  import React, { type ReactNode } from 'react';
@@ -112,6 +115,36 @@ export interface PowerSearchProps extends Omit<BaseProps<HTMLElement>, 'onChange
112
115
  * Keys are operator value types (e.g. 'string', 'enum', 'date_absolute').
113
116
  */
114
117
  components?: PowerSearchComponents;
118
+ /**
119
+ * Experimental options, outside the stable compatibility promise: anything
120
+ * in this object may change or be removed in a patch release. Omit it for
121
+ * the stable behavior.
122
+ * @experimental
123
+ */
124
+ experimental?: {
125
+ /**
126
+ * How the field presents filter editing.
127
+ * - `'popover'`: the tokenizer field with its typeahead and the editor
128
+ * popover — the stable behavior.
129
+ * - `'bottom-sheet'`: the whole field is one trigger showing display-only
130
+ * filter tokens; it opens a stack of sheets. Filters lists the filters
131
+ * as rows that edit or remove one, with Add filter, Done, and Clear
132
+ * all, which asks first and keeps read-only filters. Add filter opens
133
+ * above it with the fields (or the content search with inline
134
+ * suggestions), and a value step opens above that, stages operator →
135
+ * value, and confirms from its footer. Dismissing a step reveals the
136
+ * one beneath. Suited to compact touch screens, where the editor
137
+ * popover competes with the software keyboard.
138
+ * - `'adaptive'`: the bottom sheet on compact coarse-pointer screens,
139
+ * otherwise the popover — the same resolution Selector uses.
140
+ *
141
+ * In the sheet presentation `menuWidth` and `tokenOverflowBehavior` have
142
+ * no surface to act on and warn in development.
143
+ * @experimental
144
+ * @default 'popover'
145
+ */
146
+ presentation?: 'popover' | 'bottom-sheet' | 'adaptive';
147
+ };
115
148
  }
116
149
  /**
117
150
  * Structured filter bar where each token represents a filter (field + operator + value).
@@ -179,7 +212,7 @@ export interface PowerSearchProps extends Omit<BaseProps<HTMLElement>, 'onChange
179
212
  * };
180
213
  * ```
181
214
  */
182
- export declare function PowerSearch({ config: configProp, filters, onChange, label: labelFromProps, isLabelHidden, placeholder: placeholderFromProps, hasAutoFocus, hasClear, isReadOnly, isDisabled, disabledMessage, startIcon, onFocus, onBlur, status, statusVariant, menuWidth, maxTokenLength, maxOperatorMenuItems, maxSearchResults, popoverSaveButtonLabel: popoverSaveButtonLabelFromProps, timezoneID, tokenOverflowBehavior, endContent, resultCount, ref, handleRef, size: sizeProp, 'data-testid': testId, xstyle, className, style, components: componentOverrides, }: PowerSearchProps): React.JSX.Element;
215
+ export declare function PowerSearch({ config: configProp, filters, onChange, label: labelFromProps, isLabelHidden, placeholder: placeholderFromProps, hasAutoFocus, hasClear, isReadOnly, isDisabled, disabledMessage, startIcon, onFocus, onBlur, status, statusVariant, menuWidth, maxTokenLength, maxOperatorMenuItems, maxSearchResults, popoverSaveButtonLabel: popoverSaveButtonLabelFromProps, timezoneID, tokenOverflowBehavior, endContent, resultCount, ref, handleRef, size: sizeProp, 'data-testid': testId, xstyle, className, style, components: componentOverrides, experimental, }: PowerSearchProps): React.JSX.Element;
183
216
  export declare namespace PowerSearch {
184
217
  var displayName: string;
185
218
  }
@@ -1 +1 @@
1
- {"version":3,"file":"PowerSearch.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/PowerSearch.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"PowerSearch.d.ts","sourceRoot":"","sources":["../../src/PowerSearch/PowerSearch.tsx"],"names":[],"mappings":"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"}