@dheme/react 2.2.0 → 2.4.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.
@@ -0,0 +1,15 @@
1
+ import { GenerateThemeResponse, GenerateThemeRequest } from '@dheme/sdk';
2
+
3
+ type ThemeMode = 'light' | 'dark';
4
+
5
+ declare function themeToCSS(theme: GenerateThemeResponse, mode: ThemeMode): string;
6
+ declare function themeToCSSBothModes(theme: GenerateThemeResponse): string;
7
+ declare function applyThemeCSSVariables(theme: GenerateThemeResponse, mode: ThemeMode): void;
8
+ declare function removeThemeCSSVariables(): void;
9
+
10
+ declare function buildCacheKey(params: GenerateThemeRequest): string;
11
+
12
+ declare function getBlockingScriptPayload(defaultMode: ThemeMode): string;
13
+ declare function getNextBlockingScriptPayload(defaultMode: ThemeMode): string;
14
+
15
+ export { applyThemeCSSVariables, buildCacheKey, getBlockingScriptPayload, getNextBlockingScriptPayload, removeThemeCSSVariables, themeToCSS, themeToCSSBothModes };
@@ -0,0 +1,15 @@
1
+ import { GenerateThemeResponse, GenerateThemeRequest } from '@dheme/sdk';
2
+
3
+ type ThemeMode = 'light' | 'dark';
4
+
5
+ declare function themeToCSS(theme: GenerateThemeResponse, mode: ThemeMode): string;
6
+ declare function themeToCSSBothModes(theme: GenerateThemeResponse): string;
7
+ declare function applyThemeCSSVariables(theme: GenerateThemeResponse, mode: ThemeMode): void;
8
+ declare function removeThemeCSSVariables(): void;
9
+
10
+ declare function buildCacheKey(params: GenerateThemeRequest): string;
11
+
12
+ declare function getBlockingScriptPayload(defaultMode: ThemeMode): string;
13
+ declare function getNextBlockingScriptPayload(defaultMode: ThemeMode): string;
14
+
15
+ export { applyThemeCSSVariables, buildCacheKey, getBlockingScriptPayload, getNextBlockingScriptPayload, removeThemeCSSVariables, themeToCSS, themeToCSSBothModes };
package/dist/utils.js ADDED
@@ -0,0 +1,156 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
+ var __getOwnPropNames = Object.getOwnPropertyNames;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __export = (target, all) => {
7
+ for (var name in all)
8
+ __defProp(target, name, { get: all[name], enumerable: true });
9
+ };
10
+ var __copyProps = (to, from, except, desc) => {
11
+ if (from && typeof from === "object" || typeof from === "function") {
12
+ for (let key of __getOwnPropNames(from))
13
+ if (!__hasOwnProp.call(to, key) && key !== except)
14
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
15
+ }
16
+ return to;
17
+ };
18
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/utils.ts
21
+ var utils_exports = {};
22
+ __export(utils_exports, {
23
+ applyThemeCSSVariables: () => applyThemeCSSVariables,
24
+ buildCacheKey: () => buildCacheKey,
25
+ getBlockingScriptPayload: () => getBlockingScriptPayload,
26
+ getNextBlockingScriptPayload: () => getNextBlockingScriptPayload,
27
+ removeThemeCSSVariables: () => removeThemeCSSVariables,
28
+ themeToCSS: () => themeToCSS,
29
+ themeToCSSBothModes: () => themeToCSSBothModes
30
+ });
31
+ module.exports = __toCommonJS(utils_exports);
32
+
33
+ // src/constants.ts
34
+ var CSS_TOKEN_KEYS = [
35
+ "background",
36
+ "foreground",
37
+ "card",
38
+ "cardForeground",
39
+ "popover",
40
+ "popoverForeground",
41
+ "primary",
42
+ "primaryForeground",
43
+ "secondary",
44
+ "secondaryForeground",
45
+ "muted",
46
+ "mutedForeground",
47
+ "accent",
48
+ "accentForeground",
49
+ "destructive",
50
+ "destructiveForeground",
51
+ "border",
52
+ "input",
53
+ "ring"
54
+ ];
55
+ var TOKEN_TO_CSS_VAR = {
56
+ background: "--background",
57
+ foreground: "--foreground",
58
+ card: "--card",
59
+ cardForeground: "--card-foreground",
60
+ popover: "--popover",
61
+ popoverForeground: "--popover-foreground",
62
+ primary: "--primary",
63
+ primaryForeground: "--primary-foreground",
64
+ secondary: "--secondary",
65
+ secondaryForeground: "--secondary-foreground",
66
+ muted: "--muted",
67
+ mutedForeground: "--muted-foreground",
68
+ accent: "--accent",
69
+ accentForeground: "--accent-foreground",
70
+ destructive: "--destructive",
71
+ destructiveForeground: "--destructive-foreground",
72
+ border: "--border",
73
+ input: "--input",
74
+ ring: "--ring"
75
+ };
76
+
77
+ // src/utils/cssVariables.ts
78
+ function formatHSL(color) {
79
+ return `${color.h} ${color.s}% ${color.l}%`;
80
+ }
81
+ function themeToCSS(theme, mode) {
82
+ const colors = theme.colors[mode];
83
+ if (!colors) return "";
84
+ const parts = [];
85
+ for (const key of CSS_TOKEN_KEYS) {
86
+ const color = colors[key];
87
+ if (color) {
88
+ parts.push(`${TOKEN_TO_CSS_VAR[key]}:${formatHSL(color)}`);
89
+ }
90
+ }
91
+ if (theme.radius != null) {
92
+ parts.push(`--radius:${theme.radius}rem`);
93
+ }
94
+ return parts.join(";");
95
+ }
96
+ function themeToCSSBothModes(theme) {
97
+ const lightCSS = themeToCSS(theme, "light");
98
+ const darkCSS = themeToCSS(theme, "dark");
99
+ return `:root{${lightCSS}}.dark{${darkCSS}}`;
100
+ }
101
+ function applyThemeCSSVariables(theme, mode) {
102
+ if (typeof document === "undefined") return;
103
+ const colors = theme.colors[mode];
104
+ if (!colors) return;
105
+ const style = document.documentElement.style;
106
+ for (const key of CSS_TOKEN_KEYS) {
107
+ const color = colors[key];
108
+ if (color) {
109
+ style.setProperty(TOKEN_TO_CSS_VAR[key], formatHSL(color));
110
+ }
111
+ }
112
+ if (theme.radius != null) {
113
+ style.setProperty("--radius", `${theme.radius}rem`);
114
+ }
115
+ }
116
+ function removeThemeCSSVariables() {
117
+ if (typeof document === "undefined") return;
118
+ const style = document.documentElement.style;
119
+ for (const key of CSS_TOKEN_KEYS) {
120
+ style.removeProperty(TOKEN_TO_CSS_VAR[key]);
121
+ }
122
+ style.removeProperty("--radius");
123
+ }
124
+
125
+ // src/utils/cacheKey.ts
126
+ function buildCacheKey(params) {
127
+ const normalized = {
128
+ t: params.theme.toLowerCase().replace("#", ""),
129
+ s: (params.secondaryColor || "").toLowerCase().replace("#", ""),
130
+ r: params.radius ?? 0.5,
131
+ sa: params.saturationAdjust ?? 0,
132
+ la: params.lightnessAdjust ?? 0,
133
+ ca: params.contrastAdjust ?? 0,
134
+ ci: params.cardIsColored ?? false,
135
+ bi: params.backgroundIsColored ?? true
136
+ };
137
+ return JSON.stringify(normalized);
138
+ }
139
+
140
+ // src/utils/scriptPayload.ts
141
+ function getBlockingScriptPayload(defaultMode) {
142
+ return `(function(){try{var p=localStorage.getItem('dheme-params');if(!p)return;var params=JSON.parse(p);var n={t:(params.theme||'').toLowerCase().replace('#',''),s:(params.secondaryColor||'').toLowerCase().replace('#',''),r:params.radius!=null?params.radius:0.5,sa:params.saturationAdjust||0,la:params.lightnessAdjust||0,ca:params.contrastAdjust||0,ci:!!params.cardIsColored,bi:params.backgroundIsColored!=null?params.backgroundIsColored:true};var key='dheme-cache:'+JSON.stringify(n);var c=localStorage.getItem(key);if(!c)return;var theme=JSON.parse(c);var mode=localStorage.getItem('dheme-mode')||'${defaultMode}';var colors=theme.colors[mode];if(!colors)return;var d=document.documentElement.style;var m={background:'--background',foreground:'--foreground',card:'--card',cardForeground:'--card-foreground',popover:'--popover',popoverForeground:'--popover-foreground',primary:'--primary',primaryForeground:'--primary-foreground',secondary:'--secondary',secondaryForeground:'--secondary-foreground',muted:'--muted',mutedForeground:'--muted-foreground',accent:'--accent',accentForeground:'--accent-foreground',destructive:'--destructive',destructiveForeground:'--destructive-foreground',border:'--border',input:'--input',ring:'--ring'};for(var k in m){if(colors[k]){var v=colors[k];d.setProperty(m[k],v.h+' '+v.s+'% '+v.l+'%')}}if(theme.radius!=null)d.setProperty('--radius',theme.radius+'rem');if(mode==='dark')document.documentElement.classList.add('dark');else document.documentElement.classList.remove('dark')}catch(e){}})()`;
143
+ }
144
+ function getNextBlockingScriptPayload(defaultMode) {
145
+ return `(function(){try{var m=document.cookie.match(/dheme-mode=(\\w+)/);var mode=m?m[1]:null;if(!mode){mode=window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'${defaultMode}'}if(mode==='dark'){document.documentElement.classList.add('dark')}else{document.documentElement.classList.remove('dark')}}catch(e){}})()`;
146
+ }
147
+ // Annotate the CommonJS export names for ESM import in node:
148
+ 0 && (module.exports = {
149
+ applyThemeCSSVariables,
150
+ buildCacheKey,
151
+ getBlockingScriptPayload,
152
+ getNextBlockingScriptPayload,
153
+ removeThemeCSSVariables,
154
+ themeToCSS,
155
+ themeToCSSBothModes
156
+ });
package/dist/utils.mjs ADDED
@@ -0,0 +1,123 @@
1
+ // src/constants.ts
2
+ var CSS_TOKEN_KEYS = [
3
+ "background",
4
+ "foreground",
5
+ "card",
6
+ "cardForeground",
7
+ "popover",
8
+ "popoverForeground",
9
+ "primary",
10
+ "primaryForeground",
11
+ "secondary",
12
+ "secondaryForeground",
13
+ "muted",
14
+ "mutedForeground",
15
+ "accent",
16
+ "accentForeground",
17
+ "destructive",
18
+ "destructiveForeground",
19
+ "border",
20
+ "input",
21
+ "ring"
22
+ ];
23
+ var TOKEN_TO_CSS_VAR = {
24
+ background: "--background",
25
+ foreground: "--foreground",
26
+ card: "--card",
27
+ cardForeground: "--card-foreground",
28
+ popover: "--popover",
29
+ popoverForeground: "--popover-foreground",
30
+ primary: "--primary",
31
+ primaryForeground: "--primary-foreground",
32
+ secondary: "--secondary",
33
+ secondaryForeground: "--secondary-foreground",
34
+ muted: "--muted",
35
+ mutedForeground: "--muted-foreground",
36
+ accent: "--accent",
37
+ accentForeground: "--accent-foreground",
38
+ destructive: "--destructive",
39
+ destructiveForeground: "--destructive-foreground",
40
+ border: "--border",
41
+ input: "--input",
42
+ ring: "--ring"
43
+ };
44
+
45
+ // src/utils/cssVariables.ts
46
+ function formatHSL(color) {
47
+ return `${color.h} ${color.s}% ${color.l}%`;
48
+ }
49
+ function themeToCSS(theme, mode) {
50
+ const colors = theme.colors[mode];
51
+ if (!colors) return "";
52
+ const parts = [];
53
+ for (const key of CSS_TOKEN_KEYS) {
54
+ const color = colors[key];
55
+ if (color) {
56
+ parts.push(`${TOKEN_TO_CSS_VAR[key]}:${formatHSL(color)}`);
57
+ }
58
+ }
59
+ if (theme.radius != null) {
60
+ parts.push(`--radius:${theme.radius}rem`);
61
+ }
62
+ return parts.join(";");
63
+ }
64
+ function themeToCSSBothModes(theme) {
65
+ const lightCSS = themeToCSS(theme, "light");
66
+ const darkCSS = themeToCSS(theme, "dark");
67
+ return `:root{${lightCSS}}.dark{${darkCSS}}`;
68
+ }
69
+ function applyThemeCSSVariables(theme, mode) {
70
+ if (typeof document === "undefined") return;
71
+ const colors = theme.colors[mode];
72
+ if (!colors) return;
73
+ const style = document.documentElement.style;
74
+ for (const key of CSS_TOKEN_KEYS) {
75
+ const color = colors[key];
76
+ if (color) {
77
+ style.setProperty(TOKEN_TO_CSS_VAR[key], formatHSL(color));
78
+ }
79
+ }
80
+ if (theme.radius != null) {
81
+ style.setProperty("--radius", `${theme.radius}rem`);
82
+ }
83
+ }
84
+ function removeThemeCSSVariables() {
85
+ if (typeof document === "undefined") return;
86
+ const style = document.documentElement.style;
87
+ for (const key of CSS_TOKEN_KEYS) {
88
+ style.removeProperty(TOKEN_TO_CSS_VAR[key]);
89
+ }
90
+ style.removeProperty("--radius");
91
+ }
92
+
93
+ // src/utils/cacheKey.ts
94
+ function buildCacheKey(params) {
95
+ const normalized = {
96
+ t: params.theme.toLowerCase().replace("#", ""),
97
+ s: (params.secondaryColor || "").toLowerCase().replace("#", ""),
98
+ r: params.radius ?? 0.5,
99
+ sa: params.saturationAdjust ?? 0,
100
+ la: params.lightnessAdjust ?? 0,
101
+ ca: params.contrastAdjust ?? 0,
102
+ ci: params.cardIsColored ?? false,
103
+ bi: params.backgroundIsColored ?? true
104
+ };
105
+ return JSON.stringify(normalized);
106
+ }
107
+
108
+ // src/utils/scriptPayload.ts
109
+ function getBlockingScriptPayload(defaultMode) {
110
+ return `(function(){try{var p=localStorage.getItem('dheme-params');if(!p)return;var params=JSON.parse(p);var n={t:(params.theme||'').toLowerCase().replace('#',''),s:(params.secondaryColor||'').toLowerCase().replace('#',''),r:params.radius!=null?params.radius:0.5,sa:params.saturationAdjust||0,la:params.lightnessAdjust||0,ca:params.contrastAdjust||0,ci:!!params.cardIsColored,bi:params.backgroundIsColored!=null?params.backgroundIsColored:true};var key='dheme-cache:'+JSON.stringify(n);var c=localStorage.getItem(key);if(!c)return;var theme=JSON.parse(c);var mode=localStorage.getItem('dheme-mode')||'${defaultMode}';var colors=theme.colors[mode];if(!colors)return;var d=document.documentElement.style;var m={background:'--background',foreground:'--foreground',card:'--card',cardForeground:'--card-foreground',popover:'--popover',popoverForeground:'--popover-foreground',primary:'--primary',primaryForeground:'--primary-foreground',secondary:'--secondary',secondaryForeground:'--secondary-foreground',muted:'--muted',mutedForeground:'--muted-foreground',accent:'--accent',accentForeground:'--accent-foreground',destructive:'--destructive',destructiveForeground:'--destructive-foreground',border:'--border',input:'--input',ring:'--ring'};for(var k in m){if(colors[k]){var v=colors[k];d.setProperty(m[k],v.h+' '+v.s+'% '+v.l+'%')}}if(theme.radius!=null)d.setProperty('--radius',theme.radius+'rem');if(mode==='dark')document.documentElement.classList.add('dark');else document.documentElement.classList.remove('dark')}catch(e){}})()`;
111
+ }
112
+ function getNextBlockingScriptPayload(defaultMode) {
113
+ return `(function(){try{var m=document.cookie.match(/dheme-mode=(\\w+)/);var mode=m?m[1]:null;if(!mode){mode=window.matchMedia('(prefers-color-scheme: dark)').matches?'dark':'${defaultMode}'}if(mode==='dark'){document.documentElement.classList.add('dark')}else{document.documentElement.classList.remove('dark')}}catch(e){}})()`;
114
+ }
115
+ export {
116
+ applyThemeCSSVariables,
117
+ buildCacheKey,
118
+ getBlockingScriptPayload,
119
+ getNextBlockingScriptPayload,
120
+ removeThemeCSSVariables,
121
+ themeToCSS,
122
+ themeToCSSBothModes
123
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dheme/react",
3
- "version": "2.2.0",
3
+ "version": "2.4.0",
4
4
  "description": "React bindings for Dheme SDK with zero-FOUC theme application",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -10,6 +10,11 @@
10
10
  "types": "./dist/index.d.ts",
11
11
  "import": "./dist/index.mjs",
12
12
  "require": "./dist/index.js"
13
+ },
14
+ "./utils": {
15
+ "types": "./dist/utils.d.ts",
16
+ "import": "./dist/utils.mjs",
17
+ "require": "./dist/utils.js"
13
18
  }
14
19
  },
15
20
  "files": [
@@ -18,8 +23,8 @@
18
23
  "LICENSE"
19
24
  ],
20
25
  "scripts": {
21
- "build": "tsup src/index.ts --format cjs,esm --dts --clean --external react --external react-dom --external @dheme/sdk --tsconfig tsconfig.build.json",
22
- "dev": "tsup src/index.ts --format cjs,esm --dts --watch --external react --external react-dom --external @dheme/sdk",
26
+ "build": "tsup",
27
+ "dev": "tsup --watch",
23
28
  "test": "vitest run",
24
29
  "test:watch": "vitest",
25
30
  "lint": "eslint src --ext .ts,.tsx",