@atlaskit/top-layer 1.6.0 → 1.7.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 (41) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/README.md +13 -0
  3. package/compass.yml +10 -1
  4. package/dist/cjs/dialog/dialog-content.compiled.css +0 -10
  5. package/dist/cjs/dialog/dialog-content.js +20 -28
  6. package/dist/cjs/entry-points/animations.js +1 -49
  7. package/dist/cjs/internal/use-animated-visibility.js +14 -17
  8. package/dist/cjs/internal/use-safari-escape-fix.js +62 -0
  9. package/dist/cjs/popover/animations.js +1 -147
  10. package/dist/cjs/popover/popover.compiled.css +1 -10
  11. package/dist/cjs/popover/popover.js +9 -12
  12. package/dist/cjs/testing/polyfill.js +3 -0
  13. package/dist/es2019/dialog/dialog-content.compiled.css +0 -10
  14. package/dist/es2019/dialog/dialog-content.js +20 -28
  15. package/dist/es2019/entry-points/animations.js +0 -2
  16. package/dist/es2019/internal/use-animated-visibility.js +14 -18
  17. package/dist/es2019/internal/use-safari-escape-fix.js +58 -0
  18. package/dist/es2019/popover/animations.js +1 -145
  19. package/dist/es2019/popover/popover.compiled.css +1 -10
  20. package/dist/es2019/popover/popover.js +8 -12
  21. package/dist/es2019/testing/polyfill.js +3 -0
  22. package/dist/esm/dialog/dialog-content.compiled.css +0 -10
  23. package/dist/esm/dialog/dialog-content.js +20 -28
  24. package/dist/esm/entry-points/animations.js +0 -2
  25. package/dist/esm/internal/use-animated-visibility.js +14 -18
  26. package/dist/esm/internal/use-safari-escape-fix.js +57 -0
  27. package/dist/esm/popover/animations.js +1 -144
  28. package/dist/esm/popover/popover.compiled.css +1 -10
  29. package/dist/esm/popover/popover.js +9 -12
  30. package/dist/esm/testing/polyfill.js +3 -0
  31. package/dist/types/dialog/types.d.ts +5 -5
  32. package/dist/types/entry-points/animations.d.ts +0 -2
  33. package/dist/types/internal/use-animated-visibility.d.ts +15 -33
  34. package/dist/types/internal/use-safari-escape-fix.d.ts +12 -0
  35. package/dist/types/popover/animations.d.ts +7 -52
  36. package/dist/types/popover/types.d.ts +6 -3
  37. package/package.json +6 -5
  38. package/dist/cjs/dialog/animations.js +0 -90
  39. package/dist/es2019/dialog/animations.js +0 -80
  40. package/dist/esm/dialog/animations.js +0 -82
  41. package/dist/types/dialog/animations.d.ts +0 -57
package/CHANGELOG.md CHANGED
@@ -1,5 +1,36 @@
1
1
  # @atlaskit/top-layer
2
2
 
3
+ ## 1.7.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [`406346f89178f`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/406346f89178f) -
8
+ Fix a Safari (WebKit) layout bug where `Popover` content could collapse to `0px`. When a
9
+ `max-height: 100%` flex column with a `flex: 1 1 auto; overflow: auto` child is placed inside a
10
+ popover, the user-agent `height: fit-content` default (an indefinite block size) makes the column
11
+ collapse on WebKit. The `Popover` reset now sets `height: auto` to remove the indefinite block
12
+ size; width is left unchanged so anchor-width matching is unaffected.
13
+
14
+ The `Dialog` primitive is intentionally left unchanged for that reset: applying the same reset
15
+ there would stretch the modal `<dialog>` to fill the viewport and force a layout-centering opinion
16
+ onto an otherwise unopinionated primitive. See `notes/decisions/safari-popover-flex-collapse.md`.
17
+
18
+ Also fix a Safari (WebKit) bug where pressing `Escape` while a `popover="auto"` (for example a
19
+ menu) is open inside a modal `Dialog` closed the entire dialog instead of only the popover. On
20
+ WebKit the same Escape also fires the dialog's native `cancel` event. The `Dialog` primitive now
21
+ snapshots — at Escape keydown, before the browser's close action — whether a light-dismissable
22
+ (`auto`/`hint`) popover is open inside it, and if so keeps the dialog open so only the popover is
23
+ dismissed, matching Chromium and Firefox. See
24
+ `notes/decisions/safari-escape-nested-popover-in-dialog.md`.
25
+
26
+ ## 1.6.1
27
+
28
+ ### Patch Changes
29
+
30
+ - [`650f4c7ce7fb2`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/650f4c7ce7fb2) -
31
+ Type-only fixes for TypeScript 7 (tsgo) compatibility with the updated DOM lib. No runtime or
32
+ public API changes.
33
+
3
34
  ## 1.6.0
