@fakhrirafiki/theme-engine 0.4.15 → 0.4.17
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 +13 -2
- package/dist/index.js +5 -33
- package/dist/index.mjs +5 -33
- package/dist/styles/components.css +7 -11
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -8,6 +8,9 @@ Theme system for **Next.js (App Router)**: mode (`light | dark | system`) + them
|
|
|
8
8
|

|
|
9
9
|

|
|
10
10
|
|
|
11
|
+
Live demo: https://theme-engine-example.vercel.app/
|
|
12
|
+
Example repo: https://github.com/fakhrirafiki/theme-engine-example
|
|
13
|
+
|
|
11
14
|
## ✨ Why use this?
|
|
12
15
|
|
|
13
16
|
- ⚡ **Fast setup**: 1 CSS import + 1 provider
|
|
@@ -407,7 +410,7 @@ export function ThemePresetSelect({
|
|
|
407
410
|
|
|
408
411
|
{isActive && (
|
|
409
412
|
<span className="inline-flex items-center rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-foreground">
|
|
410
|
-
|
|
413
|
+
Active
|
|
411
414
|
</span>
|
|
412
415
|
)}
|
|
413
416
|
</span>
|
|
@@ -415,7 +418,7 @@ export function ThemePresetSelect({
|
|
|
415
418
|
);
|
|
416
419
|
})}
|
|
417
420
|
|
|
418
|
-
{presets.length === 0 && <p className="text-xs text-muted-foreground">
|
|
421
|
+
{presets.length === 0 && <p className="text-xs text-muted-foreground">No themes available yet.</p>}
|
|
419
422
|
</div>
|
|
420
423
|
);
|
|
421
424
|
}
|
|
@@ -503,6 +506,14 @@ Note: the thrown error string might mention `useTheme` because `useThemeEngine()
|
|
|
503
506
|
|
|
504
507
|
Ensure your `globals.css` imports `@fakhrirafiki/theme-engine/styles` (and Tailwind v4 is configured if you rely on Tailwind utilities).
|
|
505
508
|
|
|
509
|
+
### Turbopack: “module factory is not available” (HMR) after upgrading
|
|
510
|
+
|
|
511
|
+
This is a Next.js Turbopack dev/HMR issue that can happen after updating dependencies in `node_modules` (or when using a locally linked package that rebuilds `dist/` while `next dev` is running).
|
|
512
|
+
|
|
513
|
+
- Restart `next dev` (often enough).
|
|
514
|
+
- If it persists: delete `.next/` and restart.
|
|
515
|
+
- Workaround: run dev server with webpack: `next dev --webpack`
|
|
516
|
+
|
|
506
517
|
---
|
|
507
518
|
|
|
508
519
|
## License
|
package/dist/index.js
CHANGED
|
@@ -4715,29 +4715,10 @@ var MoonIcon = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
|
4715
4715
|
children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("path", { d: "m12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" })
|
|
4716
4716
|
}
|
|
4717
4717
|
);
|
|
4718
|
-
var SystemIcon = () => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
|
|
4719
|
-
"svg",
|
|
4720
|
-
{
|
|
4721
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
4722
|
-
width: "16",
|
|
4723
|
-
height: "16",
|
|
4724
|
-
viewBox: "0 0 24 24",
|
|
4725
|
-
fill: "none",
|
|
4726
|
-
stroke: "currentColor",
|
|
4727
|
-
strokeWidth: "2",
|
|
4728
|
-
strokeLinecap: "round",
|
|
4729
|
-
strokeLinejoin: "round",
|
|
4730
|
-
className: "theme-toggle-icon",
|
|
4731
|
-
children: [
|
|
4732
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("rect", { width: "20", height: "14", x: "2", y: "3", rx: "2" }),
|
|
4733
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "8", x2: "16", y1: "21", y2: "21" }),
|
|
4734
|
-
/* @__PURE__ */ (0, import_jsx_runtime3.jsx)("line", { x1: "12", x2: "12", y1: "17", y2: "21" })
|
|
4735
|
-
]
|
|
4736
|
-
}
|
|
4737
|
-
);
|
|
4738
4718
|
var ThemeToggle = (0, import_react3.forwardRef)(
|
|
4739
4719
|
({ className, size = "md", variant = "default", children, ...props }, ref) => {
|
|
4740
4720
|
const { mode, resolvedMode, toggleMode } = useTheme();
|
|
4721
|
+
const nextResolvedMode = resolvedMode === "light" ? "dark" : "light";
|
|
4741
4722
|
const handleClick = (event) => {
|
|
4742
4723
|
const { clientX: x, clientY: y } = event;
|
|
4743
4724
|
toggleMode({ x, y });
|
|
@@ -4767,16 +4748,7 @@ var ThemeToggle = (0, import_react3.forwardRef)(
|
|
|
4767
4748
|
);
|
|
4768
4749
|
const renderIcon = () => {
|
|
4769
4750
|
if (children) return children;
|
|
4770
|
-
|
|
4771
|
-
case "light":
|
|
4772
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SunIcon, {});
|
|
4773
|
-
case "dark":
|
|
4774
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoonIcon, {});
|
|
4775
|
-
case "system":
|
|
4776
|
-
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SystemIcon, {});
|
|
4777
|
-
default:
|
|
4778
|
-
return resolvedMode === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoonIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SunIcon, {});
|
|
4779
|
-
}
|
|
4751
|
+
return nextResolvedMode === "dark" ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(MoonIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(SunIcon, {});
|
|
4780
4752
|
};
|
|
4781
4753
|
return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
|
|
4782
4754
|
"button",
|
|
@@ -4784,10 +4756,10 @@ var ThemeToggle = (0, import_react3.forwardRef)(
|
|
|
4784
4756
|
ref,
|
|
4785
4757
|
className: baseClasses,
|
|
4786
4758
|
onClick: handleClick,
|
|
4787
|
-
"data-mode":
|
|
4759
|
+
"data-mode": mode,
|
|
4788
4760
|
"data-theme": resolvedMode,
|
|
4789
|
-
"aria-label": `Switch to ${
|
|
4790
|
-
title: `Switch to ${
|
|
4761
|
+
"aria-label": `Switch to ${nextResolvedMode} mode`,
|
|
4762
|
+
title: `Switch to ${nextResolvedMode} mode`,
|
|
4791
4763
|
...props,
|
|
4792
4764
|
children: renderIcon()
|
|
4793
4765
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -4671,29 +4671,10 @@ var MoonIcon = () => /* @__PURE__ */ jsx3(
|
|
|
4671
4671
|
children: /* @__PURE__ */ jsx3("path", { d: "m12 3a6 6 0 0 0 9 9 9 9 0 1 1-9-9Z" })
|
|
4672
4672
|
}
|
|
4673
4673
|
);
|
|
4674
|
-
var SystemIcon = () => /* @__PURE__ */ jsxs2(
|
|
4675
|
-
"svg",
|
|
4676
|
-
{
|
|
4677
|
-
xmlns: "http://www.w3.org/2000/svg",
|
|
4678
|
-
width: "16",
|
|
4679
|
-
height: "16",
|
|
4680
|
-
viewBox: "0 0 24 24",
|
|
4681
|
-
fill: "none",
|
|
4682
|
-
stroke: "currentColor",
|
|
4683
|
-
strokeWidth: "2",
|
|
4684
|
-
strokeLinecap: "round",
|
|
4685
|
-
strokeLinejoin: "round",
|
|
4686
|
-
className: "theme-toggle-icon",
|
|
4687
|
-
children: [
|
|
4688
|
-
/* @__PURE__ */ jsx3("rect", { width: "20", height: "14", x: "2", y: "3", rx: "2" }),
|
|
4689
|
-
/* @__PURE__ */ jsx3("line", { x1: "8", x2: "16", y1: "21", y2: "21" }),
|
|
4690
|
-
/* @__PURE__ */ jsx3("line", { x1: "12", x2: "12", y1: "17", y2: "21" })
|
|
4691
|
-
]
|
|
4692
|
-
}
|
|
4693
|
-
);
|
|
4694
4674
|
var ThemeToggle = forwardRef(
|
|
4695
4675
|
({ className, size = "md", variant = "default", children, ...props }, ref) => {
|
|
4696
4676
|
const { mode, resolvedMode, toggleMode } = useTheme();
|
|
4677
|
+
const nextResolvedMode = resolvedMode === "light" ? "dark" : "light";
|
|
4697
4678
|
const handleClick = (event) => {
|
|
4698
4679
|
const { clientX: x, clientY: y } = event;
|
|
4699
4680
|
toggleMode({ x, y });
|
|
@@ -4723,16 +4704,7 @@ var ThemeToggle = forwardRef(
|
|
|
4723
4704
|
);
|
|
4724
4705
|
const renderIcon = () => {
|
|
4725
4706
|
if (children) return children;
|
|
4726
|
-
|
|
4727
|
-
case "light":
|
|
4728
|
-
return /* @__PURE__ */ jsx3(SunIcon, {});
|
|
4729
|
-
case "dark":
|
|
4730
|
-
return /* @__PURE__ */ jsx3(MoonIcon, {});
|
|
4731
|
-
case "system":
|
|
4732
|
-
return /* @__PURE__ */ jsx3(SystemIcon, {});
|
|
4733
|
-
default:
|
|
4734
|
-
return resolvedMode === "dark" ? /* @__PURE__ */ jsx3(MoonIcon, {}) : /* @__PURE__ */ jsx3(SunIcon, {});
|
|
4735
|
-
}
|
|
4707
|
+
return nextResolvedMode === "dark" ? /* @__PURE__ */ jsx3(MoonIcon, {}) : /* @__PURE__ */ jsx3(SunIcon, {});
|
|
4736
4708
|
};
|
|
4737
4709
|
return /* @__PURE__ */ jsx3(
|
|
4738
4710
|
"button",
|
|
@@ -4740,10 +4712,10 @@ var ThemeToggle = forwardRef(
|
|
|
4740
4712
|
ref,
|
|
4741
4713
|
className: baseClasses,
|
|
4742
4714
|
onClick: handleClick,
|
|
4743
|
-
"data-mode":
|
|
4715
|
+
"data-mode": mode,
|
|
4744
4716
|
"data-theme": resolvedMode,
|
|
4745
|
-
"aria-label": `Switch to ${
|
|
4746
|
-
title: `Switch to ${
|
|
4717
|
+
"aria-label": `Switch to ${nextResolvedMode} mode`,
|
|
4718
|
+
title: `Switch to ${nextResolvedMode} mode`,
|
|
4747
4719
|
...props,
|
|
4748
4720
|
children: renderIcon()
|
|
4749
4721
|
}
|
|
@@ -26,16 +26,17 @@
|
|
|
26
26
|
|
|
27
27
|
/* Icon transition for theme toggle */
|
|
28
28
|
.theme-toggle-icon {
|
|
29
|
+
display: block;
|
|
29
30
|
transition: all 0.3s ease-in-out;
|
|
30
31
|
color: hsl(var(--foreground));
|
|
31
32
|
}
|
|
32
33
|
|
|
33
34
|
.theme-toggle[data-theme="light"] .theme-toggle-icon {
|
|
34
|
-
rotate:
|
|
35
|
+
rotate: 180deg;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
.theme-toggle[data-theme="dark"] .theme-toggle-icon {
|
|
38
|
-
rotate:
|
|
39
|
+
rotate: 0deg;
|
|
39
40
|
}
|
|
40
41
|
|
|
41
42
|
/* ThemePresetButtons: lightweight CSS-based animations and hover affordances */
|
|
@@ -59,10 +60,7 @@
|
|
|
59
60
|
box-shadow: 0 1px 0 hsl(var(--border) / 0.35);
|
|
60
61
|
cursor: pointer;
|
|
61
62
|
|
|
62
|
-
transition:
|
|
63
|
-
transform 0.2s ease-out,
|
|
64
|
-
background-color 0.2s ease-out,
|
|
65
|
-
border-color 0.2s ease-out,
|
|
63
|
+
transition: transform 0.2s ease-out, background-color 0.2s ease-out, border-color 0.2s ease-out,
|
|
66
64
|
box-shadow 0.2s ease-out;
|
|
67
65
|
}
|
|
68
66
|
|
|
@@ -111,9 +109,7 @@
|
|
|
111
109
|
z-index: 20;
|
|
112
110
|
background: hsl(var(--card) / 0.95);
|
|
113
111
|
border-color: hsl(var(--primary) / 0.2);
|
|
114
|
-
box-shadow:
|
|
115
|
-
0 10px 25px hsl(0 0% 0% / 0.12),
|
|
116
|
-
0 0 0 1px hsl(var(--border) / 0.35);
|
|
112
|
+
box-shadow: 0 10px 25px hsl(0 0% 0% / 0.12), 0 0 0 1px hsl(var(--border) / 0.35);
|
|
117
113
|
}
|
|
118
114
|
|
|
119
115
|
/* Color boxes within preset buttons - fallback only */
|
|
@@ -192,7 +188,7 @@
|
|
|
192
188
|
.theme-preset-button {
|
|
193
189
|
min-width: 120px;
|
|
194
190
|
}
|
|
195
|
-
|
|
191
|
+
|
|
196
192
|
.color-palette-grid {
|
|
197
193
|
grid-template-columns: repeat(auto-fit, minmax(100px, 1fr));
|
|
198
194
|
}
|
|
@@ -204,7 +200,7 @@
|
|
|
204
200
|
.theme-preset-button {
|
|
205
201
|
border-width: 2px;
|
|
206
202
|
}
|
|
207
|
-
|
|
203
|
+
|
|
208
204
|
.theme-color-box {
|
|
209
205
|
border-width: 2px;
|
|
210
206
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fakhrirafiki/theme-engine",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.17",
|
|
4
4
|
"description": "Elegant theming system with smooth transitions, custom presets, semantic accent colors, and complete shadcn/ui support for modern React applications",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
"type": "git",
|
|
38
38
|
"url": "git+https://github.com/fakhrirafiki/theme-engine.git"
|
|
39
39
|
},
|
|
40
|
-
"homepage": "https://
|
|
40
|
+
"homepage": "https://theme-engine-example.vercel.app/",
|
|
41
41
|
"bugs": {
|
|
42
42
|
"url": "https://github.com/fakhrirafiki/theme-engine/issues"
|
|
43
43
|
},
|