@atlaskit/top-layer 0.1.0 → 0.1.2

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # @atlaskit/top-layer
2
2
 
3
+ ## 0.1.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Updated dependencies
8
+
9
+ ## 0.1.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [`02483200273ec`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/02483200273ec) -
14
+ Enrol all Design System UI packages into the React Compiler with platform gating via
15
+ isReactCompilerActivePlatform.
16
+ - Updated dependencies
17
+
3
18
  ## 0.1.0
4
19
 
5
20
  ### Minor Changes
package/README.md CHANGED
@@ -21,14 +21,15 @@ Positioning or JS fallback).
21
21
  </Popup>
22
22
  ```
23
23
 
24
- For default overlay styling (background, shadow, border-radius), see `PopupSurface` in the package examples (not currently a public API; we may expose it in a future release).
24
+ For default overlay styling (background, shadow, border-radius), see `PopupSurface` in the package
25
+ examples (not currently a public API; we may expose it in a future release).
25
26
 
26
27
  ## Popover
27
28
 
28
29
  Low-level primitive: a `<div>` with the `popover` attribute and show/hide lifecycle only. No
29
- placement, no trigger wiring — use it when you need top-layer rendering with **fixed or
30
- custom positioning** (e.g. Flag uses `Popover mode="manual"`). For anchor-positioned content
31
- next to a trigger, use **Popup** instead.
30
+ placement, no trigger wiring — use it when you need top-layer rendering with **fixed or custom
31
+ positioning** (e.g. Flag uses `Popover mode="manual"`). For anchor-positioned content next to a
32
+ trigger, use **Popup** instead.
32
33
 
33
34
  ## Dialog
34
35
 
@@ -56,9 +57,9 @@ Compound component for modal dialogs using the native `<dialog>` element with `.
56
57
  ## Animations
57
58
 
58
59
  Both Popup (and the low-level Popover) and Dialog support CSS-based entry/exit animations via the
