@astryxdesign/core 0.7.7-canary.550ff21 → 0.7.7-canary.559b005

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 (264) hide show
  1. package/dist/Avatar/Avatar.d.ts.map +1 -1
  2. package/dist/Avatar/Avatar.js +1 -1
  3. package/dist/Breadcrumbs/BreadcrumbItem.d.ts.map +1 -1
  4. package/dist/Breadcrumbs/BreadcrumbItem.js +2 -1
  5. package/dist/Button/Button.d.ts.map +1 -1
  6. package/dist/Button/Button.js +3 -2
  7. package/dist/DateInput/Wheel.d.ts +17 -1
  8. package/dist/DateInput/Wheel.d.ts.map +1 -1
  9. package/dist/DateInput/Wheel.js +179 -19
  10. package/dist/DateRangeInput/DateRangeInput.d.ts.map +1 -1
  11. package/dist/DateRangeInput/DateRangeInput.js +63 -49
  12. package/dist/Dialog/Dialog.d.ts.map +1 -1
  13. package/dist/Dialog/Dialog.js +49 -12
  14. package/dist/Drawer/Drawer.d.ts.map +1 -1
  15. package/dist/Drawer/Drawer.js +15 -10
  16. package/dist/Drawer/useDrawerDialogPresence.d.ts.map +1 -1
  17. package/dist/Drawer/useDrawerDialogPresence.js +4 -0
  18. package/dist/DropdownMenu/DropdownMenu.d.ts.map +1 -1
  19. package/dist/DropdownMenu/DropdownMenu.js +20 -4
  20. package/dist/InfoTip/InfoTip.d.ts +63 -0
  21. package/dist/InfoTip/InfoTip.d.ts.map +1 -0
  22. package/dist/InfoTip/InfoTip.js +126 -0
  23. package/dist/InfoTip/index.d.ts +10 -0
  24. package/dist/InfoTip/index.d.ts.map +1 -0
  25. package/dist/InfoTip/index.js +12 -0
  26. package/dist/Layer/layerClickBoundary.d.ts +7 -1
  27. package/dist/Layer/layerClickBoundary.d.ts.map +1 -1
  28. package/dist/Layer/layerClickBoundary.js +2 -2
  29. package/dist/Layer/useBackdropPress.d.ts +27 -0
  30. package/dist/Layer/useBackdropPress.d.ts.map +1 -0
  31. package/dist/Layer/useBackdropPress.js +53 -0
  32. package/dist/Layer/usePressPin.d.ts +95 -0
  33. package/dist/Layer/usePressPin.d.ts.map +1 -0
  34. package/dist/Layer/usePressPin.js +365 -0
  35. package/dist/Layer/useTouchTrigger.d.ts +23 -1
  36. package/dist/Layer/useTouchTrigger.d.ts.map +1 -1
  37. package/dist/Layer/useTouchTrigger.js +45 -7
  38. package/dist/Lightbox/Lightbox.d.ts.map +1 -1
  39. package/dist/Lightbox/Lightbox.js +2 -1
  40. package/dist/Popover/usePopover.d.ts.map +1 -1
  41. package/dist/Popover/usePopover.js +56 -7
  42. package/dist/PowerSearch/PowerSearch.d.ts.map +1 -1
  43. package/dist/PowerSearch/PowerSearch.js +38 -30
  44. package/dist/ProgressBar/ProgressBar.d.ts +1 -1
  45. package/dist/ProgressBar/ProgressBar.d.ts.map +1 -1
  46. package/dist/ProgressBar/ProgressBar.js +33 -6
  47. package/dist/SegmentedControl/SegmentedControl.d.ts +3 -1
  48. package/dist/SegmentedControl/SegmentedControl.d.ts.map +1 -1
  49. package/dist/SegmentedControl/SegmentedControl.js +115 -8
  50. package/dist/SegmentedControl/SegmentedControlContext.d.ts +6 -0
  51. package/dist/SegmentedControl/SegmentedControlContext.d.ts.map +1 -1
  52. package/dist/SegmentedControl/SegmentedControlItem.d.ts +1 -0
  53. package/dist/SegmentedControl/SegmentedControlItem.d.ts.map +1 -1
  54. package/dist/SegmentedControl/SegmentedControlItem.js +10 -2
  55. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts +357 -0
  56. package/dist/SegmentedControl/useSegmentedSelectionMotion.d.ts.map +1 -0
  57. package/dist/SegmentedControl/useSegmentedSelectionMotion.js +1349 -0
  58. package/dist/SegmentedControl/useSegmentedTouchTracking.d.ts +70 -0
  59. package/dist/SegmentedControl/useSegmentedTouchTracking.d.ts.map +1 -0
  60. package/dist/SegmentedControl/useSegmentedTouchTracking.js +264 -0
  61. package/dist/Selector/Selector.d.ts.map +1 -1
  62. package/dist/Selector/Selector.js +96 -67
  63. package/dist/Selector/optionShape.d.ts +24 -0
  64. package/dist/Selector/optionShape.d.ts.map +1 -0
  65. package/dist/Selector/optionShape.js +48 -0
  66. package/dist/Selector/selectableOptionEntries.d.ts +20 -0
  67. package/dist/Selector/selectableOptionEntries.d.ts.map +1 -0
  68. package/dist/Selector/selectableOptionEntries.js +38 -0
  69. package/dist/Selector/utils.d.ts +2 -17
  70. package/dist/Selector/utils.d.ts.map +1 -1
  71. package/dist/Selector/utils.js +3 -51
  72. package/dist/Switch/Switch.d.ts +1 -1
  73. package/dist/Switch/Switch.d.ts.map +1 -1
  74. package/dist/Switch/Switch.js +200 -46
  75. package/dist/Switch/switchFill.d.ts +31 -0
  76. package/dist/Switch/switchFill.d.ts.map +1 -0
  77. package/dist/Switch/switchFill.js +88 -0
  78. package/dist/Switch/switchTouch.d.ts +74 -0
  79. package/dist/Switch/switchTouch.d.ts.map +1 -0
  80. package/dist/Switch/switchTouch.js +125 -0
  81. package/dist/Switch/useSwitchTouch.d.ts +276 -0
  82. package/dist/Switch/useSwitchTouch.d.ts.map +1 -0
  83. package/dist/Switch/useSwitchTouch.js +939 -0
  84. package/dist/TabList/Tab.d.ts.map +1 -1
  85. package/dist/TabList/Tab.js +4 -3
  86. package/dist/Toast/Toast.d.ts.map +1 -1
  87. package/dist/Toast/Toast.js +5 -0
  88. package/dist/Token/Token.d.ts.map +1 -1
  89. package/dist/Token/Token.js +1 -0
  90. package/dist/Tokenizer/Tokenizer.d.ts.map +1 -1
  91. package/dist/Tokenizer/Tokenizer.js +12 -5
  92. package/dist/Tokenizer/TokenizerItemRemovableContext.d.ts +3 -0
  93. package/dist/Tokenizer/TokenizerItemRemovableContext.d.ts.map +1 -0
  94. package/dist/Tokenizer/TokenizerItemRemovableContext.js +17 -0
  95. package/dist/Tooltip/Tooltip.d.ts +30 -6
  96. package/dist/Tooltip/Tooltip.d.ts.map +1 -1
  97. package/dist/Tooltip/Tooltip.js +5 -0
  98. package/dist/Tooltip/index.d.ts +1 -1
  99. package/dist/Tooltip/index.d.ts.map +1 -1
  100. package/dist/Tooltip/useTooltip.d.ts +31 -5
  101. package/dist/Tooltip/useTooltip.d.ts.map +1 -1
  102. package/dist/Tooltip/useTooltip.js +59 -18
  103. package/dist/Typeahead/Typeahead.d.ts.map +1 -1
  104. package/dist/Typeahead/Typeahead.js +26 -15
  105. package/dist/astryx.css +125 -2
  106. package/dist/gestures/GestureHost.d.ts.map +1 -1
  107. package/dist/gestures/GestureHost.js +71 -14
  108. package/dist/gestures/PressTracker.d.ts +6 -0
  109. package/dist/gestures/PressTracker.d.ts.map +1 -1
  110. package/dist/gestures/PressTracker.js +3 -0
  111. package/dist/gestures/types.d.ts +6 -0
  112. package/dist/gestures/types.d.ts.map +1 -1
  113. package/dist/gestures/usePressTracker.d.ts.map +1 -1
  114. package/dist/gestures/usePressTracker.js +1 -0
  115. package/dist/gestures/wheelSegmenter.d.ts +14 -3
  116. package/dist/gestures/wheelSegmenter.d.ts.map +1 -1
  117. package/dist/gestures/wheelSegmenter.js +32 -8
  118. package/dist/hooks/actionGroupTracker.d.ts +3 -3
  119. package/dist/hooks/actionGroupTracker.d.ts.map +1 -1
  120. package/dist/hooks/actionGroupTracker.js +6 -53
  121. package/dist/hooks/useAttachment.d.ts +16 -8
  122. package/dist/hooks/useAttachment.d.ts.map +1 -1
  123. package/dist/hooks/useAttachment.js +35 -15
  124. package/dist/hooks/useFocusTrap.d.ts +15 -0
  125. package/dist/hooks/useFocusTrap.d.ts.map +1 -1
  126. package/dist/hooks/useFocusTrap.js +13 -2
  127. package/dist/hooks/useHighlightedOptionScroll.d.ts.map +1 -1
  128. package/dist/hooks/useHighlightedOptionScroll.js +14 -11
  129. package/dist/hooks/useMediaQuery.d.ts +2 -1
  130. package/dist/hooks/useMediaQuery.d.ts.map +1 -1
  131. package/dist/hooks/useMediaQuery.js +7 -4
  132. package/dist/hooks/usePager.d.ts +261 -0
  133. package/dist/hooks/usePager.d.ts.map +1 -0
  134. package/dist/hooks/usePager.js +1169 -0
  135. package/dist/i18n/generated-english/InfoTip/InfoTip.generated.d.ts +8 -0
  136. package/dist/i18n/generated-english/InfoTip/InfoTip.generated.d.ts.map +1 -0
  137. package/dist/i18n/generated-english/InfoTip/InfoTip.generated.js +12 -0
  138. package/dist/i18n/generated-locales/en.generated.d.ts.map +1 -1
  139. package/dist/i18n/generated-locales/en.generated.js +2 -1
  140. package/dist/i18n/generated-locales/pseudo.generated.d.ts.map +1 -1
  141. package/dist/i18n/generated-locales/pseudo.generated.js +2 -1
  142. package/dist/index.d.ts +1 -0
  143. package/dist/index.d.ts.map +1 -1
  144. package/dist/index.js +1 -0
  145. package/dist/motion/paging.d.ts +16 -5
  146. package/dist/motion/paging.d.ts.map +1 -1
  147. package/dist/motion/paging.js +34 -14
  148. package/dist/motion/roles.d.ts +7 -1
  149. package/dist/motion/roles.d.ts.map +1 -1
  150. package/dist/motion/roles.js +20 -1
  151. package/dist/motion/uikit/index.d.ts +7 -4
  152. package/dist/motion/uikit/index.d.ts.map +1 -1
  153. package/dist/motion/uikit/index.js +7 -4
  154. package/dist/motion/uikit/paging.d.ts +31 -20
  155. package/dist/motion/uikit/paging.d.ts.map +1 -1
  156. package/dist/motion/uikit/paging.js +41 -11
  157. package/dist/motion/uikit/progressBar.d.ts +27 -7
  158. package/dist/motion/uikit/progressBar.d.ts.map +1 -1
  159. package/dist/motion/uikit/progressBar.js +31 -11
  160. package/dist/motion/uikit/segmented.d.ts +55 -0
  161. package/dist/motion/uikit/segmented.d.ts.map +1 -0
  162. package/dist/motion/uikit/segmented.js +77 -0
  163. package/dist/motion/uikit/springs.d.ts +8 -42
  164. package/dist/motion/uikit/springs.d.ts.map +1 -1
  165. package/dist/motion/uikit/springs.js +12 -42
  166. package/dist/motion/uikit/switch.d.ts +166 -0
  167. package/dist/motion/uikit/switch.d.ts.map +1 -0
  168. package/dist/motion/uikit/switch.js +186 -0
  169. package/dist/privateAttributes/pressHoldsDrag.stylex.d.ts +18 -0
  170. package/dist/privateAttributes/pressHoldsDrag.stylex.d.ts.map +1 -0
  171. package/dist/privateAttributes/pressHoldsDrag.stylex.js +28 -0
  172. package/dist/privateAttributes/segmentTitle.stylex.d.ts +5 -0
  173. package/dist/privateAttributes/segmentTitle.stylex.d.ts.map +1 -0
  174. package/dist/privateAttributes/segmentTitle.stylex.js +22 -0
  175. package/dist/utils/browserClickWait.d.ts +35 -0
  176. package/dist/utils/browserClickWait.d.ts.map +1 -0
  177. package/dist/utils/browserClickWait.js +123 -0
  178. package/dist/utils/clickGuard.d.ts +7 -1
  179. package/dist/utils/clickGuard.d.ts.map +1 -1
  180. package/dist/utils/clickGuard.js +23 -1
  181. package/dist/utils/pressFeedback.d.ts.map +1 -1
  182. package/dist/utils/pressFeedback.js +5 -0
  183. package/locales/en.json +4 -0
  184. package/locales/pseudo.json +3 -0
  185. package/package.json +9 -4
  186. package/src/Avatar/Avatar.tsx +3 -1
  187. package/src/Breadcrumbs/BreadcrumbItem.tsx +4 -1
  188. package/src/Button/Button.tsx +3 -2
  189. package/src/DateInput/Wheel.tsx +174 -14
  190. package/src/DateRangeInput/DateRangeInput.doc.mjs +3 -2
  191. package/src/DateRangeInput/DateRangeInput.tsx +117 -71
  192. package/src/Dialog/Dialog.tsx +62 -11
  193. package/src/Drawer/Drawer.tsx +27 -10
  194. package/src/Drawer/useDrawerDialogPresence.ts +4 -0
  195. package/src/DropdownMenu/DropdownMenu.tsx +28 -6
  196. package/src/InfoTip/InfoTip.doc.mjs +192 -0
  197. package/src/InfoTip/InfoTip.tsx +186 -0
  198. package/src/InfoTip/index.ts +14 -0
  199. package/src/Layer/layerClickBoundary.ts +2 -2
  200. package/src/Layer/useBackdropPress.ts +81 -0
  201. package/src/Layer/usePressPin.ts +516 -0
  202. package/src/Layer/useTouchTrigger.ts +56 -6
  203. package/src/Lightbox/Lightbox.tsx +2 -1
  204. package/src/Popover/usePopover.tsx +71 -9
  205. package/src/PowerSearch/PowerSearch.tsx +38 -31
  206. package/src/ProgressBar/ProgressBar.doc.mjs +4 -2
  207. package/src/ProgressBar/ProgressBar.tsx +67 -7
  208. package/src/SegmentedControl/SegmentedControl.doc.mjs +3 -3
  209. package/src/SegmentedControl/SegmentedControl.tsx +179 -5
  210. package/src/SegmentedControl/SegmentedControlContext.ts +6 -0
  211. package/src/SegmentedControl/SegmentedControlItem.tsx +14 -2
  212. package/src/SegmentedControl/useSegmentedSelectionMotion.ts +1637 -0
  213. package/src/SegmentedControl/useSegmentedTouchTracking.ts +308 -0
  214. package/src/Selector/Selector.tsx +136 -89
  215. package/src/Selector/optionShape.ts +64 -0
  216. package/src/Selector/selectableOptionEntries.ts +39 -0
  217. package/src/Selector/utils.ts +9 -68
  218. package/src/Switch/Switch.doc.mjs +3 -3
  219. package/src/Switch/Switch.tsx +412 -86
  220. package/src/Switch/switchFill.ts +106 -0
  221. package/src/Switch/switchTouch.ts +186 -0
  222. package/src/Switch/useSwitchTouch.ts +1051 -0
  223. package/src/TabList/Tab.tsx +5 -3
  224. package/src/Toast/Toast.tsx +5 -0
  225. package/src/Token/Token.tsx +2 -0
  226. package/src/Tokenizer/Tokenizer.tsx +15 -5
  227. package/src/Tokenizer/TokenizerItemRemovableContext.ts +22 -0
  228. package/src/Tooltip/Tooltip.doc.mjs +21 -6
  229. package/src/Tooltip/Tooltip.tsx +42 -5
  230. package/src/Tooltip/index.ts +1 -0
  231. package/src/Tooltip/useTooltip.doc.mjs +4 -2
  232. package/src/Tooltip/useTooltip.tsx +84 -21
  233. package/src/Typeahead/Typeahead.tsx +29 -15
  234. package/src/gestures/GestureHost.ts +100 -11
  235. package/src/gestures/PressTracker.ts +10 -0
  236. package/src/gestures/types.ts +6 -0
  237. package/src/gestures/usePressTracker.ts +2 -0
  238. package/src/gestures/wheelSegmenter.ts +36 -7
  239. package/src/hooks/actionGroupTracker.ts +12 -56
  240. package/src/hooks/useAttachment.ts +56 -14
  241. package/src/hooks/useFocusTrap.ts +26 -2
  242. package/src/hooks/useHighlightedOptionScroll.ts +15 -11
  243. package/src/hooks/useMediaQuery.doc.mjs +2 -2
  244. package/src/hooks/useMediaQuery.ts +13 -4
  245. package/src/hooks/usePager.ts +1446 -0
  246. package/src/i18n/generated-english/InfoTip/InfoTip.generated.ts +13 -0
  247. package/src/i18n/generated-locales/en.generated.ts +1 -0
  248. package/src/i18n/generated-locales/pseudo.generated.ts +1 -0
  249. package/src/index.ts +1 -0
  250. package/src/motion/MEASUREMENTS.md +36 -27
  251. package/src/motion/README.md +3 -1
  252. package/src/motion/paging.ts +37 -14
  253. package/src/motion/roles.ts +20 -1
  254. package/src/motion/uikit/index.ts +6 -5
  255. package/src/motion/uikit/paging.ts +41 -10
  256. package/src/motion/uikit/progressBar.ts +31 -11
  257. package/src/motion/uikit/segmented.ts +74 -0
  258. package/src/motion/uikit/springs.ts +12 -42
  259. package/src/motion/uikit/switch.ts +174 -0
  260. package/src/privateAttributes/pressHoldsDrag.stylex.ts +28 -0
  261. package/src/privateAttributes/segmentTitle.stylex.ts +22 -0
  262. package/src/utils/browserClickWait.ts +133 -0
  263. package/src/utils/clickGuard.ts +28 -1
  264. package/src/utils/pressFeedback.ts +5 -0
