@tamagui/dialog 2.7.7 → 3.0.0-beta.643.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.
@@ -1,3 +1,4 @@
1
+
1
2
  var __create = Object.create;
2
3
  var __defProp = Object.defineProperty;
3
4
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
@@ -5,48 +6,41 @@ var __getOwnPropNames = Object.getOwnPropertyNames;
5
6
  var __getProtoOf = Object.getPrototypeOf;
6
7
  var __hasOwnProp = Object.prototype.hasOwnProperty;
7
8
  var __export = (target, all) => {
8
- for (var name in all) __defProp(target, name, {
9
- get: all[name],
10
- enumerable: true
11
- });
9
+ for (var name in all) __defProp(target, name, {
10
+ get: all[name],
11
+ enumerable: true
12
+ });
12
13
  };
13
14
  var __copyProps = (to, from, except, desc) => {
14
- if (from && typeof from === "object" || typeof from === "function") {
15
- for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
16
- get: () => from[key],
17
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
18
- });
19
- }
20
- return to;
15
+ if (from && typeof from === "object" || typeof from === "function") {
16
+ for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
17
+ get: () => from[key],
18
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
19
+ });
20
+ }
21
+ return to;
21
22
  };
22
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
23
- // If the importer is in node compatibility mode or this is not an ESM
24
- // file that has been converted to a CommonJS file using a Babel-
25
- // compatible transform (i.e. "__esModule" has not been set), then set
26
- // "default" to the CommonJS "module.exports" for node compatibility.
27
- isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
28
- value: mod,
29
- enumerable: true
23
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
24
+ value: mod,
25
+ enumerable: true
30
26
  }) : target, mod));
31
- var __toCommonJS = mod => __copyProps(__defProp({}, "__esModule", {
32
- value: true
33
- }), mod);
27
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
34
28
  var Dialog_exports = {};
35
29
  __export(Dialog_exports, {
36
- Dialog: () => Dialog,
37
- DialogClose: () => DialogClose,
38
- DialogContent: () => DialogContent,
39
- DialogContext: () => DialogContext,
40
- DialogDescription: () => DialogDescription,
41
- DialogOverlay: () => DialogOverlay,
42
- DialogOverlayFrame: () => DialogOverlayFrame,
43
- DialogPortal: () => DialogPortal,
44
- DialogPortalFrame: () => DialogPortalFrame,
45
- DialogProvider: () => DialogProvider,
46
- DialogTitle: () => DialogTitle,
47
- DialogTrigger: () => DialogTrigger,
48
- DialogWarningProvider: () => DialogWarningProvider,
49
- useDialogContext: () => useDialogContext
30
+ Dialog: () => Dialog,
31
+ DialogClose: () => DialogClose,
32
+ DialogContent: () => DialogContent,
33
+ DialogContext: () => DialogContext,
34
+ DialogDescription: () => DialogDescription,
35
+ DialogOverlay: () => DialogOverlay,
36
+ DialogOverlayFrame: () => DialogOverlayFrame,
37
+ DialogPortal: () => DialogPortal,
38
+ DialogPortalFrame: () => DialogPortalFrame,
39
+ DialogProvider: () => DialogProvider,
40
+ DialogTitle: () => DialogTitle,
41
+ DialogTrigger: () => DialogTrigger,
42
+ DialogWarningProvider: () => DialogWarningProvider,
43
+ useDialogContext: () => useDialogContext
50
44
  });
51
45
  module.exports = __toCommonJS(Dialog_exports);
52
46
  var import_adapt = require("@tamagui/adapt");
@@ -60,644 +54,594 @@ var import_focus_scope = require("@tamagui/focus-scope");
60
54
  var import_helpers = require("@tamagui/helpers");
61
55
  var import_portal = require("@tamagui/portal");
62
56
  var import_remove_scroll = require("@tamagui/remove-scroll");
63
- var import_controller = require("@tamagui/sheet/controller");
64
57
  var import_stacks = require("@tamagui/stacks");
65
58
  var import_text = require("@tamagui/text");
66
59
  var import_use_controllable_state = require("@tamagui/use-controllable-state");
67
60
  var import_z_index_stack = require("@tamagui/z-index-stack");
68
61
  var React = __toESM(require("react"), 1);
69
62
  var import_jsx_runtime = require("react/jsx-runtime");
70
- const DialogContext = (0, import_core.createStyledContext)(
71
- // since we always provide this we can avoid setting here
72
- {}, "Dialog__");
73
- const {
74
- useStyledContext: useDialogContext,
75
- Provider: DialogProvider
76
- } = DialogContext;
77
- const DialogAdaptHiddenContext = React.createContext(true);
78
- const DialogTriggerFrame = (0, import_core.styled)(import_core.View, {
79
- name: "DialogTrigger"
80
- });
81
- const DialogTrigger = DialogTriggerFrame.styleable(function DialogTrigger2(props, forwardedRef) {
82
- const {
83
- scope,
84
- ...triggerProps
85
- } = props;
86
- const isInsideButton = React.useContext(import_stacks.ButtonNestingContext);
87
- const context = useDialogContext(scope);
88
- const composedTriggerRef = (0, import_compose_refs.useComposedRefs)(forwardedRef, context.triggerRef);
89
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_stacks.ButtonNestingContext.Provider, {
90
- value: true,
91
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogTriggerFrame, {
92
- render: isInsideButton ? "span" : "button",
93
- "aria-haspopup": "dialog",
94
- "aria-expanded": context.open,
95
- "aria-controls": context.contentId,
96
- "data-state": getState(context.open),
97
- ...triggerProps,
98
- ref: composedTriggerRef,
99
- onPress: (0, import_helpers.composeEventHandlers)(props.onPress, context.onOpenToggle)
100
- })
101
- });
63
+ const DialogContext = (0, import_core.createStyledContext)({}, "Dialog__");
64
+ const { useStyledContext: useDialogContext, Provider: DialogProvider } = DialogContext;
65
+ const DialogTriggerFrame = (0, import_core.styled)(import_core.View, { displayName: "DialogTrigger" });
66
+ const DialogTrigger = (0, import_core.createStyledHOC)(DialogTriggerFrame, function DialogTrigger2(props, forwardedRef) {
67
+ const { scope, ...triggerProps } = props;
68
+ const isInsideButton = React.useContext(import_stacks.ButtonNestingContext);
69
+ const context = useDialogContext(scope);
70
+ const composedTriggerRef = (0, import_compose_refs.useComposedRefs)(forwardedRef, context.triggerRef);
71
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_stacks.ButtonNestingContext.Provider, {
72
+ value: props.asChild ? isInsideButton : true,
73
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTriggerFrame, {
74
+ render: isInsideButton ? "span" : "button",
75
+ "aria-haspopup": "dialog",
76
+ "aria-expanded": context.open,
77
+ "aria-controls": context.contentId,
78
+ "data-state": getState(context.open),
79
+ ...triggerProps,
80
+ ref: composedTriggerRef,
81
+ onPress: (0, import_helpers.composeEventHandlers)(props.onPress, context.onOpenToggle)
82
+ })
83
+ });
102
84
  });
