@atlaskit/top-layer 0.12.2 → 0.14.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 (245) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +61 -34
  3. package/dist/cjs/animations/presets.js +4 -4
  4. package/dist/cjs/entry-points/focus.js +6 -4
  5. package/dist/cjs/entry-points/get-aria-for-trigger.js +12 -0
  6. package/dist/cjs/entry-points/popover-surface.js +12 -0
  7. package/dist/cjs/entry-points/use-anchor-position-at-point.js +12 -0
  8. package/dist/cjs/entry-points/use-popover-id.js +21 -0
  9. package/dist/cjs/focus/get-first-focusable.js +19 -0
  10. package/dist/cjs/focus/get-focusables.js +30 -0
  11. package/dist/cjs/focus/get-last-focusable.js +19 -0
  12. package/dist/cjs/focus/get-next-focusable.js +43 -0
  13. package/dist/cjs/focus/is-in-same-layer.js +23 -0
  14. package/dist/cjs/focus/is-nested-layer-focused.js +32 -0
  15. package/dist/cjs/focus/selectors.js +19 -0
  16. package/dist/cjs/focus/types.js +1 -0
  17. package/dist/cjs/internal/get-aria-for-trigger.js +88 -0
  18. package/dist/cjs/internal/role-to-aria-has-popup.js +37 -0
  19. package/dist/cjs/internal/role-types.js +2 -35
  20. package/dist/cjs/internal/should-focus-into-popover.js +19 -0
  21. package/dist/cjs/internal/slot.js +1 -1
  22. package/dist/cjs/internal/use-anchor-position-at-point.js +127 -0
  23. package/dist/cjs/internal/use-anchor-position.js +36 -16
  24. package/dist/cjs/internal/use-focus-wrap.js +8 -5
  25. package/dist/cjs/internal/use-initial-focus.js +4 -4
  26. package/dist/cjs/placement-map/index.js +2 -2
  27. package/dist/cjs/placement-map/legacy-placements.js +2 -101
  28. package/dist/cjs/placement-map/placement-mapping.js +103 -0
  29. package/dist/cjs/popover/popover.js +79 -80
  30. package/dist/cjs/popover-surface/index.js +12 -0
  31. package/dist/cjs/{popup/popup-surface.js → popover-surface/popover-surface.js} +9 -12
  32. package/dist/cjs/testing/polyfill.js +9 -6
  33. package/dist/cjs/use-arrow-navigation/use-arrow-navigation.js +7 -5
  34. package/dist/es2019/animations/presets.js +4 -4
  35. package/dist/es2019/entry-points/focus.js +3 -1
  36. package/dist/es2019/entry-points/get-aria-for-trigger.js +1 -0
  37. package/dist/es2019/entry-points/popover-surface.js +1 -0
  38. package/dist/es2019/entry-points/use-anchor-position-at-point.js +1 -0
  39. package/dist/es2019/entry-points/use-popover-id.js +15 -0
  40. package/dist/es2019/focus/get-first-focusable.js +14 -0
  41. package/dist/es2019/focus/get-focusables.js +19 -0
  42. package/dist/es2019/focus/get-last-focusable.js +14 -0
  43. package/dist/es2019/focus/get-next-focusable.js +38 -0
  44. package/dist/es2019/focus/is-in-same-layer.js +18 -0
  45. package/dist/es2019/focus/is-nested-layer-focused.js +28 -0
  46. package/dist/es2019/focus/selectors.js +11 -0
  47. package/dist/es2019/focus/types.js +0 -0
  48. package/dist/es2019/internal/get-aria-for-trigger.js +84 -0
  49. package/dist/es2019/internal/role-to-aria-has-popup.js +32 -0
  50. package/dist/es2019/internal/role-types.js +0 -33
  51. package/dist/es2019/internal/should-focus-into-popover.js +14 -0
  52. package/dist/es2019/internal/slot.js +1 -1
  53. package/dist/es2019/internal/use-anchor-position-at-point.js +122 -0
  54. package/dist/es2019/internal/use-anchor-position.js +21 -14
  55. package/dist/es2019/internal/use-focus-wrap.js +4 -1
  56. package/dist/es2019/internal/use-initial-focus.js +1 -1
  57. package/dist/es2019/placement-map/index.js +1 -1
  58. package/dist/es2019/placement-map/legacy-placements.js +1 -100
  59. package/dist/es2019/placement-map/placement-mapping.js +97 -0
  60. package/dist/es2019/popover/popover.js +79 -80
  61. package/dist/es2019/popover-surface/index.js +1 -0
  62. package/dist/es2019/popover-surface/popover-surface.js +27 -0
  63. package/dist/es2019/testing/polyfill.js +9 -6
  64. package/dist/es2019/use-arrow-navigation/use-arrow-navigation.js +3 -1
  65. package/dist/esm/animations/presets.js +4 -4
  66. package/dist/esm/entry-points/focus.js +3 -1
  67. package/dist/esm/entry-points/get-aria-for-trigger.js +1 -0
  68. package/dist/esm/entry-points/popover-surface.js +1 -0
  69. package/dist/esm/entry-points/use-anchor-position-at-point.js +1 -0
  70. package/dist/esm/entry-points/use-popover-id.js +15 -0
  71. package/dist/esm/focus/get-first-focusable.js +13 -0
  72. package/dist/esm/focus/get-focusables.js +24 -0
  73. package/dist/esm/focus/get-last-focusable.js +13 -0
  74. package/dist/esm/focus/get-next-focusable.js +37 -0
  75. package/dist/esm/focus/is-in-same-layer.js +17 -0
  76. package/dist/esm/focus/is-nested-layer-focused.js +27 -0
  77. package/dist/esm/focus/selectors.js +13 -0
  78. package/dist/esm/focus/types.js +0 -0
  79. package/dist/esm/internal/get-aria-for-trigger.js +83 -0
  80. package/dist/esm/internal/role-to-aria-has-popup.js +31 -0
  81. package/dist/esm/internal/role-types.js +2 -34
  82. package/dist/esm/internal/should-focus-into-popover.js +13 -0
  83. package/dist/esm/internal/slot.js +1 -1
  84. package/dist/esm/internal/use-anchor-position-at-point.js +122 -0
  85. package/dist/esm/internal/use-anchor-position.js +36 -16
  86. package/dist/esm/internal/use-focus-wrap.js +4 -1
  87. package/dist/esm/internal/use-initial-focus.js +1 -1
  88. package/dist/esm/placement-map/index.js +1 -1
  89. package/dist/esm/placement-map/legacy-placements.js +1 -100
  90. package/dist/esm/placement-map/placement-mapping.js +97 -0
  91. package/dist/esm/popover/popover.js +79 -80
  92. package/dist/esm/popover-surface/index.js +1 -0
  93. package/dist/esm/popover-surface/popover-surface.js +26 -0
  94. package/dist/esm/testing/polyfill.js +9 -6
  95. package/dist/esm/use-arrow-navigation/use-arrow-navigation.js +3 -1
  96. package/dist/types/animations/presets.d.ts +4 -4
  97. package/dist/types/animations/types.d.ts +1 -1
  98. package/dist/types/dialog/types.d.ts +0 -8
  99. package/dist/types/entry-points/focus.d.ts +4 -2
  100. package/dist/types/entry-points/get-aria-for-trigger.d.ts +1 -0
  101. package/dist/types/entry-points/popover-surface.d.ts +2 -0
  102. package/dist/types/entry-points/popover.d.ts +1 -1
  103. package/dist/types/entry-points/use-anchor-position-at-point.d.ts +1 -0
  104. package/dist/types/entry-points/use-popover-id.d.ts +11 -0
  105. package/dist/types/focus/get-first-focusable.d.ts +8 -0
  106. package/dist/types/focus/get-focusables.d.ts +13 -0
  107. package/dist/types/focus/get-last-focusable.d.ts +8 -0
  108. package/dist/types/focus/get-next-focusable.d.ts +13 -0
  109. package/dist/types/focus/is-in-same-layer.d.ts +8 -0
  110. package/dist/types/focus/is-nested-layer-focused.d.ts +8 -0
  111. package/dist/types/focus/selectors.d.ts +4 -0
  112. package/dist/types/focus/types.d.ts +5 -0
  113. package/dist/types/internal/get-aria-for-trigger.d.ts +86 -0
  114. package/dist/types/internal/role-to-aria-has-popup.d.ts +13 -0
  115. package/dist/types/internal/role-types.d.ts +0 -12
  116. package/dist/types/internal/should-focus-into-popover.d.ts +8 -0
  117. package/dist/types/internal/slot.d.ts +2 -2
  118. package/dist/types/internal/use-anchor-position-at-point.d.ts +62 -0
  119. package/dist/types/internal/use-anchor-position.d.ts +6 -1
  120. package/dist/types/placement-map/index.d.ts +1 -1
  121. package/dist/types/placement-map/legacy-placements.d.ts +0 -12
  122. package/dist/types/placement-map/placement-mapping.d.ts +13 -0
  123. package/dist/types/popover/index.d.ts +1 -1
  124. package/dist/types/popover/popover.d.ts +6 -13
  125. package/dist/types/popover/types.d.ts +6 -5
  126. package/dist/types/popover-surface/index.d.ts +2 -0
  127. package/dist/types/popover-surface/popover-surface.d.ts +21 -0
  128. package/dist/types/use-arrow-navigation/use-arrow-navigation.d.ts +1 -1
  129. package/dist/types-ts4.5/animations/presets.d.ts +4 -4
  130. package/dist/types-ts4.5/animations/types.d.ts +1 -1
  131. package/dist/types-ts4.5/dialog/types.d.ts +0 -8
  132. package/dist/types-ts4.5/entry-points/focus.d.ts +4 -2
  133. package/dist/types-ts4.5/entry-points/get-aria-for-trigger.d.ts +1 -0
  134. package/dist/types-ts4.5/entry-points/popover-surface.d.ts +2 -0
  135. package/dist/types-ts4.5/entry-points/popover.d.ts +1 -1
  136. package/dist/types-ts4.5/entry-points/use-anchor-position-at-point.d.ts +1 -0
  137. package/dist/types-ts4.5/entry-points/use-popover-id.d.ts +11 -0
  138. package/dist/types-ts4.5/focus/get-first-focusable.d.ts +8 -0
  139. package/dist/types-ts4.5/focus/get-focusables.d.ts +13 -0
  140. package/dist/types-ts4.5/focus/get-last-focusable.d.ts +8 -0
  141. package/dist/types-ts4.5/focus/get-next-focusable.d.ts +13 -0
  142. package/dist/types-ts4.5/focus/is-in-same-layer.d.ts +8 -0
  143. package/dist/types-ts4.5/focus/is-nested-layer-focused.d.ts +8 -0
  144. package/dist/types-ts4.5/focus/selectors.d.ts +4 -0
  145. package/dist/types-ts4.5/focus/types.d.ts +5 -0
  146. package/dist/types-ts4.5/internal/get-aria-for-trigger.d.ts +86 -0
  147. package/dist/types-ts4.5/internal/role-to-aria-has-popup.d.ts +13 -0
  148. package/dist/types-ts4.5/internal/role-types.d.ts +0 -12
  149. package/dist/types-ts4.5/internal/should-focus-into-popover.d.ts +8 -0
  150. package/dist/types-ts4.5/internal/slot.d.ts +2 -2
  151. package/dist/types-ts4.5/internal/use-anchor-position-at-point.d.ts +62 -0
  152. package/dist/types-ts4.5/internal/use-anchor-position.d.ts +6 -1
  153. package/dist/types-ts4.5/placement-map/index.d.ts +1 -1
  154. package/dist/types-ts4.5/placement-map/legacy-placements.d.ts +0 -12
  155. package/dist/types-ts4.5/placement-map/placement-mapping.d.ts +13 -0
  156. package/dist/types-ts4.5/popover/index.d.ts +1 -1
  157. package/dist/types-ts4.5/popover/popover.d.ts +6 -13
  158. package/dist/types-ts4.5/popover/types.d.ts +6 -5
  159. package/dist/types-ts4.5/popover-surface/index.d.ts +2 -0
  160. package/dist/types-ts4.5/popover-surface/popover-surface.d.ts +21 -0
  161. package/dist/types-ts4.5/use-arrow-navigation/use-arrow-navigation.d.ts +1 -1
  162. package/get-aria-for-trigger/package.json +17 -0
  163. package/package.json +3 -3
  164. package/popover-surface/package.json +17 -0
  165. package/use-anchor-position-at-point/package.json +17 -0
  166. package/use-popover-id/package.json +17 -0
  167. package/dist/cjs/entry-points/popup-surface.js +0 -12
  168. package/dist/cjs/entry-points/popup.js +0 -12
  169. package/dist/cjs/focus/focus.js +0 -169
  170. package/dist/cjs/focus/index.js +0 -24
  171. package/dist/cjs/popup/index.js +0 -37
  172. package/dist/cjs/popup/popup-content.js +0 -214
  173. package/dist/cjs/popup/popup-context.js +0 -25
  174. package/dist/cjs/popup/popup-provider.js +0 -15
  175. package/dist/cjs/popup/popup-trigger-function.js +0 -80
  176. package/dist/cjs/popup/popup-trigger.js +0 -66
  177. package/dist/cjs/popup/popup.js +0 -81
  178. package/dist/cjs/popup/types.js +0 -5
  179. package/dist/cjs/popup/use-maybe-popup-context.js +0 -17
  180. package/dist/cjs/popup/use-popup-context.js +0 -20
  181. package/dist/es2019/entry-points/popup-surface.js +0 -1
  182. package/dist/es2019/entry-points/popup.js +0 -1
  183. package/dist/es2019/focus/focus.js +0 -158
  184. package/dist/es2019/focus/index.js +0 -1
  185. package/dist/es2019/popup/index.js +0 -33
  186. package/dist/es2019/popup/popup-content.js +0 -206
  187. package/dist/es2019/popup/popup-context.js +0 -20
  188. package/dist/es2019/popup/popup-provider.js +0 -10
  189. package/dist/es2019/popup/popup-surface.js +0 -30
  190. package/dist/es2019/popup/popup-trigger-function.js +0 -75
  191. package/dist/es2019/popup/popup-trigger.js +0 -61
  192. package/dist/es2019/popup/popup.js +0 -67
  193. package/dist/es2019/popup/types.js +0 -1
  194. package/dist/es2019/popup/use-maybe-popup-context.js +0 -12
  195. package/dist/es2019/popup/use-popup-context.js +0 -15
  196. package/dist/esm/entry-points/popup-surface.js +0 -1
  197. package/dist/esm/entry-points/popup.js +0 -1
  198. package/dist/esm/focus/focus.js +0 -160
  199. package/dist/esm/focus/index.js +0 -1
  200. package/dist/esm/popup/index.js +0 -33
  201. package/dist/esm/popup/popup-content.js +0 -206
  202. package/dist/esm/popup/popup-context.js +0 -20
  203. package/dist/esm/popup/popup-provider.js +0 -10
  204. package/dist/esm/popup/popup-surface.js +0 -29
  205. package/dist/esm/popup/popup-trigger-function.js +0 -75
  206. package/dist/esm/popup/popup-trigger.js +0 -59
  207. package/dist/esm/popup/popup.js +0 -72
  208. package/dist/esm/popup/types.js +0 -1
  209. package/dist/esm/popup/use-maybe-popup-context.js +0 -12
  210. package/dist/esm/popup/use-popup-context.js +0 -15
  211. package/dist/types/entry-points/popup-surface.d.ts +0 -2
  212. package/dist/types/entry-points/popup.d.ts +0 -2
  213. package/dist/types/focus/focus.d.ts +0 -50
  214. package/dist/types/focus/index.d.ts +0 -2
  215. package/dist/types/popup/index.d.ts +0 -34
  216. package/dist/types/popup/popup-content.d.ts +0 -14
  217. package/dist/types/popup/popup-context.d.ts +0 -96
  218. package/dist/types/popup/popup-provider.d.ts +0 -10
  219. package/dist/types/popup/popup-surface.d.ts +0 -22
  220. package/dist/types/popup/popup-trigger-function.d.ts +0 -112
  221. package/dist/types/popup/popup-trigger.d.ts +0 -14
  222. package/dist/types/popup/popup.d.ts +0 -14
  223. package/dist/types/popup/types.d.ts +0 -321
  224. package/dist/types/popup/use-maybe-popup-context.d.ts +0 -8
  225. package/dist/types/popup/use-popup-context.d.ts +0 -7
  226. package/dist/types-ts4.5/entry-points/popup-surface.d.ts +0 -2
  227. package/dist/types-ts4.5/entry-points/popup.d.ts +0 -2
  228. package/dist/types-ts4.5/focus/focus.d.ts +0 -50
  229. package/dist/types-ts4.5/focus/index.d.ts +0 -2
  230. package/dist/types-ts4.5/popup/index.d.ts +0 -34
  231. package/dist/types-ts4.5/popup/popup-content.d.ts +0 -14
  232. package/dist/types-ts4.5/popup/popup-context.d.ts +0 -96
  233. package/dist/types-ts4.5/popup/popup-provider.d.ts +0 -10
  234. package/dist/types-ts4.5/popup/popup-surface.d.ts +0 -22
  235. package/dist/types-ts4.5/popup/popup-trigger-function.d.ts +0 -112
  236. package/dist/types-ts4.5/popup/popup-trigger.d.ts +0 -14
  237. package/dist/types-ts4.5/popup/popup.d.ts +0 -14
  238. package/dist/types-ts4.5/popup/types.d.ts +0 -321
  239. package/dist/types-ts4.5/popup/use-maybe-popup-context.d.ts +0 -8
  240. package/dist/types-ts4.5/popup/use-popup-context.d.ts +0 -7
  241. package/popup/package.json +0 -17
  242. package/popup-surface/package.json +0 -17
  243. /package/dist/cjs/{popup/popup-surface.compiled.css → popover-surface/popover-surface.compiled.css} +0 -0
  244. /package/dist/es2019/{popup/popup-surface.compiled.css → popover-surface/popover-surface.compiled.css} +0 -0
  245. /package/dist/esm/{popup/popup-surface.compiled.css → popover-surface/popover-surface.compiled.css} +0 -0