@@ -42,6 +42,7 @@ import { LayerContentBoundary } from "../Layer/layerScopedContext.js";
42
42
  import { layerClickBoundary } from "../Layer/layerClickBoundary.js";
43
43
  import { LayerDepthProvider } from "../Layer/LayerDepthContext.js";
44
44
  import { useLayerDismissal } from "../Layer/useLayerDismissal.js";
45
+ import { useBackdropPress } from "../Layer/useBackdropPress.js";
45
46
  import { useModalOutlet } from "../Layer/modalOutlet.js";
46
47
  import "../theme/tokens.stylex.js";
47
48
  import { colorVars, radiusVars, durationVars, easeVars, shadowVars, spacingVars } from "../theme/tokens.stylex.js";
@@ -54,15 +55,15 @@ import { DialogContext } from "./DialogContext.js";
54
55
  import { themeProps } from "../utils/themeProps.js";
55
56
  import { focusOutlineProps } from "../utils/focusOutline.stylex.js";
56
57
  import { useInteractionModalityTracking } from "../utils/interactionModality.js";
57
- import { focusForLastInput } from "../utils/focusReturn.js";
58
+ import { focusForLastInput, isFocusLost } from "../utils/focusReturn.js";
58
59
  import { ModalAnnounceProvider } from "../hooks/ModalAnnounceProvider.js";
