cyhip-dynamic-themes 0.1.5 → 0.2.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
@@ -5,6 +5,12 @@
5
5
 
6
6
  Implement dynamic color themes in your React apps with Tailwind CSS in a simple and practical way. This package also includes native support for dark mode.
7
7
 
8
+ ## Examples
9
+
10
+ - **Vite + React-ts: [cyhip-dynamic-themes](https://cyhip-dynamic-themes.vercel.app/)**
11
+
12
+ - **Nextjs + React-ts: [cyhip-dynamic-themes-nextjs-example](https://cyhip-dynamic-themes-nextjs-example.vercel.app/)**
13
+
8
14
  ## Features
9
15
 
10
16
  - **Dynamic Color Theming**: Allow your users to switch the color theme of your application in a simple and practical way.
@@ -12,6 +18,15 @@ Implement dynamic color themes in your React apps with Tailwind CSS in a simple
12
18
 
13
19
  Inspired by the excellent [article](https://evilmartians.com/chronicles/better-dynamic-themes-in-tailwind-with-oklch-color-magic) by Dan Kozlov and Travis Turner, this package uses the library provided by them which provides a series of features for handling colors and defining dynamic css variables. Take a look at:. [https://github.com/dkzlv/tw-dynamic-themes](https://github.com/dkzlv/tw-dynamic-themes)
14
20
 
21
+ ## How It Works?
22
+
23
+ `cyhip-dynamic-themes` simplifies theme setup with a unique approach:
24
+
25
+ - **Single Hue Input**: Define just the **Hue** value, and the package automatically generates all color variants across the spectrum.
26
+ - **Automatic Color Variants**: Unlike traditional methods, there’s no need to set up each shade manually—simply select a hue, and the package takes care of the rest.
27
+
28
+ - **Custom Hook for Dynamic Theme Switching**: Allow your users to switch themes dynamically with the `useColorTheme` hook.
29
+
15
30
  ## Installation
16
31
 
17
32
  To install the package, run:
package/dist/index.d.ts CHANGED
@@ -1,5 +1,7 @@
1
1
  export { version } from "./__version__";
2
- export { consistentChroma } from "./lib/tw-dynamic-themes/runtime";
2
+ export { consistentChroma as getChroma } from "./lib/tw-dynamic-themes/runtime";
3
3
  export { dynamicTwClasses } from "./lib/tw-dynamic-themes/twPlugin";
4
4
  export { currentAccentValue, getThemeProperties } from "./src/theme-helpers";
5
- export { useColorTheme } from "./src/theme-hook";
5
+ export { useTheme, updateTheme } from "./src/theme-hook";
6
+ export { type ThemeConfig, type ThemeMode, type ThemeColor } from "./src/theme.config";
7
+ export { ThemeProvider } from "./src/theme-provider";
package/dist/index.js CHANGED
@@ -1,5 +1,6 @@
1
1
  export { version } from "./__version__";
2
- export { consistentChroma } from "./lib/tw-dynamic-themes/runtime";
2
+ export { consistentChroma as getChroma } from "./lib/tw-dynamic-themes/runtime";
3
3
  export { dynamicTwClasses } from "./lib/tw-dynamic-themes/twPlugin";
4
4
  export { currentAccentValue, getThemeProperties } from "./src/theme-helpers";
5
- export { useColorTheme } from "./src/theme-hook";
5
+ export { useTheme, updateTheme } from "./src/theme-hook";
6
+ export { ThemeProvider } from "./src/theme-provider";
@@ -2,12 +2,10 @@
2
2
  * A map of CSS varable name to color
3
3
  */
4
4
  type SingleVariable = [string, string];
5
- export declare function getVariables({ baseName, hue, mode, }: {
5
+ export declare function getVariables({ baseName, hue, chromaData, }: {
6
6
  baseName: string;
7
7
  hue: number;
8
- mode?: "bright" | "consistent";
8
+ chromaData?: Record<number, number>;
9
9
  }): SingleVariable[];
10
- export declare function updateVariables(variables: SingleVariable[], el?: HTMLElement): void;
11
- export declare const highestChroma: (shadeIndex: number, hue: number) => string;
12
- export declare const consistentChroma: (i: number, hue: number, whitePalette?: boolean) => string;
10
+ export declare const consistentChroma: (shadeIndex: number, hue: number, chromaData?: Record<number, number>) => string;
13
11
  export {};
@@ -2,21 +2,14 @@ import { toGamut as _toGamut, converter, differenceEuclidean, } from "culori";
2
2
  import { makeVariable, shades } from "./common";
3
3
  var toGamut = _toGamut;
4
4
  export function getVariables(_a) {
5
- var baseName = _a.baseName, hue = _a.hue, _b = _a.mode, mode = _b === void 0 ? "consistent" : _b;
6
- var whitePalette = hue == -1;
7
- var calculator = mode === "bright" ? highestChroma : consistentChroma;
8
- return shades.map(function (shade, shadeIndex) { return [
5
+ var baseName = _a.baseName, hue = _a.hue, _b = _a.chromaData, chromaData = _b === void 0 ? chromaDataDefault : _b;
6
+ var variables = shades.map(function (shade, shadeIndex) { return [
9
7
  makeVariable({ name: baseName, shade: shade }),
10
- calculator(shadeIndex, +hue, whitePalette),
8
+ consistentChroma(shadeIndex, hue, chromaData),
11
9
  ]; });
10
+ return variables;
12
11
  }
13
- export function updateVariables(variables, el) {
14
- var target = el !== null && el !== void 0 ? el : document.documentElement;
15
- for (var _i = 0, variables_1 = variables; _i < variables_1.length; _i++) {
16
- var _a = variables_1[_i], varName = _a[0], value = _a[1];
17
- target.style.setProperty(varName, value + "");
18
- }
19
- }
12
+ ;
20
13
  var lightnessForShade = function (shade) {
21
14
  var highestL = 100;
22
15
  var lowestL = 13;
@@ -27,46 +20,27 @@ var lightnessForShade = function (shade) {
27
20
  return (lowestL + (highestL - diffL * multiplier)) / 100;
28
21
  };
29
22
  var lightness = shades.map(lightnessForShade);
30
- export var highestChroma = function (shadeIndex, hue) {
31
- var oklch = converter("oklch");
32
- // Setting an obsurdly high chroma
33
- var color = "oklch(".concat(lightness[shadeIndex], " 0.4 ").concat(hue, ")");
34
- // Clamping it to the highest chroma possible
35
- return serializeColor(oklch(toGamut("p3", "oklch", differenceEuclidean("oklch"), 0)(color)));
36
- };
37
- export var consistentChroma = function (i, hue, whitePalette) {
38
- if (whitePalette === void 0) { whitePalette = false; }
23
+ export var consistentChroma = function (shadeIndex, hue, chromaData) {
24
+ if (chromaData === void 0) { chromaData = chromaDataDefault; }
39
25
  var oklch = converter("oklch");
26
+ var asWhite = hue === -1;
40
27
  // Using a pinned chroma
41
- var chroma = whitePalette ? chromaData[i] * 0.00001 : chromaData[i];
42
- var light = whitePalette ? lightness[i] * 1.0 : lightness[i] * 0.95;
43
- var color = "oklch(".concat(light, " ").concat(chroma, " ").concat(hue, ")");
28
+ var chroma = !asWhite ? chromaData[shadeIndex] : 0.0;
29
+ var light = !asWhite ? lightness[shadeIndex] * 0.95 : lightness[shadeIndex];
30
+ var color = "oklch(".concat(light, " ").concat(chroma, " ").concat(+hue, ")");
44
31
  return serializeColor(oklch(toGamut("p3", "oklch", differenceEuclidean("oklch"), 0)(color)));
45
32
  };
46
- // const chromaData: Record<number, number> = {
47
- // 0: 0.0108,
48
- // 1: 0.0321,
49
- // 2: 0.0609,
50
- // 3: 0.0908,
51
- // 4: 0.1398,
52
- // 5: 0.1472,
53
- // 6: 0.1299,
54
- // 7: 0.1067,
55
- // 8: 0.0898,
56
- // 9: 0.0726,
57
- // 10: 0.054,
58
- // };
59
- var chromaData = {
60
- 0: 0.0114,
61
- 1: 0.0331,
62
- 2: 0.0774,
63
- 3: 0.1275,
64
- 4: 0.1547,
65
- 5: 0.1355,
66
- 6: 0.1164,
67
- 7: 0.0974,
68
- 8: 0.0782,
69
- 9: 0.0588,
70
- 10: 0.0491,
71
- };
72
33
  var serializeColor = function (c) { var _a; return "".concat(c.l.toFixed(3), " ").concat(c.c.toFixed(3), " ").concat((_a = c.h) === null || _a === void 0 ? void 0 : _a.toFixed(3)); };
34
+ var chromaDataDefault = {
35
+ 0: 0.0108,
36
+ 1: 0.0121,
37
+ 2: 0.0609,
38
+ 3: 0.0908,
39
+ 4: 0.1398,
40
+ 5: 0.1472,
41
+ 6: 0.1299,
42
+ 7: 0.1067,
43
+ 8: 0.0898,
44
+ 9: 0.0726,
45
+ 10: 0.005,
46
+ };
package/dist/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyhip-dynamic-themes",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "Tailwind-powered dynamic color themes for React apps.",
5
5
  "author": "@KassioRF, @CyberHippie-io",
6
6
  "license": "MIT",
@@ -64,7 +64,8 @@
64
64
  "culori": "^4.0.1",
65
65
  "inquirer": "^12.0.0",
66
66
  "react": "^18",
67
- "react-dom": "^18"
67
+ "react-dom": "^18",
68
+ "zustand": "^5.0.1"
68
69
  },
69
70
  "peerDependencies": {
70
71
  "react": "^18",
@@ -1,2 +1,2 @@
1
- declare const rootCss = "\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n/* \n * This is how your global.css or index.css should look like. \n *\n * To see how to apply this variables declared here on tailwind\n * check ./theme-colors.ts properties examples.\n * \n */\n\n@layer base {\n :root {\n /* oklch vars - Applied by dynamic accent colors */\n --background: oklch(var(--accent-100));\n --foreground: oklch(var(--accent-900));\n --primary: oklch(var(--accent-500));\n --primary-foreground: oklch(var(--accent-50));\n --secondary: oklch(var(--accent-800));\n --secondary-foreground: oklch(var(--accent-200));\n --ring: oklch(var(--accent-500));\n --box-shadow: oklch(var(--accent-800) / 0.15);\n --border: oklch(var(--accent-900) / 0.2);\n /* hsl vars */\n --muted: hsl(240 4.8% 95.9%);\n --muted-foreground: hsl(240 3.8% 45%);\n --input: hsl(240 5.9% 80%);\n }\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n @apply outline-accent-500 dark:outline-accent-400;\n }\n *,\n :after,\n :before {\n border-color: theme(\"colors.border\");\n }\n}\n\n.dark {\n /* oklch vars - Applied by dynamic accent colors */\n --background: oklch(var(--accent-900));\n --foreground: oklch(var(--accent-100));\n --primary: oklch(var(--accent-500));\n --primary-foreground: oklch(var(--accent-50));\n --box-shadow: oklch(var(--accent-100) / 0.15);\n --border: oklch(var(--accent-100) / 0.4);\n\n /* hsl vars */\n --muted: hsl(240 4.8% 30%);\n --muted-foreground: hsl(240 3.8% 70%);\n}\n\nbody {\n background-color: var(--background);\n color: var(--foreground);\n}\n";
1
+ declare const rootCss = "\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n/* \n * This is how your global.css or index.css should look like. \n *\n * To see how to apply this variables declared here on tailwind\n * check ./theme-colors.ts properties examples.\n * \n */\n\n@layer base {\n :root {\n /* oklch vars - Applied by dynamic accent colors */\n --background: var(--accent-50);\n --foreground: var(--accent-900);\n --primary: var(--accent-500);\n --primary-foreground: var(--accent-50);\n --secondary: var(--accent-200);\n --secondary-foreground: var(--accent-900);\n --ring: oklch(var(--accent-500) / 0.2);\n --box-shadow: oklch(var(--accent-800) / 0.15);\n --border: oklch(var(--accent-950) / 0.2);\n /* hsl vars */\n --muted: hsl(240 4.8% 95.9% / 0.6);\n --muted-foreground: hsl(240 3.8% 65%);\n --input: hsl(240 5.9% 90% / 0.5);\n }\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n @apply outline-accent-500 dark:outline-accent-400;\n }\n *,\n :after,\n :before {\n border-color: theme('colors.border');\n }\n}\n\n.dark {\n /* oklch vars - Applied by dynamic accent colors */\n --background: var(--accent-950);\n --foreground: var(--accent-100);\n --primary: var(--accent-500);\n --primary-foreground: var(--accent-50);\n --secondary: var(--accent-800);\n --secondary-foreground: var(--accent-200);\n --box-shadow: oklch(var(--accent-100) / 0.1);\n --border: oklch(var(--accent-100) / 0.25);\n\n /* hsl vars */\n --muted: hsl(240 4.8% 25% / 0.7);\n --muted-foreground: hsl(240 3.8% 70%);\n --input: hsl(240 5.9% 80% / 0.8);\n}\n\nbody {\n @apply bg-background dark:bg-background;\n @apply text-foreground;\n overflow-x: hidden;\n}\n\n";
2
2
  export default rootCss;
@@ -1,2 +1,2 @@
1
- var rootCss = "\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n/* \n * This is how your global.css or index.css should look like. \n *\n * To see how to apply this variables declared here on tailwind\n * check ./theme-colors.ts properties examples.\n * \n */\n\n@layer base {\n :root {\n /* oklch vars - Applied by dynamic accent colors */\n --background: oklch(var(--accent-100));\n --foreground: oklch(var(--accent-900));\n --primary: oklch(var(--accent-500));\n --primary-foreground: oklch(var(--accent-50));\n --secondary: oklch(var(--accent-800));\n --secondary-foreground: oklch(var(--accent-200));\n --ring: oklch(var(--accent-500));\n --box-shadow: oklch(var(--accent-800) / 0.15);\n --border: oklch(var(--accent-900) / 0.2);\n /* hsl vars */\n --muted: hsl(240 4.8% 95.9%);\n --muted-foreground: hsl(240 3.8% 45%);\n --input: hsl(240 5.9% 80%);\n }\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n @apply outline-accent-500 dark:outline-accent-400;\n }\n *,\n :after,\n :before {\n border-color: theme(\"colors.border\");\n }\n}\n\n.dark {\n /* oklch vars - Applied by dynamic accent colors */\n --background: oklch(var(--accent-900));\n --foreground: oklch(var(--accent-100));\n --primary: oklch(var(--accent-500));\n --primary-foreground: oklch(var(--accent-50));\n --box-shadow: oklch(var(--accent-100) / 0.15);\n --border: oklch(var(--accent-100) / 0.4);\n\n /* hsl vars */\n --muted: hsl(240 4.8% 30%);\n --muted-foreground: hsl(240 3.8% 70%);\n}\n\nbody {\n background-color: var(--background);\n color: var(--foreground);\n}\n";
1
+ var rootCss = "\n@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n/* \n * This is how your global.css or index.css should look like. \n *\n * To see how to apply this variables declared here on tailwind\n * check ./theme-colors.ts properties examples.\n * \n */\n\n@layer base {\n :root {\n /* oklch vars - Applied by dynamic accent colors */\n --background: var(--accent-50);\n --foreground: var(--accent-900);\n --primary: var(--accent-500);\n --primary-foreground: var(--accent-50);\n --secondary: var(--accent-200);\n --secondary-foreground: var(--accent-900);\n --ring: oklch(var(--accent-500) / 0.2);\n --box-shadow: oklch(var(--accent-800) / 0.15);\n --border: oklch(var(--accent-950) / 0.2);\n /* hsl vars */\n --muted: hsl(240 4.8% 95.9% / 0.6);\n --muted-foreground: hsl(240 3.8% 65%);\n --input: hsl(240 5.9% 90% / 0.5);\n }\n * {\n margin: 0;\n padding: 0;\n box-sizing: border-box;\n @apply outline-accent-500 dark:outline-accent-400;\n }\n *,\n :after,\n :before {\n border-color: theme('colors.border');\n }\n}\n\n.dark {\n /* oklch vars - Applied by dynamic accent colors */\n --background: var(--accent-950);\n --foreground: var(--accent-100);\n --primary: var(--accent-500);\n --primary-foreground: var(--accent-50);\n --secondary: var(--accent-800);\n --secondary-foreground: var(--accent-200);\n --box-shadow: oklch(var(--accent-100) / 0.1);\n --border: oklch(var(--accent-100) / 0.25);\n\n /* hsl vars */\n --muted: hsl(240 4.8% 25% / 0.7);\n --muted-foreground: hsl(240 3.8% 70%);\n --input: hsl(240 5.9% 80% / 0.8);\n}\n\nbody {\n @apply bg-background dark:bg-background;\n @apply text-foreground;\n overflow-x: hidden;\n}\n\n";
2
2
  export default rootCss;
@@ -1,2 +1,2 @@
1
- declare const themeColors = "\n\n/**\n * COLORS\n * \n * You can use this on tailwindcss.config.ts as follows:\n * \n * import type { Config } from \"tailwindcss\";\n * import { themeColors } from \"./src/themes/theme-colors\";\n *\n * export default {\n * content: [\"./index.html\", \".\\src\\**\\*.{js,ts,jsx,tsx}\"],\n * darkMode: \"class\",\n * theme: {\n * extend: {\n * colors: themeColors,\n * },\n * },\n * plugins: [],\n * } satisfies Config;\n *\n * \n */\n\nimport colors from \"tailwindcss/colors\";\nimport { dynamicTwClasses } from \"cyhip-dynamic-themes\";\n\nexport const themeColors = {\n // accent vars to allow dynamic color changes\n accent: dynamicTwClasses(\"accent\", 250),\n // static colors as you wish...\n white: colors.white,\n destructive: colors.red,\n success: colors.green,\n /**\n * You can customize this css vars based on accent values.\n * Take a look at root.css\n */\n background: \"var(--background)\",\n foreground: \"var(--foreground)\",\n primary: {\n DEFAULT: \"var(--primary)\",\n foreground: \"var(--primary-foreground)\",\n },\n secondary: {\n DEFAULT: \"var(--secondary)\",\n foreground: \"var(--foreground)\",\n },\n muted: {\n DEFAULT: \"var(--muted)\",\n foreground: \"var(--muted-foreground)\",\n },\n border: \"var(--border)\",\n ring: \"var(--ring)\",\n input: \"var(--input)\",\n};";
1
+ declare const themeColors = "\n\n/**\n * COLORS\n *\n * You can use this on tailwindcss.config.ts as follows:\n *\n * import type { Config } from \"tailwindcss\";\n * import { themeColors } from \"./src/themes/theme-colors\";\n *\n * export default {\n * content: [\"./index.html\", \".src***.{js,ts,jsx,tsx}\"],\n * darkMode: \"class\",\n * theme: {\n * extend: {\n * colors: themeColors,\n * },\n * },\n * plugins: [],\n * } satisfies Config;\n *\n *\n */\n\nimport { dynamicTwClasses } from 'cyhip-dynamic-themes';\nimport colors from 'tailwindcss/colors';\nimport { hueScheme } from './theme.config';\n\nexport const themeColors = {\n // accent vars to allow dynamic color changes\n accent: dynamicTwClasses('accent', hueScheme.default),\n // static colors as you wish...\n white: colors.white,\n destructive: colors.red,\n success: colors.green,\n /**\n * You can customize this css vars based on accent values.\n * Take a look at root.css\n */\n background: 'oklch(var(--background) / <alpha-value>)',\n\n foreground: 'oklch(var(--foreground) / <alpha-value>)',\n primary: {\n DEFAULT: 'oklch(var(--primary) / <alpha-value>)',\n foreground: 'oklch(var(--primary-foreground) / <alpha-value>)',\n },\n secondary: {\n DEFAULT: 'oklch(var(--secondary) / <alpha-value>)',\n foreground: 'oklch(var(--secondary-foreground) / <alpha-value>)',\n },\n muted: {\n DEFAULT: 'var(--muted)',\n foreground: 'var(--muted-foreground)',\n },\n border: 'var(--border)',\n ring: 'var(--ring)',\n input: 'var(--input)',\n};\n\n";
2
2
  export default themeColors;
@@ -1,2 +1,2 @@
1
- var themeColors = "\n\n/**\n * COLORS\n * \n * You can use this on tailwindcss.config.ts as follows:\n * \n * import type { Config } from \"tailwindcss\";\n * import { themeColors } from \"./src/themes/theme-colors\";\n *\n * export default {\n * content: [\"./index.html\", \".\\src\\**\\*.{js,ts,jsx,tsx}\"],\n * darkMode: \"class\",\n * theme: {\n * extend: {\n * colors: themeColors,\n * },\n * },\n * plugins: [],\n * } satisfies Config;\n *\n * \n */\n\nimport colors from \"tailwindcss/colors\";\nimport { dynamicTwClasses } from \"cyhip-dynamic-themes\";\n\nexport const themeColors = {\n // accent vars to allow dynamic color changes\n accent: dynamicTwClasses(\"accent\", 250),\n // static colors as you wish...\n white: colors.white,\n destructive: colors.red,\n success: colors.green,\n /**\n * You can customize this css vars based on accent values.\n * Take a look at root.css\n */\n background: \"var(--background)\",\n foreground: \"var(--foreground)\",\n primary: {\n DEFAULT: \"var(--primary)\",\n foreground: \"var(--primary-foreground)\",\n },\n secondary: {\n DEFAULT: \"var(--secondary)\",\n foreground: \"var(--foreground)\",\n },\n muted: {\n DEFAULT: \"var(--muted)\",\n foreground: \"var(--muted-foreground)\",\n },\n border: \"var(--border)\",\n ring: \"var(--ring)\",\n input: \"var(--input)\",\n};";
1
+ var themeColors = "\n\n/**\n * COLORS\n *\n * You can use this on tailwindcss.config.ts as follows:\n *\n * import type { Config } from \"tailwindcss\";\n * import { themeColors } from \"./src/themes/theme-colors\";\n *\n * export default {\n * content: [\"./index.html\", \".src***.{js,ts,jsx,tsx}\"],\n * darkMode: \"class\",\n * theme: {\n * extend: {\n * colors: themeColors,\n * },\n * },\n * plugins: [],\n * } satisfies Config;\n *\n *\n */\n\nimport { dynamicTwClasses } from 'cyhip-dynamic-themes';\nimport colors from 'tailwindcss/colors';\nimport { hueScheme } from './theme.config';\n\nexport const themeColors = {\n // accent vars to allow dynamic color changes\n accent: dynamicTwClasses('accent', hueScheme.default),\n // static colors as you wish...\n white: colors.white,\n destructive: colors.red,\n success: colors.green,\n /**\n * You can customize this css vars based on accent values.\n * Take a look at root.css\n */\n background: 'oklch(var(--background) / <alpha-value>)',\n\n foreground: 'oklch(var(--foreground) / <alpha-value>)',\n primary: {\n DEFAULT: 'oklch(var(--primary) / <alpha-value>)',\n foreground: 'oklch(var(--primary-foreground) / <alpha-value>)',\n },\n secondary: {\n DEFAULT: 'oklch(var(--secondary) / <alpha-value>)',\n foreground: 'oklch(var(--secondary-foreground) / <alpha-value>)',\n },\n muted: {\n DEFAULT: 'var(--muted)',\n foreground: 'var(--muted-foreground)',\n },\n border: 'var(--border)',\n ring: 'var(--ring)',\n input: 'var(--input)',\n};\n\n";
2
2
  export default themeColors;
@@ -1,2 +1,2 @@
1
- declare const themeSwitcher = "\n// \"use client\"; // enable this if you are using Nextjs\n/**\n * ThemeSwitcher component\n *\n * A simlpe example about how you can define a ThemeSwitcher component.\n *\n */\n\nimport { consistentChroma, useColorTheme } from \"cyhip-dynamic-themes\";\nimport { forwardRef, HTMLAttributes, useEffect, useState } from \"react\";\nimport { hueScheme } from \"./hue-palettes\";\n\n/**\n * This methods are used only to build a gradient sample based on the hue value.\n * Used for a visual referrence as a \"icon\" of the theme on the buttons.\n */\nconst buildThemeSample = (hue: number, whitePalette: boolean = false) => {\n const oklchA = 'oklch(' + consistentChroma(4, +hue, whitePalette) + ')';\n const oklchB = 'oklch(' + consistentChroma(5, +hue, whitePalette) + ')';\n const oklchC = 'oklch(' + consistentChroma(6, +hue, whitePalette) + ')';\n const gradient = 'linear-gradient(70deg, ' + oklchA + ', ' + oklchB + ', ' + oklchC + ')';\n return gradient;\n};\n\nconst availableThemes: Record<string, string> = Object.keys(hueScheme).reduce(\n (acc, key) => {\n const value = hueScheme[key];\n acc[key] = buildThemeSample(value, value === -1);\n return acc;\n },\n {} as Record<string, string>\n);\n\nconst ThemeSwitcher = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ ...props }, ref) => {\n /** To initialize here you can manage cookie values to reminder user preferences. */\n const [isMounted, setIsMounted] = useState(false);\n\n const [darkMode, setDarkMode] = useState(false);\n const [hue, setHue] = useState(hueScheme.blue);\n const { setTheme } = useColorTheme(hue, darkMode);\n\n useEffect(() => {\n if (!isMounted) return;\n setTheme(hue, darkMode);\n }, [hue, darkMode, setTheme, isMounted]);\n\n useEffect(() => {\n setIsMounted(true);\n }, []);\n\n return (\n <>\n <div\n ref={ref}\n className=\"bg-accent-200/40 dark:bg-accent-700/40 grid grid-cols-3 rounded-sm gap-2 p-6\"\n {...props}\n >\n {Object.keys(availableThemes).map((key) => (\n <button\n key={key}\n className=\"bg-background px-4 py-1 text-sm font-medium rounded-ms border flex space-x-2 hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setHue(hueScheme[key])}\n >\n <span\n className=\"w-4 h-4 rounded-full\"\n style={{\n background: availableThemes[key],\n }}\n ></span>\n <span>{key}</span>\n </button>\n ))}\n <div className=\"col-span-3 grid grid-cols-2 gap-x-2 mx-auto\">\n <button\n className=\"bg-background border px-4 py-1 text-sm font-medium rounded-ms hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setDarkMode(false)}\n >\n Light\n </button>\n <button\n className=\"bg-background border px-4 py-1 text-sm font-medium rounded-ms hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setDarkMode(true)}\n >\n Dark\n </button>\n </div>\n </div>\n </>\n );\n});\n\nThemeSwitcher.displayName = \"ThemeSwitcher\";\n\nexport { ThemeSwitcher };\n\n";
1
+ declare const themeSwitcher = "\n// \"use client\"; // enable this if you are using Nextjs\n/**\n * ThemeSwitcher component\n *\n * A simlpe example about how you can define a ThemeSwitcher component.\n *\n */\n\nimport { getChroma, ThemeConfig, useTheme } from 'cyhip-dynamic-themes';\nimport { forwardRef, HTMLAttributes, useEffect, useState } from 'react';\nimport { chromaData, hueScheme } from './theme.config';\n\n/**\n * This methods are used only to build a gradient sample based on the hue value.\n * Used for a visual referrence as a \"icon\" of the theme on the buttons.\n */\nconst buildThemeSample = (hue: number) => {\n const oklch = 'oklch(' + getChroma(5, hue, chromaData) + ')';\n return oklch;\n};\n\nconst availableThemes: Record<string, string> = Object.keys(hueScheme).reduce(\n (acc, key) => {\n const value = hueScheme[key];\n acc[key] = buildThemeSample(value);\n return acc;\n },\n {} as Record<string, string>\n);\n\nconst ThemeSwitcher = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ ...props }, ref) => {\n /** To initialize here you can manage cookie values to reminder user preferences. */\n const { theme, setTheme } = useTheme();\n const [hue, setHue] = useState(theme.hue);\n const [darkMode, setDarkMode] = useState(theme.mode === 'light');\n\n useEffect(() => {\n setTheme({\n hue,\n mode: darkMode ? 'dark' : 'light',\n chromaData: chromaData,\n } as ThemeConfig);\n }, [hue, darkMode, setTheme]);\n\n return (\n <>\n <div\n ref={ref}\n className=\"bg-accent-200/40 dark:bg-accent-700/40 grid grid-cols-3 rounded-sm gap-2 p-6\"\n {...props}\n >\n {Object.keys(availableThemes).map((key) => (\n <button\n key={key}\n className=\"bg-background px-4 py-1 text-sm font-medium rounded-ms border flex space-x-2 hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setHue(hueScheme[key])}\n >\n <span\n className=\"w-4 h-4 rounded-full\"\n style={{\n background: availableThemes[key],\n }}\n ></span>\n <span>{key}</span>\n </button>\n ))}\n <div className=\"col-span-3 grid grid-cols-2 gap-x-2 mx-auto\">\n <button\n className=\"bg-background border px-4 py-1 text-sm font-medium rounded-ms hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setDarkMode(false)}\n >\n Light\n </button>\n <button\n className=\"bg-background border px-4 py-1 text-sm font-medium rounded-ms hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setDarkMode(true)}\n >\n Dark\n </button>\n </div>\n </div>\n </>\n );\n});\n\nThemeSwitcher.displayName = 'ThemeSwitcher';\n\nexport { ThemeSwitcher };\n\n\n";
2
2
  export default themeSwitcher;
@@ -1,2 +1,2 @@
1
- var themeSwitcher = "\n// \"use client\"; // enable this if you are using Nextjs\n/**\n * ThemeSwitcher component\n *\n * A simlpe example about how you can define a ThemeSwitcher component.\n *\n */\n\nimport { consistentChroma, useColorTheme } from \"cyhip-dynamic-themes\";\nimport { forwardRef, HTMLAttributes, useEffect, useState } from \"react\";\nimport { hueScheme } from \"./hue-palettes\";\n\n/**\n * This methods are used only to build a gradient sample based on the hue value.\n * Used for a visual referrence as a \"icon\" of the theme on the buttons.\n */\nconst buildThemeSample = (hue: number, whitePalette: boolean = false) => {\n const oklchA = 'oklch(' + consistentChroma(4, +hue, whitePalette) + ')';\n const oklchB = 'oklch(' + consistentChroma(5, +hue, whitePalette) + ')';\n const oklchC = 'oklch(' + consistentChroma(6, +hue, whitePalette) + ')';\n const gradient = 'linear-gradient(70deg, ' + oklchA + ', ' + oklchB + ', ' + oklchC + ')';\n return gradient;\n};\n\nconst availableThemes: Record<string, string> = Object.keys(hueScheme).reduce(\n (acc, key) => {\n const value = hueScheme[key];\n acc[key] = buildThemeSample(value, value === -1);\n return acc;\n },\n {} as Record<string, string>\n);\n\nconst ThemeSwitcher = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ ...props }, ref) => {\n /** To initialize here you can manage cookie values to reminder user preferences. */\n const [isMounted, setIsMounted] = useState(false);\n\n const [darkMode, setDarkMode] = useState(false);\n const [hue, setHue] = useState(hueScheme.blue);\n const { setTheme } = useColorTheme(hue, darkMode);\n\n useEffect(() => {\n if (!isMounted) return;\n setTheme(hue, darkMode);\n }, [hue, darkMode, setTheme, isMounted]);\n\n useEffect(() => {\n setIsMounted(true);\n }, []);\n\n return (\n <>\n <div\n ref={ref}\n className=\"bg-accent-200/40 dark:bg-accent-700/40 grid grid-cols-3 rounded-sm gap-2 p-6\"\n {...props}\n >\n {Object.keys(availableThemes).map((key) => (\n <button\n key={key}\n className=\"bg-background px-4 py-1 text-sm font-medium rounded-ms border flex space-x-2 hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setHue(hueScheme[key])}\n >\n <span\n className=\"w-4 h-4 rounded-full\"\n style={{\n background: availableThemes[key],\n }}\n ></span>\n <span>{key}</span>\n </button>\n ))}\n <div className=\"col-span-3 grid grid-cols-2 gap-x-2 mx-auto\">\n <button\n className=\"bg-background border px-4 py-1 text-sm font-medium rounded-ms hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setDarkMode(false)}\n >\n Light\n </button>\n <button\n className=\"bg-background border px-4 py-1 text-sm font-medium rounded-ms hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setDarkMode(true)}\n >\n Dark\n </button>\n </div>\n </div>\n </>\n );\n});\n\nThemeSwitcher.displayName = \"ThemeSwitcher\";\n\nexport { ThemeSwitcher };\n\n";
1
+ var themeSwitcher = "\n// \"use client\"; // enable this if you are using Nextjs\n/**\n * ThemeSwitcher component\n *\n * A simlpe example about how you can define a ThemeSwitcher component.\n *\n */\n\nimport { getChroma, ThemeConfig, useTheme } from 'cyhip-dynamic-themes';\nimport { forwardRef, HTMLAttributes, useEffect, useState } from 'react';\nimport { chromaData, hueScheme } from './theme.config';\n\n/**\n * This methods are used only to build a gradient sample based on the hue value.\n * Used for a visual referrence as a \"icon\" of the theme on the buttons.\n */\nconst buildThemeSample = (hue: number) => {\n const oklch = 'oklch(' + getChroma(5, hue, chromaData) + ')';\n return oklch;\n};\n\nconst availableThemes: Record<string, string> = Object.keys(hueScheme).reduce(\n (acc, key) => {\n const value = hueScheme[key];\n acc[key] = buildThemeSample(value);\n return acc;\n },\n {} as Record<string, string>\n);\n\nconst ThemeSwitcher = forwardRef<\n HTMLDivElement,\n HTMLAttributes<HTMLDivElement>\n>(({ ...props }, ref) => {\n /** To initialize here you can manage cookie values to reminder user preferences. */\n const { theme, setTheme } = useTheme();\n const [hue, setHue] = useState(theme.hue);\n const [darkMode, setDarkMode] = useState(theme.mode === 'light');\n\n useEffect(() => {\n setTheme({\n hue,\n mode: darkMode ? 'dark' : 'light',\n chromaData: chromaData,\n } as ThemeConfig);\n }, [hue, darkMode, setTheme]);\n\n return (\n <>\n <div\n ref={ref}\n className=\"bg-accent-200/40 dark:bg-accent-700/40 grid grid-cols-3 rounded-sm gap-2 p-6\"\n {...props}\n >\n {Object.keys(availableThemes).map((key) => (\n <button\n key={key}\n className=\"bg-background px-4 py-1 text-sm font-medium rounded-ms border flex space-x-2 hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setHue(hueScheme[key])}\n >\n <span\n className=\"w-4 h-4 rounded-full\"\n style={{\n background: availableThemes[key],\n }}\n ></span>\n <span>{key}</span>\n </button>\n ))}\n <div className=\"col-span-3 grid grid-cols-2 gap-x-2 mx-auto\">\n <button\n className=\"bg-background border px-4 py-1 text-sm font-medium rounded-ms hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setDarkMode(false)}\n >\n Light\n </button>\n <button\n className=\"bg-background border px-4 py-1 text-sm font-medium rounded-ms hover:ring-1 hover:ring-offset-2 hover:ring-offset-background hover:ring-primary\"\n onClick={() => setDarkMode(true)}\n >\n Dark\n </button>\n </div>\n </div>\n </>\n );\n});\n\nThemeSwitcher.displayName = 'ThemeSwitcher';\n\nexport { ThemeSwitcher };\n\n\n";
2
2
  export default themeSwitcher;
@@ -0,0 +1,2 @@
1
+ declare const themeConfig = "\n\n/**\n * HUE THEMES\n *\n * Define the available color palettes here!\n *\n * The palettes are based on HUE values.\n *\n * To add or modify a HUE palette, explore and preview colors at:\n * https://oklch.com/#70,0.1,250,100\n *\n */\n\nexport const hueScheme: Record<string, number> = {\n default: -1,\n blue: 250,\n green: 150,\n orange: 35,\n pink: 0,\n purple: 316,\n};\n\n/**\n *\n * Default Chroma for each shade available on theme. See more at:\n * https://evilmartians.com/chronicles/better-dynamic-themes-in-tailwind-with-oklch-color-magic\n *\n */\nexport const chromaData: Record<number, number> = {\n 0: 0.0108,\n 1: 0.0121,\n 2: 0.0609,\n 3: 0.0908,\n 4: 0.1398,\n 5: 0.1472,\n 6: 0.1299,\n 7: 0.1067,\n 8: 0.0898,\n 9: 0.0726,\n 10: 0.005,\n};\n\n";
2
+ export default themeConfig;
@@ -0,0 +1,2 @@
1
+ var themeConfig = "\n\n/**\n * HUE THEMES\n *\n * Define the available color palettes here!\n *\n * The palettes are based on HUE values.\n *\n * To add or modify a HUE palette, explore and preview colors at:\n * https://oklch.com/#70,0.1,250,100\n *\n */\n\nexport const hueScheme: Record<string, number> = {\n default: -1,\n blue: 250,\n green: 150,\n orange: 35,\n pink: 0,\n purple: 316,\n};\n\n/**\n *\n * Default Chroma for each shade available on theme. See more at:\n * https://evilmartians.com/chronicles/better-dynamic-themes-in-tailwind-with-oklch-color-magic\n *\n */\nexport const chromaData: Record<number, number> = {\n 0: 0.0108,\n 1: 0.0121,\n 2: 0.0609,\n 3: 0.0908,\n 4: 0.1398,\n 5: 0.1472,\n 6: 0.1299,\n 7: 0.1067,\n 8: 0.0898,\n 9: 0.0726,\n 10: 0.005,\n};\n\n";
2
+ export default themeConfig;
package/dist/src/cli.js CHANGED
@@ -39,20 +39,20 @@ import chalk from "chalk";
39
39
  import fs from "fs";
40
40
  import inquirer from "inquirer";
41
41
  import path from "path";
42
- import huePalettes from "./_templates/hue-scheme.js";
43
42
  import rootCss from "./_templates/root-css.js";
44
43
  import themeColors from "./_templates/theme-colors.js";
44
+ import themeConfig from "./_templates/theme.config.js";
45
45
  import themeSwitcher from "./_templates/theme-switcher.js";
46
46
  var initThemesDirectory = function (themesDir) {
47
47
  if (!fs.existsSync(themesDir)) {
48
48
  fs.mkdirSync(themesDir);
49
- fs.writeFileSync(path.join(themesDir, "hue-palettes.ts"), huePalettes.trim());
49
+ fs.writeFileSync(path.join(themesDir, "theme.config.ts"), themeConfig.trim());
50
50
  fs.writeFileSync(path.join(themesDir, "root.css"), rootCss.trim());
51
51
  fs.writeFileSync(path.join(themesDir, "theme-colors.ts"), themeColors.trim());
52
52
  fs.writeFileSync(path.join(themesDir, "theme-switcher.tsx"), themeSwitcher.trim());
53
53
  console.log(chalk.green("Default files created in \"".concat(themesDir, "\".")));
54
54
  console.log(chalk.cyan("\n\t /themes/\n" +
55
- "\t ├── hue-palettes.ts\n" +
55
+ "\t ├── theme.config.ts\n" +
56
56
  "\t ├── root.css\n" +
57
57
  "\t ├── theme-colors.ts\n" +
58
58
  "\t └── theme-switcher.tsx\n"));
@@ -9,7 +9,7 @@
9
9
  * - `style`: A record with dynamically generated CSS variables for the accent colors.
10
10
  *
11
11
  */
12
- export declare const getThemeProperties: (hue: number, darkMode: boolean) => {
12
+ export declare const getThemeProperties: (hue: number, darkMode: boolean, chromaData?: Record<number, number>) => {
13
13
  className: string;
14
14
  style: Record<string, string>;
15
15
  };
@@ -1,4 +1,5 @@
1
- import { getVariables } from "../lib/tw-dynamic-themes/runtime";
1
+ import { getVariables } from '../lib/tw-dynamic-themes/runtime';
2
+ import { chromaData as defaultChromaData } from './theme.config';
2
3
  /**
3
4
  * getThemeProperties
4
5
  *
@@ -10,25 +11,27 @@ import { getVariables } from "../lib/tw-dynamic-themes/runtime";
10
11
  * - `style`: A record with dynamically generated CSS variables for the accent colors.
11
12
  *
12
13
  */
13
- export var getThemeProperties = function (hue, darkMode) {
14
+ export var getThemeProperties = function (hue, darkMode, chromaData) {
15
+ if (chromaData === void 0) { chromaData = defaultChromaData; }
14
16
  var whitePalette = hue == -1;
15
17
  var accent = getVariables({
16
- baseName: "accent",
18
+ baseName: 'accent',
17
19
  hue: hue,
20
+ chromaData: chromaData,
18
21
  });
19
22
  // whitePalette have a different accent behavior for accent values
20
23
  if (whitePalette) {
21
24
  accent.push([
22
- "--accent-500",
23
- darkMode ? "1.000 0.000 89.876" : "0.212 0.000 359.000",
25
+ '--accent-500',
26
+ darkMode ? '1.000 0.000 89.876' : '0.212 0.000 359.000',
24
27
  ]);
25
28
  accent.push([
26
- "--accent-50",
27
- darkMode ? "0.212 0.000 359.000" : "1.000 0.000 89.876",
29
+ '--accent-50',
30
+ darkMode ? '0.212 0.000 359.000' : '1.000 0.000 89.876',
28
31
  ]);
29
32
  }
30
33
  return {
31
- className: darkMode ? "dark" : "",
34
+ className: darkMode ? 'dark' : '',
32
35
  style: Object.fromEntries(accent),
33
36
  };
34
37
  };
@@ -42,7 +45,7 @@ export var getThemeProperties = function (hue, darkMode) {
42
45
  * @returns The OKLCH color value for the provided CSS variable, e.g., "0.614 0.136 250.000", or `null` if not available.
43
46
  */
44
47
  export var currentAccentValue = function (variableName) {
45
- if (typeof window === "undefined") {
48
+ if (typeof window === 'undefined') {
46
49
  return null;
47
50
  }
48
51
  var rootElement = document.documentElement;
@@ -1,17 +1,8 @@
1
- /**
2
- * useColorTheme
3
- *
4
- * A custom hook that manages the application of color themes based on
5
- * the provided HUE value and dark mode setting.
6
- *
7
- * It updates the document's root element with the appropriate
8
- * class name and CSS variables for the theme.
9
- *
10
- * Note: This hook dispatches a custom event 'themeChange' when the theme changes.
11
- * You can listen for this event to update components that depend on the theme.
12
- *
13
- */
14
- declare const useColorTheme: (hue: number, darkMode: boolean) => {
15
- setTheme: (newHue: number, newDarkMode: boolean) => void;
1
+ import { ThemeConfig } from "./theme.config";
2
+ declare const updateTheme: (themeConfig: ThemeConfig) => void;
3
+ type ThemeState = {
4
+ theme: ThemeConfig;
5
+ setTheme: (theme: ThemeConfig) => void;
16
6
  };
17
- export { useColorTheme };
7
+ declare const useTheme: import("zustand").UseBoundStore<import("zustand").StoreApi<ThemeState>>;
8
+ export { updateTheme, useTheme };
@@ -1,35 +1,20 @@
1
- import { useCallback, useEffect } from "react";
2
1
  import { getThemeProperties } from "./theme-helpers";
3
- /**
4
- * useColorTheme
5
- *
6
- * A custom hook that manages the application of color themes based on
7
- * the provided HUE value and dark mode setting.
8
- *
9
- * It updates the document's root element with the appropriate
10
- * class name and CSS variables for the theme.
11
- *
12
- * Note: This hook dispatches a custom event 'themeChange' when the theme changes.
13
- * You can listen for this event to update components that depend on the theme.
14
- *
15
- */
16
- var useColorTheme = function (hue, darkMode) {
17
- var setTheme = useCallback(function (newHue, newDarkMode) {
18
- var _a = getThemeProperties(newHue, newDarkMode), className = _a.className, style = _a.style;
19
- document.documentElement.className = className;
20
- document.documentElement.style.setProperty("color-scheme", newDarkMode ? "dark" : "light");
21
- Object.entries(style).forEach(function (_a) {
22
- var key = _a[0], value = _a[1];
23
- document.documentElement.style.setProperty(key, value);
24
- });
25
- var themeChangeEvent = new CustomEvent("themeChange", {
26
- detail: { hue: newHue, darkMode: newDarkMode },
27
- });
28
- window.dispatchEvent(themeChangeEvent);
29
- }, []);
30
- useEffect(function () {
31
- setTheme(hue, darkMode);
32
- }, [hue, darkMode, setTheme]);
33
- return { setTheme: setTheme };
2
+ import { create } from 'zustand';
3
+ import { chromaData } from "./theme.config";
4
+ var updateTheme = function (themeConfig) {
5
+ var _a = getThemeProperties(themeConfig.hue, themeConfig.mode === 'dark', themeConfig.chromaData), className = _a.className, style = _a.style;
6
+ document.documentElement.className = className;
7
+ document.documentElement.style.setProperty('--color-scheme', themeConfig.mode);
8
+ Object.entries(style).forEach(function (_a) {
9
+ var key = _a[0], value = _a[1];
10
+ document.documentElement.style.setProperty(key, value);
11
+ });
34
12
  };
35
- export { useColorTheme };
13
+ var useTheme = create(function (set, get) { return ({
14
+ theme: { hue: 250, mode: 'light', chromaData: chromaData },
15
+ setTheme: function (theme) {
16
+ set({ theme: theme });
17
+ updateTheme(theme);
18
+ },
19
+ }); });
20
+ export { updateTheme, useTheme };
@@ -0,0 +1,8 @@
1
+ import React, { type ReactNode } from 'react';
2
+ import { ThemeConfig } from './theme.config';
3
+ interface ThemeProviderProps {
4
+ children: ReactNode;
5
+ themeConfig: ThemeConfig;
6
+ }
7
+ declare const ThemeProvider: React.FC<ThemeProviderProps>;
8
+ export { ThemeProvider };
@@ -0,0 +1,20 @@
1
+ import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
2
+ // 'use client'; // enable on Nextjs
3
+ import { updateTheme, useTheme } from './theme-hook';
4
+ import { useEffect, useState } from 'react';
5
+ var ThemeProvider = function (_a) {
6
+ var children = _a.children, themeConfig = _a.themeConfig;
7
+ /**@TODO Get this values from user cookie */
8
+ var theme = useTheme().theme;
9
+ var _b = useState(false), isInitialized = _b[0], setIsInitialized = _b[1];
10
+ useEffect(function () {
11
+ if (!isInitialized) {
12
+ setIsInitialized(true);
13
+ updateTheme(themeConfig);
14
+ }
15
+ }, [theme, isInitialized]);
16
+ if (!isInitialized)
17
+ return null;
18
+ return _jsx(_Fragment, { children: children });
19
+ };
20
+ export { ThemeProvider };
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Theme Configuration
3
+ * Required params to init and switch the theme.
4
+ */
5
+ export type ThemeMode = 'light' | 'dark';
6
+ export type ThemeColor = number;
7
+ export type ThemeConfig = {
8
+ hue: ThemeColor;
9
+ mode: ThemeMode;
10
+ chromaData: Record<number, number>;
11
+ };
12
+ /**
13
+ * HUE THEMES
14
+ *
15
+ * Define the available color palettes here!
16
+ *
17
+ * The palettes are based on HUE values.
18
+ *
19
+ * To add or modify a HUE palette, explore and preview colors at:
20
+ * https://oklch.com/#70,0.1,250,100
21
+ *
22
+ */
23
+ export declare const hueScheme: Record<string, ThemeColor>;
24
+ /**
25
+ *
26
+ * Default Chroma for each shade available on theme. See more at:
27
+ * https://evilmartians.com/chronicles/better-dynamic-themes-in-tailwind-with-oklch-color-magic
28
+ *
29
+ */
30
+ export declare const chromaData: Record<number, number>;
@@ -0,0 +1,38 @@
1
+ /**
2
+ * HUE THEMES
3
+ *
4
+ * Define the available color palettes here!
5
+ *
6
+ * The palettes are based on HUE values.
7
+ *
8
+ * To add or modify a HUE palette, explore and preview colors at:
9
+ * https://oklch.com/#70,0.1,250,100
10
+ *
11
+ */
12
+ export var hueScheme = {
13
+ default: -1,
14
+ blue: 250,
15
+ green: 150,
16
+ orange: 35,
17
+ pink: 0,
18
+ purple: 316,
19
+ };
20
+ /**
21
+ *
22
+ * Default Chroma for each shade available on theme. See more at:
23
+ * https://evilmartians.com/chronicles/better-dynamic-themes-in-tailwind-with-oklch-color-magic
24
+ *
25
+ */
26
+ export var chromaData = {
27
+ 0: 0.0108,
28
+ 1: 0.0121,
29
+ 2: 0.0609,
30
+ 3: 0.0908,
31
+ 4: 0.1398,
32
+ 5: 0.1472,
33
+ 6: 0.1299,
34
+ 7: 0.1067,
35
+ 8: 0.0898,
36
+ 9: 0.0726,
37
+ 10: 0.054,
38
+ };
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Theme Configuration
3
+ * Required params to init and switch the theme.
4
+ */
5
+ type ThemeConfig = {
6
+ hue: number;
7
+ mode: 'light' | 'dark';
8
+ chromaData: Record<number, number>;
9
+ };
@@ -0,0 +1 @@
1
+ "use strict";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cyhip-dynamic-themes",
3
- "version": "0.1.5",
3
+ "version": "0.2.0",
4
4
  "description": "Tailwind-powered dynamic color themes for React apps.",
5
5
  "author": "@KassioRF, @CyberHippie-io",
6
6
  "license": "MIT",
@@ -59,7 +59,8 @@
59
59
  "culori": "^4.0.1",
60
60
  "inquirer": "^12.0.0",
61
61
  "react": "^18",
62
- "react-dom": "^18"
62
+ "react-dom": "^18",
63
+ "zustand": "^5.0.1"
63
64
  },
64
65
  "peerDependencies": {
65
66
  "react": "^18",