@@ -17,14 +17,13 @@ var _bindEventListener = require("bind-event-listener");
17
17
  var _mergeRefs = _interopRequireDefault(require("@atlaskit/ds-lib/merge-refs"));
18
18
  var _once = _interopRequireDefault(require("@atlaskit/ds-lib/once"));
19
19
  var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer");
20
+ var _roleTypes = require("../internal/role-types");
20
21
  var _useAnimatedVisibility = require("../internal/use-animated-visibility");
21
22
  var _useFocusWrap = require("../internal/use-focus-wrap");
22
23
  var _useInitialFocus = require("../internal/use-initial-focus");
23
24
  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); }
24
25
  /**
25
- * Detects whether the browser supports the `popover="hint"` attribute value.
26
- * Uses DOM reflection: unsupported browsers reflect the invalid value default ("manual").
27
- * Safe for SSR. Result is cached via `once`.
26
+ * Detects `popover="hint"` support via DOM reflection. SSR-safe, cached.
28
27
  */
29
28
  var supportsPopoverHint = (0, _once.default)(function () {
30
29
  if (typeof document === 'undefined') {
@@ -41,33 +40,20 @@ var styles = {
41
40
  root: "_19itglyw _ca0qidpf _u5f3idpf _n3tdidpf _19bvidpf _19pkidpf _2hwxidpf _otyridpf _18u0idpf _1r041wug _1reoewfl _18m9ewfl _bfhk1j28"
42
41
  };
43
42
  /**
44
- * ARIA roles on the Popover primitive that register with the open layer observer
45
- * as LayerType 'popup'. These are interactive overlays that should be tracked
46
- * and dismissed when closeLayers() is called (e.g. when the side nav resizes).
47
- *
48
- * Note on open layer observer types not included here:
49
- * - 'modal' only ever comes from the Dialog primitive, not Popover.
50
- * - Other layer types (e.g. 'tooltip') do not yet exist in LayerType because
51
- * there is no current use case for distinguishing them in the observer.
43
+ * Roles registered with the open layer observer as `popup`, so `closeLayers()`
44
+ * dismisses them. `modal` comes from Dialog only; other layer types are unused.
52
45
  */
53
46
  var POPUP_ROLES = new Set(['menu', 'listbox', 'dialog', 'alertdialog', 'tree', 'grid']);
54
47
 
55
48
  /**
56
- * Unopinionated top-layer primitive.
57
- *
58
- * Manages only visibility (isOpen) and animation (animate). Has no knowledge
59
- * of positioning - compose with `useAnchorPosition` for anchor positioning
60
- * and optionally `useWidthFromAnchor` for setting the width of a popover element
61
- * relative to its anchor trigger.
49
+ * Unopinionated top-layer primitive. Manages visibility and animation only;
50
+ * compose with `useAnchorPosition` / `useWidthFromAnchor` for positioning.
62
51
  *
63
- * Visibility is driven by the `isOpen` prop:
64
- * - `isOpen={true}` → `showPopover()`, entry animation via `@starting-style`
65
- * - `isOpen={false}` → `hidePopover()`, exit animation via `allow-discrete`
52
+ * `isOpen={true}` calls `showPopover()` (entry via `@starting-style`);
53
+ * `isOpen={false}` calls `hidePopover()` (exit via `allow-discrete`).
66
54
  *
67
- * For `mode="auto"`, the browser can dismiss the popover via light dismiss
68
- * (Escape, click outside). When that happens, `onClose` is called and the
69
- * consumer must set `isOpen` to `false`. The DOM owns the dismiss; React
70
- * must follow.
55
+ * In `mode="auto"`, the browser can light-dismiss (Escape, click outside).
56
+ * `onClose` fires; the consumer must then set `isOpen` to `false`.
71
57
  */
72
58
  var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Popover(_ref, ref) {
73
59
  var children = _ref.children,
@@ -89,11 +75,9 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
89
75
  var autoId = (0, _react.useId)();
90
76
  var ownRef = (0, _react.useRef)(null);
91
77
  var combinedRef = (0, _mergeRefs.default)([ownRef, ref].filter(Boolean));
92
- // Regex is intentional: `replaceAll` is not available in our supported
93
- // browser matrix. In React 18, `useId()` returns IDs containing colons
94
- // (e.g. `:r1:`) which are invalid in CSS selectors and `popover` target
95
- // attributes. React 19.2.0 replaced colons with underscores, making this
96
- // stripping unnecessary once React 18 support is dropped.
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).
97
81
  var popoverId = idProp !== null && idProp !== void 0 ? idProp : "popover-".concat(autoId.replace(/:/g, ''));
98
82
  var _useAnimatedVisibilit = (0, _useAnimatedVisibility.useAnimatedVisibility)({
99
83
  isOpen: isOpen,
@@ -105,12 +89,10 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
105
89
  showChildren = _useAnimatedVisibilit.showChildren,
106
90
  preset = _useAnimatedVisibilit.preset;
107
91
 
108
- // Focus management
109
- // Initial focus: on open, moves focus into the popover (role-dependent).
110
- // Focus wrap: Tab/Shift+Tab cycle within the popover for dialog roles.
111
- // Focus restoration: handled natively by the Popover API. The browser
112
- // tracks `previouslyFocusedElement` on show and restores it on hide.
113
- // No custom restoration hook is needed. See: notes/architecture/focus-restoration.md
92
+ // Focus management: initial focus on open (role-dependent), Tab cycling
93
+ // for dialog roles. Restoration is native for outermost popovers; nested
94
+ // focus-capturing roles are handled below via `beforetoggle` snapshot.
95
+ // See: notes/architecture/focus-restoration.md
114
96
  (0, _useFocusWrap.useFocusWrap)({
115
97
  elementRef: ownRef,
116
98
  role: role
@@ -121,13 +103,9 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
121
103
  role: role
122
104
  });
123
105
 
124
- // Open layer observer registration
125
- // Notifies the open layer observer so app-coordination features
126
- // (closeLayers(), open-count subscriptions) work with top-layer popovers.
127
- //
128
- // Only set type: 'popup' for roles that are interactive overlay popups.
129
- // Passive/informational roles (tooltip, note, status, alert, log) and
130
- // no-role cases do not map to LayerType 'popup', so type is left undefined.
106
+ // Register with open layer observer so `closeLayers()` and open-count
107
+ // subscriptions work. Only popup-like roles register as `popup`; passive
108
+ // roles (tooltip, status, etc.) leave `type` undefined.
131
109
  var handleObserverClose = (0, _react.useCallback)(function () {
132
110
  onClose === null || onClose === void 0 || onClose({
133
111
  reason: 'programmatic'
@@ -139,25 +117,29 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
139
117
  onClose: handleObserverClose
140
118
  });
141
119
 
142
- // Hint mode fallback: "hint" downgrades to "auto" if unsupported.
143
- //
144
- // Decision (2026-03-17 audit): We keep "auto" as the fallback (not "manual")
145
- // because it provides the closest behavior to "hint" (light dismiss works).
146
- // However, there is a behavioral difference: "auto" participates in the
147
- // auto-dismiss stack and WILL close other "auto" popovers when it opens
148
- // (e.g. a tooltip opening will close an open dropdown). "hint" does not
149
- // have this side effect. This difference only affects browsers without
150
- // popover="hint" support, and that set is shrinking rapidly.
120
+ // `hint` falls back to `auto` when unsupported: closest behavior (light
121
+ // dismiss works), but `auto` participates in the auto-dismiss stack so it
122
+ // will close other `auto` popovers when opened. Acceptable trade-off given
123
+ // shrinking browser set without `hint` support.
151
124
  var mode = modeProp === 'hint' && !supportsPopoverHint() ? 'auto' : modeProp;
152
125
 
153
- // Distinguishes programmatic hidePopover() from browser-initiated dismiss.
154
- // When we call hidePopover() ourselves the beforetoggle event fires synchronously,
155
- // so this ref prevents the toggle handler from calling onClose redundantly.
126
+ // Prevents toggle handler from calling onClose for our own hidePopover() calls.
156
127
  var programmaticCloseRef = (0, _react.useRef)(false);
157
128
 
158
- // Escape key tracking: set in a capture-phase keydown listener (fires before
159
- // the browser processes light dismiss), read in the toggle handler.
129
+ // Set in capture-phase keydown so the toggle handler knows close reason.
160
130
  var closeReasonRef = (0, _react.useRef)('light-dismiss');
131
+
132
+ // Snapshot of pre-open focus, used to restore focus for nested popovers
133
+ // with focus-capturing roles (browser only restores the outermost).
134
+ var previouslyFocusedElementRef = (0, _react.useRef)(null);
135
+ var handleBeforeToggle = (0, _react.useCallback)(function (event) {
136
+ if (event.newState !== 'open') {
137
+ return;
138
+ }
139
+ // eslint-disable-next-line @atlaskit/platform/no-direct-document-usage -- need active element snapshot
140
+ var active = document.activeElement;
141
+ previouslyFocusedElementRef.current = active instanceof HTMLElement ? active : null;
142
+ }, []);
161
143
  var handleToggle = (0, _react.useCallback)(function (event) {
162
144
  var element = ownRef.current;
163
145
  if (event.newState === 'open') {
@@ -175,32 +157,52 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
175
157
  isOpen: false,
176
158
  element: element
177
159
  });
160
+
161
+ // Nested-popover focus restoration fallback (browser only
162
+ // restores outermost; Firefox skips nested entirely).
163
+ // Restore only when the role moved focus in on open AND the
164
+ // close was Escape/programmatic. For light dismiss, the
165
+ // click target keeps focus per HTML spec
166
+ // (`focusPreviousElement=false`).
167
+ var previouslyFocused = previouslyFocusedElementRef.current;
168
+ var _reason = closeReasonRef.current;
169
+ var isProgrammatic = programmaticCloseRef.current;
170
+ var shouldRestore = previouslyFocused !== null && previouslyFocused.isConnected && (0, _roleTypes.shouldFocusIntoPopover)({
171
+ role: role
172
+ }) && (_reason === 'escape' || isProgrammatic);
173
+ if (shouldRestore && previouslyFocused) {
174
+ previouslyFocused.focus({
175
+ preventScroll: true
176
+ });
177
+ }
178
+ previouslyFocusedElementRef.current = null;
178
179
  }
179
180
 
180
- // Programmatic close (unmount or isOpen→false). Consumer already knows.
181
+ // Programmatic close: consumer already knows.
181
182
  if (programmaticCloseRef.current) {
183
+ // Reset reason so a stale 'escape' from a race with Escape keydown
184
+ // does not corrupt the next browser-dismiss cycle.
185
+ closeReasonRef.current = 'light-dismiss';
182
186
  return;
183
187
  }
184
188
 
185
- // Browser dismiss (Escape or click-outside). Notify consumer.
189
+ // Browser dismiss (Escape/click-outside).
186
190
  var reason = closeReasonRef.current;
187
- closeReasonRef.current = 'light-dismiss'; // reset for next dismiss
188
- // `onClose` is required for `auto`/`hint` and forbidden for
189
- // `manual`, but `TPopoverForwardedProps` is a flat type used
190
- // internally by `PopupContent` - the optional check guards
191
- // the manual-mode forwarded path where the field is undefined.
191
+ // reset for next dismiss
192
+ closeReasonRef.current = 'light-dismiss';
193
+ // Optional: `manual` mode has no `onClose` in the forwarded type.
192
194
  onClose === null || onClose === void 0 || onClose({
193
195
  reason: reason
194
196
  });
195
197
  }
196
- }, [onClose, onOpenChange]);
198
+ }, [onClose, onOpenChange, role]);
197
199
  (0, _react.useEffect)(function () {
198
200
  var element = ownRef.current;
199
201
  if (!element) {
200
202
  return;
201
203
  }
202
204
 
203
- // Capture-phase: tag Escape before the browser processes light dismiss.
205
+ // Tag Escape before the browser processes light dismiss.
204
206
  var unbindEscape = (0, _bindEventListener.bind)(element, {
205
207
  type: 'keydown',
206
208
  listener: function listener(event) {
@@ -216,15 +218,20 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
216
218
  type: 'toggle',
217
219
  listener: handleToggle
218
220
  });
221
+ // Snapshot `document.activeElement` before `useInitialFocus` moves it.
222
+ var unbindBeforeToggle = (0, _bindEventListener.bind)(element, {
223
+ type: 'beforetoggle',
224
+ listener: handleBeforeToggle
225
+ });
219
226
  return function () {
220
227
  unbindEscape();
221
228
  unbindToggle();
229
+ unbindBeforeToggle();
222
230
  };
223
- }, [handleToggle]);
231
+ }, [handleToggle, handleBeforeToggle]);
224
232
 
225
- // Placement-dependent animation CSS vars (e.g. slide direction).
226
- // Separate from show/hide so that preset reference changes
227
- // (e.g. inline `animate={slideAndFade()}`) do not re-trigger visibility.
233
+ // Placement-dependent animation CSS vars. Kept separate from show/hide
234
+ // so preset reference changes do not re-trigger visibility.
228
235
  (0, _react.useLayoutEffect)(function () {
229
236
  var el = ownRef.current;
230
237
  if (!el || !(preset !== null && preset !== void 0 && preset.getProperties) || !placement) {
@@ -241,14 +248,9 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
241
248
  });
242
249
  }, [preset, placement]);