59
60
  import { useMergedRefs } from "../hooks/useMergedRefs.js";
61
+ import { jsx as _jsx } from "react/jsx-runtime";
60
62
  /**
61
63
  * Calculate a directional translate offset for dialog entry animation.
62
64
  * Returns a normalized vector from the trigger element toward the viewport
63
65
  * center, scaled to the given distance.
64
66
  */
65
- import { jsx as _jsx } from "react/jsx-runtime";
66
67
  function getDialogDirection(triggerEl, distance = 16) {
67
68
  const rect = triggerEl.getBoundingClientRect();
68
69
  // The trigger's own window: its rect is measured in that window's viewport,
@@ -458,6 +459,42 @@ export function Dialog({
458
459
  }
459
460
  }, [isOpen, isInline]);
460
461
 
462
+ // A dialog that unmounts while open (rendered only while open, or removed
463
+ // with the rest of a view) never runs the close branch above, and removing a
464
+ // <dialog> does not run the browser's own focus return. Focus left inside
465
+ // it, or dropped to the body by the removal, goes back to the opener.
466
+ useEffect(() => {
467
+ if (isInline) {
468
+ return;
469
+ }
470
+ const dialog = dialogRef.current;
471
+ // Read now: a removed iframe's document has no window, so its frame
472
+ // element can no longer be found once the dialog is gone.
473
+ const host = dialog?.ownerDocument.defaultView?.frameElement ?? null;
474
+ return () => {
475
+ const trigger = triggerElementRef.current;
476
+ if (dialog == null || trigger == null) {
477
+ return;
478
+ }
479
+ // Checked once the commit has finished: StrictMode's simulated unmount
480
+ // leaves the dialog in the document, and only a real removal returns
481
+ // focus.
482
+ queueMicrotask(() => {
483
+ if (dialog.isConnected || !trigger.isConnected) {
484
+ return;
485
+ }
486
+ // isFocusLost reads the dialog's own document. For a dialog in an
487
+ // iframe, the document that hosts the frame must also have lost focus
488
+ // or keep it on that frame, wherever the opener is: a control the
489
+ // user pressed outside the frame to remove the dialog, or the frame
490
+ // itself, keeps its focus.
491
+ if (isFocusLost(dialog) && (host == null || isFocusLost(host))) {
492
+ focusForLastInput(trigger);
493
+ }
494
+ });
495
+ };
496
+ }, [isInline]);
497
+
461
498
  // Host app-global surfaces (toasts) inside this modal while it is open, so