4
35
 
5
36
  ### Minor Changes
package/README.md CHANGED
@@ -178,6 +178,19 @@ details.
178
178
  | Background inertness (modal dialogs) | ✓ |
179
179
  | Close reasons (Dialog) | ✓ |
180
180
 
181
+ ## Known limitations
182
+
183
+ - **Safari `<dialog>` flex-collapse.** On WebKit, a `max-height: 100%` flex column with a
184
+ `flex: 1 1 auto; overflow: auto` child placed directly inside a `Dialog` collapses to `0px` (the
185
+ block-axis `fit-content` user-agent default is an indefinite height). `Popover` sets
186
+ `height: auto` to avoid this; `Dialog` deliberately does not, to keep the primitive free of layout
187
+ opinions (see
188
+ [`notes/decisions/safari-popover-flex-collapse.md`](notes/decisions/safari-popover-flex-collapse.md)).
189
+ A consumer that builds this shape inside a `Dialog` should give the column a definite height or
190
+ apply its own `height: auto` reset on the surface.
191
+ - TODO: expand this into full public consumer documentation (the recommended workaround and a
192
+ worked example) before the top-layer `Dialog` is broadly adopted.
193
+
181
194
  ## Documentation
182
195
 
183
196
  See [`notes/`](notes/) for project documentation, architecture decisions, migration records, and
package/compass.yml CHANGED
@@ -1,7 +1,7 @@
1
1
  configVersion: 1
2
2
  id: ari:cloud:compass:a436116f-02ce-4520-8fbb-7301462a1674:component/c5751cc6-3513-4070-9deb-af31e86aed34/680f1177-ac84-4787-a7d1-258dd657dc9f
3
3
  name: '@atlaskit/top-layer'
4
- ownerId: ari:cloud:identity::team/be19136e-6275-419f-be0c-fcee844b8684 # Design System Engineers
4
+ ownerId: ari:cloud:teams::team/814283d6-8695-4329-b2f8-d78b2645722f # Design System Team (ADS)
5
5
  labels:
6
6
  - platform-code
7
7
  - platform-afm
@@ -27,6 +27,9 @@ customFields:
27
27
  - name: Technical Owner
28
28
  type: user
29
29
  value: ari:cloud:identity::user/557058:86a9b692-7997-49cb-9984-080801b1de91 # Jared Crowe
30
+ - name: Reviewer Team
31
+ type: text
32
+ value: ari:cloud:teams::team/be19136e-6275-419f-be0c-fcee844b8684 # Design System Engineers
30
33
  - name: Required Reviewers Opt In
31
34
  type: boolean
32
35
  value: true
@@ -36,3 +39,9 @@ customFields:
36
39
  - name: Required Reviewer Approvals
37
40
  type: number
38
41
  value: 1
42
+ - name: Trusted Committers
43
+ type: text
44
+ value: ari:cloud:teams::team/814283d6-8695-4329-b2f8-d78b2645722f # Design System Team (ADS)
45
+ - name: Trusted Reviewer Teams
46
+ type: text
47
+ value: ari:cloud:teams::team/42f4416b-e028-4daa-b2a5-afe213ac75e1 # Design System Designers
@@ -20,23 +20,15 @@
20
20
  ._1o51q7pw{animation-fill-mode:forwards}
21
21
  ._1oeci9qs{transition-duration:var(--ds-duration-medium,.2s)}
22
22
  ._1oil1d08[open]{transition-timing-function:var(--ds-easing-inout-bold,cubic-bezier(.4,0,0,1))}
23
- ._1pgl1lbj{animation-timing-function:var(--ds-easing-in-practical,cubic-bezier(.6,0,.8,.6))}
24
23
  ._1q51ze3t{padding-block-start:var(--ds-space-0,0)}
25
- ._1rjx1d08[open]{animation-timing-function:var(--ds-easing-inout-bold,cubic-bezier(.4,0,0,1))}
26
24
  ._1rsueoah[open]::-ms-backdrop{animation-fill-mode:backwards}
27
25
  ._1rsueoah[open]::backdrop{animation-fill-mode:backwards}
