@atlaskit/top-layer 0.17.0 → 0.18.0

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 (132) hide show
  1. package/AGENTS.md +113 -0
  2. package/CHANGELOG.md +7 -0
  3. package/animations/package.json +1 -8
  4. package/dialog/package.json +1 -8
  5. package/dialog-scroll-lock/package.json +1 -8
  6. package/dist/cjs/dialog/dialog-content.js +12 -30
  7. package/dist/cjs/internal/set-style.js +5 -5
  8. package/dist/cjs/internal/slot.js +1 -1
  9. package/dist/cjs/internal/use-anchor-position-at-point.js +8 -8
  10. package/dist/cjs/internal/use-anchor-position.js +19 -40
  11. package/dist/cjs/internal/use-animated-visibility.js +31 -61
  12. package/dist/cjs/internal/use-initial-focus.js +9 -13
  13. package/dist/cjs/internal/use-width-from-anchor.js +6 -6
  14. package/dist/cjs/popover/popover.js +30 -58
  15. package/dist/cjs/popover-surface/popover-surface.js +4 -3
  16. package/dist/cjs/testing/polyfill.js +9 -9
  17. package/dist/cjs/use-simple-light-dismiss/index.js +3 -3
  18. package/dist/es2019/dialog/dialog-content.js +12 -30
  19. package/dist/es2019/internal/set-style.js +5 -5
  20. package/dist/es2019/internal/slot.js +1 -1
  21. package/dist/es2019/internal/use-anchor-position-at-point.js +8 -8
  22. package/dist/es2019/internal/use-anchor-position.js +19 -40
  23. package/dist/es2019/internal/use-animated-visibility.js +31 -61
  24. package/dist/es2019/internal/use-initial-focus.js +9 -13
  25. package/dist/es2019/internal/use-width-from-anchor.js +6 -6
  26. package/dist/es2019/popover/popover.js +30 -58
  27. package/dist/es2019/popover-surface/popover-surface.js +1 -1
  28. package/dist/es2019/testing/polyfill.js +7 -11
  29. package/dist/es2019/use-simple-light-dismiss/index.js +3 -3
  30. package/dist/esm/dialog/dialog-content.js +12 -30
  31. package/dist/esm/internal/set-style.js +5 -5
  32. package/dist/esm/internal/slot.js +1 -1
  33. package/dist/esm/internal/use-anchor-position-at-point.js +8 -8
  34. package/dist/esm/internal/use-anchor-position.js +19 -40
  35. package/dist/esm/internal/use-animated-visibility.js +31 -61
  36. package/dist/esm/internal/use-initial-focus.js +9 -13
  37. package/dist/esm/internal/use-width-from-anchor.js +6 -6
  38. package/dist/esm/popover/popover.js +30 -58
  39. package/dist/esm/popover-surface/popover-surface.js +1 -1
  40. package/dist/esm/testing/polyfill.js +9 -9
  41. package/dist/esm/use-simple-light-dismiss/index.js +3 -3
  42. package/dist/types/internal/set-style.d.ts +2 -2
  43. package/dist/types/internal/slot.d.ts +2 -2
  44. package/dist/types/internal/use-anchor-position-at-point.d.ts +2 -2
  45. package/dist/types/internal/use-anchor-position.d.ts +0 -4
  46. package/dist/types/internal/use-initial-focus.d.ts +1 -1
  47. package/dist/types/popover/types.d.ts +5 -7
  48. package/dist/types/popover-surface/popover-surface.d.ts +2 -2
  49. package/focus/package.json +1 -8
  50. package/get-aria-for-trigger/package.json +1 -8
  51. package/open-layer-observer/package.json +1 -8
  52. package/package.json +1 -1
  53. package/placement-map/package.json +1 -8
  54. package/popover/package.json +1 -8
  55. package/popover-surface/package.json +1 -8
  56. package/testing/polyfill/package.json +1 -8
  57. package/testing/to-be-visible/package.json +1 -8
  58. package/use-anchor-position/package.json +1 -8
  59. package/use-anchor-position-at-point/package.json +1 -8
  60. package/use-arrow-navigation/package.json +1 -8
  61. package/use-popover-id/package.json +1 -8
  62. package/use-simple-light-dismiss/package.json +1 -8
  63. package/use-width-from-anchor/package.json +1 -8
  64. package/dist/types-ts4.5/animations/presets.d.ts +0 -110
  65. package/dist/types-ts4.5/animations/types.d.ts +0 -38
  66. package/dist/types-ts4.5/dialog/create-close-event.d.ts +0 -23
  67. package/dist/types-ts4.5/dialog/dialog-content.d.ts +0 -24
  68. package/dist/types-ts4.5/dialog/index.d.ts +0 -3
  69. package/dist/types-ts4.5/dialog/types.d.ts +0 -126
  70. package/dist/types-ts4.5/dialog-scroll-lock/index.d.ts +0 -40
  71. package/dist/types-ts4.5/entry-points/animations.d.ts +0 -2
  72. package/dist/types-ts4.5/entry-points/dialog-scroll-lock.d.ts +0 -1
  73. package/dist/types-ts4.5/entry-points/dialog.d.ts +0 -2
  74. package/dist/types-ts4.5/entry-points/focus.d.ts +0 -4
  75. package/dist/types-ts4.5/entry-points/get-aria-for-trigger.d.ts +0 -1
  76. package/dist/types-ts4.5/entry-points/open-layer-observer.d.ts +0 -5
  77. package/dist/types-ts4.5/entry-points/placement-map.d.ts +0 -3
  78. package/dist/types-ts4.5/entry-points/popover-surface.d.ts +0 -2
  79. package/dist/types-ts4.5/entry-points/popover.d.ts +0 -2
  80. package/dist/types-ts4.5/entry-points/use-anchor-position-at-point.d.ts +0 -1
  81. package/dist/types-ts4.5/entry-points/use-anchor-position.d.ts +0 -1
  82. package/dist/types-ts4.5/entry-points/use-arrow-navigation.d.ts +0 -3
  83. package/dist/types-ts4.5/entry-points/use-popover-id.d.ts +0 -11
  84. package/dist/types-ts4.5/entry-points/use-simple-light-dismiss.d.ts +0 -2
  85. package/dist/types-ts4.5/entry-points/use-width-from-anchor.d.ts +0 -1
  86. package/dist/types-ts4.5/focus/get-first-focusable.d.ts +0 -8
  87. package/dist/types-ts4.5/focus/get-focusables.d.ts +0 -13
  88. package/dist/types-ts4.5/focus/get-last-focusable.d.ts +0 -8
  89. package/dist/types-ts4.5/focus/get-next-focusable.d.ts +0 -13
  90. package/dist/types-ts4.5/focus/is-in-same-layer.d.ts +0 -8
  91. package/dist/types-ts4.5/focus/is-nested-layer-focused.d.ts +0 -8
  92. package/dist/types-ts4.5/focus/selectors.d.ts +0 -4
  93. package/dist/types-ts4.5/focus/types.d.ts +0 -5
  94. package/dist/types-ts4.5/index.d.ts +0 -0
  95. package/dist/types-ts4.5/internal/anchor-positioning-fallback.d.ts +0 -26
  96. package/dist/types-ts4.5/internal/combine.d.ts +0 -14
  97. package/dist/types-ts4.5/internal/ensure-preset-styles.d.ts +0 -6
  98. package/dist/types-ts4.5/internal/get-aria-for-trigger.d.ts +0 -93
  99. package/dist/types-ts4.5/internal/placement-to-position-area.d.ts +0 -21
  100. package/dist/types-ts4.5/internal/placement-to-try-fallbacks.d.ts +0 -36
  101. package/dist/types-ts4.5/internal/reduced-motion.d.ts +0 -14
  102. package/dist/types-ts4.5/internal/resolve-css-length-to-pixels.d.ts +0 -20
  103. package/dist/types-ts4.5/internal/resolve-css-length.d.ts +0 -8
  104. package/dist/types-ts4.5/internal/resolve-placement.d.ts +0 -58
  105. package/dist/types-ts4.5/internal/role-to-aria-has-popup.d.ts +0 -13
  106. package/dist/types-ts4.5/internal/role-types.d.ts +0 -71
  107. package/dist/types-ts4.5/internal/set-style.d.ts +0 -11
  108. package/dist/types-ts4.5/internal/should-focus-into-popover.d.ts +0 -8
  109. package/dist/types-ts4.5/internal/slot.d.ts +0 -29
  110. package/dist/types-ts4.5/internal/use-anchor-position-at-point.d.ts +0 -67
  111. package/dist/types-ts4.5/internal/use-anchor-position.d.ts +0 -91
  112. package/dist/types-ts4.5/internal/use-animated-visibility.d.ts +0 -109
  113. package/dist/types-ts4.5/internal/use-animation-preset.d.ts +0 -11
  114. package/dist/types-ts4.5/internal/use-focus-wrap.d.ts +0 -25
  115. package/dist/types-ts4.5/internal/use-initial-focus.d.ts +0 -73
  116. package/dist/types-ts4.5/internal/use-preset-styles.d.ts +0 -15
  117. package/dist/types-ts4.5/internal/use-width-from-anchor.d.ts +0 -21
  118. package/dist/types-ts4.5/placement-map/index.d.ts +0 -51
  119. package/dist/types-ts4.5/placement-map/legacy-placements.d.ts +0 -27
  120. package/dist/types-ts4.5/placement-map/placement-mapping.d.ts +0 -13
  121. package/dist/types-ts4.5/popover/create-close-event.d.ts +0 -25
  122. package/dist/types-ts4.5/popover/index.d.ts +0 -3
  123. package/dist/types-ts4.5/popover/popover.d.ts +0 -17
  124. package/dist/types-ts4.5/popover/types.d.ts +0 -193
  125. package/dist/types-ts4.5/popover-surface/index.d.ts +0 -2
  126. package/dist/types-ts4.5/popover-surface/popover-surface.d.ts +0 -21
  127. package/dist/types-ts4.5/testing/polyfill.d.ts +0 -25
  128. package/dist/types-ts4.5/testing/to-be-visible.d.ts +0 -23
  129. package/dist/types-ts4.5/use-arrow-navigation/index.d.ts +0 -3
  130. package/dist/types-ts4.5/use-arrow-navigation/is-at-current-menu-level.d.ts +0 -48
  131. package/dist/types-ts4.5/use-arrow-navigation/use-arrow-navigation.d.ts +0 -102
  132. package/dist/types-ts4.5/use-simple-light-dismiss/index.d.ts +0 -45
