@mirohq/design-system-dialog 0.1.0-dialog.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/dist/main.js ADDED
@@ -0,0 +1,691 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+ var designSystemUseId = require('@mirohq/design-system-use-id');
6
+ var designSystemUseBrowserNavigation = require('@mirohq/design-system-use-browser-navigation');
7
+ var designSystemUseOverlay = require('@mirohq/design-system-use-overlay');
8
+ var designSystemPrimitive = require('@mirohq/design-system-primitive');
9
+ var designSystemUtils = require('@mirohq/design-system-utils');
10
+ var reactDom = require('react-dom');
11
+ var designSystemUseFocusTrap = require('@mirohq/design-system-use-focus-trap');
12
+ var designSystemUseScrollLock = require('@mirohq/design-system-use-scroll-lock');
13
+ var designSystemStitches = require('@mirohq/design-system-stitches');
14
+
15
+ const DialogContext = react.createContext(
16
+ void 0
17
+ );
18
+ const useDialogContext = () => {
19
+ const context = react.useContext(DialogContext);
20
+ if (context === void 0) {
21
+ throw new Error("Dialog parts must be rendered within a <Dialog> root");
22
+ }
23
+ return context;
24
+ };
25
+
26
+ const Root = ({ children, ...options }) => {
27
+ var _a, _b, _c, _d, _e;
28
+ const depth = ((_b = (_a = react.useContext(DialogContext)) == null ? void 0 : _a.depth) != null ? _b : 0) + 1;
29
+ const generatedId = designSystemUseId.useId();
30
+ const id = (_c = options.id) != null ? _c : generatedId;
31
+ const role = (_d = options.role) != null ? _d : "dialog";
32
+ const modal = (_e = options.modal) != null ? _e : true;
33
+ const animated = options.animated === true;
34
+ const controlled = options.open !== void 0;
35
+ const [uncontrolledOpen, setUncontrolledOpen] = react.useState(
36
+ options.defaultOpen === true
37
+ );
38
+ const open = controlled ? options.open === true : uncontrolledOpen;
39
+ if (controlled && uncontrolledOpen !== open) setUncontrolledOpen(open);
40
+ const [exiting, setExiting] = react.useState(false);
41
+ const previousOpen = react.useRef(open);
42
+ if (previousOpen.current !== open) {
43
+ previousOpen.current = open;
44
+ if (open) {
45
+ if (exiting) setExiting(false);
46
+ } else if (animated) {
47
+ setExiting(true);
48
+ }
49
+ }
50
+ const state = open ? "open" : exiting ? "closing" : "closed";
51
+ const optionsRef = react.useRef(options);
52
+ optionsRef.current = options;
53
+ const reportedOpen = react.useRef(open);
54
+ const resolvedOpen = react.useRef(open);
55
+ react.useEffect(() => {
56
+ var _a2, _b2;
57
+ if (resolvedOpen.current === open) return;
58
+ resolvedOpen.current = open;
59
+ if (reportedOpen.current === open) return;
60
+ reportedOpen.current = open;
61
+ (_b2 = (_a2 = optionsRef.current).onOpenChange) == null ? void 0 : _b2.call(_a2, open);
62
+ });
63
+ const setOpen = (next) => {
64
+ var _a2, _b2;
65
+ if (open === next) return;
66
+ reportedOpen.current = next;
67
+ (_b2 = (_a2 = optionsRef.current).onOpenChange) == null ? void 0 : _b2.call(_a2, next);
68
+ if (!controlled) setUncontrolledOpen(next);
69
+ };
70
+ const onEscapeRef = react.useRef(() => {
71
+ });
72
+ onEscapeRef.current = (event) => {
73
+ var _a2, _b2;
74
+ if (!designSystemUseOverlay.isTopmostLayer(id)) return;
75
+ (_b2 = (_a2 = optionsRef.current).onEscapeKeyDown) == null ? void 0 : _b2.call(_a2, event);
76
+ if (event.defaultPrevented) return;
77
+ if (optionsRef.current.closeOnEscape === false) return;
78
+ setOpen(false);
79
+ };
80
+ react.useEffect(() => {
81
+ if (!open) return;
82
+ const onKeyDown = (event) => {
83
+ if (event.key === "Escape") onEscapeRef.current(event);
84
+ };
85
+ document.addEventListener("keydown", onKeyDown, true);
86
+ return () => document.removeEventListener("keydown", onKeyDown, true);
87
+ }, [open]);
88
+ const onBackRef = react.useRef(() => false);
89
+ onBackRef.current = () => {
90
+ var _a2, _b2;
91
+ const payload = {
92
+ defaultPrevented: false,
93
+ preventDefault() {
94
+ payload.defaultPrevented = true;
95
+ }
96
+ };
97
+ (_b2 = (_a2 = optionsRef.current).onBackNavigation) == null ? void 0 : _b2.call(_a2, payload);
98
+ if (payload.defaultPrevented === true) return false;
99
+ setOpen(false);
100
+ return !controlled;
101
+ };
102
+ const onForwardRef = react.useRef(() => false);
103
+ onForwardRef.current = () => {
104
+ var _a2, _b2;
105
+ const payload = {
106
+ defaultPrevented: false,
107
+ preventDefault() {
108
+ payload.defaultPrevented = true;
109
+ }
110
+ };
111
+ (_b2 = (_a2 = optionsRef.current).onForwardNavigation) == null ? void 0 : _b2.call(_a2, payload);
112
+ if (payload.defaultPrevented === true) return false;
113
+ if (optionsRef.current.closeOnBack !== true) return false;
114
+ setOpen(true);
115
+ return !controlled;
116
+ };
117
+ designSystemUseBrowserNavigation.useBrowserNavigation({
118
+ enabled: options.closeOnBack === true,
119
+ open,
120
+ onBack: () => onBackRef.current(),
121
+ onForward: () => onForwardRef.current(),
122
+ // The dialog's nesting depth is what a returning dialog recognizes its
123
+ // own spent entry by: the instance is new after a remount, but the
124
+ // position in the stack is the same.
125
+ claim: "dialog:".concat(depth)
126
+ });
127
+ const insidePressRef = react.useRef(false);
128
+ react.useEffect(() => {
129
+ if (!open) return;
130
+ const contentId = "".concat(id, "-content");
131
+ const onPointerDown = (event) => {
132
+ const content = document.getElementById(contentId);
133
+ insidePressRef.current = content !== null && event.target instanceof Node && content.contains(event.target);
134
+ };
135
+ document.addEventListener("pointerdown", onPointerDown, true);
136
+ return () => document.removeEventListener("pointerdown", onPointerDown, true);
137
+ }, [open, id]);
138
+ const interactOutside = (event) => {
139
+ var _a2, _b2;
140
+ if (insidePressRef.current) return;
141
+ (_a2 = options.onInteractOutside) == null ? void 0 : _a2.call(options, event);
142
+ if (event.defaultPrevented) return;
143
+ if (!((_b2 = options.closeOnInteractOutside) != null ? _b2 : role === "dialog")) return;
144
+ setOpen(false);
145
+ };
146
+ const interactOutsideRef = react.useRef(interactOutside);
147
+ interactOutsideRef.current = interactOutside;
148
+ const backdropRef = react.useRef(null);
149
+ const triggerRef = react.useRef(null);
150
+ const closeRef = react.useRef(null);
151
+ react.useEffect(() => {
152
+ if (!open || modal) return;
153
+ const contentId = "".concat(id, "-content");
154
+ const onClick = (event) => {
155
+ var _a2, _b2;
156
+ if (!designSystemUseOverlay.isTopmostLayer(id)) return;
157
+ if (!(event.target instanceof Node)) return;
158
+ if (((_a2 = document.getElementById(contentId)) == null ? void 0 : _a2.contains(event.target)) === true)
159
+ return;
160
+ if (((_b2 = triggerRef.current) == null ? void 0 : _b2.contains(event.target)) === true) return;
161
+ interactOutsideRef.current(event);
162
+ };
163
+ document.addEventListener("click", onClick);
164
+ return () => document.removeEventListener("click", onClick);
165
+ }, [open, modal, id]);
166
+ const [parts, setParts] = react.useState({
167
+ title: false,
168
+ description: false
169
+ });
170
+ return /* @__PURE__ */ jsxRuntime.jsx(
171
+ DialogContext.Provider,
172
+ {
173
+ value: {
174
+ state,
175
+ open,
176
+ mounted: state !== "closed",
177
+ modal,
178
+ role,
179
+ id,
180
+ ids: {
181
+ content: "".concat(id, "-content"),
182
+ title: "".concat(id, "-title"),
183
+ description: "".concat(id, "-description")
184
+ },
185
+ depth,
186
+ container: null,
187
+ backdropRef,
188
+ triggerRef,
189
+ closeRef,
190
+ parts,
191
+ setParts,
192
+ toggle: () => setOpen(!open),
193
+ close: () => setOpen(false),
194
+ interactOutside,
195
+ exitComplete: () => setExiting(false)
196
+ },
197
+ children
198
+ }
199
+ );
200
+ };
201
+
202
+ const Trigger$1 = react.forwardRef(
203
+ ({ asChild = false, ...props }, forwardedRef) => {
204
+ const { open, state, ids, toggle, triggerRef } = useDialogContext();
205
+ const consumer = designSystemUtils.composeHandlers(
206
+ { onClick: toggle },
207
+ asChild ? props : { type: "button", ...props }
208
+ );
209
+ return /* @__PURE__ */ jsxRuntime.jsx(
210
+ designSystemPrimitive.Primitive.button,
211
+ {
212
+ ...consumer,
213
+ "aria-haspopup": "dialog",
214
+ "aria-expanded": open,
215
+ "aria-controls": open ? ids.content : void 0,
216
+ "data-state": state,
217
+ asChild,
218
+ ref: designSystemUtils.mergeRefs([triggerRef, forwardedRef])
219
+ }
220
+ );
221
+ }
222
+ );
223
+
224
+ const Portal$1 = ({ children, container }) => {
225
+ const context = useDialogContext();
226
+ if (!context.mounted || typeof document === "undefined") return null;
227
+ return reactDom.createPortal(
228
+ /* @__PURE__ */ jsxRuntime.jsx(
229
+ DialogContext.Provider,
230
+ {
231
+ value: { ...context, container: container != null ? container : null },
232
+ children
233
+ }
234
+ ),
235
+ container != null ? container : document.body
236
+ );
237
+ };
238
+
239
+ const Backdrop$1 = react.forwardRef(
240
+ (props, forwardedRef) => {
241
+ const { modal, state, id, container, backdropRef, interactOutside } = useDialogContext();
242
+ if (!modal) return null;
243
+ const consumer = designSystemUtils.composeHandlers(
244
+ {
245
+ // Only the topmost dialog of a stack answers an outside press.
246
+ onClick: (event) => {
247
+ if (designSystemUseOverlay.isTopmostLayer(id)) interactOutside(event.nativeEvent);
248
+ }
249
+ },
250
+ props
251
+ );
252
+ return (
253
+ // role=presentation: the backdrop is a purely visual layer; its press
254
+ // is the pointer half of an outside dismissal, with Escape as the
255
+ // keyboard path (jsx-a11y's keyboard pairing doesn't apply).
256
+ /* @__PURE__ */ jsxRuntime.jsx(
257
+ "div",
258
+ {
259
+ role: "presentation",
260
+ ...consumer,
261
+ "data-state": state,
262
+ "data-scoped": container === null ? void 0 : "",
263
+ ref: designSystemUtils.mergeRefs([backdropRef, forwardedRef])
264
+ }
265
+ )
266
+ );
267
+ }
268
+ );
269
+
270
+ const Viewport = react.forwardRef(
271
+ ({ fullScreen, ...props }, forwardedRef) => {
272
+ const { state, id, modal, container, interactOutside } = useDialogContext();
273
+ const consumer = designSystemUtils.composeHandlers(
274
+ {
275
+ // Box presses bubble up here — only a press that started on the
276
+ // viewport itself is an outside interaction, and only the topmost
277
+ // dialog of a stack answers it.
278
+ onClick: (event) => {
279
+ if (event.target !== event.currentTarget) return;
280
+ if (!designSystemUseOverlay.isTopmostLayer(id)) return;
281
+ interactOutside(event.nativeEvent);
282
+ }
283
+ },
284
+ props
285
+ );
286
+ return (
287
+ // role=presentation: a purely presentational positioning wrapper — the
288
+ // press it answers is the pointer half of an outside dismissal, with
289
+ // Escape as the keyboard path.
290
+ /* @__PURE__ */ jsxRuntime.jsx(
291
+ "div",
292
+ {
293
+ role: "presentation",
294
+ ...consumer,
295
+ "data-state": state,
296
+ "data-scoped": container === null ? void 0 : "",
297
+ "data-modal": modal ? "" : void 0,
298
+ "data-full-screen": fullScreen === true ? "" : void 0,
299
+ ref: forwardedRef
300
+ }
301
+ )
302
+ );
303
+ }
304
+ );
305
+
306
+ const Content$1 = react.forwardRef(
307
+ ({ initialFocus, ...props }, forwardedRef) => {
308
+ const {
309
+ state,
310
+ open,
311
+ modal,
312
+ role,
313
+ id,
314
+ ids,
315
+ depth,
316
+ container,
317
+ backdropRef,
318
+ triggerRef,
319
+ closeRef,
320
+ parts,
321
+ exitComplete
322
+ } = useDialogContext();
323
+ const contentRef = react.useRef(null);
324
+ designSystemUseOverlay.useOverlay(contentRef, {
325
+ enabled: open,
326
+ id,
327
+ depth,
328
+ modal,
329
+ backdrop: () => backdropRef.current,
330
+ initialFocus,
331
+ // A pointer press opens without focusing the trigger (the DS Button
332
+ // suppresses mousedown's native focus), so the close would find only
333
+ // the body to restore to — fall back to the trigger, the invoker APG
334
+ // says focus returns to.
335
+ restoreFocus: () => triggerRef.current
336
+ });
337
+ designSystemUseOverlay.useOverlayExit(contentRef, {
338
+ exiting: !open,
339
+ boundary: container,
340
+ backdrop: () => backdropRef.current,
341
+ onExitComplete: exitComplete
342
+ });
343
+ designSystemUseScrollLock.useScrollLock(modal, container != null ? container : void 0);
344
+ designSystemUseFocusTrap.useFocusTrap(contentRef, {
345
+ // Only a modal dialog traps, and only while topmost — a nested dialog
346
+ // owns focus while open.
347
+ enabled: () => modal && designSystemUseOverlay.isTopmostLayer(id),
348
+ // The Close part is the cycle's last stop wherever it renders (SPEC).
349
+ last: () => closeRef.current
350
+ });
351
+ react.useEffect(() => {
352
+ if (!open) return;
353
+ const element = contentRef.current;
354
+ if (element === null) return;
355
+ if (parts.title || document.getElementById(ids.title) !== null) return;
356
+ if (element.hasAttribute("aria-label") || element.hasAttribute("aria-labelledby")) {
357
+ return;
358
+ }
359
+ console.warn(
360
+ "[Dialog] the dialog resolves no accessible name: render a <Dialog.Title>, or give Content an aria-label when it truly cannot have one."
361
+ );
362
+ }, [open, parts.title, ids.title]);
363
+ const labelling = {};
364
+ if (parts.title && props["aria-labelledby"] == null) {
365
+ labelling["aria-labelledby"] = ids.title;
366
+ }
367
+ if (parts.description && props["aria-describedby"] == null) {
368
+ labelling["aria-describedby"] = ids.description;
369
+ }
370
+ return (
371
+ // A neutral element with the role, not <dialog>: the window is the
372
+ // initial focus target, so it carries tabindex — which HTML forbids on
373
+ // <dialog> — and the native element only pays off via showModal(),
374
+ // which this contract deliberately doesn't use.
375
+ /* @__PURE__ */ jsxRuntime.jsx(
376
+ "div",
377
+ {
378
+ ...props,
379
+ ...labelling,
380
+ role,
381
+ id: ids.content,
382
+ "aria-modal": modal || void 0,
383
+ tabIndex: -1,
384
+ "data-state": state,
385
+ ref: designSystemUtils.mergeRefs([contentRef, forwardedRef])
386
+ }
387
+ )
388
+ );
389
+ }
390
+ );
391
+
392
+ const Title$1 = react.forwardRef(
393
+ ({ asChild = false, ...props }, forwardedRef) => {
394
+ const { ids, setParts } = useDialogContext();
395
+ react.useEffect(() => {
396
+ setParts((parts) => parts.title ? parts : { ...parts, title: true });
397
+ return () => setParts((parts) => parts.title ? { ...parts, title: false } : parts);
398
+ }, [setParts]);
399
+ return /* @__PURE__ */ jsxRuntime.jsx(
400
+ designSystemPrimitive.Primitive.h2,
401
+ {
402
+ ...props,
403
+ id: ids.title,
404
+ asChild,
405
+ ref: forwardedRef
406
+ }
407
+ );
408
+ }
409
+ );
410
+
411
+ const Description$1 = react.forwardRef(
412
+ ({ asChild = false, ...props }, forwardedRef) => {
413
+ const { ids, setParts } = useDialogContext();
414
+ react.useEffect(() => {
415
+ setParts(
416
+ (parts) => parts.description ? parts : { ...parts, description: true }
417
+ );
418
+ return () => setParts(
419
+ (parts) => parts.description ? { ...parts, description: false } : parts
420
+ );
421
+ }, [setParts]);
422
+ return /* @__PURE__ */ jsxRuntime.jsx(
423
+ designSystemPrimitive.Primitive.p,
424
+ {
425
+ ...props,
426
+ id: ids.description,
427
+ asChild,
428
+ ref: forwardedRef
429
+ }
430
+ );
431
+ }
432
+ );
433
+
434
+ const Close$1 = react.forwardRef(
435
+ ({ asChild = false, ...props }, forwardedRef) => {
436
+ const { close, closeRef } = useDialogContext();
437
+ const consumer = designSystemUtils.composeHandlers(
438
+ { onClick: close },
439
+ asChild ? props : { type: "button", ...props }
440
+ );
441
+ return /* @__PURE__ */ jsxRuntime.jsx(
442
+ designSystemPrimitive.Primitive.button,
443
+ {
444
+ ...consumer,
445
+ asChild,
446
+ ref: designSystemUtils.mergeRefs([closeRef, forwardedRef])
447
+ }
448
+ );
449
+ }
450
+ );
451
+
452
+ const useDialog = () => {
453
+ const context = useDialogContext();
454
+ return {
455
+ id: context.id,
456
+ isOpen: context.open,
457
+ state: context.state,
458
+ modal: context.modal,
459
+ // Idempotent: toggle() would close an already-open dialog.
460
+ open: () => {
461
+ if (!context.open) context.toggle();
462
+ },
463
+ close: context.close,
464
+ toggle: context.toggle
465
+ };
466
+ };
467
+
468
+ const ANIMATION_DURATION = "250ms";
469
+ const MOTION = "@media (prefers-reduced-motion: no-preference)";
470
+
471
+ const fadeIn = designSystemStitches.keyframes({
472
+ from: { opacity: 0 },
473
+ to: { opacity: 1 }
474
+ });
475
+ const fadeOut = designSystemStitches.keyframes({
476
+ from: { opacity: 1 },
477
+ to: { opacity: 0 }
478
+ });
479
+ const Backdrop = designSystemStitches.styled(Backdrop$1, {
480
+ position: "fixed",
481
+ inset: 0,
482
+ zIndex: "$dialog",
483
+ backgroundColor: "$background-alpha-neutrals-overlay",
484
+ // A scoped dialog (Portal container) pins to the container, not the page.
485
+ "&[data-scoped]": {
486
+ position: "absolute"
487
+ },
488
+ [MOTION]: {
489
+ animation: "".concat(fadeIn, " ").concat(ANIMATION_DURATION, " ease-out"),
490
+ // `forwards` holds the final frame until the unmount lands.
491
+ '&[data-state="closing"]': {
492
+ animation: "".concat(fadeOut, " ").concat(ANIMATION_DURATION, " ease-out forwards")
493
+ }
494
+ }
495
+ });
496
+
497
+ const Close = designSystemStitches.styled(Close$1, {
498
+ position: "absolute",
499
+ top: "$300",
500
+ right: "$300"
501
+ });
502
+
503
+ const Banner = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
504
+ margin: "-$500 -$500 0",
505
+ // The floor yields on short screens (text zoom, 400% reflow): the media
506
+ // must not eat the space the title and actions need.
507
+ minHeight: "min(300px, 40vh)",
508
+ borderTopLeftRadius: "$100",
509
+ borderTopRightRadius: "$100",
510
+ overflow: "hidden",
511
+ backgroundColor: "$background-primary-subtle",
512
+ // Media dropped in fills the slot with no hand-made styles.
513
+ "& > img, & > video": {
514
+ display: "block",
515
+ width: "100%",
516
+ height: "100%",
517
+ objectFit: "contain"
518
+ }
519
+ });
520
+ const Title = designSystemStitches.styled(Title$1, {
521
+ fontFamily: "$heading",
522
+ fontSize: "$300",
523
+ lineHeight: 1.35,
524
+ fontWeight: 400,
525
+ fontFeatureSettings: "'ss01'",
526
+ padding: "$400 $1200 $100 $500",
527
+ margin: "-$500 -$500 0",
528
+ // A banner before it already consumed the window's top inset, so the title
529
+ // must not escape it a second time.
530
+ ["".concat(Banner, " ~ &")]: {
531
+ marginTop: 0
532
+ }
533
+ });
534
+ const Description = designSystemStitches.styled(Description$1, {
535
+ fontFamily: "$body",
536
+ fontSize: "$200",
537
+ lineHeight: 1.5,
538
+ padding: "$200 $500",
539
+ margin: "0 -$500",
540
+ // As the last part, its own $200 plus the window's $500 would overshoot
541
+ // the $500 closing inset.
542
+ "&:last-child": {
543
+ marginBottom: "-$200"
544
+ }
545
+ });
546
+ const Actions = designSystemStitches.styled(designSystemPrimitive.Primitive.div, {
547
+ display: "flex",
548
+ gap: "$100",
549
+ // The window's inset supplies the $500 closing edge below the row.
550
+ padding: "$200 $500 0",
551
+ margin: "0 -$500"
552
+ });
553
+
554
+ const scaleIn = designSystemStitches.keyframes({
555
+ from: { opacity: 0, transform: "scale(0.8)" },
556
+ to: { opacity: 1, transform: "scale(1)" }
557
+ });
558
+ const scaleOut = designSystemStitches.keyframes({
559
+ from: { opacity: 1, transform: "scale(1)" },
560
+ to: { opacity: 0, transform: "scale(0.8)" }
561
+ });
562
+ const StyledViewport = designSystemStitches.styled(Viewport, {
563
+ position: "fixed",
564
+ inset: 0,
565
+ zIndex: "$dialog",
566
+ display: "flex",
567
+ overflow: "auto",
568
+ padding: "$300",
569
+ "&[data-scoped]": {
570
+ position: "absolute"
571
+ },
572
+ "&[data-full-screen]": {
573
+ padding: 0
574
+ },
575
+ "&:not([data-modal])": {
576
+ pointerEvents: "none"
577
+ }
578
+ });
579
+ const StyledContent = designSystemStitches.styled(Content$1, {
580
+ position: "relative",
581
+ margin: "auto",
582
+ boxSizing: "border-box",
583
+ width: "fit-content",
584
+ // The floors yield to the screen: WCAG 1.4.10 reflow requires the window
585
+ // to fit a 320px viewport (400% zoom), so neither bound may exceed the
586
+ // layer's width.
587
+ minWidth: "min(560px, 100%)",
588
+ maxWidth: "min(960px, 100%)",
589
+ backgroundColor: "$background-neutrals",
590
+ color: "$text-neutrals",
591
+ borderRadius: "$100",
592
+ boxShadow: "$elevation-300",
593
+ overflowWrap: "break-word",
594
+ outline: "none",
595
+ // The window stays interactive when its (non-modal) layer stops
596
+ // intercepting presses.
597
+ pointerEvents: "auto",
598
+ padding: "$500",
599
+ ["&:has(".concat(Title, ")")]: {
600
+ paddingTop: 0,
601
+ ["& ".concat(Banner)]: { marginTop: 0 },
602
+ ["& ".concat(Title)]: { marginTop: 0 }
603
+ },
604
+ ["&:has(".concat(Actions, ")")]: {
605
+ paddingBottom: 0,
606
+ ["& ".concat(Actions)]: { paddingBottom: "$500" },
607
+ ["& ".concat(Description, ":last-child")]: { marginBottom: 0, paddingBottom: "$500" }
608
+ },
609
+ [MOTION]: {
610
+ animation: "".concat(scaleIn, " ").concat(ANIMATION_DURATION, " ease-out"),
611
+ '&[data-state="closing"]': {
612
+ animation: "".concat(scaleOut, " ").concat(ANIMATION_DURATION, " ease-out forwards")
613
+ }
614
+ },
615
+ variants: {
616
+ scroll: {
617
+ viewport: {},
618
+ window: {
619
+ maxHeight: "100%",
620
+ overflow: "auto",
621
+ ["& ".concat(Title)]: {
622
+ position: "sticky",
623
+ top: 0,
624
+ backgroundColor: "$background-neutrals"
625
+ },
626
+ ["& ".concat(Close)]: {
627
+ position: "sticky",
628
+ top: "$300",
629
+ right: "auto",
630
+ float: "right",
631
+ marginRight: "-$200",
632
+ zIndex: 1
633
+ },
634
+ ["& ".concat(Banner)]: {
635
+ overflow: "visible"
636
+ }
637
+ }
638
+ },
639
+ flat: {
640
+ true: {
641
+ padding: 0,
642
+ overflow: "hidden",
643
+ ["& ".concat(Banner)]: { margin: 0 },
644
+ ["& ".concat(Title)]: { margin: 0 },
645
+ ["& ".concat(Description)]: { margin: 0 },
646
+ ["& ".concat(Description, ":last-child")]: { paddingBottom: "$500" },
647
+ ["& ".concat(Actions)]: { margin: 0, paddingBottom: "$500" }
648
+ }
649
+ },
650
+ fullScreen: {
651
+ true: {
652
+ width: "100%",
653
+ height: "100%",
654
+ minWidth: 0,
655
+ maxWidth: "none",
656
+ margin: 0,
657
+ borderRadius: 0
658
+ }
659
+ }
660
+ },
661
+ compoundVariants: [
662
+ {
663
+ flat: true,
664
+ scroll: "window",
665
+ css: { overflow: "auto" }
666
+ }
667
+ ],
668
+ defaultVariants: {
669
+ scroll: "viewport"
670
+ }
671
+ });
672
+ const Content = react.forwardRef(({ fullScreen, ...props }, forwardedRef) => /* @__PURE__ */ jsxRuntime.jsx(StyledViewport, { fullScreen: fullScreen === true, children: /* @__PURE__ */ jsxRuntime.jsx(StyledContent, { ...props, fullScreen, ref: forwardedRef }) }));
673
+
674
+ const Portal = Portal$1;
675
+
676
+ const Trigger = Trigger$1;
677
+
678
+ const Dialog = (props) => /* @__PURE__ */ jsxRuntime.jsx(Root, { ...props });
679
+ Dialog.Trigger = Trigger;
680
+ Dialog.Portal = Portal;
681
+ Dialog.Backdrop = Backdrop;
682
+ Dialog.Content = Content;
683
+ Dialog.Banner = Banner;
684
+ Dialog.Title = Title;
685
+ Dialog.Description = Description;
686
+ Dialog.Actions = Actions;
687
+ Dialog.Close = Close;
688
+
689
+ exports.Dialog = Dialog;
690
+ exports.useDialog = useDialog;
691
+ //# sourceMappingURL=main.js.map