103
85
  const DialogPortalFrame = (0, import_core.styled)(import_stacks.YStack, {
104
- pointerEvents: "none",
105
- render: "dialog",
106
- variants: {
107
- unstyled: {
108
- false: {
109
- alignItems: "center",
110
- justifyContent: "center",
111
- fullscreen: true,
112
- "$platform-web": {
113
- // undo dialog styles
114
- borderWidth: 0,
115
- backgroundColor: "transparent",
116
- color: "inherit",
117
- maxInlineSize: "none",
118
- margin: 0,
119
- width: "auto",
120
- height: "auto",
121
- // ensure always in frame and right height
122
- maxHeight: "100vh",
123
- position: "fixed",
124
- // ensure dialog inherits stacking context from portal wrapper
125
- zIndex: 1
126
- }
127
- }
128
- }
129
- },
130
- defaultVariants: {
131
- unstyled: process.env.TAMAGUI_HEADLESS === "1"
132
- }
86
+ pointerEvents: "none",
87
+ alignItems: "center",
88
+ justifyContent: "center",
89
+ position: "absolute web:fixed",
90
+ inset: 0,
91
+ borderWidth: "web:0px",
92
+ backgroundColor: "web:transparent",
93
+ color: "web:inherit",
94
+ maxInlineSize: "web:none",
95
+ margin: "web:0px",
96
+ width: "web:auto",
97
+ height: "web:auto",
98
+ maxHeight: "web:100vh",
99
+ zIndex: "web:1",
100
+ render: "dialog"
133
101
  });
134
102
  const needsRepropagation = (0, import_portal.needsPortalRepropagation)();
135
- const DialogPortalItem = ({
136
- context,
137
- children
138
- }) => {
139
- const themeName = (0, import_core.useThemeName)();
140
- const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
141
- const adaptContext = (0, import_adapt.useAdaptContext)(context.adaptScope);
142
- let content = /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_core.Theme, {
143
- name: themeName,
144
- children
145
- });
146
- if (needsRepropagation) {
147
- content = /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_adapt.ProvideAdaptContext, {
148
- ...adaptContext,
149
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogProvider, {
150
- ...context,
151
- children: content
152
- })
153
- });
154
- }
155
- return isAdapted ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_adapt.AdaptPortalContents, {
156
- scope: context.adaptScope,
157
- children: content
158
- }) : context.modal ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_portal.PortalItem, {
159
- hostName: context.modal ? "root" : context.adaptScope,
160
- children: content
161
- }) : content;
103
+ const DialogPortalItem = ({ context, children }) => {
104
+ const themeName = (0, import_core.useThemeName)();
105
+ const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
106
+ const adaptContext = (0, import_adapt.useAdaptContext)(context.adaptScope);
107
+ let content = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Theme, {
108
+ name: themeName,
109
+ children
110
+ });
111
+ if (needsRepropagation) {
112
+ content = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_adapt.ProvideAdaptContext, {
113
+ ...adaptContext,
114
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogProvider, {
115
+ ...context,
116
+ children: content
117
+ })
118
+ });
119
+ }
120
+ return isAdapted ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_adapt.AdaptPortalContents, {
121
+ scope: context.adaptScope,
122
+ children: content
123
+ }) : context.modal ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_portal.PortalItem, {
124
+ hostName: "root",
125
+ children: content
126
+ }) : content;
162
127
  };