28
26
  ._1s9z1a5r{transition-behavior:allow-discrete}
29
- ._1szp1mzy[open]{animation-duration:var(--ds-duration-long,.25s)}
30
27
  ._2hwx1wug{margin-right:auto}
31
- ._5sagi9qs{animation-duration:var(--ds-duration-medium,.2s)}
32
28
  ._85i5ze3t{padding-block-end:var(--ds-space-0,0)}
33
- ._8ar61bym[open]{animation-name:var(--ds-keyframe-fade-in,FadeIn0to100)}
34
- ._8ar6yjsl[open]{animation-name:k1c1nn4,var(--ds-keyframe-fade-in,FadeIn0to100)}
35
29
  ._bfhk1j28{background-color:transparent}
36
30
  ._bozgze3t{padding-inline-start:var(--ds-space-0,0)}
37
31
  ._c71lglyw{max-height:none}
38
- ._j7hq1a5s{animation-name:var(--ds-keyframe-fade-out,FadeOut100to0)}
39
- ._j7hqcmlg{animation-name:ku52lnv,var(--ds-keyframe-fade-out,FadeOut100to0)}
40
32
  ._k8m011k7{transition-property:overlay,display}
41
33
  ._njwk11k7::-ms-backdrop{-ms-transition-property:overlay,display;transition-property:overlay,display}
42
34
  ._njwk11k7::backdrop{transition-property:overlay,display}
@@ -45,6 +37,4 @@
45
37
  ._y4tize3t{padding-inline-end:var(--ds-space-0,0)}
46
38
  ._yhpqi9qs::-ms-backdrop{transition-duration:var(--ds-duration-medium,.2s)}
47
39
  ._yhpqi9qs::backdrop{transition-duration:var(--ds-duration-medium,.2s)}
48
- @keyframes k1c1nn4{0%{transform:translateY(calc(var(--ds-dialog-ty, 9pt)))}to{transform:none}}
49
- @keyframes ku52lnv{0%{transform:none}to{transform:translateY(calc(var(--ds-dialog-ty, 9pt)*-1))}}
50
40
  @media (prefers-reduced-motion:reduce){._bl8aglyw{animation-name:none}._156y147i{transition-duration:var(--ds-duration-instant,0ms)}._10aiglyw[open]{animation-name:none}._aeld147i[open]{transition-duration:var(--ds-duration-instant,0ms)}._l57nglyw::-ms-backdrop{animation-name:none}._l57nglyw::backdrop{animation-name:none}._1sbq147i::-ms-backdrop{transition-duration:var(--ds-duration-instant,0ms)}._1sbq147i::backdrop{transition-duration:var(--ds-duration-instant,0ms)}._19awglyw[open]::-ms-backdrop{animation-name:none}._19awglyw[open]::backdrop{animation-name:none}._1i6z147i[open]::-ms-backdrop{transition-duration:var(--ds-duration-instant,0ms)}._1i6z147i[open]::backdrop{transition-duration:var(--ds-duration-instant,0ms)}}
@@ -14,23 +14,17 @@ var _bindEventListener = require("bind-event-listener");
14
14
  var _mergeRefs = _interopRequireDefault(require("@atlaskit/ds-lib/merge-refs"));
15
15
  var _noop = _interopRequireDefault(require("@atlaskit/ds-lib/noop"));
16
16
  var _openLayerObserver = require("@atlaskit/layering/experimental/open-layer-observer");
17
- var _setStyle = require("../internal/set-style");
18
17
  var _useAnimatedVisibility = require("../internal/use-animated-visibility");
19
18
  var _useFocusWrap = require("../internal/use-focus-wrap");
19
+ var _useSafariEscapeFix2 = require("../internal/use-safari-escape-fix");
20
20
  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); }
21
- var slideInKeyframes = null;
22
- var slideOutKeyframes = null;
23
-
24
21
  // These animation styles use the non-strict Compiled cssMap because they rely
25
22
  // on `@starting-style`, `[open]`, and `allow-discrete`. Keep them in this
26
23
  // component so the Compiled transform can statically extract every referenced
27
24
  // style.
28
25
  var dialogAnimationStyles = {
29
26
  root: "_k8m011k7 _1oeci9qs _1s9z1a5r _1fsl1mzy _1oil1d08",
30
- motion: "_y44vgeqi _1o51q7pw _1iu47kvq _1i0neoah",
31
- 'slide-up-and-fade': "_j7hqcmlg _5sagi9qs _1pgl1lbj _8ar6yjsl _1szp1mzy _1rjx1d08",
32
- fade: "_j7hq1a5s _5sagi9qs _1pgl1lbj _8ar61bym _1szp1mzy _1rjx1d08",
33
- custom: ""
27
+ motion: "_y44vgeqi _1o51q7pw _1iu47kvq _1i0neoah"
34
28
  };