@@ -134,8 +134,6 @@ function getInitialFocusTarget(_ref2) {
134
134
  });
135
135
  }
136
136
  if (role === 'menu') {
137
- // ARIA Combobox Pattern: if the popup is owned by a focused combobox,
138
- // leave focus on the textbox. Navigation is proxied via the combobox.
139
137
  if (isComboboxControllingPopup({
140
138
  container: container
141
139
  })) {
@@ -152,9 +150,9 @@ function getInitialFocusTarget(_ref2) {
152
150
  });
153
151
  }
154
152
  if (role === 'listbox') {
155
- // ARIA Combobox Pattern: if the popup is owned by a focused
156
- // combobox-like textbox (in-popup or external e.g. react-select),
157
- // leave focus on the textbox. Navigation is proxied via the combobox.
153
+ // ARIA Combobox Pattern: if a combobox-like textbox owns the popup
154
+ // (in-popup or external e.g. react-select), leave focus on the
155
+ // textbox - navigation is proxied through it.
158
156
  if (isComboboxControllingPopup({
159
157
  container: container
160
158
  })) {
@@ -216,7 +214,7 @@ function getInitialFocusTarget(_ref2) {
216
214
  * `<dialog>.close()`. If the consumer reopens before the exit transition
217
215
  * has settled, the phase machine jumps `exiting → entering` without
218
216
  * passing through `closed`, so without this branch the popup would be
219
- * visible again with focus stranded on the trigger — a keyboard usability
217
+ * visible again with focus stranded on the trigger - a keyboard usability
220
218
  * gap for menu/dialog/listbox roles.
221
219
  *
222
220
  * Note: there is a rare programmatic path where a consumer flips `isOpen`
@@ -257,22 +255,20 @@ function useInitialFocus(_ref3) {
257
255
  var prevPhase = prevPhaseRef.current;
258
256
  prevPhaseRef.current = phase;
259
257
 
260
- // Skip the `phase === 'closed'` transitions (host is going away,
261
- // nothing to focus) and any transition whose previous phase was
262
- // neither `'closed'` (fresh open) nor `'exiting'` (mid-exit
263
- // reopen, focus already on the trigger).
258
+ // Only focus on transitions into a visible phase from `'closed'`
259
+ // (fresh open) or `'exiting'` (mid-exit reopen).
264
260
  if (phase === 'closed') {
265
261
  return;
266
262
  }
267
263
  if (prevPhase !== 'closed' && prevPhase !== 'exiting') {
268
264
  return;
269
265
  }
270
- var el = elementRef.current;
271
- if (!el) {
266
+ var element = elementRef.current;
267
+ if (!element) {
272
268
  return;
273
269
  }
274
270
  (_getInitialFocusTarge = getInitialFocusTarget({
275
- container: el,
271
+ container: element,
276
272
  role: role
277
273
  })) === null || _getInitialFocusTarge === void 0 || _getInitialFocusTarge.focus();
278
274
  }, [elementRef, phase, role]);
@@ -40,7 +40,7 @@ function useWidthFromAnchor(_ref) {
40
40
  // explicit width constraint, allowing the popover to grow past the anchor's width.
41
41
  if (supportsAnchorSize) {
42
42
  return (0, _setStyle.setStyle)({
43
- el: node,
43
+ element: node,
44
44
  styles: [{
45
45
  property: 'width',
46
46
  value: 'anchor-size(width)'
@@ -52,7 +52,7 @@ function useWidthFromAnchor(_ref) {
52
52
  var anchor = anchorRef.current;
53
53
  if (anchor) {
54
54
  return (0, _setStyle.setStyle)({
55
- el: node,
55
+ element: node,
56
56
  styles: [{
57
57
  property: 'width',
58
58
  value: "".concat(anchor.offsetWidth, "px")
@@ -74,7 +74,7 @@ function useWidthFromAnchor(_ref) {
74
74
  // if its content requires it.
75
75
  if (supportsAnchorSize) {
76
76
  return (0, _setStyle.setStyle)({
77
- el: node,
77
+ element: node,
78
78
  styles: [minInlineSizeStyle, {
79
79
  property: 'min-width',
80
80
  value: 'anchor-size(width)'
@@ -84,7 +84,7 @@ function useWidthFromAnchor(_ref) {
84
84
  var _anchor = anchorRef.current;
85
85
  if (_anchor) {
86
86
  return (0, _setStyle.setStyle)({
87
- el: node,
87
+ element: node,
88
88
  styles: [minInlineSizeStyle, {
89
89
  property: 'min-width',
90
90
  value: "".concat(_anchor.offsetWidth, "px")
@@ -94,14 +94,14 @@ function useWidthFromAnchor(_ref) {
94
94
 
95
95
  // No anchor available in JS fallback - still apply min-inline-size.
96
96
  return (0, _setStyle.setStyle)({
97
- el: node,
97
+ element: node,
98
98
  styles: [minInlineSizeStyle]
99
99
  });
100
100
  }
101
101
 
102
102
  // 'none' mode: no explicit width, but still apply `min-inline-size: max-content`.
103
103
  return (0, _setStyle.setStyle)({
104
- el: node,
104
+ element: node,
105
105
  styles: [minInlineSizeStyle]
106
106
  });
107
107
  }, [mode, popoverRef, anchorRef, isOpen]);
@@ -30,9 +30,9 @@ var supportsPopoverHint = (0, _once.default)(function () {
30
30
  return false;
31
31
  }
32
32
  // eslint-disable-next-line @atlaskit/platform/no-direct-document-usage -- feature detection
33
- var el = document.createElement('div');
34
- el.setAttribute('popover', 'hint');
35
- return el.popover === 'hint';
33
+ var element = document.createElement('div');
34
+ element.setAttribute('popover', 'hint');
35
+ return element.popover === 'hint';
36
36
  });
37
37
 
38
38
  // eslint-disable-next-line @atlaskit/ui-styling-standard/no-unsafe-values -- popover UA reset requires values not in cssMap's type union
@@ -75,9 +75,7 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
75
75
  var autoId = (0, _react.useId)();
76
76
  var ownRef = (0, _react.useRef)(null);
77
77
  var combinedRef = (0, _mergeRefs.default)([ownRef, ref].filter(Boolean));
78
- // React 18 `useId()` returns IDs with colons (invalid in CSS selectors
79
- // and popover target attributes). Strip them; remove once React 18 is
80
- // dropped (React 19.2 uses underscores).
78
+ // `useId()` colons are invalid in CSS selectors and popover target attributes.
81
79
  var popoverId = idProp !== null && idProp !== void 0 ? idProp : "popover-".concat(autoId.replace(/:/g, ''));
82
80
  var _useAnimatedVisibilit = (0, _useAnimatedVisibility.useAnimatedVisibility)({
83
81
  isOpen: isOpen,
@@ -89,21 +87,15 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
89
87
  phase = _useAnimatedVisibilit.phase,
90
88
  preset = _useAnimatedVisibilit.preset;
91
89
 
92
- // Pre-computed phase predicate. `isVisible` mirrors "host element is
93
- // mounted and on screen" (any phase except `closed`); used as a dep
94
- // signal for listener-re-bind effects so they re-attach to the fresh
95
- // host element after a close → reopen unmount/remount cycle.
90
+ // True while the host element is mounted (any phase except `closed`).
91
+ // Used as a dep so listener-rebind effects re-attach after a remount.
96
92
  var isVisible = phase !== 'closed';
97
93
 
98
94
  // Focus management: initial focus on entry (role-dependent), Tab cycling
99
95
  // for dialog roles. Restoration is native for outermost popovers; nested
100
- // focus-capturing roles are handled below via `beforetoggle` snapshot.
101
- // See: notes/architecture/focus-restoration.md
102
- //
103
- // Both hooks take `phase` directly: `useFocusWrap` keeps its listener
104
- // attached while `phase !== 'closed'` (so focus stays trapped through
105
- // the animated-exit window — WCAG 2.4.3 regression guard);
106
- // `useInitialFocus` moves focus on the transition into `'open'`.
96
+ // focus-capturing roles are handled below via the `beforetoggle` snapshot.
97
+ // Passing `phase` keeps `useFocusWrap` attached through the animated-exit
98
+ // window (WCAG 2.4.3 guard). See notes/architecture/focus-restoration.md.
107
99
  (0, _useFocusWrap.useFocusWrap)({
108
100
  elementRef: ownRef,
109
101
  role: role,
@@ -200,7 +192,6 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
200
192
 
201
193
  // Browser dismiss (Escape/click-outside).
202
194
  var reason = closeReasonRef.current;
203
- // reset for next dismiss
204
195
  closeReasonRef.current = 'light-dismiss';
205
196
  // Optional: `manual` mode has no `onClose` in the forwarded type.
206
197
  onClose === null || onClose === void 0 || onClose({
@@ -209,21 +200,12 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
209
200
  }
210
201
  }, [onClose, onOpenChange, role]);
211
202
 
212
- // Bind toggle/beforetoggle/keydown listeners via `useLayoutEffect` so
213
- // they are attached BEFORE the show/hide layout effect calls
214
- // `el.showPopover()`. `showPopover()` dispatches `beforetoggle`
215
- // synchronously; binding the listener in a regular `useEffect`
216
- // (which runs after layout effects) misses that first dispatch and
217
- // the `previouslyFocusedElementRef` snapshot never gets taken — which
218
- // breaks nested-popover focus restoration on close.
219
- //
220
- // `isVisible` is in deps so the listeners re-bind to the new host
221
- // element after a host unmount/remount cycle. The cleanup detaches
222
- // the old listeners.
223
- //
224
- // This layout effect MUST appear in the file before the show/hide
225
- // layout effect — React runs layout effects in source order on the
226
- // same commit, and we need listeners attached first.
203
+ // Bind via `useLayoutEffect`, and BEFORE the show/hide layout effect
204
+ // below, so listeners are attached when `showPopover()` synchronously
205
+ // dispatches `beforetoggle`. A regular `useEffect` would miss that
206
+ // first dispatch, dropping the `previouslyFocusedElementRef` snapshot
207
+ // and breaking nested-popover focus restoration on close. React runs
208
+ // layout effects in source order on the same commit.
227
209
  (0, _react.useLayoutEffect)(function () {
228
210
  var element = ownRef.current;
229
211
  if (!element) {
@@ -259,13 +241,10 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
259
241
  }, [handleToggle, handleBeforeToggle, isVisible]);
260
242
 
261
243
  // Placement-dependent animation CSS vars. Kept separate from show/hide
262
- // so preset reference changes do not re-trigger visibility. `isVisible`
263
- // is in deps so the CSS vars are re-applied to the new host element after
264
- // a remount cycle (otherwise the freshly mounted element would have no
265
- // transform / placement vars set).
244
+ // so preset reference changes do not re-trigger visibility.
266
245
  (0, _react.useLayoutEffect)(function () {
267
- var el = ownRef.current;
268
- if (!el || !(preset !== null && preset !== void 0 && preset.getProperties) || !placement) {
246
+ var element = ownRef.current;
247
+ if (!element || !(preset !== null && preset !== void 0 && preset.getProperties) || !placement) {
269
248
  return;
270
249
  }
271
250
  var props = preset.getProperties({
@@ -275,7 +254,7 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
275
254
  var _ref3 = (0, _slicedToArray2.default)(_ref2, 2),
276
255
  key = _ref3[0],
277
256
  value = _ref3[1];
278
- el.style.setProperty(key, String(value));
257
+ element.style.setProperty(key, String(value));
279
258
  });
280
259
  }, [preset, placement, isVisible]);
281
260
 
@@ -283,42 +262,35 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
283
262
  // already in the target state. Try/catch guards `InvalidStateError` on
284
263
  // disconnected elements (StrictMode/concurrent/unmount edge cases).
285
264
  (0, _react.useLayoutEffect)(function () {
286
- var el = ownRef.current;
287
- if (!el) {
265
+ var element = ownRef.current;
266
+ if (!element) {
288
267
  return;
289
268
  }
290
269
  if (isOpen) {
291
270
  programmaticCloseRef.current = false;
292
- // Reset the close-reason snapshot at the start of every open
293
- // cycle. The ref outlives the host element (lives on the
294
- // component, not the DOM), so a stale 'escape' from a prior
295
- // cycle would otherwise leak into the next close — especially
296
- // in the no-animation path where the host unmounts before
297
- // `handleToggle` has a chance to reset the ref itself.
271
+ // Clear stale 'escape' from a prior cycle: the ref outlives
272
+ // the host element, and the no-animation path unmounts before
273
+ // `handleToggle` can reset it.
298
274
  closeReasonRef.current = 'light-dismiss';
299
275
  try {
300
- el.showPopover();
276
+ element.showPopover();
301
277
  } catch (_unused) {}
302
278
  return function () {
303
279
  programmaticCloseRef.current = true;
304
280
  try {
305
- el.hidePopover();
281
+ element.hidePopover();
306
282
  } catch (_unused2) {}
307
283
  };
308
284
  }
309
285
  programmaticCloseRef.current = true;
310
286
  try {
311
- el.hidePopover();
287
+ element.hidePopover();
312
288
  } catch (_unused3) {}
313
289
  }, [isOpen]);
314
290
 
315
- // The host element is only rendered while the popover is open or its exit
316
- // animation is playing. Once the phase returns to `closed`, we unmount
317
- // the host entirely so it does not leave an empty `role="..."` /
318
- // `popover` element in the accessibility tree. The element re-mounts on
319
- // the next `isOpen=true` commit; refs and event listeners re-bind via
320
- // the existing layout effect and `useEffect`. The popover `id` is stable
321
- // across opens (derived from `useId()` or the consumer-supplied `idProp`).
291
+ // Unmount the host once exit completes so it does not leave an empty
292
+ // `role`/`popover` element in the accessibility tree. The element
293
+ // remounts on the next open; the `popoverId` is stable across opens.
322
294
  if (!isVisible) {
323
295
  return null;
324
296
  }
@@ -1,14 +1,15 @@
1
1
  /* popover-surface.tsx generated by @compiled/babel-plugin v0.39.1 */
2
2
  "use strict";
3
3
 
4
- var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _typeof = require("@babel/runtime/helpers/typeof");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
8
  exports.PopoverSurface = PopoverSurface;
9
9
  require("./popover-surface.compiled.css");
10
+ var React = _interopRequireWildcard(require("react"));
10
11
  var _runtime = require("@compiled/react/runtime");
11
- var _react = _interopRequireDefault(require("react"));
12
+ function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); }
12
13
  var styles = {
13
14
  root: "_2rkofajl _1reo1wug _18m91wug _bfhk1bhr _16qs130s"
14
15
  };
@@ -27,7 +28,7 @@ var styles = {
27
28
  */
28
29
  function PopoverSurface(_ref) {
29
30
  var children = _ref.children;
30
- return /*#__PURE__*/_react.default.createElement("div", {
31
+ return /*#__PURE__*/React.createElement("div", {
31
32
  className: (0, _runtime.ax)([styles.root])
32
33
  }, children);
33
34
  }
@@ -354,17 +354,17 @@ function isInChainTo(_ref12) {
354
354
  function hidePopoversInStackNotInChainTo(_ref13) {
355
355
  var stack = _ref13.stack,
356
356
  target = _ref13.target;
357
- var snapshot = stack.slice();
358
- for (var i = snapshot.length - 1; i >= 0; i -= 1) {
359
- var popover = snapshot[i];
360
- if (isInChainTo({
357
+ var snapshot = stack.slice().reverse();
358
+ var stopIndex = snapshot.findIndex(function (popover) {
359
+ return isInChainTo({
361
360
  candidate: popover,
362
361
  target: target
363
- })) {
364
- break;
365
- }
366
- popover.hidePopover();
367
- }
362
+ });
363
+ });
364
+ var toHide = stopIndex === -1 ? snapshot : snapshot.slice(0, stopIndex);
365
+ toHide.forEach(function (popover) {
366
+ return popover.hidePopover();
367
+ });
368
368
  }
369
369
 
370
370
  // Two-phase light-dismiss: pointerdown stores the nearest open popover for
@@ -59,13 +59,13 @@ function useSimpleLightDismiss(_ref) {
59
59
  var unbindClickOutside = (0, _bindEventListener.bind)(document, {
60
60
  type: 'click',
61
61
  listener: function listener(event) {
62
- var el = popoverRef.current;
63
- if (!el) {
62
+ var element = popoverRef.current;
63
+ if (!element) {
64
64
  return;
65
65
  }
66
66
 
67
67
  // If the click target is inside the popover, do not dismiss.
68
- if (event.target instanceof Node && el.contains(event.target)) {
68
+ if (event.target instanceof Node && element.contains(event.target)) {
69
69
  return;
70
70
  }
71
71
  onCloseRef.current({
@@ -48,8 +48,6 @@ export const Dialog = /*#__PURE__*/forwardRef(function Dialog({
48
48
  const dialogId = providedId !== null && providedId !== void 0 ? providedId : generatedId;
49
49
  const ownRef = useRef(null);
50
50
  const combinedRef = mergeRefs([ownRef, ref]);
51
-
52
- // Animation lifecycle
53
51
  const {
54
52
  phase,
55
53
  preset
@@ -60,31 +58,22 @@ export const Dialog = /*#__PURE__*/forwardRef(function Dialog({
60
58
  onExitFinish
61
59
  });
62
60
 
63
- // Pre-computed phase predicate. `isVisible` means "host element is
64
- // mounted and on screen" (any phase except `closed`), used as a dep
65
- // signal for the backdrop-click rebind effect so it re-attaches to
66
- // the fresh <dialog> element after a close → reopen unmount/remount
67
- // cycle.
61
+ // True while the host element is mounted (any phase except `closed`).
62
+ // Used as a dep so listener-rebind effects re-attach after a remount.
68
63
  const isVisible = phase !== 'closed';
69
64
 
70
- // Focus wrap
71
- // Native <dialog>.showModal() traps focus but wraps through <body> at
72
- // the boundary (A → B → C → body → A). This hook intercepts Tab to
73
- // wrap directly (A → B → C → A), matching the WAI-ARIA APG pattern.
74
- //
75
- // Takes `phase` directly: the listener stays attached while
76
- // `phase !== 'closed'`, i.e. through the animated-exit window.
77
- // Gating on `isOpen` would unbind the listener at the start of an
78
- // exit animation while the dialog is still visible, letting focus
79
- // escape (WCAG 2.4.3 Focus Order regression).
65
+ // Native `<dialog>.showModal()` traps focus but wraps through `<body>` at
66
+ // the boundary (A → B → C → body → A). This hook intercepts Tab to wrap
67
+ // directly (A → B → C → A), matching the WAI-ARIA APG pattern. Passing
68
+ // `phase` keeps the listener attached through the animated-exit window
69
+ // (WCAG 2.4.3 Focus Order regression guard).
80
70
  useFocusWrap({
81
71
  elementRef: ownRef,
82
72
  role: 'dialog',
83
73
  phase
84
74
  });
85
75
 
86
- // Open layer observer registration
87
- // Notifies the open layer observer so app-coordination features
76
+ // Notify the open layer observer so app-coordination features
88
77
  // (open-count subscriptions) work with top-layer dialogs.
89
78
  useNotifyOpenLayerObserver({
90
79
  type: 'modal',
@@ -92,8 +81,6 @@ export const Dialog = /*#__PURE__*/forwardRef(function Dialog({
92
81
  // No-op: no current use case for programmatic close via OpenLayerObserver.
93
82
  onClose: noop
94
83
  });
95
-
96
- // Show/hide the dialog in response to isOpen changes.
97
84
  useLayoutEffect(() => {
98
85
  const dialog = ownRef.current;
99
86
  if (!dialog) {
@@ -151,15 +138,10 @@ export const Dialog = /*#__PURE__*/forwardRef(function Dialog({
151
138
  // any atomic class, so the override always wins.
152
139
  const escapedId = CSS.escape(dialogId);
153
140
 
154
- // The `<dialog>` host element is only rendered while open or its exit
155
- // animation is playing. After exit completes the phase returns to
156
- // `closed` and we unmount the dialog entirely so it does not leave an
157
- // empty `role="dialog"` element in the accessibility tree. The element
158
- // re-mounts on the next `isOpen=true` commit; `showModal()` is called
159
- // from the existing `useLayoutEffect([isOpen])` on that same commit,
160
- // and listeners (cancel, click) re-bind via the `[onClose, isVisible]`
161
- // effect re-running after remount (React clears the ref on unmount, so
162
- // we need the listener effect to re-run with the fresh element).
141
+ // Unmount the `<dialog>` once exit completes so it does not leave an
142
+ // empty `role="dialog"` element in the accessibility tree. On the next
143
+ // open the element remounts and the `[isOpen]` and `[onClose, isVisible]`
144
+ // effects re-run against the fresh element.
163
145
  if (!isVisible) {
164
146
  return null;
165
147
  }
@@ -3,7 +3,7 @@
3
3
  * restores the prior inline values (so we do not stomp consumer styles).
4
4
  */
5
5
  export function setStyle({
6
- el,
6
+ element,
7
7
  styles
8
8
  }) {
9
9
  // Snapshot the prior inline value (NOT the computed style - we only want
@@ -13,13 +13,13 @@ export function setStyle({
13
13
  property
14
14
  }) => ({
15
15
  property,
16
- value: el.style.getPropertyValue(property)
16
+ value: element.style.getPropertyValue(property)
17
17
  }));
18
18
  styles.forEach(({
19
19
  property,
20
20
  value
21
21
  }) => {
22
- el.style.setProperty(property, value);
22
+ element.style.setProperty(property, value);
23
23
  });
24
24
  return function cleanup() {
25
25
  priorValues.forEach(({
@@ -27,10 +27,10 @@ export function setStyle({
27
27
  value
28
28
  }) => {
29
29
  if (value === '') {
30
- el.style.removeProperty(property);
30
+ element.style.removeProperty(property);
31
31
  return;
32
32
  }
33
- el.style.setProperty(property, value);
33
+ element.style.setProperty(property, value);
34
34
  });
35
35
  };
36
36
  }
@@ -43,7 +43,7 @@ export const Slot = /*#__PURE__*/forwardRef(function Slot(slotProps, ref) {
43
43
  children: rawChildren,
44
44
  ...props
45
45
  } = slotProps;
46
- // `SlotProps` intersects `Record<string, unknown>`, so `children` is typed as `unknown`.
46
+ // `TSlotProps` intersects `Record<string, unknown>`, so `children` is typed as `unknown`.
47
47
  const children = rawChildren;
48
48
  if (!isSlotChild(children)) {
49
49
  return children;
@@ -6,7 +6,7 @@ import { useAnchorPosition } from './use-anchor-position';
6
6
  * anchor should be placed.
7
7
  *
8
8
  * Axis-named (`x`/`y`) rather than edge-named (`left`/`top`) so the
9
- * shape is unambiguous in RTL writing modes — there is no ambiguity
9
+ * shape is unambiguous in RTL writing modes - there is no ambiguity
10
10
  * about whether a coordinate is logical (`inline-start`/`block-start`)
11
11
  * or physical (`left`/`top`). Viewport coordinates are always
12
12
  * physical, so we name them with the physical axis labels.
@@ -17,19 +17,19 @@ import { useAnchorPosition } from './use-anchor-position';
17
17
  * Dynamic `inset-*` overrides are written by the positioning effect.
18
18
  *
19
19
  * Uses `Object.assign` rather than Compiled CSS (element is outside the React tree)
20
- * or the internal `setStyle` helper (we own this element entirely — it is created
21
- * and removed by this hook — so the snapshot/restore semantics `setStyle`
20
+ * or the internal `setStyle` helper (we own this element entirely - it is created
21
+ * and removed by this hook - so the snapshot/restore semantics `setStyle`
22
22
  * provides for caller-owned elements would be dead work here).
23
23
  */
24
- function applyStaticAnchorStyles(el) {
25
- Object.assign(el.style, {
24
+ function applyStaticAnchorStyles(element) {
25
+ Object.assign(element.style, {
26
26
  position: 'fixed',
27
27
  // `top`/`left` rather than `inset-block-start`/`inset-inline-start`
28
28
  // for consistency with the dynamic positioning effect below, which
29
29
  // uses physical properties (see comment there for the rationale).
30
30
  top: '0',
31
31
  left: '0',
32
- // Zero size — placement decides which side the popover sits on.
32
+ // Zero size - placement decides which side the popover sits on.
33
33
  width: '0',
34
34
  height: '0',
35
35
  // Prevent the overlay from intercepting pointer events.
@@ -75,7 +75,7 @@ export function useAnchorPositionAtPoint({
75
75
  const syntheticAnchorRef = useRef(null);
76
76
 
77
77
  // `getPoint` is kept in a ref so the layout effect can call the
78
- // latest version without listing it as a dep — that would re-fire
78
+ // latest version without listing it as a dep - that would re-fire
79
79
  // on every render and re-latch the point.
80
80
  const getPointRef = useRef(getPoint);
81
81
  getPointRef.current = getPoint;
@@ -111,7 +111,7 @@ export function useAnchorPositionAtPoint({
111
111
  };
112
112
  }, [isEnabled]);
113
113
 
114
- // Mirror `isEnabled` so both hooks stay in sync — when disabled,
114
+ // Mirror `isEnabled` so both hooks stay in sync - when disabled,
115
115
  // neither this hook nor the inner one touches the popover, leaving
116
116
  // any other positioning the consumer has set up free to take effect.
117
117
  useAnchorPosition({