163
- const DialogPortal = React.forwardRef((props, forwardRef) => {
164
- const {
165
- scope,
166
- forceMount,
167
- children,
168
- ...frameProps
169
- } = props;
170
- const dialogRef = React.useRef(null);
171
- const ref = (0, import_compose_refs.composeRefs)(dialogRef, forwardRef);
172
- const context = useDialogContext(scope);
173
- const keepMounted = forceMount || context.keepChildrenMounted;
174
- const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
175
- const [isFullyHidden, setIsFullyHidden] = React.useState(!context.open);
176
- if (context.open && isFullyHidden) {
177
- setIsFullyHidden(false);
178
- }
179
- const isVisible = context.open ? true : !isFullyHidden;
180
- if (import_constants.isWeb) {
181
- (0, import_constants.useIsomorphicLayoutEffect)(() => {
182
- const node = dialogRef.current;
183
- if (!(node instanceof HTMLDialogElement)) return;
184
- if (isVisible) {
185
- node.show?.();
186
- } else {
187
- node.close?.();
188
- }
189
- }, [isVisible]);
190
- }
191
- const onAnimationCompleteRef = React.useRef(context.onAnimationComplete);
192
- onAnimationCompleteRef.current = context.onAnimationComplete;
193
- const handleExitComplete = React.useCallback(() => {
194
- setIsFullyHidden(true);
195
- onAnimationCompleteRef.current?.({
196
- open: false
197
- });
198
- }, []);
199
- React.useEffect(() => {
200
- if (context.open && !isAdapted && onAnimationCompleteRef.current) {
201
- const tm = setTimeout(() => {
202
- onAnimationCompleteRef.current?.({
203
- open: true
204
- });
205
- }, 350);
206
- return () => clearTimeout(tm);
207
- }
208
- }, [context.open, isAdapted]);
209
- const zIndex = (0, import_core.getExpandedShorthand)("zIndex", props);
210
- const contents = /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_z_index_stack.StackZIndexContext, {
211
- zIndex: (0, import_portal.resolveViewZIndex)(zIndex),
212
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_animate.Animate, {
213
- type: "presence",
214
- present: Boolean(context.open),
215
- keepChildrenMounted: Boolean(keepMounted),
216
- onExitComplete: handleExitComplete,
217
- passThrough: isAdapted,
218
- children
219
- })
220
- });
221
- const framedContents = isFullyHidden && !keepMounted && !isAdapted ? null : /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_core.LayoutMeasurementController, {
222
- disable: !context.open,
223
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogPortalFrame, {
224
- ref,
225
- ...(import_constants.isWeb && context.open && {
226
- "aria-modal": true
227
- }),
228
- pointerEvents: context.open ? "auto" : "none",
229
- ...frameProps,
230
- className: `_no_backdrop ` + (frameProps.className || ""),
231
- children: contents
232
- })
233
- });
234
- if (import_constants.isWeb) {
235
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_portal.Portal, {
236
- zIndex,
237
- stackZIndex: 1e5,
238
- passThrough: isAdapted,
239
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(PassthroughTheme, {
240
- passThrough: isAdapted,
241
- children: framedContents
242
- })
243
- });
244
- }
245
- return isAdapted ? framedContents : /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogPortalItem, {
246
- context,
247
- children: framedContents
248
- });
128
+ const DialogPortal = (0, import_core.createRefComponent)((props, forwardedRef) => {
129
+ const { scope, forceMount, children, ...frameProps } = props;
130
+ const dialogRef = React.useRef(null);
131
+ const ref = (0, import_compose_refs.composeRefs)(dialogRef, forwardedRef);
132
+ const context = useDialogContext(scope);
133
+ const portalContext = forceMount ? {
134
+ ...context,
135
+ forceMount: true
136
+ } : context;
137
+ const keepMounted = forceMount || context.keepChildrenMounted;
138
+ const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
139
+ const isVisible = context.open || context.hasPresentParts;
140
+ if (import_constants.isWeb) {
141
+ (0, import_constants.useIsomorphicLayoutEffect)(() => {
142
+ const node = dialogRef.current;
143
+ if (!(node instanceof HTMLDialogElement)) return;
144
+ if (isVisible) {
145
+ node.show?.();
146
+ } else {
147
+ node.close?.();
148
+ }
149
+ }, [isVisible]);
150
+ }
151
+ const zIndex = (0, import_core.getExpandedShorthand)("zIndex", props);
152
+ const contents = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_z_index_stack.StackZIndexContext, {
153
+ zIndex: (0, import_portal.resolveViewZIndex)(zIndex),
154
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogProvider, {
155
+ scope: context.dialogScope,
156
+ ...portalContext,
157
+ children
158
+ })
159
+ });
160
+ const framedContents = !isVisible && !keepMounted && !isAdapted ? null : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.LayoutMeasurementController, {
161
+ disable: !context.open,
162
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogPortalFrame, {
163
+ ref,
164
+ ...import_constants.isWeb && context.open && context.modal && { "aria-modal": true },
165
+ pointerEvents: context.open && context.modal ? "auto" : "none",
166
+ ...frameProps,
167
+ className: `_no_backdrop ` + (frameProps.className || ""),
168
+ children: contents
169
+ })
170
+ });
171
+ if (import_constants.isWeb) {
172
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_portal.Portal, {
173
+ zIndex,
174
+ stackZIndex: 1e5,
175
+ passThrough: isAdapted,
176
+ hidden: !isVisible,
177
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(PassthroughTheme, {
178
+ passThrough: isAdapted,
179
+ children: framedContents
180
+ })
181
+ });
182
+ }
183
+ return isAdapted ? framedContents : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogPortalItem, {
184
+ context: portalContext,
185
+ children: framedContents
186
+ });
249
187
  });
250
- const PassthroughTheme = ({
251
- children,
252
- passThrough
253
- }) => {
254
- const themeName = (0, import_core.useThemeName)();
255
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_core.Theme, {
256
- passThrough,
257
- name: themeName,
258
- forceClassName: true,
259
- children
260
- });
188
+ const PassthroughTheme = ({ children, passThrough }) => {
189
+ const themeName = (0, import_core.useThemeName)();
190
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Theme, {
191
+ passThrough,
192
+ name: themeName,
193
+ forceClassName: true,
194
+ children
195
+ });
261
196
  };
197
+ function useDialogAnimationReporter(context) {
198
+ const onAnimationCompleteRef = React.useRef(context.onAnimationComplete);
199
+ onAnimationCompleteRef.current = context.onAnimationComplete;
200
+ const openRef = React.useRef(context.open);
201
+ const pendingTransitionRef = React.useRef(context.open ? true : null);
202
+ if (openRef.current !== context.open) {
203
+ openRef.current = context.open;
204
+ pendingTransitionRef.current = context.open;
205
+ }
206
+ const reportComplete = React.useCallback((open) => {
207
+ if (pendingTransitionRef.current !== open) return;
208
+ if (openRef.current !== open) return;
209
+ pendingTransitionRef.current = null;
210
+ onAnimationCompleteRef.current?.({ open });
211
+ }, []);
212
+ return React.useMemo(() => ({
213
+ onEnterComplete: () => reportComplete(true),
214
+ onExitComplete: () => reportComplete(false)
215
+ }), [reportComplete]);
216
+ }
217
+ function useDialogPartPresence(context, options) {
218
+ const [isFullyHidden, setIsFullyHidden] = React.useState(!context.open);
219
+ const reactId = React.useId();
220
+ const partPresenceId = `${context.contentId}-${options.id}-${reactId}`;
221
+ const keepMounted = options.forceMount || context.keepChildrenMounted;
222
+ const isPresent = context.open || !isFullyHidden;
223
+ (0, import_constants.useIsomorphicLayoutEffect)(() => {
224
+ if (context.open && isFullyHidden) {
225
+ setIsFullyHidden(false);
226
+ }
227
+ }, [context.open, isFullyHidden]);
228
+ (0, import_constants.useIsomorphicLayoutEffect)(() => {
229
+ if (options.disabled) return;
230
+ context.setPartPresence(partPresenceId, isPresent);
231
+ return () => {
232
+ context.setPartPresence(partPresenceId, false);
233
+ };
234
+ }, [
235
+ context.setPartPresence,
236
+ isPresent,
237
+ options.disabled,
238
+ partPresenceId
239
+ ]);
240
+ const onExitComplete = React.useCallback(() => {
241
+ setIsFullyHidden(true);
242
+ options.onExitComplete?.();
243
+ }, [options.onExitComplete]);
244
+ return {
245
+ keepMounted,
246
+ onExitComplete,
247
+ shouldRender: Boolean(keepMounted || context.open || !isFullyHidden)
248
+ };
249
+ }
262
250
  const OVERLAY_NAME = "DialogOverlay";