35
29
  var styles = {
36
30
  dialog: "_19itglyw _19pk1wug _2hwx1wug _otyr1wug _18u01wug _1q51ze3t _y4tize3t _85i5ze3t _bozgze3t _p12fglyw _c71lglyw _bfhk1j28 _bl8aglyw _156y147i _10aiglyw _aeld147i"
@@ -64,7 +58,8 @@ var Dialog = exports.Dialog = /*#__PURE__*/(0, _react.forwardRef)(function Dialo
64
58
  onClose = _ref.onClose,
65
59
  onEnterFinish = _ref.onEnterFinish,
66
60
  onExitFinish = _ref.onExitFinish,
67
- animate = _ref.animate,
61
+ _ref$animate = _ref.animate,
62
+ animate = _ref$animate === void 0 ? false : _ref$animate,
68
63
  consumerXcss = _ref.xcss,
69
64
  style = _ref.style,
70
65
  testId = _ref.testId,
@@ -78,6 +73,7 @@ var Dialog = exports.Dialog = /*#__PURE__*/(0, _react.forwardRef)(function Dialo
78
73
  var combinedRef = (0, _mergeRefs.default)([ownRef, ref]);
79
74
  var _useAnimatedVisibilit = (0, _useAnimatedVisibility.useAnimatedVisibility)({
80
75
  isOpen: isOpen,
76
+ animationKind: 'dialog',
81
77
  animate: animate,
82
78
  elementRef: ownRef,
83
79
  onEnterFinish: onEnterFinish,
@@ -129,23 +125,13 @@ var Dialog = exports.Dialog = /*#__PURE__*/(0, _react.forwardRef)(function Dialo
129
125
  }
130
126
  }, [isOpen]);
131
127
 
132
- // Apply preset-provided animation custom properties (e.g. the
133
- // `--ds-dialog-ty` slide distance for `dialogSlideUpAndFade`). The
134
- // cleanup restores the previous inline values so a preset change does
135
- // not leave stale custom properties on the element. Dialog presets do
136
- // not vary by placement, so an empty placement is passed.
137
- (0, _react.useLayoutEffect)(function () {
138
- var dialog = ownRef.current;
139
- if (!dialog || !(preset !== null && preset !== void 0 && preset.getStyles)) {
140
- return;
141
- }
142
- return (0, _setStyle.setStyle)({
143
- element: dialog,
144
- styles: preset.getStyles({
145
- placement: {}
146
- })
147
- });
148
- }, [preset, isVisible]);
128
+ // Safari bug: escape closes open dialog and popovers, rather than just innermost popover
129
+ // See notes/decisions/safari-escape-nested-popover-in-dialog.md
130
+ var _useSafariEscapeFix = (0, _useSafariEscapeFix2.useSafariEscapeFix)({
131
+ dialogRef: ownRef,
132
+ isVisible: isVisible
133
+ }),
134
+ shouldIgnoreEscape = _useSafariEscapeFix.shouldIgnoreEscape;
149
135
 
150
136
  // Handle native Escape (cancel event)
151
137
  var handleCancel = (0, _react.useCallback)(function (event) {
@@ -158,10 +144,16 @@ var Dialog = exports.Dialog = /*#__PURE__*/(0, _react.forwardRef)(function Dialo
158
144
  return;
159
145
  }
160
146
  event.preventDefault();
147
+ // Spurious Safari `cancel`: the keydown snapshot saw an open child
148
+ // popover, so this Escape belongs to that popover (light-dismissed
149
+ // natively). Keep the dialog open instead of forwarding to `onClose`.
150
+ if (shouldIgnoreEscape()) {
151
+ return;
152
+ }
161
153
  onClose({
162
154
  reason: 'escape'
163
155
  });
164
- }, [onClose]);
156
+ }, [onClose, shouldIgnoreEscape]);
165
157
 
166
158
  // Handle backdrop click
167
159
  // Attached via bind-event-listener rather than a React prop so we avoid
@@ -207,6 +199,6 @@ var Dialog = exports.Dialog = /*#__PURE__*/(0, _react.forwardRef)(function Dialo
207
199
  style: style,
208
200
  onCancel: handleCancel,
209
201
  "data-testid": testId,
210
- className: (0, _runtime.ax)([styles.dialog, shouldHideBackdrop ? backdropStyles.hidden : backdropStyles.root, preset && backdropStyles.motion, preset && dialogAnimationStyles.root, preset && dialogAnimationStyles[preset.name], consumerXcss])
202
+ className: (0, _runtime.ax)([styles.dialog, shouldHideBackdrop ? backdropStyles.hidden : backdropStyles.root, preset && backdropStyles.motion, preset && dialogAnimationStyles.root, preset && dialogAnimationStyles.motion, consumerXcss])
211
203
  }, children);
