@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
@@ -0,0 +1,694 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/v2/index.ts
31
+ var v2_exports = {};
32
+ __export(v2_exports, {
33
+ BODY_PADDING: () => BODY_PADDING,
34
+ DEFAULT_MODAL_BG: () => DEFAULT_MODAL_BG,
35
+ DEFAULT_MODAL_WIDTH: () => DEFAULT_MODAL_WIDTH,
36
+ DEFAULT_MODAL_Z_INDEX: () => DEFAULT_MODAL_Z_INDEX,
37
+ DEFAULT_OVERLAY_Z_INDEX_OFFSET: () => DEFAULT_OVERLAY_Z_INDEX_OFFSET,
38
+ MODAL_PRIORITY_Z_INDEX: () => MODAL_PRIORITY_Z_INDEX,
39
+ MODAL_SIZE_PRESETS: () => MODAL_SIZE_PRESETS,
40
+ Modal: () => ModalV2_default,
41
+ ModalAction: () => ModalAction,
42
+ ModalClose: () => ModalClose,
43
+ ModalCloseButton: () => ModalCloseButton,
44
+ ModalContent: () => ModalContent,
45
+ ModalDescription: () => ModalDescription,
46
+ ModalFooter: () => ModalFooter,
47
+ ModalHeader: () => ModalHeader,
48
+ ModalRail: () => ModalRail,
49
+ ModalTrigger: () => ModalTrigger
50
+ });
51
+ module.exports = __toCommonJS(v2_exports);
52
+
53
+ // src/v2/ModalV2.tsx
54
+ var React10 = __toESM(require("react"));
55
+ var Dialog8 = __toESM(require("@radix-ui/react-dialog"));
56
+
57
+ // src/v2/ModalV2Styles.tsx
58
+ var import_react = require("react");
59
+ var import_styled_components = __toESM(require("styled-components"));
60
+ var import_styled_system = require("styled-system");
61
+ var Dialog = __toESM(require("@radix-ui/react-dialog"));
62
+ var import_seeds_react_system_props = require("@sproutsocial/seeds-react-system-props");
63
+ var import_seeds_react_box = __toESM(require("@sproutsocial/seeds-react-box"));
64
+
65
+ // src/shared/constants.ts
66
+ var DEFAULT_MODAL_Z_INDEX = 6;
67
+ var DEFAULT_OVERLAY_Z_INDEX_OFFSET = -1;
68
+ var DEFAULT_MODAL_WIDTH = "600px";
69
+ var DEFAULT_MODAL_BG = "container.background.base";
70
+ var BODY_PADDING = "64px";
71
+ var MODAL_SIZE_PRESETS = {
72
+ small: "400px",
73
+ medium: "600px",
74
+ large: "800px",
75
+ full: "90vw"
76
+ };
77
+ var MODAL_PRIORITY_Z_INDEX = {
78
+ low: 100,
79
+ medium: 1e3,
80
+ high: 2e3
81
+ };
82
+
83
+ // src/v2/ModalV2Styles.tsx
84
+ var StyledOverlay = (0, import_styled_components.default)(Dialog.Overlay)`
85
+ position: fixed;
86
+ top: 0px;
87
+ left: 0px;
88
+ right: 0px;
89
+ bottom: 0px;
90
+ background-color: ${(props) => props.theme.colors.overlay.background.base};
91
+ opacity: 0;
92
+ will-change: opacity;
93
+ transition: opacity ${(props) => props.theme.duration.medium}
94
+ ${(props) => props.theme.easing.ease_inout};
95
+ z-index: ${(props) => props.zIndex ? props.zIndex + DEFAULT_OVERLAY_Z_INDEX_OFFSET : 999};
96
+
97
+ ${import_styled_system.zIndex}
98
+
99
+ &[data-state="open"] {
100
+ opacity: 1;
101
+ }
102
+ &[data-state="closed"] {
103
+ opacity: 0;
104
+ }
105
+ `;
106
+ var StyledContent = (0, import_styled_components.default)(Dialog.Content)`
107
+ position: fixed;
108
+ ${(props) => props.draggable ? `
109
+ top: 50%;
110
+ left: 50%;
111
+ transform: translate(-50%, -50%);
112
+ ` : `
113
+ top: 50%;
114
+ left: 50%;
115
+ transform: translate(-50%, -50%);
116
+ `}
117
+ display: flex;
118
+ flex-direction: column;
119
+ border-radius: ${(props) => props.theme.radii[600]};
120
+ box-shadow: ${(props) => props.theme.shadows.medium};
121
+ filter: blur(0);
122
+ color: ${(props) => props.theme.colors.text.body};
123
+ outline: none;
124
+ max-width: calc(100vw - ${BODY_PADDING});
125
+ max-height: calc(100vh - ${BODY_PADDING});
126
+ z-index: ${(props) => props.zIndex || 1e3};
127
+
128
+ /* Draggable styling */
129
+ ${(props) => props.draggable && `
130
+ cursor: ${props.isDragging ? "grabbing" : "grab"};
131
+ user-select: none;
132
+ `}
133
+
134
+ @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
135
+ height: calc(100vh - ${BODY_PADDING});
136
+ }
137
+
138
+ ${import_styled_system.width}
139
+ ${import_seeds_react_system_props.COMMON}
140
+
141
+ /* Enhanced Radix Dialog animations */
142
+ opacity: 0;
143
+ ${(props) => !props.draggable ? `
144
+ transform: translate(-50%, -50%) scale(0.95);
145
+ transition: opacity ${props.theme.duration.medium} ${props.theme.easing.ease_inout},
146
+ transform ${props.theme.duration.medium} ${props.theme.easing.ease_inout};
147
+ ` : `
148
+ transition: opacity ${props.theme.duration.medium} ${props.theme.easing.ease_inout};
149
+ `}
150
+
151
+ &[data-state="open"] {
152
+ opacity: 1;
153
+ ${(props) => !props.draggable ? `transform: translate(-50%, -50%) scale(1);` : ``}
154
+ }
155
+ &[data-state="closed"] {
156
+ opacity: 0;
157
+ ${(props) => !props.draggable ? `transform: translate(-50%, -50%) scale(0.95);` : ``}
158
+ }
159
+ `;
160
+ var Content2 = (0, import_styled_components.default)(import_seeds_react_box.default)`
161
+ font-family: ${(props) => props.theme.fontFamily};
162
+ min-height: 80px;
163
+ overflow-y: auto;
164
+ flex: 1 1 auto;
165
+ padding: 0 ${(props) => props.theme.space[300]}
166
+ ${(props) => props.theme.space[300]} ${(props) => props.theme.space[300]};
167
+ @media screen and (-ms-high-contrast: active), (-ms-high-contrast: none) {
168
+ flex-basis: 100%;
169
+ }
170
+ `;
171
+ var Header = (0, import_styled_components.default)(import_seeds_react_box.default)`
172
+ font-family: ${(props) => props.theme.fontFamily};
173
+ padding: ${(props) => props.theme.space[400]}
174
+ ${(props) => props.theme.space[300]};
175
+ display: flex;
176
+ align-items: center;
177
+ justify-content: space-between;
178
+ flex: 0 0 auto;
179
+ `;
180
+ var Footer = (0, import_styled_components.default)(import_seeds_react_box.default)`
181
+ flex: 0 0 auto;
182
+ font-family: ${(props) => props.theme.fontFamily};
183
+ padding: ${(props) => props.theme.space[400]}
184
+ ${(props) => props.theme.space[300]};
185
+ border-bottom-right-radius: ${(props) => props.theme.radii[500]};
186
+ border-bottom-left-radius: ${(props) => props.theme.radii[500]};
187
+ display: flex;
188
+ align-items: center;
189
+ justify-content: flex-end;
190
+ gap: ${(props) => props.theme.space[100]};
191
+ `;
192
+ StyledOverlay.displayName = "ModalOverlay";
193
+ StyledContent.displayName = "ModalContent";
194
+ Content2.displayName = "ModalContent";
195
+ Header.displayName = "ModalHeader";
196
+ Footer.displayName = "ModalFooter";
197
+
198
+ // src/v2/components/ModalHeader.tsx
199
+ var React3 = __toESM(require("react"));
200
+ var Dialog3 = __toESM(require("@radix-ui/react-dialog"));
201
+ var import_seeds_react_box2 = __toESM(require("@sproutsocial/seeds-react-box"));
202
+ var import_seeds_react_text = __toESM(require("@sproutsocial/seeds-react-text"));
203
+
204
+ // src/v2/components/ModalCloseButton.tsx
205
+ var React2 = __toESM(require("react"));
206
+ var Dialog2 = __toESM(require("@radix-ui/react-dialog"));
207
+ var import_styled_components2 = __toESM(require("styled-components"));
208
+ var import_seeds_react_icon = __toESM(require("@sproutsocial/seeds-react-icon"));
209
+ var import_jsx_runtime = require("react/jsx-runtime");
210
+ var CloseButtonWrapper = import_styled_components2.default.button`
211
+ width: ${(p) => p.size || 44}px;
212
+ height: ${(p) => p.size || 44}px;
213
+ display: inline-grid;
214
+ place-items: center;
215
+ border-radius: 8px;
216
+ border: none;
217
+ background: rgba(22, 32, 32, 0.56);
218
+ color: #ffffff;
219
+ cursor: pointer;
220
+ outline: none;
221
+ transition: all 0.2s ease;
222
+
223
+ ${(p) => p.position === "absolute" && `
224
+ position: absolute;
225
+ top: 0px;
226
+ ${p.side || "right"}: ${p.offset || -48}px;
227
+ z-index: 1;
228
+ `}
229
+
230
+ &:hover {
231
+ background: rgba(22, 32, 32, 0.7);
232
+ transform: translateY(-1px);
233
+ }
234
+
235
+ &:active {
236
+ transform: translateY(0);
237
+ }
238
+
239
+ &:focus-visible {
240
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #205bc3;
241
+ }
242
+
243
+ &:disabled {
244
+ opacity: 0.5;
245
+ cursor: not-allowed;
246
+ }
247
+ `;
248
+ var ModalCloseButton = (props) => {
249
+ const {
250
+ children,
251
+ onClick,
252
+ asChild,
253
+ closeButtonLabel = "Close modal",
254
+ size = 44,
255
+ position = "absolute",
256
+ side = "right",
257
+ offset = -48,
258
+ ...rest
259
+ } = props;
260
+ const handleClick = (e) => {
261
+ onClick?.(e);
262
+ };
263
+ if (asChild) {
264
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog2.Close, { asChild: true, children: React2.cloneElement(children, {
265
+ onClick: handleClick,
266
+ ...rest
267
+ }) });
268
+ }
269
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(Dialog2.Close, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
270
+ CloseButtonWrapper,
271
+ {
272
+ onClick: handleClick,
273
+ size,
274
+ position,
275
+ side,
276
+ offset,
277
+ "aria-label": closeButtonLabel,
278
+ title: closeButtonLabel,
279
+ ...rest,
280
+ children: children || /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_seeds_react_icon.default, { name: "x-outline", size: "small" })
281
+ }
282
+ ) });
283
+ };
284
+ ModalCloseButton.displayName = "ModalCloseButton";
285
+
286
+ // src/v2/components/ModalHeader.tsx
287
+ var import_jsx_runtime2 = require("react/jsx-runtime");
288
+ var ModalHeader = (props) => {
289
+ const {
290
+ title,
291
+ subtitle,
292
+ children,
293
+ bordered,
294
+ titleProps = {},
295
+ subtitleProps = {},
296
+ showInlineClose,
297
+ ...rest
298
+ } = props;
299
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Header, { ...rest, children: children ? children : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(React3.Fragment, { children: [
300
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_seeds_react_box2.default, { children: [
301
+ title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Dialog3.Title, { asChild: true, ...titleProps, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_text.default.Headline, { children: title }) }),
302
+ subtitle && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Dialog3.Description, { asChild: true, ...subtitleProps, children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_text.default, { as: "div", fontSize: 200, children: subtitle }) })
303
+ ] }),
304
+ showInlineClose && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_seeds_react_box2.default, { display: "flex", alignItems: "center", justifyContent: "flex-end", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(ModalCloseButton, { position: "relative", offset: 0 }) })
305
+ ] }) });
306
+ };
307
+ ModalHeader.displayName = "ModalHeader";
308
+
309
+ // src/v2/components/ModalFooter.tsx
310
+ var React4 = require("react");
311
+ var import_jsx_runtime3 = require("react/jsx-runtime");
312
+ var ModalFooter = (props) => {
313
+ const { bg = DEFAULT_MODAL_BG, children, ...rest } = props;
314
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
315
+ Footer,
316
+ {
317
+ bg,
318
+ borderTop: 500,
319
+ borderColor: "container.border.base",
320
+ ...rest,
321
+ children
322
+ }
323
+ );
324
+ };
325
+ ModalFooter.displayName = "ModalFooter";
326
+
327
+ // src/v2/components/ModalContent.tsx
328
+ var React5 = __toESM(require("react"));
329
+ var import_jsx_runtime4 = require("react/jsx-runtime");
330
+ var ModalContent = React5.forwardRef(({ children, ...rest }, ref) => {
331
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(Content2, { "data-qa-modal": true, ref, ...rest, children });
332
+ });
333
+ ModalContent.displayName = "ModalContent";
334
+
335
+ // src/v2/components/ModalDescription.tsx
336
+ var React6 = __toESM(require("react"));
337
+ var Dialog4 = __toESM(require("@radix-ui/react-dialog"));
338
+ var import_seeds_react_box3 = __toESM(require("@sproutsocial/seeds-react-box"));
339
+ var import_jsx_runtime5 = require("react/jsx-runtime");
340
+ var ModalDescription = React6.forwardRef(({ children, descriptionProps = {}, ...rest }, ref) => {
341
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Dialog4.Description, { asChild: true, ...descriptionProps, children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_seeds_react_box3.default, { ref, ...rest, children }) });
342
+ });
343
+ ModalDescription.displayName = "ModalDescription";
344
+
345
+ // src/v2/components/ModalTrigger.tsx
346
+ var React7 = __toESM(require("react"));
347
+ var Dialog5 = __toESM(require("@radix-ui/react-dialog"));
348
+ var import_seeds_react_button = __toESM(require("@sproutsocial/seeds-react-button"));
349
+ var import_jsx_runtime6 = require("react/jsx-runtime");
350
+ var ModalTrigger = (props) => {
351
+ const { children, onClick, asChild, ...rest } = props;
352
+ const handleClick = (e) => {
353
+ onClick?.(e);
354
+ };
355
+ if (asChild) {
356
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog5.Trigger, { asChild: true, children: React7.cloneElement(children, {
357
+ onClick: handleClick,
358
+ ...rest
359
+ }) });
360
+ }
361
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Dialog5.Trigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_seeds_react_button.default, { onClick: handleClick, ...rest, children }) });
362
+ };
363
+ ModalTrigger.displayName = "ModalTrigger";
364
+
365
+ // src/v2/components/ModalClose.tsx
366
+ var React8 = require("react");
367
+ var Dialog6 = __toESM(require("@radix-ui/react-dialog"));
368
+ var import_jsx_runtime7 = require("react/jsx-runtime");
369
+ var ModalClose = (props) => {
370
+ const { children, onClick, asChild = false, ...rest } = props;
371
+ const handleClick = (e) => {
372
+ onClick?.(e);
373
+ };
374
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Dialog6.Close, { asChild, onClick: handleClick, ...rest, children });
375
+ };
376
+ ModalClose.displayName = "ModalClose";
377
+
378
+ // src/v2/components/ModalRail.tsx
379
+ var React9 = __toESM(require("react"));
380
+ var Dialog7 = __toESM(require("@radix-ui/react-dialog"));
381
+ var import_styled_components3 = __toESM(require("styled-components"));
382
+ var import_seeds_react_icon2 = __toESM(require("@sproutsocial/seeds-react-icon"));
383
+ var import_jsx_runtime8 = require("react/jsx-runtime");
384
+ var Rail = import_styled_components3.default.div`
385
+ position: absolute;
386
+ top: ${(p) => p.offset}px;
387
+ ${(p) => p.side === "right" ? `right: calc(-1 * (${p.size}px + ${p.offset}px));` : `left: calc(-1 * (${p.size}px + ${p.offset}px));`}
388
+ display: grid;
389
+ grid-auto-flow: row;
390
+ gap: ${(p) => p.gap}px;
391
+ z-index: 1;
392
+
393
+ @media (max-width: ${(p) => p.collapseAt}px) {
394
+ ${(p) => p.side === "right" ? `right: ${p.offset}px;` : `left: ${p.offset}px;`}
395
+ }
396
+ `;
397
+ var RailBtn = import_styled_components3.default.button`
398
+ width: ${(p) => p.size}px;
399
+ height: ${(p) => p.size}px;
400
+ display: inline-grid;
401
+ place-items: center;
402
+ border-radius: 8px;
403
+ border: none;
404
+ background: rgba(22, 32, 32, 0.56);
405
+ color: #ffffff;
406
+ cursor: pointer;
407
+ outline: none;
408
+ transition: all 0.2s ease;
409
+
410
+ &:hover {
411
+ background: rgba(22, 32, 32, 0.7);
412
+ transform: translateY(-1px);
413
+ }
414
+
415
+ &:active {
416
+ transform: translateY(0);
417
+ }
418
+
419
+ &:focus-visible {
420
+ box-shadow: 0 0 0 2px #ffffff, 0 0 0 4px #205bc3;
421
+ }
422
+
423
+ &:disabled {
424
+ opacity: 0.5;
425
+ cursor: not-allowed;
426
+ }
427
+ `;
428
+ var ModalRail = ({
429
+ side = "right",
430
+ offset = 12,
431
+ gap = 12,
432
+ size = 44,
433
+ collapseAt = 640,
434
+ children
435
+ }) => {
436
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
437
+ Rail,
438
+ {
439
+ "data-slot": "modal-rail",
440
+ side,
441
+ offset,
442
+ gap,
443
+ size,
444
+ collapseAt,
445
+ "aria-label": "Modal quick actions",
446
+ children: React9.Children.map(
447
+ children,
448
+ (child) => React9.isValidElement(child) ? React9.cloneElement(child, { size }) : child
449
+ )
450
+ }
451
+ );
452
+ };
453
+ var ModalAction = ({
454
+ "aria-label": ariaLabel,
455
+ iconName,
456
+ disabled,
457
+ size = 44,
458
+ actionType,
459
+ onClick,
460
+ ...rest
461
+ }) => {
462
+ const Btn = /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
463
+ RailBtn,
464
+ {
465
+ size,
466
+ "aria-label": ariaLabel,
467
+ title: ariaLabel,
468
+ disabled,
469
+ ...rest,
470
+ children: iconName ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_seeds_react_icon2.default, { name: iconName, size: "small" }) : ariaLabel
471
+ }
472
+ );
473
+ return actionType === "close" ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(Dialog7.Close, { asChild: true, children: Btn }) : React9.cloneElement(Btn, { onClick });
474
+ };
475
+
476
+ // src/v2/ModalV2.tsx
477
+ var import_jsx_runtime9 = require("react/jsx-runtime");
478
+ var DraggableModalContent = ({
479
+ children,
480
+ computedWidth,
481
+ bg,
482
+ computedZIndex,
483
+ label,
484
+ dataAttributes,
485
+ draggable,
486
+ rest
487
+ }) => {
488
+ const [position, setPosition] = React10.useState({ x: 0, y: 0 });
489
+ const [isDragging, setIsDragging] = React10.useState(false);
490
+ const contentRef = React10.useRef(null);
491
+ const handleMouseDown = React10.useCallback(
492
+ (e) => {
493
+ if (!draggable) return;
494
+ const target = e.target;
495
+ if (target.tagName === "BUTTON" || target.tagName === "INPUT" || target.closest("button")) {
496
+ return;
497
+ }
498
+ e.preventDefault();
499
+ setIsDragging(true);
500
+ const rect = contentRef.current?.getBoundingClientRect();
501
+ if (!rect) return;
502
+ const offsetX = e.clientX - rect.left;
503
+ const offsetY = e.clientY - rect.top;
504
+ const handleMouseMove = (e2) => {
505
+ e2.preventDefault();
506
+ const newX = e2.clientX - offsetX;
507
+ const newY = e2.clientY - offsetY;
508
+ const modalWidth = rect.width;
509
+ const modalHeight = rect.height;
510
+ const maxX = window.innerWidth - modalWidth;
511
+ const minX = 0;
512
+ const maxY = window.innerHeight - modalHeight;
513
+ const minY = 0;
514
+ const constrainedX = Math.max(minX, Math.min(maxX, newX));
515
+ const constrainedY = Math.max(minY, Math.min(maxY, newY));
516
+ const centerX = window.innerWidth / 2 - modalWidth / 2;
517
+ const centerY = window.innerHeight / 2 - modalHeight / 2;
518
+ setPosition({
519
+ x: constrainedX - centerX,
520
+ y: constrainedY - centerY
521
+ });
522
+ };
523
+ const handleMouseUp = () => {
524
+ setIsDragging(false);
525
+ document.removeEventListener("mousemove", handleMouseMove);
526
+ document.removeEventListener("mouseup", handleMouseUp);
527
+ };
528
+ document.addEventListener("mousemove", handleMouseMove);
529
+ document.addEventListener("mouseup", handleMouseUp);
530
+ },
531
+ [draggable]
532
+ );
533
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
534
+ StyledContent,
535
+ {
536
+ ref: contentRef,
537
+ width: computedWidth,
538
+ bg,
539
+ zIndex: computedZIndex,
540
+ "aria-label": label,
541
+ draggable,
542
+ isDragging,
543
+ onMouseDown: handleMouseDown,
544
+ style: draggable ? {
545
+ transform: `translate(calc(-50% + ${position.x}px), calc(-50% + ${position.y}px))`,
546
+ transition: isDragging ? "none" : void 0
547
+ } : void 0,
548
+ ...dataAttributes,
549
+ ...rest,
550
+ children
551
+ }
552
+ );
553
+ };
554
+ var Modal = (props) => {
555
+ const {
556
+ children,
557
+ modalTrigger,
558
+ draggable = false,
559
+ open,
560
+ defaultOpen,
561
+ onOpenChange,
562
+ "aria-label": label,
563
+ title,
564
+ subtitle,
565
+ description,
566
+ size,
567
+ priority,
568
+ data = {},
569
+ bg = DEFAULT_MODAL_BG,
570
+ showOverlay = true,
571
+ actions,
572
+ railProps,
573
+ ...rest
574
+ } = props;
575
+ const handleOpenChange = React10.useCallback(
576
+ (newOpen) => {
577
+ onOpenChange?.(newOpen);
578
+ },
579
+ [onOpenChange]
580
+ );
581
+ const computedWidth = React10.useMemo(() => {
582
+ if (size) {
583
+ if (typeof size === "string" && size in MODAL_SIZE_PRESETS) {
584
+ return MODAL_SIZE_PRESETS[size];
585
+ }
586
+ return size;
587
+ }
588
+ return DEFAULT_MODAL_WIDTH;
589
+ }, [size]);
590
+ const computedZIndex = React10.useMemo(() => {
591
+ if (priority) {
592
+ return MODAL_PRIORITY_Z_INDEX[priority];
593
+ }
594
+ return DEFAULT_MODAL_Z_INDEX;
595
+ }, [priority]);
596
+ const dataAttributes = React10.useMemo(() => {
597
+ const attrs = {};
598
+ Object.entries(data).forEach(([key, value]) => {
599
+ attrs[`data-${key}`] = String(value);
600
+ });
601
+ attrs["data-qa-modal"] = "";
602
+ if (open !== void 0) {
603
+ attrs["data-qa-modal-open"] = String(open);
604
+ }
605
+ return attrs;
606
+ }, [data, open]);
607
+ const shouldRenderHeader = Boolean(title || subtitle);
608
+ const dialogRootProps = React10.useMemo(() => {
609
+ const props2 = {};
610
+ if (open !== void 0) {
611
+ props2.open = open;
612
+ } else if (defaultOpen !== void 0) {
613
+ props2.defaultOpen = defaultOpen;
614
+ } else {
615
+ props2.defaultOpen = false;
616
+ }
617
+ if (onOpenChange) {
618
+ props2.onOpenChange = handleOpenChange;
619
+ }
620
+ return props2;
621
+ }, [open, defaultOpen, handleOpenChange, onOpenChange]);
622
+ const triggers = [];
623
+ const content = [];
624
+ if (modalTrigger) {
625
+ triggers.push(
626
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(Dialog8.Trigger, { asChild: true, children: modalTrigger }, "modal-trigger")
627
+ );
628
+ content.push(children);
629
+ } else {
630
+ React10.Children.forEach(children, (child) => {
631
+ if (React10.isValidElement(child) && child.type === ModalTrigger) {
632
+ triggers.push(child);
633
+ } else {
634
+ content.push(child);
635
+ }
636
+ });
637
+ }
638
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Dialog8.Root, { ...dialogRootProps, children: [
639
+ triggers,
640
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(Dialog8.Portal, { children: [
641
+ showOverlay && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StyledOverlay, { zIndex: computedZIndex }),
642
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
643
+ DraggableModalContent,
644
+ {
645
+ computedWidth,
646
+ bg,
647
+ computedZIndex,
648
+ label,
649
+ dataAttributes,
650
+ draggable,
651
+ rest,
652
+ children: [
653
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(ModalRail, { ...railProps, children: [
654
+ /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
655
+ ModalAction,
656
+ {
657
+ actionType: "close",
658
+ "aria-label": "Close",
659
+ iconName: "x-outline"
660
+ }
661
+ ),
662
+ actions?.map((action, idx) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ModalAction, { ...action }, idx))
663
+ ] }),
664
+ shouldRenderHeader && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ModalHeader, { title, subtitle }),
665
+ description && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ModalDescription, { children: description }),
666
+ content
667
+ ]
668
+ }
669
+ )
670
+ ] })
671
+ ] });
672
+ };
673
+ var ModalV2_default = Modal;
674
+ // Annotate the CommonJS export names for ESM import in node:
675
+ 0 && (module.exports = {
676
+ BODY_PADDING,
677
+ DEFAULT_MODAL_BG,
678
+ DEFAULT_MODAL_WIDTH,
679
+ DEFAULT_MODAL_Z_INDEX,
680
+ DEFAULT_OVERLAY_Z_INDEX_OFFSET,
681
+ MODAL_PRIORITY_Z_INDEX,
682
+ MODAL_SIZE_PRESETS,
683
+ Modal,
684
+ ModalAction,
685
+ ModalClose,
686
+ ModalCloseButton,
687
+ ModalContent,
688
+ ModalDescription,
689
+ ModalFooter,
690
+ ModalHeader,
691
+ ModalRail,
692
+ ModalTrigger
693
+ });
694
+ //# sourceMappingURL=index.js.map