263
251
  const DialogOverlayFrame = (0, import_core.styled)(import_stacks.YStack, {
264
- name: OVERLAY_NAME,
265
- zIndex: 1,
266
- variants: {
267
- open: {
268
- true: {
269
- pointerEvents: "auto"
270
- },
271
- false: {
272
- pointerEvents: "none"
273
- }
274
- },
275
- unstyled: {
276
- false: {
277
- fullscreen: true,
278
- position: "absolute",
279
- backgroundColor: "$background",
280
- pointerEvents: "auto"
281
- }
282
- }
283
- },
284
- defaultVariants: {
285
- unstyled: process.env.TAMAGUI_HEADLESS === "1"
286
- }
252
+ displayName: OVERLAY_NAME,
253
+ zIndex: 1,
254
+ inset: 0,
255
+ position: "absolute",
256
+ pointerEvents: "auto",
257
+ variants: { open: {
258
+ true: { pointerEvents: "auto" },
259
+ false: { pointerEvents: "none" }
260
+ } }
287
261
  });
288
- const DialogOverlay = DialogOverlayFrame.styleable(function DialogOverlay2({
289
- scope,
290
- ...props
291
- }, forwardedRef) {
292
- const context = useDialogContext(scope);
293
- const {
294
- forceMount = context.forceMount,
295
- ...overlayProps
296
- } = props;
297
- const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
298
- if (!forceMount) {
299
- if (!context.modal || isAdapted) {
300
- return null;
301
- }
302
- }
303
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogOverlayFrame, {
304
- "data-state": getState(context.open),
305
- pointerEvents: context.open ? "auto" : "none",
306
- ...overlayProps,
307
- ref: forwardedRef
308
- });
262
+ const DialogOverlay = (0, import_core.createStyledHOC)(DialogOverlayFrame, function DialogOverlay2({ scope, ...props }, forwardedRef) {
263
+ const context = useDialogContext(scope);
264
+ const { forceMount = context.forceMount, ...overlayProps } = props;
265
+ const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
266
+ const presence = useDialogPartPresence(context, {
267
+ disabled: isAdapted,
268
+ forceMount,
269
+ id: "overlay"
270
+ });
271
+ if (!forceMount && isAdapted) {
272
+ return null;
273
+ }
274
+ if (!presence.shouldRender) {
275
+ return null;
276
+ }
277
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_animate.Animate, {
278
+ type: "presence",
279
+ present: Boolean(context.open),
280
+ keepChildrenMounted: Boolean(presence.keepMounted),
281
+ onExitComplete: presence.onExitComplete,
282
+ passThrough: isAdapted,
283
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogOverlayFrame, {
284
+ "data-state": getState(context.open),
285
+ pointerEvents: context.open && context.modal ? "auto exit:none" : "none",
286
+ ...overlayProps,
287
+ ref: forwardedRef
288
+ }, `${context.contentId}-overlay`)
289
+ });
309
290
  });
310
291
  const CONTENT_NAME = "DialogContent";
311
- const DialogContentFrame = (0, import_core.styled)(import_stacks.ThemeableStack, {
312
- name: CONTENT_NAME,
313
- zIndex: 2,
314
- variants: {
315
- size: {
316
- "...size": (val, extras) => {
317
- return {};
318
- }
319
- },
320
- unstyled: {
321
- false: {
322
- position: "relative",
323
- backgroundColor: "$background",
324
- borderWidth: 1,
325
- borderColor: "$borderColor",
326
- padding: "$true",
327
- borderRadius: "$true",
328
- elevate: true,
329
- // Ensure content receives pointer events (fixes React 19 + display:contents inheritance)
330
- pointerEvents: "auto"
331
- }
332
- }
333
- },
334
- defaultVariants: {
335
- size: "$true",
336
- unstyled: process.env.TAMAGUI_HEADLESS === "1"
337
- }
338
- });
339
- const DialogContent = DialogContentFrame.styleable(function DialogContent2({
340
- scope,
341
- ...props
342
- }, forwardedRef) {
343
- const context = useDialogContext(scope);
344
- const contents = /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, {
345
- children: context.modal ? /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogContentModal, {
346
- context,
347
- ...props,
348
- ref: forwardedRef
349
- }) : /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogContentNonModal, {
350
- context,
351
- ...props,
352
- ref: forwardedRef
353
- })
354
- });
355
- if (!import_constants.isWeb || context.disableRemoveScroll) {
356
- return contents;
357
- }
358
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_remove_scroll.RemoveScroll, {
359
- enabled: context.open,
360
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)("div", {
361
- "data-remove-scroll-container": true,
362
- className: "_dsp_contents",
363
- children: contents
364
- })
365
- });
366
- });
367
- const DialogContentModal = React.forwardRef(({
368
- children,
369
- context,
370
- ...props
371
- }, forwardedRef) => {
372
- const contentRef = React.useRef(null);
373
- const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, context.contentRef, contentRef);
374
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogContentImpl, {
375
- ...props,
376
- context,
377
- ref: composedRefs,
378
- trapFocus: context.open,
379
- disableOutsidePointerEvents: true,
380
- onCloseAutoFocus: (0, import_helpers.composeEventHandlers)(props.onCloseAutoFocus, event => {
381
- event.preventDefault();
382
- context.triggerRef.current?.focus();
383
- }),
384
- onPointerDownOutside: (0, import_helpers.composeEventHandlers)(props.onPointerDownOutside, event => {
385
- const originalEvent = event["detail"].originalEvent;
386
- const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
387
- const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
388
- if (isRightClick) event.preventDefault();
389
- }),
390
- onFocusOutside: (0, import_helpers.composeEventHandlers)(props.onFocusOutside, event => event.preventDefault()),
391
- ...(!props.unstyled && {
392
- outlineStyle: "none"
393
- }),
394
- children
395
- });
292
+ const DialogContentFrame = (0, import_core.styled)(import_stacks.YStack, {
293
+ displayName: CONTENT_NAME,
294
+ zIndex: 2,
295
+ position: "relative",
296
+ pointerEvents: "auto",
297
+ variants: {
298
+ elevate: { true: {
299
+ shadowColor: "shadow-color",
300
+ shadowRadius: 24,
301
+ shadowOffset: {
302
+ width: 0,
303
+ height: 12
304
+ }
305
+ } },
306
+ bordered: { true: {
307
+ borderWidth: 1,
308
+ borderColor: "border-color"
309
+ } }
310
+ }
396
311
  });
