@jameskabz/nextcraft-ui 0.1.4 → 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 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
- ## Tailwind setup
30
+ ## Styles setup
30
31
 
31
- This library ships class names only. Make sure Tailwind scans your node_modules
32
- for the package so the classes are generated:
32
+ This library ships a precompiled stylesheet. Import it once in your app’s
33
+ global entry:
33
34
 
34
35
  ```ts
35
- // tailwind.config.ts
36
- export default {
37
- content: [
38
- "./src/**/*.{ts,tsx}",
39
- "./node_modules/@jameskabz/nextcraft-ui/dist/**/*.{js,mjs}"
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-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]",
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-sky-400 border-2 border-sky-400/50 hover:border-sky-400 hover:bg-sky-400/10",
51
- gradient: "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]"
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-sky-400 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 disabled:opacity-50 disabled:cursor-not-allowed disabled:hover:scale-100",
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-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" : "",
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 = "ocean",
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: cn2(
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
- cardToneClasses[tone],
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 = "ocean", inputSize = "md", glow = true, icon, ...props }, ref) => {
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: cn3(
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
- inputToneClasses[tone],
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": tone === "aurora" ? "rgba(52,211,153,0.5)" : tone === "ember" ? "rgba(251,191,36,0.5)" : tone === "midnight" ? "rgba(167,139,250,0.5)" : "rgba(56,189,248,0.5)"
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
@@ -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?: "aurora" | "ember" | "ocean" | "midnight" | "cosmic";
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?: CraftInputTone;
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?: CraftInputTone;
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
- export { CraftButton, type CraftButtonProps, CraftInput, type CraftInputProps, GlassCard, type GlassCardProps };
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?: "aurora" | "ember" | "ocean" | "midnight" | "cosmic";
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?: CraftInputTone;
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?: CraftInputTone;
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
- export { CraftButton, type CraftButtonProps, CraftInput, type CraftInputProps, GlassCard, type GlassCardProps };
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 };