@sproutsocial/seeds-react-modal 1.0.2 → 1.0.4

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.
Files changed (54) hide show
  1. package/.turbo/turbo-build.log +39 -19
  2. package/CHANGELOG.md +19 -0
  3. package/dist/Modal-ki8oiGbC.d.mts +69 -0
  4. package/dist/Modal-ki8oiGbC.d.ts +69 -0
  5. package/dist/ModalRail-OQ8DZ1vH.d.mts +178 -0
  6. package/dist/ModalRail-OQ8DZ1vH.d.ts +178 -0
  7. package/dist/esm/chunk-GKQRFPCX.js +642 -0
  8. package/dist/esm/chunk-GKQRFPCX.js.map +1 -0
  9. package/dist/esm/chunk-IYDY4OPB.js +237 -0
  10. package/dist/esm/chunk-IYDY4OPB.js.map +1 -0
  11. package/dist/esm/index.js +28 -235
  12. package/dist/esm/index.js.map +1 -1
  13. package/dist/esm/v1/index.js +9 -0
  14. package/dist/esm/v1/index.js.map +1 -0
  15. package/dist/esm/v2/index.js +39 -0
  16. package/dist/esm/v2/index.js.map +1 -0
  17. package/dist/index.d.mts +11 -66
  18. package/dist/index.d.ts +11 -66
  19. package/dist/index.js +658 -17
  20. package/dist/index.js.map +1 -1
  21. package/dist/v1/index.d.mts +11 -0
  22. package/dist/v1/index.d.ts +11 -0
  23. package/dist/v1/index.js +273 -0
  24. package/dist/v1/index.js.map +1 -0
  25. package/dist/v2/index.d.mts +26 -0
  26. package/dist/v2/index.d.ts +26 -0
  27. package/dist/v2/index.js +694 -0
  28. package/dist/v2/index.js.map +1 -0
  29. package/package.json +36 -16
  30. package/src/Modal.stories.tsx +1 -1
  31. package/src/__tests__/v1/Modal.test.tsx +134 -0
  32. package/src/__tests__/v1/Modal.typetest.tsx +209 -0
  33. package/src/index.ts +36 -3
  34. package/src/shared/constants.ts +28 -0
  35. package/src/v1/Modal.tsx +159 -0
  36. package/src/v1/ModalTypes.ts +67 -0
  37. package/src/v1/index.ts +14 -0
  38. package/src/v1/styles.tsx +141 -0
  39. package/src/v2/ModalV2.stories.tsx +282 -0
  40. package/src/v2/ModalV2.tsx +306 -0
  41. package/src/v2/ModalV2Styles.tsx +150 -0
  42. package/src/v2/ModalV2Types.ts +158 -0
  43. package/src/v2/components/ModalClose.tsx +29 -0
  44. package/src/v2/components/ModalCloseButton.tsx +100 -0
  45. package/src/v2/components/ModalContent.tsx +16 -0
  46. package/src/v2/components/ModalDescription.tsx +19 -0
  47. package/src/v2/components/ModalFooter.tsx +20 -0
  48. package/src/v2/components/ModalHeader.tsx +52 -0
  49. package/src/v2/components/ModalRail.tsx +121 -0
  50. package/src/v2/components/ModalTrigger.tsx +39 -0
  51. package/src/v2/components/index.ts +8 -0
  52. package/src/v2/index.ts +37 -0
  53. package/tsconfig.json +7 -1
  54. package/tsup.config.ts +5 -1
package/dist/index.js CHANGED
@@ -28,14 +28,24 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
28
28
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
29
 
30
30
  // src/index.ts