462
499
  // they stay visible and operable above it.
463
500
  useModalOutlet(dialogRef, isOpen && !isInline);
@@ -502,16 +539,13 @@ export function Dialog({
502
539
  }
503
540
  }, [isOpen, isInline, hasConsumerName, titleId]);
504
541
 
505
- // Handle backdrop click — when the user clicks the ::backdrop pseudo-element,
506
- // the event target is the <dialog> element itself; clicks on child content
507
- // always target the child. This avoids false positives from native browser
542
+ // A press on the ::backdrop targets the <dialog> itself, so native browser
508
543
  // popups (date pickers, selects, color pickers) that render outside the
509
- // dialog's bounding rect.
510
- const handleClick = event => {
511
- if (event.target === event.currentTarget && allowBackdropClick) {
512
- onOpenChange(false);
513
- }
514
- };
544
+ // dialog's rect never count. The press must start and end there.
545
+ const handleBackdropPress = useCallback(() => {
546
+ onOpenChange(false);
547
+ }, [onOpenChange]);
548
+ const backdropPress = useBackdropPress(handleBackdropPress, allowBackdropClick);
515
549
 
516
550
  // The native `cancel` event is the browser's own close-watcher firing: an
517
551
  // Android back gesture, or a close request the stack never saw a press for.
@@ -602,8 +636,11 @@ export function Dialog({
602
636
  })(), isFullscreen && styles.fullscreen, isFullscreen && isOpen && styles.fullscreenOpen, opensSettled && styles.openSettled, xstyle), className, style),
603
637
  ...layerClickBoundary({
604
638
  ...safeProps,
605
- onClick: chainEventHandlers(handleClick, onClickProp)
639
+ onClick: chainEventHandlers(backdropPress.onClick, onClickProp)
606
640
  }),
641
+ onPointerDownCapture: chainEventHandlers(backdropPress.onPointerDownCapture, safeProps.onPointerDownCapture),
642
+ onPointerUpCapture: chainEventHandlers(backdropPress.onPointerUpCapture, safeProps.onPointerUpCapture),
643
+ onPointerCancelCapture: chainEventHandlers(backdropPress.onPointerCancelCapture, safeProps.onPointerCancelCapture),
607
644
  onCancel: handleCancel,
608
645
  "aria-modal": isHydrating ? undefined : 'true'
609
646
  // The default aria-labelledby (from a DialogHeader title) is set
@@ -1 +1 @@
1
- {"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../src/Drawer/Drawer.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,EAAgC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAIpE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAQ5C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,WAAW,CAAC;AAkB7C,OAAO,KAAK,EAAC,WAAW,EAAe,MAAM,WAAW,CAAC;AA6MzD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,iDAAiD;IACjD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAExC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAEvB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QACb;;;;;;WAMG;QACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B,CAAC;IAEF;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EAAE,UAAU,EAClB,YAAY,EACZ,IAAY,EACZ,KAAW,EACX,YAAY,EACZ,KAAK,EACL,QAAe,EACf,OAAgB,EAChB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAyMb;yBA3Ne,MAAM"}
1
+ {"version":3,"file":"Drawer.d.ts","sourceRoot":"","sources":["../../src/Drawer/Drawer.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuDG;AAEH,OAAO,EAAgC,KAAK,SAAS,EAAC,MAAM,OAAO,CAAC;AAIpE,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAQ5C,OAAO,KAAK,EAAC,aAAa,EAAC,MAAM,WAAW,CAAC;AAoB7C,OAAO,KAAK,EAAC,WAAW,EAAe,MAAM,WAAW,CAAC;AA+MzD,MAAM,WAAW,WAAY,SAAQ,SAAS,CAAC,iBAAiB,CAAC;IAC/D,iDAAiD;IACjD,GAAG,CAAC,EAAE,KAAK,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAEnC;;OAEG;IACH,MAAM,EAAE,OAAO,CAAC;IAEhB;;;;;;OAMG;IACH,YAAY,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAExC;;;;;OAKG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IAEvB;;;;;;OAMG;IACH,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAExB;;;;;OAKG;IACH,YAAY,CAAC,EAAE;QACb;;;;;;WAMG;QACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;KAC/B,CAAC;IAEF;;;OAGG;IACH,KAAK,EAAE,MAAM,CAAC;IAEd;;;;;;;OAOG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,aAAa,CAAC;IAExB;;;;;;;;OAQG;IACH,OAAO,CAAC,EAAE,WAAW,CAAC;IAEtB;;;OAGG;IACH,QAAQ,EAAE,SAAS,CAAC;IAEpB;;OAEG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAmCG;AACH,wBAAgB,MAAM,CAAC,EACrB,MAAM,EAAE,UAAU,EAClB,YAAY,EACZ,IAAY,EACZ,KAAW,EACX,YAAY,EACZ,KAAK,EACL,QAAe,EACf,OAAgB,EAChB,OAAO,EACP,QAAQ,EACR,MAAM,EACN,SAAS,EACT,KAAK,EACL,OAAO,EAAE,WAAW,EACpB,SAAS,EAAE,aAAa,EACxB,GAAG,EACH,GAAG,KAAK,EACT,EAAE,WAAW,+BAsNb;yBAxOe,MAAM"}
@@ -70,13 +70,15 @@ import { layerTextReset } from "../Layer/layerTextReset.stylex.js";
70
70
  import { layerStructureReset } from "../Layer/layerStructureReset.stylex.js";
71
71
  import { LayerContentBoundary } from "../Layer/layerScopedContext.js";
72
72
  import { useModalOutlet } from "../Layer/modalOutlet.js";
73
+ import { useBackdropPress } from "../Layer/useBackdropPress.js";
73
74
  import { layerClickBoundary } from "../Layer/layerClickBoundary.js";
74
75
  import { ModalAnnounceProvider } from "../hooks/ModalAnnounceProvider.js";
75
76
  import { composeEventHandlers, mergeProps, themeProps } from "../utils/index.js";
77
+ import { chainEventHandlers } from "../utils/chainEventHandlers.js";
76
78
  import { container, overlayPaddingReset } from "../Layout/index.js";
77
79
  import { containerPaddingBlockEndVarStyles, containerPaddingBlockStartVarStyles, containerPaddingInlineVarStyles, paddingStyles, spacingStepToToken } from "../Layout/padding.stylex.js";
78
80
  import { useDrawerDialogPresence } from "./useDrawerDialogPresence.js";
79
-
81
+ import { jsx as _jsx } from "react/jsx-runtime";
80
82
  // =============================================================================
81
83
  // Styles
82
84
  // =============================================================================
@@ -84,7 +86,6 @@ import { useDrawerDialogPresence } from "./useDrawerDialogPresence.js";
84
86
  // Below this viewport width the drawer preserves a fixed reveal of the page
85
87
  // behind instead of growing proportionally with the viewport. 640px is the
86
88
  // repo's mobile breakpoint.
87
- import { jsx as _jsx } from "react/jsx-runtime";
88
89
  const MOBILE_BREAKPOINT = 640;
89
90
 
90
91
  // Material's established mobile drawer pattern leaves a 56dp reveal. Using
@@ -347,13 +348,12 @@ export function Drawer({
347
348
  }
348
349
  }, [allowEscape, handleDismiss, shouldDismissOnCloseRequest]);
