@fakhrirafiki/theme-engine 0.4.3 → 0.4.4
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/dist/index.js +277 -138
- package/dist/index.mjs +277 -138
- package/dist/styles/components.css +3 -3
- package/dist/styles/tailwind.css +48 -48
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3870,7 +3870,15 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3870
3870
|
'destructive', 'destructive-foreground', 'border', 'input', 'ring',
|
|
3871
3871
|
'chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5',
|
|
3872
3872
|
'sidebar', 'sidebar-foreground', 'sidebar-primary', 'sidebar-primary-foreground',
|
|
3873
|
-
'sidebar-accent', 'sidebar-accent-foreground', 'sidebar-border', 'sidebar-ring'
|
|
3873
|
+
'sidebar-accent', 'sidebar-accent-foreground', 'sidebar-border', 'sidebar-ring',
|
|
3874
|
+
// Semantic accent colors for status and feedback
|
|
3875
|
+
'accent-info', 'accent-info-foreground',
|
|
3876
|
+
'accent-success', 'accent-success-foreground',
|
|
3877
|
+
'accent-warning', 'accent-warning-foreground',
|
|
3878
|
+
'accent-danger', 'accent-danger-foreground',
|
|
3879
|
+
'accent-brand', 'accent-brand-foreground',
|
|
3880
|
+
'accent-feature', 'accent-feature-foreground',
|
|
3881
|
+
'accent-highlight', 'accent-highlight-foreground'
|
|
3874
3882
|
],
|
|
3875
3883
|
typography: ['font-sans', 'font-serif', 'font-mono'],
|
|
3876
3884
|
layout: ['radius'],
|
|
@@ -3878,6 +3886,106 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3878
3886
|
spacing: ['letter-spacing', 'spacing']
|
|
3879
3887
|
};
|
|
3880
3888
|
|
|
3889
|
+
// Normalize hex/rgb/hsl() colors into "H S% L%" for hsl(var(--token)) usage.
|
|
3890
|
+
function normalizeColorValueToHslTriplet(value) {
|
|
3891
|
+
if (!value) return value;
|
|
3892
|
+
const trimmed = String(value).trim();
|
|
3893
|
+
if (!trimmed) return value;
|
|
3894
|
+
if (trimmed.startsWith('var(')) return trimmed;
|
|
3895
|
+
|
|
3896
|
+
// Already a triplet: "210 40% 98%"
|
|
3897
|
+
if (/^\\d+(?:\\.\\d+)?\\s+\\d+(?:\\.\\d+)?%\\s+\\d+(?:\\.\\d+)?%$/.test(trimmed)) {
|
|
3898
|
+
return trimmed;
|
|
3899
|
+
}
|
|
3900
|
+
|
|
3901
|
+
function clamp(n, min, max) {
|
|
3902
|
+
return Math.min(max, Math.max(min, n));
|
|
3903
|
+
}
|
|
3904
|
+
|
|
3905
|
+
function rgbToHsl(r, g, b) {
|
|
3906
|
+
r /= 255;
|
|
3907
|
+
g /= 255;
|
|
3908
|
+
b /= 255;
|
|
3909
|
+
const max = Math.max(r, g, b);
|
|
3910
|
+
const min = Math.min(r, g, b);
|
|
3911
|
+
const diff = max - min;
|
|
3912
|
+
let h = 0;
|
|
3913
|
+
let s = 0;
|
|
3914
|
+
const l = (max + min) / 2;
|
|
3915
|
+
|
|
3916
|
+
if (diff !== 0) {
|
|
3917
|
+
s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min);
|
|
3918
|
+
switch (max) {
|
|
3919
|
+
case r:
|
|
3920
|
+
h = (g - b) / diff + (g < b ? 6 : 0);
|
|
3921
|
+
break;
|
|
3922
|
+
case g:
|
|
3923
|
+
h = (b - r) / diff + 2;
|
|
3924
|
+
break;
|
|
3925
|
+
case b:
|
|
3926
|
+
h = (r - g) / diff + 4;
|
|
3927
|
+
break;
|
|
3928
|
+
}
|
|
3929
|
+
h /= 6;
|
|
3930
|
+
}
|
|
3931
|
+
|
|
3932
|
+
return {
|
|
3933
|
+
h: Math.round(h * 360),
|
|
3934
|
+
s: Math.round(s * 100),
|
|
3935
|
+
l: Math.round(l * 100),
|
|
3936
|
+
};
|
|
3937
|
+
}
|
|
3938
|
+
|
|
3939
|
+
function hexToRgb(hex) {
|
|
3940
|
+
let clean = hex.replace('#', '').trim();
|
|
3941
|
+
if (clean.length === 3) clean = clean.split('').map(function(c) { return c + c; }).join('');
|
|
3942
|
+
if (clean.length === 8) clean = clean.substring(0, 6); // ignore alpha
|
|
3943
|
+
if (clean.length !== 6) return null;
|
|
3944
|
+
|
|
3945
|
+
const r = parseInt(clean.substring(0, 2), 16);
|
|
3946
|
+
const g = parseInt(clean.substring(2, 4), 16);
|
|
3947
|
+
const b = parseInt(clean.substring(4, 6), 16);
|
|
3948
|
+
if (isNaN(r) || isNaN(g) || isNaN(b)) return null;
|
|
3949
|
+
return { r: r, g: g, b: b };
|
|
3950
|
+
}
|
|
3951
|
+
|
|
3952
|
+
function toTriplet(hsl) {
|
|
3953
|
+
return String(clamp(hsl.h, 0, 360)) + ' ' + String(clamp(hsl.s, 0, 100)) + '% ' + String(clamp(hsl.l, 0, 100)) + '%';
|
|
3954
|
+
}
|
|
3955
|
+
|
|
3956
|
+
// hsl(...) or raw "H S% L%"
|
|
3957
|
+
if (/^hsl\\(/i.test(trimmed)) {
|
|
3958
|
+
const cleaned = trimmed.replace(/hsl\\(|\\)/gi, '').replace(/[,%]/g, ' ').trim();
|
|
3959
|
+
const parts = cleaned.split(/\\s+/).filter(Boolean);
|
|
3960
|
+
if (parts.length === 3) {
|
|
3961
|
+
const h = parseFloat(parts[0]) || 0;
|
|
3962
|
+
const s = parseFloat(parts[1]) || 0;
|
|
3963
|
+
const l = parseFloat(parts[2]) || 0;
|
|
3964
|
+
return toTriplet({ h: h, s: s, l: l });
|
|
3965
|
+
}
|
|
3966
|
+
}
|
|
3967
|
+
|
|
3968
|
+
// rgb(...)
|
|
3969
|
+
if (/^rgb\\(/i.test(trimmed)) {
|
|
3970
|
+
const cleaned = trimmed.replace(/rgb\\(|\\)/gi, '').trim();
|
|
3971
|
+
const parts = cleaned.split(',').map(function(p) { return p.trim(); });
|
|
3972
|
+
if (parts.length === 3) {
|
|
3973
|
+
const r = clamp(parseFloat(parts[0]) || 0, 0, 255);
|
|
3974
|
+
const g = clamp(parseFloat(parts[1]) || 0, 0, 255);
|
|
3975
|
+
const b = clamp(parseFloat(parts[2]) || 0, 0, 255);
|
|
3976
|
+
return toTriplet(rgbToHsl(r, g, b));
|
|
3977
|
+
}
|
|
3978
|
+
}
|
|
3979
|
+
|
|
3980
|
+
// hex
|
|
3981
|
+
if (trimmed[0] === '#') {
|
|
3982
|
+
const rgb = hexToRgb(trimmed);
|
|
3983
|
+
if (rgb) return toTriplet(rgbToHsl(rgb.r, rgb.g, rgb.b));
|
|
3984
|
+
}
|
|
3985
|
+
|
|
3986
|
+
return value;
|
|
3987
|
+
}
|
|
3988
|
+
|
|
3881
3989
|
// Function to apply all preset properties - with proper clearing and defaults
|
|
3882
3990
|
function applyPresetProperties(colors) {
|
|
3883
3991
|
if (!colors) return;
|
|
@@ -3909,6 +4017,10 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3909
4017
|
|
|
3910
4018
|
// Apply all properties with defaults for missing ones
|
|
3911
4019
|
let appliedCount = 0;
|
|
4020
|
+
const colorProps = {};
|
|
4021
|
+
CSS_CATEGORIES.colors.forEach(function(prop) { colorProps[prop] = true; });
|
|
4022
|
+
colorProps['shadow-color'] = true;
|
|
4023
|
+
|
|
3912
4024
|
allProperties.forEach(function(prop) {
|
|
3913
4025
|
let value = colors[prop];
|
|
3914
4026
|
|
|
@@ -3918,6 +4030,10 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3918
4030
|
}
|
|
3919
4031
|
|
|
3920
4032
|
if (value) {
|
|
4033
|
+
if (colorProps[prop]) {
|
|
4034
|
+
value = normalizeColorValueToHslTriplet(value);
|
|
4035
|
+
}
|
|
4036
|
+
|
|
3921
4037
|
const cssVar = '--' + prop;
|
|
3922
4038
|
// Apply directly like TweakCN does - no conversion, no !important
|
|
3923
4039
|
root.style.setProperty(cssVar, value);
|
|
@@ -3979,6 +4095,138 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3979
4095
|
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("script", { dangerouslySetInnerHTML: { __html: scriptContent }, suppressHydrationWarning: true });
|
|
3980
4096
|
}
|
|
3981
4097
|
|
|
4098
|
+
// src/utils/colors.ts
|
|
4099
|
+
function parseHSL(hslString) {
|
|
4100
|
+
try {
|
|
4101
|
+
const cleaned = hslString.replace(/hsl\(|\)/g, "").replace(/[,%]/g, " ").trim();
|
|
4102
|
+
const parts = cleaned.split(/\s+/).filter(Boolean);
|
|
4103
|
+
if (parts.length !== 3) return null;
|
|
4104
|
+
const h = parseFloat(parts[0]) || 0;
|
|
4105
|
+
const s = parseFloat(parts[1]) || 0;
|
|
4106
|
+
const l = parseFloat(parts[2]) || 0;
|
|
4107
|
+
return {
|
|
4108
|
+
h: Math.max(0, Math.min(360, h)),
|
|
4109
|
+
s: Math.max(0, Math.min(100, s)),
|
|
4110
|
+
l: Math.max(0, Math.min(100, l))
|
|
4111
|
+
};
|
|
4112
|
+
} catch {
|
|
4113
|
+
return null;
|
|
4114
|
+
}
|
|
4115
|
+
}
|
|
4116
|
+
function parseHex(hexString) {
|
|
4117
|
+
try {
|
|
4118
|
+
let hex = hexString.replace("#", "");
|
|
4119
|
+
if (hex.length === 3) {
|
|
4120
|
+
hex = hex.split("").map((char) => char + char).join("");
|
|
4121
|
+
}
|
|
4122
|
+
if (hex.length !== 6) return null;
|
|
4123
|
+
const r = parseInt(hex.substring(0, 2), 16);
|
|
4124
|
+
const s = parseInt(hex.substring(2, 4), 16);
|
|
4125
|
+
const l = parseInt(hex.substring(4, 6), 16);
|
|
4126
|
+
if (isNaN(r) || isNaN(s) || isNaN(l)) return null;
|
|
4127
|
+
return { r, g: s, b: l };
|
|
4128
|
+
} catch {
|
|
4129
|
+
return null;
|
|
4130
|
+
}
|
|
4131
|
+
}
|
|
4132
|
+
function hslToRgb(hsl) {
|
|
4133
|
+
const h = hsl.h / 360;
|
|
4134
|
+
const s = hsl.s / 100;
|
|
4135
|
+
const l = hsl.l / 100;
|
|
4136
|
+
if (s === 0) {
|
|
4137
|
+
const gray = Math.round(l * 255);
|
|
4138
|
+
return { r: gray, g: gray, b: gray };
|
|
4139
|
+
}
|
|
4140
|
+
const hue2rgb = (p2, q2, t) => {
|
|
4141
|
+
if (t < 0) t += 1;
|
|
4142
|
+
if (t > 1) t -= 1;
|
|
4143
|
+
if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
|
|
4144
|
+
if (t < 1 / 2) return q2;
|
|
4145
|
+
if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
|
|
4146
|
+
return p2;
|
|
4147
|
+
};
|
|
4148
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
4149
|
+
const p = 2 * l - q;
|
|
4150
|
+
const r = Math.round(hue2rgb(p, q, h + 1 / 3) * 255);
|
|
4151
|
+
const g = Math.round(hue2rgb(p, q, h) * 255);
|
|
4152
|
+
const b = Math.round(hue2rgb(p, q, h - 1 / 3) * 255);
|
|
4153
|
+
return { r, g, b };
|
|
4154
|
+
}
|
|
4155
|
+
function rgbToHsl(rgb) {
|
|
4156
|
+
const r = rgb.r / 255;
|
|
4157
|
+
const g = rgb.g / 255;
|
|
4158
|
+
const b = rgb.b / 255;
|
|
4159
|
+
const max = Math.max(r, g, b);
|
|
4160
|
+
const min = Math.min(r, g, b);
|
|
4161
|
+
const diff = max - min;
|
|
4162
|
+
let h = 0;
|
|
4163
|
+
let s = 0;
|
|
4164
|
+
const l = (max + min) / 2;
|
|
4165
|
+
if (diff !== 0) {
|
|
4166
|
+
s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min);
|
|
4167
|
+
switch (max) {
|
|
4168
|
+
case r:
|
|
4169
|
+
h = (g - b) / diff + (g < b ? 6 : 0);
|
|
4170
|
+
break;
|
|
4171
|
+
case g:
|
|
4172
|
+
h = (b - r) / diff + 2;
|
|
4173
|
+
break;
|
|
4174
|
+
case b:
|
|
4175
|
+
h = (r - g) / diff + 4;
|
|
4176
|
+
break;
|
|
4177
|
+
}
|
|
4178
|
+
h /= 6;
|
|
4179
|
+
}
|
|
4180
|
+
return {
|
|
4181
|
+
h: Math.round(h * 360),
|
|
4182
|
+
s: Math.round(s * 100),
|
|
4183
|
+
l: Math.round(l * 100)
|
|
4184
|
+
};
|
|
4185
|
+
}
|
|
4186
|
+
function formatHSL(hsl, includeHslWrapper = true) {
|
|
4187
|
+
const values = `${hsl.h} ${hsl.s}% ${hsl.l}%`;
|
|
4188
|
+
return includeHslWrapper ? `hsl(${values})` : values;
|
|
4189
|
+
}
|
|
4190
|
+
function formatRGB(rgb) {
|
|
4191
|
+
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
|
|
4192
|
+
}
|
|
4193
|
+
function formatHex(rgb) {
|
|
4194
|
+
const toHex = (n) => {
|
|
4195
|
+
const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
|
|
4196
|
+
return hex.length === 1 ? "0" + hex : hex;
|
|
4197
|
+
};
|
|
4198
|
+
return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
|
|
4199
|
+
}
|
|
4200
|
+
function formatColor(colorInput, outputFormat = "hsl", includeFunctionWrapper = true) {
|
|
4201
|
+
let hsl = parseHSL(colorInput);
|
|
4202
|
+
if (!hsl) {
|
|
4203
|
+
const rgb = parseHex(colorInput);
|
|
4204
|
+
if (rgb) {
|
|
4205
|
+
hsl = rgbToHsl(rgb);
|
|
4206
|
+
}
|
|
4207
|
+
}
|
|
4208
|
+
if (!hsl) {
|
|
4209
|
+
return colorInput;
|
|
4210
|
+
}
|
|
4211
|
+
switch (outputFormat) {
|
|
4212
|
+
case "hsl":
|
|
4213
|
+
return formatHSL(hsl, includeFunctionWrapper);
|
|
4214
|
+
case "rgb":
|
|
4215
|
+
return formatRGB(hslToRgb(hsl));
|
|
4216
|
+
case "hex":
|
|
4217
|
+
return formatHex(hslToRgb(hsl));
|
|
4218
|
+
default:
|
|
4219
|
+
return colorInput;
|
|
4220
|
+
}
|
|
4221
|
+
}
|
|
4222
|
+
function withAlpha(colorInput, alpha) {
|
|
4223
|
+
const hsl = parseHSL(colorInput);
|
|
4224
|
+
if (!hsl) return colorInput;
|
|
4225
|
+
const rgb = hslToRgb(hsl);
|
|
4226
|
+
const clampedAlpha = Math.max(0, Math.min(1, alpha));
|
|
4227
|
+
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${clampedAlpha})`;
|
|
4228
|
+
}
|
|
4229
|
+
|
|
3982
4230
|
// src/providers/UnifiedThemeProvider.tsx
|
|
3983
4231
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
3984
4232
|
var UnifiedThemeContext = (0, import_react2.createContext)(void 0);
|
|
@@ -4001,6 +4249,14 @@ function setStoredMode(mode, storageKey) {
|
|
|
4001
4249
|
} catch {
|
|
4002
4250
|
}
|
|
4003
4251
|
}
|
|
4252
|
+
function normalizeColorValueToHslTriplet(value) {
|
|
4253
|
+
const trimmed = value.trim();
|
|
4254
|
+
const parsedHsl = parseHSL(trimmed);
|
|
4255
|
+
if (parsedHsl) return formatHSL(parsedHsl, false);
|
|
4256
|
+
const parsedRgb = parseHex(trimmed);
|
|
4257
|
+
if (parsedRgb) return formatHSL(rgbToHsl(parsedRgb), false);
|
|
4258
|
+
return value;
|
|
4259
|
+
}
|
|
4004
4260
|
function ThemeProvider({
|
|
4005
4261
|
children,
|
|
4006
4262
|
defaultMode = "system",
|
|
@@ -4176,6 +4432,9 @@ function ThemeProvider({
|
|
|
4176
4432
|
value = defaultValues[prop];
|
|
4177
4433
|
}
|
|
4178
4434
|
if (value) {
|
|
4435
|
+
if (CSS_PROPERTY_CATEGORIES.colors.includes(prop) || prop === "shadow-color") {
|
|
4436
|
+
value = normalizeColorValueToHslTriplet(String(value));
|
|
4437
|
+
}
|
|
4179
4438
|
const cssVar = `--${prop}`;
|
|
4180
4439
|
root.style.setProperty(cssVar, value);
|
|
4181
4440
|
appliedCount++;
|
|
@@ -4461,140 +4720,6 @@ ThemeToggle.displayName = "ThemeToggle";
|
|
|
4461
4720
|
// src/components/ThemePresetButtons.tsx
|
|
4462
4721
|
var import_react4 = require("react");
|
|
4463
4722
|
var import_clsx2 = require("clsx");
|
|
4464
|
-
|
|
4465
|
-
// src/utils/colors.ts
|
|
4466
|
-
function parseHSL(hslString) {
|
|
4467
|
-
try {
|
|
4468
|
-
const cleaned = hslString.replace(/hsl\(|\)/g, "").replace(/[,%]/g, " ").trim();
|
|
4469
|
-
const parts = cleaned.split(/\s+/).filter(Boolean);
|
|
4470
|
-
if (parts.length !== 3) return null;
|
|
4471
|
-
const h = parseFloat(parts[0]) || 0;
|
|
4472
|
-
const s = parseFloat(parts[1]) || 0;
|
|
4473
|
-
const l = parseFloat(parts[2]) || 0;
|
|
4474
|
-
return {
|
|
4475
|
-
h: Math.max(0, Math.min(360, h)),
|
|
4476
|
-
s: Math.max(0, Math.min(100, s)),
|
|
4477
|
-
l: Math.max(0, Math.min(100, l))
|
|
4478
|
-
};
|
|
4479
|
-
} catch {
|
|
4480
|
-
return null;
|
|
4481
|
-
}
|
|
4482
|
-
}
|
|
4483
|
-
function parseHex(hexString) {
|
|
4484
|
-
try {
|
|
4485
|
-
let hex = hexString.replace("#", "");
|
|
4486
|
-
if (hex.length === 3) {
|
|
4487
|
-
hex = hex.split("").map((char) => char + char).join("");
|
|
4488
|
-
}
|
|
4489
|
-
if (hex.length !== 6) return null;
|
|
4490
|
-
const r = parseInt(hex.substring(0, 2), 16);
|
|
4491
|
-
const s = parseInt(hex.substring(2, 4), 16);
|
|
4492
|
-
const l = parseInt(hex.substring(4, 6), 16);
|
|
4493
|
-
if (isNaN(r) || isNaN(s) || isNaN(l)) return null;
|
|
4494
|
-
return { r, g: s, b: l };
|
|
4495
|
-
} catch {
|
|
4496
|
-
return null;
|
|
4497
|
-
}
|
|
4498
|
-
}
|
|
4499
|
-
function hslToRgb(hsl) {
|
|
4500
|
-
const h = hsl.h / 360;
|
|
4501
|
-
const s = hsl.s / 100;
|
|
4502
|
-
const l = hsl.l / 100;
|
|
4503
|
-
if (s === 0) {
|
|
4504
|
-
const gray = Math.round(l * 255);
|
|
4505
|
-
return { r: gray, g: gray, b: gray };
|
|
4506
|
-
}
|
|
4507
|
-
const hue2rgb = (p2, q2, t) => {
|
|
4508
|
-
if (t < 0) t += 1;
|
|
4509
|
-
if (t > 1) t -= 1;
|
|
4510
|
-
if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
|
|
4511
|
-
if (t < 1 / 2) return q2;
|
|
4512
|
-
if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
|
|
4513
|
-
return p2;
|
|
4514
|
-
};
|
|
4515
|
-
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
4516
|
-
const p = 2 * l - q;
|
|
4517
|
-
const r = Math.round(hue2rgb(p, q, h + 1 / 3) * 255);
|
|
4518
|
-
const g = Math.round(hue2rgb(p, q, h) * 255);
|
|
4519
|
-
const b = Math.round(hue2rgb(p, q, h - 1 / 3) * 255);
|
|
4520
|
-
return { r, g, b };
|
|
4521
|
-
}
|
|
4522
|
-
function rgbToHsl(rgb) {
|
|
4523
|
-
const r = rgb.r / 255;
|
|
4524
|
-
const g = rgb.g / 255;
|
|
4525
|
-
const b = rgb.b / 255;
|
|
4526
|
-
const max = Math.max(r, g, b);
|
|
4527
|
-
const min = Math.min(r, g, b);
|
|
4528
|
-
const diff = max - min;
|
|
4529
|
-
let h = 0;
|
|
4530
|
-
let s = 0;
|
|
4531
|
-
const l = (max + min) / 2;
|
|
4532
|
-
if (diff !== 0) {
|
|
4533
|
-
s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min);
|
|
4534
|
-
switch (max) {
|
|
4535
|
-
case r:
|
|
4536
|
-
h = (g - b) / diff + (g < b ? 6 : 0);
|
|
4537
|
-
break;
|
|
4538
|
-
case g:
|
|
4539
|
-
h = (b - r) / diff + 2;
|
|
4540
|
-
break;
|
|
4541
|
-
case b:
|
|
4542
|
-
h = (r - g) / diff + 4;
|
|
4543
|
-
break;
|
|
4544
|
-
}
|
|
4545
|
-
h /= 6;
|
|
4546
|
-
}
|
|
4547
|
-
return {
|
|
4548
|
-
h: Math.round(h * 360),
|
|
4549
|
-
s: Math.round(s * 100),
|
|
4550
|
-
l: Math.round(l * 100)
|
|
4551
|
-
};
|
|
4552
|
-
}
|
|
4553
|
-
function formatHSL(hsl, includeHslWrapper = true) {
|
|
4554
|
-
const values = `${hsl.h} ${hsl.s}% ${hsl.l}%`;
|
|
4555
|
-
return includeHslWrapper ? `hsl(${values})` : values;
|
|
4556
|
-
}
|
|
4557
|
-
function formatRGB(rgb) {
|
|
4558
|
-
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
|
|
4559
|
-
}
|
|
4560
|
-
function formatHex(rgb) {
|
|
4561
|
-
const toHex = (n) => {
|
|
4562
|
-
const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
|
|
4563
|
-
return hex.length === 1 ? "0" + hex : hex;
|
|
4564
|
-
};
|
|
4565
|
-
return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
|
|
4566
|
-
}
|
|
4567
|
-
function formatColor(colorInput, outputFormat = "hsl", includeFunctionWrapper = true) {
|
|
4568
|
-
let hsl = parseHSL(colorInput);
|
|
4569
|
-
if (!hsl) {
|
|
4570
|
-
const rgb = parseHex(colorInput);
|
|
4571
|
-
if (rgb) {
|
|
4572
|
-
hsl = rgbToHsl(rgb);
|
|
4573
|
-
}
|
|
4574
|
-
}
|
|
4575
|
-
if (!hsl) {
|
|
4576
|
-
return colorInput;
|
|
4577
|
-
}
|
|
4578
|
-
switch (outputFormat) {
|
|
4579
|
-
case "hsl":
|
|
4580
|
-
return formatHSL(hsl, includeFunctionWrapper);
|
|
4581
|
-
case "rgb":
|
|
4582
|
-
return formatRGB(hslToRgb(hsl));
|
|
4583
|
-
case "hex":
|
|
4584
|
-
return formatHex(hslToRgb(hsl));
|
|
4585
|
-
default:
|
|
4586
|
-
return colorInput;
|
|
4587
|
-
}
|
|
4588
|
-
}
|
|
4589
|
-
function withAlpha(colorInput, alpha) {
|
|
4590
|
-
const hsl = parseHSL(colorInput);
|
|
4591
|
-
if (!hsl) return colorInput;
|
|
4592
|
-
const rgb = hslToRgb(hsl);
|
|
4593
|
-
const clampedAlpha = Math.max(0, Math.min(1, alpha));
|
|
4594
|
-
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${clampedAlpha})`;
|
|
4595
|
-
}
|
|
4596
|
-
|
|
4597
|
-
// src/components/ThemePresetButtons.tsx
|
|
4598
4723
|
var import_jsx_runtime4 = require("react/jsx-runtime");
|
|
4599
4724
|
var DEFAULT_ANIMATION = {
|
|
4600
4725
|
enabled: true,
|
|
@@ -4617,6 +4742,17 @@ var DEFAULT_LAYOUT = {
|
|
|
4617
4742
|
colorBoxCount: 3,
|
|
4618
4743
|
enableMask: true
|
|
4619
4744
|
};
|
|
4745
|
+
function getPresetButtonWidthPx(label, layout) {
|
|
4746
|
+
const approxCharWidthPx = 7.25;
|
|
4747
|
+
const maxWidthPx = 360;
|
|
4748
|
+
const dotSizePx = 12;
|
|
4749
|
+
const dotGapPx = 4;
|
|
4750
|
+
const dotsWidthPx = layout.showColorBoxes ? layout.colorBoxCount * dotSizePx + Math.max(0, layout.colorBoxCount - 1) * dotGapPx : 0;
|
|
4751
|
+
const contentPaddingPx = 28;
|
|
4752
|
+
const estimatedTextWidthPx = Math.ceil(label.length * approxCharWidthPx);
|
|
4753
|
+
const estimatedWidthPx = contentPaddingPx + dotsWidthPx + estimatedTextWidthPx;
|
|
4754
|
+
return Math.min(maxWidthPx, Math.max(layout.buttonWidth, estimatedWidthPx));
|
|
4755
|
+
}
|
|
4620
4756
|
var ColorBox = ({ color, className }) => {
|
|
4621
4757
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4622
4758
|
"div",
|
|
@@ -4637,6 +4773,7 @@ var PresetButton = ({
|
|
|
4637
4773
|
}) => {
|
|
4638
4774
|
const colors = preset.colors[mode];
|
|
4639
4775
|
const label = preset.name.replace(/-/g, " ");
|
|
4776
|
+
const buttonWidth = Math.max(layout.buttonWidth, Number(preset.metadata?.buttonWidth ?? 0) || layout.buttonWidth);
|
|
4640
4777
|
if (renderPreset) {
|
|
4641
4778
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4642
4779
|
"div",
|
|
@@ -4648,7 +4785,7 @@ var PresetButton = ({
|
|
|
4648
4785
|
}
|
|
4649
4786
|
);
|
|
4650
4787
|
}
|
|
4651
|
-
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex-shrink-0", style: {
|
|
4788
|
+
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { className: "flex-shrink-0", style: { width: buttonWidth }, children: /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
|
|
4652
4789
|
"button",
|
|
4653
4790
|
{
|
|
4654
4791
|
type: "button",
|
|
@@ -4680,7 +4817,7 @@ var AnimatedRow = ({
|
|
|
4680
4817
|
}) => {
|
|
4681
4818
|
if (presets.length === 0) return null;
|
|
4682
4819
|
const duplicatedPresets = Array(animation.duplicationFactor).fill(presets).flat();
|
|
4683
|
-
const totalWidth = presets.
|
|
4820
|
+
const totalWidth = presets.reduce((sum, preset) => sum + (Number(preset.metadata?.buttonWidth) || layout.buttonWidth), 0) + presets.length * layout.buttonGap;
|
|
4684
4821
|
const effectiveScrollSpeed = Math.max(0.1, animation.scrollSpeed || 1);
|
|
4685
4822
|
const animationDuration = presets.length * animation.duration / effectiveScrollSpeed;
|
|
4686
4823
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
@@ -4760,6 +4897,7 @@ var ThemePresetButtons = ({
|
|
|
4760
4897
|
dark: preset.styles.dark
|
|
4761
4898
|
},
|
|
4762
4899
|
metadata: {
|
|
4900
|
+
buttonWidth: getPresetButtonWidthPx(preset.label, layout),
|
|
4763
4901
|
category: preset.label.toLowerCase().includes("minimal") ? "minimal" : preset.label.toLowerCase().includes("violet") || preset.label.toLowerCase().includes("purple") ? "vibrant" : "modern",
|
|
4764
4902
|
tags: [preset.label.toLowerCase().replace(/\s+/g, "-")],
|
|
4765
4903
|
createdAt: preset.createdAt,
|
|
@@ -4778,6 +4916,7 @@ var ThemePresetButtons = ({
|
|
|
4778
4916
|
dark: preset.styles.dark
|
|
4779
4917
|
},
|
|
4780
4918
|
metadata: {
|
|
4919
|
+
buttonWidth: getPresetButtonWidthPx(preset.label, layout),
|
|
4781
4920
|
category: preset.label.toLowerCase().includes("minimal") ? "minimal" : preset.label.toLowerCase().includes("violet") || preset.label.toLowerCase().includes("purple") ? "vibrant" : "modern",
|
|
4782
4921
|
tags: [preset.label.toLowerCase().replace(/\s+/g, "-")],
|
|
4783
4922
|
createdAt: preset.createdAt,
|
|
@@ -4802,7 +4941,7 @@ var ThemePresetButtons = ({
|
|
|
4802
4941
|
} finally {
|
|
4803
4942
|
setLoading(false);
|
|
4804
4943
|
}
|
|
4805
|
-
}, [availablePresets, builtInPresets, customPresets, categories, maxPresets, showBuiltIn, showCustom]);
|
|
4944
|
+
}, [availablePresets, builtInPresets, customPresets, categories, maxPresets, showBuiltIn, showCustom, layout]);
|
|
4806
4945
|
(0, import_react4.useEffect)(() => {
|
|
4807
4946
|
loadPresets();
|
|
4808
4947
|
}, [loadPresets]);
|
package/dist/index.mjs
CHANGED
|
@@ -3827,7 +3827,15 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3827
3827
|
'destructive', 'destructive-foreground', 'border', 'input', 'ring',
|
|
3828
3828
|
'chart-1', 'chart-2', 'chart-3', 'chart-4', 'chart-5',
|
|
3829
3829
|
'sidebar', 'sidebar-foreground', 'sidebar-primary', 'sidebar-primary-foreground',
|
|
3830
|
-
'sidebar-accent', 'sidebar-accent-foreground', 'sidebar-border', 'sidebar-ring'
|
|
3830
|
+
'sidebar-accent', 'sidebar-accent-foreground', 'sidebar-border', 'sidebar-ring',
|
|
3831
|
+
// Semantic accent colors for status and feedback
|
|
3832
|
+
'accent-info', 'accent-info-foreground',
|
|
3833
|
+
'accent-success', 'accent-success-foreground',
|
|
3834
|
+
'accent-warning', 'accent-warning-foreground',
|
|
3835
|
+
'accent-danger', 'accent-danger-foreground',
|
|
3836
|
+
'accent-brand', 'accent-brand-foreground',
|
|
3837
|
+
'accent-feature', 'accent-feature-foreground',
|
|
3838
|
+
'accent-highlight', 'accent-highlight-foreground'
|
|
3831
3839
|
],
|
|
3832
3840
|
typography: ['font-sans', 'font-serif', 'font-mono'],
|
|
3833
3841
|
layout: ['radius'],
|
|
@@ -3835,6 +3843,106 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3835
3843
|
spacing: ['letter-spacing', 'spacing']
|
|
3836
3844
|
};
|
|
3837
3845
|
|
|
3846
|
+
// Normalize hex/rgb/hsl() colors into "H S% L%" for hsl(var(--token)) usage.
|
|
3847
|
+
function normalizeColorValueToHslTriplet(value) {
|
|
3848
|
+
if (!value) return value;
|
|
3849
|
+
const trimmed = String(value).trim();
|
|
3850
|
+
if (!trimmed) return value;
|
|
3851
|
+
if (trimmed.startsWith('var(')) return trimmed;
|
|
3852
|
+
|
|
3853
|
+
// Already a triplet: "210 40% 98%"
|
|
3854
|
+
if (/^\\d+(?:\\.\\d+)?\\s+\\d+(?:\\.\\d+)?%\\s+\\d+(?:\\.\\d+)?%$/.test(trimmed)) {
|
|
3855
|
+
return trimmed;
|
|
3856
|
+
}
|
|
3857
|
+
|
|
3858
|
+
function clamp(n, min, max) {
|
|
3859
|
+
return Math.min(max, Math.max(min, n));
|
|
3860
|
+
}
|
|
3861
|
+
|
|
3862
|
+
function rgbToHsl(r, g, b) {
|
|
3863
|
+
r /= 255;
|
|
3864
|
+
g /= 255;
|
|
3865
|
+
b /= 255;
|
|
3866
|
+
const max = Math.max(r, g, b);
|
|
3867
|
+
const min = Math.min(r, g, b);
|
|
3868
|
+
const diff = max - min;
|
|
3869
|
+
let h = 0;
|
|
3870
|
+
let s = 0;
|
|
3871
|
+
const l = (max + min) / 2;
|
|
3872
|
+
|
|
3873
|
+
if (diff !== 0) {
|
|
3874
|
+
s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min);
|
|
3875
|
+
switch (max) {
|
|
3876
|
+
case r:
|
|
3877
|
+
h = (g - b) / diff + (g < b ? 6 : 0);
|
|
3878
|
+
break;
|
|
3879
|
+
case g:
|
|
3880
|
+
h = (b - r) / diff + 2;
|
|
3881
|
+
break;
|
|
3882
|
+
case b:
|
|
3883
|
+
h = (r - g) / diff + 4;
|
|
3884
|
+
break;
|
|
3885
|
+
}
|
|
3886
|
+
h /= 6;
|
|
3887
|
+
}
|
|
3888
|
+
|
|
3889
|
+
return {
|
|
3890
|
+
h: Math.round(h * 360),
|
|
3891
|
+
s: Math.round(s * 100),
|
|
3892
|
+
l: Math.round(l * 100),
|
|
3893
|
+
};
|
|
3894
|
+
}
|
|
3895
|
+
|
|
3896
|
+
function hexToRgb(hex) {
|
|
3897
|
+
let clean = hex.replace('#', '').trim();
|
|
3898
|
+
if (clean.length === 3) clean = clean.split('').map(function(c) { return c + c; }).join('');
|
|
3899
|
+
if (clean.length === 8) clean = clean.substring(0, 6); // ignore alpha
|
|
3900
|
+
if (clean.length !== 6) return null;
|
|
3901
|
+
|
|
3902
|
+
const r = parseInt(clean.substring(0, 2), 16);
|
|
3903
|
+
const g = parseInt(clean.substring(2, 4), 16);
|
|
3904
|
+
const b = parseInt(clean.substring(4, 6), 16);
|
|
3905
|
+
if (isNaN(r) || isNaN(g) || isNaN(b)) return null;
|
|
3906
|
+
return { r: r, g: g, b: b };
|
|
3907
|
+
}
|
|
3908
|
+
|
|
3909
|
+
function toTriplet(hsl) {
|
|
3910
|
+
return String(clamp(hsl.h, 0, 360)) + ' ' + String(clamp(hsl.s, 0, 100)) + '% ' + String(clamp(hsl.l, 0, 100)) + '%';
|
|
3911
|
+
}
|
|
3912
|
+
|
|
3913
|
+
// hsl(...) or raw "H S% L%"
|
|
3914
|
+
if (/^hsl\\(/i.test(trimmed)) {
|
|
3915
|
+
const cleaned = trimmed.replace(/hsl\\(|\\)/gi, '').replace(/[,%]/g, ' ').trim();
|
|
3916
|
+
const parts = cleaned.split(/\\s+/).filter(Boolean);
|
|
3917
|
+
if (parts.length === 3) {
|
|
3918
|
+
const h = parseFloat(parts[0]) || 0;
|
|
3919
|
+
const s = parseFloat(parts[1]) || 0;
|
|
3920
|
+
const l = parseFloat(parts[2]) || 0;
|
|
3921
|
+
return toTriplet({ h: h, s: s, l: l });
|
|
3922
|
+
}
|
|
3923
|
+
}
|
|
3924
|
+
|
|
3925
|
+
// rgb(...)
|
|
3926
|
+
if (/^rgb\\(/i.test(trimmed)) {
|
|
3927
|
+
const cleaned = trimmed.replace(/rgb\\(|\\)/gi, '').trim();
|
|
3928
|
+
const parts = cleaned.split(',').map(function(p) { return p.trim(); });
|
|
3929
|
+
if (parts.length === 3) {
|
|
3930
|
+
const r = clamp(parseFloat(parts[0]) || 0, 0, 255);
|
|
3931
|
+
const g = clamp(parseFloat(parts[1]) || 0, 0, 255);
|
|
3932
|
+
const b = clamp(parseFloat(parts[2]) || 0, 0, 255);
|
|
3933
|
+
return toTriplet(rgbToHsl(r, g, b));
|
|
3934
|
+
}
|
|
3935
|
+
}
|
|
3936
|
+
|
|
3937
|
+
// hex
|
|
3938
|
+
if (trimmed[0] === '#') {
|
|
3939
|
+
const rgb = hexToRgb(trimmed);
|
|
3940
|
+
if (rgb) return toTriplet(rgbToHsl(rgb.r, rgb.g, rgb.b));
|
|
3941
|
+
}
|
|
3942
|
+
|
|
3943
|
+
return value;
|
|
3944
|
+
}
|
|
3945
|
+
|
|
3838
3946
|
// Function to apply all preset properties - with proper clearing and defaults
|
|
3839
3947
|
function applyPresetProperties(colors) {
|
|
3840
3948
|
if (!colors) return;
|
|
@@ -3866,6 +3974,10 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3866
3974
|
|
|
3867
3975
|
// Apply all properties with defaults for missing ones
|
|
3868
3976
|
let appliedCount = 0;
|
|
3977
|
+
const colorProps = {};
|
|
3978
|
+
CSS_CATEGORIES.colors.forEach(function(prop) { colorProps[prop] = true; });
|
|
3979
|
+
colorProps['shadow-color'] = true;
|
|
3980
|
+
|
|
3869
3981
|
allProperties.forEach(function(prop) {
|
|
3870
3982
|
let value = colors[prop];
|
|
3871
3983
|
|
|
@@ -3875,6 +3987,10 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3875
3987
|
}
|
|
3876
3988
|
|
|
3877
3989
|
if (value) {
|
|
3990
|
+
if (colorProps[prop]) {
|
|
3991
|
+
value = normalizeColorValueToHslTriplet(value);
|
|
3992
|
+
}
|
|
3993
|
+
|
|
3878
3994
|
const cssVar = '--' + prop;
|
|
3879
3995
|
// Apply directly like TweakCN does - no conversion, no !important
|
|
3880
3996
|
root.style.setProperty(cssVar, value);
|
|
@@ -3936,6 +4052,138 @@ function ThemeScript({ presetStorageKey = "theme-preset", defaultPreset }) {
|
|
|
3936
4052
|
return /* @__PURE__ */ jsx("script", { dangerouslySetInnerHTML: { __html: scriptContent }, suppressHydrationWarning: true });
|
|
3937
4053
|
}
|
|
3938
4054
|
|
|
4055
|
+
// src/utils/colors.ts
|
|
4056
|
+
function parseHSL(hslString) {
|
|
4057
|
+
try {
|
|
4058
|
+
const cleaned = hslString.replace(/hsl\(|\)/g, "").replace(/[,%]/g, " ").trim();
|
|
4059
|
+
const parts = cleaned.split(/\s+/).filter(Boolean);
|
|
4060
|
+
if (parts.length !== 3) return null;
|
|
4061
|
+
const h = parseFloat(parts[0]) || 0;
|
|
4062
|
+
const s = parseFloat(parts[1]) || 0;
|
|
4063
|
+
const l = parseFloat(parts[2]) || 0;
|
|
4064
|
+
return {
|
|
4065
|
+
h: Math.max(0, Math.min(360, h)),
|
|
4066
|
+
s: Math.max(0, Math.min(100, s)),
|
|
4067
|
+
l: Math.max(0, Math.min(100, l))
|
|
4068
|
+
};
|
|
4069
|
+
} catch {
|
|
4070
|
+
return null;
|
|
4071
|
+
}
|
|
4072
|
+
}
|
|
4073
|
+
function parseHex(hexString) {
|
|
4074
|
+
try {
|
|
4075
|
+
let hex = hexString.replace("#", "");
|
|
4076
|
+
if (hex.length === 3) {
|
|
4077
|
+
hex = hex.split("").map((char) => char + char).join("");
|
|
4078
|
+
}
|
|
4079
|
+
if (hex.length !== 6) return null;
|
|
4080
|
+
const r = parseInt(hex.substring(0, 2), 16);
|
|
4081
|
+
const s = parseInt(hex.substring(2, 4), 16);
|
|
4082
|
+
const l = parseInt(hex.substring(4, 6), 16);
|
|
4083
|
+
if (isNaN(r) || isNaN(s) || isNaN(l)) return null;
|
|
4084
|
+
return { r, g: s, b: l };
|
|
4085
|
+
} catch {
|
|
4086
|
+
return null;
|
|
4087
|
+
}
|
|
4088
|
+
}
|
|
4089
|
+
function hslToRgb(hsl) {
|
|
4090
|
+
const h = hsl.h / 360;
|
|
4091
|
+
const s = hsl.s / 100;
|
|
4092
|
+
const l = hsl.l / 100;
|
|
4093
|
+
if (s === 0) {
|
|
4094
|
+
const gray = Math.round(l * 255);
|
|
4095
|
+
return { r: gray, g: gray, b: gray };
|
|
4096
|
+
}
|
|
4097
|
+
const hue2rgb = (p2, q2, t) => {
|
|
4098
|
+
if (t < 0) t += 1;
|
|
4099
|
+
if (t > 1) t -= 1;
|
|
4100
|
+
if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
|
|
4101
|
+
if (t < 1 / 2) return q2;
|
|
4102
|
+
if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
|
|
4103
|
+
return p2;
|
|
4104
|
+
};
|
|
4105
|
+
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
4106
|
+
const p = 2 * l - q;
|
|
4107
|
+
const r = Math.round(hue2rgb(p, q, h + 1 / 3) * 255);
|
|
4108
|
+
const g = Math.round(hue2rgb(p, q, h) * 255);
|
|
4109
|
+
const b = Math.round(hue2rgb(p, q, h - 1 / 3) * 255);
|
|
4110
|
+
return { r, g, b };
|
|
4111
|
+
}
|
|
4112
|
+
function rgbToHsl(rgb) {
|
|
4113
|
+
const r = rgb.r / 255;
|
|
4114
|
+
const g = rgb.g / 255;
|
|
4115
|
+
const b = rgb.b / 255;
|
|
4116
|
+
const max = Math.max(r, g, b);
|
|
4117
|
+
const min = Math.min(r, g, b);
|
|
4118
|
+
const diff = max - min;
|
|
4119
|
+
let h = 0;
|
|
4120
|
+
let s = 0;
|
|
4121
|
+
const l = (max + min) / 2;
|
|
4122
|
+
if (diff !== 0) {
|
|
4123
|
+
s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min);
|
|
4124
|
+
switch (max) {
|
|
4125
|
+
case r:
|
|
4126
|
+
h = (g - b) / diff + (g < b ? 6 : 0);
|
|
4127
|
+
break;
|
|
4128
|
+
case g:
|
|
4129
|
+
h = (b - r) / diff + 2;
|
|
4130
|
+
break;
|
|
4131
|
+
case b:
|
|
4132
|
+
h = (r - g) / diff + 4;
|
|
4133
|
+
break;
|
|
4134
|
+
}
|
|
4135
|
+
h /= 6;
|
|
4136
|
+
}
|
|
4137
|
+
return {
|
|
4138
|
+
h: Math.round(h * 360),
|
|
4139
|
+
s: Math.round(s * 100),
|
|
4140
|
+
l: Math.round(l * 100)
|
|
4141
|
+
};
|
|
4142
|
+
}
|
|
4143
|
+
function formatHSL(hsl, includeHslWrapper = true) {
|
|
4144
|
+
const values = `${hsl.h} ${hsl.s}% ${hsl.l}%`;
|
|
4145
|
+
return includeHslWrapper ? `hsl(${values})` : values;
|
|
4146
|
+
}
|
|
4147
|
+
function formatRGB(rgb) {
|
|
4148
|
+
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
|
|
4149
|
+
}
|
|
4150
|
+
function formatHex(rgb) {
|
|
4151
|
+
const toHex = (n) => {
|
|
4152
|
+
const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
|
|
4153
|
+
return hex.length === 1 ? "0" + hex : hex;
|
|
4154
|
+
};
|
|
4155
|
+
return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
|
|
4156
|
+
}
|
|
4157
|
+
function formatColor(colorInput, outputFormat = "hsl", includeFunctionWrapper = true) {
|
|
4158
|
+
let hsl = parseHSL(colorInput);
|
|
4159
|
+
if (!hsl) {
|
|
4160
|
+
const rgb = parseHex(colorInput);
|
|
4161
|
+
if (rgb) {
|
|
4162
|
+
hsl = rgbToHsl(rgb);
|
|
4163
|
+
}
|
|
4164
|
+
}
|
|
4165
|
+
if (!hsl) {
|
|
4166
|
+
return colorInput;
|
|
4167
|
+
}
|
|
4168
|
+
switch (outputFormat) {
|
|
4169
|
+
case "hsl":
|
|
4170
|
+
return formatHSL(hsl, includeFunctionWrapper);
|
|
4171
|
+
case "rgb":
|
|
4172
|
+
return formatRGB(hslToRgb(hsl));
|
|
4173
|
+
case "hex":
|
|
4174
|
+
return formatHex(hslToRgb(hsl));
|
|
4175
|
+
default:
|
|
4176
|
+
return colorInput;
|
|
4177
|
+
}
|
|
4178
|
+
}
|
|
4179
|
+
function withAlpha(colorInput, alpha) {
|
|
4180
|
+
const hsl = parseHSL(colorInput);
|
|
4181
|
+
if (!hsl) return colorInput;
|
|
4182
|
+
const rgb = hslToRgb(hsl);
|
|
4183
|
+
const clampedAlpha = Math.max(0, Math.min(1, alpha));
|
|
4184
|
+
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${clampedAlpha})`;
|
|
4185
|
+
}
|
|
4186
|
+
|
|
3939
4187
|
// src/providers/UnifiedThemeProvider.tsx
|
|
3940
4188
|
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
3941
4189
|
var UnifiedThemeContext = createContext(void 0);
|
|
@@ -3958,6 +4206,14 @@ function setStoredMode(mode, storageKey) {
|
|
|
3958
4206
|
} catch {
|
|
3959
4207
|
}
|
|
3960
4208
|
}
|
|
4209
|
+
function normalizeColorValueToHslTriplet(value) {
|
|
4210
|
+
const trimmed = value.trim();
|
|
4211
|
+
const parsedHsl = parseHSL(trimmed);
|
|
4212
|
+
if (parsedHsl) return formatHSL(parsedHsl, false);
|
|
4213
|
+
const parsedRgb = parseHex(trimmed);
|
|
4214
|
+
if (parsedRgb) return formatHSL(rgbToHsl(parsedRgb), false);
|
|
4215
|
+
return value;
|
|
4216
|
+
}
|
|
3961
4217
|
function ThemeProvider({
|
|
3962
4218
|
children,
|
|
3963
4219
|
defaultMode = "system",
|
|
@@ -4133,6 +4389,9 @@ function ThemeProvider({
|
|
|
4133
4389
|
value = defaultValues[prop];
|
|
4134
4390
|
}
|
|
4135
4391
|
if (value) {
|
|
4392
|
+
if (CSS_PROPERTY_CATEGORIES.colors.includes(prop) || prop === "shadow-color") {
|
|
4393
|
+
value = normalizeColorValueToHslTriplet(String(value));
|
|
4394
|
+
}
|
|
4136
4395
|
const cssVar = `--${prop}`;
|
|
4137
4396
|
root.style.setProperty(cssVar, value);
|
|
4138
4397
|
appliedCount++;
|
|
@@ -4418,140 +4677,6 @@ ThemeToggle.displayName = "ThemeToggle";
|
|
|
4418
4677
|
// src/components/ThemePresetButtons.tsx
|
|
4419
4678
|
import { useEffect as useEffect2, useState as useState2, useCallback as useCallback2, useMemo as useMemo3 } from "react";
|
|
4420
4679
|
import { clsx as clsx2 } from "clsx";
|
|
4421
|
-
|
|
4422
|
-
// src/utils/colors.ts
|
|
4423
|
-
function parseHSL(hslString) {
|
|
4424
|
-
try {
|
|
4425
|
-
const cleaned = hslString.replace(/hsl\(|\)/g, "").replace(/[,%]/g, " ").trim();
|
|
4426
|
-
const parts = cleaned.split(/\s+/).filter(Boolean);
|
|
4427
|
-
if (parts.length !== 3) return null;
|
|
4428
|
-
const h = parseFloat(parts[0]) || 0;
|
|
4429
|
-
const s = parseFloat(parts[1]) || 0;
|
|
4430
|
-
const l = parseFloat(parts[2]) || 0;
|
|
4431
|
-
return {
|
|
4432
|
-
h: Math.max(0, Math.min(360, h)),
|
|
4433
|
-
s: Math.max(0, Math.min(100, s)),
|
|
4434
|
-
l: Math.max(0, Math.min(100, l))
|
|
4435
|
-
};
|
|
4436
|
-
} catch {
|
|
4437
|
-
return null;
|
|
4438
|
-
}
|
|
4439
|
-
}
|
|
4440
|
-
function parseHex(hexString) {
|
|
4441
|
-
try {
|
|
4442
|
-
let hex = hexString.replace("#", "");
|
|
4443
|
-
if (hex.length === 3) {
|
|
4444
|
-
hex = hex.split("").map((char) => char + char).join("");
|
|
4445
|
-
}
|
|
4446
|
-
if (hex.length !== 6) return null;
|
|
4447
|
-
const r = parseInt(hex.substring(0, 2), 16);
|
|
4448
|
-
const s = parseInt(hex.substring(2, 4), 16);
|
|
4449
|
-
const l = parseInt(hex.substring(4, 6), 16);
|
|
4450
|
-
if (isNaN(r) || isNaN(s) || isNaN(l)) return null;
|
|
4451
|
-
return { r, g: s, b: l };
|
|
4452
|
-
} catch {
|
|
4453
|
-
return null;
|
|
4454
|
-
}
|
|
4455
|
-
}
|
|
4456
|
-
function hslToRgb(hsl) {
|
|
4457
|
-
const h = hsl.h / 360;
|
|
4458
|
-
const s = hsl.s / 100;
|
|
4459
|
-
const l = hsl.l / 100;
|
|
4460
|
-
if (s === 0) {
|
|
4461
|
-
const gray = Math.round(l * 255);
|
|
4462
|
-
return { r: gray, g: gray, b: gray };
|
|
4463
|
-
}
|
|
4464
|
-
const hue2rgb = (p2, q2, t) => {
|
|
4465
|
-
if (t < 0) t += 1;
|
|
4466
|
-
if (t > 1) t -= 1;
|
|
4467
|
-
if (t < 1 / 6) return p2 + (q2 - p2) * 6 * t;
|
|
4468
|
-
if (t < 1 / 2) return q2;
|
|
4469
|
-
if (t < 2 / 3) return p2 + (q2 - p2) * (2 / 3 - t) * 6;
|
|
4470
|
-
return p2;
|
|
4471
|
-
};
|
|
4472
|
-
const q = l < 0.5 ? l * (1 + s) : l + s - l * s;
|
|
4473
|
-
const p = 2 * l - q;
|
|
4474
|
-
const r = Math.round(hue2rgb(p, q, h + 1 / 3) * 255);
|
|
4475
|
-
const g = Math.round(hue2rgb(p, q, h) * 255);
|
|
4476
|
-
const b = Math.round(hue2rgb(p, q, h - 1 / 3) * 255);
|
|
4477
|
-
return { r, g, b };
|
|
4478
|
-
}
|
|
4479
|
-
function rgbToHsl(rgb) {
|
|
4480
|
-
const r = rgb.r / 255;
|
|
4481
|
-
const g = rgb.g / 255;
|
|
4482
|
-
const b = rgb.b / 255;
|
|
4483
|
-
const max = Math.max(r, g, b);
|
|
4484
|
-
const min = Math.min(r, g, b);
|
|
4485
|
-
const diff = max - min;
|
|
4486
|
-
let h = 0;
|
|
4487
|
-
let s = 0;
|
|
4488
|
-
const l = (max + min) / 2;
|
|
4489
|
-
if (diff !== 0) {
|
|
4490
|
-
s = l > 0.5 ? diff / (2 - max - min) : diff / (max + min);
|
|
4491
|
-
switch (max) {
|
|
4492
|
-
case r:
|
|
4493
|
-
h = (g - b) / diff + (g < b ? 6 : 0);
|
|
4494
|
-
break;
|
|
4495
|
-
case g:
|
|
4496
|
-
h = (b - r) / diff + 2;
|
|
4497
|
-
break;
|
|
4498
|
-
case b:
|
|
4499
|
-
h = (r - g) / diff + 4;
|
|
4500
|
-
break;
|
|
4501
|
-
}
|
|
4502
|
-
h /= 6;
|
|
4503
|
-
}
|
|
4504
|
-
return {
|
|
4505
|
-
h: Math.round(h * 360),
|
|
4506
|
-
s: Math.round(s * 100),
|
|
4507
|
-
l: Math.round(l * 100)
|
|
4508
|
-
};
|
|
4509
|
-
}
|
|
4510
|
-
function formatHSL(hsl, includeHslWrapper = true) {
|
|
4511
|
-
const values = `${hsl.h} ${hsl.s}% ${hsl.l}%`;
|
|
4512
|
-
return includeHslWrapper ? `hsl(${values})` : values;
|
|
4513
|
-
}
|
|
4514
|
-
function formatRGB(rgb) {
|
|
4515
|
-
return `rgb(${rgb.r}, ${rgb.g}, ${rgb.b})`;
|
|
4516
|
-
}
|
|
4517
|
-
function formatHex(rgb) {
|
|
4518
|
-
const toHex = (n) => {
|
|
4519
|
-
const hex = Math.round(Math.max(0, Math.min(255, n))).toString(16);
|
|
4520
|
-
return hex.length === 1 ? "0" + hex : hex;
|
|
4521
|
-
};
|
|
4522
|
-
return `#${toHex(rgb.r)}${toHex(rgb.g)}${toHex(rgb.b)}`;
|
|
4523
|
-
}
|
|
4524
|
-
function formatColor(colorInput, outputFormat = "hsl", includeFunctionWrapper = true) {
|
|
4525
|
-
let hsl = parseHSL(colorInput);
|
|
4526
|
-
if (!hsl) {
|
|
4527
|
-
const rgb = parseHex(colorInput);
|
|
4528
|
-
if (rgb) {
|
|
4529
|
-
hsl = rgbToHsl(rgb);
|
|
4530
|
-
}
|
|
4531
|
-
}
|
|
4532
|
-
if (!hsl) {
|
|
4533
|
-
return colorInput;
|
|
4534
|
-
}
|
|
4535
|
-
switch (outputFormat) {
|
|
4536
|
-
case "hsl":
|
|
4537
|
-
return formatHSL(hsl, includeFunctionWrapper);
|
|
4538
|
-
case "rgb":
|
|
4539
|
-
return formatRGB(hslToRgb(hsl));
|
|
4540
|
-
case "hex":
|
|
4541
|
-
return formatHex(hslToRgb(hsl));
|
|
4542
|
-
default:
|
|
4543
|
-
return colorInput;
|
|
4544
|
-
}
|
|
4545
|
-
}
|
|
4546
|
-
function withAlpha(colorInput, alpha) {
|
|
4547
|
-
const hsl = parseHSL(colorInput);
|
|
4548
|
-
if (!hsl) return colorInput;
|
|
4549
|
-
const rgb = hslToRgb(hsl);
|
|
4550
|
-
const clampedAlpha = Math.max(0, Math.min(1, alpha));
|
|
4551
|
-
return `rgba(${rgb.r}, ${rgb.g}, ${rgb.b}, ${clampedAlpha})`;
|
|
4552
|
-
}
|
|
4553
|
-
|
|
4554
|
-
// src/components/ThemePresetButtons.tsx
|
|
4555
4680
|
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
4556
4681
|
var DEFAULT_ANIMATION = {
|
|
4557
4682
|
enabled: true,
|
|
@@ -4574,6 +4699,17 @@ var DEFAULT_LAYOUT = {
|
|
|
4574
4699
|
colorBoxCount: 3,
|
|
4575
4700
|
enableMask: true
|
|
4576
4701
|
};
|
|
4702
|
+
function getPresetButtonWidthPx(label, layout) {
|
|
4703
|
+
const approxCharWidthPx = 7.25;
|
|
4704
|
+
const maxWidthPx = 360;
|
|
4705
|
+
const dotSizePx = 12;
|
|
4706
|
+
const dotGapPx = 4;
|
|
4707
|
+
const dotsWidthPx = layout.showColorBoxes ? layout.colorBoxCount * dotSizePx + Math.max(0, layout.colorBoxCount - 1) * dotGapPx : 0;
|
|
4708
|
+
const contentPaddingPx = 28;
|
|
4709
|
+
const estimatedTextWidthPx = Math.ceil(label.length * approxCharWidthPx);
|
|
4710
|
+
const estimatedWidthPx = contentPaddingPx + dotsWidthPx + estimatedTextWidthPx;
|
|
4711
|
+
return Math.min(maxWidthPx, Math.max(layout.buttonWidth, estimatedWidthPx));
|
|
4712
|
+
}
|
|
4577
4713
|
var ColorBox = ({ color, className }) => {
|
|
4578
4714
|
return /* @__PURE__ */ jsx4(
|
|
4579
4715
|
"div",
|
|
@@ -4594,6 +4730,7 @@ var PresetButton = ({
|
|
|
4594
4730
|
}) => {
|
|
4595
4731
|
const colors = preset.colors[mode];
|
|
4596
4732
|
const label = preset.name.replace(/-/g, " ");
|
|
4733
|
+
const buttonWidth = Math.max(layout.buttonWidth, Number(preset.metadata?.buttonWidth ?? 0) || layout.buttonWidth);
|
|
4597
4734
|
if (renderPreset) {
|
|
4598
4735
|
return /* @__PURE__ */ jsx4(
|
|
4599
4736
|
"div",
|
|
@@ -4605,7 +4742,7 @@ var PresetButton = ({
|
|
|
4605
4742
|
}
|
|
4606
4743
|
);
|
|
4607
4744
|
}
|
|
4608
|
-
return /* @__PURE__ */ jsx4("div", { className: "flex-shrink-0", style: {
|
|
4745
|
+
return /* @__PURE__ */ jsx4("div", { className: "flex-shrink-0", style: { width: buttonWidth }, children: /* @__PURE__ */ jsxs3(
|
|
4609
4746
|
"button",
|
|
4610
4747
|
{
|
|
4611
4748
|
type: "button",
|
|
@@ -4637,7 +4774,7 @@ var AnimatedRow = ({
|
|
|
4637
4774
|
}) => {
|
|
4638
4775
|
if (presets.length === 0) return null;
|
|
4639
4776
|
const duplicatedPresets = Array(animation.duplicationFactor).fill(presets).flat();
|
|
4640
|
-
const totalWidth = presets.
|
|
4777
|
+
const totalWidth = presets.reduce((sum, preset) => sum + (Number(preset.metadata?.buttonWidth) || layout.buttonWidth), 0) + presets.length * layout.buttonGap;
|
|
4641
4778
|
const effectiveScrollSpeed = Math.max(0.1, animation.scrollSpeed || 1);
|
|
4642
4779
|
const animationDuration = presets.length * animation.duration / effectiveScrollSpeed;
|
|
4643
4780
|
return /* @__PURE__ */ jsx4(
|
|
@@ -4717,6 +4854,7 @@ var ThemePresetButtons = ({
|
|
|
4717
4854
|
dark: preset.styles.dark
|
|
4718
4855
|
},
|
|
4719
4856
|
metadata: {
|
|
4857
|
+
buttonWidth: getPresetButtonWidthPx(preset.label, layout),
|
|
4720
4858
|
category: preset.label.toLowerCase().includes("minimal") ? "minimal" : preset.label.toLowerCase().includes("violet") || preset.label.toLowerCase().includes("purple") ? "vibrant" : "modern",
|
|
4721
4859
|
tags: [preset.label.toLowerCase().replace(/\s+/g, "-")],
|
|
4722
4860
|
createdAt: preset.createdAt,
|
|
@@ -4735,6 +4873,7 @@ var ThemePresetButtons = ({
|
|
|
4735
4873
|
dark: preset.styles.dark
|
|
4736
4874
|
},
|
|
4737
4875
|
metadata: {
|
|
4876
|
+
buttonWidth: getPresetButtonWidthPx(preset.label, layout),
|
|
4738
4877
|
category: preset.label.toLowerCase().includes("minimal") ? "minimal" : preset.label.toLowerCase().includes("violet") || preset.label.toLowerCase().includes("purple") ? "vibrant" : "modern",
|
|
4739
4878
|
tags: [preset.label.toLowerCase().replace(/\s+/g, "-")],
|
|
4740
4879
|
createdAt: preset.createdAt,
|
|
@@ -4759,7 +4898,7 @@ var ThemePresetButtons = ({
|
|
|
4759
4898
|
} finally {
|
|
4760
4899
|
setLoading(false);
|
|
4761
4900
|
}
|
|
4762
|
-
}, [availablePresets, builtInPresets, customPresets, categories, maxPresets, showBuiltIn, showCustom]);
|
|
4901
|
+
}, [availablePresets, builtInPresets, customPresets, categories, maxPresets, showBuiltIn, showCustom, layout]);
|
|
4763
4902
|
useEffect2(() => {
|
|
4764
4903
|
loadPresets();
|
|
4765
4904
|
}, [loadPresets]);
|
|
@@ -95,10 +95,10 @@
|
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
.theme-preset-button__label {
|
|
98
|
-
display:
|
|
99
|
-
-
|
|
100
|
-
-webkit-line-clamp: 2;
|
|
98
|
+
display: block;
|
|
99
|
+
white-space: nowrap;
|
|
101
100
|
overflow: hidden;
|
|
101
|
+
text-overflow: ellipsis;
|
|
102
102
|
|
|
103
103
|
line-height: 1.1;
|
|
104
104
|
font-size: 0.875rem;
|
package/dist/styles/tailwind.css
CHANGED
|
@@ -7,58 +7,58 @@
|
|
|
7
7
|
|
|
8
8
|
@theme inline {
|
|
9
9
|
/* Color mappings - Bridge between CSS variables and Tailwind classes */
|
|
10
|
-
--color-background: var(--background);
|
|
11
|
-
--color-foreground: var(--foreground);
|
|
12
|
-
--color-card: var(--card);
|
|
13
|
-
--color-card-foreground: var(--card-foreground);
|
|
14
|
-
--color-popover: var(--popover);
|
|
15
|
-
--color-popover-foreground: var(--popover-foreground);
|
|
16
|
-
--color-primary: var(--primary);
|
|
17
|
-
--color-primary-foreground: var(--primary-foreground);
|
|
18
|
-
--color-secondary: var(--secondary);
|
|
19
|
-
--color-secondary-foreground: var(--secondary-foreground);
|
|
20
|
-
--color-muted: var(--muted);
|
|
21
|
-
--color-muted-foreground: var(--muted-foreground);
|
|
22
|
-
--color-accent: var(--accent);
|
|
23
|
-
--color-accent-foreground: var(--accent-foreground);
|
|
24
|
-
--color-destructive: var(--destructive);
|
|
25
|
-
--color-destructive-foreground: var(--destructive-foreground);
|
|
26
|
-
--color-border: var(--border);
|
|
27
|
-
--color-input: var(--input);
|
|
28
|
-
--color-ring: var(--ring);
|
|
10
|
+
--color-background: hsl(var(--background));
|
|
11
|
+
--color-foreground: hsl(var(--foreground));
|
|
12
|
+
--color-card: hsl(var(--card));
|
|
13
|
+
--color-card-foreground: hsl(var(--card-foreground));
|
|
14
|
+
--color-popover: hsl(var(--popover));
|
|
15
|
+
--color-popover-foreground: hsl(var(--popover-foreground));
|
|
16
|
+
--color-primary: hsl(var(--primary));
|
|
17
|
+
--color-primary-foreground: hsl(var(--primary-foreground));
|
|
18
|
+
--color-secondary: hsl(var(--secondary));
|
|
19
|
+
--color-secondary-foreground: hsl(var(--secondary-foreground));
|
|
20
|
+
--color-muted: hsl(var(--muted));
|
|
21
|
+
--color-muted-foreground: hsl(var(--muted-foreground));
|
|
22
|
+
--color-accent: hsl(var(--accent));
|
|
23
|
+
--color-accent-foreground: hsl(var(--accent-foreground));
|
|
24
|
+
--color-destructive: hsl(var(--destructive));
|
|
25
|
+
--color-destructive-foreground: hsl(var(--destructive-foreground));
|
|
26
|
+
--color-border: hsl(var(--border));
|
|
27
|
+
--color-input: hsl(var(--input));
|
|
28
|
+
--color-ring: hsl(var(--ring));
|
|
29
29
|
|
|
30
30
|
/* Chart colors for data visualization */
|
|
31
|
-
--color-chart-1: var(--chart-1);
|
|
32
|
-
--color-chart-2: var(--chart-2);
|
|
33
|
-
--color-chart-3: var(--chart-3);
|
|
34
|
-
--color-chart-4: var(--chart-4);
|
|
35
|
-
--color-chart-5: var(--chart-5);
|
|
31
|
+
--color-chart-1: hsl(var(--chart-1));
|
|
32
|
+
--color-chart-2: hsl(var(--chart-2));
|
|
33
|
+
--color-chart-3: hsl(var(--chart-3));
|
|
34
|
+
--color-chart-4: hsl(var(--chart-4));
|
|
35
|
+
--color-chart-5: hsl(var(--chart-5));
|
|
36
36
|
|
|
37
37
|
/* Sidebar colors for dashboard layouts */
|
|
38
|
-
--color-sidebar: var(--sidebar);
|
|
39
|
-
--color-sidebar-foreground: var(--sidebar-foreground);
|
|
40
|
-
--color-sidebar-primary: var(--sidebar-primary);
|
|
41
|
-
--color-sidebar-primary-foreground: var(--sidebar-primary-foreground);
|
|
42
|
-
--color-sidebar-accent: var(--sidebar-accent);
|
|
43
|
-
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
|
44
|
-
--color-sidebar-border: var(--sidebar-border);
|
|
45
|
-
--color-sidebar-ring: var(--sidebar-ring);
|
|
38
|
+
--color-sidebar: hsl(var(--sidebar));
|
|
39
|
+
--color-sidebar-foreground: hsl(var(--sidebar-foreground));
|
|
40
|
+
--color-sidebar-primary: hsl(var(--sidebar-primary));
|
|
41
|
+
--color-sidebar-primary-foreground: hsl(var(--sidebar-primary-foreground));
|
|
42
|
+
--color-sidebar-accent: hsl(var(--sidebar-accent));
|
|
43
|
+
--color-sidebar-accent-foreground: hsl(var(--sidebar-accent-foreground));
|
|
44
|
+
--color-sidebar-border: hsl(var(--sidebar-border));
|
|
45
|
+
--color-sidebar-ring: hsl(var(--sidebar-ring));
|
|
46
46
|
|
|
47
47
|
/* Semantic accent colors for status and feedback */
|
|
48
|
-
--color-accent-info: var(--accent-info);
|
|
49
|
-
--color-accent-info-foreground: var(--accent-info-foreground);
|
|
50
|
-
--color-accent-success: var(--accent-success);
|
|
51
|
-
--color-accent-success-foreground: var(--accent-success-foreground);
|
|
52
|
-
--color-accent-warning: var(--accent-warning);
|
|
53
|
-
--color-accent-warning-foreground: var(--accent-warning-foreground);
|
|
54
|
-
--color-accent-danger: var(--accent-danger);
|
|
55
|
-
--color-accent-danger-foreground: var(--accent-danger-foreground);
|
|
56
|
-
--color-accent-brand: var(--accent-brand);
|
|
57
|
-
--color-accent-brand-foreground: var(--accent-brand-foreground);
|
|
58
|
-
--color-accent-feature: var(--accent-feature);
|
|
59
|
-
--color-accent-feature-foreground: var(--accent-feature-foreground);
|
|
60
|
-
--color-accent-highlight: var(--accent-highlight);
|
|
61
|
-
--color-accent-highlight-foreground: var(--accent-highlight-foreground);
|
|
48
|
+
--color-accent-info: hsl(var(--accent-info));
|
|
49
|
+
--color-accent-info-foreground: hsl(var(--accent-info-foreground));
|
|
50
|
+
--color-accent-success: hsl(var(--accent-success));
|
|
51
|
+
--color-accent-success-foreground: hsl(var(--accent-success-foreground));
|
|
52
|
+
--color-accent-warning: hsl(var(--accent-warning));
|
|
53
|
+
--color-accent-warning-foreground: hsl(var(--accent-warning-foreground));
|
|
54
|
+
--color-accent-danger: hsl(var(--accent-danger));
|
|
55
|
+
--color-accent-danger-foreground: hsl(var(--accent-danger-foreground));
|
|
56
|
+
--color-accent-brand: hsl(var(--accent-brand));
|
|
57
|
+
--color-accent-brand-foreground: hsl(var(--accent-brand-foreground));
|
|
58
|
+
--color-accent-feature: hsl(var(--accent-feature));
|
|
59
|
+
--color-accent-feature-foreground: hsl(var(--accent-feature-foreground));
|
|
60
|
+
--color-accent-highlight: hsl(var(--accent-highlight));
|
|
61
|
+
--color-accent-highlight-foreground: hsl(var(--accent-highlight-foreground));
|
|
62
62
|
|
|
63
63
|
/* Dynamic border radius system */
|
|
64
64
|
--radius-sm: calc(var(--radius) - 4px);
|
|
@@ -83,7 +83,7 @@
|
|
|
83
83
|
--size-spacing: var(--spacing);
|
|
84
84
|
|
|
85
85
|
/* Shadow system integration */
|
|
86
|
-
--color-shadow: var(--shadow-color);
|
|
86
|
+
--color-shadow: hsl(var(--shadow-color));
|
|
87
87
|
--shadow-opacity: var(--shadow-opacity);
|
|
88
88
|
--shadow-blur: var(--shadow-blur);
|
|
89
89
|
--shadow-spread: var(--shadow-spread);
|
|
@@ -118,4 +118,4 @@
|
|
|
118
118
|
-webkit-font-smoothing: antialiased;
|
|
119
119
|
-moz-osx-font-smoothing: grayscale;
|
|
120
120
|
}
|
|
121
|
-
}
|
|
121
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fakhrirafiki/theme-engine",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.4",
|
|
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",
|