31
- var index_exports = {};
32
- __export(index_exports, {
33
- Modal: () => Modal_default,
34
- default: () => index_default
31
+ var src_exports = {};
32
+ __export(src_exports, {
33
+ Modal: () => v1_default,
34
+ ModalAction: () => ModalAction,
35
+ ModalClose: () => ModalClose,
36
+ ModalCloseButton: () => ModalCloseButton2,
37
+ ModalContent: () => ModalContent2,
38
+ ModalDescription: () => ModalDescription,
39
+ ModalFooter: () => ModalFooter2,
40
+ ModalHeader: () => ModalHeader2,
41
+ ModalRail: () => ModalRail,
42
+ ModalTrigger: () => ModalTrigger,
43
+ ModalV2: () => ModalV2_default,
44
+ default: () => src_default
35
45
  });
36
- module.exports = __toCommonJS(index_exports);
46
+ module.exports = __toCommonJS(src_exports);
37
47
 
38
- // src/Modal.tsx
48
+ // src/v1/Modal.tsx
39
49
  var React2 = __toESM(require("react"));
40
50
  var import_react2 = require("react");
41
51
  var import_seeds_react_box2 = __toESM(require("@sproutsocial/seeds-react-box"));
@@ -43,7 +53,7 @@ var import_seeds_react_button = __toESM(require("@sproutsocial/seeds-react-butto
43
53
  var import_seeds_react_icon = __toESM(require("@sproutsocial/seeds-react-icon"));
44
54
  var import_seeds_react_text = __toESM(require("@sproutsocial/seeds-react-text"));
45
55
 
46
- // src/styles.tsx
56
+ // src/v1/styles.tsx
47
57
  var import_react = require("react");
48
58
  var import_styled_components = __toESM(require("styled-components"));
49
59
  var import_styled_system = require("styled-system");
@@ -163,7 +173,7 @@ Content.displayName = "Content";
163
173
  Header.displayName = "Modal.Header";
164
174
  Footer.displayName = "Modal.Footer";
165
175
 
166
- // src/Modal.tsx
176
+ // src/v1/Modal.tsx
167
177
  var import_jsx_runtime2 = require("react/jsx-runtime");
168
178
  var ModalContext = React2.createContext({});
169
179
  var ModalHeader = (props) => {
@@ -207,8 +217,8 @@ var Modal = (props) => {
207
217
  label,
208
218
  onClose,
209
219
  closeButtonLabel,
210
- width: width2 = "800px",
211
- zIndex: zIndex2 = 6,
220
+ width: width3 = "800px",
221
+ zIndex: zIndex3 = 6,
212
222
  data = {},
213
223
  ...rest
214
224
  } = props;
@@ -229,8 +239,8 @@ var Modal = (props) => {
229
239
  shouldReturnFocusAfterClose: true,
230
240
  closeTimeoutMS: 200,
231
241
  role: "dialog",
232
- width: width2,
233
- zIndex: zIndex2,
242
+ width: width3,
243
+ zIndex: zIndex3,
234
244
  data: {
235
245
  "qa-modal": "",
236
246
  "qa-modal-isopen": isOpen,
@@ -264,14 +274,645 @@ Modal.Content = ModalContent;
264
274
  Modal.CloseButton = ModalCloseButton;
265
275
  var Modal_default = Modal;
266
276
 
267
- // src/ModalTypes.ts
268
- var React3 = require("react");
269
- var import_react_modal2 = require("react-modal");
277
+ // src/v1/index.ts
278
+ var v1_default = Modal_default;
279
+
280
+ // src/v2/ModalV2.tsx
281
+ var React12 = __toESM(require("react"));
282
+ var Dialog8 = __toESM(require("@radix-ui/react-dialog"));
283
+
284
+ // src/v2/ModalV2Styles.tsx
285
+ var import_react3 = require("react");
286
+ var import_styled_components2 = __toESM(require("styled-components"));
287
+ var import_styled_system2 = require("styled-system");
288
+ var Dialog = __toESM(require("@radix-ui/react-dialog"));
289
+ var import_seeds_react_system_props2 = require("@sproutsocial/seeds-react-system-props");
290
+ var import_seeds_react_box3 = __toESM(require("@sproutsocial/seeds-react-box"));
291
+
292
+ // src/shared/constants.ts
293
+ var DEFAULT_MODAL_Z_INDEX = 6;
294
+ var DEFAULT_OVERLAY_Z_INDEX_OFFSET = -1;
295
+ var DEFAULT_MODAL_WIDTH = "600px";
296
+ var DEFAULT_MODAL_BG = "container.background.base";
297
+ var BODY_PADDING2 = "64px";
298
+ var MODAL_SIZE_PRESETS = {
299
+ small: "400px",
300
+ medium: "600px",
301
+ large: "800px",
302
+ full: "90vw"
303
+ };
304
+ var MODAL_PRIORITY_Z_INDEX = {
305
+ low: 100,
306
+ medium: 1e3,
307
+ high: 2e3
308
+ };
309
+
310
+ // src/v2/ModalV2Styles.tsx
311
+ var StyledOverlay = (0, import_styled_components2.default)(Dialog.Overlay)`
312
+ position: fixed;
313
+ top: 0px;
314
+ left: 0px;
315
+ right: 0px;
316
+ bottom: 0px;
317
+ background-color: ${(props) => props.theme.colors.overlay.background.base};
318
+ opacity: 0;
319
+ will-change: opacity;
320
+ transition: opacity ${(props) => props.theme.duration.medium}
321
+ ${(props) => props.theme.easing.ease_inout};
322
+ z-index: ${(props) => props.zIndex ? props.zIndex + DEFAULT_OVERLAY_Z_INDEX_OFFSET : 999};
323
+
324
+ ${import_styled_system2.zIndex}
325
+
326
+ &[data-state="open"] {
327
+ opacity: 1;
328
+ }
329
+ &[data-state="closed"] {
330
+ opacity: 0;
331
+ }
332
+ `;
333
+ var StyledContent = (0, import_styled_components2.default)(Dialog.Content)`
334
+ position: fixed;
335
+ ${(props) => props.draggable ? `
336
+ top: 50%;
337
+ left: 50%;
338
+ transform: translate(-50%, -50%);
339
+ ` : `
340
+ top: 50%;
341
+ left: 50%;
342
+ transform: translate(-50%, -50%);
343
+ `}
344
+ display: flex;
345
+ flex-direction: column;
346
+ border-radius: ${(props) => props.theme.radii[600]};
347
+ box-shadow: ${(props) => props.theme.shadows.medium};
348
+ filter: blur(0);
349
+ color: ${(props) => props.theme.colors.text.body};
350
+ outline: none;
351
+ max-width: calc(100vw - ${BODY_PADDING2});
352
+ max-height: calc(100vh - ${BODY_PADDING2});
353
+ z-index: ${(props) => props.zIndex || 1e3};
354
+
355
+ /* Draggable styling */
356
+ ${(props) => props.draggable && `
357
+ cursor: ${props.isDragging ? "grabbing" : "grab"};
358
+ user-select: none;
359
+ `}
360
+
361
+ @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
362
+ height: calc(100vh - ${BODY_PADDING2});
363
+ }
364
+
365
+ ${import_styled_system2.width}
366
+ ${import_seeds_react_system_props2.COMMON}
367
+
368
+ /* Enhanced Radix Dialog animations */
369
+ opacity: 0;
370
+ ${(props) => !props.draggable ? `
371
+ transform: translate(-50%, -50%) scale(0.95);
372
+ transition: opacity ${props.theme.duration.medium} ${props.theme.easing.ease_inout},
373
+ transform ${props.theme.duration.medium} ${props.theme.easing.ease_inout};
374
+ ` : `
375
+ transition: opacity ${props.theme.duration.medium} ${props.theme.easing.ease_inout};
376
+ `}
377
+
378
+ &[data-state="open"] {
379
+ opacity: 1;
380
+ ${(props) => !props.draggable ? `transform: translate(-50%, -50%) scale(1);` : ``}
381
+ }
382
+ &[data-state="closed"] {
383
+ opacity: 0;
384
+ ${(props) => !props.draggable ? `transform: translate(-50%, -50%) scale(0.95);` : ``}
385
+ }
386
+ `;
387
+ var Content3 = (0, import_styled_components2.default)(import_seeds_react_box3.default)`
388
+ font-family: ${(props) => props.theme.fontFamily};
389
+ min-height: 80px;
390
+ overflow-y: auto;
391
+ flex: 1 1 auto;
392
+ padding: 0 ${(props) => props.theme.space[300]}
393
+ ${(props) => props.theme.space[300]} ${(props) => props.theme.space[300]};
394
+ @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
395
+ flex-basis: 100%;
396
+ }
397
+ `;
398
+ var Header2 = (0, import_styled_components2.default)(import_seeds_react_box3.default)`
399
+ font-family: ${(props) => props.theme.fontFamily};
400
+ padding: ${(props) => props.theme.space[400]}
401
+ ${(props) => props.theme.space[300]};
402
+ display: flex;
403
+ align-items: center;
404
+ justify-content: space-between;
405
+ flex: 0 0 auto;
406
+ `;
407
+ var Footer2 = (0, import_styled_components2.default)(import_seeds_react_box3.default)`
408
+ flex: 0 0 auto;
409
+ font-family: ${(props) => props.theme.fontFamily};
410
+ padding: ${(props) => props.theme.space[400]}
411
+ ${(props) => props.theme.space[300]};
412
+ border-bottom-right-radius: ${(props) => props.theme.radii[500]};
413
+ border-bottom-left-radius: ${(props) => props.theme.radii[500]};
414
+ display: flex;
415
+ align-items: center;
416
+ justify-content: flex-end;
417
+ gap: ${(props) => props.theme.space[100]};
418
+ `;
419
+ StyledOverlay.displayName = "ModalOverlay";
420
+ StyledContent.displayName = "ModalContent";
421
+ Content3.displayName = "ModalContent";
422
+ Header2.displayName = "ModalHeader";
423
+ Footer2.displayName = "ModalFooter";
424
+
425
+ // src/v2/components/ModalHeader.tsx
426
+ var React5 = __toESM(require("react"));
427
+ var Dialog3 = __toESM(require("@radix-ui/react-dialog"));
428
+ var import_seeds_react_box4 = __toESM(require("@sproutsocial/seeds-react-box"));
429
+ var import_seeds_react_text2 = __toESM(require("@sproutsocial/seeds-react-text"));
430
+
431
+ // src/v2/components/ModalCloseButton.tsx
432
+ var React4 = __toESM(require("react"));
433
+ var Dialog2 = __toESM(require("@radix-ui/react-dialog"));
434
+ var import_styled_components3 = __toESM(require("styled-components"));
435
+ var import_seeds_react_icon2 = __toESM(require("@sproutsocial/seeds-react-icon"));
436
+ var import_jsx_runtime3 = require("react/jsx-runtime");
437
+ var CloseButtonWrapper = import_styled_components3.default.button`
438
+ width: ${(p) => p.size || 44}px;
439
+ height: ${(p) => p.size || 44}px;
440
+ display: inline-grid;
441
+ place-items: center;
442
+ border-radius: 8px;
443
+ border: none;
444
+ background: rgba(22, 32, 32, 0.56);
445
+ color: #ffffff;
446
+ cursor: pointer;
447
+ outline: none;
448
+ transition: all 0.2s ease;
449
+
450
+ ${(p) => p.position === "absolute" && `
451
+ position: absolute;
452
+ top: 0px;
453
+ ${p.side || "right"}: ${p.offset || -48}px;
454
+ z-index: 1;
455
+ `}
456
+
457
+ &:hover {
458
+ background: rgba(22, 32, 32, 0.7);
459
+ transform: translateY(-1px);
460
+ }
461
+
462
+ &:active {
463
+ transform: translateY(0);
464
+ }
465
+
466
+ &:focus-visible {
467
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #205bc3;
468
+ }
469
+
470
+ &:disabled {
471
+ opacity: 0.5;
472
+ cursor: not-allowed;
473
+ }
474
+ `;
475
+ var ModalCloseButton2 = (props) => {
476
+ const {
477
+ children,
478
+ onClick,
479
+ asChild,
480
+ closeButtonLabel = "Close modal",
481
+ size = 44,
482
+ position = "absolute",
483
+ side = "right",
484
+ offset = -48,
485
+ ...rest
486
+ } = props;
487
+ const handleClick = (e) => {
488
+ onClick?.(e);
489
+ };
490
+ if (asChild) {
491
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog2.Close, { asChild: true, children: React4.cloneElement(children, {
492
+ onClick: handleClick,
493
+ ...rest
494
+ }) });
495
+ }
496
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(Dialog2.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
497
+ CloseButtonWrapper,
498
+ {
499
+ onClick: handleClick,
500
+ size,
501
+ position,
502
+ side,
503
+ offset,
504
+ "aria-label": closeButtonLabel,
505
+ title: closeButtonLabel,
506
+ ...rest,
507
+ children: children || /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_seeds_react_icon2.default, { name: "x-outline", size: "small" })
508
+ }
509
+ ) });
510
+ };
511
+ ModalCloseButton2.displayName = "ModalCloseButton";
512
+
513
+ // src/v2/components/ModalHeader.tsx
514
+ var import_jsx_runtime4 = require("react/jsx-runtime");
515
+ var ModalHeader2 = (props) => {
516
+ const {
517
+ title,
518
+ subtitle,
519
+ children,
520
+ bordered,
521
+ titleProps = {},
522
+ subtitleProps = {},
523
+ showInlineClose,
524
+ ...rest
525
+ } = props;
526
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Header2, { ...rest, children: children ? children : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(React5.Fragment, { children: [
527
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_seeds_react_box4.default, { children: [
528
+ title && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog3.Title, { asChild: true, ...titleProps, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_seeds_react_text2.default.Headline, { children: title }) }),
529
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Dialog3.Description, { asChild: true, ...subtitleProps, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_seeds_react_text2.default, { as: "div", fontSize: 200, children: subtitle }) })
530
+ ] }),
531
+ showInlineClose && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_seeds_react_box4.default, { display: "flex", alignItems: "center", justifyContent: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ModalCloseButton2, { position: "relative", offset: 0 }) })
532
+ ] }) });
533
+ };
534
+ ModalHeader2.displayName = "ModalHeader";
535
+
536
+ // src/v2/components/ModalFooter.tsx
537
+ var React6 = require("react");
538
+ var import_jsx_runtime5 = require("react/jsx-runtime");
539
+ var ModalFooter2 = (props) => {
540
+ const { bg = DEFAULT_MODAL_BG, children, ...rest } = props;
541
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
542
+ Footer2,
543
+ {
544
+ bg,
545
+ borderTop: 500,
546
+ borderColor: "container.border.base",
547
+ ...rest,
548
+ children
549
+ }
550
+ );
551
+ };
552
+ ModalFooter2.displayName = "ModalFooter";
553
+
554
+ // src/v2/components/ModalContent.tsx
555
+ var React7 = __toESM(require("react"));
556
+ var import_jsx_runtime6 = require("react/jsx-runtime");
557
+ var ModalContent2 = React7.forwardRef(({ children, ...rest }, ref) => {
558
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Content3, { "data-qa-modal": true, ref, ...rest, children });
559
+ });
560
+ ModalContent2.displayName = "ModalContent";
561
+
562
+ // src/v2/components/ModalDescription.tsx
563
+ var React8 = __toESM(require("react"));
564
+ var Dialog4 = __toESM(require("@radix-ui/react-dialog"));
565
+ var import_seeds_react_box5 = __toESM(require("@sproutsocial/seeds-react-box"));
566
+ var import_jsx_runtime7 = require("react/jsx-runtime");
567
+ var ModalDescription = React8.forwardRef(({ children, descriptionProps = {}, ...rest }, ref) => {
568
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Dialog4.Description, { asChild: true, ...descriptionProps, children: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_seeds_react_box5.default, { ref, ...rest, children }) });
569
+ });
570
+ ModalDescription.displayName = "ModalDescription";
571
+
572
+ // src/v2/components/ModalTrigger.tsx
573
+ var React9 = __toESM(require("react"));
574
+ var Dialog5 = __toESM(require("@radix-ui/react-dialog"));
575
+ var import_seeds_react_button2 = __toESM(require("@sproutsocial/seeds-react-button"));
576
+ var import_jsx_runtime8 = require("react/jsx-runtime");
577
+ var ModalTrigger = (props) => {
578
+ const { children, onClick, asChild, ...rest } = props;
579
+ const handleClick = (e) => {
580
+ onClick?.(e);
581
+ };
582
+ if (asChild) {
583
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dialog5.Trigger, { asChild: true, children: React9.cloneElement(children, {
584
+ onClick: handleClick,
585
+ ...rest
586
+ }) });
587
+ }
588
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dialog5.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_seeds_react_button2.default, { onClick: handleClick, ...rest, children }) });
589
+ };
590
+ ModalTrigger.displayName = "ModalTrigger";
591
+
592
+ // src/v2/components/ModalClose.tsx
593
+ var React10 = require("react");
594
+ var Dialog6 = __toESM(require("@radix-ui/react-dialog"));
595
+ var import_jsx_runtime9 = require("react/jsx-runtime");
596
+ var ModalClose = (props) => {
597
+ const { children, onClick, asChild = false, ...rest } = props;
598
+ const handleClick = (e) => {
599
+ onClick?.(e);
600
+ };
601
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Dialog6.Close, { asChild, onClick: handleClick, ...rest, children });
602
+ };
603
+ ModalClose.displayName = "ModalClose";
604
+
605
+ // src/v2/components/ModalRail.tsx
606
+ var React11 = __toESM(require("react"));
607
+ var Dialog7 = __toESM(require("@radix-ui/react-dialog"));
608
+ var import_styled_components4 = __toESM(require("styled-components"));
609
+ var import_seeds_react_icon3 = __toESM(require("@sproutsocial/seeds-react-icon"));
610
+ var import_jsx_runtime10 = require("react/jsx-runtime");
611
+ var Rail = import_styled_components4.default.div`
612
+ position: absolute;
613
+ top: ${(p) => p.offset}px;
614
+ ${(p) => p.side === "right" ? `right: calc(-1 * (${p.size}px + ${p.offset}px));` : `left: calc(-1 * (${p.size}px + ${p.offset}px));`}
615
+ display: grid;
616
+ grid-auto-flow: row;
617
+ gap: ${(p) => p.gap}px;
618
+ z-index: 1;
619
+
620
+ @media (max-width: ${(p) => p.collapseAt}px) {
621
+ ${(p) => p.side === "right" ? `right: ${p.offset}px;` : `left: ${p.offset}px;`}
622
+ }
623
+ `;
624
+ var RailBtn = import_styled_components4.default.button`
625
+ width: ${(p) => p.size}px;
626
+ height: ${(p) => p.size}px;
627
+ display: inline-grid;
628
+ place-items: center;
629
+ border-radius: 8px;
630
+ border: none;
631
+ background: rgba(22, 32, 32, 0.56);
632
+ color: #ffffff;
633
+ cursor: pointer;
634
+ outline: none;
635
+ transition: all 0.2s ease;
636
+
637
+ &:hover {
638
+ background: rgba(22, 32, 32, 0.7);
639
+ transform: translateY(-1px);
640
+ }
641
+
642
+ &:active {
643
+ transform: translateY(0);
644
+ }
645
+
646
+ &:focus-visible {
647
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #205bc3;
648
+ }
649
+
650
+ &:disabled {
651
+ opacity: 0.5;
652
+ cursor: not-allowed;
653
+ }
654
+ `;
655
+ var ModalRail = ({
656
+ side = "right",
657
+ offset = 12,
658
+ gap = 12,
659
+ size = 44,
660
+ collapseAt = 640,
661
+ children
662
+ }) => {
663
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
664
+ Rail,
665
+ {
666
+ "data-slot": "modal-rail",
667
+ side,
668
+ offset,
669
+ gap,
670
+ size,
671
+ collapseAt,
672
+ "aria-label": "Modal quick actions",
673
+ children: React11.Children.map(
674
+ children,
675
+ (child) => React11.isValidElement(child) ? React11.cloneElement(child, { size }) : child
676
+ )
677
+ }
678
+ );
679
+ };
680
+ var ModalAction = ({
681
+ "aria-label": ariaLabel,
682
+ iconName,
683
+ disabled,
684
+ size = 44,
685
+ actionType,
686
+ onClick,
687
+ ...rest
688
+ }) => {
689
+ const Btn = /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
690
+ RailBtn,
691
+ {
692
+ size,
693
+ "aria-label": ariaLabel,
694
+ title: ariaLabel,
695
+ disabled,
696
+ ...rest,
697
+ children: iconName ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_seeds_react_icon3.default, { name: iconName, size: "small" }) : ariaLabel
698
+ }
699
+ );
700
+ return actionType === "close" ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Dialog7.Close, { asChild: true, children: Btn }) : React11.cloneElement(Btn, { onClick });
701
+ };
702
+
703
+ // src/v2/ModalV2.tsx
704
+ var import_jsx_runtime11 = require("react/jsx-runtime");
705
+ var DraggableModalContent = ({
706
+ children,
707
+ computedWidth,
708
+ bg,
709
+ computedZIndex,
710
+ label,
711
+ dataAttributes,
712
+ draggable,
713
+ rest
714
+ }) => {
715
+ const [position, setPosition] = React12.useState({ x: 0, y: 0 });
716
+ const [isDragging, setIsDragging] = React12.useState(false);
717
+ const contentRef = React12.useRef(null);
718
+ const handleMouseDown = React12.useCallback(
719
+ (e) => {
720
+ if (!draggable) return;
721
+ const target = e.target;
722
+ if (target.tagName === "BUTTON" || target.tagName === "INPUT" || target.closest("button")) {
723
+ return;
724
+ }
725
+ e.preventDefault();
726
+ setIsDragging(true);
727
+ const rect = contentRef.current?.getBoundingClientRect();
728
+ if (!rect) return;
729
+ const offsetX = e.clientX - rect.left;
730
+ const offsetY = e.clientY - rect.top;
731
+ const handleMouseMove = (e2) => {
732
+ e2.preventDefault();
733
+ const newX = e2.clientX - offsetX;
734
+ const newY = e2.clientY - offsetY;
735
+ const modalWidth = rect.width;
736
+ const modalHeight = rect.height;
737
+ const maxX = window.innerWidth - modalWidth;
738
+ const minX = 0;
739
+ const maxY = window.innerHeight - modalHeight;
740
+ const minY = 0;
741
+ const constrainedX = Math.max(minX, Math.min(maxX, newX));
742
+ const constrainedY = Math.max(minY, Math.min(maxY, newY));
743
+ const centerX = window.innerWidth / 2 - modalWidth / 2;
744
+ const centerY = window.innerHeight / 2 - modalHeight / 2;
745
+ setPosition({
746
+ x: constrainedX - centerX,
747
+ y: constrainedY - centerY
748
+ });
749
+ };
750
+ const handleMouseUp = () => {
751
+ setIsDragging(false);
752
+ document.removeEventListener("mousemove", handleMouseMove);
753
+ document.removeEventListener("mouseup", handleMouseUp);
754
+ };
755
+ document.addEventListener("mousemove", handleMouseMove);
756
+ document.addEventListener("mouseup", handleMouseUp);
757
+ },
758
+ [draggable]
759
+ );
760
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
761
+ StyledContent,
762
+ {
763
+ ref: contentRef,
764
+ width: computedWidth,
765
+ bg,
766
+ zIndex: computedZIndex,
767
+ "aria-label": label,
768
+ draggable,
769
+ isDragging,
770
+ onMouseDown: handleMouseDown,
771
+ style: draggable ? {
772
+ transform: `translate(calc(-50% + ${position.x}px), calc(-50% + ${position.y}px))`,
773
+ transition: isDragging ? "none" : void 0
774
+ } : void 0,
775
+ ...dataAttributes,
776
+ ...rest,
777
+ children
778
+ }
779
+ );
780
+ };
781
+ var Modal2 = (props) => {
782
+ const {
783
+ children,
784
+ modalTrigger,
785
+ draggable = false,
786
+ open,
787
+ defaultOpen,
788
+ onOpenChange,
789
+ "aria-label": label,
790
+ title,
791
+ subtitle,
792
+ description,
793
+ size,
794
+ priority,
795
+ data = {},
796
+ bg = DEFAULT_MODAL_BG,
797
+ showOverlay = true,
798
+ actions,
799
+ railProps,
800
+ ...rest
801
+ } = props;
802
+ const handleOpenChange = React12.useCallback(
803
+ (newOpen) => {
804
+ onOpenChange?.(newOpen);
805
+ },
806
+ [onOpenChange]
807
+ );
808
+ const computedWidth = React12.useMemo(() => {
809
+ if (size) {
810
+ if (typeof size === "string" && size in MODAL_SIZE_PRESETS) {
811
+ return MODAL_SIZE_PRESETS[size];
812
+ }
813
+ return size;
814
+ }
815
+ return DEFAULT_MODAL_WIDTH;
816
+ }, [size]);
817
+ const computedZIndex = React12.useMemo(() => {
818
+ if (priority) {
819
+ return MODAL_PRIORITY_Z_INDEX[priority];
820
+ }
821
+ return DEFAULT_MODAL_Z_INDEX;
822
+ }, [priority]);
823
+ const dataAttributes = React12.useMemo(() => {
824
+ const attrs = {};
825
+ Object.entries(data).forEach(([key, value]) => {
826
+ attrs[`data-${key}`] = String(value);
827
+ });
828
+ attrs["data-qa-modal"] = "";
829
+ if (open !== void 0) {
830
+ attrs["data-qa-modal-open"] = String(open);
831
+ }
832
+ return attrs;
833
+ }, [data, open]);
834
+ const shouldRenderHeader = Boolean(title || subtitle);
835
+ const dialogRootProps = React12.useMemo(() => {
836
+ const props2 = {};
837
+ if (open !== void 0) {
838
+ props2.open = open;
839
+ } else if (defaultOpen !== void 0) {
840
+ props2.defaultOpen = defaultOpen;
841
+ } else {
842
+ props2.defaultOpen = false;
843
+ }
844
+ if (onOpenChange) {
845
+ props2.onOpenChange = handleOpenChange;
846
+ }
847
+ return props2;
848
+ }, [open, defaultOpen, handleOpenChange, onOpenChange]);
849
+ const triggers = [];
850
+ const content = [];
851
+ if (modalTrigger) {
852
+ triggers.push(
853
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Dialog8.Trigger, { asChild: true, children: modalTrigger }, "modal-trigger")
854
+ );
855
+ content.push(children);
856
+ } else {
857
+ React12.Children.forEach(children, (child) => {
858
+ if (React12.isValidElement(child) && child.type === ModalTrigger) {
859
+ triggers.push(child);
860
+ } else {
861
+ content.push(child);
862
+ }
863
+ });
864
+ }
865
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Dialog8.Root, { ...dialogRootProps, children: [
866
+ triggers,
867
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Dialog8.Portal, { children: [
868
+ showOverlay && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(StyledOverlay, { zIndex: computedZIndex }),
869
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
870
+ DraggableModalContent,
871
+ {
872
+ computedWidth,
873
+ bg,
874
+ computedZIndex,
875
+ label,
876
+ dataAttributes,
877
+ draggable,
878
+ rest,
879
+ children: [
880
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(ModalRail, { ...railProps, children: [
881
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
882
+ ModalAction,
883
+ {
884
+ actionType: "close",
885
+ "aria-label": "Close",
886
+ iconName: "x-outline"
887
+ }
888
+ ),
889
+ actions?.map((action, idx) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ModalAction, { ...action }, idx))
890
+ ] }),
891
+ shouldRenderHeader && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ModalHeader2, { title, subtitle }),
892
+ description && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(ModalDescription, { children: description }),
893
+ content
894
+ ]
895
+ }
896
+ )
897
+ ] })
898
+ ] });
899
+ };
900
+ var ModalV2_default = Modal2;
270
901
 
271
902
  // src/index.ts
272
- var index_default = Modal_default;
903
+ var src_default = v1_default;
273
904
  // Annotate the CommonJS export names for ESM import in node:
274
905
  0 && (module.exports = {
275
- Modal
906
+ Modal,
907
+ ModalAction,
908
+ ModalClose,
909
+ ModalCloseButton,
910
+ ModalContent,
911
+ ModalDescription,
912
+ ModalFooter,
913
+ ModalHeader,
914
+ ModalRail,
915
+ ModalTrigger,
916
+ ModalV2
276
917
  });
277
918
  //# sourceMappingURL=index.js.map