243
250
 
244
- // Show/hide based on isOpen.
245
- // showPopover() and hidePopover() are no-ops when the popover is already
246
- // in the target state (e.g. browser dismissed via light-dismiss before our
247
- // effect ran).
248
- // Defensive try/catch: these APIs throw InvalidStateError if the element
249
- // is disconnected or missing the popover attribute. While we do not expect
250
- // that to happen in normal usage, it can occur in edge cases (e.g. React
251
- // concurrent mode, StrictMode double-effects, or unmount races).
251
+ // Show/hide based on isOpen. `showPopover`/`hidePopover` are no-ops when
252
+ // already in the target state. Try/catch guards `InvalidStateError` on
253
+ // disconnected elements (StrictMode/concurrent/unmount edge cases).
252
254
  (0, _react.useLayoutEffect)(function () {
253
255
  var el = ownRef.current;
254
256
  if (!el) {
@@ -256,20 +258,17 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
256
258
  }
257
259
  if (isOpen) {
258
260
  programmaticCloseRef.current = false;
259
- // Defensive: element may be disconnected or in an unexpected state.
260
261
  try {
261
262
  el.showPopover();
262
263
  } catch (_unused) {}
263
264
  return function () {
264
265
  programmaticCloseRef.current = true;
265
- // Defensive: element may be disconnected or in an unexpected state.
266
266
  try {
267
267
  el.hidePopover();
268
268
  } catch (_unused2) {}
269
269
  };
270
270
  }
271
271
  programmaticCloseRef.current = true;
272
- // Defensive: element may be disconnected or in an unexpected state.
273
272
  try {
274
273
  el.hidePopover();
275
274
  } catch (_unused3) {}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "PopoverSurface", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _popoverSurface.PopoverSurface;
10
+ }
11
+ });
12
+ var _popoverSurface = require("./popover-surface");
@@ -1,12 +1,12 @@
1
- /* popup-surface.tsx generated by @compiled/babel-plugin v0.39.1 */
1
+ /* popover-surface.tsx generated by @compiled/babel-plugin v0.39.1 */
2
2
  "use strict";
