@atlaskit/top-layer 0.13.0 → 0.15.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 (179) hide show
  1. package/CHANGELOG.md +23 -0
  2. package/README.md +61 -34
  3. package/dist/cjs/animations/presets.js +4 -4
  4. package/dist/cjs/dialog/create-close-event.js +1 -2
  5. package/dist/cjs/entry-points/dialog.js +6 -0
  6. package/dist/cjs/entry-points/get-aria-for-trigger.js +12 -0
  7. package/dist/cjs/entry-points/popover-surface.js +12 -0
  8. package/dist/cjs/entry-points/popover.js +6 -0
  9. package/dist/cjs/entry-points/use-popover-id.js +21 -0
  10. package/dist/cjs/internal/get-aria-for-trigger.js +88 -0
  11. package/dist/cjs/internal/role-types.js +64 -1
  12. package/dist/cjs/internal/slot.js +1 -1
  13. package/dist/cjs/internal/use-anchor-position.js +30 -14
  14. package/dist/cjs/popover/create-close-event.js +1 -2
  15. package/dist/cjs/popover/popover.js +79 -80
  16. package/dist/cjs/popover-surface/index.js +12 -0
  17. package/dist/cjs/{popup/popup-surface.js → popover-surface/popover-surface.js} +9 -12
  18. package/dist/cjs/testing/polyfill.js +9 -6
  19. package/dist/es2019/animations/presets.js +4 -4
  20. package/dist/es2019/dialog/create-close-event.js +1 -2
  21. package/dist/es2019/entry-points/dialog.js +1 -1
  22. package/dist/es2019/entry-points/get-aria-for-trigger.js +1 -0
  23. package/dist/es2019/entry-points/popover-surface.js +1 -0
  24. package/dist/es2019/entry-points/popover.js +1 -1
  25. package/dist/es2019/entry-points/use-popover-id.js +15 -0
  26. package/dist/es2019/internal/get-aria-for-trigger.js +84 -0
  27. package/dist/es2019/internal/role-types.js +59 -0
  28. package/dist/es2019/internal/slot.js +1 -1
  29. package/dist/es2019/internal/use-anchor-position.js +16 -12
  30. package/dist/es2019/popover/create-close-event.js +1 -2
  31. package/dist/es2019/popover/popover.js +79 -80
  32. package/dist/es2019/popover-surface/index.js +1 -0
  33. package/dist/es2019/popover-surface/popover-surface.js +27 -0
  34. package/dist/es2019/testing/polyfill.js +9 -6
  35. package/dist/esm/animations/presets.js +4 -4
  36. package/dist/esm/dialog/create-close-event.js +1 -2
  37. package/dist/esm/entry-points/dialog.js +1 -1
  38. package/dist/esm/entry-points/get-aria-for-trigger.js +1 -0
  39. package/dist/esm/entry-points/popover-surface.js +1 -0
  40. package/dist/esm/entry-points/popover.js +1 -1
  41. package/dist/esm/entry-points/use-popover-id.js +15 -0
  42. package/dist/esm/internal/get-aria-for-trigger.js +83 -0
  43. package/dist/esm/internal/role-types.js +58 -0
  44. package/dist/esm/internal/slot.js +1 -1
  45. package/dist/esm/internal/use-anchor-position.js +30 -14
  46. package/dist/esm/popover/create-close-event.js +1 -2
  47. package/dist/esm/popover/popover.js +79 -80
  48. package/dist/esm/popover-surface/index.js +1 -0
  49. package/dist/esm/popover-surface/popover-surface.js +26 -0
  50. package/dist/esm/testing/polyfill.js +9 -6
  51. package/dist/types/animations/presets.d.ts +4 -4
  52. package/dist/types/animations/types.d.ts +1 -9
  53. package/dist/types/dialog/create-close-event.d.ts +1 -2
  54. package/dist/types/dialog/types.d.ts +0 -8
  55. package/dist/types/entry-points/animations.d.ts +1 -1
  56. package/dist/types/entry-points/dialog.d.ts +1 -1
  57. package/dist/types/entry-points/get-aria-for-trigger.d.ts +1 -0
  58. package/dist/types/entry-points/popover-surface.d.ts +2 -0
  59. package/dist/types/entry-points/popover.d.ts +2 -2
  60. package/dist/types/entry-points/use-popover-id.d.ts +11 -0
  61. package/dist/types/internal/get-aria-for-trigger.d.ts +86 -0
  62. package/dist/types/internal/role-types.d.ts +7 -0
  63. package/dist/types/internal/slot.d.ts +2 -2
  64. package/dist/types/popover/create-close-event.d.ts +1 -2
  65. package/dist/types/popover/index.d.ts +1 -1
  66. package/dist/types/popover/popover.d.ts +6 -13
  67. package/dist/types/popover/types.d.ts +6 -5
  68. package/dist/types/popover-surface/index.d.ts +2 -0
  69. package/dist/types/popover-surface/popover-surface.d.ts +21 -0
  70. package/dist/types-ts4.5/animations/presets.d.ts +4 -4
  71. package/dist/types-ts4.5/animations/types.d.ts +1 -9
  72. package/dist/types-ts4.5/dialog/create-close-event.d.ts +1 -2
  73. package/dist/types-ts4.5/dialog/types.d.ts +0 -8
  74. package/dist/types-ts4.5/entry-points/animations.d.ts +1 -1
  75. package/dist/types-ts4.5/entry-points/dialog.d.ts +1 -1
  76. package/dist/types-ts4.5/entry-points/get-aria-for-trigger.d.ts +1 -0
  77. package/dist/types-ts4.5/entry-points/popover-surface.d.ts +2 -0
  78. package/dist/types-ts4.5/entry-points/popover.d.ts +2 -2
  79. package/dist/types-ts4.5/entry-points/use-popover-id.d.ts +11 -0
  80. package/dist/types-ts4.5/internal/get-aria-for-trigger.d.ts +86 -0
  81. package/dist/types-ts4.5/internal/role-types.d.ts +7 -0
  82. package/dist/types-ts4.5/internal/slot.d.ts +2 -2
  83. package/dist/types-ts4.5/popover/create-close-event.d.ts +1 -2
  84. package/dist/types-ts4.5/popover/index.d.ts +1 -1
  85. package/dist/types-ts4.5/popover/popover.d.ts +6 -13
  86. package/dist/types-ts4.5/popover/types.d.ts +6 -5
  87. package/dist/types-ts4.5/popover-surface/index.d.ts +2 -0
  88. package/dist/types-ts4.5/popover-surface/popover-surface.d.ts +21 -0
  89. package/get-aria-for-trigger/package.json +17 -0
  90. package/package.json +3 -3
  91. package/popover-surface/package.json +17 -0
  92. package/use-popover-id/package.json +17 -0
  93. package/create-close-event/package.json +0 -17
  94. package/dialog/create-close-event/package.json +0 -17
  95. package/dist/cjs/entry-points/create-close-event.js +0 -19
  96. package/dist/cjs/entry-points/dialog/create-close-event.js +0 -12
  97. package/dist/cjs/entry-points/popover/create-close-event.js +0 -12
  98. package/dist/cjs/entry-points/popup-surface.js +0 -12
  99. package/dist/cjs/entry-points/popup.js +0 -12
  100. package/dist/cjs/popup/index.js +0 -37
  101. package/dist/cjs/popup/popup-content.js +0 -215
  102. package/dist/cjs/popup/popup-context.js +0 -25
  103. package/dist/cjs/popup/popup-provider.js +0 -15
  104. package/dist/cjs/popup/popup-trigger-function.js +0 -80
  105. package/dist/cjs/popup/popup-trigger.js +0 -66
  106. package/dist/cjs/popup/popup.js +0 -81
  107. package/dist/cjs/popup/types.js +0 -5
  108. package/dist/cjs/popup/use-maybe-popup-context.js +0 -17
  109. package/dist/cjs/popup/use-popup-context.js +0 -20
  110. package/dist/es2019/entry-points/create-close-event.js +0 -9
  111. package/dist/es2019/entry-points/dialog/create-close-event.js +0 -1
  112. package/dist/es2019/entry-points/popover/create-close-event.js +0 -1
  113. package/dist/es2019/entry-points/popup-surface.js +0 -1
  114. package/dist/es2019/entry-points/popup.js +0 -1
  115. package/dist/es2019/popup/index.js +0 -33
  116. package/dist/es2019/popup/popup-content.js +0 -207
  117. package/dist/es2019/popup/popup-context.js +0 -20
  118. package/dist/es2019/popup/popup-provider.js +0 -10
  119. package/dist/es2019/popup/popup-surface.js +0 -30
  120. package/dist/es2019/popup/popup-trigger-function.js +0 -75
  121. package/dist/es2019/popup/popup-trigger.js +0 -61
  122. package/dist/es2019/popup/popup.js +0 -67
  123. package/dist/es2019/popup/types.js +0 -1
  124. package/dist/es2019/popup/use-maybe-popup-context.js +0 -12
  125. package/dist/es2019/popup/use-popup-context.js +0 -15
  126. package/dist/esm/entry-points/create-close-event.js +0 -9
  127. package/dist/esm/entry-points/dialog/create-close-event.js +0 -1
  128. package/dist/esm/entry-points/popover/create-close-event.js +0 -1
  129. package/dist/esm/entry-points/popup-surface.js +0 -1
  130. package/dist/esm/entry-points/popup.js +0 -1
  131. package/dist/esm/popup/index.js +0 -33
  132. package/dist/esm/popup/popup-content.js +0 -207
  133. package/dist/esm/popup/popup-context.js +0 -20
  134. package/dist/esm/popup/popup-provider.js +0 -10
  135. package/dist/esm/popup/popup-surface.js +0 -29
  136. package/dist/esm/popup/popup-trigger-function.js +0 -75
  137. package/dist/esm/popup/popup-trigger.js +0 -59
  138. package/dist/esm/popup/popup.js +0 -72
  139. package/dist/esm/popup/types.js +0 -1
  140. package/dist/esm/popup/use-maybe-popup-context.js +0 -12
  141. package/dist/esm/popup/use-popup-context.js +0 -15
  142. package/dist/types/entry-points/create-close-event.d.ts +0 -11
  143. package/dist/types/entry-points/dialog/create-close-event.d.ts +0 -2
  144. package/dist/types/entry-points/popover/create-close-event.d.ts +0 -2
  145. package/dist/types/entry-points/popup-surface.d.ts +0 -2
  146. package/dist/types/entry-points/popup.d.ts +0 -2
  147. package/dist/types/popup/index.d.ts +0 -34
  148. package/dist/types/popup/popup-content.d.ts +0 -14
  149. package/dist/types/popup/popup-context.d.ts +0 -96
  150. package/dist/types/popup/popup-provider.d.ts +0 -10
  151. package/dist/types/popup/popup-surface.d.ts +0 -22
  152. package/dist/types/popup/popup-trigger-function.d.ts +0 -112
  153. package/dist/types/popup/popup-trigger.d.ts +0 -14
  154. package/dist/types/popup/popup.d.ts +0 -14
  155. package/dist/types/popup/types.d.ts +0 -321
  156. package/dist/types/popup/use-maybe-popup-context.d.ts +0 -8
  157. package/dist/types/popup/use-popup-context.d.ts +0 -7
  158. package/dist/types-ts4.5/entry-points/create-close-event.d.ts +0 -11
  159. package/dist/types-ts4.5/entry-points/dialog/create-close-event.d.ts +0 -2
  160. package/dist/types-ts4.5/entry-points/popover/create-close-event.d.ts +0 -2
  161. package/dist/types-ts4.5/entry-points/popup-surface.d.ts +0 -2
  162. package/dist/types-ts4.5/entry-points/popup.d.ts +0 -2
  163. package/dist/types-ts4.5/popup/index.d.ts +0 -34
  164. package/dist/types-ts4.5/popup/popup-content.d.ts +0 -14
  165. package/dist/types-ts4.5/popup/popup-context.d.ts +0 -96
  166. package/dist/types-ts4.5/popup/popup-provider.d.ts +0 -10
  167. package/dist/types-ts4.5/popup/popup-surface.d.ts +0 -22
  168. package/dist/types-ts4.5/popup/popup-trigger-function.d.ts +0 -112
  169. package/dist/types-ts4.5/popup/popup-trigger.d.ts +0 -14
  170. package/dist/types-ts4.5/popup/popup.d.ts +0 -14
  171. package/dist/types-ts4.5/popup/types.d.ts +0 -321
  172. package/dist/types-ts4.5/popup/use-maybe-popup-context.d.ts +0 -8
  173. package/dist/types-ts4.5/popup/use-popup-context.d.ts +0 -7
  174. package/popover/create-close-event/package.json +0 -17
  175. package/popup/package.json +0 -17
  176. package/popup-surface/package.json +0 -17
  177. /package/dist/cjs/{popup/popup-surface.compiled.css → popover-surface/popover-surface.compiled.css} +0 -0
  178. /package/dist/es2019/{popup/popup-surface.compiled.css → popover-surface/popover-surface.compiled.css} +0 -0
  179. /package/dist/esm/{popup/popup-surface.compiled.css → popover-surface/popover-surface.compiled.css} +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,28 @@
