@oxyhq/bloom 0.14.0 → 0.16.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.
- package/lib/commonjs/alert-dialog/AlertDialog.js +35 -27
- package/lib/commonjs/alert-dialog/AlertDialog.js.map +1 -1
- package/lib/commonjs/alert-dialog/index.js +1 -1
- package/lib/commonjs/alert-dialog/index.js.map +1 -1
- package/lib/commonjs/alert-dialog/index.web.js +1 -1
- package/lib/commonjs/alert-dialog/index.web.js.map +1 -1
- package/lib/commonjs/command/Command.js +27 -16
- package/lib/commonjs/command/Command.js.map +1 -1
- package/lib/commonjs/command/index.js +1 -1
- package/lib/commonjs/command/index.js.map +1 -1
- package/lib/commonjs/command/index.web.js +1 -1
- package/lib/commonjs/command/index.web.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.js +336 -43
- package/lib/commonjs/dialog/Dialog.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +420 -66
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/dialog/index.js +2 -9
- package/lib/commonjs/dialog/index.js.map +1 -1
- package/lib/commonjs/dialog/index.web.js +2 -15
- package/lib/commonjs/dialog/index.web.js.map +1 -1
- package/lib/commonjs/dialog/placement.js +104 -0
- package/lib/commonjs/dialog/placement.js.map +1 -0
- package/lib/commonjs/index.js +7 -29
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/index.web.js +13 -35
- package/lib/commonjs/index.web.js.map +1 -1
- package/lib/module/alert-dialog/AlertDialog.js +35 -27
- package/lib/module/alert-dialog/AlertDialog.js.map +1 -1
- package/lib/module/alert-dialog/index.js +2 -2
- package/lib/module/alert-dialog/index.js.map +1 -1
- package/lib/module/alert-dialog/index.web.js +2 -2
- package/lib/module/alert-dialog/index.web.js.map +1 -1
- package/lib/module/command/Command.js +27 -16
- package/lib/module/command/Command.js.map +1 -1
- package/lib/module/command/index.js +2 -2
- package/lib/module/command/index.js.map +1 -1
- package/lib/module/command/index.web.js +2 -2
- package/lib/module/command/index.web.js.map +1 -1
- package/lib/module/dialog/Dialog.js +335 -46
- package/lib/module/dialog/Dialog.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +418 -68
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/dialog/index.js +1 -2
- package/lib/module/dialog/index.js.map +1 -1
- package/lib/module/dialog/index.web.js +1 -2
- package/lib/module/dialog/index.web.js.map +1 -1
- package/lib/module/dialog/placement.js +100 -0
- package/lib/module/dialog/placement.js.map +1 -0
- package/lib/module/index.js +1 -3
- package/lib/module/index.js.map +1 -1
- package/lib/module/index.web.js +1 -3
- package/lib/module/index.web.js.map +1 -1
- package/lib/typescript/commonjs/alert-dialog/AlertDialog.d.ts +13 -12
- package/lib/typescript/commonjs/alert-dialog/AlertDialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/alert-dialog/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/alert-dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/command/Command.d.ts +8 -8
- package/lib/typescript/commonjs/command/Command.d.ts.map +1 -1
- package/lib/typescript/commonjs/command/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/command/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.d.ts +17 -15
- package/lib/typescript/commonjs/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts +18 -5
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/index.d.ts +2 -4
- package/lib/typescript/commonjs/dialog/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/index.web.d.ts +2 -4
- package/lib/typescript/commonjs/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/placement.d.ts +71 -0
- package/lib/typescript/commonjs/dialog/placement.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/types.d.ts +66 -3
- package/lib/typescript/commonjs/dialog/types.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.d.ts +2 -4
- package/lib/typescript/commonjs/index.d.ts.map +1 -1
- package/lib/typescript/commonjs/index.web.d.ts +2 -4
- package/lib/typescript/commonjs/index.web.d.ts.map +1 -1
- package/lib/typescript/module/alert-dialog/AlertDialog.d.ts +13 -12
- package/lib/typescript/module/alert-dialog/AlertDialog.d.ts.map +1 -1
- package/lib/typescript/module/alert-dialog/index.d.ts.map +1 -1
- package/lib/typescript/module/alert-dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/module/command/Command.d.ts +8 -8
- package/lib/typescript/module/command/Command.d.ts.map +1 -1
- package/lib/typescript/module/command/index.d.ts.map +1 -1
- package/lib/typescript/module/command/index.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.d.ts +17 -15
- package/lib/typescript/module/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts +18 -5
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/index.d.ts +2 -4
- package/lib/typescript/module/dialog/index.d.ts.map +1 -1
- package/lib/typescript/module/dialog/index.web.d.ts +2 -4
- package/lib/typescript/module/dialog/index.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/placement.d.ts +71 -0
- package/lib/typescript/module/dialog/placement.d.ts.map +1 -0
- package/lib/typescript/module/dialog/types.d.ts +66 -3
- package/lib/typescript/module/dialog/types.d.ts.map +1 -1
- package/lib/typescript/module/index.d.ts +2 -4
- package/lib/typescript/module/index.d.ts.map +1 -1
- package/lib/typescript/module/index.web.d.ts +2 -4
- package/lib/typescript/module/index.web.d.ts.map +1 -1
- package/package.json +1 -18
- package/src/__tests__/AlertDialog.test.tsx +122 -0
- package/src/__tests__/Command.test.tsx +107 -0
- package/src/__tests__/DialogPlacement.test.tsx +144 -0
- package/src/alert-dialog/AlertDialog.tsx +46 -36
- package/src/alert-dialog/index.ts +2 -2
- package/src/alert-dialog/index.web.ts +2 -2
- package/src/command/Command.tsx +30 -19
- package/src/command/index.ts +2 -2
- package/src/command/index.web.ts +2 -2
- package/src/dialog/Dialog.tsx +406 -50
- package/src/dialog/Dialog.web.tsx +496 -78
- package/src/dialog/index.ts +4 -3
- package/src/dialog/index.web.ts +4 -7
- package/src/dialog/placement.ts +113 -0
- package/src/dialog/types.ts +69 -3
- package/src/index.ts +4 -11
- package/src/index.web.ts +4 -11
- package/lib/commonjs/dialog/CenteredDialog.js +0 -250
- package/lib/commonjs/dialog/CenteredDialog.js.map +0 -1
- package/lib/commonjs/dialog/CenteredDialog.web.js +0 -328
- package/lib/commonjs/dialog/CenteredDialog.web.js.map +0 -1
- package/lib/commonjs/dialog/centered-dialog-tokens.js +0 -62
- package/lib/commonjs/dialog/centered-dialog-tokens.js.map +0 -1
- package/lib/commonjs/dialog/centered-dialog-types.js +0 -6
- package/lib/commonjs/dialog/centered-dialog-types.js.map +0 -1
- package/lib/commonjs/responsive-sheet/ResponsiveSheet.js +0 -300
- package/lib/commonjs/responsive-sheet/ResponsiveSheet.js.map +0 -1
- package/lib/commonjs/responsive-sheet/ResponsiveSheet.native.js +0 -226
- package/lib/commonjs/responsive-sheet/ResponsiveSheet.native.js.map +0 -1
- package/lib/commonjs/responsive-sheet/const.js +0 -60
- package/lib/commonjs/responsive-sheet/const.js.map +0 -1
- package/lib/commonjs/responsive-sheet/index.js +0 -19
- package/lib/commonjs/responsive-sheet/index.js.map +0 -1
- package/lib/commonjs/responsive-sheet/index.web.js +0 -19
- package/lib/commonjs/responsive-sheet/index.web.js.map +0 -1
- package/lib/commonjs/responsive-sheet/types.js +0 -6
- package/lib/commonjs/responsive-sheet/types.js.map +0 -1
- package/lib/module/dialog/CenteredDialog.js +0 -244
- package/lib/module/dialog/CenteredDialog.js.map +0 -1
- package/lib/module/dialog/CenteredDialog.web.js +0 -322
- package/lib/module/dialog/CenteredDialog.web.js.map +0 -1
- package/lib/module/dialog/centered-dialog-tokens.js +0 -58
- package/lib/module/dialog/centered-dialog-tokens.js.map +0 -1
- package/lib/module/dialog/centered-dialog-types.js +0 -4
- package/lib/module/dialog/centered-dialog-types.js.map +0 -1
- package/lib/module/responsive-sheet/ResponsiveSheet.js +0 -293
- package/lib/module/responsive-sheet/ResponsiveSheet.js.map +0 -1
- package/lib/module/responsive-sheet/ResponsiveSheet.native.js +0 -219
- package/lib/module/responsive-sheet/ResponsiveSheet.native.js.map +0 -1
- package/lib/module/responsive-sheet/const.js +0 -56
- package/lib/module/responsive-sheet/const.js.map +0 -1
- package/lib/module/responsive-sheet/index.js +0 -4
- package/lib/module/responsive-sheet/index.js.map +0 -1
- package/lib/module/responsive-sheet/index.web.js +0 -14
- package/lib/module/responsive-sheet/index.web.js.map +0 -1
- package/lib/module/responsive-sheet/types.js +0 -4
- package/lib/module/responsive-sheet/types.js.map +0 -1
- package/lib/typescript/commonjs/dialog/CenteredDialog.d.ts +0 -20
- package/lib/typescript/commonjs/dialog/CenteredDialog.d.ts.map +0 -1
- package/lib/typescript/commonjs/dialog/CenteredDialog.web.d.ts +0 -29
- package/lib/typescript/commonjs/dialog/CenteredDialog.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/dialog/centered-dialog-tokens.d.ts +0 -47
- package/lib/typescript/commonjs/dialog/centered-dialog-tokens.d.ts.map +0 -1
- package/lib/typescript/commonjs/dialog/centered-dialog-types.d.ts +0 -70
- package/lib/typescript/commonjs/dialog/centered-dialog-types.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/ResponsiveSheet.d.ts +0 -26
- package/lib/typescript/commonjs/responsive-sheet/ResponsiveSheet.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/ResponsiveSheet.native.d.ts +0 -20
- package/lib/typescript/commonjs/responsive-sheet/ResponsiveSheet.native.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/const.d.ts +0 -43
- package/lib/typescript/commonjs/responsive-sheet/const.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/index.d.ts +0 -3
- package/lib/typescript/commonjs/responsive-sheet/index.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/index.web.d.ts +0 -3
- package/lib/typescript/commonjs/responsive-sheet/index.web.d.ts.map +0 -1
- package/lib/typescript/commonjs/responsive-sheet/types.d.ts +0 -55
- package/lib/typescript/commonjs/responsive-sheet/types.d.ts.map +0 -1
- package/lib/typescript/module/dialog/CenteredDialog.d.ts +0 -20
- package/lib/typescript/module/dialog/CenteredDialog.d.ts.map +0 -1
- package/lib/typescript/module/dialog/CenteredDialog.web.d.ts +0 -29
- package/lib/typescript/module/dialog/CenteredDialog.web.d.ts.map +0 -1
- package/lib/typescript/module/dialog/centered-dialog-tokens.d.ts +0 -47
- package/lib/typescript/module/dialog/centered-dialog-tokens.d.ts.map +0 -1
- package/lib/typescript/module/dialog/centered-dialog-types.d.ts +0 -70
- package/lib/typescript/module/dialog/centered-dialog-types.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/ResponsiveSheet.d.ts +0 -26
- package/lib/typescript/module/responsive-sheet/ResponsiveSheet.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/ResponsiveSheet.native.d.ts +0 -20
- package/lib/typescript/module/responsive-sheet/ResponsiveSheet.native.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/const.d.ts +0 -43
- package/lib/typescript/module/responsive-sheet/const.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/index.d.ts +0 -3
- package/lib/typescript/module/responsive-sheet/index.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/index.web.d.ts +0 -3
- package/lib/typescript/module/responsive-sheet/index.web.d.ts.map +0 -1
- package/lib/typescript/module/responsive-sheet/types.d.ts +0 -55
- package/lib/typescript/module/responsive-sheet/types.d.ts.map +0 -1
- package/src/__tests__/CenteredDialog.test.tsx +0 -108
- package/src/__tests__/ResponsiveSheet.test.tsx +0 -104
- package/src/dialog/CenteredDialog.stories.tsx +0 -125
- package/src/dialog/CenteredDialog.tsx +0 -303
- package/src/dialog/CenteredDialog.web.tsx +0 -372
- package/src/dialog/centered-dialog-tokens.ts +0 -68
- package/src/dialog/centered-dialog-types.ts +0 -70
- package/src/responsive-sheet/ResponsiveSheet.native.tsx +0 -257
- package/src/responsive-sheet/ResponsiveSheet.stories.tsx +0 -54
- package/src/responsive-sheet/ResponsiveSheet.tsx +0 -327
- package/src/responsive-sheet/const.ts +0 -53
- package/src/responsive-sheet/index.ts +0 -6
- package/src/responsive-sheet/index.web.ts +0 -16
- package/src/responsive-sheet/types.ts +0 -57
|
@@ -5,6 +5,12 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
5
5
|
});
|
|
6
6
|
exports.AutoMountedDialog = AutoMountedDialog;
|
|
7
7
|
exports.BLOOM_DIALOG_CSS = void 0;
|
|
8
|
+
Object.defineProperty(exports, "DIALOG_SHEET_BACKDROP_TESTID", {
|
|
9
|
+
enumerable: true,
|
|
10
|
+
get: function () {
|
|
11
|
+
return _placement.DIALOG_SHEET_BACKDROP_TESTID;
|
|
12
|
+
}
|
|
13
|
+
});
|
|
8
14
|
exports.Dialog = Dialog;
|
|
9
15
|
var _react = _interopRequireWildcard(require("react"));
|
|
10
16
|
var _reactNative = require("react-native");
|
|
@@ -13,9 +19,10 @@ var _indexWeb = require("../portal/index.web.js");
|
|
|
13
19
|
var _zIndex = require("../styles/z-index.js");
|
|
14
20
|
var _useTheme = require("../theme/use-theme.js");
|
|
15
21
|
var _context = require("./context.js");
|
|
22
|
+
var _placement = require("./placement.js");
|
|
16
23
|
var _jsxRuntime = require("react/jsx-runtime");
|
|
17
24
|
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (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 (const 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); }
|
|
18
|
-
const FADE_OUT_DURATION =
|
|
25
|
+
const FADE_OUT_DURATION = _placement.CENTER_FADE_OUT_DURATION;
|
|
19
26
|
const dialogZIndex = (0, _zIndex.createOverlayZIndex)();
|
|
20
27
|
const stopPropagation = e => e.stopPropagation();
|
|
21
28
|
const ClosingContext = /*#__PURE__*/(0, _react.createContext)(false);
|
|
@@ -23,40 +30,94 @@ const ClosingContext = /*#__PURE__*/(0, _react.createContext)(false);
|
|
|
23
30
|
/**
|
|
24
31
|
* Web variant of `<Dialog>`.
|
|
25
32
|
*
|
|
26
|
-
* A centered modal card rendered into the bloom Portal at the end of
|
|
27
|
-
* `document.body
|
|
28
|
-
*
|
|
29
|
-
* agnostic.
|
|
33
|
+
* A centered modal card (default) rendered into the bloom Portal at the end of
|
|
34
|
+
* `document.body`, or — when `placement` is `left`/`right`/`bottom` — an
|
|
35
|
+
* anchored side-sheet or bottom-sheet. Same prop API as native, so call sites
|
|
36
|
+
* are platform agnostic.
|
|
37
|
+
*
|
|
38
|
+
* Open/close is driven by EITHER the imperative `control` (legacy) OR the
|
|
39
|
+
* controlled `open` prop. When `open` is provided it wins.
|
|
30
40
|
*
|
|
31
41
|
* Accessibility: the panel has `role="dialog"` and the `title`/`description`
|
|
32
42
|
* props (when provided) become the `aria-labelledby` / `aria-describedby`
|
|
33
43
|
* targets. Pressing the backdrop dismisses. Pressing `Escape` dismisses.
|
|
34
44
|
* Focus is locked inside the dialog while it's open.
|
|
45
|
+
*
|
|
46
|
+
* Web motion never uses reanimated `exiting` (which throws `removeChild` on
|
|
47
|
+
* concurrent React unmounts): the centered card uses CSS keyframes and the
|
|
48
|
+
* side/bottom modes use self-contained CSS transitions on a
|
|
49
|
+
* mounted-through-exit node.
|
|
35
50
|
*/
|
|
36
51
|
function Dialog({
|
|
37
52
|
control,
|
|
53
|
+
open: controlledOpen,
|
|
38
54
|
onClose,
|
|
39
55
|
testID,
|
|
40
56
|
title,
|
|
41
57
|
description,
|
|
42
58
|
actions,
|
|
59
|
+
placement,
|
|
60
|
+
width = _placement.DEFAULT_SIDE_WIDTH,
|
|
61
|
+
maxWidth = _placement.DEFAULT_CENTER_MAX_WIDTH,
|
|
62
|
+
maxHeightRatio = _placement.DEFAULT_MAX_HEIGHT_RATIO,
|
|
63
|
+
inset,
|
|
64
|
+
showHandle = true,
|
|
65
|
+
dismissOnBackdrop = true,
|
|
43
66
|
style,
|
|
67
|
+
panelStyle,
|
|
68
|
+
panelClassName,
|
|
69
|
+
containerStyle,
|
|
70
|
+
containerClassName,
|
|
44
71
|
label,
|
|
45
72
|
children
|
|
46
73
|
}) {
|
|
74
|
+
// Controlled mode is opt-in: when `open` is a boolean the host owns the
|
|
75
|
+
// visible state; otherwise the legacy imperative `control` path drives it.
|
|
76
|
+
const isControlled = controlledOpen !== undefined;
|
|
77
|
+
const resolvedPlacement = (0, _placement.useResolvedPlacement)(placement);
|
|
47
78
|
const [isOpen, setIsOpen] = (0, _react.useState)(false);
|
|
48
79
|
const [isClosing, setIsClosing] = (0, _react.useState)(false);
|
|
49
80
|
const closeCallbacksRef = (0, _react.useRef)([]);
|
|
81
|
+
// Read the latest controlled flag inside stable callbacks without re-binding.
|
|
82
|
+
const isControlledRef = (0, _react.useRef)(isControlled);
|
|
83
|
+
isControlledRef.current = isControlled;
|
|
50
84
|
const open = (0, _react.useCallback)(() => {
|
|
51
85
|
setIsClosing(false);
|
|
52
86
|
setIsOpen(true);
|
|
53
87
|
}, []);
|
|
88
|
+
|
|
89
|
+
// A dismissal request (backdrop, Escape, action button). In controlled mode
|
|
90
|
+
// it asks the host to close via `onClose` (the host flips `open`); in
|
|
91
|
+
// imperative mode it starts the exit animation directly. Either way an
|
|
92
|
+
// optional callback runs after the dialog has finished closing.
|
|
54
93
|
const close = (0, _react.useCallback)(cb => {
|
|
55
94
|
if (typeof cb === 'function') {
|
|
56
95
|
closeCallbacksRef.current.push(cb);
|
|
57
96
|
}
|
|
97
|
+
if (isControlledRef.current) {
|
|
98
|
+
onCloseRef.current?.();
|
|
99
|
+
return;
|
|
100
|
+
}
|
|
58
101
|
setIsClosing(true);
|
|
59
102
|
}, []);
|
|
103
|
+
|
|
104
|
+
// `onClose` mirrored into a ref so `close` stays referentially stable (the
|
|
105
|
+
// dialog context + imperative handle depend on it).
|
|
106
|
+
const onCloseRef = (0, _react.useRef)(onClose);
|
|
107
|
+
onCloseRef.current = onClose;
|
|
108
|
+
|
|
109
|
+
// In controlled mode, mirror the `open` prop into the internal open/closing
|
|
110
|
+
// state machine so both modes share the same exit-animation lifecycle.
|
|
111
|
+
(0, _react.useEffect)(() => {
|
|
112
|
+
if (!isControlled) return;
|
|
113
|
+
if (controlledOpen) {
|
|
114
|
+
setIsClosing(false);
|
|
115
|
+
setIsOpen(true);
|
|
116
|
+
} else {
|
|
117
|
+
setIsClosing(true);
|
|
118
|
+
}
|
|
119
|
+
}, [isControlled, controlledOpen]);
|
|
120
|
+
const exitDuration = resolvedPlacement === 'center' ? FADE_OUT_DURATION : _placement.ANIMATION_DURATION;
|
|
60
121
|
(0, _react.useEffect)(() => {
|
|
61
122
|
if (!isClosing) return;
|
|
62
123
|
const timer = setTimeout(() => {
|
|
@@ -73,16 +134,22 @@ function Dialog({
|
|
|
73
134
|
}
|
|
74
135
|
}
|
|
75
136
|
}
|
|
76
|
-
onClose
|
|
77
|
-
|
|
137
|
+
// Imperative mode fires `onClose` when the exit settles. Controlled mode
|
|
138
|
+
// already requested the close through `onClose` (the host then flipped
|
|
139
|
+
// `open`), so it must NOT fire it a second time here.
|
|
140
|
+
if (!isControlledRef.current) onCloseRef.current?.();
|
|
141
|
+
}, exitDuration);
|
|
78
142
|
return () => clearTimeout(timer);
|
|
79
|
-
}, [isClosing,
|
|
143
|
+
}, [isClosing, exitDuration]);
|
|
80
144
|
|
|
81
145
|
// Escape-to-close while open. The listener is intentionally scoped to the
|
|
82
146
|
// open lifetime so stacked dialogs don't fight for the keydown — the
|
|
83
|
-
// top-most one wins via document-level event order.
|
|
147
|
+
// top-most one wins via document-level event order. Escape honors
|
|
148
|
+
// `dismissOnBackdrop`: a blocking dialog (e.g. an unanswered confirm) is not
|
|
149
|
+
// dismissible by Escape, matching the backdrop's behavior. The default
|
|
150
|
+
// (`dismissOnBackdrop` true) is unchanged — Escape still closes.
|
|
84
151
|
(0, _react.useEffect)(() => {
|
|
85
|
-
if (!isOpen || typeof document === 'undefined') return;
|
|
152
|
+
if (!isOpen || !dismissOnBackdrop || typeof document === 'undefined') return;
|
|
86
153
|
const handler = e => {
|
|
87
154
|
if (e.key === 'Escape') {
|
|
88
155
|
e.stopPropagation();
|
|
@@ -91,8 +158,8 @@ function Dialog({
|
|
|
91
158
|
};
|
|
92
159
|
document.addEventListener('keydown', handler);
|
|
93
160
|
return () => document.removeEventListener('keydown', handler);
|
|
94
|
-
}, [close, isOpen]);
|
|
95
|
-
(0, _react.useImperativeHandle)(control
|
|
161
|
+
}, [close, dismissOnBackdrop, isOpen]);
|
|
162
|
+
(0, _react.useImperativeHandle)(control?.ref, () => ({
|
|
96
163
|
open,
|
|
97
164
|
close
|
|
98
165
|
}), [open, close]);
|
|
@@ -101,46 +168,121 @@ function Dialog({
|
|
|
101
168
|
isWithinDialog: true
|
|
102
169
|
}), [close]);
|
|
103
170
|
if (!isOpen) return null;
|
|
171
|
+
if (resolvedPlacement === 'center') {
|
|
172
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_indexWeb.Portal, {
|
|
173
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_context.Context.Provider, {
|
|
174
|
+
value: context,
|
|
175
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(ClosingContext.Provider, {
|
|
176
|
+
value: isClosing,
|
|
177
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRemoveScrollBar.RemoveScrollBar, {}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.Pressable, {
|
|
178
|
+
onPress: dismissOnBackdrop ? () => close() : undefined,
|
|
179
|
+
disabled: !dismissOnBackdrop
|
|
180
|
+
// `pointerEvents: 'auto'` opts back in from the Portal root's
|
|
181
|
+
// `pointer-events: none`, which is set so the idle portal
|
|
182
|
+
// doesn't intercept clicks on the underlying app.
|
|
183
|
+
,
|
|
184
|
+
style: {
|
|
185
|
+
position: 'fixed',
|
|
186
|
+
top: 0,
|
|
187
|
+
left: 0,
|
|
188
|
+
right: 0,
|
|
189
|
+
bottom: 0,
|
|
190
|
+
zIndex: dialogZIndex.backdrop,
|
|
191
|
+
alignItems: 'center',
|
|
192
|
+
justifyContent: 'center',
|
|
193
|
+
paddingHorizontal: 20,
|
|
194
|
+
pointerEvents: 'auto'
|
|
195
|
+
},
|
|
196
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(DialogBackdrop, {
|
|
197
|
+
isClosing: isClosing
|
|
198
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(DialogPanel, {
|
|
199
|
+
testID: testID,
|
|
200
|
+
label: label,
|
|
201
|
+
title: title,
|
|
202
|
+
description: description,
|
|
203
|
+
actions: actions,
|
|
204
|
+
style: style,
|
|
205
|
+
maxWidth: maxWidth,
|
|
206
|
+
isClosing: isClosing,
|
|
207
|
+
children: children
|
|
208
|
+
})]
|
|
209
|
+
})]
|
|
210
|
+
})
|
|
211
|
+
})
|
|
212
|
+
});
|
|
213
|
+
}
|
|
104
214
|
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_indexWeb.Portal, {
|
|
105
215
|
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_context.Context.Provider, {
|
|
106
216
|
value: context,
|
|
107
217
|
children: /*#__PURE__*/(0, _jsxRuntime.jsxs)(ClosingContext.Provider, {
|
|
108
218
|
value: isClosing,
|
|
109
|
-
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRemoveScrollBar.RemoveScrollBar, {}), /*#__PURE__*/(0, _jsxRuntime.
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
,
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
}), /*#__PURE__*/(0, _jsxRuntime.jsx)(DialogPanel, {
|
|
130
|
-
testID: testID,
|
|
131
|
-
label: label,
|
|
132
|
-
title: title,
|
|
133
|
-
description: description,
|
|
134
|
-
actions: actions,
|
|
135
|
-
style: style,
|
|
136
|
-
isClosing: isClosing,
|
|
137
|
-
children: children
|
|
138
|
-
})]
|
|
219
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRemoveScrollBar.RemoveScrollBar, {}), /*#__PURE__*/(0, _jsxRuntime.jsx)(SheetSurface, {
|
|
220
|
+
testID: testID,
|
|
221
|
+
label: label,
|
|
222
|
+
title: title,
|
|
223
|
+
description: description,
|
|
224
|
+
actions: actions,
|
|
225
|
+
placement: resolvedPlacement,
|
|
226
|
+
shown: !isClosing,
|
|
227
|
+
width: width,
|
|
228
|
+
maxHeightRatio: maxHeightRatio,
|
|
229
|
+
inset: inset,
|
|
230
|
+
showHandle: showHandle,
|
|
231
|
+
dismissOnBackdrop: dismissOnBackdrop,
|
|
232
|
+
onDismiss: close,
|
|
233
|
+
panelStyle: panelStyle,
|
|
234
|
+
panelClassName: panelClassName,
|
|
235
|
+
containerStyle: containerStyle,
|
|
236
|
+
containerClassName: containerClassName,
|
|
237
|
+
style: style,
|
|
238
|
+
children: children
|
|
139
239
|
})]
|
|
140
240
|
})
|
|
141
241
|
})
|
|
142
242
|
});
|
|
143
243
|
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Renders the dialog's body: optional declarative title + description, any
|
|
247
|
+
* `children`, then the action row. Shared by the centered panel and the
|
|
248
|
+
* side/bottom sheet so all placements present identical content. The
|
|
249
|
+
* `titleId`/`descriptionId` are wired by the caller onto the `role="dialog"`
|
|
250
|
+
* element for `aria-labelledby` / `aria-describedby`.
|
|
251
|
+
*/
|
|
252
|
+
function DialogBody({
|
|
253
|
+
titleId,
|
|
254
|
+
descriptionId,
|
|
255
|
+
title,
|
|
256
|
+
description,
|
|
257
|
+
actions,
|
|
258
|
+
children
|
|
259
|
+
}) {
|
|
260
|
+
const theme = (0, _useTheme.useTheme)();
|
|
261
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
262
|
+
children: [title ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
263
|
+
nativeID: titleId,
|
|
264
|
+
style: {
|
|
265
|
+
fontSize: 22,
|
|
266
|
+
fontWeight: '600',
|
|
267
|
+
color: theme.colors.text,
|
|
268
|
+
paddingBottom: description ? 4 : 16,
|
|
269
|
+
lineHeight: 30
|
|
270
|
+
},
|
|
271
|
+
children: title
|
|
272
|
+
}) : null, description ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
273
|
+
nativeID: descriptionId,
|
|
274
|
+
style: {
|
|
275
|
+
fontSize: 16,
|
|
276
|
+
color: theme.colors.textSecondary,
|
|
277
|
+
paddingBottom: 16,
|
|
278
|
+
lineHeight: 22
|
|
279
|
+
},
|
|
280
|
+
children: description
|
|
281
|
+
}) : null, children, actions && actions.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(ActionRow, {
|
|
282
|
+
actions: actions
|
|
283
|
+
}) : null]
|
|
284
|
+
});
|
|
285
|
+
}
|
|
144
286
|
function DialogPanel({
|
|
145
287
|
testID,
|
|
146
288
|
label,
|
|
@@ -148,13 +290,14 @@ function DialogPanel({
|
|
|
148
290
|
description,
|
|
149
291
|
actions,
|
|
150
292
|
style,
|
|
293
|
+
maxWidth,
|
|
151
294
|
isClosing,
|
|
152
295
|
children
|
|
153
296
|
}) {
|
|
154
297
|
const theme = (0, _useTheme.useTheme)();
|
|
155
298
|
const titleId = (0, _react.useId)();
|
|
156
299
|
const descriptionId = (0, _react.useId)();
|
|
157
|
-
return /*#__PURE__*/(0, _jsxRuntime.
|
|
300
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
158
301
|
role: "dialog",
|
|
159
302
|
"aria-label": label,
|
|
160
303
|
"aria-labelledby": title ? titleId : undefined,
|
|
@@ -167,7 +310,7 @@ function DialogPanel({
|
|
|
167
310
|
position: 'relative',
|
|
168
311
|
borderRadius: 20,
|
|
169
312
|
width: '100%',
|
|
170
|
-
maxWidth
|
|
313
|
+
maxWidth,
|
|
171
314
|
backgroundColor: theme.colors.background,
|
|
172
315
|
borderWidth: 1,
|
|
173
316
|
borderColor: theme.isDark ? 'rgba(255,255,255,0.1)' : 'rgba(0,0,0,0.1)',
|
|
@@ -185,30 +328,194 @@ function DialogPanel({
|
|
|
185
328
|
} : {
|
|
186
329
|
animation: 'bloomDialogZoomFadeIn cubic-bezier(0.16, 1, 0.3, 1) 0.3s'
|
|
187
330
|
}, style],
|
|
188
|
-
children:
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
331
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(DialogBody, {
|
|
332
|
+
titleId: titleId,
|
|
333
|
+
descriptionId: descriptionId,
|
|
334
|
+
title: title,
|
|
335
|
+
description: description,
|
|
336
|
+
actions: actions,
|
|
337
|
+
children: children
|
|
338
|
+
})
|
|
339
|
+
});
|
|
340
|
+
}
|
|
341
|
+
/**
|
|
342
|
+
* Side-sheet / bottom-sheet surface for the `left`/`right`/`bottom`
|
|
343
|
+
* placements. Pure CSS transitions: the
|
|
344
|
+
* node stays mounted through the exit while a `shown` flag drives the
|
|
345
|
+
* transform/opacity, so both directions animate without reanimated `exiting`.
|
|
346
|
+
*/
|
|
347
|
+
function SheetSurface({
|
|
348
|
+
testID,
|
|
349
|
+
label,
|
|
350
|
+
title,
|
|
351
|
+
description,
|
|
352
|
+
actions,
|
|
353
|
+
placement,
|
|
354
|
+
shown,
|
|
355
|
+
width,
|
|
356
|
+
maxHeightRatio,
|
|
357
|
+
inset,
|
|
358
|
+
showHandle,
|
|
359
|
+
dismissOnBackdrop,
|
|
360
|
+
onDismiss,
|
|
361
|
+
panelStyle,
|
|
362
|
+
panelClassName,
|
|
363
|
+
containerStyle,
|
|
364
|
+
containerClassName,
|
|
365
|
+
style,
|
|
366
|
+
children
|
|
367
|
+
}) {
|
|
368
|
+
const theme = (0, _useTheme.useTheme)();
|
|
369
|
+
const titleId = (0, _react.useId)();
|
|
370
|
+
const descriptionId = (0, _react.useId)();
|
|
371
|
+
const {
|
|
372
|
+
width: viewportWidth,
|
|
373
|
+
height: viewportHeight
|
|
374
|
+
} = (0, _reactNative.useWindowDimensions)();
|
|
375
|
+
|
|
376
|
+
// Defer the entry transition by a frame so the start state paints before the
|
|
377
|
+
// browser animates to `shown`. `entered` is false on the first committed
|
|
378
|
+
// frame, then flips true so the CSS transition runs.
|
|
379
|
+
const frameRef = (0, _react.useRef)(null);
|
|
380
|
+
const [entered, setEntered] = (0, _react.useState)(false);
|
|
381
|
+
(0, _react.useEffect)(() => {
|
|
382
|
+
frameRef.current = scheduleFrame(() => {
|
|
383
|
+
frameRef.current = scheduleFrame(() => setEntered(true));
|
|
384
|
+
});
|
|
385
|
+
return () => {
|
|
386
|
+
if (frameRef.current !== null) cancelFrame(frameRef.current);
|
|
387
|
+
frameRef.current = null;
|
|
388
|
+
};
|
|
389
|
+
}, []);
|
|
390
|
+
const visible = shown && entered;
|
|
391
|
+
const isBottom = placement === 'bottom';
|
|
392
|
+
const panelTransition = (0, _react.useMemo)(() => ({
|
|
393
|
+
transitionProperty: 'transform, opacity',
|
|
394
|
+
transitionDuration: `${_placement.ANIMATION_DURATION}ms`,
|
|
395
|
+
transitionTimingFunction: _placement.EASE_OUT
|
|
396
|
+
}), []);
|
|
397
|
+
const backdropTransition = (0, _react.useMemo)(() => ({
|
|
398
|
+
transitionProperty: 'opacity',
|
|
399
|
+
transitionDuration: `${_placement.ANIMATION_DURATION}ms`,
|
|
400
|
+
transitionTimingFunction: _placement.EASE_OUT
|
|
401
|
+
}), []);
|
|
402
|
+
const panelGeometry = (0, _react.useMemo)(() => {
|
|
403
|
+
if (isBottom) {
|
|
404
|
+
return {
|
|
405
|
+
left: 0,
|
|
406
|
+
right: 0,
|
|
407
|
+
bottom: 0,
|
|
408
|
+
maxHeight: Math.round(viewportHeight * maxHeightRatio),
|
|
409
|
+
borderTopLeftRadius: _placement.PANEL_RADIUS,
|
|
410
|
+
borderTopRightRadius: _placement.PANEL_RADIUS,
|
|
411
|
+
transform: [{
|
|
412
|
+
translateY: visible ? 0 : '100%'
|
|
413
|
+
}],
|
|
414
|
+
opacity: visible ? 1 : 0
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
const insetTop = inset?.top ?? 0;
|
|
418
|
+
const insetBottom = inset?.bottom ?? 0;
|
|
419
|
+
const insetLeft = inset?.left ?? 0;
|
|
420
|
+
const insetRight = inset?.right ?? 0;
|
|
421
|
+
const anchorInset = placement === 'left' ? insetLeft : insetRight;
|
|
422
|
+
const oppositeInset = placement === 'left' ? insetRight : insetLeft;
|
|
423
|
+
const available = viewportWidth - anchorInset - oppositeInset - _placement.SIDE_SHEET_MIN_GUTTER;
|
|
424
|
+
const cappedWidth = Math.max(0, Math.min(width, available));
|
|
425
|
+
const hiddenSign = placement === 'left' ? '-100%' : '100%';
|
|
426
|
+
return {
|
|
427
|
+
top: insetTop,
|
|
428
|
+
bottom: insetBottom,
|
|
429
|
+
[placement]: anchorInset,
|
|
430
|
+
width: cappedWidth,
|
|
431
|
+
borderRadius: _placement.PANEL_RADIUS,
|
|
432
|
+
transform: [{
|
|
433
|
+
translateX: visible ? 0 : hiddenSign
|
|
434
|
+
}],
|
|
435
|
+
opacity: visible ? 1 : 0
|
|
436
|
+
};
|
|
437
|
+
}, [isBottom, visible, placement, width, inset, viewportWidth, viewportHeight, maxHeightRatio]);
|
|
438
|
+
const handleBackdropPress = (0, _react.useCallback)(() => {
|
|
439
|
+
if (dismissOnBackdrop) onDismiss();
|
|
440
|
+
}, [dismissOnBackdrop, onDismiss]);
|
|
441
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
442
|
+
style: [sheetStyles.root, containerStyle],
|
|
443
|
+
...(containerClassName ? {
|
|
444
|
+
className: containerClassName
|
|
445
|
+
} : {}),
|
|
446
|
+
pointerEvents: "box-none",
|
|
447
|
+
children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Pressable, {
|
|
448
|
+
testID: testID ? `${testID}-backdrop` : _placement.DIALOG_SHEET_BACKDROP_TESTID,
|
|
449
|
+
accessibilityRole: "button",
|
|
450
|
+
accessibilityLabel: label ? `Dismiss ${label}` : 'Dismiss dialog',
|
|
451
|
+
onPress: handleBackdropPress,
|
|
452
|
+
disabled: !dismissOnBackdrop,
|
|
453
|
+
style: [sheetStyles.backdrop, backdropTransition, {
|
|
454
|
+
opacity: visible ? _placement.SHEET_BACKDROP_OPACITY : 0
|
|
455
|
+
}]
|
|
456
|
+
}), /*#__PURE__*/(0, _jsxRuntime.jsxs)(_reactNative.View, {
|
|
457
|
+
role: "dialog",
|
|
458
|
+
"aria-label": label,
|
|
459
|
+
"aria-labelledby": title ? titleId : undefined,
|
|
460
|
+
"aria-describedby": description ? descriptionId : undefined,
|
|
461
|
+
accessibilityViewIsModal: true,
|
|
462
|
+
testID: testID,
|
|
463
|
+
onStartShouldSetResponder: () => true,
|
|
464
|
+
onResponderRelease: stopPropagation,
|
|
465
|
+
onClick: stopPropagation,
|
|
466
|
+
...(panelClassName ? {
|
|
467
|
+
className: panelClassName
|
|
468
|
+
} : {}),
|
|
469
|
+
style: [sheetStyles.panel, {
|
|
470
|
+
backgroundColor: theme.colors.background,
|
|
471
|
+
shadowColor: theme.colors.shadow
|
|
472
|
+
}, panelGeometry, panelTransition, panelStyle, style],
|
|
473
|
+
pointerEvents: "auto",
|
|
474
|
+
children: [isBottom && showHandle ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
475
|
+
style: sheetStyles.handleRow,
|
|
476
|
+
pointerEvents: "none",
|
|
477
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
478
|
+
style: [sheetStyles.handle, {
|
|
479
|
+
backgroundColor: theme.colors.border
|
|
480
|
+
}]
|
|
481
|
+
})
|
|
482
|
+
}) : null, /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
483
|
+
style: sheetStyles.body,
|
|
484
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(DialogBody, {
|
|
485
|
+
titleId: titleId,
|
|
486
|
+
descriptionId: descriptionId,
|
|
487
|
+
title: title,
|
|
488
|
+
description: description,
|
|
489
|
+
actions: actions,
|
|
490
|
+
children: children
|
|
491
|
+
})
|
|
492
|
+
})]
|
|
493
|
+
})]
|
|
210
494
|
});
|
|
211
495
|
}
|
|
496
|
+
|
|
497
|
+
/**
|
|
498
|
+
* Opaque token returned by `scheduleFrame`. `requestAnimationFrame` returns a
|
|
499
|
+
* number; the `setTimeout` fallback returns a timer handle.
|
|
500
|
+
*/
|
|
501
|
+
|
|
502
|
+
function scheduleFrame(cb) {
|
|
503
|
+
if (typeof requestAnimationFrame === 'function') {
|
|
504
|
+
return {
|
|
505
|
+
raf: requestAnimationFrame(cb)
|
|
506
|
+
};
|
|
507
|
+
}
|
|
508
|
+
return {
|
|
509
|
+
timer: setTimeout(cb, 0)
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
function cancelFrame(token) {
|
|
513
|
+
if ('raf' in token) {
|
|
514
|
+
if (typeof cancelAnimationFrame === 'function') cancelAnimationFrame(token.raf);
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
clearTimeout(token.timer);
|
|
518
|
+
}
|
|
212
519
|
function ActionRow({
|
|
213
520
|
actions
|
|
214
521
|
}) {
|
|
@@ -343,6 +650,50 @@ function AutoMountedDialog({
|
|
|
343
650
|
onClose: onResolve
|
|
344
651
|
});
|
|
345
652
|
}
|
|
653
|
+
const sheetStyles = {
|
|
654
|
+
root: {
|
|
655
|
+
position: 'fixed',
|
|
656
|
+
top: 0,
|
|
657
|
+
left: 0,
|
|
658
|
+
right: 0,
|
|
659
|
+
bottom: 0,
|
|
660
|
+
zIndex: dialogZIndex.backdrop
|
|
661
|
+
},
|
|
662
|
+
backdrop: {
|
|
663
|
+
position: 'absolute',
|
|
664
|
+
top: 0,
|
|
665
|
+
left: 0,
|
|
666
|
+
right: 0,
|
|
667
|
+
bottom: 0,
|
|
668
|
+
backgroundColor: '#000'
|
|
669
|
+
},
|
|
670
|
+
panel: {
|
|
671
|
+
position: 'absolute',
|
|
672
|
+
overflow: 'hidden',
|
|
673
|
+
shadowOpacity: 0.18,
|
|
674
|
+
shadowRadius: 24,
|
|
675
|
+
shadowOffset: {
|
|
676
|
+
width: 0,
|
|
677
|
+
height: 8
|
|
678
|
+
},
|
|
679
|
+
zIndex: dialogZIndex.surface
|
|
680
|
+
},
|
|
681
|
+
handleRow: {
|
|
682
|
+
width: '100%',
|
|
683
|
+
alignItems: 'center',
|
|
684
|
+
paddingTop: 8,
|
|
685
|
+
paddingBottom: 4
|
|
686
|
+
},
|
|
687
|
+
handle: {
|
|
688
|
+
width: _placement.HANDLE_WIDTH,
|
|
689
|
+
height: _placement.HANDLE_HEIGHT,
|
|
690
|
+
borderRadius: _placement.HANDLE_RADIUS,
|
|
691
|
+
opacity: 0.5
|
|
692
|
+
},
|
|
693
|
+
body: {
|
|
694
|
+
padding: 20
|
|
695
|
+
}
|
|
696
|
+
};
|
|
346
697
|
|
|
347
698
|
/**
|
|
348
699
|
* CSS keyframes required for web dialog animations.
|
|
@@ -354,6 +705,9 @@ function AutoMountedDialog({
|
|
|
354
705
|
* @keyframes bloomDialogZoomFadeIn { from { opacity: 0; transform: scale(0.95); } to { opacity: 1; transform: scale(1); } }
|
|
355
706
|
* @keyframes bloomDialogZoomFadeOut { from { opacity: 1; transform: scale(1); } to { opacity: 0; transform: scale(0.95); } }
|
|
356
707
|
* ```
|
|
708
|
+
*
|
|
709
|
+
* The `left`/`right`/`bottom` placements do NOT depend on this — they animate
|
|
710
|
+
* via self-contained inline CSS transitions and need no keyframe injection.
|
|
357
711
|
*/
|
|
358
712
|
const BLOOM_DIALOG_CSS = exports.BLOOM_DIALOG_CSS = `
|
|
359
713
|
@keyframes bloomDialogFadeIn { from { opacity: 0; } to { opacity: 1; } }
|