349
350
 
350
- // Clicks on the ::backdrop target the <dialog> element itself; clicks on
351
- // drawer content always target a child (the content area fills the panel).
352
- const handleClick = useCallback(event => {
353
- if (event.target === event.currentTarget && hasScrim && allowScrimClick) {
354
- onOpenChange(false);
355
- }
356
- }, [allowScrimClick, hasScrim, onOpenChange]);
351
+ // A press on the ::backdrop targets the <dialog> itself (the content area
352
+ // fills the panel). The press must start and end there.
353
+ const handleScrimPress = useCallback(() => {
354
+ onOpenChange(false);
355
+ }, [onOpenChange]);
356
+ const scrimPress = useBackdropPress(handleScrimPress, hasScrim && allowScrimClick);
357
357
  const widthValue = typeof width === 'number' ? `${width}px` : width;
358
358
  const isFullWidthOnMobile = experimental?.isFullWidthOnMobile ?? false;
359
359
  const mobileWidth = isFullWidthOnMobile ? MOBILE_WIDTH_FULL : `min(${widthValue}, calc(100dvw - ${MOBILE_PAGE_REVEAL}px))`;
@@ -391,8 +391,13 @@ export function Drawer({
391
391
  } : undefined),
392
392
  ...layerClickBoundary({
393
393
  ...safeProps,
394
- onClick: composeEventHandlers(onClickProp, handleClick)
394
+ onClick: composeEventHandlers(onClickProp, scrimPress.onClick)
395
395
  }),
396
+ // The hook records where the press started first. The caller's capture
397
+ // handler then runs, also when a child prevented default.
398
+ onPointerDownCapture: chainEventHandlers(scrimPress.onPointerDownCapture, safeProps.onPointerDownCapture),
399
+ onPointerUpCapture: chainEventHandlers(scrimPress.onPointerUpCapture, safeProps.onPointerUpCapture),
400
+ onPointerCancelCapture: chainEventHandlers(scrimPress.onPointerCancelCapture, safeProps.onPointerCancelCapture),
396
401
  onKeyDown: onKeyDownProp,
397
402
  onCancel: handleCancel,