212
204
  });
@@ -1,49 +1 @@
1
- "use strict";
2
-
3
- Object.defineProperty(exports, "__esModule", {
4
- value: true
5
- });
6
- Object.defineProperty(exports, "dialogFade", {
7
- enumerable: true,
8
- get: function get() {
9
- return _animations.dialogFade;
10
- }
11
- });
12
- Object.defineProperty(exports, "dialogMotion", {
13
- enumerable: true,
14
- get: function get() {
15
- return _animations.dialogMotion;
16
- }
17
- });
18
- Object.defineProperty(exports, "dialogSlideUpAndFade", {
19
- enumerable: true,
20
- get: function get() {
21
- return _animations.dialogSlideUpAndFade;
22
- }
23
- });
24
- Object.defineProperty(exports, "fade", {
25
- enumerable: true,
26
- get: function get() {
27
- return _animations2.fade;
28
- }
29
- });
30
- Object.defineProperty(exports, "popupMotion", {
31
- enumerable: true,
32
- get: function get() {
33
- return _animations2.popupMotion;
34
- }
35
- });
36
- Object.defineProperty(exports, "scaleAndFade", {
37
- enumerable: true,
38
- get: function get() {
39
- return _animations2.scaleAndFade;
40
- }
41
- });
42
- Object.defineProperty(exports, "slideAndFade", {
43
- enumerable: true,
44
- get: function get() {
45
- return _animations2.slideAndFade;
46
- }
47
- });
48
- var _animations = require("../dialog/animations");
49
- var _animations2 = require("../popover/animations");
1
+ "use strict";
@@ -9,17 +9,6 @@ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/sli
9
9
  var _react = require("react");
10
10
  var _bindEventListener = require("bind-event-listener");
11
11
  var _reducedMotion = require("./reduced-motion");
12
- /**
13
- * A self-contained animation preset for top-layer elements.
14
- *
15
- * Contains a stable preset name used by the host component to select its
16
- * component-local Compiled style entry, plus optional per-placement inline
17
- * styles.
18
- *
19
- * The actual Compiled styles are kept static and component-local so the
20
- * Compiled transform can extract them at build time.
21
- */
22
-
23
12
  /**
24
13
  * Using the recommended motion timings for safety net.
25
14
  *
@@ -78,6 +67,13 @@ function runOnTransitionEndOrTimeout(_ref) {
78
67
  return teardown;
79
68
  }
80
69
 
70
+ /**
71
+ * Animation config for entry/exit transitions.
72
+ *
73
+ * Currently no configuration is supported via this prop,
74
+ * and this is just a placeholder.
75
+ */
76
+
81
77
  /**
82
78
  * Visibility lifecycle phase shared between `useAnimatedVisibility`,
83
79
  * `useFocusWrap`, `useInitialFocus`, and the `Popover` / `Dialog`
@@ -141,6 +137,7 @@ function runOnTransitionEndOrTimeout(_ref) {
141
137
  */
142
138
  function useAnimatedVisibility(_ref2) {
143
139
  var isOpen = _ref2.isOpen,
140
+ animationKind = _ref2.animationKind,
144
141
  animate = _ref2.animate,
145
142
  elementRef = _ref2.elementRef,
146
143
  onEnterFinish = _ref2.onEnterFinish,
@@ -194,7 +191,7 @@ function useAnimatedVisibility(_ref2) {
194
191
  // move to `open`. The fallback guarantees settle on swallowed events
195
192
  // (zero-duration, browser quirk, mid-transition unmount).
196
193
  (0, _react.useEffect)(function () {
197
- if (phase !== 'entering' || !(preset !== null && preset !== void 0 && preset.kind)) {
194
+ if (phase !== 'entering') {
198
195
  return;
199
196
  }
200
197
  var element = elementRef.current;
@@ -203,7 +200,7 @@ function useAnimatedVisibility(_ref2) {
203
200
  }
204
201
  return runOnTransitionEndOrTimeout({
205
202
  element: element,
206
- safetyNetMs: safetyNetMsMap[preset.kind].enter + 50,
203
+ safetyNetMs: safetyNetMsMap[animationKind].enter + 50,
207
204
  onSettled: function onSettled() {
208
205
  var _onEnterFinishRef$cur;
209
206
  // Fire the consumer callback before transitioning phase so any
@@ -216,7 +213,7 @@ function useAnimatedVisibility(_ref2) {
216
213
  });
217
214
  }
218
215
  });
219
- }, [phase, preset === null || preset === void 0 ? void 0 : preset.kind, elementRef]);
216
+ }, [phase, animationKind, elementRef]);
220
217
 
