@jameskabz/nextcraft-ui 0.2.0 → 0.3.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 +38 -10
- package/dist/index.cjs +149 -35
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +29 -6
- package/dist/index.d.ts +29 -6
- package/dist/index.js +145 -34
- package/dist/index.js.map +1 -1
- package/dist/styles.css +154 -474
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ npm install @jameskabz/nextcraft-ui
|
|
|
11
11
|
## Usage
|
|
12
12
|
|
|
13
13
|
```tsx
|
|
14
|
+
import "@jameskabz/nextcraft-ui/styles.css";
|
|
14
15
|
import { CraftButton, GlassCard } from "@jameskabz/nextcraft-ui";
|
|
15
16
|
|
|
16
17
|
export default function Example() {
|
|
@@ -26,19 +27,46 @@ export default function Example() {
|
|
|
26
27
|
}
|
|
27
28
|
```
|
|
28
29
|
|
|
29
|
-
##
|
|
30
|
+
## Styles setup
|
|
30
31
|
|
|
31
|
-
This library ships
|
|
32
|
-
|
|
32
|
+
This library ships a precompiled stylesheet. Import it once in your app’s
|
|
33
|
+
global entry:
|
|
33
34
|
|
|
34
35
|
```ts
|
|
35
|
-
//
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
36
|
+
// App Router (Next.js)
|
|
37
|
+
import "@jameskabz/nextcraft-ui/styles.css";
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Themes
|
|
41
|
+
|
|
42
|
+
Wrap your app once to enable theme switching:
|
|
43
|
+
|
|
44
|
+
```tsx
|
|
45
|
+
import { ThemeProvider } from "@jameskabz/nextcraft-ui";
|
|
46
|
+
|
|
47
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
48
|
+
return (
|
|
49
|
+
<ThemeProvider>
|
|
50
|
+
{children}
|
|
51
|
+
</ThemeProvider>
|
|
52
|
+
);
|
|
53
|
+
}
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
Add a switcher anywhere in your UI:
|
|
57
|
+
|
|
58
|
+
```tsx
|
|
59
|
+
import { ThemeSwitcher } from "@jameskabz/nextcraft-ui";
|
|
60
|
+
|
|
61
|
+
export function Settings() {
|
|
62
|
+
return <ThemeSwitcher />;
|
|
63
|
+
}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Per-component theme override:
|
|
67
|
+
|
|
68
|
+
```tsx
|
|
69
|
+
<GlassCard tone="ember">...</GlassCard>
|
|
42
70
|
```
|
|
43
71
|
|
|
44
72
|
## Troubleshooting: Module not found
|
package/dist/index.cjs
CHANGED
|
@@ -32,29 +32,37 @@ var index_exports = {};
|
|
|
32
32
|
__export(index_exports, {
|
|
33
33
|
CraftButton: () => CraftButton,
|
|
34
34
|
CraftInput: () => CraftInput,
|
|
35
|
-
GlassCard: () => GlassCard
|
|
35
|
+
GlassCard: () => GlassCard,
|
|
36
|
+
ThemeProvider: () => ThemeProvider,
|
|
37
|
+
ThemeSwitcher: () => ThemeSwitcher,
|
|
38
|
+
useTheme: () => useTheme
|
|
36
39
|
});
|
|
37
40
|
module.exports = __toCommonJS(index_exports);
|
|
38
41
|
|
|
42
|
+
// src/utils/cn.ts
|
|
43
|
+
function cn(...values) {
|
|
44
|
+
return values.filter(Boolean).join(" ");
|
|
45
|
+
}
|
|
46
|
+
|
|
39
47
|
// src/components/craft-button.tsx
|
|
40
48
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
41
|
-
var cn = (...classes) => classes.filter(Boolean).join(" ");
|
|
42
49
|
var sizeClasses = {
|
|
43
50
|
sm: "h-9 px-4 text-xs",
|
|
44
51
|
md: "h-11 px-6 text-sm",
|
|
45
52
|
lg: "h-13 px-8 text-base"
|
|
46
53
|
};
|
|
47
54
|
var variantClasses = {
|
|
48
|
-
solid: "bg-gradient-to-br from-
|
|
55
|
+
solid: "bg-gradient-to-br from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))] text-white shadow-[0_12px_30px_rgb(var(--nc-accent-1)/0.45)] hover:shadow-[0_16px_36px_rgb(var(--nc-accent-1)/0.6)] hover:scale-[1.02] active:scale-[0.98]",
|
|
49
56
|
ghost: "bg-white/5 text-white hover:bg-white/10 backdrop-blur-sm border border-white/10 hover:border-white/20",
|
|
50
|
-
outline: "bg-transparent text-
|
|
51
|
-
gradient: "bg-gradient-to-r from-
|
|
57
|
+
outline: "bg-transparent text-[color:rgb(var(--nc-accent-1))] border-2 border-[color:rgb(var(--nc-accent-1)/0.5)] hover:border-[color:rgb(var(--nc-accent-1))] hover:bg-[color:rgb(var(--nc-accent-1)/0.1)]",
|
|
58
|
+
gradient: "bg-gradient-to-r from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))] text-white shadow-[0_12px_30px_rgb(var(--nc-accent-2)/0.45)] hover:shadow-[0_16px_36px_rgb(var(--nc-accent-2)/0.6)] hover:scale-[1.02] active:scale-[0.98]"
|
|
52
59
|
};
|
|
53
60
|
function CraftButton({
|
|
54
61
|
className,
|
|
55
62
|
variant = "solid",
|
|
56
63
|
size = "md",
|
|
57
64
|
glow = true,
|
|
65
|
+
tone,
|
|
58
66
|
disabled,
|
|
59
67
|
...props
|
|
60
68
|
}) {
|
|
@@ -62,32 +70,21 @@ function CraftButton({
|
|
|
62
70
|
"button",
|
|
63
71
|
{
|
|
64
72
|
className: cn(
|
|
65
|
-
"relative inline-flex items-center justify-center gap-2 rounded-xl font-semibold tracking-wide transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-
|
|
73
|
+
"relative inline-flex items-center justify-center gap-2 rounded-xl font-semibold tracking-wide transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--nc-accent-1)/0.6)] focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100",
|
|
66
74
|
sizeClasses[size],
|
|
67
75
|
variantClasses[variant],
|
|
68
|
-
glow && (variant === "solid" || variant === "gradient") ? "before:absolute before:-inset-1 before:rounded-xl before:bg-linear-to-r before:from-
|
|
76
|
+
glow && (variant === "solid" || variant === "gradient") ? "before:absolute before:-inset-1 before:rounded-xl before:bg-linear-to-r before:from-[rgb(var(--nc-accent-1)/0.2)] before:via-[rgb(var(--nc-accent-2)/0.2)] before:to-[rgb(var(--nc-accent-3)/0.2)] before:blur-xl before:-z-10 before:opacity-0 hover:before:opacity-100 before:transition-opacity" : "",
|
|
69
77
|
className
|
|
70
78
|
),
|
|
79
|
+
"data-nc-theme": tone,
|
|
71
80
|
disabled,
|
|
72
81
|
...props
|
|
73
82
|
}
|
|
74
83
|
);
|
|
75
84
|
}
|
|
76
85
|
|
|
77
|
-
// src/utils/cn.ts
|
|
78
|
-
function cn2(...values) {
|
|
79
|
-
return values.filter(Boolean).join(" ");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
86
|
// src/components/glass-card.tsx
|
|
83
87
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
84
|
-
var cardToneClasses = {
|
|
85
|
-
aurora: "bg-gradient-to-br from-emerald-400/15 via-teal-400/10 to-cyan-400/15 border-emerald-300/30",
|
|
86
|
-
ember: "bg-gradient-to-br from-amber-400/15 via-orange-400/10 to-rose-400/15 border-amber-300/30",
|
|
87
|
-
ocean: "bg-gradient-to-br from-sky-400/15 via-blue-400/10 to-indigo-400/15 border-sky-300/30",
|
|
88
|
-
midnight: "bg-gradient-to-br from-violet-400/15 via-purple-400/10 to-fuchsia-400/15 border-violet-300/30",
|
|
89
|
-
cosmic: "bg-gradient-to-br from-pink-400/15 via-purple-400/10 to-indigo-400/15 border-pink-300/30"
|
|
90
|
-
};
|
|
91
88
|
var intensityClasses = {
|
|
92
89
|
subtle: "backdrop-blur-md bg-opacity-50",
|
|
93
90
|
medium: "backdrop-blur-xl bg-opacity-70",
|
|
@@ -95,7 +92,7 @@ var intensityClasses = {
|
|
|
95
92
|
};
|
|
96
93
|
function GlassCard({
|
|
97
94
|
className,
|
|
98
|
-
tone
|
|
95
|
+
tone,
|
|
99
96
|
intensity = "medium",
|
|
100
97
|
bordered = true,
|
|
101
98
|
children,
|
|
@@ -104,17 +101,19 @@ function GlassCard({
|
|
|
104
101
|
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
105
102
|
"div",
|
|
106
103
|
{
|
|
107
|
-
className:
|
|
104
|
+
className: cn(
|
|
108
105
|
"relative overflow-hidden rounded-3xl p-6 text-white",
|
|
109
106
|
"shadow-[0_8px_32px_rgba(0,0,0,0.3)]",
|
|
110
107
|
"transition-all duration-300",
|
|
111
108
|
"hover:shadow-[0_8px_40px_rgba(0,0,0,0.4)]",
|
|
112
109
|
intensityClasses[intensity],
|
|
113
|
-
|
|
110
|
+
"bg-linear-to-br from-[rgb(var(--nc-accent-1)/0.15)] via-[rgb(var(--nc-accent-2)/0.10)] to-[rgb(var(--nc-accent-3)/0.15)]",
|
|
111
|
+
"border-[rgb(var(--nc-accent-1)/0.3)]",
|
|
114
112
|
bordered ? "border-2" : "border-0",
|
|
115
113
|
"before:absolute before:inset-0 before:bg-linear-to-br before:from-white/10 before:to-transparent before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-300",
|
|
116
114
|
className
|
|
117
115
|
),
|
|
116
|
+
"data-nc-theme": tone,
|
|
118
117
|
...props,
|
|
119
118
|
children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "relative z-10", children })
|
|
120
119
|
}
|
|
@@ -124,40 +123,35 @@ function GlassCard({
|
|
|
124
123
|
// src/components/craft-input.tsx
|
|
125
124
|
var React = __toESM(require("react"), 1);
|
|
126
125
|
var import_jsx_runtime3 = require("react/jsx-runtime");
|
|
127
|
-
var cn3 = (...classes) => classes.filter(Boolean).join(" ");
|
|
128
|
-
var inputToneClasses = {
|
|
129
|
-
aurora: "border-emerald-400/30 focus:border-emerald-400/80 focus:ring-emerald-400/30 placeholder:text-emerald-200/40",
|
|
130
|
-
ember: "border-amber-400/30 focus:border-amber-400/80 focus:ring-amber-400/30 placeholder:text-amber-200/40",
|
|
131
|
-
ocean: "border-sky-400/30 focus:border-sky-400/80 focus:ring-sky-400/30 placeholder:text-sky-200/40",
|
|
132
|
-
midnight: "border-violet-400/30 focus:border-violet-400/80 focus:ring-violet-400/30 placeholder:text-violet-200/40"
|
|
133
|
-
};
|
|
134
126
|
var inputSizeClasses = {
|
|
135
127
|
sm: "h-10 px-4 text-sm",
|
|
136
128
|
md: "h-12 px-5 text-base",
|
|
137
129
|
lg: "h-14 px-6 text-lg"
|
|
138
130
|
};
|
|
139
131
|
var CraftInput = React.forwardRef(
|
|
140
|
-
({ className, tone
|
|
141
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative w-full", children: [
|
|
132
|
+
({ className, tone, inputSize = "md", glow = true, icon, ...props }, ref) => {
|
|
133
|
+
return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "relative w-full", "data-nc-theme": tone, children: [
|
|
142
134
|
icon && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "absolute left-4 top-1/2 -translate-y-1/2 text-white/50", children: icon }),
|
|
143
135
|
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
144
136
|
"input",
|
|
145
137
|
{
|
|
146
138
|
ref,
|
|
147
|
-
className:
|
|
139
|
+
className: cn(
|
|
148
140
|
"w-full rounded-2xl border-2 bg-white/5 text-white backdrop-blur-xl",
|
|
149
141
|
"shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]",
|
|
150
142
|
"focus:outline-none focus:ring-4",
|
|
151
143
|
"transition-all duration-300",
|
|
152
144
|
"disabled:opacity-50 disabled:cursor-not-allowed",
|
|
153
145
|
inputSizeClasses[inputSize],
|
|
154
|
-
|
|
146
|
+
"border-[rgb(var(--nc-accent-1)/0.3)]",
|
|
147
|
+
"focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]",
|
|
148
|
+
"placeholder:text-[rgb(var(--nc-accent-soft)/0.4)]",
|
|
155
149
|
glow ? "focus:shadow-[0_0_30px_-5px_var(--glow-color)]" : "",
|
|
156
150
|
icon ? "pl-12" : "",
|
|
157
151
|
className
|
|
158
152
|
),
|
|
159
153
|
style: {
|
|
160
|
-
"--glow-color":
|
|
154
|
+
"--glow-color": "rgb(var(--nc-accent-1) / 0.5)"
|
|
161
155
|
},
|
|
162
156
|
...props
|
|
163
157
|
}
|
|
@@ -166,10 +160,130 @@ var CraftInput = React.forwardRef(
|
|
|
166
160
|
}
|
|
167
161
|
);
|
|
168
162
|
CraftInput.displayName = "CraftInput";
|
|
163
|
+
|
|
164
|
+
// src/theme/theme-context.tsx
|
|
165
|
+
var React2 = __toESM(require("react"), 1);
|
|
166
|
+
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
167
|
+
var THEME_NAMES = [
|
|
168
|
+
"aurora",
|
|
169
|
+
"ember",
|
|
170
|
+
"ocean",
|
|
171
|
+
"midnight",
|
|
172
|
+
"cosmic"
|
|
173
|
+
];
|
|
174
|
+
var ThemeContext = React2.createContext(null);
|
|
175
|
+
var DEFAULT_THEME_KEY = "nextcraft-theme";
|
|
176
|
+
var DEFAULT_MODE_KEY = "nextcraft-mode";
|
|
177
|
+
function ThemeProvider({
|
|
178
|
+
children,
|
|
179
|
+
defaultTheme = "ocean",
|
|
180
|
+
defaultMode = "system",
|
|
181
|
+
storageKeyTheme = DEFAULT_THEME_KEY,
|
|
182
|
+
storageKeyMode = DEFAULT_MODE_KEY
|
|
183
|
+
}) {
|
|
184
|
+
const [theme, setTheme] = React2.useState(defaultTheme);
|
|
185
|
+
const [mode, setMode] = React2.useState(defaultMode);
|
|
186
|
+
React2.useEffect(() => {
|
|
187
|
+
if (typeof window === "undefined") return;
|
|
188
|
+
try {
|
|
189
|
+
const storedTheme = window.localStorage.getItem(storageKeyTheme);
|
|
190
|
+
const storedMode = window.localStorage.getItem(storageKeyMode);
|
|
191
|
+
if (storedTheme) setTheme(storedTheme);
|
|
192
|
+
if (storedMode) setMode(storedMode);
|
|
193
|
+
} catch {
|
|
194
|
+
}
|
|
195
|
+
}, [storageKeyTheme, storageKeyMode]);
|
|
196
|
+
React2.useEffect(() => {
|
|
197
|
+
if (typeof window === "undefined") return;
|
|
198
|
+
try {
|
|
199
|
+
window.localStorage.setItem(storageKeyTheme, theme);
|
|
200
|
+
window.localStorage.setItem(storageKeyMode, mode);
|
|
201
|
+
} catch {
|
|
202
|
+
}
|
|
203
|
+
}, [theme, mode, storageKeyTheme, storageKeyMode]);
|
|
204
|
+
React2.useEffect(() => {
|
|
205
|
+
if (typeof document === "undefined") return;
|
|
206
|
+
const root = document.documentElement;
|
|
207
|
+
root.dataset.ncTheme = theme;
|
|
208
|
+
if (mode !== "system") {
|
|
209
|
+
root.dataset.ncMode = mode;
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)");
|
|
213
|
+
const applySystem = () => {
|
|
214
|
+
root.dataset.ncMode = mediaQuery.matches ? "dark" : "light";
|
|
215
|
+
};
|
|
216
|
+
applySystem();
|
|
217
|
+
if (typeof mediaQuery.addEventListener === "function") {
|
|
218
|
+
mediaQuery.addEventListener("change", applySystem);
|
|
219
|
+
return () => mediaQuery.removeEventListener("change", applySystem);
|
|
220
|
+
}
|
|
221
|
+
mediaQuery.addListener(applySystem);
|
|
222
|
+
return () => mediaQuery.removeListener(applySystem);
|
|
223
|
+
}, [theme, mode]);
|
|
224
|
+
const value = React2.useMemo(
|
|
225
|
+
() => ({ theme, mode, setTheme, setMode }),
|
|
226
|
+
[theme, mode]
|
|
227
|
+
);
|
|
228
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ThemeContext.Provider, { value, children });
|
|
229
|
+
}
|
|
230
|
+
function useTheme() {
|
|
231
|
+
const context = React2.useContext(ThemeContext);
|
|
232
|
+
if (!context) {
|
|
233
|
+
throw new Error("useTheme must be used within ThemeProvider");
|
|
234
|
+
}
|
|
235
|
+
return context;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
// src/components/theme-switcher.tsx
|
|
239
|
+
var import_jsx_runtime5 = require("react/jsx-runtime");
|
|
240
|
+
var MODE_OPTIONS = ["system", "light", "dark"];
|
|
241
|
+
function ThemeSwitcher({ className, showLabels = true, ...props }) {
|
|
242
|
+
const { theme, mode, setTheme, setMode } = useTheme();
|
|
243
|
+
return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
|
|
244
|
+
"div",
|
|
245
|
+
{
|
|
246
|
+
className: cn(
|
|
247
|
+
"flex flex-wrap items-center gap-3 rounded-2xl border border-white/10 bg-white/5 px-4 py-3 text-sm text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.06)]",
|
|
248
|
+
className
|
|
249
|
+
),
|
|
250
|
+
...props,
|
|
251
|
+
children: [
|
|
252
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "flex items-center gap-2", children: [
|
|
253
|
+
showLabels && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-white/70", children: "Theme" }),
|
|
254
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
255
|
+
"select",
|
|
256
|
+
{
|
|
257
|
+
className: "rounded-lg border border-white/10 bg-white/10 px-3 py-1 text-white outline-none focus:ring-2 focus:ring-[rgb(var(--nc-accent-1)/0.5)]",
|
|
258
|
+
value: theme,
|
|
259
|
+
onChange: (event) => setTheme(event.target.value),
|
|
260
|
+
children: THEME_NAMES.map((name) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value: name, className: "text-slate-900", children: name }, name))
|
|
261
|
+
}
|
|
262
|
+
)
|
|
263
|
+
] }),
|
|
264
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("label", { className: "flex items-center gap-2", children: [
|
|
265
|
+
showLabels && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-white/70", children: "Mode" }),
|
|
266
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
267
|
+
"select",
|
|
268
|
+
{
|
|
269
|
+
className: "rounded-lg border border-white/10 bg-white/10 px-3 py-1 text-white outline-none focus:ring-2 focus:ring-[rgb(var(--nc-accent-1)/0.5)]",
|
|
270
|
+
value: mode,
|
|
271
|
+
onChange: (event) => setMode(event.target.value),
|
|
272
|
+
children: MODE_OPTIONS.map((value) => /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("option", { value, className: "text-slate-900", children: value }, value))
|
|
273
|
+
}
|
|
274
|
+
)
|
|
275
|
+
] })
|
|
276
|
+
]
|
|
277
|
+
}
|
|
278
|
+
);
|
|
279
|
+
}
|
|
169
280
|
// Annotate the CommonJS export names for ESM import in node:
|
|
170
281
|
0 && (module.exports = {
|
|
171
282
|
CraftButton,
|
|
172
283
|
CraftInput,
|
|
173
|
-
GlassCard
|
|
284
|
+
GlassCard,
|
|
285
|
+
ThemeProvider,
|
|
286
|
+
ThemeSwitcher,
|
|
287
|
+
useTheme
|
|
174
288
|
});
|
|
175
289
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/components/craft-button.tsx","../src/utils/cn.ts","../src/components/glass-card.tsx","../src/components/craft-input.tsx"],"sourcesContent":["export { CraftButton } from \"./components/craft-button\";\nexport type { CraftButtonProps } from \"./components/craft-button\";\n\nexport { GlassCard } from \"./components/glass-card\";\nexport type { GlassCardProps } from \"./components/glass-card\";\n\nexport { CraftInput } from \"./components/craft-input\";\nexport type { CraftInputProps } from \"./components/craft-input\";\n","import * as React from \"react\";\n\nconst cn = (...classes: (string | boolean | undefined)[]) => \n classes.filter(Boolean).join(\" \");\n\ntype CraftButtonVariant = \"solid\" | \"ghost\" | \"outline\" | \"gradient\";\ntype CraftButtonSize = \"sm\" | \"md\" | \"lg\";\n\nexport type CraftButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n variant?: CraftButtonVariant;\n size?: CraftButtonSize;\n glow?: boolean;\n};\n\nconst sizeClasses: Record<CraftButtonSize, string> = {\n sm: \"h-9 px-4 text-xs\",\n md: \"h-11 px-6 text-sm\",\n lg: \"h-13 px-8 text-base\",\n};\n\nconst variantClasses: Record<CraftButtonVariant, string> = {\n solid:\n \"bg-gradient-to-br from-sky-400 via-blue-500 to-indigo-600 text-white shadow-lg shadow-blue-500/50 hover:shadow-xl hover:shadow-blue-500/60 hover:scale-[1.02] active:scale-[0.98]\",\n ghost:\n \"bg-white/5 text-white hover:bg-white/10 backdrop-blur-sm border border-white/10 hover:border-white/20\",\n outline:\n \"bg-transparent text-sky-400 border-2 border-sky-400/50 hover:border-sky-400 hover:bg-sky-400/10\",\n gradient:\n \"bg-gradient-to-r from-violet-600 via-fuchsia-500 to-pink-500 text-white shadow-lg shadow-fuchsia-500/50 hover:shadow-xl hover:shadow-fuchsia-500/60 hover:scale-[1.02] active:scale-[0.98]\",\n};\n\nexport function CraftButton({\n className,\n variant = \"solid\",\n size = \"md\",\n glow = true,\n disabled,\n ...props\n}: CraftButtonProps) {\n return (\n <button\n className={cn(\n \"relative inline-flex items-center justify-center gap-2 rounded-xl font-semibold tracking-wide transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-sky-400 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100\",\n sizeClasses[size],\n variantClasses[variant],\n glow && (variant === \"solid\" || variant === \"gradient\")\n ? \"before:absolute before:-inset-1 before:rounded-xl before:bg-linear-to-r before:from-sky-400/20 before:via-blue-500/20 before:to-indigo-600/20 before:blur-xl before:-z-10 before:opacity-0 hover:before:opacity-100 before:transition-opacity\"\n : \"\",\n className\n )}\n disabled={disabled}\n {...props}\n />\n );\n}","export function cn(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(\" \");\n}\n","import { cn } from \"@/utils/cn\";\n\nexport type GlassCardProps = React.HTMLAttributes<HTMLDivElement> & {\n tone?: \"aurora\" | \"ember\" | \"ocean\" | \"midnight\" | \"cosmic\";\n intensity?: \"subtle\" | \"medium\" | \"strong\";\n bordered?: boolean;\n};\n\nconst cardToneClasses: Record<NonNullable<GlassCardProps[\"tone\"]>, string> = {\n aurora:\n \"bg-gradient-to-br from-emerald-400/15 via-teal-400/10 to-cyan-400/15 border-emerald-300/30\",\n ember: \n \"bg-gradient-to-br from-amber-400/15 via-orange-400/10 to-rose-400/15 border-amber-300/30\",\n ocean: \n \"bg-gradient-to-br from-sky-400/15 via-blue-400/10 to-indigo-400/15 border-sky-300/30\",\n midnight:\n \"bg-gradient-to-br from-violet-400/15 via-purple-400/10 to-fuchsia-400/15 border-violet-300/30\",\n cosmic:\n \"bg-gradient-to-br from-pink-400/15 via-purple-400/10 to-indigo-400/15 border-pink-300/30\",\n};\n\nconst intensityClasses: Record<NonNullable<GlassCardProps[\"intensity\"]>, string> = {\n subtle: \"backdrop-blur-md bg-opacity-50\",\n medium: \"backdrop-blur-xl bg-opacity-70\",\n strong: \"backdrop-blur-2xl bg-opacity-90\",\n};\n\nexport function GlassCard({\n className,\n tone = \"ocean\",\n intensity = \"medium\",\n bordered = true,\n children,\n ...props\n}: GlassCardProps) {\n return (\n <div\n className={cn(\n \"relative overflow-hidden rounded-3xl p-6 text-white\",\n \"shadow-[0_8px_32px_rgba(0,0,0,0.3)]\",\n \"transition-all duration-300\",\n \"hover:shadow-[0_8px_40px_rgba(0,0,0,0.4)]\",\n intensityClasses[intensity],\n cardToneClasses[tone],\n bordered ? \"border-2\" : \"border-0\",\n \"before:absolute before:inset-0 before:bg-linear-to-br before:from-white/10 before:to-transparent before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-300\",\n className\n )}\n {...props}\n >\n <div className=\"relative z-10\">{children}</div>\n </div>\n );\n}","\nimport * as React from \"react\";\n\nconst cn = (...classes: (string | boolean | undefined)[]) => \n classes.filter(Boolean).join(\" \");\n\n// ============================================================================\n// CRAFT INPUT\n// ============================================================================\n\ntype CraftInputTone = \"aurora\" | \"ember\" | \"ocean\" | \"midnight\";\ntype CraftInputSize = \"sm\" | \"md\" | \"lg\";\n\nexport type CraftInputProps = Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> & {\n tone?: CraftInputTone;\n inputSize?: CraftInputSize;\n glow?: boolean;\n icon?: React.ReactNode;\n};\n\nconst inputToneClasses: Record<CraftInputTone, string> = {\n aurora:\n \"border-emerald-400/30 focus:border-emerald-400/80 focus:ring-emerald-400/30 placeholder:text-emerald-200/40\",\n ember:\n \"border-amber-400/30 focus:border-amber-400/80 focus:ring-amber-400/30 placeholder:text-amber-200/40\",\n ocean: \n \"border-sky-400/30 focus:border-sky-400/80 focus:ring-sky-400/30 placeholder:text-sky-200/40\",\n midnight:\n \"border-violet-400/30 focus:border-violet-400/80 focus:ring-violet-400/30 placeholder:text-violet-200/40\",\n};\n\nconst inputSizeClasses: Record<CraftInputSize, string> = {\n sm: \"h-10 px-4 text-sm\",\n md: \"h-12 px-5 text-base\",\n lg: \"h-14 px-6 text-lg\",\n};\n\nexport const CraftInput = React.forwardRef<HTMLInputElement, CraftInputProps>(\n (\n { className, tone = \"ocean\", inputSize = \"md\", glow = true, icon, ...props },\n ref\n ) => {\n return (\n <div className=\"relative w-full\">\n {icon && (\n <div className=\"absolute left-4 top-1/2 -translate-y-1/2 text-white/50\">\n {icon}\n </div>\n )}\n <input\n ref={ref}\n className={cn(\n \"w-full rounded-2xl border-2 bg-white/5 text-white backdrop-blur-xl\",\n \"shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]\",\n \"focus:outline-none focus:ring-4\",\n \"transition-all duration-300\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n inputSizeClasses[inputSize],\n inputToneClasses[tone],\n glow ? \"focus:shadow-[0_0_30px_-5px_var(--glow-color)]\" : \"\",\n icon ? \"pl-12\" : \"\",\n className\n )}\n style={{\n \"--glow-color\": tone === \"aurora\" ? \"rgba(52,211,153,0.5)\" : \n tone === \"ember\" ? \"rgba(251,191,36,0.5)\" : \n tone === \"midnight\" ? \"rgba(167,139,250,0.5)\" :\n \"rgba(56,189,248,0.5)\"\n } as React.CSSProperties}\n {...props}\n />\n </div>\n );\n }\n);\n\nCraftInput.displayName = \"CraftInput\";"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACwCI;AAtCJ,IAAM,KAAK,IAAI,YACb,QAAQ,OAAO,OAAO,EAAE,KAAK,GAAG;AAWlC,IAAM,cAA+C;AAAA,EACnD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEA,IAAM,iBAAqD;AAAA,EACzD,OACE;AAAA,EACF,OACE;AAAA,EACF,SACE;AAAA,EACF,UACE;AACJ;AAEO,SAAS,YAAY;AAAA,EAC1B;AAAA,EACA,UAAU;AAAA,EACV,OAAO;AAAA,EACP,OAAO;AAAA,EACP;AAAA,EACA,GAAG;AACL,GAAqB;AACnB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAW;AAAA,QACT;AAAA,QACA,YAAY,IAAI;AAAA,QAChB,eAAe,OAAO;AAAA,QACtB,SAAS,YAAY,WAAW,YAAY,cACxC,kPACA;AAAA,QACJ;AAAA,MACF;AAAA,MACA;AAAA,MACC,GAAG;AAAA;AAAA,EACN;AAEJ;;;ACtDO,SAASA,OAAM,QAA0D;AAC9E,SAAO,OAAO,OAAO,OAAO,EAAE,KAAK,GAAG;AACxC;;;ACgDM,IAAAC,sBAAA;AA1CN,IAAM,kBAAuE;AAAA,EAC3E,QACE;AAAA,EACF,OACE;AAAA,EACF,OACE;AAAA,EACF,UACE;AAAA,EACF,QACE;AACJ;AAEA,IAAM,mBAA6E;AAAA,EACjF,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,QAAQ;AACV;AAEO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,WAAW;AAAA,EACX;AAAA,EACA,GAAG;AACL,GAAmB;AACjB,SACE;AAAA,IAAC;AAAA;AAAA,MACC,WAAWC;AAAA,QACT;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,iBAAiB,SAAS;AAAA,QAC1B,gBAAgB,IAAI;AAAA,QACpB,WAAW,aAAa;AAAA,QACxB;AAAA,QACA;AAAA,MACF;AAAA,MACC,GAAG;AAAA,MAEJ,uDAAC,SAAI,WAAU,iBAAiB,UAAS;AAAA;AAAA,EAC3C;AAEJ;;;ACpDA,YAAuB;AA6CjB,IAAAC,sBAAA;AA3CN,IAAMC,MAAK,IAAI,YACb,QAAQ,OAAO,OAAO,EAAE,KAAK,GAAG;AAmBlC,IAAM,mBAAmD;AAAA,EACvD,QACE;AAAA,EACF,OACE;AAAA,EACF,OACE;AAAA,EACF,UACE;AACJ;AAEA,IAAM,mBAAmD;AAAA,EACvD,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEO,IAAM,aAAmB;AAAA,EAC9B,CACE,EAAE,WAAW,OAAO,SAAS,YAAY,MAAM,OAAO,MAAM,MAAM,GAAG,MAAM,GAC3E,QACG;AACH,WACE,8CAAC,SAAI,WAAU,mBACZ;AAAA,cACC,6CAAC,SAAI,WAAU,0DACZ,gBACH;AAAA,MAEF;AAAA,QAAC;AAAA;AAAA,UACC;AAAA,UACA,WAAWA;AAAA,YACT;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA;AAAA,YACA,iBAAiB,SAAS;AAAA,YAC1B,iBAAiB,IAAI;AAAA,YACrB,OAAO,mDAAmD;AAAA,YAC1D,OAAO,UAAU;AAAA,YACjB;AAAA,UACF;AAAA,UACA,OAAO;AAAA,YACL,gBAAgB,SAAS,WAAW,yBACpB,SAAS,UAAU,yBACnB,SAAS,aAAa,0BACtB;AAAA,UAClB;AAAA,UACC,GAAG;AAAA;AAAA,MACN;AAAA,OACF;AAAA,EAEJ;AACF;AAEA,WAAW,cAAc;","names":["cn","import_jsx_runtime","cn","import_jsx_runtime","cn"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils/cn.ts","../src/components/craft-button.tsx","../src/components/glass-card.tsx","../src/components/craft-input.tsx","../src/theme/theme-context.tsx","../src/components/theme-switcher.tsx"],"sourcesContent":["export { CraftButton } from \"./components/craft-button\";\nexport type { CraftButtonProps } from \"./components/craft-button\";\n\nexport { GlassCard } from \"./components/glass-card\";\nexport type { GlassCardProps } from \"./components/glass-card\";\n\nexport { CraftInput } from \"./components/craft-input\";\nexport type { CraftInputProps } from \"./components/craft-input\";\n\nexport { ThemeSwitcher } from \"./components/theme-switcher\";\nexport type { ThemeSwitcherProps } from \"./components/theme-switcher\";\n\nexport { ThemeProvider, useTheme } from \"./theme/theme-context\";\nexport type { ThemeName, ThemeMode } from \"./theme/theme-context\";\n","export function cn(...values: Array<string | false | null | undefined>): string {\n return values.filter(Boolean).join(\" \");\n}\n","import * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\n\ntype CraftButtonVariant = \"solid\" | \"ghost\" | \"outline\" | \"gradient\";\ntype CraftButtonSize = \"sm\" | \"md\" | \"lg\";\n\nexport type CraftButtonProps = React.ButtonHTMLAttributes<HTMLButtonElement> & {\n variant?: CraftButtonVariant;\n size?: CraftButtonSize;\n glow?: boolean;\n tone?: ThemeName;\n};\n\nconst sizeClasses: Record<CraftButtonSize, string> = {\n sm: \"h-9 px-4 text-xs\",\n md: \"h-11 px-6 text-sm\",\n lg: \"h-13 px-8 text-base\",\n};\n\nconst variantClasses: Record<CraftButtonVariant, string> = {\n solid:\n \"bg-gradient-to-br from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))] text-white shadow-[0_12px_30px_rgb(var(--nc-accent-1)/0.45)] hover:shadow-[0_16px_36px_rgb(var(--nc-accent-1)/0.6)] hover:scale-[1.02] active:scale-[0.98]\",\n ghost:\n \"bg-white/5 text-white hover:bg-white/10 backdrop-blur-sm border border-white/10 hover:border-white/20\",\n outline:\n \"bg-transparent text-[color:rgb(var(--nc-accent-1))] border-2 border-[color:rgb(var(--nc-accent-1)/0.5)] hover:border-[color:rgb(var(--nc-accent-1))] hover:bg-[color:rgb(var(--nc-accent-1)/0.1)]\",\n gradient:\n \"bg-gradient-to-r from-[rgb(var(--nc-accent-1))] via-[rgb(var(--nc-accent-2))] to-[rgb(var(--nc-accent-3))] text-white shadow-[0_12px_30px_rgb(var(--nc-accent-2)/0.45)] hover:shadow-[0_16px_36px_rgb(var(--nc-accent-2)/0.6)] hover:scale-[1.02] active:scale-[0.98]\",\n};\n\nexport function CraftButton({\n className,\n variant = \"solid\",\n size = \"md\",\n glow = true,\n tone,\n disabled,\n ...props\n}: CraftButtonProps) {\n return (\n <button\n className={cn(\n \"relative inline-flex items-center justify-center gap-2 rounded-xl font-semibold tracking-wide transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[rgb(var(--nc-accent-1)/0.6)] focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100\",\n sizeClasses[size],\n variantClasses[variant],\n glow && (variant === \"solid\" || variant === \"gradient\")\n ? \"before:absolute before:-inset-1 before:rounded-xl before:bg-linear-to-r before:from-[rgb(var(--nc-accent-1)/0.2)] before:via-[rgb(var(--nc-accent-2)/0.2)] before:to-[rgb(var(--nc-accent-3)/0.2)] before:blur-xl before:-z-10 before:opacity-0 hover:before:opacity-100 before:transition-opacity\"\n : \"\",\n className\n )}\n data-nc-theme={tone}\n disabled={disabled}\n {...props}\n />\n );\n}\n","import { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\n\nexport type GlassCardProps = React.HTMLAttributes<HTMLDivElement> & {\n tone?: ThemeName;\n intensity?: \"subtle\" | \"medium\" | \"strong\";\n bordered?: boolean;\n};\n\nconst intensityClasses: Record<NonNullable<GlassCardProps[\"intensity\"]>, string> = {\n subtle: \"backdrop-blur-md bg-opacity-50\",\n medium: \"backdrop-blur-xl bg-opacity-70\",\n strong: \"backdrop-blur-2xl bg-opacity-90\",\n};\n\nexport function GlassCard({\n className,\n tone,\n intensity = \"medium\",\n bordered = true,\n children,\n ...props\n}: GlassCardProps) {\n return (\n <div\n className={cn(\n \"relative overflow-hidden rounded-3xl p-6 text-white\",\n \"shadow-[0_8px_32px_rgba(0,0,0,0.3)]\",\n \"transition-all duration-300\",\n \"hover:shadow-[0_8px_40px_rgba(0,0,0,0.4)]\",\n intensityClasses[intensity],\n \"bg-linear-to-br from-[rgb(var(--nc-accent-1)/0.15)] via-[rgb(var(--nc-accent-2)/0.10)] to-[rgb(var(--nc-accent-3)/0.15)]\",\n \"border-[rgb(var(--nc-accent-1)/0.3)]\",\n bordered ? \"border-2\" : \"border-0\",\n \"before:absolute before:inset-0 before:bg-linear-to-br before:from-white/10 before:to-transparent before:opacity-0 hover:before:opacity-100 before:transition-opacity before:duration-300\",\n className\n )}\n data-nc-theme={tone}\n {...props}\n >\n <div className=\"relative z-10\">{children}</div>\n </div>\n );\n}\n","\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport type { ThemeName } from \"@/theme/theme-context\";\n\n// ============================================================================\n// CRAFT INPUT\n// ============================================================================\n\ntype CraftInputSize = \"sm\" | \"md\" | \"lg\";\n\nexport type CraftInputProps = Omit<\n React.InputHTMLAttributes<HTMLInputElement>,\n \"size\"\n> & {\n tone?: ThemeName;\n inputSize?: CraftInputSize;\n glow?: boolean;\n icon?: React.ReactNode;\n};\n\nconst inputSizeClasses: Record<CraftInputSize, string> = {\n sm: \"h-10 px-4 text-sm\",\n md: \"h-12 px-5 text-base\",\n lg: \"h-14 px-6 text-lg\",\n};\n\nexport const CraftInput = React.forwardRef<HTMLInputElement, CraftInputProps>(\n (\n { className, tone, inputSize = \"md\", glow = true, icon, ...props },\n ref\n ) => {\n return (\n <div className=\"relative w-full\" data-nc-theme={tone}>\n {icon && (\n <div className=\"absolute left-4 top-1/2 -translate-y-1/2 text-white/50\">\n {icon}\n </div>\n )}\n <input\n ref={ref}\n className={cn(\n \"w-full rounded-2xl border-2 bg-white/5 text-white backdrop-blur-xl\",\n \"shadow-[inset_0_2px_8px_rgba(0,0,0,0.3)]\",\n \"focus:outline-none focus:ring-4\",\n \"transition-all duration-300\",\n \"disabled:opacity-50 disabled:cursor-not-allowed\",\n inputSizeClasses[inputSize],\n \"border-[rgb(var(--nc-accent-1)/0.3)]\",\n \"focus:border-[rgb(var(--nc-accent-1)/0.8)] focus:ring-[rgb(var(--nc-accent-1)/0.3)]\",\n \"placeholder:text-[rgb(var(--nc-accent-soft)/0.4)]\",\n glow ? \"focus:shadow-[0_0_30px_-5px_var(--glow-color)]\" : \"\",\n icon ? \"pl-12\" : \"\",\n className\n )}\n style={{\n \"--glow-color\": \"rgb(var(--nc-accent-1) / 0.5)\",\n } as React.CSSProperties}\n {...props}\n />\n </div>\n );\n }\n);\n\nCraftInput.displayName = \"CraftInput\";\n","\"use client\";\n\nimport * as React from \"react\";\n\nexport type ThemeName = \"aurora\" | \"ember\" | \"ocean\" | \"midnight\" | \"cosmic\";\nexport type ThemeMode = \"light\" | \"dark\" | \"system\";\n\nexport const THEME_NAMES: ThemeName[] = [\n \"aurora\",\n \"ember\",\n \"ocean\",\n \"midnight\",\n \"cosmic\",\n];\n\ntype ThemeContextValue = {\n theme: ThemeName;\n mode: ThemeMode;\n setTheme: (theme: ThemeName) => void;\n setMode: (mode: ThemeMode) => void;\n};\n\nconst ThemeContext = React.createContext<ThemeContextValue | null>(null);\n\ntype ThemeProviderProps = {\n children: React.ReactNode;\n defaultTheme?: ThemeName;\n defaultMode?: ThemeMode;\n storageKeyTheme?: string;\n storageKeyMode?: string;\n};\n\nconst DEFAULT_THEME_KEY = \"nextcraft-theme\";\nconst DEFAULT_MODE_KEY = \"nextcraft-mode\";\n\nexport function ThemeProvider({\n children,\n defaultTheme = \"ocean\",\n defaultMode = \"system\",\n storageKeyTheme = DEFAULT_THEME_KEY,\n storageKeyMode = DEFAULT_MODE_KEY,\n}: ThemeProviderProps) {\n const [theme, setTheme] = React.useState<ThemeName>(defaultTheme);\n const [mode, setMode] = React.useState<ThemeMode>(defaultMode);\n\n React.useEffect(() => {\n if (typeof window === \"undefined\") return;\n try {\n const storedTheme = window.localStorage.getItem(storageKeyTheme) as ThemeName | null;\n const storedMode = window.localStorage.getItem(storageKeyMode) as ThemeMode | null;\n if (storedTheme) setTheme(storedTheme);\n if (storedMode) setMode(storedMode);\n } catch {\n // Ignore storage errors.\n }\n }, [storageKeyTheme, storageKeyMode]);\n\n React.useEffect(() => {\n if (typeof window === \"undefined\") return;\n try {\n window.localStorage.setItem(storageKeyTheme, theme);\n window.localStorage.setItem(storageKeyMode, mode);\n } catch {\n // Ignore storage errors.\n }\n }, [theme, mode, storageKeyTheme, storageKeyMode]);\n\n React.useEffect(() => {\n if (typeof document === \"undefined\") return;\n const root = document.documentElement;\n root.dataset.ncTheme = theme;\n\n if (mode !== \"system\") {\n root.dataset.ncMode = mode;\n return;\n }\n\n const mediaQuery = window.matchMedia(\"(prefers-color-scheme: dark)\");\n const applySystem = () => {\n root.dataset.ncMode = mediaQuery.matches ? \"dark\" : \"light\";\n };\n\n applySystem();\n\n if (typeof mediaQuery.addEventListener === \"function\") {\n mediaQuery.addEventListener(\"change\", applySystem);\n return () => mediaQuery.removeEventListener(\"change\", applySystem);\n }\n\n mediaQuery.addListener(applySystem);\n return () => mediaQuery.removeListener(applySystem);\n }, [theme, mode]);\n\n const value = React.useMemo(\n () => ({ theme, mode, setTheme, setMode }),\n [theme, mode]\n );\n\n return <ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>;\n}\n\nexport function useTheme() {\n const context = React.useContext(ThemeContext);\n if (!context) {\n throw new Error(\"useTheme must be used within ThemeProvider\");\n }\n return context;\n}\n","\"use client\";\n\nimport * as React from \"react\";\n\nimport { cn } from \"@/utils/cn\";\nimport { THEME_NAMES, type ThemeMode, type ThemeName, useTheme } from \"@/theme/theme-context\";\n\nconst MODE_OPTIONS: ThemeMode[] = [\"system\", \"light\", \"dark\"];\n\nexport type ThemeSwitcherProps = React.HTMLAttributes<HTMLDivElement> & {\n showLabels?: boolean;\n};\n\nexport function ThemeSwitcher({ className, showLabels = true, ...props }: ThemeSwitcherProps) {\n const { theme, mode, setTheme, setMode } = useTheme();\n\n return (\n <div\n className={cn(\n \"flex flex-wrap items-center gap-3 rounded-2xl border border-white/10 bg-white/5 px-4 py-3 text-sm text-white shadow-[inset_0_1px_0_rgba(255,255,255,0.06)]\",\n className\n )}\n {...props}\n >\n <label className=\"flex items-center gap-2\">\n {showLabels && <span className=\"text-white/70\">Theme</span>}\n <select\n className=\"rounded-lg border border-white/10 bg-white/10 px-3 py-1 text-white outline-none focus:ring-2 focus:ring-[rgb(var(--nc-accent-1)/0.5)]\"\n value={theme}\n onChange={(event) => setTheme(event.target.value as ThemeName)}\n >\n {THEME_NAMES.map((name) => (\n <option key={name} value={name} className=\"text-slate-900\">\n {name}\n </option>\n ))}\n </select>\n </label>\n <label className=\"flex items-center gap-2\">\n {showLabels && <span className=\"text-white/70\">Mode</span>}\n <select\n className=\"rounded-lg border border-white/10 bg-white/10 px-3 py-1 text-white outline-none focus:ring-2 focus:ring-[rgb(var(--nc-accent-1)/0.5)]\"\n value={mode}\n onChange={(event) => setMode(event.target.value as ThemeMode)}\n >\n {MODE_OPTIONS.map((value) => (\n <option key={value} value={value} className=\"text-slate-900\">\n {value}\n </option>\n ))}\n </select>\n </label>\n </div>\n );\n}\n"],"mappings":"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","names":["import_jsx_runtime","import_jsx_runtime","React","import_jsx_runtime","import_jsx_runtime"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -1,35 +1,58 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React$1 from 'react';
|
|
3
3
|
|
|
4
|
+
type ThemeName = "aurora" | "ember" | "ocean" | "midnight" | "cosmic";
|
|
5
|
+
type ThemeMode = "light" | "dark" | "system";
|
|
6
|
+
type ThemeContextValue = {
|
|
7
|
+
theme: ThemeName;
|
|
8
|
+
mode: ThemeMode;
|
|
9
|
+
setTheme: (theme: ThemeName) => void;
|
|
10
|
+
setMode: (mode: ThemeMode) => void;
|
|
11
|
+
};
|
|
12
|
+
type ThemeProviderProps = {
|
|
13
|
+
children: React$1.ReactNode;
|
|
14
|
+
defaultTheme?: ThemeName;
|
|
15
|
+
defaultMode?: ThemeMode;
|
|
16
|
+
storageKeyTheme?: string;
|
|
17
|
+
storageKeyMode?: string;
|
|
18
|
+
};
|
|
19
|
+
declare function ThemeProvider({ children, defaultTheme, defaultMode, storageKeyTheme, storageKeyMode, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
|
|
20
|
+
declare function useTheme(): ThemeContextValue;
|
|
21
|
+
|
|
4
22
|
type CraftButtonVariant = "solid" | "ghost" | "outline" | "gradient";
|
|
5
23
|
type CraftButtonSize = "sm" | "md" | "lg";
|
|
6
24
|
type CraftButtonProps = React$1.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
7
25
|
variant?: CraftButtonVariant;
|
|
8
26
|
size?: CraftButtonSize;
|
|
9
27
|
glow?: boolean;
|
|
28
|
+
tone?: ThemeName;
|
|
10
29
|
};
|
|
11
|
-
declare function CraftButton({ className, variant, size, glow, disabled, ...props }: CraftButtonProps): react_jsx_runtime.JSX.Element;
|
|
30
|
+
declare function CraftButton({ className, variant, size, glow, tone, disabled, ...props }: CraftButtonProps): react_jsx_runtime.JSX.Element;
|
|
12
31
|
|
|
13
32
|
type GlassCardProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
14
|
-
tone?:
|
|
33
|
+
tone?: ThemeName;
|
|
15
34
|
intensity?: "subtle" | "medium" | "strong";
|
|
16
35
|
bordered?: boolean;
|
|
17
36
|
};
|
|
18
37
|
declare function GlassCard({ className, tone, intensity, bordered, children, ...props }: GlassCardProps): react_jsx_runtime.JSX.Element;
|
|
19
38
|
|
|
20
|
-
type CraftInputTone = "aurora" | "ember" | "ocean" | "midnight";
|
|
21
39
|
type CraftInputSize = "sm" | "md" | "lg";
|
|
22
40
|
type CraftInputProps = Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "size"> & {
|
|
23
|
-
tone?:
|
|
41
|
+
tone?: ThemeName;
|
|
24
42
|
inputSize?: CraftInputSize;
|
|
25
43
|
glow?: boolean;
|
|
26
44
|
icon?: React$1.ReactNode;
|
|
27
45
|
};
|
|
28
46
|
declare const CraftInput: React$1.ForwardRefExoticComponent<Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "size"> & {
|
|
29
|
-
tone?:
|
|
47
|
+
tone?: ThemeName;
|
|
30
48
|
inputSize?: CraftInputSize;
|
|
31
49
|
glow?: boolean;
|
|
32
50
|
icon?: React$1.ReactNode;
|
|
33
51
|
} & React$1.RefAttributes<HTMLInputElement>>;
|
|
34
52
|
|
|
35
|
-
|
|
53
|
+
type ThemeSwitcherProps = React$1.HTMLAttributes<HTMLDivElement> & {
|
|
54
|
+
showLabels?: boolean;
|
|
55
|
+
};
|
|
56
|
+
declare function ThemeSwitcher({ className, showLabels, ...props }: ThemeSwitcherProps): react_jsx_runtime.JSX.Element;
|
|
57
|
+
|
|
58
|
+
export { CraftButton, type CraftButtonProps, CraftInput, type CraftInputProps, GlassCard, type GlassCardProps, type ThemeMode, type ThemeName, ThemeProvider, ThemeSwitcher, type ThemeSwitcherProps, useTheme };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,35 +1,58 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import * as React$1 from 'react';
|
|
3
3
|
|
|
4
|
+
type ThemeName = "aurora" | "ember" | "ocean" | "midnight" | "cosmic";
|
|
5
|
+
type ThemeMode = "light" | "dark" | "system";
|
|
6
|
+
type ThemeContextValue = {
|
|
7
|
+
theme: ThemeName;
|
|
8
|
+
mode: ThemeMode;
|
|
9
|
+
setTheme: (theme: ThemeName) => void;
|
|
10
|
+
setMode: (mode: ThemeMode) => void;
|
|
11
|
+
};
|
|
12
|
+
type ThemeProviderProps = {
|
|
13
|
+
children: React$1.ReactNode;
|
|
14
|
+
defaultTheme?: ThemeName;
|
|
15
|
+
defaultMode?: ThemeMode;
|
|
16
|
+
storageKeyTheme?: string;
|
|
17
|
+
storageKeyMode?: string;
|
|
18
|
+
};
|
|
19
|
+
declare function ThemeProvider({ children, defaultTheme, defaultMode, storageKeyTheme, storageKeyMode, }: ThemeProviderProps): react_jsx_runtime.JSX.Element;
|
|
20
|
+
declare function useTheme(): ThemeContextValue;
|
|
21
|
+
|
|
4
22
|
type CraftButtonVariant = "solid" | "ghost" | "outline" | "gradient";
|
|
5
23
|
type CraftButtonSize = "sm" | "md" | "lg";
|
|
6
24
|
type CraftButtonProps = React$1.ButtonHTMLAttributes<HTMLButtonElement> & {
|
|
7
25
|
variant?: CraftButtonVariant;
|
|
8
26
|
size?: CraftButtonSize;
|
|
9
27
|
glow?: boolean;
|
|
28
|
+
tone?: ThemeName;
|
|
10
29
|
};
|
|
11
|
-
declare function CraftButton({ className, variant, size, glow, disabled, ...props }: CraftButtonProps): react_jsx_runtime.JSX.Element;
|
|
30
|
+
declare function CraftButton({ className, variant, size, glow, tone, disabled, ...props }: CraftButtonProps): react_jsx_runtime.JSX.Element;
|
|
12
31
|
|
|
13
32
|
type GlassCardProps = React.HTMLAttributes<HTMLDivElement> & {
|
|
14
|
-
tone?:
|
|
33
|
+
tone?: ThemeName;
|
|
15
34
|
intensity?: "subtle" | "medium" | "strong";
|
|
16
35
|
bordered?: boolean;
|
|
17
36
|
};
|
|
18
37
|
declare function GlassCard({ className, tone, intensity, bordered, children, ...props }: GlassCardProps): react_jsx_runtime.JSX.Element;
|
|
19
38
|
|
|
20
|
-
type CraftInputTone = "aurora" | "ember" | "ocean" | "midnight";
|
|
21
39
|
type CraftInputSize = "sm" | "md" | "lg";
|
|
22
40
|
type CraftInputProps = Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "size"> & {
|
|
23
|
-
tone?:
|
|
41
|
+
tone?: ThemeName;
|
|
24
42
|
inputSize?: CraftInputSize;
|
|
25
43
|
glow?: boolean;
|
|
26
44
|
icon?: React$1.ReactNode;
|
|
27
45
|
};
|
|
28
46
|
declare const CraftInput: React$1.ForwardRefExoticComponent<Omit<React$1.InputHTMLAttributes<HTMLInputElement>, "size"> & {
|
|
29
|
-
tone?:
|
|
47
|
+
tone?: ThemeName;
|
|
30
48
|
inputSize?: CraftInputSize;
|
|
31
49
|
glow?: boolean;
|
|
32
50
|
icon?: React$1.ReactNode;
|
|
33
51
|
} & React$1.RefAttributes<HTMLInputElement>>;
|
|
34
52
|
|
|
35
|
-
|
|
53
|
+
type ThemeSwitcherProps = React$1.HTMLAttributes<HTMLDivElement> & {
|
|
54
|
+
showLabels?: boolean;
|
|
55
|
+
};
|
|
56
|
+
declare function ThemeSwitcher({ className, showLabels, ...props }: ThemeSwitcherProps): react_jsx_runtime.JSX.Element;
|
|
57
|
+
|
|
58
|
+
export { CraftButton, type CraftButtonProps, CraftInput, type CraftInputProps, GlassCard, type GlassCardProps, type ThemeMode, type ThemeName, ThemeProvider, ThemeSwitcher, type ThemeSwitcherProps, useTheme };
|