@mhome/ui 0.1.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/README.md +188 -0
- package/dist/index.cjs.js +9 -0
- package/dist/index.cjs.js.map +1 -0
- package/dist/index.css +2 -0
- package/dist/index.esm.js +9 -0
- package/dist/index.esm.js.map +1 -0
- package/package.json +54 -0
- package/src/common/adaptive-theme-provider.js +19 -0
- package/src/components/accordion.jsx +306 -0
- package/src/components/alert.jsx +137 -0
- package/src/components/app-bar.jsx +105 -0
- package/src/components/autocomplete.jsx +347 -0
- package/src/components/avatar.jsx +160 -0
- package/src/components/box.jsx +165 -0
- package/src/components/button.jsx +104 -0
- package/src/components/card.jsx +156 -0
- package/src/components/checkbox.jsx +63 -0
- package/src/components/chip.jsx +137 -0
- package/src/components/collapse.jsx +188 -0
- package/src/components/container.jsx +67 -0
- package/src/components/date-picker.jsx +528 -0
- package/src/components/dialog-content-text.jsx +27 -0
- package/src/components/dialog.jsx +584 -0
- package/src/components/divider.jsx +192 -0
- package/src/components/drawer.jsx +255 -0
- package/src/components/form-control-label.jsx +89 -0
- package/src/components/form-group.jsx +32 -0
- package/src/components/form-label.jsx +54 -0
- package/src/components/grid.jsx +135 -0
- package/src/components/icon-button.jsx +101 -0
- package/src/components/index.js +78 -0
- package/src/components/input-adornment.jsx +43 -0
- package/src/components/input-label.jsx +55 -0
- package/src/components/list.jsx +239 -0
- package/src/components/menu.jsx +370 -0
- package/src/components/paper.jsx +173 -0
- package/src/components/radio-group.jsx +76 -0
- package/src/components/radio.jsx +108 -0
- package/src/components/select.jsx +308 -0
- package/src/components/slider.jsx +382 -0
- package/src/components/stack.jsx +110 -0
- package/src/components/table.jsx +243 -0
- package/src/components/tabs.jsx +363 -0
- package/src/components/text-field.jsx +289 -0
- package/src/components/toggle-button.jsx +209 -0
- package/src/components/toolbar.jsx +48 -0
- package/src/components/tooltip.jsx +127 -0
- package/src/components/typography.jsx +77 -0
- package/src/global-state.js +29 -0
- package/src/index.css +110 -0
- package/src/index.js +6 -0
- package/src/lib/useMediaQuery.js +37 -0
- package/src/lib/utils.js +113 -0
|
@@ -0,0 +1,584 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { createPortal } from "react-dom";
|
|
3
|
+
import { cn, spacingToPx, useIsDarkMode } from "../lib/utils";
|
|
4
|
+
import { getBackground } from "../common/adaptive-theme-provider";
|
|
5
|
+
import { useRecoilValue, backgroundTypeState } from "../global-state";
|
|
6
|
+
|
|
7
|
+
const Dialog = ({
|
|
8
|
+
open,
|
|
9
|
+
onClose,
|
|
10
|
+
children,
|
|
11
|
+
variant,
|
|
12
|
+
maxWidth,
|
|
13
|
+
fullWidth,
|
|
14
|
+
fullScreen = false,
|
|
15
|
+
PaperProps,
|
|
16
|
+
"aria-labelledby": ariaLabelledBy,
|
|
17
|
+
"aria-describedby": ariaDescribedBy,
|
|
18
|
+
...props
|
|
19
|
+
}) => {
|
|
20
|
+
const dialogId = React.useId();
|
|
21
|
+
const actualMode = useIsDarkMode();
|
|
22
|
+
const backgroundType = useRecoilValue(backgroundTypeState);
|
|
23
|
+
|
|
24
|
+
// All hooks must be called before any early returns
|
|
25
|
+
// This ensures hooks are called in the same order on every render
|
|
26
|
+
// Merge sx styles from PaperProps if provided
|
|
27
|
+
const paperSxStyles = React.useMemo(() => {
|
|
28
|
+
if (!PaperProps?.sx) return {};
|
|
29
|
+
const sxObj =
|
|
30
|
+
typeof PaperProps.sx === "function"
|
|
31
|
+
? PaperProps.sx({}) // Empty theme object for compatibility
|
|
32
|
+
: PaperProps.sx;
|
|
33
|
+
return sxObj;
|
|
34
|
+
}, [PaperProps?.sx]);
|
|
35
|
+
|
|
36
|
+
if (!open) return null;
|
|
37
|
+
|
|
38
|
+
const maxWidthClass =
|
|
39
|
+
{
|
|
40
|
+
xs: "max-w-xs",
|
|
41
|
+
sm: "max-w-sm",
|
|
42
|
+
md: "max-w-md",
|
|
43
|
+
lg: "max-w-lg",
|
|
44
|
+
xl: "max-w-xl",
|
|
45
|
+
}[maxWidth] || "max-w-lg";
|
|
46
|
+
|
|
47
|
+
// Get pops variant styles from theme
|
|
48
|
+
const popsStyles =
|
|
49
|
+
variant === "pops"
|
|
50
|
+
? {
|
|
51
|
+
minWidth: "300px",
|
|
52
|
+
maxWidth: "800px",
|
|
53
|
+
}
|
|
54
|
+
: {};
|
|
55
|
+
|
|
56
|
+
// Drawer variant styles
|
|
57
|
+
const drawerStyles =
|
|
58
|
+
variant === "drawer"
|
|
59
|
+
? {
|
|
60
|
+
margin: 0,
|
|
61
|
+
maxHeight: "100vh",
|
|
62
|
+
height: "100vh",
|
|
63
|
+
borderRadius: "16px 0 0 16px",
|
|
64
|
+
}
|
|
65
|
+
: {};
|
|
66
|
+
|
|
67
|
+
// For drawer variant, use background gradient if available, otherwise use standard background
|
|
68
|
+
const paperBg =
|
|
69
|
+
variant === "drawer"
|
|
70
|
+
? getBackground(backgroundType, actualMode === "dark")
|
|
71
|
+
: null;
|
|
72
|
+
const isGradient =
|
|
73
|
+
paperBg &&
|
|
74
|
+
typeof paperBg === "string" &&
|
|
75
|
+
(paperBg.startsWith("linear-gradient") ||
|
|
76
|
+
paperBg.startsWith("radial-gradient") ||
|
|
77
|
+
paperBg.startsWith("conic-gradient"));
|
|
78
|
+
|
|
79
|
+
const borderRadius =
|
|
80
|
+
variant === "pops"
|
|
81
|
+
? "16px"
|
|
82
|
+
: variant === "drawer"
|
|
83
|
+
? "16px 0 0 16px"
|
|
84
|
+
: "8px";
|
|
85
|
+
|
|
86
|
+
// Handle PaperProps (MUI compatibility)
|
|
87
|
+
const paperPropsStyle = PaperProps?.style || {};
|
|
88
|
+
const paperPropsClassName = PaperProps?.className || "";
|
|
89
|
+
|
|
90
|
+
// Determine container alignment based on variant
|
|
91
|
+
const containerClass =
|
|
92
|
+
variant === "drawer"
|
|
93
|
+
? "flex items-stretch justify-end"
|
|
94
|
+
: fullScreen
|
|
95
|
+
? "flex items-stretch"
|
|
96
|
+
: "flex items-center justify-center";
|
|
97
|
+
|
|
98
|
+
// Get z-index from CSS variable or use default
|
|
99
|
+
const zIndex =
|
|
100
|
+
variant === "drawer"
|
|
101
|
+
? parseInt(
|
|
102
|
+
getComputedStyle(document.documentElement).getPropertyValue(
|
|
103
|
+
"--z-index-drawer"
|
|
104
|
+
) || "1300",
|
|
105
|
+
10
|
|
106
|
+
)
|
|
107
|
+
: parseInt(
|
|
108
|
+
getComputedStyle(document.documentElement).getPropertyValue(
|
|
109
|
+
"--z-index-modal"
|
|
110
|
+
) || "1300",
|
|
111
|
+
10
|
|
112
|
+
);
|
|
113
|
+
|
|
114
|
+
// Render dialog content using Portal to body to avoid parent container constraints
|
|
115
|
+
const dialogContent = (
|
|
116
|
+
<>
|
|
117
|
+
{/* Backdrop - more opaque for better separation */}
|
|
118
|
+
<div
|
|
119
|
+
className={cn(
|
|
120
|
+
"fixed inset-0",
|
|
121
|
+
actualMode === "dark" ? "bg-black/80" : "bg-black/60"
|
|
122
|
+
)}
|
|
123
|
+
style={{
|
|
124
|
+
zIndex: zIndex - 1,
|
|
125
|
+
pointerEvents: "auto",
|
|
126
|
+
}}
|
|
127
|
+
onClick={(e) => {
|
|
128
|
+
if (onClose) onClose(e, "backdropClick");
|
|
129
|
+
}}
|
|
130
|
+
/>
|
|
131
|
+
{/* Dialog content - fully opaque, above backdrop */}
|
|
132
|
+
<div
|
|
133
|
+
className={cn("fixed inset-0", containerClass)}
|
|
134
|
+
style={{
|
|
135
|
+
zIndex: zIndex,
|
|
136
|
+
pointerEvents: "none",
|
|
137
|
+
}}
|
|
138
|
+
{...props}
|
|
139
|
+
>
|
|
140
|
+
<div
|
|
141
|
+
role="dialog"
|
|
142
|
+
aria-modal="true"
|
|
143
|
+
aria-labelledby={ariaLabelledBy || `${dialogId}-title`}
|
|
144
|
+
aria-describedby={ariaDescribedBy || `${dialogId}-description`}
|
|
145
|
+
className={cn(
|
|
146
|
+
"relative shadow-2xl",
|
|
147
|
+
fullScreen || variant === "drawer"
|
|
148
|
+
? "h-full w-full"
|
|
149
|
+
: "w-full max-w-[calc(100%-32px)]",
|
|
150
|
+
fullScreen || variant === "drawer" ? "" : "mx-4",
|
|
151
|
+
!fullScreen && variant !== "drawer" && maxWidthClass,
|
|
152
|
+
fullWidth && !fullScreen && variant !== "drawer" && "max-w-full",
|
|
153
|
+
variant === "drawer" && !isGradient && "bg-background",
|
|
154
|
+
!isGradient && variant !== "drawer" && "bg-card",
|
|
155
|
+
paperPropsClassName
|
|
156
|
+
)}
|
|
157
|
+
style={{
|
|
158
|
+
// Use background for gradients, className for solid colors
|
|
159
|
+
...(isGradient ? { background: paperBg } : {}),
|
|
160
|
+
borderRadius: fullScreen ? 0 : borderRadius,
|
|
161
|
+
position: "relative",
|
|
162
|
+
opacity: 1,
|
|
163
|
+
pointerEvents: "auto",
|
|
164
|
+
touchAction: "none",
|
|
165
|
+
...popsStyles,
|
|
166
|
+
...drawerStyles,
|
|
167
|
+
...paperSxStyles,
|
|
168
|
+
...paperPropsStyle,
|
|
169
|
+
}}
|
|
170
|
+
>
|
|
171
|
+
{children}
|
|
172
|
+
</div>
|
|
173
|
+
</div>
|
|
174
|
+
</>
|
|
175
|
+
);
|
|
176
|
+
|
|
177
|
+
// Use Portal to render dialog to body, ensuring it's not constrained by parent containers
|
|
178
|
+
return typeof document !== "undefined"
|
|
179
|
+
? createPortal(dialogContent, document.body)
|
|
180
|
+
: null;
|
|
181
|
+
};
|
|
182
|
+
|
|
183
|
+
const DialogContent = React.forwardRef(
|
|
184
|
+
({ className, children, style, sx, ...props }, ref) => {
|
|
185
|
+
const actualMode = useIsDarkMode();
|
|
186
|
+
const backgroundType = useRecoilValue(backgroundTypeState);
|
|
187
|
+
const bgColor = getBackground(backgroundType, actualMode === "dark");
|
|
188
|
+
const isGradient =
|
|
189
|
+
bgColor &&
|
|
190
|
+
typeof bgColor === "string" &&
|
|
191
|
+
(bgColor.startsWith("linear-gradient") ||
|
|
192
|
+
bgColor.startsWith("radial-gradient") ||
|
|
193
|
+
bgColor.startsWith("conic-gradient"));
|
|
194
|
+
|
|
195
|
+
// Convert sx prop to style if provided, handling MUI spacing
|
|
196
|
+
const sxStyles = React.useMemo(() => {
|
|
197
|
+
if (!sx) return {};
|
|
198
|
+
const sxObj = typeof sx === "function" ? sx({}) : sx; // Empty theme object for compatibility
|
|
199
|
+
|
|
200
|
+
// Convert MUI spacing properties to CSS
|
|
201
|
+
const converted = { ...sxObj };
|
|
202
|
+
|
|
203
|
+
// Padding shortcuts
|
|
204
|
+
if (converted.p !== undefined) {
|
|
205
|
+
converted.padding = spacingToPx(converted.p);
|
|
206
|
+
delete converted.p;
|
|
207
|
+
}
|
|
208
|
+
if (converted.px !== undefined) {
|
|
209
|
+
converted.paddingLeft = spacingToPx(converted.px);
|
|
210
|
+
converted.paddingRight = spacingToPx(converted.px);
|
|
211
|
+
delete converted.px;
|
|
212
|
+
}
|
|
213
|
+
if (converted.py !== undefined) {
|
|
214
|
+
converted.paddingTop = spacingToPx(converted.py);
|
|
215
|
+
converted.paddingBottom = spacingToPx(converted.py);
|
|
216
|
+
delete converted.py;
|
|
217
|
+
}
|
|
218
|
+
if (converted.pt !== undefined) {
|
|
219
|
+
converted.paddingTop = spacingToPx(converted.pt);
|
|
220
|
+
delete converted.pt;
|
|
221
|
+
}
|
|
222
|
+
if (converted.pb !== undefined) {
|
|
223
|
+
converted.paddingBottom = spacingToPx(converted.pb);
|
|
224
|
+
delete converted.pb;
|
|
225
|
+
}
|
|
226
|
+
if (converted.pl !== undefined) {
|
|
227
|
+
converted.paddingLeft = spacingToPx(converted.pl);
|
|
228
|
+
delete converted.pl;
|
|
229
|
+
}
|
|
230
|
+
if (converted.pr !== undefined) {
|
|
231
|
+
converted.paddingRight = spacingToPx(converted.pr);
|
|
232
|
+
delete converted.pr;
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Margin shortcuts
|
|
236
|
+
if (converted.m !== undefined) {
|
|
237
|
+
converted.margin = spacingToPx(converted.m);
|
|
238
|
+
delete converted.m;
|
|
239
|
+
}
|
|
240
|
+
if (converted.mx !== undefined) {
|
|
241
|
+
converted.marginLeft = spacingToPx(converted.mx);
|
|
242
|
+
converted.marginRight = spacingToPx(converted.mx);
|
|
243
|
+
delete converted.mx;
|
|
244
|
+
}
|
|
245
|
+
if (converted.my !== undefined) {
|
|
246
|
+
converted.marginTop = spacingToPx(converted.my);
|
|
247
|
+
converted.marginBottom = spacingToPx(converted.my);
|
|
248
|
+
delete converted.my;
|
|
249
|
+
}
|
|
250
|
+
if (converted.mt !== undefined) {
|
|
251
|
+
converted.marginTop = spacingToPx(converted.mt);
|
|
252
|
+
delete converted.mt;
|
|
253
|
+
}
|
|
254
|
+
if (converted.mb !== undefined) {
|
|
255
|
+
converted.marginBottom = spacingToPx(converted.mb);
|
|
256
|
+
delete converted.mb;
|
|
257
|
+
}
|
|
258
|
+
if (converted.ml !== undefined) {
|
|
259
|
+
converted.marginLeft = spacingToPx(converted.ml);
|
|
260
|
+
delete converted.ml;
|
|
261
|
+
}
|
|
262
|
+
if (converted.mr !== undefined) {
|
|
263
|
+
converted.marginRight = spacingToPx(converted.mr);
|
|
264
|
+
delete converted.mr;
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
// Gap
|
|
268
|
+
if (converted.gap !== undefined) {
|
|
269
|
+
converted.gap = spacingToPx(converted.gap);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
return converted;
|
|
273
|
+
}, [sx]);
|
|
274
|
+
|
|
275
|
+
// Extract padding from style to allow override
|
|
276
|
+
const {
|
|
277
|
+
padding,
|
|
278
|
+
paddingTop,
|
|
279
|
+
paddingBottom,
|
|
280
|
+
paddingLeft,
|
|
281
|
+
paddingRight,
|
|
282
|
+
backgroundColor,
|
|
283
|
+
...restStyle
|
|
284
|
+
} = style || {};
|
|
285
|
+
|
|
286
|
+
const hasPaddingInStyle =
|
|
287
|
+
padding !== undefined ||
|
|
288
|
+
paddingTop !== undefined ||
|
|
289
|
+
paddingBottom !== undefined ||
|
|
290
|
+
paddingLeft !== undefined ||
|
|
291
|
+
paddingRight !== undefined;
|
|
292
|
+
|
|
293
|
+
// Default padding class, but allow override
|
|
294
|
+
const defaultPaddingClass = hasPaddingInStyle ? "" : "p-6";
|
|
295
|
+
|
|
296
|
+
return (
|
|
297
|
+
<div
|
|
298
|
+
ref={ref}
|
|
299
|
+
className={cn(
|
|
300
|
+
"text-left rounded-b-[inherit]",
|
|
301
|
+
defaultPaddingClass,
|
|
302
|
+
"p-6",
|
|
303
|
+
className
|
|
304
|
+
)}
|
|
305
|
+
style={{
|
|
306
|
+
// Only set background if explicitly provided, otherwise inherit from parent
|
|
307
|
+
...(backgroundColor !== undefined
|
|
308
|
+
? backgroundColor.startsWith("linear-gradient") ||
|
|
309
|
+
backgroundColor.startsWith("radial-gradient") ||
|
|
310
|
+
backgroundColor.startsWith("conic-gradient")
|
|
311
|
+
? { background: backgroundColor }
|
|
312
|
+
: { backgroundColor }
|
|
313
|
+
: {}),
|
|
314
|
+
padding: padding,
|
|
315
|
+
paddingTop: paddingTop,
|
|
316
|
+
paddingBottom: paddingBottom,
|
|
317
|
+
paddingLeft: paddingLeft,
|
|
318
|
+
paddingRight: paddingRight,
|
|
319
|
+
opacity: 1,
|
|
320
|
+
pointerEvents: "auto",
|
|
321
|
+
...sxStyles,
|
|
322
|
+
...restStyle,
|
|
323
|
+
}}
|
|
324
|
+
{...props}
|
|
325
|
+
>
|
|
326
|
+
{children}
|
|
327
|
+
</div>
|
|
328
|
+
);
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
DialogContent.displayName = "DialogContent";
|
|
332
|
+
|
|
333
|
+
const DialogHeader = ({ className, ...props }) => (
|
|
334
|
+
<div
|
|
335
|
+
className={cn(
|
|
336
|
+
"flex flex-col space-y-1.5 text-center sm:text-left px-6 pt-6",
|
|
337
|
+
className
|
|
338
|
+
)}
|
|
339
|
+
{...props}
|
|
340
|
+
/>
|
|
341
|
+
);
|
|
342
|
+
DialogHeader.displayName = "DialogHeader";
|
|
343
|
+
|
|
344
|
+
const DialogFooter = ({ className, ...props }) => (
|
|
345
|
+
<div
|
|
346
|
+
className={cn(
|
|
347
|
+
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2 px-6 pb-6",
|
|
348
|
+
className
|
|
349
|
+
)}
|
|
350
|
+
{...props}
|
|
351
|
+
/>
|
|
352
|
+
);
|
|
353
|
+
DialogFooter.displayName = "DialogFooter";
|
|
354
|
+
|
|
355
|
+
const DialogTitle = React.forwardRef(
|
|
356
|
+
({ className, style, sx, ...props }, ref) => {
|
|
357
|
+
const actualMode = useIsDarkMode();
|
|
358
|
+
const backgroundType = useRecoilValue(backgroundTypeState);
|
|
359
|
+
const bgColor = getBackground(backgroundType, actualMode === "dark");
|
|
360
|
+
const isGradient =
|
|
361
|
+
bgColor &&
|
|
362
|
+
typeof bgColor === "string" &&
|
|
363
|
+
(bgColor.startsWith("linear-gradient") ||
|
|
364
|
+
bgColor.startsWith("radial-gradient") ||
|
|
365
|
+
bgColor.startsWith("conic-gradient"));
|
|
366
|
+
|
|
367
|
+
// Convert sx prop to style if provided, handling MUI spacing
|
|
368
|
+
const sxStyles = React.useMemo(() => {
|
|
369
|
+
if (!sx) return {};
|
|
370
|
+
const sxObj = typeof sx === "function" ? sx({}) : sx; // Empty theme object for compatibility
|
|
371
|
+
|
|
372
|
+
// Convert MUI spacing properties to CSS
|
|
373
|
+
const converted = { ...sxObj };
|
|
374
|
+
|
|
375
|
+
// Padding shortcuts
|
|
376
|
+
if (converted.p !== undefined) {
|
|
377
|
+
converted.padding = spacingToPx(converted.p);
|
|
378
|
+
delete converted.p;
|
|
379
|
+
}
|
|
380
|
+
if (converted.px !== undefined) {
|
|
381
|
+
converted.paddingLeft = spacingToPx(converted.px);
|
|
382
|
+
converted.paddingRight = spacingToPx(converted.px);
|
|
383
|
+
delete converted.px;
|
|
384
|
+
}
|
|
385
|
+
if (converted.py !== undefined) {
|
|
386
|
+
converted.paddingTop = spacingToPx(converted.py);
|
|
387
|
+
converted.paddingBottom = spacingToPx(converted.py);
|
|
388
|
+
delete converted.py;
|
|
389
|
+
}
|
|
390
|
+
if (converted.pt !== undefined) {
|
|
391
|
+
converted.paddingTop = spacingToPx(converted.pt);
|
|
392
|
+
delete converted.pt;
|
|
393
|
+
}
|
|
394
|
+
if (converted.pb !== undefined) {
|
|
395
|
+
converted.paddingBottom = spacingToPx(converted.pb);
|
|
396
|
+
delete converted.pb;
|
|
397
|
+
}
|
|
398
|
+
if (converted.pl !== undefined) {
|
|
399
|
+
converted.paddingLeft = spacingToPx(converted.pl);
|
|
400
|
+
delete converted.pl;
|
|
401
|
+
}
|
|
402
|
+
if (converted.pr !== undefined) {
|
|
403
|
+
converted.paddingRight = spacingToPx(converted.pr);
|
|
404
|
+
delete converted.pr;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// Margin shortcuts
|
|
408
|
+
if (converted.m !== undefined) {
|
|
409
|
+
converted.margin = spacingToPx(converted.m);
|
|
410
|
+
delete converted.m;
|
|
411
|
+
}
|
|
412
|
+
if (converted.mx !== undefined) {
|
|
413
|
+
converted.marginLeft = spacingToPx(converted.mx);
|
|
414
|
+
converted.marginRight = spacingToPx(converted.mx);
|
|
415
|
+
delete converted.mx;
|
|
416
|
+
}
|
|
417
|
+
if (converted.my !== undefined) {
|
|
418
|
+
converted.marginTop = spacingToPx(converted.my);
|
|
419
|
+
converted.marginBottom = spacingToPx(converted.my);
|
|
420
|
+
delete converted.my;
|
|
421
|
+
}
|
|
422
|
+
if (converted.mt !== undefined) {
|
|
423
|
+
converted.marginTop = spacingToPx(converted.mt);
|
|
424
|
+
delete converted.mt;
|
|
425
|
+
}
|
|
426
|
+
if (converted.mb !== undefined) {
|
|
427
|
+
converted.marginBottom = spacingToPx(converted.mb);
|
|
428
|
+
delete converted.mb;
|
|
429
|
+
}
|
|
430
|
+
if (converted.ml !== undefined) {
|
|
431
|
+
converted.marginLeft = spacingToPx(converted.ml);
|
|
432
|
+
delete converted.ml;
|
|
433
|
+
}
|
|
434
|
+
if (converted.mr !== undefined) {
|
|
435
|
+
converted.marginRight = spacingToPx(converted.mr);
|
|
436
|
+
delete converted.mr;
|
|
437
|
+
}
|
|
438
|
+
|
|
439
|
+
// Gap
|
|
440
|
+
if (converted.gap !== undefined) {
|
|
441
|
+
converted.gap = spacingToPx(converted.gap);
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return converted;
|
|
445
|
+
}, [sx]);
|
|
446
|
+
|
|
447
|
+
// Extract padding from style to allow override
|
|
448
|
+
const {
|
|
449
|
+
padding,
|
|
450
|
+
paddingTop,
|
|
451
|
+
paddingBottom,
|
|
452
|
+
paddingLeft,
|
|
453
|
+
paddingRight,
|
|
454
|
+
backgroundColor,
|
|
455
|
+
...restStyle
|
|
456
|
+
} = style || {};
|
|
457
|
+
|
|
458
|
+
// Check if padding is explicitly set (if padding is set, individual paddings should be undefined)
|
|
459
|
+
// If no padding is set at all, use defaults
|
|
460
|
+
const hasAnyPadding =
|
|
461
|
+
padding !== undefined ||
|
|
462
|
+
paddingTop !== undefined ||
|
|
463
|
+
paddingBottom !== undefined ||
|
|
464
|
+
paddingLeft !== undefined ||
|
|
465
|
+
paddingRight !== undefined;
|
|
466
|
+
|
|
467
|
+
return (
|
|
468
|
+
<h2
|
|
469
|
+
ref={ref}
|
|
470
|
+
className={cn(
|
|
471
|
+
"rounded-t-[inherit]",
|
|
472
|
+
"text-lg font-semibold leading-none tracking-tight",
|
|
473
|
+
"text-foreground",
|
|
474
|
+
// DialogTitle is typically used inside DialogHeader which has padding
|
|
475
|
+
// Only add padding if explicitly needed (when used standalone)
|
|
476
|
+
// For normal use, padding is handled by DialogHeader
|
|
477
|
+
className
|
|
478
|
+
)}
|
|
479
|
+
style={{
|
|
480
|
+
// Only set background if explicitly provided, otherwise inherit from parent
|
|
481
|
+
...(backgroundColor !== undefined
|
|
482
|
+
? backgroundColor.startsWith("linear-gradient") ||
|
|
483
|
+
backgroundColor.startsWith("radial-gradient") ||
|
|
484
|
+
backgroundColor.startsWith("conic-gradient")
|
|
485
|
+
? { background: backgroundColor }
|
|
486
|
+
: { backgroundColor }
|
|
487
|
+
: {}),
|
|
488
|
+
// Allow padding override via style prop
|
|
489
|
+
padding: padding,
|
|
490
|
+
paddingLeft: paddingLeft,
|
|
491
|
+
paddingRight: paddingRight,
|
|
492
|
+
paddingTop: paddingTop,
|
|
493
|
+
paddingBottom: paddingBottom,
|
|
494
|
+
...sxStyles,
|
|
495
|
+
...restStyle,
|
|
496
|
+
}}
|
|
497
|
+
{...props}
|
|
498
|
+
/>
|
|
499
|
+
);
|
|
500
|
+
}
|
|
501
|
+
);
|
|
502
|
+
DialogTitle.displayName = "DialogTitle";
|
|
503
|
+
|
|
504
|
+
const DialogDescription = React.forwardRef(
|
|
505
|
+
({ className, id, ...props }, ref) => (
|
|
506
|
+
<p
|
|
507
|
+
ref={ref}
|
|
508
|
+
id={id}
|
|
509
|
+
className={cn("text-sm text-muted-foreground", className)}
|
|
510
|
+
{...props}
|
|
511
|
+
/>
|
|
512
|
+
)
|
|
513
|
+
);
|
|
514
|
+
DialogDescription.displayName = "DialogDescription";
|
|
515
|
+
|
|
516
|
+
const DialogActions = ({ className, style, ...props }) => {
|
|
517
|
+
const actualMode = useIsDarkMode();
|
|
518
|
+
|
|
519
|
+
// Extract padding and gap from style to allow override
|
|
520
|
+
const {
|
|
521
|
+
padding,
|
|
522
|
+
paddingTop,
|
|
523
|
+
paddingBottom,
|
|
524
|
+
paddingLeft,
|
|
525
|
+
paddingRight,
|
|
526
|
+
gap,
|
|
527
|
+
backgroundColor,
|
|
528
|
+
...restStyle
|
|
529
|
+
} = style || {};
|
|
530
|
+
|
|
531
|
+
return (
|
|
532
|
+
<div
|
|
533
|
+
className={cn(
|
|
534
|
+
"flex items-center justify-end rounded-b-[inherit]",
|
|
535
|
+
className
|
|
536
|
+
)}
|
|
537
|
+
style={{
|
|
538
|
+
// Only set background if explicitly provided, otherwise inherit from parent
|
|
539
|
+
backgroundColor: backgroundColor,
|
|
540
|
+
// If padding is set, let it control all sides; otherwise use individual defaults
|
|
541
|
+
padding: padding,
|
|
542
|
+
paddingLeft:
|
|
543
|
+
paddingLeft !== undefined
|
|
544
|
+
? paddingLeft
|
|
545
|
+
: padding !== undefined
|
|
546
|
+
? undefined
|
|
547
|
+
: "1rem",
|
|
548
|
+
paddingRight:
|
|
549
|
+
paddingRight !== undefined
|
|
550
|
+
? paddingRight
|
|
551
|
+
: padding !== undefined
|
|
552
|
+
? undefined
|
|
553
|
+
: "1rem",
|
|
554
|
+
paddingTop:
|
|
555
|
+
paddingTop !== undefined
|
|
556
|
+
? paddingTop
|
|
557
|
+
: padding !== undefined
|
|
558
|
+
? undefined
|
|
559
|
+
: "0.5rem",
|
|
560
|
+
paddingBottom:
|
|
561
|
+
paddingBottom !== undefined
|
|
562
|
+
? paddingBottom
|
|
563
|
+
: padding !== undefined
|
|
564
|
+
? undefined
|
|
565
|
+
: "1rem",
|
|
566
|
+
gap: gap !== undefined ? gap : "0.5rem",
|
|
567
|
+
opacity: 1,
|
|
568
|
+
...restStyle,
|
|
569
|
+
}}
|
|
570
|
+
{...props}
|
|
571
|
+
/>
|
|
572
|
+
);
|
|
573
|
+
};
|
|
574
|
+
DialogActions.displayName = "DialogActions";
|
|
575
|
+
|
|
576
|
+
export {
|
|
577
|
+
Dialog,
|
|
578
|
+
DialogContent,
|
|
579
|
+
DialogHeader,
|
|
580
|
+
DialogFooter,
|
|
581
|
+
DialogTitle,
|
|
582
|
+
DialogDescription,
|
|
583
|
+
DialogActions,
|
|
584
|
+
};
|