397
- const DialogContentNonModal = React.forwardRef((props, forwardedRef) => {
398
- const hasInteractedOutsideRef = React.useRef(false);
399
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogContentImpl, {
400
- ...props,
401
- ref: forwardedRef,
402
- trapFocus: false,
403
- disableOutsidePointerEvents: false,
404
- onCloseAutoFocus: event => {
405
- props.onCloseAutoFocus?.(event);
406
- if (!event.defaultPrevented) {
407
- if (!hasInteractedOutsideRef.current) {
408
- props.context.triggerRef.current?.focus();
409
- }
410
- event.preventDefault();
411
- }
412
- hasInteractedOutsideRef.current = false;
413
- },
414
- onInteractOutside: event => {
415
- props.onInteractOutside?.(event);
416
- if (!event.defaultPrevented) hasInteractedOutsideRef.current = true;
417
- const target = event.target;
418
- const trigger = props.context.triggerRef.current;
419
- if (!(trigger instanceof HTMLElement)) return;
420
- const targetIsTrigger = trigger.contains(target);
421
- if (targetIsTrigger) event.preventDefault();
422
- }
423
- });
312
+ const DialogContent = (0, import_core.createStyledHOC)(DialogContentFrame, function DialogContent2({ scope, ...props }, forwardedRef) {
313
+ const context = useDialogContext(scope);
314
+ const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
315
+ const reporter = useDialogAnimationReporter(context);
316
+ const onTransitionProp = props.onTransition;
317
+ const onTransition = React.useCallback((event) => {
318
+ if (event.phase === "end" && event.cause === "enter") {
319
+ reporter.onEnterComplete();
320
+ }
321
+ onTransitionProp?.(event);
322
+ }, [reporter.onEnterComplete, onTransitionProp]);
323
+ const presence = useDialogPartPresence(context, {
324
+ disabled: isAdapted,
325
+ forceMount: context.forceMount,
326
+ id: "content",
327
+ onExitComplete: reporter.onExitComplete
328
+ });
329
+ const contents = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_jsx_runtime.Fragment, { children: context.modal ? /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogContentModal, {
330
+ context,
331
+ ...props,
332
+ onTransition,
333
+ ref: forwardedRef
334
+ }) : /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogContentNonModal, {
335
+ context,
336
+ ...props,
337
+ onTransition,
338
+ ref: forwardedRef
339
+ }) });
340
+ if (isAdapted) {
341
+ if (!import_constants.isWeb || context.disableRemoveScroll) {
342
+ return contents;
343
+ }
344
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_remove_scroll.RemoveScroll, {
345
+ enabled: context.open && context.modal,
346
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
347
+ "data-remove-scroll-container": true,
348
+ className: "_dsp_contents",
349
+ children: contents
350
+ })
351
+ });
352
+ }
353
+ if (!presence.shouldRender) {
354
+ return null;
355
+ }
356
+ const animated = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_animate.Animate, {
357
+ type: "presence",
358
+ present: Boolean(context.open),
359
+ keepChildrenMounted: Boolean(presence.keepMounted),
360
+ onExitComplete: presence.onExitComplete,
361
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(React.Fragment, { children: contents }, context.contentId)
362
+ });
363
+ if (!import_constants.isWeb || context.disableRemoveScroll) {
364
+ return animated;
365
+ }
366
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_remove_scroll.RemoveScroll, {
367
+ enabled: context.open && context.modal,
368
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", {
369
+ "data-remove-scroll-container": true,
370
+ className: "_dsp_contents",
371
+ children: animated
372
+ })
373
+ });
424
374
  });
425
- const DialogContentImpl = React.forwardRef((props, forwardedRef) => {
426
- const {
427
- trapFocus,
428
- onOpenAutoFocus,
429
- onCloseAutoFocus,
430
- disableOutsidePointerEvents,
431
- onEscapeKeyDown,
432
- onPointerDownOutside,
433
- onFocusOutside,
434
- onInteractOutside,
435
- context,
436
- ...contentProps
437
- } = props;
438
- const contentRef = React.useRef(null);
439
- const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, contentRef);
440
- const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
441
- const isAdaptFullyHidden = React.useContext(DialogAdaptHiddenContext);
442
- if (isAdapted) {
443
- if (!context.open && !context.keepChildrenMounted && isAdaptFullyHidden) {
444
- return null;
445
- }
446
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogPortalItem, {
447
- context,
448
- children: contentProps.children
449
- });
450
- }
451
- const contents = /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogContentFrame, {
452
- ref: composedRefs,
453
- id: context.contentId,
454
- role: "dialog",
455
- "aria-modal": context.modal,
456
- "aria-describedby": context.descriptionId,
457
- "aria-labelledby": context.titleId,
458
- "data-state": getState(context.open),
459
- pointerEvents: context.open ? "auto" : "none",
460
- ...contentProps
461
- });
462
- if (!import_constants.isWeb) {
463
- return contents;
464
- }
465
- return /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
466
- children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(import_dismissable.Dismissable, {
467
- disableOutsidePointerEvents: context.open && disableOutsidePointerEvents,
468
- forceUnmount: !context.open,
469
- onEscapeKeyDown,
470
- onPointerDownOutside,
471
- onFocusOutside,
472
- onInteractOutside,
473
- onDismiss: () => context?.onOpenChange?.(false),
474
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_focus_scope.FocusScope, {
475
- loop: true,
476
- enabled: context.open,
477
- trapped: trapFocus,
478
- onMountAutoFocus: onOpenAutoFocus,
479
- forceUnmount: !context.open,
480
- onUnmountAutoFocus: onCloseAutoFocus,
481
- children: contents
482
- })
483
- }), process.env.NODE_ENV === "development" && /* @__PURE__ */(0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, {
484
- children: [/* @__PURE__ */(0, import_jsx_runtime.jsx)(TitleWarning, {
485
- titleId: context.titleId
486
- }), /* @__PURE__ */(0, import_jsx_runtime.jsx)(DescriptionWarning, {
487
- contentRef,
488
- descriptionId: context.descriptionId
489
- })]
490
- })]
491
- });
375
+ const DialogContentModal = (0, import_core.createRefComponent)(({ children, context: contextProp, ...props }, forwardedRef) => {
376
+ const context = useDialogContext(contextProp.dialogScope);
377
+ const contentRef = React.useRef(null);
378
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, context.contentRef, contentRef);
379
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogContentImpl, {
380
+ ...props,
381
+ context,
382
+ ref: composedRefs,
383
+ trapFocus: context.open,
384
+ disableOutsidePointerEvents: true,
385
+ onCloseAutoFocus: (0, import_helpers.composeEventHandlers)(props.onCloseAutoFocus, (event) => {
386
+ event.cancel();
387
+ context.triggerRef.current?.focus();
388
+ }),
389
+ onPointerDownOutside: (0, import_helpers.composeEventHandlers)(props.onPointerDownOutside, (event) => {
390
+ const originalEvent = event.event;
391
+ if (!originalEvent) return;
392
+ const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
393
+ const isRightClick = originalEvent.button === 2 || ctrlLeftClick;
394
+ if (isRightClick) event.cancel();
395
+ }),
396
+ onFocusOutside: (0, import_helpers.composeEventHandlers)(props.onFocusOutside, (event) => event.cancel()),
397
+ outlineStyle: "none",
398
+ children
399
+ });
492
400
  });
