@tamagui/dialog 1.0.1-beta.99 → 1.0.1-rc.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/LICENSE +21 -0
- package/dist/cjs/Dialog.js +413 -297
- package/dist/cjs/Dialog.js.map +3 -3
- package/dist/cjs/index.js +1 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/Dialog.js +408 -299
- package/dist/esm/Dialog.js.map +3 -3
- package/dist/esm/index.js +0 -0
- package/dist/esm/index.js.map +1 -1
- package/dist/jsx/Dialog.js +256 -168
- package/dist/jsx/Dialog.js.map +3 -3
- package/dist/jsx/index.js +0 -0
- package/dist/jsx/index.js.map +1 -1
- package/package.json +32 -21
- package/src/Dialog.tsx +292 -159
- package/types/Dialog.d.ts +1009 -584
- package/types/index.d.ts +0 -0
- package/types/Dialog.d.ts.map +0 -1
- package/types/index.d.ts.map +0 -1
package/dist/esm/Dialog.js
CHANGED
|
@@ -1,56 +1,29 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
4
|
-
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
7
|
-
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
8
|
-
var __spreadValues = (a, b) => {
|
|
9
|
-
for (var prop in b || (b = {}))
|
|
10
|
-
if (__hasOwnProp.call(b, prop))
|
|
11
|
-
__defNormalProp(a, prop, b[prop]);
|
|
12
|
-
if (__getOwnPropSymbols)
|
|
13
|
-
for (var prop of __getOwnPropSymbols(b)) {
|
|
14
|
-
if (__propIsEnum.call(b, prop))
|
|
15
|
-
__defNormalProp(a, prop, b[prop]);
|
|
16
|
-
}
|
|
17
|
-
return a;
|
|
18
|
-
};
|
|
19
|
-
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
20
|
-
var __objRest = (source, exclude) => {
|
|
21
|
-
var target = {};
|
|
22
|
-
for (var prop in source)
|
|
23
|
-
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
24
|
-
target[prop] = source[prop];
|
|
25
|
-
if (source != null && __getOwnPropSymbols)
|
|
26
|
-
for (var prop of __getOwnPropSymbols(source)) {
|
|
27
|
-
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
28
|
-
target[prop] = source[prop];
|
|
29
|
-
}
|
|
30
|
-
return target;
|
|
31
|
-
};
|
|
1
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Adapt, useAdaptParent } from "@tamagui/adapt";
|
|
32
3
|
import { AnimatePresence } from "@tamagui/animate-presence";
|
|
4
|
+
import { hideOthers } from "@tamagui/aria-hidden";
|
|
33
5
|
import { useComposedRefs } from "@tamagui/compose-refs";
|
|
34
6
|
import {
|
|
35
|
-
Slot,
|
|
36
7
|
Theme,
|
|
37
8
|
composeEventHandlers,
|
|
38
9
|
isWeb,
|
|
39
10
|
styled,
|
|
11
|
+
useGet,
|
|
40
12
|
useId,
|
|
13
|
+
useMedia,
|
|
41
14
|
useThemeName,
|
|
42
15
|
withStaticProperties
|
|
43
16
|
} from "@tamagui/core";
|
|
44
17
|
import { createContext, createContextScope } from "@tamagui/create-context";
|
|
45
18
|
import { Dismissable } from "@tamagui/dismissable";
|
|
46
19
|
import { FocusScope } from "@tamagui/focus-scope";
|
|
47
|
-
import {
|
|
20
|
+
import { PortalHost, PortalItem } from "@tamagui/portal";
|
|
21
|
+
import { RemoveScroll } from "@tamagui/remove-scroll";
|
|
22
|
+
import { ControlledSheet, SheetController } from "@tamagui/sheet";
|
|
48
23
|
import { ThemeableStack, YStack } from "@tamagui/stacks";
|
|
49
24
|
import { H2, Paragraph } from "@tamagui/text";
|
|
50
25
|
import { useControllableState } from "@tamagui/use-controllable-state";
|
|
51
|
-
import { hideOthers } from "aria-hidden";
|
|
52
26
|
import * as React from "react";
|
|
53
|
-
import { RemoveScroll } from "react-remove-scroll";
|
|
54
27
|
const DIALOG_NAME = "Dialog";
|
|
55
28
|
const [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);
|
|
56
29
|
const [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);
|
|
@@ -58,96 +31,112 @@ const TRIGGER_NAME = "DialogTrigger";
|
|
|
58
31
|
const DialogTriggerFrame = styled(YStack, {
|
|
59
32
|
name: TRIGGER_NAME
|
|
60
33
|
});
|
|
61
|
-
const DialogTrigger = React.forwardRef(
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
});
|
|
34
|
+
const DialogTrigger = React.forwardRef(
|
|
35
|
+
(props, forwardedRef) => {
|
|
36
|
+
const { __scopeDialog, ...triggerProps } = props;
|
|
37
|
+
const context = useDialogContext(TRIGGER_NAME, __scopeDialog);
|
|
38
|
+
const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);
|
|
39
|
+
return /* @__PURE__ */ jsx(DialogTriggerFrame, {
|
|
40
|
+
tag: "button",
|
|
41
|
+
"aria-haspopup": "dialog",
|
|
42
|
+
"aria-expanded": context.open,
|
|
43
|
+
"aria-controls": context.contentId,
|
|
44
|
+
"data-state": getState(context.open),
|
|
45
|
+
...triggerProps,
|
|
46
|
+
ref: composedTriggerRef,
|
|
47
|
+
onPress: composeEventHandlers(props.onPress, context.onOpenToggle)
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
);
|
|
76
51
|
DialogTrigger.displayName = TRIGGER_NAME;
|
|
77
52
|
const PORTAL_NAME = "DialogPortal";
|
|
78
53
|
const [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {
|
|
79
54
|
forceMount: void 0
|
|
80
55
|
});
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
return contents;
|
|
56
|
+
const DialogPortalFrame = styled(YStack, {
|
|
57
|
+
alignItems: "center",
|
|
58
|
+
justifyContent: "center",
|
|
59
|
+
fullscreen: true,
|
|
60
|
+
zIndex: 100,
|
|
61
|
+
...isWeb && {
|
|
62
|
+
maxHeight: "100vh"
|
|
89
63
|
}
|
|
90
|
-
|
|
91
|
-
|
|
64
|
+
});
|
|
65
|
+
const DialogPortal = DialogPortalFrame.extractable(
|
|
66
|
+
(props) => {
|
|
67
|
+
const { __scopeDialog, forceMount, children, ...frameProps } = props;
|
|
68
|
+
const themeName = useThemeName();
|
|
69
|
+
const context = useDialogContext(PORTAL_NAME, __scopeDialog);
|
|
70
|
+
const isShowing = forceMount || context.open;
|
|
71
|
+
const contents = /* @__PURE__ */ jsx(AnimatePresence, {
|
|
72
|
+
children: isShowing ? children : null
|
|
73
|
+
});
|
|
74
|
+
const isSheet = useShowDialogSheet(context);
|
|
75
|
+
if (!context.modal || isSheet) {
|
|
76
|
+
return contents;
|
|
77
|
+
}
|
|
78
|
+
return /* @__PURE__ */ jsx(PortalItem, {
|
|
79
|
+
name: `${context.scopeKey}SheetContents`,
|
|
80
|
+
children: /* @__PURE__ */ jsx(DialogProvider, {
|
|
81
|
+
scope: __scopeDialog,
|
|
82
|
+
...context,
|
|
83
|
+
children: /* @__PURE__ */ jsx(Theme, {
|
|
84
|
+
name: themeName,
|
|
85
|
+
children: /* @__PURE__ */ jsx(PortalProvider, {
|
|
86
|
+
scope: __scopeDialog,
|
|
87
|
+
forceMount,
|
|
88
|
+
children: /* @__PURE__ */ jsx(DialogPortalFrame, {
|
|
89
|
+
pointerEvents: isShowing ? "auto" : "none",
|
|
90
|
+
...frameProps,
|
|
91
|
+
children: contents
|
|
92
|
+
})
|
|
93
|
+
})
|
|
94
|
+
})
|
|
95
|
+
})
|
|
96
|
+
});
|
|
92
97
|
}
|
|
93
|
-
|
|
94
|
-
scope: __scopeDialog,
|
|
95
|
-
forceMount
|
|
96
|
-
}, /* @__PURE__ */ React.createElement(Portal, __spreadValues(__spreadValues({
|
|
97
|
-
alignItems: "center",
|
|
98
|
-
justifyContent: "center",
|
|
99
|
-
zIndex: 100,
|
|
100
|
-
pointerEvents: isShowing ? "auto" : "none"
|
|
101
|
-
}, isWeb && {
|
|
102
|
-
maxHeight: "100vh"
|
|
103
|
-
}), rest), /* @__PURE__ */ React.createElement(Theme, {
|
|
104
|
-
name: themeName
|
|
105
|
-
}, contents)));
|
|
106
|
-
};
|
|
98
|
+
);
|
|
107
99
|
DialogPortal.displayName = PORTAL_NAME;
|
|
108
100
|
const OVERLAY_NAME = "DialogOverlay";
|
|
109
101
|
const DialogOverlayFrame = styled(ThemeableStack, {
|
|
110
102
|
name: OVERLAY_NAME,
|
|
111
|
-
pointerEvents: "auto",
|
|
112
103
|
backgrounded: true,
|
|
113
104
|
fullscreen: true
|
|
114
105
|
});
|
|
115
|
-
const DialogOverlay = React.forwardRef(
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
106
|
+
const DialogOverlay = React.forwardRef(
|
|
107
|
+
({ __scopeDialog, ...props }, forwardedRef) => {
|
|
108
|
+
const portalContext = usePortalContext(OVERLAY_NAME, __scopeDialog);
|
|
109
|
+
const { forceMount = portalContext.forceMount, ...overlayProps } = props;
|
|
110
|
+
const context = useDialogContext(OVERLAY_NAME, __scopeDialog);
|
|
111
|
+
const showSheet = useShowDialogSheet(context);
|
|
112
|
+
if (!forceMount) {
|
|
113
|
+
if (!context.modal || showSheet) {
|
|
114
|
+
return null;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
return /* @__PURE__ */ jsx(DialogOverlayImpl, {
|
|
118
|
+
context,
|
|
119
|
+
...overlayProps,
|
|
120
|
+
ref: forwardedRef
|
|
121
|
+
});
|
|
122
122
|
}
|
|
123
|
-
|
|
124
|
-
ref: forwardedRef
|
|
125
|
-
}));
|
|
126
|
-
});
|
|
123
|
+
);
|
|
127
124
|
DialogOverlay.displayName = OVERLAY_NAME;
|
|
128
|
-
const DialogOverlayImpl = React.forwardRef(
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
if (!isWeb) {
|
|
138
|
-
return content;
|
|
125
|
+
const DialogOverlayImpl = React.forwardRef(
|
|
126
|
+
(props, forwardedRef) => {
|
|
127
|
+
const { context, ...overlayProps } = props;
|
|
128
|
+
return /* @__PURE__ */ jsx(DialogOverlayFrame, {
|
|
129
|
+
"data-state": getState(context.open),
|
|
130
|
+
pointerEvents: context.open ? "auto" : "none",
|
|
131
|
+
...overlayProps,
|
|
132
|
+
ref: forwardedRef
|
|
133
|
+
});
|
|
139
134
|
}
|
|
140
|
-
|
|
141
|
-
as: Slot,
|
|
142
|
-
allowPinchZoom: context.allowPinchZoom,
|
|
143
|
-
shards: [context.contentRef]
|
|
144
|
-
}, content);
|
|
145
|
-
});
|
|
135
|
+
);
|
|
146
136
|
const CONTENT_NAME = "DialogContent";
|
|
147
137
|
const DialogContentFrame = styled(ThemeableStack, {
|
|
148
138
|
name: CONTENT_NAME,
|
|
149
139
|
tag: "dialog",
|
|
150
|
-
pointerEvents: "auto",
|
|
151
140
|
position: "relative",
|
|
152
141
|
backgrounded: true,
|
|
153
142
|
padded: true,
|
|
@@ -164,216 +153,289 @@ const DialogContentFrame = styled(ThemeableStack, {
|
|
|
164
153
|
size: "$4"
|
|
165
154
|
}
|
|
166
155
|
});
|
|
167
|
-
const DialogContent =
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
})
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
React.useEffect(() => {
|
|
185
|
-
if (!context.open)
|
|
186
|
-
return;
|
|
187
|
-
const content = contentRef.current;
|
|
188
|
-
if (content)
|
|
189
|
-
return hideOthers(content);
|
|
190
|
-
}, [context.open]);
|
|
191
|
-
return /* @__PURE__ */ React.createElement(DialogContentImpl, __spreadProps(__spreadValues({}, props), {
|
|
192
|
-
ref: composedRefs,
|
|
193
|
-
trapFocus: context.open,
|
|
194
|
-
disableOutsidePointerEvents: true,
|
|
195
|
-
onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {
|
|
196
|
-
var _a;
|
|
197
|
-
event.preventDefault();
|
|
198
|
-
(_a = context.triggerRef.current) == null ? void 0 : _a.focus();
|
|
199
|
-
}),
|
|
200
|
-
onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {
|
|
201
|
-
const originalEvent = event["detail"].originalEvent;
|
|
202
|
-
const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
|
|
203
|
-
const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
|
|
204
|
-
if (isRightClick)
|
|
205
|
-
event.preventDefault();
|
|
206
|
-
}),
|
|
207
|
-
onFocusOutside: composeEventHandlers(props.onFocusOutside, (event) => event.preventDefault())
|
|
208
|
-
}));
|
|
209
|
-
});
|
|
210
|
-
const DialogContentNonModal = React.forwardRef((props, forwardedRef) => {
|
|
211
|
-
const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);
|
|
212
|
-
const hasInteractedOutsideRef = React.useRef(false);
|
|
213
|
-
return /* @__PURE__ */ React.createElement(DialogContentImpl, __spreadProps(__spreadValues({}, props), {
|
|
214
|
-
ref: forwardedRef,
|
|
215
|
-
trapFocus: false,
|
|
216
|
-
disableOutsidePointerEvents: false,
|
|
217
|
-
onCloseAutoFocus: (event) => {
|
|
218
|
-
var _a, _b;
|
|
219
|
-
(_a = props.onCloseAutoFocus) == null ? void 0 : _a.call(props, event);
|
|
220
|
-
if (!event.defaultPrevented) {
|
|
221
|
-
if (!hasInteractedOutsideRef.current)
|
|
222
|
-
(_b = context.triggerRef.current) == null ? void 0 : _b.focus();
|
|
223
|
-
event.preventDefault();
|
|
156
|
+
const DialogContent = DialogContentFrame.extractable(
|
|
157
|
+
React.forwardRef(
|
|
158
|
+
({ __scopeDialog, ...props }, forwardedRef) => {
|
|
159
|
+
const portalContext = usePortalContext(CONTENT_NAME, __scopeDialog);
|
|
160
|
+
const { forceMount = portalContext.forceMount, ...contentProps } = props;
|
|
161
|
+
const context = useDialogContext(CONTENT_NAME, __scopeDialog);
|
|
162
|
+
const contents = context.modal ? /* @__PURE__ */ jsx(DialogContentModal, {
|
|
163
|
+
context,
|
|
164
|
+
...contentProps,
|
|
165
|
+
ref: forwardedRef
|
|
166
|
+
}) : /* @__PURE__ */ jsx(DialogContentNonModal, {
|
|
167
|
+
context,
|
|
168
|
+
...contentProps,
|
|
169
|
+
ref: forwardedRef
|
|
170
|
+
});
|
|
171
|
+
if (!isWeb) {
|
|
172
|
+
return contents;
|
|
224
173
|
}
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
174
|
+
return /* @__PURE__ */ jsx(RemoveScroll, {
|
|
175
|
+
forwardProps: true,
|
|
176
|
+
enabled: context.open,
|
|
177
|
+
allowPinchZoom: context.allowPinchZoom,
|
|
178
|
+
shards: [context.contentRef],
|
|
179
|
+
removeScrollBar: false,
|
|
180
|
+
children: /* @__PURE__ */ jsx("div", {
|
|
181
|
+
className: "_dsp_contents",
|
|
182
|
+
children: contents
|
|
183
|
+
})
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
DialogContent.displayName = CONTENT_NAME;
|
|
189
|
+
const DialogContentModal = React.forwardRef(
|
|
190
|
+
({ children, context, ...props }, forwardedRef) => {
|
|
191
|
+
const contentRef = React.useRef(null);
|
|
192
|
+
const composedRefs = useComposedRefs(forwardedRef, context.contentRef, contentRef);
|
|
193
|
+
React.useEffect(() => {
|
|
194
|
+
if (!context.open)
|
|
235
195
|
return;
|
|
236
|
-
const
|
|
237
|
-
if (
|
|
196
|
+
const content = contentRef.current;
|
|
197
|
+
if (content)
|
|
198
|
+
return hideOthers(content);
|
|
199
|
+
}, [context.open]);
|
|
200
|
+
return /* @__PURE__ */ jsx(DialogContentImpl, {
|
|
201
|
+
...props,
|
|
202
|
+
context,
|
|
203
|
+
ref: composedRefs,
|
|
204
|
+
trapFocus: context.open,
|
|
205
|
+
disableOutsidePointerEvents: true,
|
|
206
|
+
onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {
|
|
207
|
+
var _a;
|
|
238
208
|
event.preventDefault();
|
|
209
|
+
(_a = context.triggerRef.current) == null ? void 0 : _a.focus();
|
|
210
|
+
}),
|
|
211
|
+
onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {
|
|
212
|
+
const originalEvent = event["detail"].originalEvent;
|
|
213
|
+
const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
|
|
214
|
+
const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
|
|
215
|
+
if (isRightClick)
|
|
216
|
+
event.preventDefault();
|
|
217
|
+
}),
|
|
218
|
+
onFocusOutside: composeEventHandlers(
|
|
219
|
+
props.onFocusOutside,
|
|
220
|
+
(event) => event.preventDefault()
|
|
221
|
+
),
|
|
222
|
+
children
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
);
|
|
226
|
+
const DialogContentNonModal = React.forwardRef(
|
|
227
|
+
(props, forwardedRef) => {
|
|
228
|
+
const hasInteractedOutsideRef = React.useRef(false);
|
|
229
|
+
return /* @__PURE__ */ jsx(DialogContentImpl, {
|
|
230
|
+
...props,
|
|
231
|
+
ref: forwardedRef,
|
|
232
|
+
trapFocus: false,
|
|
233
|
+
disableOutsidePointerEvents: false,
|
|
234
|
+
onCloseAutoFocus: (event) => {
|
|
235
|
+
var _a, _b;
|
|
236
|
+
(_a = props.onCloseAutoFocus) == null ? void 0 : _a.call(props, event);
|
|
237
|
+
if (!event.defaultPrevented) {
|
|
238
|
+
if (!hasInteractedOutsideRef.current) {
|
|
239
|
+
(_b = props.context.triggerRef.current) == null ? void 0 : _b.focus();
|
|
240
|
+
}
|
|
241
|
+
event.preventDefault();
|
|
242
|
+
}
|
|
243
|
+
hasInteractedOutsideRef.current = false;
|
|
244
|
+
},
|
|
245
|
+
onInteractOutside: (event) => {
|
|
246
|
+
var _a;
|
|
247
|
+
(_a = props.onInteractOutside) == null ? void 0 : _a.call(props, event);
|
|
248
|
+
if (!event.defaultPrevented)
|
|
249
|
+
hasInteractedOutsideRef.current = true;
|
|
250
|
+
const target = event.target;
|
|
251
|
+
const trigger = props.context.triggerRef.current;
|
|
252
|
+
if (!(trigger instanceof HTMLElement))
|
|
253
|
+
return;
|
|
254
|
+
const targetIsTrigger = trigger.contains(target);
|
|
255
|
+
if (targetIsTrigger)
|
|
256
|
+
event.preventDefault();
|
|
257
|
+
}
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
);
|
|
261
|
+
const DialogContentImpl = React.forwardRef(
|
|
262
|
+
(props, forwardedRef) => {
|
|
263
|
+
const {
|
|
264
|
+
__scopeDialog,
|
|
265
|
+
trapFocus,
|
|
266
|
+
onOpenAutoFocus,
|
|
267
|
+
onCloseAutoFocus,
|
|
268
|
+
disableOutsidePointerEvents,
|
|
269
|
+
onEscapeKeyDown,
|
|
270
|
+
onPointerDownOutside,
|
|
271
|
+
onFocusOutside,
|
|
272
|
+
onInteractOutside,
|
|
273
|
+
context,
|
|
274
|
+
...contentProps
|
|
275
|
+
} = props;
|
|
276
|
+
const contentRef = React.useRef(null);
|
|
277
|
+
const composedRefs = useComposedRefs(forwardedRef, contentRef);
|
|
278
|
+
const showSheet = useShowDialogSheet(context);
|
|
279
|
+
const contents = /* @__PURE__ */ jsx(DialogContentFrame, {
|
|
280
|
+
id: context.contentId,
|
|
281
|
+
"aria-describedby": context.descriptionId,
|
|
282
|
+
"aria-labelledby": context.titleId,
|
|
283
|
+
"data-state": getState(context.open),
|
|
284
|
+
...contentProps
|
|
285
|
+
});
|
|
286
|
+
if (showSheet) {
|
|
287
|
+
return /* @__PURE__ */ jsx(PortalItem, {
|
|
288
|
+
hostName: `${context.scopeKey}SheetContents`,
|
|
289
|
+
children: contentProps.children
|
|
290
|
+
});
|
|
239
291
|
}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
titleId: context.titleId
|
|
287
|
-
}), /* @__PURE__ */ React.createElement(DescriptionWarning, {
|
|
288
|
-
contentRef,
|
|
289
|
-
descriptionId: context.descriptionId
|
|
290
|
-
})));
|
|
291
|
-
});
|
|
292
|
+
if (!isWeb) {
|
|
293
|
+
return contents;
|
|
294
|
+
}
|
|
295
|
+
return /* @__PURE__ */ jsxs(Fragment, {
|
|
296
|
+
children: [
|
|
297
|
+
/* @__PURE__ */ jsx(FocusScope, {
|
|
298
|
+
loop: true,
|
|
299
|
+
trapped: trapFocus,
|
|
300
|
+
onMountAutoFocus: onOpenAutoFocus,
|
|
301
|
+
forceUnmount: !context.open,
|
|
302
|
+
onUnmountAutoFocus: onCloseAutoFocus,
|
|
303
|
+
children: /* @__PURE__ */ jsx(Dismissable, {
|
|
304
|
+
disableOutsidePointerEvents: context.open && disableOutsidePointerEvents,
|
|
305
|
+
forceUnmount: !context.open,
|
|
306
|
+
onEscapeKeyDown,
|
|
307
|
+
onPointerDownOutside,
|
|
308
|
+
onFocusOutside,
|
|
309
|
+
onInteractOutside,
|
|
310
|
+
ref: composedRefs,
|
|
311
|
+
onDismiss: () => context.onOpenChange(false),
|
|
312
|
+
children: contents
|
|
313
|
+
})
|
|
314
|
+
}),
|
|
315
|
+
process.env.NODE_ENV === "development" && /* @__PURE__ */ jsxs(Fragment, {
|
|
316
|
+
children: [
|
|
317
|
+
/* @__PURE__ */ jsx(TitleWarning, {
|
|
318
|
+
titleId: context.titleId
|
|
319
|
+
}),
|
|
320
|
+
/* @__PURE__ */ jsx(DescriptionWarning, {
|
|
321
|
+
contentRef,
|
|
322
|
+
descriptionId: context.descriptionId
|
|
323
|
+
})
|
|
324
|
+
]
|
|
325
|
+
})
|
|
326
|
+
]
|
|
327
|
+
});
|
|
328
|
+
}
|
|
329
|
+
);
|
|
330
|
+
const SHEET_CONTENTS_NAME = "DialogSheetContents";
|
|
331
|
+
const DialogSheetContents = ({ __scopeDialog }) => {
|
|
332
|
+
const context = useDialogContext(SHEET_CONTENTS_NAME, __scopeDialog);
|
|
333
|
+
return /* @__PURE__ */ jsx(PortalHost, {
|
|
334
|
+
name: `${context.scopeKey}SheetContents`
|
|
335
|
+
});
|
|
336
|
+
};
|
|
337
|
+
DialogSheetContents.displayName = SHEET_CONTENTS_NAME;
|
|
292
338
|
const TITLE_NAME = "DialogTitle";
|
|
293
339
|
const DialogTitleFrame = styled(H2, {
|
|
294
340
|
name: TITLE_NAME
|
|
295
341
|
});
|
|
296
|
-
const DialogTitle = React.forwardRef(
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
});
|
|
342
|
+
const DialogTitle = React.forwardRef(
|
|
343
|
+
(props, forwardedRef) => {
|
|
344
|
+
const { __scopeDialog, ...titleProps } = props;
|
|
345
|
+
const context = useDialogContext(TITLE_NAME, __scopeDialog);
|
|
346
|
+
return /* @__PURE__ */ jsx(DialogTitleFrame, {
|
|
347
|
+
id: context.titleId,
|
|
348
|
+
...titleProps,
|
|
349
|
+
ref: forwardedRef
|
|
350
|
+
});
|
|
351
|
+
}
|
|
352
|
+
);
|
|
305
353
|
DialogTitle.displayName = TITLE_NAME;
|
|
306
354
|
const DialogDescriptionFrame = styled(Paragraph, {
|
|
307
355
|
name: "DialogDescription"
|
|
308
356
|
});
|
|
309
357
|
const DESCRIPTION_NAME = "DialogDescription";
|
|
310
|
-
const DialogDescription = React.forwardRef(
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
});
|
|
358
|
+
const DialogDescription = React.forwardRef(
|
|
359
|
+
(props, forwardedRef) => {
|
|
360
|
+
const { __scopeDialog, ...descriptionProps } = props;
|
|
361
|
+
const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);
|
|
362
|
+
return /* @__PURE__ */ jsx(DialogDescriptionFrame, {
|
|
363
|
+
id: context.descriptionId,
|
|
364
|
+
...descriptionProps,
|
|
365
|
+
ref: forwardedRef
|
|
366
|
+
});
|
|
367
|
+
}
|
|
368
|
+
);
|
|
319
369
|
DialogDescription.displayName = DESCRIPTION_NAME;
|
|
320
370
|
const CLOSE_NAME = "DialogClose";
|
|
321
|
-
const DialogClose = React.forwardRef(
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
371
|
+
const DialogClose = React.forwardRef(
|
|
372
|
+
(props, forwardedRef) => {
|
|
373
|
+
const { __scopeDialog, ...closeProps } = props;
|
|
374
|
+
const context = useDialogContext(CLOSE_NAME, __scopeDialog);
|
|
375
|
+
const isSheet = useShowDialogSheet(context);
|
|
376
|
+
if (isSheet) {
|
|
377
|
+
return null;
|
|
378
|
+
}
|
|
379
|
+
return /* @__PURE__ */ jsx(YStack, {
|
|
380
|
+
tag: "button",
|
|
381
|
+
...closeProps,
|
|
382
|
+
ref: forwardedRef,
|
|
383
|
+
onPress: composeEventHandlers(props.onPress, () => context.onOpenChange(false))
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
);
|
|
331
387
|
DialogClose.displayName = CLOSE_NAME;
|
|
332
388
|
function getState(open) {
|
|
333
389
|
return open ? "open" : "closed";
|
|
334
390
|
}
|
|
335
391
|
const TITLE_WARNING_NAME = "DialogTitleWarning";
|
|
336
|
-
const [
|
|
392
|
+
const [DialogWarningProvider, useWarningContext] = createContext(TITLE_WARNING_NAME, {
|
|
337
393
|
contentName: CONTENT_NAME,
|
|
338
394
|
titleName: TITLE_NAME,
|
|
339
395
|
docsSlug: "dialog"
|
|
340
396
|
});
|
|
341
397
|
const TitleWarning = ({ titleId }) => {
|
|
342
|
-
|
|
343
|
-
|
|
398
|
+
if (process.env.NODE_ENV === "development") {
|
|
399
|
+
const titleWarningContext = useWarningContext(TITLE_WARNING_NAME);
|
|
400
|
+
const MESSAGE = `\`${titleWarningContext.contentName}\` requires a \`${titleWarningContext.titleName}\` for the component to be accessible for screen reader users.
|
|
344
401
|
|
|
345
402
|
If you want to hide the \`${titleWarningContext.titleName}\`, you can wrap it with our VisuallyHidden component.
|
|
346
403
|
|
|
347
404
|
For more information, see https://radix-ui.com/primitives/docs/components/${titleWarningContext.docsSlug}`;
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
405
|
+
React.useEffect(() => {
|
|
406
|
+
if (!isWeb)
|
|
407
|
+
return;
|
|
408
|
+
if (titleId) {
|
|
409
|
+
const hasTitle = document.getElementById(titleId);
|
|
410
|
+
if (!hasTitle) {
|
|
411
|
+
console.warn(MESSAGE);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
}, [MESSAGE, titleId]);
|
|
415
|
+
}
|
|
357
416
|
return null;
|
|
358
417
|
};
|
|
359
418
|
const DESCRIPTION_WARNING_NAME = "DialogDescriptionWarning";
|
|
360
419
|
const DescriptionWarning = ({ contentRef, descriptionId }) => {
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
420
|
+
if (process.env.NODE_ENV === "development") {
|
|
421
|
+
const descriptionWarningContext = useWarningContext(DESCRIPTION_WARNING_NAME);
|
|
422
|
+
const MESSAGE = `Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${descriptionWarningContext.contentName}}.`;
|
|
423
|
+
React.useEffect(() => {
|
|
424
|
+
if (!isWeb)
|
|
425
|
+
return;
|
|
426
|
+
const contentNode = contentRef.current;
|
|
427
|
+
if (!(contentNode instanceof HTMLElement)) {
|
|
428
|
+
return;
|
|
429
|
+
}
|
|
430
|
+
const describedById = contentNode.getAttribute("aria-describedby");
|
|
431
|
+
if (descriptionId && describedById) {
|
|
432
|
+
const hasDescription = document.getElementById(descriptionId);
|
|
433
|
+
if (!hasDescription) {
|
|
434
|
+
console.warn(MESSAGE);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}, [MESSAGE, contentRef, descriptionId]);
|
|
438
|
+
}
|
|
377
439
|
return null;
|
|
378
440
|
};
|
|
379
441
|
const DialogInner = React.forwardRef(function Dialog(props, ref) {
|
|
@@ -386,6 +448,10 @@ const DialogInner = React.forwardRef(function Dialog(props, ref) {
|
|
|
386
448
|
modal = true,
|
|
387
449
|
allowPinchZoom = false
|
|
388
450
|
} = props;
|
|
451
|
+
const { when, AdaptProvider } = useAdaptParent({
|
|
452
|
+
Contents: DialogSheetContents
|
|
453
|
+
});
|
|
454
|
+
const sheetBreakpoint = when || false;
|
|
389
455
|
const triggerRef = React.useRef(null);
|
|
390
456
|
const contentRef = React.useRef(null);
|
|
391
457
|
const [open, setOpen] = useControllableState({
|
|
@@ -393,22 +459,37 @@ const DialogInner = React.forwardRef(function Dialog(props, ref) {
|
|
|
393
459
|
defaultProp: defaultOpen,
|
|
394
460
|
onChange: onOpenChange
|
|
395
461
|
});
|
|
396
|
-
React.useImperativeHandle(
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
462
|
+
React.useImperativeHandle(
|
|
463
|
+
ref,
|
|
464
|
+
() => ({
|
|
465
|
+
open: setOpen
|
|
466
|
+
}),
|
|
467
|
+
[setOpen]
|
|
468
|
+
);
|
|
469
|
+
const scopeId = useId();
|
|
470
|
+
const scopeKey = __scopeDialog ? Object.keys(__scopeDialog)[0] : scopeId;
|
|
471
|
+
return /* @__PURE__ */ jsx(AdaptProvider, {
|
|
472
|
+
children: /* @__PURE__ */ jsx(DialogProvider, {
|
|
473
|
+
scope: __scopeDialog,
|
|
474
|
+
scopeKey,
|
|
475
|
+
triggerRef,
|
|
476
|
+
contentRef,
|
|
477
|
+
contentId: useId() || "",
|
|
478
|
+
titleId: useId() || "",
|
|
479
|
+
descriptionId: useId() || "",
|
|
480
|
+
open,
|
|
481
|
+
onOpenChange: setOpen,
|
|
482
|
+
onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),
|
|
483
|
+
modal,
|
|
484
|
+
allowPinchZoom,
|
|
485
|
+
sheetBreakpoint,
|
|
486
|
+
children: /* @__PURE__ */ jsx(DialogSheetController, {
|
|
487
|
+
onOpenChange: setOpen,
|
|
488
|
+
__scopeDialog,
|
|
489
|
+
children
|
|
490
|
+
})
|
|
491
|
+
})
|
|
492
|
+
});
|
|
412
493
|
});
|
|
413
494
|
const Dialog2 = withStaticProperties(DialogInner, {
|
|
414
495
|
Trigger: DialogTrigger,
|
|
@@ -417,8 +498,34 @@ const Dialog2 = withStaticProperties(DialogInner, {
|
|
|
417
498
|
Content: DialogContent,
|
|
418
499
|
Title: DialogTitle,
|
|
419
500
|
Description: DialogDescription,
|
|
420
|
-
Close: DialogClose
|
|
501
|
+
Close: DialogClose,
|
|
502
|
+
Sheet: ControlledSheet,
|
|
503
|
+
Adapt
|
|
421
504
|
});
|
|
505
|
+
const DialogSheetController = (props) => {
|
|
506
|
+
const context = useDialogContext("DialogSheetController", props.__scopeDialog);
|
|
507
|
+
const showSheet = useShowDialogSheet(context);
|
|
508
|
+
const breakpointActive = useSheetBreakpointActive(context);
|
|
509
|
+
const getShowSheet = useGet(showSheet);
|
|
510
|
+
return /* @__PURE__ */ jsx(SheetController, {
|
|
511
|
+
onOpenChange: (val) => {
|
|
512
|
+
if (getShowSheet()) {
|
|
513
|
+
props.onOpenChange(val);
|
|
514
|
+
}
|
|
515
|
+
},
|
|
516
|
+
open: context.open,
|
|
517
|
+
hidden: breakpointActive === false,
|
|
518
|
+
children: props.children
|
|
519
|
+
});
|
|
520
|
+
};
|
|
521
|
+
const useSheetBreakpointActive = (context) => {
|
|
522
|
+
const media = useMedia();
|
|
523
|
+
return context.sheetBreakpoint ? media[context.sheetBreakpoint] : false;
|
|
524
|
+
};
|
|
525
|
+
const useShowDialogSheet = (context) => {
|
|
526
|
+
const breakpointActive = useSheetBreakpointActive(context);
|
|
527
|
+
return context.open === false ? false : breakpointActive;
|
|
528
|
+
};
|
|
422
529
|
export {
|
|
423
530
|
Dialog2 as Dialog,
|
|
424
531
|
DialogClose,
|
|
@@ -426,9 +533,11 @@ export {
|
|
|
426
533
|
DialogDescription,
|
|
427
534
|
DialogOverlay,
|
|
428
535
|
DialogPortal,
|
|
536
|
+
DialogPortalFrame,
|
|
537
|
+
DialogSheetContents,
|
|
429
538
|
DialogTitle,
|
|
430
539
|
DialogTrigger,
|
|
431
|
-
|
|
540
|
+
DialogWarningProvider,
|
|
432
541
|
createDialogScope
|
|
433
542
|
};
|
|
434
543
|
//# sourceMappingURL=Dialog.js.map
|