@edux-design/modals 0.1.2 → 0.1.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @edux-design/modals
2
2
 
3
+ ## 0.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - Rebuilt dist
8
+
3
9
  ## 0.1.2
4
10
 
5
11
  ### Patch Changes
package/dist/index.js CHANGED
@@ -47,20 +47,48 @@ module.exports = __toCommonJS(index_exports);
47
47
  var import_react = __toESM(require("react"));
48
48
  var DialogPrimitive = __toESM(require("@radix-ui/react-dialog"));
49
49
  var import_utils = require("@edux-design/utils");
50
+ var import_buttons = require("@edux-design/buttons");
51
+ var import_icons = require("@edux-design/icons");
50
52
  var MODAL_OVERLAY_Z_INDEX = 2147483645;
51
53
  var MODAL_CONTENT_Z_INDEX = 2147483646;
54
+ var ModalContext = (0, import_react.createContext)({ hasOnClose: false });
55
+ var MODAL_SECTION_PADDING_X = "px-16";
56
+ var MODAL_SECTION_PADDING_Y = "py-16";
57
+ var MODAL_SURFACE_CLASSES = [
58
+ "fixed left-1/2 top-1/2 max-h-[92vh] -translate-x-1/2 -translate-y-1/2",
59
+ "bg-bg-base text-fg-base shadow-xl outline-none rounded-md border-2 border-border-subtle",
60
+ "flex flex-col overflow-hidden",
61
+ "data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out"
62
+ ].join(" ");
63
+ var MODAL_HEADER_CLASSES = [
64
+ "flex justify-between gap-12",
65
+ MODAL_SECTION_PADDING_X,
66
+ MODAL_SECTION_PADDING_Y,
67
+ "border-b border-border-subtle"
68
+ ].join(" ");
69
+ var MODAL_HEADER_CONTENT_CLASSES = "flex min-w-0 flex-1 flex-col gap-4";
70
+ var MODAL_BODY_CLASSES = [
71
+ "flex-1 overflow-auto",
72
+ MODAL_SECTION_PADDING_X,
73
+ MODAL_SECTION_PADDING_Y
74
+ ].join(" ");
75
+ var MODAL_FOOTER_CLASSES = [
76
+ "flex items-center justify-end gap-8",
77
+ MODAL_SECTION_PADDING_X,
78
+ MODAL_SECTION_PADDING_Y,
79
+ "border-t border-border-subtle"
80
+ ].join(" ");
81
+ var MODAL_TITLE_CLASSES = "text-lg font-semibold text-fg-base";
82
+ var MODAL_DESCRIPTION_CLASSES = "text-sm text-fg-subtle";
83
+ var MODAL_CLOSE_LABEL = "Close modal";
84
+ var MODAL_SIZE_CLASSES = {
85
+ small: "w-[min(92vw,420px)]",
86
+ medium: "w-[min(92vw,640px)]",
87
+ large: "w-[min(92vw,840px)]",
88
+ full: "w-[min(96vw,1200px)] h-[min(92vh,900px)]"
89
+ };
52
90
  var getSizeClasses = (size) => {
53
- switch (size) {
54
- case "small":
55
- return "w-[min(92vw,420px)]";
56
- case "large":
57
- return "w-[min(92vw,840px)]";
58
- case "full":
59
- return "w-[min(96vw,1200px)] h-[min(92vh,900px)]";
60
- case "medium":
61
- default:
62
- return "w-[min(92vw,640px)]";
63
- }
91
+ return MODAL_SIZE_CLASSES[size] ?? MODAL_SIZE_CLASSES.medium;
64
92
  };