493
- const DialogTitleFrame = (0, import_core.styled)(import_text.H2, {
494
- name: "DialogTitle"
401
+ const DialogContentNonModal = (0, import_core.createRefComponent)((props, forwardedRef) => {
402
+ const context = useDialogContext(props.context.dialogScope);
403
+ const hasInteractedOutsideRef = React.useRef(false);
404
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogContentImpl, {
405
+ ...props,
406
+ context,
407
+ ref: forwardedRef,
408
+ trapFocus: false,
409
+ disableOutsidePointerEvents: false,
410
+ onCloseAutoFocus: (event) => {
411
+ props.onCloseAutoFocus?.(event);
412
+ if (!event.isCanceled) {
413
+ if (!hasInteractedOutsideRef.current) {
414
+ props.context.triggerRef.current?.focus();
415
+ }
416
+ event.cancel();
417
+ }
418
+ hasInteractedOutsideRef.current = false;
419
+ },
420
+ onInteractOutside: (event) => {
421
+ props.onInteractOutside?.(event);
422
+ if (!event.isCanceled) hasInteractedOutsideRef.current = true;
423
+ const target = event.event?.target;
424
+ const trigger = props.context.triggerRef.current;
425
+ if (!target || !(trigger instanceof HTMLElement)) return;
426
+ const targetIsTrigger = trigger.contains(target);
427
+ if (targetIsTrigger) event.cancel();
428
+ }
429
+ });
495
430
  });
496
- const DialogTitle = DialogTitleFrame.styleable(function DialogTitle2(props, forwardedRef) {
497
- const {
498
- scope,
499
- ...titleProps
500
- } = props;
501
- const context = useDialogContext(scope);
502
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogTitleFrame, {
503
- id: context.titleId,
504
- ...titleProps,
505
- ref: forwardedRef
506
- });
431
+ const DialogContentImpl = (0, import_core.createRefComponent)((props, forwardedRef) => {
432
+ const { trapFocus, onOpenAutoFocus, onCloseAutoFocus, disableOutsidePointerEvents, onEscapeKeyDown, onPointerDownOutside, onFocusOutside, onInteractOutside, context, onTransition, ...contentProps } = props;
433
+ const contentRef = React.useRef(null);
434
+ const composedRefs = (0, import_compose_refs.useComposedRefs)(forwardedRef, contentRef);
435
+ const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
436
+ const adaptContext = (0, import_adapt.useAdaptContext)(context.adaptScope);
437
+ if (isAdapted) {
438
+ if (!context.open && !context.keepChildrenMounted && adaptContext.targetFullyHidden) {
439
+ return null;
440
+ }
441
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogPortalItem, {
442
+ context,
443
+ children: contentProps.children
444
+ });
445
+ }
446
+ const contents = /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogContentFrame, {
447
+ ref: composedRefs,
448
+ id: context.contentId,
449
+ role: "dialog",
450
+ "aria-modal": context.modal,
451
+ "aria-describedby": context.descriptionId,
452
+ "aria-labelledby": context.titleId,
453
+ "data-state": getState(context.open),
454
+ pointerEvents: context.open ? "auto" : "none",
455
+ onTransition,
456
+ ...contentProps
457
+ });
458
+ if (!import_constants.isWeb) {
459
+ return contents;
460
+ }
461
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_dismissable.Dismissable, {
462
+ disableOutsidePointerEvents: context.open && disableOutsidePointerEvents,
463
+ forceUnmount: !context.open,
464
+ onEscapeKeyDown,
465
+ onPointerDownOutside,
466
+ onFocusOutside,
467
+ onInteractOutside,
468
+ onDismiss: () => context?.onOpenChange?.(false),
469
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_focus_scope.FocusScope, {
470
+ loop: true,
471
+ enabled: context.open,
472
+ trapped: trapFocus,
473
+ onMountAutoFocus: onOpenAutoFocus,
474
+ forceUnmount: !context.open,
475
+ onUnmountAutoFocus: onCloseAutoFocus,
476
+ children: contents
477
+ })
478
+ }), process.env.NODE_ENV === "development" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(import_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, import_jsx_runtime.jsx)(TitleWarning, { titleId: context.titleId }), /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DescriptionWarning, {
479
+ contentRef,
480
+ descriptionId: context.descriptionId
481
+ })] })] });
507
482
  });