398
403
  children: /*#__PURE__*/_jsx(ModalAnnounceProvider, {
@@ -1 +1 @@
1
- {"version":3,"file":"useDrawerDialogPresence.d.ts","sourceRoot":"","sources":["../../src/Drawer/useDrawerDialogPresence.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAaf,KAAK,8BAA8B,GAAG;IACpC,SAAS,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC/C,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CAClD,CAAC;AAuDF;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,MAAM,EACN,OAAO,EACP,aAAa,GACd,EAAE,8BAA8B,GAAG,IAAI,CAoEvC"}
1
+ {"version":3,"file":"useDrawerDialogPresence.d.ts","sourceRoot":"","sources":["../../src/Drawer/useDrawerDialogPresence.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,EAGL,KAAK,QAAQ,EACb,KAAK,SAAS,EACd,KAAK,cAAc,EACpB,MAAM,OAAO,CAAC;AAcf,KAAK,8BAA8B,GAAG;IACpC,SAAS,EAAE,SAAS,CAAC,iBAAiB,GAAG,IAAI,CAAC,CAAC;IAC/C,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,OAAO,CAAC;IACjB,aAAa,EAAE,QAAQ,CAAC,cAAc,CAAC,OAAO,CAAC,CAAC,CAAC;CAClD,CAAC;AA0DF;;;;;;;;;;GAUG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,SAAS,EACT,MAAM,EACN,OAAO,EACP,aAAa,GACd,EAAE,8BAA8B,GAAG,IAAI,CAoEvC"}
@@ -25,6 +25,7 @@
25
25
  */
26
26
  import { useEffect, useRef } from 'react';
27
27
  import { flushSync } from 'react-dom';
28
+ import { notifyTopLayerEntry } from "../Layer/modalOutlet.js";
28
29
 
29
30
  /** Slack past the computed transition before the backstop gives up waiting. */
30
31
  const EXIT_BACKSTOP_BUFFER_MS = 50;
@@ -51,6 +52,9 @@ function showDrawerHost(dialog, isModal) {
51
52
  dialog.showModal();
52
53
  } else if (typeof dialog.showPopover === 'function') {
53
54
  dialog.showPopover();
55
+ // The drawer is now the newest top-layer entry: global hosts shown before
56
+ // it (the toast viewport) re-enter above it, as they do above a modal.
57
+ notifyTopLayerEntry();
54
58
  } else {
55
59
  // Reduced fallback for browsers below the Popover API support floor.
56
60
  dialog.show();
@@ -1 +1 @@
1
- {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"DropdownMenu.d.ts","sourceRoot":"","sources":["../../src/DropdownMenu/DropdownMenu.tsx"],"names":[],"mappings":"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"}
@@ -279,6 +279,15 @@ function holdInvokerThroughPress(control, popoverId) {
279
279
  doc.addEventListener('pointerup', onPressEnd, true);
280
280
  doc.addEventListener('pointercancel', onPressEnd, true);
281
281
  }
282
+
283
+ /**
284
+ * The name of a menu opened from a custom trigger: the caller's `aria-label`
285
+ * when it is a non-empty string, else the trigger's own accessible name. The
286
+ * popover and the bottom sheet both name the menu through this.
287
+ */
288
+ function resolveCustomTriggerMenuName(callerLabel, triggerName) {
289
+ return typeof callerLabel === 'string' && callerLabel.trim() !== '' ? callerLabel : triggerName;
290
+ }
282
291
  function DropdownMenuBottomSheet({
283
292
  button: buttonFromProps,
284
293
  renderTrigger,
@@ -340,10 +349,18 @@ function DropdownMenuBottomSheet({
340
349
  useEffect(() => {
341
350
  void preloadMenuBottomSheetActionList();
342
351
  }, []);
352
+ // The control's name is only readable from the DOM once it is rendered.
353
+ const [triggerName, setTriggerName] = useState(undefined);
354
+ useIsomorphicLayoutEffect(() => {
355
+ if (renderTrigger != null && isOpen) {
356
+ setTriggerName(readAccessibleName(buttonRef.current));
357
+ }
358
+ }, [renderTrigger, isOpen]);
359
+ const rootTitle = (renderTrigger != null ? resolveCustomTriggerMenuName(rest['aria-label'], triggerName) : undefined) ?? button.label;
343
360
  const currentSubmenu = submenuPath.at(-1);
344
361
  const currentItems = currentSubmenu?.items ?? items;
345
- const currentTitle = currentSubmenu?.label ?? button.label;
346
- const sheetLabel = typeof currentTitle === 'string' ? currentTitle : button.label;
362
+ const currentTitle = currentSubmenu?.label ?? rootTitle;
363
+ const sheetLabel = typeof currentTitle === 'string' ? currentTitle : rootTitle;
347
364
  const setOpen = useCallback(nextIsOpen => {
348
365
  if (!nextIsOpen) {
349
366
  setSubmenuPath([]);
@@ -734,8 +751,7 @@ function DropdownMenuPopover({
734
751
  // The design system's button names the menu by its label. A custom trigger
735
752
  // names it by reference (or the caller's `aria-label` does), so that name
736
753
  // is read off the control as the menu opens.
737
- const callerMenuLabel = rest['aria-label'];
738
- const menuLabel = renderTrigger != null ? typeof callerMenuLabel === 'string' && callerMenuLabel.trim() !== '' ? callerMenuLabel : triggerName : typeof button.label === 'string' ? button.label : undefined;
754
+ const menuLabel = renderTrigger != null ? resolveCustomTriggerMenuName(rest['aria-label'], triggerName) : typeof button.label === 'string' ? button.label : undefined;
739
755
  const popover = usePopover({
740
756
  onHide: handleLayerHide,
741
757
  onShow: handleLayerShow,
@@ -0,0 +1,63 @@
1
+ /**
2
+ * @file InfoTip.tsx
3
+ * @input Uses React, StyleX, Tooltip, Icon, useComponentTranslator, the shared
4
+ * touch hit area, color/spacing/radius/duration/ease tokens
5
+ * @output Exports InfoTip component, InfoTipProps, InfoTipSize types
6
+ * @position Core implementation; consumed by index.ts, tested by
7
+ * InfoTip.test.tsx; `@astryxdesign/lab` re-exports it, deprecated
8
+ *
9
+ * SYNC: When modified, update these files to stay in sync:
10
+ * - /packages/core/src/InfoTip/InfoTip.doc.mjs (props table, features)
11
+ * - /docs/specs/components/InfoTip/InfoTip.spec.md (contract)
12
+ * - /packages/core/src/InfoTip/InfoTip.test.tsx (tests for new/changed behavior)
13
+ * - /packages/core/src/InfoTip/index.ts (exports if types change)
14
+ */
15
+ import { type ReactNode, type Ref } from 'react';
16
+ import type { BaseProps } from '../BaseProps.js';
17
+ import { type IconSize } from '../Icon/Icon.js';
18
+ /**
19
+ * Size of the info icon. Maps 1:1 to Icon sizes
20
+ * (xsm: 12px, sm: 16px, md: 20px, lg: 24px).
21
+ */
22
+ export type InfoTipSize = IconSize;
23
+ export interface InfoTipProps extends Pick<BaseProps, 'xstyle' | 'className' | 'style'> {
24
+ /** Ref forwarded to the info button. */
25
+ ref?: Ref<HTMLButtonElement>;
26
+ /**
27
+ * The help the button reveals. Short, noninteractive text; for links or
28
+ * buttons, use HoverCard.
29
+ */
30
+ content: ReactNode;
31
+ /**
32
+ * Accessible name of the button.
33
+ * @default A translated "More information"
34
+ */
35
+ label?: string;
36
+ /**
37
+ * Size of the info icon.
38
+ * @default 'sm'
39
+ */
40
+ size?: InfoTipSize;
41
+ }
42
+ /**
43
+ * An info icon that reveals help: a small "i" button. Hover and keyboard
44
+ * focus preview the help. A click, tap, Enter, or Space pins it open until
45
+ * Escape, a second press, a press outside, or focus leaving. Use it next to
46
+ * labels, values, and metrics for permission notes, metric definitions, and
47
+ * field help.
48
+ *
49
+ * InfoTip is Tooltip with `triggerBehavior="toggle"` on a named button: Tooltip
50
+ * opens, pins, announces, and closes the help. The info icon resolves from
51
+ * the icon registry, so themes can replace it.
52
+ *
53
+ * @example
54
+ * ```
55
+ * <InfoTip content="Editors can change this field; viewers cannot." />
56
+ * <InfoTip content="30-day rolling average." label="About this metric" />
57
+ * ```
58
+ */
59
+ export declare function InfoTip({ content, label, size, ref, xstyle, className, style, }: InfoTipProps): ReactNode;
60
+ export declare namespace InfoTip {
61
+ var displayName: string;
62
+ }
63
+ //# sourceMappingURL=InfoTip.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InfoTip.d.ts","sourceRoot":"","sources":["../../src/InfoTip/InfoTip.tsx"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;GAaG;AAEH,OAAO,EAAc,KAAK,SAAS,EAAE,KAAK,GAAG,EAAC,MAAM,OAAO,CAAC;AAG5D,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,cAAc,CAAC;AAE5C,OAAO,EAAO,KAAK,QAAQ,EAAC,MAAM,cAAc,CAAC;AAoBjD;;;GAGG;AACH,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;AAEnC,MAAM,WAAW,YAAa,SAAQ,IAAI,CACxC,SAAS,EACT,QAAQ,GAAG,WAAW,GAAG,OAAO,CACjC;IACC,wCAAwC;IACxC,GAAG,CAAC,EAAE,GAAG,CAAC,iBAAiB,CAAC,CAAC;IAC7B;;;OAGG;IACH,OAAO,EAAE,SAAS,CAAC;IACnB;;;OAGG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAC;CACpB;AA8CD;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,OAAO,CAAC,EACtB,OAAO,EACP,KAAK,EACL,IAAW,EACX,GAAG,EACH,MAAM,EACN,SAAS,EACT,KAAK,GACN,EAAE,YAAY,GAAG,SAAS,CAyC1B;yBAjDe,OAAO"}
@@ -0,0 +1,126 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file InfoTip.tsx
7
+ * @input Uses React, StyleX, Tooltip, Icon, useComponentTranslator, the shared
8
+ * touch hit area, color/spacing/radius/duration/ease tokens
9
+ * @output Exports InfoTip component, InfoTipProps, InfoTipSize types
10
+ * @position Core implementation; consumed by index.ts, tested by
11
+ * InfoTip.test.tsx; `@astryxdesign/lab` re-exports it, deprecated
12
+ *
13
+ * SYNC: When modified, update these files to stay in sync:
14
+ * - /packages/core/src/InfoTip/InfoTip.doc.mjs (props table, features)
15
+ * - /docs/specs/components/InfoTip/InfoTip.spec.md (contract)
16
+ * - /packages/core/src/InfoTip/InfoTip.test.tsx (tests for new/changed behavior)
17
+ * - /packages/core/src/InfoTip/index.ts (exports if types change)
18
+ */
19
+ import { useCallback } from 'react';
20
+ import * as stylex from '@stylexjs/stylex';
21
+ import { useMergedRefs } from "../hooks/useMergedRefs.js";
22
+ import { Icon } from "../Icon/Icon.js";
23
+ import { Tooltip } from "../Tooltip/Tooltip.js";
24
+ import { registerEnglishFallback, useComponentTranslator } from "../i18n/useComponentTranslator.js";
25
+ import english from "../i18n/generated-english/InfoTip/InfoTip.generated.js";
26
+ import "../theme/tokens.stylex.js";
27
+ import { colorVars, durationVars, easeVars, radiusVars, spacingVars } from "../theme/tokens.stylex.js";
28
+ import { focusOutlineStyles } from "../utils/focusOutline.stylex.js";
29
+ import { mergeProps } from "../utils/mergeProps.js";
30
+ import { watchHitArea, writeHitInsets } from "../utils/hitArea.js";
31
+ import { jsx as _jsx } from "react/jsx-runtime";
32
+ registerEnglishFallback(english);
33
+
34
+ /**
35
+ * Size of the info icon. Maps 1:1 to Icon sizes
36
+ * (xsm: 12px, sm: 16px, md: 20px, lg: 24px).
37
+ */
38
+
39
+ const styles = {
40
+ trigger: {
41
+ kVAEAm: "x1n2onr6",
42
+ k1xSpc: "x3nfvp2",
43
+ kGNEyG: "x6s0dn4",
44
+ kjj79g: "xl56j7k",
45
+ kXLuUW: "xxymvpz",
46
+ kmVPX3: "x12nba7r",
47
+ kogj98: "x1ghz6dp",
48
+ ksu8eU: "xng3xce",
49
+ kWkggS: "xjbqb8w",
50
+ kaIpWk: "xjspbzw",
51
+ kkrTdU: "x1ypdohk x16khyan",
52
+ kMwMTN: "xv9yike x10ue8fs",
53
+ k1ekBW: "xt3l3uh",
54
+ kIyJzY: "xuedmi6",
55
+ kAMwcw: "xlr8y92",
56
+ $$css: true
57
+ },
58
+ hitArea: {
59
+ k5JduY: "x1s928wv",
60
+ kwXMNM: "x1j6awrg",
61
+ kv0HGH: "xzdy5ak",
62
+ $$css: true
63
+ }
64
+ };
65
+
66
+ /**
67
+ * An info icon that reveals help: a small "i" button. Hover and keyboard
68
+ * focus preview the help. A click, tap, Enter, or Space pins it open until
69
+ * Escape, a second press, a press outside, or focus leaving. Use it next to
70
+ * labels, values, and metrics for permission notes, metric definitions, and
71
+ * field help.
72
+ *
73
+ * InfoTip is Tooltip with `triggerBehavior="toggle"` on a named button: Tooltip
74
+ * opens, pins, announces, and closes the help. The info icon resolves from
75
+ * the icon registry, so themes can replace it.
76
+ *
77
+ * @example
78
+ * ```
79
+ * <InfoTip content="Editors can change this field; viewers cannot." />
80
+ * <InfoTip content="30-day rolling average." label="About this metric" />
81
+ * ```
82
+ */
83
+ export function InfoTip({
84
+ content,
85
+ label,
86
+ size = 'sm',
87
+ ref,
88
+ xstyle,
89
+ className,
90
+ style
91
+ }) {
92
+ const t = useComponentTranslator();
93
+ // Under a coarse pointer the button takes taps out toward 44 px. The watch
94
+ // lives as long as the button is attached: the ref's cleanup stops it, and a
95
+ // replaced button starts its own.
96
+ const watchButtonHitArea = useCallback(button => {
97
+ if (button == null) {
98
+ return;
99
+ }
100
+ return watchHitArea(button, insets => writeHitInsets(button, insets));
101
+ }, []);
102
+ const mergedRef = useMergedRefs(ref, watchButtonHitArea);
103
+
104
+ // No Escape handler of its own. Tooltip's entry in the shared dismissal
105
+ // stack takes Escape, so one press never closes both the help and an
106
+ // enclosing Dialog.
107
+ return /*#__PURE__*/_jsx(Tooltip, {
108
+ content: content
109
+ // The tooltip is the button's only purpose. A click, a tap, Enter, or
110
+ // Space pins it open, and the press stops at the button. So an InfoTip's
111
+ // content is reachable on a phone and from the keyboard alike.
112
+ ,
113
+ triggerBehavior: "toggle",
114
+ children: /*#__PURE__*/_jsx("button", {
115
+ ref: mergedRef,
116
+ type: "button",
117
+ "aria-label": label ?? t('@astryx.infoTip.label'),
118
+ ...mergeProps(stylex.props(focusOutlineStyles.focusVisible, styles.trigger, styles.hitArea, xstyle), className, style),
119
+ children: /*#__PURE__*/_jsx(Icon, {
120
+ icon: "info",
121
+ size: size
122
+ })
123
+ })
124
+ });
125
+ }
126
+ InfoTip.displayName = 'InfoTip';
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @file InfoTip component barrel export
3
+ * @input InfoTip.tsx
4
+ * @output Exports InfoTip, InfoTipProps, InfoTipSize
5
+ * @position Barrel; consumed by packages/core/src/index.ts and the
6
+ * `@astryxdesign/core/InfoTip` entry
7
+ */
8
+ export { InfoTip } from './InfoTip.js';
9
+ export type { InfoTipProps, InfoTipSize } from './InfoTip.js';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/InfoTip/index.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,EAAC,OAAO,EAAC,MAAM,WAAW,CAAC;AAClC,YAAY,EAAC,YAAY,EAAE,WAAW,EAAC,MAAM,WAAW,CAAC"}
@@ -0,0 +1,12 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file InfoTip component barrel export
7
+ * @input InfoTip.tsx
8
+ * @output Exports InfoTip, InfoTipProps, InfoTipSize
9
+ * @position Barrel; consumed by packages/core/src/index.ts and the
10
+ * `@astryxdesign/core/InfoTip` entry
11
+ */
12
+ export { InfoTip } from "./InfoTip.js";
@@ -2,7 +2,7 @@
2
2
  * @file layerClickBoundary.ts
3
3
  * @input React pointer, mouse, touch and click events on a layer root
4
4
  * @output Exports layerClickBoundary, the props every layer content root
5
- * spreads, including the layer-root mark
5
+ * spreads, including the layer-root mark; also stopInReactTree
6
6
  * @position Internal to Layer; used by useLayer's renderers and the Dialog,
7
7
  * Drawer, Lightbox, MobileNav, BottomSheetPanel and ToastViewport roots.
8
8
  * Not exported from the package.
@@ -21,6 +21,12 @@ declare const BOUNDARY_EVENTS: readonly ["onClick", "onAuxClick", "onDoubleClick
21
21
  type BoundaryEvent = (typeof BOUNDARY_EVENTS)[number];
22
22
  type Handler = (event: SyntheticEvent) => void;
23
23
  export type LayerClickBoundaryProps = Record<BoundaryEvent, Handler> & Readonly<Record<`data-${string}`, string>>;
24
+ /**
25
+ * Stop a synthetic event at this element for the rest of the React tree only.
26
+ * React's dispatch asks `isPropagationStopped()` before each further
27
+ * listener; the native event is left alone.
28
+ */
29
+ export declare function stopInReactTree(event: SyntheticEvent): void;
24
30
  /**
25
31
  * The boundary props for a layer content root. Pass the root's own props
26
32
  * (its caller's rest props and its own handlers): for each boundary event, a
@@ -1 +1 @@
1
- {"version":3,"file":"layerClickBoundary.d.ts","sourceRoot":"","sources":["../../src/Layer/layerClickBoundary.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,OAAO,CAAC;AAG1C,uDAAuD;AACvD,QAAA,MAAM,eAAe,gWAsBX,CAAC;AAEX,KAAK,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AACtD,KAAK,OAAO,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAE/C,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,GAClE,QAAQ,CAAC,MAAM,CAAC,QAAQ,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AAa7C;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,GAC1C,uBAAuB,CAkBzB"}
1
+ {"version":3,"file":"layerClickBoundary.d.ts","sourceRoot":"","sources":["../../src/Layer/layerClickBoundary.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAC,cAAc,EAAC,MAAM,OAAO,CAAC;AAG1C,uDAAuD;AACvD,QAAA,MAAM,eAAe,gWAsBX,CAAC;AAEX,KAAK,aAAa,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC;AACtD,KAAK,OAAO,GAAG,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,CAAC;AAE/C,MAAM,MAAM,uBAAuB,GAAG,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,GAClE,QAAQ,CAAC,MAAM,CAAC,QAAQ,MAAM,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AAI7C;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,cAAc,GAAG,IAAI,CAE3D;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,GAAG,GAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAM,GAC1C,uBAAuB,CAkBzB"}
@@ -6,7 +6,7 @@
6
6
  * @file layerClickBoundary.ts
7
7
  * @input React pointer, mouse, touch and click events on a layer root
8
8
  * @output Exports layerClickBoundary, the props every layer content root
9
- * spreads, including the layer-root mark
9
+ * spreads, including the layer-root mark; also stopInReactTree
10
10
  * @position Internal to Layer; used by useLayer's renderers and the Dialog,
11
11
  * Drawer, Lightbox, MobileNav, BottomSheetPanel and ToastViewport roots.
12
12
  * Not exported from the package.
@@ -30,7 +30,7 @@ const returnTrue = () => true;
30
30
  * React's dispatch asks `isPropagationStopped()` before each further
31
31
  * listener; the native event is left alone.
32
32
  */
33
- function stopInReactTree(event) {
33
+ export function stopInReactTree(event) {
34
34
  event.isPropagationStopped = returnTrue;
35
35
  }
36
36
 
@@ -0,0 +1,27 @@
1
+ /**
2
+ * @file useBackdropPress.ts
3
+ * @input A modal layer's backdrop dismissal and whether it is allowed now
4
+ * @output Capture-phase pointer handlers and a click handler for the layer's
5
+ * <dialog> root
6
+ * @position Shared backdrop-press rule for Dialog and Drawer
7
+ */
8
+ import { type PointerEvent, type MouseEvent } from 'react';
9
+ export interface BackdropPressHandlers {
10
+ onPointerDownCapture: (event: PointerEvent<HTMLElement>) => void;
11
+ onPointerUpCapture: (event: PointerEvent<HTMLElement>) => void;
12
+ onPointerCancelCapture: (event: PointerEvent<HTMLElement>) => void;
13
+ onClick: (event: MouseEvent<HTMLElement>) => void;
14
+ }
15
+ /**
16
+ * A press on a modal layer's backdrop targets the <dialog> root itself. A
17
+ * click there is also what the browser sends when a press starts on one side
18
+ * of the layer's edge and ends on the other (it goes to the nearest common
19
+ * ancestor), so a backdrop press dismisses only when its pointer-down and its
20
+ * pointer-up both landed on the backdrop. A cancelled pointer ends the press.
21
+ *
22
+ * The pointer handlers run in the capture phase. A nested layer, such as a
23
+ * popover open in the dialog, stops its presses at its own root, so a
24
+ * bubble-phase handler here does not see them.
25
+ */
26
+ export declare function useBackdropPress(onBackdropPress: () => void, isEnabled: boolean): BackdropPressHandlers;
27
+ //# sourceMappingURL=useBackdropPress.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useBackdropPress.d.ts","sourceRoot":"","sources":["../../src/Layer/useBackdropPress.ts"],"names":[],"mappings":"AAIA;;;;;;GAMG;AAEH,OAAO,EAAsB,KAAK,YAAY,EAAE,KAAK,UAAU,EAAC,MAAM,OAAO,CAAC;AAE9E,MAAM,WAAW,qBAAqB;IACpC,oBAAoB,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACjE,kBAAkB,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IAC/D,sBAAsB,EAAE,CAAC,KAAK,EAAE,YAAY,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;IACnE,OAAO,EAAE,CAAC,KAAK,EAAE,UAAU,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;CACnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAC9B,eAAe,EAAE,MAAM,IAAI,EAC3B,SAAS,EAAE,OAAO,GACjB,qBAAqB,CA6CvB"}
@@ -0,0 +1,53 @@
1
+ // Copyright (c) Meta Platforms, Inc. and affiliates.
2
+
3
+ 'use client';
4
+
5
+ /**
6
+ * @file useBackdropPress.ts
7
+ * @input A modal layer's backdrop dismissal and whether it is allowed now
8
+ * @output Capture-phase pointer handlers and a click handler for the layer's
9
+ * <dialog> root
10
+ * @position Shared backdrop-press rule for Dialog and Drawer
11
+ */
12
+ import { useCallback, useRef } from 'react';
13
+ /**
14
+ * A press on a modal layer's backdrop targets the <dialog> root itself. A
15
+ * click there is also what the browser sends when a press starts on one side
16
+ * of the layer's edge and ends on the other (it goes to the nearest common
17
+ * ancestor), so a backdrop press dismisses only when its pointer-down and its
18
+ * pointer-up both landed on the backdrop. A cancelled pointer ends the press.
19
+ *
20
+ * The pointer handlers run in the capture phase. A nested layer, such as a
21
+ * popover open in the dialog, stops its presses at its own root, so a
22
+ * bubble-phase handler here does not see them.
23
+ */
24
+ export function useBackdropPress(onBackdropPress, isEnabled) {
25
+ const startedOnBackdropRef = useRef(false);
26
+ const endedOnBackdropRef = useRef(false);
27
+ const onPointerDownCapture = useCallback(event => {
28
+ startedOnBackdropRef.current = event.target === event.currentTarget;
29
+ endedOnBackdropRef.current = false;
30
+ }, []);
31
+ const onPointerUpCapture = useCallback(event => {
32
+ endedOnBackdropRef.current = startedOnBackdropRef.current && event.target === event.currentTarget;
33
+ startedOnBackdropRef.current = false;
34
+ }, []);
35
+ const onPointerCancelCapture = useCallback(() => {
36
+ startedOnBackdropRef.current = false;
37
+ endedOnBackdropRef.current = false;
38
+ }, []);
39
+ const onClick = useCallback(event => {
40
+ const pressWasOnBackdrop = endedOnBackdropRef.current;
41
+ startedOnBackdropRef.current = false;
42
+ endedOnBackdropRef.current = false;
43
+ if (isEnabled && pressWasOnBackdrop && event.target === event.currentTarget) {
44
+ onBackdropPress();
45
+ }
46
+ }, [isEnabled, onBackdropPress]);
47
+ return {
48
+ onPointerDownCapture,
49
+ onPointerUpCapture,
50
+ onPointerCancelCapture,
51
+ onClick
52
+ };
53
+ }