@neoptocom/neopto-ui 0.9.5 → 0.9.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +8 -9
- package/dist/index.d.cts +1 -3
- package/dist/index.d.ts +1 -3
- package/dist/index.js +8 -9
- package/package.json +1 -1
- package/src/components/Card.tsx +5 -1
- package/src/components/Modal.tsx +6 -11
- package/src/stories/Modal.stories.tsx +6 -18
package/dist/index.cjs
CHANGED
|
@@ -166,10 +166,12 @@ function Card({
|
|
|
166
166
|
transition: "background-color 0.3s ease, color 0.3s ease",
|
|
167
167
|
...style
|
|
168
168
|
};
|
|
169
|
+
const hasPadding = className && /\b(p-|px-|py-|pt-|pb-|pl-|pr-)\d/.test(className);
|
|
170
|
+
const cardClasses = `${!hasPadding ? "p-6" : ""} ${className || ""}`.trim();
|
|
169
171
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
170
172
|
"div",
|
|
171
173
|
{
|
|
172
|
-
className:
|
|
174
|
+
className: cardClasses,
|
|
173
175
|
style: mergedStyle,
|
|
174
176
|
...props,
|
|
175
177
|
children: [
|
|
@@ -258,7 +260,6 @@ function useIsomorphicLayoutEffect(effect, deps) {
|
|
|
258
260
|
function Modal({
|
|
259
261
|
open,
|
|
260
262
|
onClose,
|
|
261
|
-
title,
|
|
262
263
|
closeOnBackdrop = true,
|
|
263
264
|
children,
|
|
264
265
|
className = "",
|
|
@@ -299,24 +300,22 @@ function Modal({
|
|
|
299
300
|
return () => window.removeEventListener("keydown", onKey);
|
|
300
301
|
}, [open, onClose]);
|
|
301
302
|
if (!mounted) return null;
|
|
303
|
+
const hasMaxWidth = className?.includes("max-w-");
|
|
304
|
+
const modalClasses = `w-full ${!hasMaxWidth ? "max-w-lg" : ""} ${className || ""}`.trim();
|
|
302
305
|
const modal = /* @__PURE__ */ jsxRuntime.jsx("div", { className: isDark ? "dark" : "", children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
303
306
|
BackgroundBlur,
|
|
304
307
|
{
|
|
305
308
|
open,
|
|
306
309
|
onClose: closeOnBackdrop ? onClose : void 0,
|
|
307
310
|
zIndex,
|
|
308
|
-
children: /* @__PURE__ */ jsxRuntime.
|
|
311
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
309
312
|
Card,
|
|
310
313
|
{
|
|
311
|
-
className:
|
|
314
|
+
className: modalClasses,
|
|
312
315
|
role: "dialog",
|
|
313
316
|
"aria-modal": "true",
|
|
314
|
-
"aria-labelledby": title ? "modal-title" : void 0,
|
|
315
317
|
showDecorations,
|
|
316
|
-
children
|
|
317
|
-
title && /* @__PURE__ */ jsxRuntime.jsx("h2", { id: "modal-title", className: "mb-4 text-xl font-semibold", children: title }),
|
|
318
|
-
/* @__PURE__ */ jsxRuntime.jsx("div", { children })
|
|
319
|
-
]
|
|
318
|
+
children
|
|
320
319
|
}
|
|
321
320
|
)
|
|
322
321
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -60,8 +60,6 @@ type ModalProps = {
|
|
|
60
60
|
onClose?: () => void;
|
|
61
61
|
/** Modal content */
|
|
62
62
|
children?: React.ReactNode;
|
|
63
|
-
/** Optional title (rendered as heading) */
|
|
64
|
-
title?: string;
|
|
65
63
|
/** When true, closes when the backdrop is clicked (default: true) */
|
|
66
64
|
closeOnBackdrop?: boolean;
|
|
67
65
|
/** Custom className for the Card */
|
|
@@ -71,7 +69,7 @@ type ModalProps = {
|
|
|
71
69
|
/** Show decorative elements on the Card (default: true) */
|
|
72
70
|
showDecorations?: boolean;
|
|
73
71
|
};
|
|
74
|
-
declare function Modal({ open, onClose,
|
|
72
|
+
declare function Modal({ open, onClose, closeOnBackdrop, children, className, zIndex, showDecorations, }: ModalProps): React.ReactPortal | null;
|
|
75
73
|
|
|
76
74
|
type TypoVariant = "display-lg" | "display-md" | "display-sm" | "headline-lg" | "headline-md" | "headline-sm" | "title-lg" | "title-md" | "title-sm" | "label-lg" | "label-md" | "label-sm" | "body-lg" | "body-md" | "body-sm" | "button";
|
|
77
75
|
type TypoWeight = "normal" | "medium" | "semibold" | "bold";
|
package/dist/index.d.ts
CHANGED
|
@@ -60,8 +60,6 @@ type ModalProps = {
|
|
|
60
60
|
onClose?: () => void;
|
|
61
61
|
/** Modal content */
|
|
62
62
|
children?: React.ReactNode;
|
|
63
|
-
/** Optional title (rendered as heading) */
|
|
64
|
-
title?: string;
|
|
65
63
|
/** When true, closes when the backdrop is clicked (default: true) */
|
|
66
64
|
closeOnBackdrop?: boolean;
|
|
67
65
|
/** Custom className for the Card */
|
|
@@ -71,7 +69,7 @@ type ModalProps = {
|
|
|
71
69
|
/** Show decorative elements on the Card (default: true) */
|
|
72
70
|
showDecorations?: boolean;
|
|
73
71
|
};
|
|
74
|
-
declare function Modal({ open, onClose,
|
|
72
|
+
declare function Modal({ open, onClose, closeOnBackdrop, children, className, zIndex, showDecorations, }: ModalProps): React.ReactPortal | null;
|
|
75
73
|
|
|
76
74
|
type TypoVariant = "display-lg" | "display-md" | "display-sm" | "headline-lg" | "headline-md" | "headline-sm" | "title-lg" | "title-md" | "title-sm" | "label-lg" | "label-md" | "label-sm" | "body-lg" | "body-md" | "body-sm" | "button";
|
|
77
75
|
type TypoWeight = "normal" | "medium" | "semibold" | "bold";
|
package/dist/index.js
CHANGED
|
@@ -145,10 +145,12 @@ function Card({
|
|
|
145
145
|
transition: "background-color 0.3s ease, color 0.3s ease",
|
|
146
146
|
...style
|
|
147
147
|
};
|
|
148
|
+
const hasPadding = className && /\b(p-|px-|py-|pt-|pb-|pl-|pr-)\d/.test(className);
|
|
149
|
+
const cardClasses = `${!hasPadding ? "p-6" : ""} ${className || ""}`.trim();
|
|
148
150
|
return /* @__PURE__ */ jsxs(
|
|
149
151
|
"div",
|
|
150
152
|
{
|
|
151
|
-
className:
|
|
153
|
+
className: cardClasses,
|
|
152
154
|
style: mergedStyle,
|
|
153
155
|
...props,
|
|
154
156
|
children: [
|
|
@@ -237,7 +239,6 @@ function useIsomorphicLayoutEffect(effect, deps) {
|
|
|
237
239
|
function Modal({
|
|
238
240
|
open,
|
|
239
241
|
onClose,
|
|
240
|
-
title,
|
|
241
242
|
closeOnBackdrop = true,
|
|
242
243
|
children,
|
|
243
244
|
className = "",
|
|
@@ -278,24 +279,22 @@ function Modal({
|
|
|
278
279
|
return () => window.removeEventListener("keydown", onKey);
|
|
279
280
|
}, [open, onClose]);
|
|
280
281
|
if (!mounted) return null;
|
|
282
|
+
const hasMaxWidth = className?.includes("max-w-");
|
|
283
|
+
const modalClasses = `w-full ${!hasMaxWidth ? "max-w-lg" : ""} ${className || ""}`.trim();
|
|
281
284
|
const modal = /* @__PURE__ */ jsx("div", { className: isDark ? "dark" : "", children: /* @__PURE__ */ jsx(
|
|
282
285
|
BackgroundBlur,
|
|
283
286
|
{
|
|
284
287
|
open,
|
|
285
288
|
onClose: closeOnBackdrop ? onClose : void 0,
|
|
286
289
|
zIndex,
|
|
287
|
-
children: /* @__PURE__ */
|
|
290
|
+
children: /* @__PURE__ */ jsx(
|
|
288
291
|
Card,
|
|
289
292
|
{
|
|
290
|
-
className:
|
|
293
|
+
className: modalClasses,
|
|
291
294
|
role: "dialog",
|
|
292
295
|
"aria-modal": "true",
|
|
293
|
-
"aria-labelledby": title ? "modal-title" : void 0,
|
|
294
296
|
showDecorations,
|
|
295
|
-
children
|
|
296
|
-
title && /* @__PURE__ */ jsx("h2", { id: "modal-title", className: "mb-4 text-xl font-semibold", children: title }),
|
|
297
|
-
/* @__PURE__ */ jsx("div", { children })
|
|
298
|
-
]
|
|
297
|
+
children
|
|
299
298
|
}
|
|
300
299
|
)
|
|
301
300
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@neoptocom/neopto-ui",
|
|
3
|
-
"version": "0.9.
|
|
3
|
+
"version": "0.9.7",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "A modern React component library built with Tailwind CSS v4 and TypeScript. Features dark mode, design tokens, and comprehensive Storybook documentation. Requires Tailwind v4+.",
|
|
6
6
|
"keywords": [
|
package/src/components/Card.tsx
CHANGED
|
@@ -29,9 +29,13 @@ export function Card({
|
|
|
29
29
|
...style,
|
|
30
30
|
};
|
|
31
31
|
|
|
32
|
+
// Smart class merging: only add default padding if not provided
|
|
33
|
+
const hasPadding = className && /\b(p-|px-|py-|pt-|pb-|pl-|pr-)\d/.test(className);
|
|
34
|
+
const cardClasses = `${!hasPadding ? "p-6" : ""} ${className || ""}`.trim();
|
|
35
|
+
|
|
32
36
|
return (
|
|
33
37
|
<div
|
|
34
|
-
className={
|
|
38
|
+
className={cardClasses}
|
|
35
39
|
style={mergedStyle}
|
|
36
40
|
{...props}
|
|
37
41
|
>
|
package/src/components/Modal.tsx
CHANGED
|
@@ -10,8 +10,6 @@ export type ModalProps = {
|
|
|
10
10
|
onClose?: () => void;
|
|
11
11
|
/** Modal content */
|
|
12
12
|
children?: React.ReactNode;
|
|
13
|
-
/** Optional title (rendered as heading) */
|
|
14
|
-
title?: string;
|
|
15
13
|
/** When true, closes when the backdrop is clicked (default: true) */
|
|
16
14
|
closeOnBackdrop?: boolean;
|
|
17
15
|
/** Custom className for the Card */
|
|
@@ -30,7 +28,6 @@ function useIsomorphicLayoutEffect(effect: React.EffectCallback, deps?: React.De
|
|
|
30
28
|
export function Modal({
|
|
31
29
|
open,
|
|
32
30
|
onClose,
|
|
33
|
-
title,
|
|
34
31
|
closeOnBackdrop = true,
|
|
35
32
|
children,
|
|
36
33
|
className = "",
|
|
@@ -85,6 +82,10 @@ export function Modal({
|
|
|
85
82
|
|
|
86
83
|
if (!mounted) return null;
|
|
87
84
|
|
|
85
|
+
// Smart class merging: only add defaults if not provided
|
|
86
|
+
const hasMaxWidth = className?.includes("max-w-");
|
|
87
|
+
const modalClasses = `w-full ${!hasMaxWidth ? "max-w-lg" : ""} ${className || ""}`.trim();
|
|
88
|
+
|
|
88
89
|
const modal = (
|
|
89
90
|
<div className={isDark ? "dark" : ""}>
|
|
90
91
|
<BackgroundBlur
|
|
@@ -93,18 +94,12 @@ export function Modal({
|
|
|
93
94
|
zIndex={zIndex}
|
|
94
95
|
>
|
|
95
96
|
<Card
|
|
96
|
-
className={
|
|
97
|
+
className={modalClasses}
|
|
97
98
|
role="dialog"
|
|
98
99
|
aria-modal="true"
|
|
99
|
-
aria-labelledby={title ? "modal-title" : undefined}
|
|
100
100
|
showDecorations={showDecorations}
|
|
101
101
|
>
|
|
102
|
-
{
|
|
103
|
-
<h2 id="modal-title" className="mb-4 text-xl font-semibold">
|
|
104
|
-
{title}
|
|
105
|
-
</h2>
|
|
106
|
-
)}
|
|
107
|
-
<div>{children}</div>
|
|
102
|
+
{children}
|
|
108
103
|
</Card>
|
|
109
104
|
</BackgroundBlur>
|
|
110
105
|
</div>
|
|
@@ -42,27 +42,14 @@ export const Default: Story = {
|
|
|
42
42
|
),
|
|
43
43
|
};
|
|
44
44
|
|
|
45
|
-
export const WithTitle: Story = {
|
|
46
|
-
args: { open: false },
|
|
47
|
-
render: () => (
|
|
48
|
-
<ModalDemo title="Modal Title">
|
|
49
|
-
<Typo variant="body-md">
|
|
50
|
-
This modal includes a title heading. You can still add any content you want below it.
|
|
51
|
-
</Typo>
|
|
52
|
-
<Typo variant="body-sm" className="mt-4 text-[var(--muted-fg)]">
|
|
53
|
-
Try clicking the backdrop to close, or press ESC.
|
|
54
|
-
</Typo>
|
|
55
|
-
</ModalDemo>
|
|
56
|
-
),
|
|
57
|
-
};
|
|
58
45
|
|
|
59
46
|
export const NoBackdropClose: Story = {
|
|
60
47
|
args: { open: false },
|
|
61
48
|
render: () => (
|
|
62
49
|
<ModalDemo
|
|
63
|
-
title="Important Notice"
|
|
64
50
|
closeOnBackdrop={false}
|
|
65
51
|
>
|
|
52
|
+
<Typo variant="headline-md" bold="semibold" className="mb-4">Important Notice</Typo>
|
|
66
53
|
<Typo variant="body-md">
|
|
67
54
|
This modal cannot be closed by clicking the backdrop.
|
|
68
55
|
</Typo>
|
|
@@ -80,9 +67,9 @@ export const CustomStyling: Story = {
|
|
|
80
67
|
args: { open: false },
|
|
81
68
|
render: () => (
|
|
82
69
|
<ModalDemo
|
|
83
|
-
title="Large Modal"
|
|
84
70
|
className="max-w-2xl p-12"
|
|
85
71
|
>
|
|
72
|
+
<Typo variant="headline-md" bold="semibold" className="mb-4">Large Modal</Typo>
|
|
86
73
|
<Typo variant="body-md">
|
|
87
74
|
This modal has custom styling with a larger max-width and more padding.
|
|
88
75
|
</Typo>
|
|
@@ -119,9 +106,9 @@ export const FormModal: Story = {
|
|
|
119
106
|
<Modal
|
|
120
107
|
open={open}
|
|
121
108
|
onClose={() => setOpen(false)}
|
|
122
|
-
title="Contact Form"
|
|
123
109
|
>
|
|
124
110
|
<form onSubmit={handleSubmit}>
|
|
111
|
+
<Typo variant="headline-md" bold="semibold" className="mb-4">Contact Form</Typo>
|
|
125
112
|
<div className="space-y-4">
|
|
126
113
|
<div>
|
|
127
114
|
<label className="block mb-2 text-sm font-medium">Name</label>
|
|
@@ -181,9 +168,9 @@ export const ConfirmationDialog: Story = {
|
|
|
181
168
|
<Modal
|
|
182
169
|
open={open}
|
|
183
170
|
onClose={() => setOpen(false)}
|
|
184
|
-
title="Confirm Deletion"
|
|
185
171
|
closeOnBackdrop={false}
|
|
186
172
|
>
|
|
173
|
+
<Typo variant="headline-md" bold="semibold" className="mb-4">Confirm Deletion</Typo>
|
|
187
174
|
<Typo variant="body-md">
|
|
188
175
|
Are you sure you want to delete this item? This action cannot be undone.
|
|
189
176
|
</Typo>
|
|
@@ -242,7 +229,8 @@ export const WithCardDecorations: Story = {
|
|
|
242
229
|
);
|
|
243
230
|
|
|
244
231
|
return (
|
|
245
|
-
<ModalDemo
|
|
232
|
+
<ModalDemo>
|
|
233
|
+
<Typo variant="headline-md" bold="semibold" className="mb-4">Card with Decorative Elements</Typo>
|
|
246
234
|
<div className="space-y-4">
|
|
247
235
|
<Typo variant="body-md">
|
|
248
236
|
The Card component now includes decorative SVG elements from your Figma design:
|