1
1
  # @atlaskit/top-layer
2
2
 
3
+ ## 0.15.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`e5b4070f51a93`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/e5b4070f51a93) -
8
+ Remove Top Layer compatibility aliases and expose close-event helpers from the `dialog` and
9
+ `popover` entry points.
10
+
11
+ ## 0.14.0
12
+
13
+ ### Minor Changes
14
+
15
+ - [`021a645c6f39a`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/021a645c6f39a) -
16
+ Remove the `Popup` compound and `PopupSurface`; use `Popover`, `PopoverSurface`,
17
+ `useAnchorPosition`, `useWidthFromAnchor`, `usePopoverId`, and `getAriaForTrigger` instead.
18
+
19
+ Nested-popover focus restoration is now automatic: `Popover` snapshots `document.activeElement` in
20
+ `beforetoggle` (newState='open') and restores it on close for focus-capturing roles (`dialog`,
21
+ `alertdialog`, `menu`, `listbox`, `tree`, `grid`) when the close reason is Escape or programmatic.
22
+ Click-outside (light dismiss) intentionally does not restore focus, matching the HTML Popover
23
+ spec's `focusPreviousElement=false` rule. This fixes a Firefox bug where nested popovers left
24
+ focus on `<body>` after dismiss.
25
+
3
26
  ## 0.13.0
