@oxyhq/bloom 0.16.0 → 0.16.1
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/dialog/Dialog.js +38 -150
- package/lib/commonjs/dialog/Dialog.js.map +1 -1
- package/lib/commonjs/dialog/Dialog.web.js +55 -193
- package/lib/commonjs/dialog/Dialog.web.js.map +1 -1
- package/lib/commonjs/dialog/DialogBottomSheet.js +205 -0
- package/lib/commonjs/dialog/DialogBottomSheet.js.map +1 -0
- package/lib/commonjs/dialog/DialogContent.js +155 -0
- package/lib/commonjs/dialog/DialogContent.js.map +1 -0
- package/lib/module/dialog/Dialog.js +41 -153
- package/lib/module/dialog/Dialog.js.map +1 -1
- package/lib/module/dialog/Dialog.web.js +57 -195
- package/lib/module/dialog/Dialog.web.js.map +1 -1
- package/lib/module/dialog/DialogBottomSheet.js +200 -0
- package/lib/module/dialog/DialogBottomSheet.js.map +1 -0
- package/lib/module/dialog/DialogContent.js +148 -0
- package/lib/module/dialog/DialogContent.js.map +1 -0
- package/lib/typescript/commonjs/dialog/Dialog.d.ts +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts +11 -8
- package/lib/typescript/commonjs/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/commonjs/dialog/DialogBottomSheet.d.ts +29 -0
- package/lib/typescript/commonjs/dialog/DialogBottomSheet.d.ts.map +1 -0
- package/lib/typescript/commonjs/dialog/DialogContent.d.ts +32 -0
- package/lib/typescript/commonjs/dialog/DialogContent.d.ts.map +1 -0
- package/lib/typescript/module/dialog/Dialog.d.ts +1 -1
- package/lib/typescript/module/dialog/Dialog.d.ts.map +1 -1
- package/lib/typescript/module/dialog/Dialog.web.d.ts +11 -8
- package/lib/typescript/module/dialog/Dialog.web.d.ts.map +1 -1
- package/lib/typescript/module/dialog/DialogBottomSheet.d.ts +29 -0
- package/lib/typescript/module/dialog/DialogBottomSheet.d.ts.map +1 -0
- package/lib/typescript/module/dialog/DialogContent.d.ts +32 -0
- package/lib/typescript/module/dialog/DialogContent.d.ts.map +1 -0
- package/package.json +1 -1
- package/src/__tests__/BottomSheetGesture.test.tsx +135 -0
- package/src/__tests__/DialogBottomSheet.test.tsx +130 -0
- package/src/dialog/Dialog.tsx +34 -166
- package/src/dialog/Dialog.web.tsx +46 -206
- package/src/dialog/DialogBottomSheet.tsx +235 -0
- package/src/dialog/DialogContent.tsx +157 -0
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.DialogBottomSheet = DialogBottomSheet;
|
|
7
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
8
|
+
var _reactNative = require("react-native");
|
|
9
|
+
var _index = require("../bottom-sheet/index.js");
|
|
10
|
+
var _useTheme = require("../theme/use-theme.js");
|
|
11
|
+
var _context = require("./context.js");
|
|
12
|
+
var _DialogContent = require("./DialogContent.js");
|
|
13
|
+
var _placement = require("./placement.js");
|
|
14
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
15
|
+
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); }
|
|
16
|
+
/**
|
|
17
|
+
* Padding of the bottom-sheet content container (px). Matches the side-sheet
|
|
18
|
+
* and centered-panel body padding so every placement reads identically.
|
|
19
|
+
*/
|
|
20
|
+
const SHEET_CONTENT_PADDING = 20;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Shared `BottomSheet`-backed surface for the `bottom` placement, used by BOTH
|
|
24
|
+
* `Dialog.tsx` (native) and `Dialog.web.tsx` (web). `BottomSheet` is itself a
|
|
25
|
+
* single cross-platform implementation (react-native-gesture-handler +
|
|
26
|
+
* reanimated, drag-to-dismiss on web and native alike), so routing the bottom
|
|
27
|
+
* placement through here gives ONE code path with drag working everywhere — no
|
|
28
|
+
* duplicated CSS slide-up sheet.
|
|
29
|
+
*
|
|
30
|
+
* This component owns the entire open↔present/dismiss bridge and the Dialog →
|
|
31
|
+
* BottomSheet prop mapping in one place:
|
|
32
|
+
*
|
|
33
|
+
* - `open` (controlled) / `control` (imperative) → `present()` / `dismiss()`
|
|
34
|
+
* - `onClose` → fired once the sheet settles
|
|
35
|
+
* - `maxHeightRatio` → sheet `maxHeight`
|
|
36
|
+
* - `showHandle` / `dismissOnBackdrop` / `label` → forwarded to the surface
|
|
37
|
+
* - `panelStyle` → paints the sheet surface
|
|
38
|
+
* - `containerStyle` → wraps the content subtree
|
|
39
|
+
* so a host's CSS-var theme scope (`vars()`) still applies to descendants
|
|
40
|
+
* - `title` / `description` / `actions` / `children` → declarative body
|
|
41
|
+
*/
|
|
42
|
+
function DialogBottomSheet({
|
|
43
|
+
control,
|
|
44
|
+
open: controlledOpen,
|
|
45
|
+
onClose,
|
|
46
|
+
testID,
|
|
47
|
+
title,
|
|
48
|
+
description,
|
|
49
|
+
actions,
|
|
50
|
+
maxHeightRatio = _placement.DEFAULT_MAX_HEIGHT_RATIO,
|
|
51
|
+
showHandle = true,
|
|
52
|
+
dismissOnBackdrop = true,
|
|
53
|
+
style,
|
|
54
|
+
panelStyle,
|
|
55
|
+
panelClassName,
|
|
56
|
+
containerStyle,
|
|
57
|
+
containerClassName,
|
|
58
|
+
label,
|
|
59
|
+
children
|
|
60
|
+
}) {
|
|
61
|
+
const isControlled = controlledOpen !== undefined;
|
|
62
|
+
const theme = (0, _useTheme.useTheme)();
|
|
63
|
+
const ref = (0, _react.useRef)(null);
|
|
64
|
+
const closeCallbacks = (0, _react.useRef)([]);
|
|
65
|
+
const titleId = (0, _react.useId)();
|
|
66
|
+
const descriptionId = (0, _react.useId)();
|
|
67
|
+
|
|
68
|
+
// Read the latest controlled flag / `onClose` inside stable callbacks without
|
|
69
|
+
// re-binding them (the context + imperative handle depend on `close` staying
|
|
70
|
+
// referentially stable).
|
|
71
|
+
const isControlledRef = (0, _react.useRef)(isControlled);
|
|
72
|
+
isControlledRef.current = isControlled;
|
|
73
|
+
const onCloseRef = (0, _react.useRef)(onClose);
|
|
74
|
+
onCloseRef.current = onClose;
|
|
75
|
+
|
|
76
|
+
// Drain queued close callbacks atomically — capturing the list and resetting
|
|
77
|
+
// it before invocation ensures a callback that synchronously re-opens the
|
|
78
|
+
// dialog (and queues fresh callbacks) does not see the old ones replayed
|
|
79
|
+
// against the new session.
|
|
80
|
+
const callQueuedCallbacks = (0, _react.useCallback)(() => {
|
|
81
|
+
const queued = closeCallbacks.current;
|
|
82
|
+
closeCallbacks.current = [];
|
|
83
|
+
for (const cb of queued) {
|
|
84
|
+
try {
|
|
85
|
+
cb();
|
|
86
|
+
} catch (e) {
|
|
87
|
+
if (typeof console !== 'undefined' && console.error) {
|
|
88
|
+
console.error('Dialog close callback error:', e);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}, []);
|
|
93
|
+
const open = (0, _react.useCallback)(() => {
|
|
94
|
+
ref.current?.present();
|
|
95
|
+
}, []);
|
|
96
|
+
|
|
97
|
+
// A dismissal request (backdrop, pan-to-close, action button). In controlled
|
|
98
|
+
// mode it asks the host to close via `onClose` (the host flips `open`); in
|
|
99
|
+
// imperative mode it dismisses the surface directly. The optional callback
|
|
100
|
+
// runs once the dialog has finished closing.
|
|
101
|
+
const close = (0, _react.useCallback)(cb => {
|
|
102
|
+
if (typeof cb === 'function') {
|
|
103
|
+
closeCallbacks.current.push(cb);
|
|
104
|
+
}
|
|
105
|
+
if (isControlledRef.current) {
|
|
106
|
+
onCloseRef.current?.();
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
ref.current?.dismiss();
|
|
110
|
+
}, []);
|
|
111
|
+
|
|
112
|
+
// Fired when the sheet has finished closing. Drains queued callbacks, then
|
|
113
|
+
// fires `onClose` ONLY in imperative mode — controlled mode already requested
|
|
114
|
+
// the close through `onClose` (the host then flipped `open`), so firing it
|
|
115
|
+
// again here would double-call it.
|
|
116
|
+
const handleDismiss = (0, _react.useCallback)(() => {
|
|
117
|
+
callQueuedCallbacks();
|
|
118
|
+
if (!isControlledRef.current) onCloseRef.current?.();
|
|
119
|
+
}, [callQueuedCallbacks]);
|
|
120
|
+
|
|
121
|
+
// In controlled mode, mirror the `open` prop onto the underlying sheet so both
|
|
122
|
+
// modes share one lifecycle.
|
|
123
|
+
(0, _react.useEffect)(() => {
|
|
124
|
+
if (!isControlled) return;
|
|
125
|
+
if (controlledOpen) {
|
|
126
|
+
ref.current?.present();
|
|
127
|
+
} else {
|
|
128
|
+
ref.current?.dismiss();
|
|
129
|
+
}
|
|
130
|
+
}, [isControlled, controlledOpen]);
|
|
131
|
+
(0, _react.useImperativeHandle)(control?.ref, () => ({
|
|
132
|
+
open,
|
|
133
|
+
close
|
|
134
|
+
}), [open, close]);
|
|
135
|
+
const context = (0, _react.useMemo)(() => ({
|
|
136
|
+
close,
|
|
137
|
+
isWithinDialog: true
|
|
138
|
+
}), [close]);
|
|
139
|
+
|
|
140
|
+
// Backdrop press → dismiss, unless the host disabled it. Returning `false`
|
|
141
|
+
// from `onDismissAttempt` blocks the BottomSheet's own backdrop/pan dismissal,
|
|
142
|
+
// which is how `dismissOnBackdrop: false` maps onto the single sheet API.
|
|
143
|
+
const onDismissAttempt = (0, _react.useCallback)(() => dismissOnBackdrop, [dismissOnBackdrop]);
|
|
144
|
+
|
|
145
|
+
// `panelStyle` paints the sheet surface (e.g. a brand background). It composes
|
|
146
|
+
// AFTER the BottomSheet's internal background so a host palette wins; the
|
|
147
|
+
// shape (radius, max height) is supplied here and remains overridable.
|
|
148
|
+
const sheetStyle = (0, _react.useMemo)(() => {
|
|
149
|
+
const maxHeightPercent = `${Math.round(maxHeightRatio * 100)}%`;
|
|
150
|
+
return [{
|
|
151
|
+
backgroundColor: theme.colors.background,
|
|
152
|
+
borderTopLeftRadius: _placement.PANEL_RADIUS + 4,
|
|
153
|
+
borderTopRightRadius: _placement.PANEL_RADIUS + 4,
|
|
154
|
+
maxHeight: maxHeightPercent
|
|
155
|
+
}, panelStyle];
|
|
156
|
+
}, [theme.colors.background, maxHeightRatio, panelStyle]);
|
|
157
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_index.BottomSheet, {
|
|
158
|
+
ref: ref,
|
|
159
|
+
onDismiss: handleDismiss,
|
|
160
|
+
onDismissAttempt: onDismissAttempt,
|
|
161
|
+
enablePanDownToClose: true,
|
|
162
|
+
showHandle: showHandle
|
|
163
|
+
// Stronger dim than a lone sheet so an underlying sheet's handle/content
|
|
164
|
+
// doesn't bleed through when a Dialog is stacked over one.
|
|
165
|
+
,
|
|
166
|
+
backdropOpacity: _placement.SHEET_BACKDROP_OPACITY + 0.3,
|
|
167
|
+
style: sheetStyle,
|
|
168
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_context.Context.Provider, {
|
|
169
|
+
value: context,
|
|
170
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
171
|
+
testID: testID,
|
|
172
|
+
accessibilityLabel: label,
|
|
173
|
+
"aria-labelledby": title ? titleId : undefined,
|
|
174
|
+
"aria-describedby": description ? descriptionId : undefined,
|
|
175
|
+
...(containerClassName ? {
|
|
176
|
+
className: containerClassName
|
|
177
|
+
} : {}),
|
|
178
|
+
...(panelClassName ? {
|
|
179
|
+
className: panelClassName
|
|
180
|
+
} : {}),
|
|
181
|
+
style: [{
|
|
182
|
+
padding: SHEET_CONTENT_PADDING
|
|
183
|
+
},
|
|
184
|
+
// `containerStyle` carries the host's CSS-var theme scope; it wraps
|
|
185
|
+
// the content subtree so descendants read the scoped palette.
|
|
186
|
+
containerStyle, style, panelStyle],
|
|
187
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DialogContent.DialogBody, {
|
|
188
|
+
titleId: titleId,
|
|
189
|
+
descriptionId: descriptionId,
|
|
190
|
+
title: title,
|
|
191
|
+
description: description,
|
|
192
|
+
actions: actions,
|
|
193
|
+
children: children
|
|
194
|
+
})
|
|
195
|
+
})
|
|
196
|
+
})
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* Props the shared bottom-sheet surface consumes — the `bottom`-relevant subset
|
|
202
|
+
* of `DialogProps`. `width`, `maxWidth`, and `inset` are placement-specific to
|
|
203
|
+
* the side/centered surfaces and intentionally excluded.
|
|
204
|
+
*/
|
|
205
|
+
//# sourceMappingURL=DialogBottomSheet.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_index","_useTheme","_context","_DialogContent","_placement","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","SHEET_CONTENT_PADDING","DialogBottomSheet","control","open","controlledOpen","onClose","testID","title","description","actions","maxHeightRatio","DEFAULT_MAX_HEIGHT_RATIO","showHandle","dismissOnBackdrop","style","panelStyle","panelClassName","containerStyle","containerClassName","label","children","isControlled","undefined","theme","useTheme","ref","useRef","closeCallbacks","titleId","useId","descriptionId","isControlledRef","current","onCloseRef","callQueuedCallbacks","useCallback","queued","cb","console","error","present","close","push","dismiss","handleDismiss","useEffect","useImperativeHandle","context","useMemo","isWithinDialog","onDismissAttempt","sheetStyle","maxHeightPercent","Math","round","backgroundColor","colors","background","borderTopLeftRadius","PANEL_RADIUS","borderTopRightRadius","maxHeight","jsx","BottomSheet","onDismiss","enablePanDownToClose","backdropOpacity","SHEET_BACKDROP_OPACITY","Context","Provider","value","View","accessibilityLabel","className","padding","DialogBody"],"sourceRoot":"../../../src","sources":["dialog/DialogBottomSheet.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.ActionRow = ActionRow;
|
|
7
|
+
exports.DialogBody = DialogBody;
|
|
8
|
+
exports.getActionPalette = getActionPalette;
|
|
9
|
+
var _react = _interopRequireWildcard(require("react"));
|
|
10
|
+
var _reactNative = require("react-native");
|
|
11
|
+
var _useTheme = require("../theme/use-theme.js");
|
|
12
|
+
var _context = require("./context.js");
|
|
13
|
+
var _jsxRuntime = require("react/jsx-runtime");
|
|
14
|
+
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); }
|
|
15
|
+
/**
|
|
16
|
+
* Shared dialog content primitives used by every `<Dialog>` placement on both
|
|
17
|
+
* platforms — the centered panel, the side-sheets, and the `BottomSheet`-backed
|
|
18
|
+
* bottom placement. Keeping them here is the single source of truth for the
|
|
19
|
+
* declarative `title` / `description` / `actions` chrome, so the surfaces never
|
|
20
|
+
* drift in spacing, typography, or action-button behaviour.
|
|
21
|
+
*/
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Renders the dialog's body: optional declarative title + description, any
|
|
25
|
+
* `children`, then the action row. The `titleId`/`descriptionId` are wired by
|
|
26
|
+
* the caller onto the dialog role element for `aria-labelledby` /
|
|
27
|
+
* `aria-describedby`.
|
|
28
|
+
*/
|
|
29
|
+
function DialogBody({
|
|
30
|
+
titleId,
|
|
31
|
+
descriptionId,
|
|
32
|
+
title,
|
|
33
|
+
description,
|
|
34
|
+
actions,
|
|
35
|
+
children
|
|
36
|
+
}) {
|
|
37
|
+
const theme = (0, _useTheme.useTheme)();
|
|
38
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
|
|
39
|
+
children: [title ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
40
|
+
nativeID: titleId,
|
|
41
|
+
style: {
|
|
42
|
+
fontSize: 22,
|
|
43
|
+
fontWeight: '600',
|
|
44
|
+
color: theme.colors.text,
|
|
45
|
+
paddingBottom: description ? 4 : 16,
|
|
46
|
+
lineHeight: 30
|
|
47
|
+
},
|
|
48
|
+
children: title
|
|
49
|
+
}) : null, description ? /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
50
|
+
nativeID: descriptionId,
|
|
51
|
+
style: {
|
|
52
|
+
fontSize: 16,
|
|
53
|
+
color: theme.colors.textSecondary,
|
|
54
|
+
paddingBottom: 16,
|
|
55
|
+
lineHeight: 22
|
|
56
|
+
},
|
|
57
|
+
children: description
|
|
58
|
+
}) : null, children, actions && actions.length > 0 ? /*#__PURE__*/(0, _jsxRuntime.jsx)(ActionRow, {
|
|
59
|
+
actions: actions
|
|
60
|
+
}) : null]
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
function ActionRow({
|
|
64
|
+
actions
|
|
65
|
+
}) {
|
|
66
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.View, {
|
|
67
|
+
style: {
|
|
68
|
+
width: '100%',
|
|
69
|
+
gap: 8,
|
|
70
|
+
justifyContent: 'flex-end'
|
|
71
|
+
},
|
|
72
|
+
children: actions.map((action, idx) => /*#__PURE__*/(0, _jsxRuntime.jsx)(ActionButton, {
|
|
73
|
+
action: action
|
|
74
|
+
}, `${action.label}-${idx}`))
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
function ActionButton({
|
|
78
|
+
action
|
|
79
|
+
}) {
|
|
80
|
+
const {
|
|
81
|
+
close
|
|
82
|
+
} = (0, _context.useDialogContext)();
|
|
83
|
+
const theme = (0, _useTheme.useTheme)();
|
|
84
|
+
const color = action.color ?? 'default';
|
|
85
|
+
const shouldCloseOnPress = action.shouldCloseOnPress ?? true;
|
|
86
|
+
const {
|
|
87
|
+
background,
|
|
88
|
+
foreground
|
|
89
|
+
} = getActionPalette(color, theme.colors);
|
|
90
|
+
const handlePress = (0, _react.useCallback)(e => {
|
|
91
|
+
const onPress = action.onPress;
|
|
92
|
+
if (color === 'cancel') {
|
|
93
|
+
// Cancel always dismisses; consumer's onPress (rare) runs after.
|
|
94
|
+
close(onPress ? () => onPress(e) : undefined);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
if (shouldCloseOnPress) {
|
|
98
|
+
close(onPress ? () => onPress(e) : undefined);
|
|
99
|
+
} else {
|
|
100
|
+
onPress?.(e);
|
|
101
|
+
}
|
|
102
|
+
}, [action.onPress, close, color, shouldCloseOnPress]);
|
|
103
|
+
return /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.TouchableOpacity, {
|
|
104
|
+
style: {
|
|
105
|
+
borderRadius: 9999,
|
|
106
|
+
alignItems: 'center',
|
|
107
|
+
justifyContent: 'center',
|
|
108
|
+
backgroundColor: background,
|
|
109
|
+
opacity: action.disabled ? 0.5 : 1,
|
|
110
|
+
paddingVertical: 12,
|
|
111
|
+
paddingHorizontal: 24
|
|
112
|
+
},
|
|
113
|
+
onPress: handlePress,
|
|
114
|
+
disabled: action.disabled,
|
|
115
|
+
activeOpacity: 0.7,
|
|
116
|
+
testID: action.testID,
|
|
117
|
+
children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_reactNative.Text, {
|
|
118
|
+
style: {
|
|
119
|
+
fontSize: 16,
|
|
120
|
+
fontWeight: '500',
|
|
121
|
+
color: foreground
|
|
122
|
+
},
|
|
123
|
+
children: action.label
|
|
124
|
+
})
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function getActionPalette(color, colors) {
|
|
128
|
+
switch (color) {
|
|
129
|
+
case 'destructive':
|
|
130
|
+
return {
|
|
131
|
+
background: colors.negative,
|
|
132
|
+
foreground: colors.negativeForeground
|
|
133
|
+
};
|
|
134
|
+
case 'cancel':
|
|
135
|
+
return {
|
|
136
|
+
background: colors.contrast50,
|
|
137
|
+
foreground: colors.text
|
|
138
|
+
};
|
|
139
|
+
case 'default':
|
|
140
|
+
return {
|
|
141
|
+
background: colors.primary,
|
|
142
|
+
foreground: colors.primaryForeground
|
|
143
|
+
};
|
|
144
|
+
/* c8 ignore next 3 -- TS exhaustiveness check guards this branch */
|
|
145
|
+
default:
|
|
146
|
+
{
|
|
147
|
+
const _exhaustive = color;
|
|
148
|
+
return {
|
|
149
|
+
background: colors.primary,
|
|
150
|
+
foreground: colors.primaryForeground
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=DialogContent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":["_react","_interopRequireWildcard","require","_reactNative","_useTheme","_context","_jsxRuntime","e","t","WeakMap","r","n","__esModule","o","i","f","__proto__","default","has","get","set","hasOwnProperty","call","Object","defineProperty","getOwnPropertyDescriptor","DialogBody","titleId","descriptionId","title","description","actions","children","theme","useTheme","jsxs","Fragment","jsx","Text","nativeID","style","fontSize","fontWeight","color","colors","text","paddingBottom","lineHeight","textSecondary","length","ActionRow","View","width","gap","justifyContent","map","action","idx","ActionButton","label","close","useDialogContext","shouldCloseOnPress","background","foreground","getActionPalette","handlePress","useCallback","onPress","undefined","TouchableOpacity","borderRadius","alignItems","backgroundColor","opacity","disabled","paddingVertical","paddingHorizontal","activeOpacity","testID","negative","negativeForeground","contrast50","primary","primaryForeground","_exhaustive"],"sourceRoot":"../../../src","sources":["dialog/DialogContent.tsx"],"mappings":"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","ignoreList":[]}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
3
|
import React, { useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from 'react';
|
|
4
|
-
import { Pressable, StyleSheet,
|
|
4
|
+
import { Pressable, StyleSheet, useWindowDimensions, View } from 'react-native';
|
|
5
5
|
import Animated, { cancelAnimation, Easing, runOnJS, useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';
|
|
6
6
|
import { BottomSheet } from "../bottom-sheet/index.js";
|
|
7
7
|
import { Z_INDEX } from "../styles/z-index.js";
|
|
8
8
|
import { useTheme } from "../theme/use-theme.js";
|
|
9
|
-
import { Context,
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
9
|
+
import { Context, useDialogControl } from "./context.js";
|
|
10
|
+
import { DialogBody } from "./DialogContent.js";
|
|
11
|
+
import { DialogBottomSheet } from "./DialogBottomSheet.js";
|
|
12
|
+
import { ANIMATION_DURATION, DEFAULT_SIDE_WIDTH, DIALOG_SHEET_BACKDROP_TESTID, PANEL_RADIUS, SHEET_BACKDROP_OPACITY, SIDE_SHEET_MIN_GUTTER, useResolvedPlacement } from "./placement.js";
|
|
13
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
12
14
|
export { DIALOG_SHEET_BACKDROP_TESTID };
|
|
13
15
|
|
|
14
16
|
/**
|
|
@@ -33,6 +35,36 @@ export { DIALOG_SHEET_BACKDROP_TESTID };
|
|
|
33
35
|
* 3. Pure children — no `title`/`description`/`actions`.
|
|
34
36
|
*/
|
|
35
37
|
export function Dialog({
|
|
38
|
+
placement,
|
|
39
|
+
...rest
|
|
40
|
+
}) {
|
|
41
|
+
const resolvedPlacement = useResolvedPlacement(placement);
|
|
42
|
+
|
|
43
|
+
// `bottom` routes to the shared cross-platform `BottomSheet` surface — one
|
|
44
|
+
// code path with drag-to-dismiss on web and native. `center` (default) and
|
|
45
|
+
// the side-sheets keep their existing native lifecycle below. Each branch is
|
|
46
|
+
// its own component so the dispatcher only ever calls `useResolvedPlacement`,
|
|
47
|
+
// keeping the rules-of-hooks contract intact across a responsive placement
|
|
48
|
+
// change.
|
|
49
|
+
if (resolvedPlacement === 'bottom') {
|
|
50
|
+
return /*#__PURE__*/_jsx(DialogBottomSheet, {
|
|
51
|
+
...rest
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
return /*#__PURE__*/_jsx(CenteredOrSideDialog, {
|
|
55
|
+
...rest,
|
|
56
|
+
placement: resolvedPlacement
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Native `center` and `left`/`right` placements. `center` uses bloom's
|
|
62
|
+
* `BottomSheet` in `detached` mode (a floating, content-hugging card that
|
|
63
|
+
* degrades from sheet to centered card via the 500px cap); the side placements
|
|
64
|
+
* use a reanimated drawer. These share one open/close lifecycle. The `bottom`
|
|
65
|
+
* placement is handled separately by `DialogBottomSheet`.
|
|
66
|
+
*/
|
|
67
|
+
function CenteredOrSideDialog({
|
|
36
68
|
control,
|
|
37
69
|
open: controlledOpen,
|
|
38
70
|
onClose,
|
|
@@ -42,9 +74,7 @@ export function Dialog({
|
|
|
42
74
|
actions,
|
|
43
75
|
placement,
|
|
44
76
|
width = DEFAULT_SIDE_WIDTH,
|
|
45
|
-
maxHeightRatio = DEFAULT_MAX_HEIGHT_RATIO,
|
|
46
77
|
inset,
|
|
47
|
-
showHandle = true,
|
|
48
78
|
dismissOnBackdrop = true,
|
|
49
79
|
style,
|
|
50
80
|
panelStyle,
|
|
@@ -55,8 +85,7 @@ export function Dialog({
|
|
|
55
85
|
children
|
|
56
86
|
}) {
|
|
57
87
|
const isControlled = controlledOpen !== undefined;
|
|
58
|
-
const
|
|
59
|
-
const isSide = resolvedPlacement === 'left' || resolvedPlacement === 'right';
|
|
88
|
+
const isSide = placement === 'left' || placement === 'right';
|
|
60
89
|
|
|
61
90
|
// Imperative open state for the side placement (the BottomSheet path owns its
|
|
62
91
|
// own visibility via its ref instead).
|
|
@@ -165,7 +194,7 @@ export function Dialog({
|
|
|
165
194
|
children: /*#__PURE__*/_jsx(SideSheet, {
|
|
166
195
|
open: sideOpen,
|
|
167
196
|
onDismiss: handleDismiss,
|
|
168
|
-
side:
|
|
197
|
+
side: placement,
|
|
169
198
|
width: width,
|
|
170
199
|
inset: inset,
|
|
171
200
|
dismissOnBackdrop: dismissOnBackdrop,
|
|
@@ -184,18 +213,17 @@ export function Dialog({
|
|
|
184
213
|
})
|
|
185
214
|
});
|
|
186
215
|
}
|
|
187
|
-
const isBottom = resolvedPlacement === 'bottom';
|
|
188
216
|
return /*#__PURE__*/_jsx(BottomSheet, {
|
|
189
217
|
ref: ref,
|
|
190
218
|
onDismiss: handleDismiss,
|
|
191
219
|
enablePanDownToClose: true,
|
|
192
|
-
detached:
|
|
193
|
-
showHandle:
|
|
220
|
+
detached: true,
|
|
221
|
+
showHandle: true
|
|
194
222
|
// Stronger dim when a Dialog is stacked over another sheet so the
|
|
195
223
|
// underlying sheet's handle/content doesn't bleed through.
|
|
196
224
|
,
|
|
197
225
|
backdropOpacity: 0.7,
|
|
198
|
-
style:
|
|
226
|
+
style: sheetStyle,
|
|
199
227
|
children: /*#__PURE__*/_jsx(Context.Provider, {
|
|
200
228
|
value: context,
|
|
201
229
|
children: /*#__PURE__*/_jsx(View, {
|
|
@@ -222,54 +250,6 @@ export function Dialog({
|
|
|
222
250
|
})
|
|
223
251
|
});
|
|
224
252
|
}
|
|
225
|
-
function bottomSheetStyle(background, maxHeightRatio) {
|
|
226
|
-
return {
|
|
227
|
-
backgroundColor: background,
|
|
228
|
-
borderTopLeftRadius: PANEL_RADIUS + 4,
|
|
229
|
-
borderTopRightRadius: PANEL_RADIUS + 4,
|
|
230
|
-
maxHeight: `${Math.round(maxHeightRatio * 100)}%`
|
|
231
|
-
};
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
/**
|
|
235
|
-
* Renders the dialog's body: optional declarative title + description, any
|
|
236
|
-
* `children`, then the action row. Shared by all placements. The
|
|
237
|
-
* `titleId`/`descriptionId` are wired by the caller for accessibility.
|
|
238
|
-
*/
|
|
239
|
-
function DialogBody({
|
|
240
|
-
titleId,
|
|
241
|
-
descriptionId,
|
|
242
|
-
title,
|
|
243
|
-
description,
|
|
244
|
-
actions,
|
|
245
|
-
children
|
|
246
|
-
}) {
|
|
247
|
-
const theme = useTheme();
|
|
248
|
-
return /*#__PURE__*/_jsxs(_Fragment, {
|
|
249
|
-
children: [title ? /*#__PURE__*/_jsx(Text, {
|
|
250
|
-
nativeID: titleId,
|
|
251
|
-
style: {
|
|
252
|
-
fontSize: 22,
|
|
253
|
-
fontWeight: '600',
|
|
254
|
-
color: theme.colors.text,
|
|
255
|
-
paddingBottom: description ? 4 : 16,
|
|
256
|
-
lineHeight: 30
|
|
257
|
-
},
|
|
258
|
-
children: title
|
|
259
|
-
}) : null, description ? /*#__PURE__*/_jsx(Text, {
|
|
260
|
-
nativeID: descriptionId,
|
|
261
|
-
style: {
|
|
262
|
-
fontSize: 16,
|
|
263
|
-
color: theme.colors.textSecondary,
|
|
264
|
-
paddingBottom: 16,
|
|
265
|
-
lineHeight: 22
|
|
266
|
-
},
|
|
267
|
-
children: description
|
|
268
|
-
}) : null, children, actions && actions.length > 0 ? /*#__PURE__*/_jsx(ActionRow, {
|
|
269
|
-
actions: actions
|
|
270
|
-
}) : null]
|
|
271
|
-
});
|
|
272
|
-
}
|
|
273
253
|
|
|
274
254
|
/**
|
|
275
255
|
* Reanimated side-sheet/drawer for the `left`/`right` placements (native).
|
|
@@ -409,98 +389,6 @@ function SideSheet({
|
|
|
409
389
|
})]
|
|
410
390
|
});
|
|
411
391
|
}
|
|
412
|
-
function ActionRow({
|
|
413
|
-
actions
|
|
414
|
-
}) {
|
|
415
|
-
return /*#__PURE__*/_jsx(View, {
|
|
416
|
-
style: {
|
|
417
|
-
width: '100%',
|
|
418
|
-
gap: 8,
|
|
419
|
-
justifyContent: 'flex-end'
|
|
420
|
-
},
|
|
421
|
-
children: actions.map((action, idx) => /*#__PURE__*/_jsx(ActionButton, {
|
|
422
|
-
action: action
|
|
423
|
-
}, `${action.label}-${idx}`))
|
|
424
|
-
});
|
|
425
|
-
}
|
|
426
|
-
function ActionButton({
|
|
427
|
-
action
|
|
428
|
-
}) {
|
|
429
|
-
const {
|
|
430
|
-
close
|
|
431
|
-
} = useDialogContext();
|
|
432
|
-
const theme = useTheme();
|
|
433
|
-
const color = action.color ?? 'default';
|
|
434
|
-
const shouldCloseOnPress = action.shouldCloseOnPress ?? true;
|
|
435
|
-
const {
|
|
436
|
-
background,
|
|
437
|
-
foreground
|
|
438
|
-
} = getActionPalette(color, theme.colors);
|
|
439
|
-
const handlePress = useCallback(e => {
|
|
440
|
-
const onPress = action.onPress;
|
|
441
|
-
if (color === 'cancel') {
|
|
442
|
-
// Cancel always dismisses; consumer's onPress (rare) runs after.
|
|
443
|
-
close(onPress ? () => onPress(e) : undefined);
|
|
444
|
-
return;
|
|
445
|
-
}
|
|
446
|
-
if (shouldCloseOnPress) {
|
|
447
|
-
close(onPress ? () => onPress(e) : undefined);
|
|
448
|
-
} else {
|
|
449
|
-
onPress?.(e);
|
|
450
|
-
}
|
|
451
|
-
}, [action.onPress, close, color, shouldCloseOnPress]);
|
|
452
|
-
return /*#__PURE__*/_jsx(TouchableOpacity, {
|
|
453
|
-
style: {
|
|
454
|
-
borderRadius: 9999,
|
|
455
|
-
alignItems: 'center',
|
|
456
|
-
justifyContent: 'center',
|
|
457
|
-
backgroundColor: background,
|
|
458
|
-
opacity: action.disabled ? 0.5 : 1,
|
|
459
|
-
paddingVertical: 12,
|
|
460
|
-
paddingHorizontal: 24
|
|
461
|
-
},
|
|
462
|
-
onPress: handlePress,
|
|
463
|
-
disabled: action.disabled,
|
|
464
|
-
activeOpacity: 0.7,
|
|
465
|
-
testID: action.testID,
|
|
466
|
-
children: /*#__PURE__*/_jsx(Text, {
|
|
467
|
-
style: {
|
|
468
|
-
fontSize: 16,
|
|
469
|
-
fontWeight: '500',
|
|
470
|
-
color: foreground
|
|
471
|
-
},
|
|
472
|
-
children: action.label
|
|
473
|
-
})
|
|
474
|
-
});
|
|
475
|
-
}
|
|
476
|
-
function getActionPalette(color, colors) {
|
|
477
|
-
switch (color) {
|
|
478
|
-
case 'destructive':
|
|
479
|
-
return {
|
|
480
|
-
background: colors.negative,
|
|
481
|
-
foreground: colors.negativeForeground
|
|
482
|
-
};
|
|
483
|
-
case 'cancel':
|
|
484
|
-
return {
|
|
485
|
-
background: colors.contrast50,
|
|
486
|
-
foreground: colors.text
|
|
487
|
-
};
|
|
488
|
-
case 'default':
|
|
489
|
-
return {
|
|
490
|
-
background: colors.primary,
|
|
491
|
-
foreground: colors.primaryForeground
|
|
492
|
-
};
|
|
493
|
-
/* c8 ignore next 2 -- TS exhaustiveness check guards this branch */
|
|
494
|
-
default:
|
|
495
|
-
{
|
|
496
|
-
const _exhaustive = color;
|
|
497
|
-
return {
|
|
498
|
-
background: colors.primary,
|
|
499
|
-
foreground: colors.primaryForeground
|
|
500
|
-
};
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
}
|
|
504
392
|
const sideStyles = StyleSheet.create({
|
|
505
393
|
root: {
|
|
506
394
|
...StyleSheet.absoluteFill,
|