221
218
  // Non-animated entry callback. The lifecycle goes `closed → open`
222
219
  // directly with no `entering` phase; fire `onEnterFinish` on that jump.
@@ -237,7 +234,7 @@ function useAnimatedVisibility(_ref2) {
237
234
  // Animated exit: wait for `transitionend` (or a safety-net timeout),
238
235
  // fire `onExitFinish`, then move to `closed` to unmount the host.
239
236
  (0, _react.useEffect)(function () {
240
- if (phase !== 'exiting' || !willAnimate || !(preset !== null && preset !== void 0 && preset.kind)) {
237
+ if (phase !== 'exiting' || !willAnimate) {
241
238
  return;
242
239
  }
243
240
  var element = elementRef.current;
@@ -246,7 +243,7 @@ function useAnimatedVisibility(_ref2) {
246
243
  }
247
244
  return runOnTransitionEndOrTimeout({
248
245
  element: element,
249
- safetyNetMs: safetyNetMsMap[preset.kind].exit + 50,
246
+ safetyNetMs: safetyNetMsMap[animationKind].exit + 50,
250
247
  onSettled: function onSettled() {
251
248
  var _onExitFinishRef$curr;
252
249
  // Fire the consumer callback before transitioning phase to
@@ -261,7 +258,7 @@ function useAnimatedVisibility(_ref2) {
261
258
  });
262
259
  }
263
260
  });
264
- }, [phase, willAnimate, preset === null || preset === void 0 ? void 0 : preset.kind, elementRef]);
261
+ }, [phase, willAnimate, animationKind, elementRef]);
265
262
 
266
263
  // Non-animated exit: wait for the browser's `toggle` (closed) or
267
264
  // `close` event before unmounting, so the consumer's listener (close
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.useSafariEscapeFix = useSafariEscapeFix;
7
+ var _react = require("react");
8
+ var _bindEventListener = require("bind-event-listener");
9
+ var _isSafari = require("@atlaskit/ds-lib/is-safari");
10
+ /**
11
+ * Safari-only guard: WebKit fires dialog `cancel` on Escape even when a child
12
+ * `auto`/`hint` popover consumed it, closing the dialog too.
13
+ * See notes/decisions/safari-escape-nested-popover-in-dialog.md
14
+ */
15
+ function useSafariEscapeFix(_ref) {
16
+ var dialogRef = _ref.dialogRef,
17
+ isVisible = _ref.isVisible;
18
+ var childPopoverOpenAtEscapeRef = (0, _react.useRef)(false);
19
+ (0, _react.useEffect)(function () {
20
+ if (!(0, _isSafari.isSafari)()) {
21
+ return;
22
+ }
23
+ var dialog = dialogRef.current;
24
+ if (!dialog) {
25
+ return;
26
+ }
27
+
28
+ // Bind to `document`, not the dialog: on Safari focus can be on `<body>`
29
+ // (buttons are not focused on click), where a dialog-scoped listener would
30
+ // never fire. The query below stays scoped to this dialog's subtree.
31
+ return (0, _bindEventListener.bind)(document, {
32
+ type: 'keydown',
33
+ listener: function listener(event) {
34
+ if (event.key !== 'Escape') {
35
+ return;
36
+ }
37
+ try {
38
+ childPopoverOpenAtEscapeRef.current = Boolean(dialog.querySelector('[popover="auto"]:popover-open, [popover="hint"]:popover-open'));
39
+ } catch (_unused) {
40
+ // `:popover-open` is unsupported in some environments (e.g. jsdom);
41
+ // treat as "no child popover" so a plain Escape still closes the dialog.
42
+ childPopoverOpenAtEscapeRef.current = false;
43
+ }
44
+ },
45
+ options: {
46
+ capture: true
47
+ }
48
+ });
49
+ }, [dialogRef, isVisible]);
50
+ var api = (0, _react.useMemo)(function () {
51
+ return {
52
+ shouldIgnoreEscape: function shouldIgnoreEscape() {
53
+ if (childPopoverOpenAtEscapeRef.current) {
54
+ childPopoverOpenAtEscapeRef.current = false;
55
+ return true;
56
+ }
57
+ return false;
58
+ }
59
+ };
60
+ }, []);
61
+ return api;
62
+ }
@@ -3,10 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports.fade = fade;
7
- exports.popupMotion = popupMotion;
8
- exports.scaleAndFade = scaleAndFade;
9
- exports.slideAndFade = slideAndFade;
6
+ exports.getPopupMotionStyles = getPopupMotionStyles;
10
7
  var _resolvePlacement = require("../internal/resolve-placement");