508
- const DialogDescriptionFrame = (0, import_core.styled)(import_text.Paragraph, {
509
- name: "DialogDescription"
483
+ const DialogTitleFrame = (0, import_core.styled)(import_text.H2, { displayName: "DialogTitle" });
484
+ const DialogTitle = (0, import_core.createStyledHOC)(DialogTitleFrame, function DialogTitle2(props, forwardedRef) {
485
+ const { scope, ...titleProps } = props;
486
+ const context = useDialogContext(scope);
487
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogTitleFrame, {
488
+ id: context.titleId,
489
+ ...titleProps,
490
+ ref: forwardedRef
491
+ });
510
492
  });
511
- const DialogDescription = DialogDescriptionFrame.styleable(function DialogDescription2(props, forwardedRef) {
512
- const {
513
- scope,
514
- ...descriptionProps
515
- } = props;
516
- const context = useDialogContext(scope);
517
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogDescriptionFrame, {
518
- id: context.descriptionId,
519
- ...descriptionProps,
520
- ref: forwardedRef
521
- });
493
+ const DialogDescriptionFrame = (0, import_core.styled)(import_text.Paragraph, { displayName: "DialogDescription" });
494
+ const DialogDescription = (0, import_core.createStyledHOC)(DialogDescriptionFrame, function DialogDescription2(props, forwardedRef) {
495
+ const { scope, ...descriptionProps } = props;
496
+ const context = useDialogContext(scope);
497
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogDescriptionFrame, {
498
+ id: context.descriptionId,
499
+ ...descriptionProps,
500
+ ref: forwardedRef
501
+ });
522
502
  });
523
503
  const CLOSE_NAME = "DialogClose";
524
504
  const DialogCloseFrame = (0, import_core.styled)(import_core.View, {
525
- name: CLOSE_NAME,
526
- render: "button"
505
+ displayName: CLOSE_NAME,
506
+ render: "button"
527
507
  });
528
- const DialogClose = DialogCloseFrame.styleable((props, forwardedRef) => {
529
- const {
530
- scope,
531
- displayWhenAdapted,
532
- ...closeProps
533
- } = props;
534
- const context = useDialogContext(scope);
535
- const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
536
- const isInsideButton = React.useContext(import_stacks.ButtonNestingContext);
537
- if (isAdapted && !displayWhenAdapted) {
538
- return null;
539
- }
540
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogCloseFrame, {
541
- "aria-label": "Dialog Close",
542
- render: isInsideButton ? "span" : "button",
543
- ...closeProps,
544
- ref: forwardedRef,
545
- onPress: (0, import_helpers.composeEventHandlers)(props.onPress, () => {
546
- context.onOpenChange(false);
547
- })
548
- });
508
+ const DialogClose = (0, import_core.createStyledHOC)(DialogCloseFrame, (props, forwardedRef) => {
509
+ const { scope, displayWhenAdapted, ...closeProps } = props;
510
+ const context = useDialogContext(scope);
511
+ const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
512
+ const isInsideButton = React.useContext(import_stacks.ButtonNestingContext);
513
+ if (isAdapted && !displayWhenAdapted) {
514
+ return null;
515
+ }
516
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogCloseFrame, {
517
+ "aria-label": "Dialog Close",
518
+ render: isInsideButton ? "span" : "button",
519
+ ...closeProps,
520
+ ref: forwardedRef,
521
+ onPress: (0, import_helpers.composeEventHandlers)(props.onPress, () => {
522
+ context.onOpenChange(false);
523
+ })
524
+ });
549
525
  });
550
526
  function getState(open) {
551
- return open ? "open" : "closed";
527
+ return open ? "open" : "closed";
552
528
  }
553
529
  const TITLE_WARNING_NAME = "DialogTitleWarning";
554
530
  const [DialogWarningProvider, useWarningContext] = (0, import_create_context.createContext)(TITLE_WARNING_NAME, {
555
- contentName: CONTENT_NAME,
556
- titleName: "DialogTitle",
557
- docsSlug: "dialog"
531
+ contentName: CONTENT_NAME,
532
+ titleName: "DialogTitle",
533
+ docsSlug: "dialog"
558
534
  });
559
- const TitleWarning = ({
560
- titleId
561
- }) => {
562
- if (process.env.NODE_ENV === "development") {
563
- const titleWarningContext = useWarningContext(TITLE_WARNING_NAME);
564
- const MESSAGE = `\`${titleWarningContext.contentName}\` wants a \`${titleWarningContext.titleName}\` to be accessible. If you want to hide the \`${titleWarningContext.titleName}\`, wrap it with <VisuallyHidden />.`;
565
- React.useEffect(() => {
566
- if (!import_constants.isWeb) return;
567
- if (titleId) {
568
- const hasTitle = document.getElementById(titleId);
569
- if (!hasTitle) {
570
- console.warn(MESSAGE);
571
- }
572
- }
573
- }, [MESSAGE, titleId]);
574
- }
575
- return null;
535
+ const TitleWarning = ({ titleId }) => {
536
+ if (process.env.NODE_ENV === "development") {
537
+ const titleWarningContext = useWarningContext(TITLE_WARNING_NAME);
538
+ const MESSAGE = `\`${titleWarningContext.contentName}\` wants a \`${titleWarningContext.titleName}\` to be accessible. If you want to hide the \`${titleWarningContext.titleName}\`, wrap it with <VisuallyHidden />.`;
539
+ React.useEffect(() => {
540
+ if (!import_constants.isWeb) return;
541
+ if (titleId) {
542
+ const hasTitle = document.getElementById(titleId);
543
+ if (!hasTitle) {
544
+ console.warn(MESSAGE);
545
+ }
546
+ }
547
+ }, [MESSAGE, titleId]);
548
+ }
549
+ return null;
576
550
  };
577
551
  const DESCRIPTION_WARNING_NAME = "DialogDescriptionWarning";
578
- const DescriptionWarning = ({
579
- contentRef,
580
- descriptionId
581
- }) => {
582
- if (process.env.NODE_ENV === "development") {
583
- const descriptionWarningContext = useWarningContext(DESCRIPTION_WARNING_NAME);
584
- const MESSAGE = `Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${descriptionWarningContext.contentName}}.`;
585
- React.useEffect(() => {
586
- if (!import_constants.isWeb) return;
587
- const contentNode = contentRef.current;
588
- if (!(contentNode instanceof HTMLElement)) {
589
- return;
590
- }
591
- const describedById = contentNode.getAttribute("aria-describedby");
592
- if (descriptionId && describedById) {
593
- const hasDescription = document.getElementById(descriptionId);
594
- if (!hasDescription) {
595
- console.warn(MESSAGE);
596
- }
597
- }
598
- }, [MESSAGE, contentRef, descriptionId]);
599
- }
600
- return null;
552
+ const DescriptionWarning = ({ contentRef, descriptionId }) => {
553
+ if (process.env.NODE_ENV === "development") {
554
+ const descriptionWarningContext = useWarningContext(DESCRIPTION_WARNING_NAME);
555
+ const MESSAGE = `Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${descriptionWarningContext.contentName}}.`;
556
+ React.useEffect(() => {
557
+ if (!import_constants.isWeb) return;
558
+ const contentNode = contentRef.current;
559
+ if (!(contentNode instanceof HTMLElement)) {
560
+ return;
561
+ }
562
+ const describedById = contentNode.getAttribute("aria-describedby");
563
+ if (descriptionId && describedById) {
564
+ const hasDescription = document.getElementById(descriptionId);
565
+ if (!hasDescription) {
566
+ console.warn(MESSAGE);
567
+ }
568
+ }
569
+ }, [
570
+ MESSAGE,
571
+ contentRef,
572
+ descriptionId
573
+ ]);
574
+ }
575
+ return null;
601
576
  };
602
- const Dialog = (0, import_helpers.withStaticProperties)(React.forwardRef(function Dialog2(props, ref) {
603
- const {
604
- scope = "",
605
- children,
606
- open: openProp,
607
- defaultOpen = false,
608
- onOpenChange,
609
- modal = true,
610
- keepChildrenMounted,
611
- disableRemoveScroll = false,
612
- onAnimationComplete
613
- } = props;
614
- const baseId = React.useId();
615
- const dialogId = `Dialog-${scope}-${baseId}`;
616
- const contentId = `${dialogId}-content`;
617
- const titleId = `${dialogId}-title`;
618
- const descriptionId = `${dialogId}-description`;
619
- const triggerRef = React.useRef(null);
620
- const contentRef = React.useRef(null);
621
- const [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
622
- prop: openProp,
623
- defaultProp: defaultOpen,
624
- onChange: onOpenChange
625
- });
626
- const onOpenToggle = React.useCallback(() => {
627
- setOpen(prevOpen => !prevOpen);
628
- }, [setOpen]);
629
- const adaptScope = `DialogAdapt${scope}`;
630
- const context = {
631
- dialogScope: scope,
632
- adaptScope,
633
- triggerRef,
634
- contentRef,
635
- contentId,
636
- titleId,
637
- descriptionId,
638
- open,
639
- onOpenChange: setOpen,
640
- onOpenToggle,
641
- modal,
642
- keepChildrenMounted,
643
- disableRemoveScroll,
644
- onAnimationComplete
645
- };
646
- React.useImperativeHandle(ref, () => ({
647
- open: setOpen
648
- }), [setOpen]);
649
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_adapt.AdaptParent, {
650
- scope: adaptScope,
651
- portal: {
652
- forwardProps: props
653
- },
654
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogProvider, {
655
- scope,
656
- ...context,
657
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogSheetController, {
658
- onOpenChange: setOpen,
659
- scope,
660
- children
661
- })
662
- })
663
- });
577
+ const Dialog = (0, import_helpers.withStaticProperties)((0, import_core.createRefComponent)(function Dialog2(props) {
578
+ const { scope = "", children, open: openProp, defaultOpen = false, onOpenChange, modal = true, keepChildrenMounted, disableRemoveScroll = false, onAnimationComplete } = props;
579
+ const baseId = React.useId();
580
+ const dialogId = `Dialog-${scope}-${baseId}`;
581
+ const contentId = `${dialogId}-content`;
582
+ const titleId = `${dialogId}-title`;
583
+ const descriptionId = `${dialogId}-description`;
584
+ const triggerRef = React.useRef(null);
585
+ const contentRef = React.useRef(null);
586
+ const presentPartIdsRef = React.useRef(/* @__PURE__ */ new Set());
587
+ const [presentPartCount, setPresentPartCount] = React.useState(0);
588
+ const [open, setOpen] = (0, import_use_controllable_state.useControllableState)({
589
+ prop: openProp,
590
+ defaultProp: defaultOpen,
591
+ onChange: onOpenChange
592
+ });
593
+ const onOpenToggle = React.useCallback(() => {
594
+ setOpen((prevOpen) => !prevOpen);
595
+ }, [setOpen]);
596
+ const adaptScope = `DialogAdapt${scope}`;
597
+ const setPartPresence = React.useCallback((id, present) => {
598
+ const presentPartIds = presentPartIdsRef.current;
599
+ const hasPart = presentPartIds.has(id);
600
+ if (present && !hasPart) {
601
+ presentPartIds.add(id);
602
+ setPresentPartCount(presentPartIds.size);
603
+ } else if (!present && hasPart) {
604
+ presentPartIds.delete(id);
605
+ setPresentPartCount(presentPartIds.size);
606
+ }
607
+ }, []);
608
+ const context = {
609
+ dialogScope: scope,
610
+ adaptScope,
611
+ triggerRef,
612
+ contentRef,
613
+ contentId,
614
+ titleId,
615
+ descriptionId,
616
+ open,
617
+ onOpenChange: setOpen,
618
+ onOpenToggle,
619
+ modal,
620
+ keepChildrenMounted,
621
+ disableRemoveScroll,
622
+ hasPresentParts: presentPartCount > 0,
623
+ setPartPresence,
624
+ onAnimationComplete
625
+ };
626
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_adapt.AdaptParent, {
627
+ scope: adaptScope,
628
+ open,
629
+ onOpenChange: setOpen,
630
+ state: context,
631
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(DialogProvider, {
632
+ scope,
633
+ ...context,
634
+ children
635
+ })
636
+ });
664
637
  }), {
665
- Trigger: DialogTrigger,
666
- Portal: DialogPortal,
667
- Overlay: DialogOverlay,
668
- Content: DialogContent,
669
- Title: DialogTitle,
670
- Description: DialogDescription,
671
- Close: DialogClose,
672
- FocusScope: import_focus_scope.FocusScopeController,
673
- Adapt: import_adapt.Adapt
638
+ Trigger: DialogTrigger,
639
+ Portal: DialogPortal,
640
+ Overlay: DialogOverlay,
641
+ Content: DialogContent,
642
+ Title: DialogTitle,
643
+ Description: DialogDescription,
644
+ Close: DialogClose,
645
+ FocusScope: import_focus_scope.FocusScopeController,
646
+ Adapt: import_adapt.Adapt
674
647
  });
675
- const DialogSheetController = props => {
676
- const context = useDialogContext(props.scope);
677
- const isAdapted = (0, import_adapt.useAdaptIsActive)(context.adaptScope);
678
- const [isAdaptFullyHidden, setIsAdaptFullyHidden] = React.useState(!context.open);
679
- if (context.open && isAdaptFullyHidden) {
680
- setIsAdaptFullyHidden(false);
681
- }
682
- const handleSheetAnimationComplete = React.useCallback(({
683
- open
684
- }) => {
685
- if (!open) {
686
- setIsAdaptFullyHidden(true);
687
- }
688
- }, []);
689
- return /* @__PURE__ */(0, import_jsx_runtime.jsx)(import_controller.SheetController, {
690
- onOpenChange: val => {
691
- if (isAdapted) {
692
- props.onOpenChange?.(val);
693
- }
694
- },
695
- onAnimationComplete: handleSheetAnimationComplete,
696
- open: context.open,
697
- hidden: !isAdapted,
698
- children: /* @__PURE__ */(0, import_jsx_runtime.jsx)(DialogAdaptHiddenContext.Provider, {
699
- value: isAdaptFullyHidden,
700
- children: props.children
701
- })
702
- });
703
- };