4
27
 
5
28
  ### Minor Changes
package/README.md CHANGED
@@ -4,36 +4,63 @@ Low-level top-layer primitives using the native
4
4
  [Popover API](https://developer.mozilla.org/en-US/docs/Web/API/Popover_API) (`popover="auto"`) and
5
5
  [`<dialog>`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/dialog) element.
6
6
 
7
- ## Popup
7
+ ## Popover
8
8
 
9
- Compound component for rendering content in the browser's top layer with CSS Anchor Positioning.
10
- Placement is owned by this compound: root provides it via context, Content applies it (CSS Anchor
11
- Positioning or JS fallback).
9
+ The primary primitive: a `<div>` with the `popover` attribute, plus a small lifecycle (animations,
10
+ role-based focus management, light-dismiss, nested-focus restoration). It does **not** know about
11
+ placement — compose it with the `useAnchorPosition` hook when you need anchor-positioned content.
12
12
 
13
13
  ```tsx
14
- <Popup onClose={handleClose}>
15
- <Popup.Trigger>
16
- <button>Open</button>
17
- </Popup.Trigger>
18
- <Popup.Content role="dialog" label="My popup">
19
- Content here
20
- </Popup.Content>
21
- </Popup>
14
+ import { useRef } from 'react';
15
+ import { slideAndFade } from '@atlaskit/top-layer/animations';
16
+ import { getAriaForTrigger } from '@atlaskit/top-layer/get-aria-for-trigger';
17
+ import { Popover } from '@atlaskit/top-layer/popover';
18
+ import { PopoverSurface } from '@atlaskit/top-layer/popover-surface';
19
+ import { usePopoverId } from '@atlaskit/top-layer/use-popover-id';
20
+ import { useAnchorPosition } from '@atlaskit/top-layer/use-anchor-position';
21
+
22
+ function MyPopup({ isOpen, onClose }: { isOpen: boolean; onClose: () => void }) {
23
+ const triggerRef = useRef<HTMLButtonElement>(null);
24
+ const popoverRef = useRef<HTMLDivElement>(null);
25
+ const popoverId = usePopoverId();
26
+
27
+ useAnchorPosition({
28
+ anchorRef: triggerRef,
29
+ popoverRef,
30
+ placement: { axis: 'block', edge: 'end', align: 'start' },
31
+ });
32
+
33
+ return (
34
+ <>
35
+ <button
36
+ ref={triggerRef}
37
+ onClick={() => popoverRef.current?.togglePopover()}
38
+ {...getAriaForTrigger({ role: 'dialog', isOpen, popoverId })}
39
+ >
40
+ Open
41
+ </button>
42
+ <Popover
43
+ ref={popoverRef}
44
+ id={popoverId}
45
+ role="dialog"
46
+ label="Settings"
47
+ isOpen={isOpen}
48
+ animate={slideAndFade()}
49
+ onClose={onClose}
50
+ >
51
+ <PopoverSurface>Content here</PopoverSurface>
52
+ </Popover>
53
+ </>
54
+ );
55
+ }
22
56
  ```
23
57
 
24
- `placement` defaults to `{}` - "below trigger, centered, with `space.100` gap". Pass an explicit
25
- object to override (e.g. `placement={{ axis: 'inline', edge: 'end' }}` for a popover anchored to the
26
- trigger's right edge).
27
-
28
- For default overlay styling (background, shadow, border-radius), see `PopupSurface` in the package
29
- examples (not currently a public API; we may expose it in a future release).
30
-
31
- ## Popover
32
-
33
- Low-level primitive: a `<div>` with the `popover` attribute and show/hide lifecycle only. No
34
- placement, no trigger wiring — use it when you need top-layer rendering with **fixed or custom
35
- positioning** (e.g. Flag uses `Popover mode="manual"`). For anchor-positioned content next to a
36
- trigger, use **Popup** instead.
58
+ - Focus restoration is automatic. The browser handles it for outermost popovers; `Popover`
59
+ snapshots `document.activeElement` on open and restores it on close for nested cases.
60
+ - For default overlay styling (background, shadow, border-radius), wrap content in `PopoverSurface`
61
+ from `@atlaskit/top-layer/popover-surface`.
62
+ - For trigger-less or custom-positioned UI (flag, tooltip, react-select menu portal), use `Popover`
63
+ on its own without `useAnchorPosition`.
37
64
 
38
65
  ## Dialog
39
66
 
@@ -60,8 +87,8 @@ Compound component for modal dialogs using the native `<dialog>` element with `.
60
87
 
61
88
  ## Animations
62
89
 
63
- Both Popup (and the low-level Popover) and Dialog support CSS-based entry/exit animations via the
64
- `animate` prop. Animations use
90
+ Both `Popover` and `Dialog` support CSS-based entry/exit animations via the `animate` prop.
91
+ Animations use
65
92
  [`@starting-style`](https://developer.mozilla.org/en-US/docs/Web/CSS/@starting-style) for entry and
66
93
  [`allow-discrete`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior) on
67
94
  `display`/`overlay` for exit — no JavaScript animation coordination required.
@@ -80,23 +107,23 @@ import {
80
107
  } from '@atlaskit/top-layer/animations';
81
108
  ```
82
109
 
83
- ### Popup animation
110
+ ### Popover animation
84
111
 
85
- Pass a preset to `Popup.Content` (or to `Popover` when using the low-level primitive without
86
- placement):
112
+ Pass a preset to `Popover`:
87
113
 
88
114
  ```tsx
89
115
  import { slideAndFade } from '@atlaskit/top-layer/animations';
116
+ import { Popover } from '@atlaskit/top-layer/popover';
90
117
 
91
118
  const animation = slideAndFade();
92
119
 
93
- <Popup.Content animate={animation} role="dialog" label="My popup">
120
+ <Popover animate={animation} role="dialog" label="My popover">
94
121
  Content
95
- </Popup.Content>;
122
+ </Popover>;
96
123
  ```
97
124
 
98
- For overlay styling (background, shadow, border-radius), see the `PopupSurface` usage in the package
99
- examples.
125
+ For overlay styling (background, shadow, border-radius), wrap children in `PopoverSurface` from
126
+ `@atlaskit/top-layer/popover-surface`.
100
127
 
101
128
  Available popover presets:
102
129
 
@@ -67,10 +67,10 @@ var SLIDE_AND_FADE_CSS = "\n[data-ds-popover-slide-and-fade] {\n opacity: 0;\n
67
67
  * import { slideAndFade } from '@atlaskit/top-layer/animations';
68
68
  *
69
69
  * // Default 4px slide (tooltip)
70
- * <Popup.Content animate={slideAndFade()} />
70
+ * <Popover animate={slideAndFade()} />
71
71
  *
72
72
  * // Custom 8px slide (popup / dropdown)
73
- * <Popup.Content animate={slideAndFade({ distance: 8 })} />
73
+ * <Popover animate={slideAndFade({ distance: 8 })} />
74
74
  * ```
75
75
  */
76
76
  function slideAndFade(options) {
@@ -104,7 +104,7 @@ var FADE_CSS = "\n[data-ds-popover-fade] {\n opacity: 0;\n transition:\n op
104
104
  * ```tsx
105
105
  * import { fade } from '@atlaskit/top-layer/animations';
106
106
  *
107
- * <Popup.Content animate={fade()} />
107
+ * <Popover animate={fade()} />
108
108
  * ```
109
109
  */
110
110
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
@@ -130,7 +130,7 @@ var SCALE_AND_FADE_CSS = "\n[data-ds-popover-scale-and-fade] {\n opacity: 0;\n
130
130
  * ```tsx
131
131
  * import { scaleAndFade } from '@atlaskit/top-layer/animations';
132
132
  *
133
- * <Popup.Content animate={scaleAndFade()} />
133
+ * <Popover animate={scaleAndFade()} />
134
134
  * ```
135
135
  */
136
136
  // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
@@ -16,8 +16,7 @@ exports.createCloseEvent = createCloseEvent;
16
16
  *
17
17
  * @example
18
18
  * ```tsx
19
- * import { createCloseEvent } from '@atlaskit/top-layer/create-close-event';
20
- * import { type TDialogCloseReason } from '@atlaskit/top-layer/dialog';
19
+ * import { createCloseEvent, type TDialogCloseReason } from '@atlaskit/top-layer/dialog';
21
20
  *
22
21
  * function onDialogClose({ reason }: { reason: TDialogCloseReason }) {
23
22
  * legacyOnClose(createCloseEvent({ reason }));
@@ -9,4 +9,10 @@ Object.defineProperty(exports, "Dialog", {
9
9
  return _dialog.Dialog;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "createCloseEvent", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _dialog.createCloseEvent;
16
+ }
17
+ });
12
18
  var _dialog = require("../dialog");
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "getAriaForTrigger", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _getAriaForTrigger.getAriaForTrigger;
10
+ }
11
+ });
12
+ var _getAriaForTrigger = require("../internal/get-aria-for-trigger");
@@ -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");
@@ -9,4 +9,10 @@ Object.defineProperty(exports, "Popover", {
9
9
  return _popover.Popover;
10
10
  }
11
11
  });