11
8
  function getPopupMotionStyles(_ref) {
12
9
  var placement = _ref.placement;
@@ -50,147 +47,4 @@ function getPopupMotionStyles(_ref) {
50
47
  property: '--ds-popover-motion-exit',
51
48
  value: "var(--ds-popup-exit-bottom, 100ms cubic-bezier(0.6, 0, 0.8, 0.6) SlideOutBottom8px, 100ms cubic-bezier(0.6, 0, 0.8, 0.6) FadeOut100to0)"
52
49
  }];
53
- }
54
-
55
- // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
56
- function popupMotion() {
57
- return {
58
- kind: 'popover',
59
- name: 'motion',
60
- getStyles: getPopupMotionStyles
61
- };
62
- }
63
- function getSlideAndFadeStyles(_ref2) {
64
- var placement = _ref2.placement,
65
- distance = _ref2.distance;
66
- var pos = "".concat(distance, "px");
67
- var neg = "-".concat(distance, "px");
68
- var _getPlacement2 = (0, _resolvePlacement.getPlacement)({
69
- placement: placement
70
- }),
71
- axis = _getPlacement2.axis,
72
- edge = _getPlacement2.edge;
73
- if (axis === 'block' && edge === 'start') {
74
- return [{
75
- property: '--ds-popover-tx',
76
- value: '0'
77
- }, {
78
- property: '--ds-popover-ty',
79
- value: pos
80
- }];
81
- }
82
- if (axis === 'block' && edge === 'end') {
83
- return [{
84
- property: '--ds-popover-tx',
85
- value: '0'
86
- }, {
87
- property: '--ds-popover-ty',
88
- value: neg
89
- }];
90
- }
91
- if (axis === 'inline' && edge === 'start') {
92
- return [{
93
- property: '--ds-popover-tx',
94
- value: pos
95
- }, {
96
- property: '--ds-popover-ty',
97
- value: '0'
98
- }];
99
- }
100
- if (axis === 'inline' && edge === 'end') {
101
- return [{
102
- property: '--ds-popover-tx',
103
- value: neg
104
- }, {
105
- property: '--ds-popover-ty',
106
- value: '0'
107
- }];
108
- }
109
- return [{
110
- property: '--ds-popover-tx',
111
- value: '0'
112
- }, {
113
- property: '--ds-popover-ty',
114
- value: neg
115
- }];
116
- }
117
-
118
- /**
119
- * Directional slide + opacity animation.
120
- *
121
- * The popover slides in from the direction opposite its placement edge
122
- * (e.g. a `block-end` popover slides down from above).
123
- *
124
- * @param options.distance - Slide distance in pixels. Defaults to `4`.
125
- *
126
- * @example
127
- * ```tsx
128
- * import { slideAndFade } from '@atlaskit/top-layer/animations';
129
- *
130
- * // Default 4px slide (tooltip)
131
- * <Popover animate={slideAndFade()} />
132
- *
133
- * // Custom 8px slide (popup / dropdown)
134
- * <Popover animate={slideAndFade({ distance: 8 })} />
135
- * ```
136
- */
137
- // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
138
- function slideAndFade(options) {
139
- var _options$distance;
140
- var distance = (_options$distance = options === null || options === void 0 ? void 0 : options.distance) !== null && _options$distance !== void 0 ? _options$distance : 4;
141
- return {
142
- kind: 'popover',
143
- name: 'slide-and-fade',
144
- getStyles: function getStyles(_ref3) {
145
- var placement = _ref3.placement;
146
- return getSlideAndFadeStyles({
147
- placement: placement,
148
- distance: distance
149
- });
150
- }
151
- };
152
- }
153
-
154
- // fade
155
-
156
- /**
157
- * Simple opacity transition, no transform.
158
- *
159
- * Suitable for popup dialogs or content that does not need directional motion.
160
- *
161
- * @example
162
- * ```tsx
163
- * import { fade } from '@atlaskit/top-layer/animations';
164
- *
165
- * <Popover animate={fade()} />
166
- * ```
167
- */
168
- // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
169
- function fade() {
170
- return {
171
- kind: 'popover',
172
- name: 'fade'
173
- };
174
- }
175
-
176
- // scaleAndFade
177
-
178
- /**
179
- * Scale from 0.95 + opacity transition.
180
- *
181
- * Suitable for menus, dropdowns, and select options.
182
- *
183
- * @example
184
- * ```tsx
185
- * import { scaleAndFade } from '@atlaskit/top-layer/animations';
186
- *
187
- * <Popover animate={scaleAndFade()} />
188
- * ```
189
- */
190
- // eslint-disable-next-line @atlaskit/volt-strict-mode/no-multiple-exports
191
- function scaleAndFade() {
192
- return {
193
- kind: 'popover',
194
- name: 'scale-and-fade'
195
- };
196
50
  }