59
- `animate` prop. Animations
60
- use [`@starting-style`](https://developer.mozilla.org/en-US/docs/Web/CSS/@starting-style) for entry
61
- and [`allow-discrete`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior) on
60
+ `animate` prop. Animations use
61
+ [`@starting-style`](https://developer.mozilla.org/en-US/docs/Web/CSS/@starting-style) for entry and
62
+ [`allow-discrete`](https://developer.mozilla.org/en-US/docs/Web/CSS/transition-behavior) on
62
63
  `display`/`overlay` for exit — no JavaScript animation coordination required.
63
64
 
64
65
  Presets are available from `@atlaskit/top-layer/animations`:
@@ -90,7 +91,8 @@ const animation = slideAndFade();
90
91
  </Popup.Content>;
91
92
  ```
92
93
 
93
- For overlay styling (background, shadow, border-radius), see the `PopupSurface` usage in the package examples.
94
+ For overlay styling (background, shadow, border-radius), see the `PopupSurface` usage in the package
95
+ examples.
94
96
 
95
97
  Available popover presets:
96
98
 
@@ -130,20 +132,20 @@ Browser tests in `__tests__/playwright/` verify the following WCAG 2.2 success c
130
132
  [`notes/audits/accessibility-audit-report.md`](notes/audits/accessibility-audit-report.md) for
131
133
  details.
132
134
 
133
- | A11y criterion | Browser test |
134
- | ------------------------------------- | ------------ |
135
- | 1.3.1 Info and Relationships | ✓ |
136
- | 1.3.2 Meaningful Sequence | ✓ |
137
- | 2.1.1 Keyboard | ✓ |
138
- | 2.1.2 No Keyboard Trap | ✓ |
139
- | 2.4.3 Focus Order | ✓ |
140
- | 2.4.7 Focus Visible | ✓ |
135
+ | A11y criterion | Browser test |
136
+ | ------------------------------------ | ------------ |
137
+ | 1.3.1 Info and Relationships | ✓ |
138
+ | 1.3.2 Meaningful Sequence | ✓ |
139
+ | 2.1.1 Keyboard | ✓ |
140
+ | 2.1.2 No Keyboard Trap | ✓ |
141
+ | 2.4.3 Focus Order | ✓ |
142
+ | 2.4.7 Focus Visible | ✓ |
141
143
  | 2.4.11 Focus Not Obscured | ✓ |
142
- | 3.2.1 On Focus | ✓ |
144
+ | 3.2.1 On Focus | ✓ |
143
145
  | 4.1.2 Name, Role, Value | ✓ |
144
- | 4.1.3 Status Messages | ✓ |
145
- | Background inertness (modal dialogs) | ✓ |
146
- | Close reasons (Dialog) | ✓ |
146
+ | 4.1.3 Status Messages | ✓ |
147
+ | Background inertness (modal dialogs) | ✓ |
148
+ | Close reasons (Dialog) | ✓ |
147
149
 
148
150
  ## Documentation
149
151
 
@@ -117,7 +117,7 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
117
117
  var mode = modeProp === 'hint' && !supportsPopoverHint() ? 'auto' : modeProp;
118
118
 
119
119
  // Distinguishes programmatic hidePopover() from browser-initiated dismiss.
120
- // When we call hidePopover() ourselves the toggle event fires synchronously —
120
+ // When we call hidePopover() ourselves the beforetoggle event fires synchronously —
121
121
  // this ref prevents the toggle handler from calling onClose redundantly.
122
122
  var programmaticCloseRef = (0, _react.useRef)(false);
123
123
 
@@ -203,9 +203,14 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
203
203
  });
204
204
  }, [preset, placement]);
205
205
 
206
- // Show/hide based on isOpen. try/catch because show/hide throw if the
207
- // element is already in the target state (e.g. browser dismissed via
208
- // light-dismiss before our effect ran).
206
+ // Show/hide based on isOpen.
207
+ // showPopover() and hidePopover() are no-ops when the popover is already
208
+ // in the target state (e.g. browser dismissed via light-dismiss before our
209
+ // effect ran).
210
+ // Defensive try/catch: these APIs throw InvalidStateError if the element
211
+ // is disconnected or missing the popover attribute. While we don't expect
212
+ // that to happen in normal usage, it can occur in edge cases (e.g. React
213
+ // concurrent mode, StrictMode double-effects, or unmount races).
209
214
  (0, _react.useLayoutEffect)(function () {
210
215
  var el = ownRef.current;
211
216
  if (!el) {
@@ -213,26 +218,23 @@ var Popover = exports.Popover = /*#__PURE__*/(0, _react.forwardRef)(function Pop
213
218
  }
214
219
  if (isOpen) {
215
220
  programmaticCloseRef.current = false;
221
+ // Defensive: element may be disconnected or in an unexpected state.
216
222
  try {
217
223
  el.showPopover();
218
- } catch (_unused) {
219
- // Already showing or unsupported — DOM matches intent.
220
- }
224
+ } catch (_unused) {}
221
225
  return function () {
222
226
  programmaticCloseRef.current = true;
227
+ // Defensive: element may be disconnected or in an unexpected state.
223
228
  try {
224
229
  el.hidePopover();
225
- } catch (_unused2) {
226
- // Already hidden — DOM matches intent.
227
- }
230
+ } catch (_unused2) {}
228
231
  };
229
232
  }
230
233
  programmaticCloseRef.current = true;
234
+ // Defensive: element may be disconnected or in an unexpected state.
231
235
  try {
232
236
  el.hidePopover();
233
- } catch (_unused3) {
234
- // Already hidden — DOM matches intent.
235
- }
237
+ } catch (_unused3) {}
236
238
  }, [isOpen]);
237
239
  return /*#__PURE__*/_react.default.createElement("div", (0, _extends2.default)({
238
240
  ref: combinedRef,
@@ -54,7 +54,10 @@ function PopupTriggerFunction(_ref) {
54
54
  var toggle = (0, _react.useCallback)(function () {
55
55
  var popoverEl = popoverRef.current;
56
56
  if (popoverEl) {
57
- popoverEl.togglePopover();
57
+ // Defensive: element may be disconnected or in an unexpected state.
58
+ try {
59
+ popoverEl.togglePopover();
60
+ } catch (_unused) {}
58
61
  }
59
62
  }, [popoverRef]);
60
63
  var ariaAttributes = (0, _react.useMemo)(function () {
@@ -59,11 +59,10 @@ function PopupTrigger(_ref) {
59
59
  // - If React thinks it was closed → the user wants to open.
60
60
  // Call showPopover().
61
61
  if (!isOpenRef.current) {
62
+ // Defensive: element may be disconnected or in an unexpected state.
62
63
  try {
63
64
  popoverEl.showPopover();
64
- } catch (_unused) {
65
- // Already showing — safe to ignore.
66
- }
65
+ } catch (_unused) {}
67
66
  }
68
67
  // When isOpenRef.current is true, the browser's light-dismiss
69
68
  // already closed the popover and fired the toggle event, which
@@ -107,7 +107,7 @@ export const Popover = /*#__PURE__*/forwardRef(function Popover({
107
107
  const mode = modeProp === 'hint' && !supportsPopoverHint() ? 'auto' : modeProp;
108
108
 
109
109
  // Distinguishes programmatic hidePopover() from browser-initiated dismiss.
110
- // When we call hidePopover() ourselves the toggle event fires synchronously —
110
+ // When we call hidePopover() ourselves the beforetoggle event fires synchronously —
111
111
  // this ref prevents the toggle handler from calling onClose redundantly.
112
112
  const programmaticCloseRef = useRef(false);
113
113
 
@@ -190,9 +190,14 @@ export const Popover = /*#__PURE__*/forwardRef(function Popover({
190
190
  });
191
191
  }, [preset, placement]);
192
192
 
193
- // Show/hide based on isOpen. try/catch because show/hide throw if the
194
- // element is already in the target state (e.g. browser dismissed via
195
- // light-dismiss before our effect ran).
193
+ // Show/hide based on isOpen.
194
+ // showPopover() and hidePopover() are no-ops when the popover is already
195
+ // in the target state (e.g. browser dismissed via light-dismiss before our
196
+ // effect ran).
197
+ // Defensive try/catch: these APIs throw InvalidStateError if the element
198
+ // is disconnected or missing the popover attribute. While we don't expect
199
+ // that to happen in normal usage, it can occur in edge cases (e.g. React
200
+ // concurrent mode, StrictMode double-effects, or unmount races).
196
201
  useLayoutEffect(() => {
197
202
  const el = ownRef.current;
198
203
  if (!el) {
@@ -200,26 +205,23 @@ export const Popover = /*#__PURE__*/forwardRef(function Popover({
200
205
  }
201
206
  if (isOpen) {
202
207
  programmaticCloseRef.current = false;
208
+ // Defensive: element may be disconnected or in an unexpected state.
203
209
  try {
204
210
  el.showPopover();
205
- } catch {
206
- // Already showing or unsupported — DOM matches intent.
207
- }
211
+ } catch {}
208
212
  return () => {
209
213
  programmaticCloseRef.current = true;
214
+ // Defensive: element may be disconnected or in an unexpected state.
210
215
  try {
211
216
  el.hidePopover();
212
- } catch {
213
- // Already hidden — DOM matches intent.
214
- }
217
+ } catch {}
215
218
  };
216
219
  }
217
220
  programmaticCloseRef.current = true;
221
+ // Defensive: element may be disconnected or in an unexpected state.
218
222
  try {
219
223
  el.hidePopover();
220
- } catch {
221
- // Already hidden — DOM matches intent.
222
- }
224
+ } catch {}
223
225
  }, [isOpen]);
224
226
  return /*#__PURE__*/React.createElement("div", _extends({
225
227
  ref: combinedRef,
@@ -51,7 +51,10 @@ export function PopupTriggerFunction({
51
51
  const toggle = useCallback(() => {
52
52
  const popoverEl = popoverRef.current;
53
53
  if (popoverEl) {
54
- popoverEl.togglePopover();
54
+ // Defensive: element may be disconnected or in an unexpected state.
55
+ try {
56
+ popoverEl.togglePopover();
57
+ } catch {}
55
58
  }
56
59
  }, [popoverRef]);
57
60
  const ariaAttributes = useMemo(() => ({
@@ -53,11 +53,10 @@ export function PopupTrigger({
53
53
  // - If React thinks it was closed → the user wants to open.
54
54
  // Call showPopover().
55
55
  if (!isOpenRef.current) {
56
+ // Defensive: element may be disconnected or in an unexpected state.
56
57
  try {
57
58
  popoverEl.showPopover();
58
- } catch {
59
- // Already showing — safe to ignore.
60
- }
59
+ } catch {}
61
60
  }
62
61
  // When isOpenRef.current is true, the browser's light-dismiss
63
62
  // already closed the popover and fired the toggle event, which
@@ -108,7 +108,7 @@ export var Popover = /*#__PURE__*/forwardRef(function Popover(_ref, ref) {
108
108
  var mode = modeProp === 'hint' && !supportsPopoverHint() ? 'auto' : modeProp;
109
109
 
110
110
  // Distinguishes programmatic hidePopover() from browser-initiated dismiss.
111
- // When we call hidePopover() ourselves the toggle event fires synchronously —
111
+ // When we call hidePopover() ourselves the beforetoggle event fires synchronously —
112
112
  // this ref prevents the toggle handler from calling onClose redundantly.
113
113
  var programmaticCloseRef = useRef(false);
114
114
 
@@ -194,9 +194,14 @@ export var Popover = /*#__PURE__*/forwardRef(function Popover(_ref, ref) {
194
194
  });
195
195
  }, [preset, placement]);
196
196
 
197
- // Show/hide based on isOpen. try/catch because show/hide throw if the
198
- // element is already in the target state (e.g. browser dismissed via
199
- // light-dismiss before our effect ran).
197
+ // Show/hide based on isOpen.
198
+ // showPopover() and hidePopover() are no-ops when the popover is already
199
+ // in the target state (e.g. browser dismissed via light-dismiss before our
200
+ // effect ran).
201
+ // Defensive try/catch: these APIs throw InvalidStateError if the element
202
+ // is disconnected or missing the popover attribute. While we don't expect
203
+ // that to happen in normal usage, it can occur in edge cases (e.g. React
204
+ // concurrent mode, StrictMode double-effects, or unmount races).
200
205
  useLayoutEffect(function () {
201
206
  var el = ownRef.current;
202
207
  if (!el) {
@@ -204,26 +209,23 @@ export var Popover = /*#__PURE__*/forwardRef(function Popover(_ref, ref) {
204
209
  }
205
210
  if (isOpen) {
206
211
  programmaticCloseRef.current = false;
212
+ // Defensive: element may be disconnected or in an unexpected state.
207
213
  try {
208
214
  el.showPopover();
209
- } catch (_unused) {
210
- // Already showing or unsupported — DOM matches intent.
211
- }
215
+ } catch (_unused) {}
212
216
  return function () {
213
217
  programmaticCloseRef.current = true;
218
+ // Defensive: element may be disconnected or in an unexpected state.
214
219
  try {
215
220
  el.hidePopover();
216
- } catch (_unused2) {
217
- // Already hidden — DOM matches intent.
218
- }
221
+ } catch (_unused2) {}
219
222
  };
220
223
  }
221
224
  programmaticCloseRef.current = true;
225
+ // Defensive: element may be disconnected or in an unexpected state.
222
226
  try {
223
227
  el.hidePopover();
224
- } catch (_unused3) {
225
- // Already hidden — DOM matches intent.
226
- }
228
+ } catch (_unused3) {}
227
229
  }, [isOpen]);
228
230
  return /*#__PURE__*/React.createElement("div", _extends({
229
231
  ref: combinedRef,
@@ -49,7 +49,10 @@ export function PopupTriggerFunction(_ref) {
49
49
  var toggle = useCallback(function () {
50
50
  var popoverEl = popoverRef.current;
51
51
  if (popoverEl) {
52
- popoverEl.togglePopover();
52
+ // Defensive: element may be disconnected or in an unexpected state.
53
+ try {
54
+ popoverEl.togglePopover();
55
+ } catch (_unused) {}
53
56
  }
54
57
  }, [popoverRef]);
55
58
  var ariaAttributes = useMemo(function () {
@@ -51,11 +51,10 @@ export function PopupTrigger(_ref) {
51
51
  // - If React thinks it was closed → the user wants to open.
52
52
  // Call showPopover().
53
53
  if (!isOpenRef.current) {
54
+ // Defensive: element may be disconnected or in an unexpected state.
54
55
  try {
55
56
  popoverEl.showPopover();
56
- } catch (_unused) {
57
- // Already showing — safe to ignore.
58
- }
57
+ } catch (_unused) {}
59
58
  }
60
59
  // When isOpenRef.current is true, the browser's light-dismiss
61
60
  // already closed the popover and fired the toggle event, which
@@ -1,4 +1,4 @@
1
- import { type TPlacementOptions } from '../popup/types';
1
+ import type { TPlacementOptions } from '../popup/types';
2
2
  /**
3
3
  * A self-contained animation preset for top-layer elements (popovers and dialogs).
4
4
  *
@@ -1,4 +1,4 @@
1
- import { type TPlacementOptions } from '../popup/types';
1
+ import type { TPlacementOptions } from '../popup/types';
2
2
  /**
3
3
  * A self-contained arrow preset for PopoverContent.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { type TDialogCloseReason } from './types';
1
+ import type { TDialogCloseReason } from './types';
2
2
  /**
3
3
  * Creates a synthetic DOM event from a `TDialogCloseReason`.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { type TPopoverCloseReason } from './types';
1
+ import type { TPopoverCloseReason } from './types';
2
2
  /**
3
3
  * Creates a synthetic DOM event from a `TPopoverCloseReason`.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { type TPlacementOptions } from '../popup/types';
1
+ import type { TPlacementOptions } from '../popup/types';
2
2
  /**
3
3
  * A self-contained animation preset for top-layer elements (popovers and dialogs).
4
4
  *
@@ -1,4 +1,4 @@
1
- import { type TPlacementOptions } from '../popup/types';
1
+ import type { TPlacementOptions } from '../popup/types';
2
2
  /**
3
3
  * A self-contained arrow preset for PopoverContent.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { type TDialogCloseReason } from './types';
1
+ import type { TDialogCloseReason } from './types';
2
2
  /**
3
3
  * Creates a synthetic DOM event from a `TDialogCloseReason`.
4
4
  *
@@ -1,4 +1,4 @@
1
- import { type TPopoverCloseReason } from './types';
1
+ import type { TPopoverCloseReason } from './types';
2
2
  /**
3
3
  * Creates a synthetic DOM event from a `TPopoverCloseReason`.
4
4
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/top-layer",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "Low-level layering primitives based on popover and dialog",
5
5
  "homepage": "https://atlassian.design/components/top-layer",
6
6
  "repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
@@ -15,6 +15,13 @@
15
15
  ],
16
16
  "atlaskit:src": "src/index.tsx",
17
17
  "atlassian": {
18
+ "react-compiler": {
19
+ "enabled": true,
20
+ "gating": {
21
+ "source": "@atlassian/react-compiler-gating",
22
+ "importSpecifierName": "isReactCompilerActivePlatform"
23
+ }
24
+ },
18
25
  "team": "Design System Team",
19
26
  "website": {
20
27
  "name": "Top Layer",
@@ -29,8 +36,8 @@
29
36
  "dependencies": {
30
37
  "@atlaskit/browser-apis": "^0.0.1",
31
38
  "@atlaskit/css": "^0.19.0",
32
- "@atlaskit/ds-lib": "^6.0.0",
33
- "@atlaskit/tokens": "^11.1.0",
39
+ "@atlaskit/ds-lib": "^7.0.0",
40
+ "@atlaskit/tokens": "^12.0.0",
34
41
  "@babel/runtime": "^7.0.0",
35
42
  "@compiled/react": "^0.20.0",
36
43
  "bind-event-listener": "^3.0.0",
@@ -43,13 +50,15 @@
43
50
  "devDependencies": {
44
51
  "@af/integration-testing": "workspace:^",
45
52
  "@af/visual-regression": "workspace:^",
46
- "@atlaskit/button": "^23.10.0",
47
- "@atlaskit/heading": "^5.3.0",
53
+ "@atlaskit/button": "^23.11.0",
54
+ "@atlaskit/heading": "^5.4.0",
48
55
  "@atlaskit/lozenge": "^13.5.0",
49
- "@atlaskit/primitives": "^18.0.0",
56
+ "@atlaskit/primitives": "^18.1.0",
50
57
  "@atlaskit/ssr": "workspace:^",
51
- "@atlaskit/textfield": "^8.2.0",
52
- "@atlassian/testing-library": "^0.4.0",
58
+ "@atlaskit/textfield": "^8.3.0",
59
+ "@atlassian/react-compiler-gating": "workspace:^",
60
+ "@atlassian/ssr-tests": "workspace:^",
61
+ "@atlassian/testing-library": "^0.5.0",
53
62
  "@testing-library/react": "^16.3.0",
54
63
  "@types/raf-schd": "^4.0.1",
55
64
  "tiny-invariant": "^1.2.0"