12
+ Object.defineProperty(exports, "createPopoverCloseEvent", {
13
+ enumerable: true,
14
+ get: function get() {
15
+ return _popover.createPopoverCloseEvent;
16
+ }
17
+ });
12
18
  var _popover = require("../popover");
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.usePopoverId = usePopoverId;
7
+ var _useId = require("@atlaskit/ds-lib/use-id");
8
+ /**
9
+ * Returns a stable HTML `id` used to wire a trigger element to its popover
10
+ * via ARIA (`aria-controls`) and the Popover API (`popovertarget`).
11
+ *
12
+ * The returned value is intended for the `id` attribute on the popover and
13
+ * for the matching `aria-controls` / `popovertarget` references on the
14
+ * trigger. It is NOT a CSS `anchor-name` value: CSS anchor positioning is
15
+ * handled internally by `useAnchorPosition`, which mints and applies its
16
+ * own `anchor-name` on the trigger element.
17
+ */
18
+ function usePopoverId() {
19
+ // prefixing for debug clarity in the DOM
20
+ return "popover-".concat((0, _useId.useId)());
21
+ }
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.getAriaForTrigger = getAriaForTrigger;
7
+ var _roleToAriaHasPopup = require("./role-to-aria-has-popup");
8
+ /**
9
+ * Roles accepted by `getAriaForTrigger`.
10
+ *
11
+ * Excludes tooltip-family roles (`tooltip`, `note`, `status`, `alert`, `log`)
12
+ * because the correct trigger wiring for those is `aria-describedby`, not
13
+ * `aria-haspopup` / `aria-expanded` / `aria-controls`. Use `aria-describedby`
14
+ * manually for tooltip triggers.
15
+ */
16
+
17
+ /**
18
+ * Non-undefined subset of `TAriaHasPopupValue`. Every role accepted by
19
+ * `getAriaForTrigger` maps to a concrete `aria-haspopup` string, so the
20
+ * trigger always receives a defined attribute value.
21
+ */
22
+
23
+ /**
24
+ * Returns the ARIA attributes to spread onto a click-activated popover trigger.
25
+ *
26
+ * Centralises three attributes that are easy to forget or get wrong individually:
27
+ *
28
+ * - `aria-haspopup` - derived from the popover's role (e.g. `dialog → "dialog"`,
29
+ * `menu → "menu"`, `tooltip → undefined`). React omits the attribute when
30
+ * the value is `undefined`.
31
+ * - `aria-expanded` - reflects the current open state.
32
+ * - `aria-controls` - references the popover element by its id, even
33
+ * while the popover is closed. The relationship is stable; `aria-expanded`
34
+ * carries the current visibility state.
35
+ *
36
+ * **This function is for click/keyboard-activated popovers only.** For
37
+ * hover-driven tooltips, the trigger should use `aria-describedby` instead.
38
+ *
39
+ * @example
40
+ * ```tsx
41
+ * import { getAriaForTrigger } from '@atlaskit/top-layer/get-aria-for-trigger';
42
+ * import { usePopoverId } from '@atlaskit/top-layer/use-popover-id';
43
+ *
44
+ * const popoverId = usePopoverId();
45
+ * const [isOpen, setIsOpen] = useState(false);
46
+ *
47
+ * return (
48
+ * <>
49
+ * <button
50
+ * ref={triggerRef}
51
+ * onClick={() => setIsOpen((previous) => !previous)}
52
+ * {...getAriaForTrigger({ role: 'dialog', isOpen, popoverId })}
53
+ * >
54
+ * Open
55
+ * </button>
56
+ * <Popover
57
+ * id={popoverId}
58
+ * role="dialog"
59
+ * label="My dialog"
60
+ * isOpen={isOpen}
61
+ * triggerRef={triggerRef}
62
+ * onClose={() => setIsOpen(false)}
63
+ * >
64
+ * …
65
+ * </Popover>
66
+ * </>
67
+ * );
68
+ * ```
69
+ */
70
+ function getAriaForTrigger(_ref) {
71
+ var role = _ref.role,
72
+ isOpen = _ref.isOpen,
73
+ popoverId = _ref.popoverId;
74
+ // `roleToAriaHasPopup` accepts a wider role union (including tooltip-family
75
+ // roles that map to `undefined`). `TAriaForTriggerRole` excludes those, so
76
+ // the returned value is guaranteed to be a defined string. The cast narrows
77
+ // the wider helper signature to match.
78
+ var ariaHasPopup = (0, _roleToAriaHasPopup.roleToAriaHasPopup)({
79
+ role: role
80
+ });
81
+ return {
82
+ 'aria-haspopup': ariaHasPopup,
83
+ 'aria-expanded': isOpen,
84
+ // Keep the trigger-to-popover relationship stable. `aria-expanded`
85
+ // tells assistive technology whether the controlled popover is visible.
86
+ 'aria-controls': popoverId
87
+ };
88
+ }
@@ -1 +1,64 @@
1
- "use strict";
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.shouldFocusIntoPopover = shouldFocusIntoPopover;
7
+ /**
8
+ * Valid values for the `aria-haspopup` attribute.
9
+ *
10
+ * Derived from the HTML spec - maps popover roles to what the trigger
11
+ * announces. `undefined` means the attribute is omitted entirely (used for
12
+ * non-popup roles like `tooltip`/`status`/`alert`/`note`/`log` where
13
+ * `aria-haspopup` would be misleading).
14
+ *
15
+ * `true` is intentionally NOT in the union - the runtime only ever produces
16
+ * the explicit string forms, so widening the type would invite consumers to
17
+ * pass `true` and get an `aria-haspopup="true"` serialisation that the
18
+ * runtime no longer emits.
19
+ */
20
+
21
+ /**
22
+ * Roles that require an accessible name (`label` or `labelledBy`) per WCAG 4.1.2.
23
+ * Without a name, assistive technology cannot identify these landmarks.
24
+ */
25
+
26
+ /**
27
+ * Roles where the accessible name is derived from content or provided externally
28
+ * (e.g. a combobox labels its listbox, tooltip content IS the accessible name).
29
+ */
30
+
31
+ // Shared ARIA role discrimination types
32
+ //
33
+ // These encode the WCAG 4.1.2 constraint: roles like `dialog`, `alertdialog`,
34
+ // and `menu` MUST have an accessible name (either `label` or `labelledBy`).
35
+ // TypeScript enforces this at compile time via discriminated unions.
36
+
37
+ /**
38
+ * ARIA role props where a role is always required.
39
+ *
40
+ * Used by `TPopupContentProps`. Popup content must always declare
41
+ * its role so assistive technology can identify the layer.
42
+ */
43
+
44
+ /**
45
+ * ARIA role props where a role is optional.
46
+ *
47
+ * Used by `TPopoverProps`. The low-level primitive allows omitting
48
+ * the role for cases where it is set externally or not needed.
49
+ */
50
+
51
+ var rolesThatMoveFocus = new Set(['dialog', 'alertdialog', 'menu', 'listbox', 'tree', 'grid']);
52
+
53
+ /**
54
+ * Returns `true` when the given popover role moves focus into the popover
55
+ * on open, and `false` otherwise (including when `role` is `undefined`).
56
+ */
57
+ // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
58
+ function shouldFocusIntoPopover(_ref) {
59
+ var role = _ref.role;
60
+ if (!role) {
61
+ return false;
62
+ }
63
+ return rolesThatMoveFocus.has(role);
64
+ }
@@ -52,7 +52,7 @@ function isSlotChild(child) {
52
52
  var Slot = exports.Slot = /*#__PURE__*/(0, _react.forwardRef)(function Slot(slotProps, ref) {
53
53
  var rawChildren = slotProps.children,
54
54
  props = (0, _objectWithoutProperties2.default)(slotProps, _excluded);
55
- // `TSlotProps` intersects `Record<string, unknown>`, so `children` is typed as `unknown`.
55
+ // `SlotProps` intersects `Record<string, unknown>`, so `children` is typed as `unknown`.
56
56
  var children = rawChildren;
57
57
  if (!isSlotChild(children)) {
58
58
  return children;
@@ -5,6 +5,8 @@ Object.defineProperty(exports, "__esModule", {
5
5
  value: true
6
6
  });
7
7
  exports.useAnchorPosition = useAnchorPosition;
8
+ var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
9
+ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
8
10
  var _react = require("react");
9
11
  var _bindEventListener = require("bind-event-listener");
10
12
  var _rafSchd = _interopRequireDefault(require("raf-schd"));
@@ -35,15 +37,25 @@ var _setStyle = require("./set-style");
35
37
  // from `./resolve-placement` so search-and-jump lands at the source of truth.
36
38
 
37
39
  /**
38
- * Module-scope no-op `ResizeObserver` stub used in non-DOM jest environments where
40
+ * Module-scope no-op `ResizeObserver` used in non-DOM jest environments where
39
41
  * `ResizeObserver` is `undefined`. Hoisted out of the effect to avoid
40
- * re-allocating on every run.
42
+ * allocating a new class declaration on every run.
41
43
  */
42
- var noopResizeObserver = {
43
- observe: function observe() {},
44
- unobserve: function unobserve() {},
45
- disconnect: function disconnect() {}
46
- };
44
+ var NoopResizeObserver = /*#__PURE__*/function () {
45
+ function NoopResizeObserver() {
46
+ (0, _classCallCheck2.default)(this, NoopResizeObserver);
47
+ }
48
+ return (0, _createClass2.default)(NoopResizeObserver, [{
49
+ key: "observe",
50
+ value: function observe() {}
51
+ }, {
52
+ key: "unobserve",
53
+ value: function unobserve() {}
54
+ }, {
55
+ key: "disconnect",
56
+ value: function disconnect() {}
57
+ }]);
58
+ }();
47
59
 
48
60
  /**
49
61
  * Returns true when the popover is currently open. Wrapped because the
@@ -200,6 +212,7 @@ function useStablePlacement(placement) {
200
212
  * comparison is used internally so re-runs are skipped when the resolved
201
213
  * placement shape is unchanged.
202
214
  */
215
+ // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
203
216
  function useAnchorPosition(_ref3) {
204
217
  var anchorRef = _ref3.anchorRef,
205
218
  popoverRef = _ref3.popoverRef,
@@ -406,17 +419,20 @@ function useAnchorPosition(_ref3) {
406
419
  // Self-disconnects after one valid measurement; ongoing
407
420
  // scroll/resize is handled by the window listeners below.
408
421
  // `ResizeObserver` is missing in some non-DOM jest environments
409
- // (e.g. post-office's `node` environment). Fall back to the
410
- // module-scope `noopResizeObserver` stub there. The scroll/resize
411
- // listeners below still keep the popover positioned in the rare
412
- // case the consumer also polyfilled `showPopover` but not
413
- // `ResizeObserver`. Real browsers always have it.
414
- var resizeObserver = typeof ResizeObserver !== 'undefined' ? new ResizeObserver(function () {
422
+ // (e.g. post-office's `node` environment). Fall back to a no-op
423
+ // observer there. The scroll/resize listeners below still keep
424
+ // the popover positioned in the rare case the consumer also
425
+ // polyfilled `showPopover` but not `ResizeObserver`. Real
426
+ // browsers always have it. The `NoopResizeObserver` class is
427
+ // hoisted to module scope (see top of file) so we do not allocate
428
+ // a new constructor on every effect run.
429
+ var ResizeObserverImpl = typeof ResizeObserver !== 'undefined' ? ResizeObserver : NoopResizeObserver;
430
+ var resizeObserver = new ResizeObserverImpl(function () {
415
431
  if (popover.offsetWidth > 0 && popover.offsetHeight > 0) {
416
432
  update();
417
433
  resizeObserver.disconnect();
418
434
  }
419
- }) : noopResizeObserver;
435
+ });
420
436
 
421
437
  // If the popover is already open by the time this effect runs (for
422
438
  // example, the parent `useAnchorPosition` effect runs after the child
@@ -18,8 +18,7 @@ exports.createPopoverCloseEvent = createPopoverCloseEvent;
18
18
  *
19
19
  * @example
20
20
  * ```tsx
21
- * import { createPopoverCloseEvent } from '@atlaskit/top-layer/create-close-event';
22
- * import { type TPopoverCloseReason } from '@atlaskit/top-layer/popover';
21
+ * import { createPopoverCloseEvent, type TPopoverCloseReason } from '@atlaskit/top-layer/popover';
23
22
  *
24
23
  * function onPopoverClose({ reason }: { reason: TPopoverCloseReason }) {
25
24
  * legacyOnClose(createPopoverCloseEvent({ reason }));