@@ -7,7 +7,6 @@
7
7
  ._18u0idpf{margin-left:0}
8
8
  ._19bvidpf{padding-left:0}
9
9
  ._19pkidpf{margin-top:0}
10
- ._1a5xt94y{--dir:1px}
11
10
  ._1o51q7pw{animation-fill-mode:forwards}
12
11
  ._1oecdn4k{transition-duration:var(--ds-duration-xshort,.1s)}
13
12
  ._1pgl1lbj{animation-timing-function:var(--ds-easing-in-practical,cubic-bezier(.6,0,.8,.6))}
@@ -15,22 +14,14 @@
15
14
  ._1reoewfl{overflow-x:visible}
16
15
  ._1s9z1a5r{transition-behavior:allow-discrete}
17
16
  ._2hwxidpf{margin-right:0}
17
+ ._4t3i1wug{height:auto}
18
18
  ._5sagdn4k{animation-duration:var(--ds-duration-xshort,.1s)}
19
- ._71re1bym:popover-open{animation-name:var(--ds-keyframe-fade-in,FadeIn0to100)}
20
- ._71re1v6b:popover-open{animation-name:var(--ds-keyframe-fade-in,FadeIn0to100),var(--ds-keyframe-scale-in-small,ScaleIn95to100)}
21
- ._71rervlo:popover-open{animation-name:k1ut9kob,var(--ds-keyframe-fade-in,FadeIn0to100)}
22
19
  ._bfhk1j28{background-color:transparent}
23
20
  ._ca0qidpf{padding-top:0}
24
- ._j7hq1a5s{animation-name:var(--ds-keyframe-fade-out,FadeOut100to0)}
25
- ._j7hq1l2h{animation-name:k1e4c1ew,var(--ds-keyframe-fade-out,FadeOut100to0)}
26
- ._j7hqneez{animation-name:var(--ds-keyframe-fade-out,FadeOut100to0),var(--ds-keyframe-scale-out-small,ScaleOut100to95)}
27
21
  ._k8m011k7{transition-property:overlay,display}
28
22
  ._n3tdidpf{padding-bottom:0}
29
23
  ._n70peoah:popover-open{animation-fill-mode:backwards}
30
24
  ._o8i7indk:popover-open{animation-timing-function:var(--ds-easing-out-practical,cubic-bezier(.4,1,.6,1))}
31
25
  ._otyridpf{margin-bottom:0}
32
26
  ._u5f3idpf{padding-right:0}
33
- [dir=rtl] ._34bx1n1a{--dir:-1px}
34
- @keyframes k1e4c1ew{0%{transform:none}to{transform:translate(calc(var(--dir)*var(--ds-popover-tx, 0)),var(--ds-popover-ty,0))}}
35
- @keyframes k1ut9kob{0%{transform:translate(calc(var(--dir)*var(--ds-popover-tx, 0)),var(--ds-popover-ty,0))}to{transform:none}}
36
27
  @media (prefers-reduced-motion:reduce){._bl8aglyw{animation-name:none}._156yru3m{transition-duration:0s}._8rmvglyw:popover-open{animation-name:none}._2qm2ru3m:popover-open{transition-duration:0s}}