65
93
  var Modal = ({
66
94
  open,
@@ -71,6 +99,10 @@ var Modal = ({
71
99
  children,
72
100
  ...props
73
101
  }) => {
102
+ const contextValue = (0, import_react.useMemo)(
103
+ () => ({ hasOnClose: typeof onClose === "function" }),
104
+ [onClose]
105
+ );
74
106
  const handleOpenChange = (0, import_react.useCallback)(
75
107
  (nextOpen) => {
76
108
  onOpenChange == null ? void 0 : onOpenChange(nextOpen);
@@ -82,7 +114,7 @@ var Modal = ({
82
114
  },
83
115
  [onClose, onOpen, onOpenChange]
84
116
  );
85
- return /* @__PURE__ */ import_react.default.createElement(
117
+ return /* @__PURE__ */ import_react.default.createElement(ModalContext.Provider, { value: contextValue }, /* @__PURE__ */ import_react.default.createElement(
86
118
  DialogPrimitive.Root,
87
119
  {
88
120
  open,
@@ -91,11 +123,20 @@ var Modal = ({
91
123
  ...props
92
124
  },
93
125
  children
94
- );
126
+ ));
95
127
  };
96
128
  var ModalTrigger = DialogPrimitive.Trigger;
97
129
  var ModalClose = DialogPrimitive.Close;
98
130
  var ModalPortal = DialogPrimitive.Portal;
131
+ var ModalHeaderCloseButton = () => /* @__PURE__ */ import_react.default.createElement(ModalClose, { asChild: true }, /* @__PURE__ */ import_react.default.createElement(
132
+ import_buttons.IconButton,
133
+ {
134
+ size: "small",
135
+ isBare: true,
136
+ icon: /* @__PURE__ */ import_react.default.createElement(import_icons.Close, { "aria-hidden": "true" }),
137
+ "aria-label": MODAL_CLOSE_LABEL
138
+ }
139
+ ));
99
140
  var ModalOverlay = (0, import_react.forwardRef)(
100
141
  ({ className, style, ...props }, ref) => /* @__PURE__ */ import_react.default.createElement(
101
142
  DialogPrimitive.Overlay,
@@ -124,22 +165,20 @@ var ModalContent = (0, import_react.forwardRef)(
124
165
  ...restProps
125
166
  }, ref) => {
126
167
  const resolvedBackdropProps = backdropProps ?? backDropProps ?? {};
168
+ const { className: backdropClassName, style: backdropStyle, ...overlayProps } = resolvedBackdropProps;
127
169
  return /* @__PURE__ */ import_react.default.createElement(ModalPortal, null, /* @__PURE__ */ import_react.default.createElement(
128
170
  ModalOverlay,
129
171
  {
130
- ...resolvedBackdropProps,
131
- className: (0, import_utils.cx)(resolvedBackdropProps.className),
132
- style: { ...resolvedBackdropProps.style }
172
+ ...overlayProps,
173
+ className: (0, import_utils.cx)(backdropClassName),
174
+ style: { ...backdropStyle }
133
175
  }
134
176
  ), /* @__PURE__ */ import_react.default.createElement(
135
177
  DialogPrimitive.Content,
136
178
  {
137
179
  ref,
138
180
  className: (0, import_utils.cx)(
139
- "fixed left-1/2 top-1/2 max-h-[92vh] -translate-x-1/2 -translate-y-1/2",
140
- "bg-bg-base text-fg-base shadow-xl outline-none rounded-2xl border border-border-subtle",
141
- "flex flex-col overflow-hidden",
142
- "data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out",
181
+ MODAL_SURFACE_CLASSES,
143
182
  getSizeClasses(size),
144
183
  className
145
184
  ),
@@ -152,23 +191,25 @@ var ModalContent = (0, import_react.forwardRef)(
152
191
  }
153
192
  );
154
193
  ModalContent.displayName = "ModalContent";
155
- var ModalHeader = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */ import_react.default.createElement(
156
- "div",
157
- {
158
- ref,
159
- className: (0, import_utils.cx)(
160
- "flex flex-col gap-4 px-20 py-16 border-b border-border-subtle",
161
- className
162
- ),
163
- ...props
164
- }
165
- ));
194
+ var ModalHeader = (0, import_react.forwardRef)(({ className, children, ...props }, ref) => {
195
+ const { hasOnClose } = (0, import_react.useContext)(ModalContext);
196
+ return /* @__PURE__ */ import_react.default.createElement(
197
+ "div",
198
+ {
199
+ ref,
200
+ className: (0, import_utils.cx)(MODAL_HEADER_CLASSES, className),
201
+ ...props
202
+ },
203
+ /* @__PURE__ */ import_react.default.createElement("div", { className: MODAL_HEADER_CONTENT_CLASSES }, children),
204
+ hasOnClose ? /* @__PURE__ */ import_react.default.createElement(ModalHeaderCloseButton, null) : null
205
+ );
206
+ });
166
207
  ModalHeader.displayName = "ModalHeader";
167
208
  var ModalBody = (0, import_react.forwardRef)(({ className, ...props }, ref) => /* @__PURE__ */ import_react.default.createElement(
168
209
  "div",
169
210
  {
170
211
  ref,
171
- className: (0, import_utils.cx)("flex-1 overflow-auto px-20 py-16", className),
212
+ className: (0, import_utils.cx)(MODAL_BODY_CLASSES, className),
172
213
  ...props
173
214
  }
174
215
  ));
@@ -177,10 +218,7 @@ var ModalFooter = (0, import_react.forwardRef)(({ className, ...props }, ref) =>
177
218
  "div",
178
219
  {
179
220
  ref,
180
- className: (0, import_utils.cx)(
181
- "flex items-center justify-end gap-8 px-20 py-16 border-t border-border-subtle",
182
- className
183
- ),
221
+ className: (0, import_utils.cx)(MODAL_FOOTER_CLASSES, className),
184
222
  ...props
185
223
  }
186
224
  ));
@@ -189,7 +227,7 @@ var ModalTitle = (0, import_react.forwardRef)(({ className, ...props }, ref) =>
189
227
  DialogPrimitive.Title,
190
228
  {
191
229
  ref,
192
- className: (0, import_utils.cx)("text-lg font-semibold text-fg-base", className),
230
+ className: (0, import_utils.cx)(MODAL_TITLE_CLASSES, className),
193
231
  ...props
194
232
  }
195
233
  ));
@@ -198,7 +236,7 @@ var ModalDescription = (0, import_react.forwardRef)(({ className, ...props }, re
198
236
  DialogPrimitive.Description,
199
237
  {
200
238
  ref,
201
- className: (0, import_utils.cx)("text-sm text-fg-subtle", className),
239
+ className: (0, import_utils.cx)(MODAL_DESCRIPTION_CLASSES, className),
202
240
  ...props
203
241
  }
204
242
  ));
package/dist/index.mjs CHANGED
@@ -1,21 +1,55 @@
1
1
  // src/elements/Modal.jsx
2
- import React, { forwardRef, useCallback } from "react";
2
+ import React, {
3
+ createContext,
4
+ forwardRef,
5
+ useCallback,
6
+ useContext,
7
+ useMemo
8
+ } from "react";
3
9
  import * as DialogPrimitive from "@radix-ui/react-dialog";
4
10
  import { cx } from "@edux-design/utils";
11
+ import { IconButton } from "@edux-design/buttons";
12
+ import { Close as Close2 } from "@edux-design/icons";
5
13
  var MODAL_OVERLAY_Z_INDEX = 2147483645;
6
14
  var MODAL_CONTENT_Z_INDEX = 2147483646;
15
+ var ModalContext = createContext({ hasOnClose: false });
16
+ var MODAL_SECTION_PADDING_X = "px-16";
17
+ var MODAL_SECTION_PADDING_Y = "py-16";
18
+ var MODAL_SURFACE_CLASSES = [
19
+ "fixed left-1/2 top-1/2 max-h-[92vh] -translate-x-1/2 -translate-y-1/2",
20
+ "bg-bg-base text-fg-base shadow-xl outline-none rounded-md border-2 border-border-subtle",
21
+ "flex flex-col overflow-hidden",
22
+ "data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out"
23
+ ].join(" ");
24
+ var MODAL_HEADER_CLASSES = [
25
+ "flex justify-between gap-12",
26
+ MODAL_SECTION_PADDING_X,
27
+ MODAL_SECTION_PADDING_Y,
28
+ "border-b border-border-subtle"
29
+ ].join(" ");
30
+ var MODAL_HEADER_CONTENT_CLASSES = "flex min-w-0 flex-1 flex-col gap-4";
31
+ var MODAL_BODY_CLASSES = [
32
+ "flex-1 overflow-auto",
33
+ MODAL_SECTION_PADDING_X,
34
+ MODAL_SECTION_PADDING_Y
35
+ ].join(" ");
36
+ var MODAL_FOOTER_CLASSES = [
37
+ "flex items-center justify-end gap-8",
38
+ MODAL_SECTION_PADDING_X,
39
+ MODAL_SECTION_PADDING_Y,
40
+ "border-t border-border-subtle"
41
+ ].join(" ");
42
+ var MODAL_TITLE_CLASSES = "text-lg font-semibold text-fg-base";
43
+ var MODAL_DESCRIPTION_CLASSES = "text-sm text-fg-subtle";
44
+ var MODAL_CLOSE_LABEL = "Close modal";
45
+ var MODAL_SIZE_CLASSES = {
46
+ small: "w-[min(92vw,420px)]",
47
+ medium: "w-[min(92vw,640px)]",
48
+ large: "w-[min(92vw,840px)]",
49
+ full: "w-[min(96vw,1200px)] h-[min(92vh,900px)]"
50
+ };
7
51
  var getSizeClasses = (size) => {
8
- switch (size) {
9
- case "small":
10
- return "w-[min(92vw,420px)]";
11
- case "large":
12
- return "w-[min(92vw,840px)]";
13
- case "full":
14
- return "w-[min(96vw,1200px)] h-[min(92vh,900px)]";
15
- case "medium":
16
- default:
17
- return "w-[min(92vw,640px)]";
18
- }
52
+ return MODAL_SIZE_CLASSES[size] ?? MODAL_SIZE_CLASSES.medium;
19
53
  };
20
54
  var Modal = ({
21
55
  open,
@@ -26,6 +60,10 @@ var Modal = ({
26
60
  children,
27
61
  ...props
28
62
  }) => {
63
+ const contextValue = useMemo(
64
+ () => ({ hasOnClose: typeof onClose === "function" }),
65
+ [onClose]
66
+ );
29
67
  const handleOpenChange = useCallback(
30
68
  (nextOpen) => {
31
69
  onOpenChange == null ? void 0 : onOpenChange(nextOpen);
@@ -37,7 +75,7 @@ var Modal = ({
37
75
  },
38
76
  [onClose, onOpen, onOpenChange]
39
77
  );
40
- return /* @__PURE__ */ React.createElement(
78
+ return /* @__PURE__ */ React.createElement(ModalContext.Provider, { value: contextValue }, /* @__PURE__ */ React.createElement(
41
79
  DialogPrimitive.Root,
42
80
  {
43
81
  open,
@@ -46,11 +84,20 @@ var Modal = ({
46
84
  ...props
47
85
  },
48
86
  children
49
- );
87
+ ));
50
88
  };
51
89
  var ModalTrigger = DialogPrimitive.Trigger;
52
90
  var ModalClose = DialogPrimitive.Close;
53
91
  var ModalPortal = DialogPrimitive.Portal;
92
+ var ModalHeaderCloseButton = () => /* @__PURE__ */ React.createElement(ModalClose, { asChild: true }, /* @__PURE__ */ React.createElement(
93
+ IconButton,
94
+ {
95
+ size: "small",
96
+ isBare: true,
97
+ icon: /* @__PURE__ */ React.createElement(Close2, { "aria-hidden": "true" }),
98
+ "aria-label": MODAL_CLOSE_LABEL
99
+ }
100
+ ));
54
101
  var ModalOverlay = forwardRef(
55
102
  ({ className, style, ...props }, ref) => /* @__PURE__ */ React.createElement(
56
103
  DialogPrimitive.Overlay,
@@ -79,22 +126,20 @@ var ModalContent = forwardRef(
79
126
  ...restProps
80
127
  }, ref) => {
81
128
  const resolvedBackdropProps = backdropProps ?? backDropProps ?? {};
129
+ const { className: backdropClassName, style: backdropStyle, ...overlayProps } = resolvedBackdropProps;
82
130
  return /* @__PURE__ */ React.createElement(ModalPortal, null, /* @__PURE__ */ React.createElement(
83
131
  ModalOverlay,
84
132
  {
85
- ...resolvedBackdropProps,
86
- className: cx(resolvedBackdropProps.className),
87
- style: { ...resolvedBackdropProps.style }
133
+ ...overlayProps,
134
+ className: cx(backdropClassName),
135
+ style: { ...backdropStyle }
88
136
  }
89
137
  ), /* @__PURE__ */ React.createElement(
90
138
  DialogPrimitive.Content,
91
139
  {
92
140
  ref,
93
141
  className: cx(
94
- "fixed left-1/2 top-1/2 max-h-[92vh] -translate-x-1/2 -translate-y-1/2",
95
- "bg-bg-base text-fg-base shadow-xl outline-none rounded-2xl border border-border-subtle",
96
- "flex flex-col overflow-hidden",
97
- "data-[state=open]:animate-fade-in data-[state=closed]:animate-fade-out",
142
+ MODAL_SURFACE_CLASSES,
98
143
  getSizeClasses(size),
99
144
  className
100
145
  ),
@@ -107,23 +152,25 @@ var ModalContent = forwardRef(
107
152
  }
108
153
  );
109
154
  ModalContent.displayName = "ModalContent";
110
- var ModalHeader = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
111
- "div",
112
- {
113
- ref,
114
- className: cx(
115
- "flex flex-col gap-4 px-20 py-16 border-b border-border-subtle",
116
- className
117
- ),
118
- ...props
119
- }
120
- ));
155
+ var ModalHeader = forwardRef(({ className, children, ...props }, ref) => {
156
+ const { hasOnClose } = useContext(ModalContext);
157
+ return /* @__PURE__ */ React.createElement(
158
+ "div",
159
+ {
160
+ ref,
161
+ className: cx(MODAL_HEADER_CLASSES, className),
162
+ ...props
163
+ },
164
+ /* @__PURE__ */ React.createElement("div", { className: MODAL_HEADER_CONTENT_CLASSES }, children),
165
+ hasOnClose ? /* @__PURE__ */ React.createElement(ModalHeaderCloseButton, null) : null
166
+ );
167
+ });
121
168
  ModalHeader.displayName = "ModalHeader";
122
169
  var ModalBody = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ React.createElement(
123
170
  "div",
124
171
  {
125
172
  ref,
126
- className: cx("flex-1 overflow-auto px-20 py-16", className),
173
+ className: cx(MODAL_BODY_CLASSES, className),
127
174
  ...props
128
175
  }
129
176
  ));
@@ -132,10 +179,7 @@ var ModalFooter = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ R
132
179
  "div",
133
180
  {
134
181
  ref,
135
- className: cx(
136
- "flex items-center justify-end gap-8 px-20 py-16 border-t border-border-subtle",
137
- className
138
- ),
182
+ className: cx(MODAL_FOOTER_CLASSES, className),
139
183
  ...props
140
184
  }
141
185
  ));
@@ -144,7 +188,7 @@ var ModalTitle = forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ Re
144
188
  DialogPrimitive.Title,
145
189
  {
146
190
  ref,
147
- className: cx("text-lg font-semibold text-fg-base", className),
191
+ className: cx(MODAL_TITLE_CLASSES, className),
148
192
  ...props
149
193
  }
150
194
  ));
@@ -153,7 +197,7 @@ var ModalDescription = forwardRef(({ className, ...props }, ref) => /* @__PURE__
153
197
  DialogPrimitive.Description,
154
198
  {
155
199
  ref,
156
- className: cx("text-sm text-fg-subtle", className),
200
+ className: cx(MODAL_DESCRIPTION_CLASSES, className),
157
201
  ...props
158
202
  }
159
203
  ));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@edux-design/modals",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "private": false,
5
5
  "sideEffects": [
6
6
  "**/*.css"