3
3
 
4
4
  var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
5
5
  Object.defineProperty(exports, "__esModule", {
6
6
  value: true
7
7
  });
8
- exports.PopupSurface = PopupSurface;
9
- require("./popup-surface.compiled.css");
8
+ exports.PopoverSurface = PopoverSurface;
9
+ require("./popover-surface.compiled.css");
10
10
  var _runtime = require("@compiled/react/runtime");
11
11
  var _react = _interopRequireDefault(require("react"));
12
12
  var styles = {
@@ -14,21 +14,18 @@ var styles = {
14
14
  };
15
15
 
16
16
  /**
17
- * Optional styled wrapper for popup content.
17
+ * Optional styled wrapper for popover content.
18
18
  *
19
19
  * Adds default visual styling (background, border-radius, box-shadow)
20
- * using design tokens. Consumers who want fully custom styling
21
- * should use `Popup.Content` without wrapping in `PopupSurface`.
20
+ * using design tokens.
22
21
  *
23
- * Exposed as `Popup.Surface` on the compound component.
24
- *
25
- * **Presentational primitive - `children`-only by design.** This component
22
+ * Presentational primitive - `children`-only by design. This component
26
23
  * intentionally exposes no `style`, `className`, `xcss`, `id`, or `ref`
27
24
  * props. If you need any of those, render your own wrapper element inside
28
- * `Popup.Content` instead - `PopupSurface` is the no-config "give me the
29
- * default ADS overlay look" surface, nothing more.
25
+ * `Popover` instead. `PopoverSurface` is the no-config "give me the default
26
+ * ADS overlay look" surface, nothing more.
30
27
  */
31
- function PopupSurface(_ref) {
28
+ function PopoverSurface(_ref) {
32
29
  var children = _ref.children;
33
30
  return /*#__PURE__*/_react.default.createElement("div", {
34
31
  className: (0, _runtime.ax)([styles.root])
@@ -104,7 +104,7 @@ function createToggleScheduler() {
104
104
  newState: newState
105
105
  });
106
106
 
107
- // Task queue (setTimeout) - browser fires toggle after microtasks drain, not during
107
+ // Task queue (setTimeout): browser fires toggle after microtasks drain, not during
108
108
  setTimeout(function () {
109
109
  var entry = pending.get(element);
110
110
  if (!entry) {
@@ -534,10 +534,11 @@ if (typeof HTMLElement !== 'undefined') {
534
534
  element: this
535
535
  }), " is not connected to the document. Ensure the element has been added to the DOM (e.g. via render() or document.body.appendChild()) before calling showPopover()."), 'InvalidStateError');
536
536
  }
537
+ // No-op: already showing.
537
538
  if (isPopoverOpen({
538
539
  element: this
539
540
  })) {
540
- return; // already showing - no-op
541
+ return;
541
542
  }
542
543
 
543
544
  // sync, cancelable on show only
@@ -731,8 +732,9 @@ if (typeof HTMLDialogElement !== 'undefined') {
731
732
  }), " is not connected to the document. Ensure the element has been added to the DOM (e.g. via render() or document.body.appendChild()) before calling showModal()."), 'InvalidStateError');
732
733
  }
733
734
  if (this.hasAttribute('open')) {
735
+ // No-op: already modal.
734
736
  if (this._isModal) {
735
- return; // already modal - no-op
737
+ return;
736
738
  }
737
739
  throw new DOMException("Failed to execute 'showModal' on 'HTMLDialogElement': ".concat(describeElement({
738
740
  element: this
@@ -756,7 +758,7 @@ if (typeof HTMLDialogElement !== 'undefined') {
756
758
  }
757
759
  if (typeof proto.show !== 'function') {
758
760
  proto.show = function show() {
759
- // Browser does not throw for disconnected elements on show - just no-op
761
+ // Browser does not throw for disconnected elements on show; no-op.
760
762
  if (!this.isConnected || this.hasAttribute('open')) {
761
763
  return;
762
764
  }
@@ -778,11 +780,12 @@ if (typeof HTMLDialogElement !== 'undefined') {
778
780
  }
779
781
  if (typeof proto.close !== 'function') {
780
782
  proto.close = function close(returnValue) {
783
+ // No-op: already closed.
781
784
  if (!this.hasAttribute('open')) {
782
- return; // already closed - no-op
785
+ return;
783
786
  }
784
787
 
785
- // Sync beforetoggle (not cancelable) - matches browser behavior
788
+ // Sync beforetoggle (not cancelable); matches browser behavior.
786
789
  fireToggleEvent({
787
790
  element: this,
788
791
  type: 'beforetoggle',
@@ -8,7 +8,9 @@ var _react = require("react");
8
8
  var _bindEventListener = require("bind-event-listener");
9
9
  var _browserApis = require("@atlaskit/browser-apis");
10
10
  var _keycodes = require("@atlaskit/ds-lib/keycodes");
11
- var _focus = require("../focus");
11
+ var _getFirstFocusable2 = require("../focus/get-first-focusable");
12
+ var _getLastFocusable2 = require("../focus/get-last-focusable");
13
+ var _getNextFocusable3 = require("../focus/get-next-focusable");
12
14
  var menuScope = '[role="menu"]';
13
15
 
14
16
  /**
@@ -96,7 +98,7 @@ function useArrowNavigation(_ref) {
96
98
  var _getNextFocusable;
97
99
  // Prevent page scroll while navigating menu items.
98
100
  event.preventDefault();
99
- (_getNextFocusable = (0, _focus.getNextFocusable)({
101
+ (_getNextFocusable = (0, _getNextFocusable3.getNextFocusable)({
100
102
  container: container,
101
103
  direction: 'forwards',
102
104
  filter: filter
@@ -107,7 +109,7 @@ function useArrowNavigation(_ref) {
107
109
  var _getNextFocusable2;
108
110
  // Prevent page scroll while navigating menu items.
109
111
  event.preventDefault();
110
- (_getNextFocusable2 = (0, _focus.getNextFocusable)({
112
+ (_getNextFocusable2 = (0, _getNextFocusable3.getNextFocusable)({
111
113
  container: container,
112
114
  direction: 'backwards',
113
115
  filter: filter
@@ -118,7 +120,7 @@ function useArrowNavigation(_ref) {
118
120
  var _getFirstFocusable;
119
121
  // Prevent browser default (e.g. scrolling to top of page).
120
122
  event.preventDefault();
121
- (_getFirstFocusable = (0, _focus.getFirstFocusable)({
123
+ (_getFirstFocusable = (0, _getFirstFocusable2.getFirstFocusable)({
122
124
  container: container,
123
125
  filter: filter
124
126
  })) === null || _getFirstFocusable === void 0 || _getFirstFocusable.focus();
@@ -128,7 +130,7 @@ function useArrowNavigation(_ref) {
128
130
  var _getLastFocusable;
129
131
  // Prevent browser default (e.g. scrolling to bottom of page).
130
132
  event.preventDefault();
131
- (_getLastFocusable = (0, _focus.getLastFocusable)({
133
+ (_getLastFocusable = (0, _getLastFocusable2.getLastFocusable)({
132
134
  container: container,
133
135
  filter: filter
134
136
  })) === null || _getLastFocusable === void 0 || _getLastFocusable.focus();
@@ -100,10 +100,10 @@ const SLIDE_AND_FADE_CSS = `
100
100
  * import { slideAndFade } from '@atlaskit/top-layer/animations';
101
101
  *
102
102
  * // Default 4px slide (tooltip)
103
- * <Popup.Content animate={slideAndFade()} />
103
+ * <Popover animate={slideAndFade()} />
104
104
  *
105
105
  * // Custom 8px slide (popup / dropdown)
106
- * <Popup.Content animate={slideAndFade({ distance: 8 })} />
106
+ * <Popover animate={slideAndFade({ distance: 8 })} />
107
107
  * ```
108
108
  */
109
109
  export function slideAndFade(options) {
@@ -162,7 +162,7 @@ const FADE_CSS = `
162
162
  * ```tsx
163
163
  * import { fade } from '@atlaskit/top-layer/animations';
164
164
  *
165
- * <Popup.Content animate={fade()} />
165
+ * <Popover animate={fade()} />
166
166
  * ```
167
167
  */
168
168
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
@@ -218,7 +218,7 @@ const SCALE_AND_FADE_CSS = `
218
218
  * ```tsx
219
219
  * import { scaleAndFade } from '@atlaskit/top-layer/animations';
220
220
  *
221
- * <Popup.Content animate={scaleAndFade()} />
221
+ * <Popover animate={scaleAndFade()} />
222
222
  * ```
223
223
  */
224
224
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
@@ -1 +1,3 @@
1
- export { getFirstFocusable, getLastFocusable, getNextFocusable } from '../focus';
1
+ export { getFirstFocusable } from '../focus/get-first-focusable';
2
+ export { getLastFocusable } from '../focus/get-last-focusable';
3
+ export { getNextFocusable } from '../focus/get-next-focusable';
@@ -0,0 +1 @@
1
+ export { getAriaForTrigger } from '../internal/get-aria-for-trigger';
@@ -0,0 +1 @@
1
+ export { PopoverSurface } from '../popover-surface';
@@ -0,0 +1 @@
1
+ export { useAnchorPositionAtPoint } from '../internal/use-anchor-position-at-point';
@@ -0,0 +1,15 @@
1
+ import { useId } from '@atlaskit/ds-lib/use-id';
2
+ /**
3
+ * Returns a stable HTML `id` used to wire a trigger element to its popover
4
+ * via ARIA (`aria-controls`) and the Popover API (`popovertarget`).
5
+ *
6
+ * The returned value is intended for the `id` attribute on the popover and
7
+ * for the matching `aria-controls` / `popovertarget` references on the
8
+ * trigger. It is NOT a CSS `anchor-name` value: CSS anchor positioning is
9
+ * handled internally by `useAnchorPosition`, which mints and applies its
10
+ * own `anchor-name` on the trigger element.
11
+ */
12
+ export function usePopoverId() {
13
+ // prefixing for debug clarity in the DOM
14
+ return `popover-${useId()}`;
15
+ }
@@ -0,0 +1,14 @@
1
+ import { getFocusables } from './get-focusables';
2
+ /**
3
+ * Returns the first focusable element within the container.
4
+ */
5
+ export function getFirstFocusable({
6
+ container,
7
+ filter
8
+ }) {
9
+ const items = getFocusables({
10
+ container,
11
+ filter
12
+ });
13
+ return items.length > 0 ? items[0] : null;
14
+ }
@@ -0,0 +1,19 @@
1
+ import { isInSameLayer } from './is-in-same-layer';
2
+ import { selectors } from './selectors';
3
+ /**
4
+ * Returns all focusable HTMLElements within the container, optionally filtered.
5
+ *
6
+ * Focusables that belong to a nested top-layer scope (a `[popover]` or
7
+ * `<dialog>` descendant of the container) are excluded - those elements
8
+ * are owned by the inner layer's focus management. The container itself
9
+ * is allowed to be a popover/dialog; only nested ones are filtered.
10
+ */
11
+ export function getFocusables({
12
+ container,
13
+ filter
14
+ }) {
15
+ return Array.from(container.querySelectorAll(selectors.focusable)).filter(element => element instanceof HTMLElement).filter(element => isInSameLayer({
16
+ element,
17
+ container
18
+ })).filter(element => !filter || filter(element, container));
19
+ }
@@ -0,0 +1,14 @@
1
+ import { getFocusables } from './get-focusables';
2
+ /**
3
+ * Returns the last focusable element within the container.
4
+ */
5
+ export function getLastFocusable({
6
+ container,
7
+ filter
8
+ }) {
9
+ const items = getFocusables({
10
+ container,
11
+ filter
12
+ });
13
+ return items.length > 0 ? items[items.length - 1] : null;
14
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Returns the next focusable element in the given direction relative to the
3
+ * currently focused element within the container. Wraps around at both ends.
4
+ *
5
+ * Returns `null` if there is no focused element within the container or if
6
+ * the focused element is not in the list of focusable elements.
7
+ */
8
+
9
+ import { getFocusables } from './get-focusables';
10
+ import { selectors } from './selectors';
11
+ export function getNextFocusable({
12
+ container,
13
+ direction,
14
+ filter
15
+ }) {
16
+ var _all$nextIndex;
17
+ const all = getFocusables({
18
+ container,
19
+ filter
20
+ });
21
+ const current = container.querySelector(selectors.focused);
22
+ if (!(current instanceof HTMLElement)) {
23
+ return null;
24
+ }
25
+ const index = all.indexOf(current);
26
+ if (index === -1) {
27
+ return null;
28
+ }
29
+ const nextIndex = (() => {
30
+ if (direction === 'forwards') {
31
+ return (index + 1) % all.length;
32
+ }
33
+ const proposed = index - 1;
34
+ // if going into negative numbers, loop back to the last item
35
+ return proposed < 0 ? all.length - 1 : proposed;
36
+ })();
37
+ return (_all$nextIndex = all[nextIndex]) !== null && _all$nextIndex !== void 0 ? _all$nextIndex : null;
38
+ }
@@ -0,0 +1,18 @@
1
+ const topLayerSelector = '[popover], dialog, [role="dialog"], [role="alertdialog"]';
2
+
3
+ /**
4
+ * Returns true when `element` and `container` resolve to the same nearest
5
+ * top-layer host (or both resolve to `null`, meaning the document layer).
6
+ */
7
+ export function isInSameLayer({
8
+ element,
9
+ container
10
+ }) {
11
+ const elementLayer = element.closest(topLayerSelector);
12
+ const containerLayer = container.closest(topLayerSelector);
13
+ // Both elements are in the "document" layer
14
+ if (!elementLayer && !containerLayer) {
15
+ return true;
16
+ }
17
+ return elementLayer === containerLayer;
18
+ }
@@ -0,0 +1,28 @@
1
+ import { getDocument } from '@atlaskit/browser-apis';
2
+ import { isInSameLayer } from './is-in-same-layer';
3
+
4
+ /**
5
+ * Returns `true` when `document.activeElement` is inside a nested top-layer
6
+ * descendant of `container` (a `[popover]`, `<dialog>`, `[role="dialog"]` or
7
+ * `[role="alertdialog"]` that is itself a descendant of `container`).
8
+ */
9
+ export function isNestedLayerFocused({
10
+ container
11
+ }) {
12
+ var _getDocument;
13
+ const focused = (_getDocument = getDocument()) === null || _getDocument === void 0 ? void 0 : _getDocument.activeElement;
14
+ if (!(focused instanceof HTMLElement)) {
15
+ return false;
16
+ }
17
+
18
+ // Cannot be in a nested layer if it is not in the container
19
+ if (!container.contains(focused)) {
20
+ return false;
21
+ }
22
+
23
+ // If not in the same layer, must be in a nested layer
24
+ return !isInSameLayer({
25
+ element: focused,
26
+ container
27
+ });
28
+ }