@charstudios/pallet 0.1.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/LICENSE +21 -0
- package/README.md +479 -0
- package/dist/chunk-4GSIZANE.js +231 -0
- package/dist/chunk-4GSIZANE.js.map +1 -0
- package/dist/index-DcC8QTrl.d.ts +172 -0
- package/dist/index.d.ts +400 -0
- package/dist/index.js +651 -0
- package/dist/index.js.map +1 -0
- package/dist/presets/index.d.ts +1 -0
- package/dist/presets/index.js +3 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/server.d.ts +85 -0
- package/dist/server.js +166 -0
- package/dist/server.js.map +1 -0
- package/dist/styles/base.css +39 -0
- package/dist/styles/index.css +15 -0
- package/dist/styles/variant-flat.css +32 -0
- package/dist/styles/variant-launch.css +75 -0
- package/package.json +78 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,651 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import * as React from 'react';
|
|
3
|
+
import { createContext, useContext, useMemo, useCallback } from 'react';
|
|
4
|
+
import { jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
// src/provider.tsx
|
|
7
|
+
|
|
8
|
+
// src/core/css-vars.ts
|
|
9
|
+
function applyCssVars(element, vars) {
|
|
10
|
+
if (!element) return;
|
|
11
|
+
for (const [name, value] of Object.entries(vars)) {
|
|
12
|
+
element.style.setProperty(name, value);
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
function clearCssVars(element, names) {
|
|
16
|
+
if (!element) return;
|
|
17
|
+
for (const name of names) {
|
|
18
|
+
element.style.removeProperty(name);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
function cssVarsToString(vars) {
|
|
22
|
+
return Object.entries(vars).map(([name, value]) => `${name}:${value};`).join("");
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// src/core/merge.ts
|
|
26
|
+
function isPlainObject(value) {
|
|
27
|
+
return typeof value === "object" && value !== null && !Array.isArray(value) && Object.getPrototypeOf(value) === Object.prototype;
|
|
28
|
+
}
|
|
29
|
+
function deepMerge(base, override) {
|
|
30
|
+
if (!override) return base;
|
|
31
|
+
const result = { ...base };
|
|
32
|
+
for (const key of Object.keys(override)) {
|
|
33
|
+
const overrideValue = override[key];
|
|
34
|
+
if (overrideValue === void 0) continue;
|
|
35
|
+
const baseValue = result[key];
|
|
36
|
+
if (isPlainObject(baseValue) && isPlainObject(overrideValue)) {
|
|
37
|
+
result[key] = deepMerge(baseValue, overrideValue);
|
|
38
|
+
} else {
|
|
39
|
+
result[key] = overrideValue;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return result;
|
|
43
|
+
}
|
|
44
|
+
function mergeAll(base, ...overrides) {
|
|
45
|
+
return overrides.reduce((acc, override) => deepMerge(acc, override), base);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
// src/core/resolve.ts
|
|
49
|
+
var DEFAULT_RADIUS_SCALE = {
|
|
50
|
+
sm: 0.6,
|
|
51
|
+
md: 0.8,
|
|
52
|
+
lg: 1,
|
|
53
|
+
xl: 1.4,
|
|
54
|
+
"2xl": 1.8,
|
|
55
|
+
"3xl": 2.2,
|
|
56
|
+
"4xl": 2.6
|
|
57
|
+
};
|
|
58
|
+
var COLOR_VAR = {
|
|
59
|
+
background: "--background",
|
|
60
|
+
foreground: "--foreground",
|
|
61
|
+
card: "--card",
|
|
62
|
+
cardForeground: "--card-foreground",
|
|
63
|
+
popover: "--popover",
|
|
64
|
+
popoverForeground: "--popover-foreground",
|
|
65
|
+
primary: "--primary",
|
|
66
|
+
primaryForeground: "--primary-foreground",
|
|
67
|
+
secondary: "--secondary",
|
|
68
|
+
secondaryForeground: "--secondary-foreground",
|
|
69
|
+
muted: "--muted",
|
|
70
|
+
mutedForeground: "--muted-foreground",
|
|
71
|
+
accent: "--accent",
|
|
72
|
+
accentForeground: "--accent-foreground",
|
|
73
|
+
destructive: "--destructive",
|
|
74
|
+
destructiveForeground: "--destructive-foreground",
|
|
75
|
+
border: "--border",
|
|
76
|
+
input: "--input",
|
|
77
|
+
ring: "--ring",
|
|
78
|
+
chart1: "--chart-1",
|
|
79
|
+
chart2: "--chart-2",
|
|
80
|
+
chart3: "--chart-3",
|
|
81
|
+
chart4: "--chart-4",
|
|
82
|
+
chart5: "--chart-5",
|
|
83
|
+
sidebar: "--sidebar",
|
|
84
|
+
sidebarForeground: "--sidebar-foreground",
|
|
85
|
+
sidebarPrimary: "--sidebar-primary",
|
|
86
|
+
sidebarPrimaryForeground: "--sidebar-primary-foreground",
|
|
87
|
+
sidebarAccent: "--sidebar-accent",
|
|
88
|
+
sidebarAccentForeground: "--sidebar-accent-foreground",
|
|
89
|
+
sidebarBorder: "--sidebar-border",
|
|
90
|
+
sidebarRing: "--sidebar-ring"
|
|
91
|
+
};
|
|
92
|
+
function colorTokensToVars(tokens) {
|
|
93
|
+
const vars = {};
|
|
94
|
+
for (const key of Object.keys(COLOR_VAR)) {
|
|
95
|
+
vars[COLOR_VAR[key]] = tokens[key];
|
|
96
|
+
}
|
|
97
|
+
return vars;
|
|
98
|
+
}
|
|
99
|
+
function structuralVars(theme) {
|
|
100
|
+
const vars = {};
|
|
101
|
+
vars["--radius"] = theme.radius.base;
|
|
102
|
+
const scale = { ...DEFAULT_RADIUS_SCALE, ...theme.radius.scale };
|
|
103
|
+
for (const key of Object.keys(scale)) {
|
|
104
|
+
vars[`--radius-${key}`] = `calc(var(--radius) * ${scale[key]})`;
|
|
105
|
+
}
|
|
106
|
+
vars["--font-sans"] = theme.typography.sans;
|
|
107
|
+
vars["--font-heading"] = theme.typography.heading;
|
|
108
|
+
vars["--font-mono"] = theme.typography.mono;
|
|
109
|
+
const { shadows } = theme.elevation;
|
|
110
|
+
vars["--shadow-xs"] = shadows.xs;
|
|
111
|
+
vars["--shadow-sm"] = shadows.sm;
|
|
112
|
+
vars["--shadow-md"] = shadows.md;
|
|
113
|
+
vars["--shadow-lg"] = shadows.lg;
|
|
114
|
+
vars["--shadow-xl"] = shadows.xl;
|
|
115
|
+
vars["--surface-border-strength"] = String(theme.elevation.borderStrength);
|
|
116
|
+
vars["--elevation"] = theme.elevation.level === "none" ? "none" : `var(--shadow-${theme.elevation.level})`;
|
|
117
|
+
vars["--spacing"] = theme.density.spacing;
|
|
118
|
+
vars["--density"] = String(theme.density.scale);
|
|
119
|
+
vars["--motion-duration"] = `${theme.motion.duration}ms`;
|
|
120
|
+
vars["--motion-ease"] = theme.motion.easing;
|
|
121
|
+
vars["--motion-intensity"] = String(theme.motion.intensity);
|
|
122
|
+
return vars;
|
|
123
|
+
}
|
|
124
|
+
function resolveTheme(theme, scheme) {
|
|
125
|
+
return {
|
|
126
|
+
...structuralVars(theme),
|
|
127
|
+
...colorTokensToVars(theme.colors[scheme])
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
function resolveColors(theme, scheme) {
|
|
131
|
+
return colorTokensToVars(theme.colors[scheme]);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// src/core/serialize.ts
|
|
135
|
+
function themeToCss(theme, options = {}) {
|
|
136
|
+
const selector = options.selector ?? ":root";
|
|
137
|
+
const darkSelector = options.darkSelector ?? ".dark";
|
|
138
|
+
const light3 = resolveTheme(theme, "light");
|
|
139
|
+
const darkColors = resolveColors(theme, "dark");
|
|
140
|
+
const variantComment = options.includeVariantComment ? `/* pallet variant: ${theme.variant} (set data-pallet-variant="${theme.variant}") */
|
|
141
|
+
` : "";
|
|
142
|
+
return variantComment + `${selector}{${cssVarsToString(light3)}}${darkSelector}{${cssVarsToString(darkColors)}}`;
|
|
143
|
+
}
|
|
144
|
+
function serializeTheme(theme) {
|
|
145
|
+
return JSON.stringify(theme);
|
|
146
|
+
}
|
|
147
|
+
function deserializeTheme(json) {
|
|
148
|
+
try {
|
|
149
|
+
return JSON.parse(json);
|
|
150
|
+
} catch {
|
|
151
|
+
return null;
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
function themeToInlineStyle(theme, scheme) {
|
|
155
|
+
return resolveTheme(theme, scheme);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// src/fonts/google-fonts.ts
|
|
159
|
+
var LINK_ID = "pallet-google-fonts";
|
|
160
|
+
var loaded = /* @__PURE__ */ new Set();
|
|
161
|
+
function buildGoogleFontsUrl(families, options = {}) {
|
|
162
|
+
const weights = options.weights ?? [400, 500, 600, 700];
|
|
163
|
+
const display = options.display ?? "swap";
|
|
164
|
+
const params = families.filter(Boolean).map((family) => {
|
|
165
|
+
const name = family.trim().replace(/\s+/g, "+");
|
|
166
|
+
return `family=${name}:wght@${weights.join(";")}`;
|
|
167
|
+
}).join("&");
|
|
168
|
+
return `https://fonts.googleapis.com/css2?${params}&display=${display}`;
|
|
169
|
+
}
|
|
170
|
+
function loadGoogleFonts(families, options = {}) {
|
|
171
|
+
if (typeof document === "undefined") return null;
|
|
172
|
+
const unique = Array.from(new Set(families.filter(Boolean)));
|
|
173
|
+
if (unique.length === 0) return null;
|
|
174
|
+
const key = unique.sort().join("|") + JSON.stringify(options);
|
|
175
|
+
if (loaded.has(key)) {
|
|
176
|
+
return document.getElementById(LINK_ID);
|
|
177
|
+
}
|
|
178
|
+
ensurePreconnect();
|
|
179
|
+
let link = document.getElementById(LINK_ID);
|
|
180
|
+
if (!link) {
|
|
181
|
+
link = document.createElement("link");
|
|
182
|
+
link.id = LINK_ID;
|
|
183
|
+
link.rel = "stylesheet";
|
|
184
|
+
document.head.appendChild(link);
|
|
185
|
+
}
|
|
186
|
+
link.href = buildGoogleFontsUrl(unique, options);
|
|
187
|
+
loaded.add(key);
|
|
188
|
+
return link;
|
|
189
|
+
}
|
|
190
|
+
function ensurePreconnect() {
|
|
191
|
+
if (document.getElementById("pallet-gf-preconnect")) return;
|
|
192
|
+
const a = document.createElement("link");
|
|
193
|
+
a.id = "pallet-gf-preconnect";
|
|
194
|
+
a.rel = "preconnect";
|
|
195
|
+
a.href = "https://fonts.googleapis.com";
|
|
196
|
+
document.head.appendChild(a);
|
|
197
|
+
const b = document.createElement("link");
|
|
198
|
+
b.rel = "preconnect";
|
|
199
|
+
b.href = "https://fonts.gstatic.com";
|
|
200
|
+
b.crossOrigin = "anonymous";
|
|
201
|
+
document.head.appendChild(b);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
// src/presets/flat.ts
|
|
205
|
+
var light = {
|
|
206
|
+
background: "oklch(1 0 0)",
|
|
207
|
+
foreground: "oklch(0.148 0.004 228.8)",
|
|
208
|
+
card: "oklch(1 0 0)",
|
|
209
|
+
cardForeground: "oklch(0.148 0.004 228.8)",
|
|
210
|
+
popover: "oklch(1 0 0)",
|
|
211
|
+
popoverForeground: "oklch(0.148 0.004 228.8)",
|
|
212
|
+
primary: "oklch(0.514 0.222 16.935)",
|
|
213
|
+
primaryForeground: "oklch(0.969 0.015 12.422)",
|
|
214
|
+
secondary: "oklch(0.967 0.001 286.375)",
|
|
215
|
+
secondaryForeground: "oklch(0.21 0.006 285.885)",
|
|
216
|
+
muted: "oklch(0.963 0.002 197.1)",
|
|
217
|
+
mutedForeground: "oklch(0.56 0.021 213.5)",
|
|
218
|
+
accent: "oklch(0.963 0.002 197.1)",
|
|
219
|
+
accentForeground: "oklch(0.218 0.008 223.9)",
|
|
220
|
+
destructive: "oklch(0.577 0.245 27.325)",
|
|
221
|
+
destructiveForeground: "oklch(0.985 0 0)",
|
|
222
|
+
border: "oklch(0.925 0.005 214.3)",
|
|
223
|
+
input: "oklch(0.925 0.005 214.3)",
|
|
224
|
+
ring: "oklch(0.723 0.014 214.4)",
|
|
225
|
+
chart1: "oklch(0.81 0.117 11.638)",
|
|
226
|
+
chart2: "oklch(0.645 0.246 16.439)",
|
|
227
|
+
chart3: "oklch(0.586 0.253 17.585)",
|
|
228
|
+
chart4: "oklch(0.514 0.222 16.935)",
|
|
229
|
+
chart5: "oklch(0.455 0.188 13.697)",
|
|
230
|
+
sidebar: "oklch(0.987 0.002 197.1)",
|
|
231
|
+
sidebarForeground: "oklch(0.148 0.004 228.8)",
|
|
232
|
+
sidebarPrimary: "oklch(0.586 0.253 17.585)",
|
|
233
|
+
sidebarPrimaryForeground: "oklch(0.969 0.015 12.422)",
|
|
234
|
+
sidebarAccent: "oklch(0.963 0.002 197.1)",
|
|
235
|
+
sidebarAccentForeground: "oklch(0.218 0.008 223.9)",
|
|
236
|
+
sidebarBorder: "oklch(0.925 0.005 214.3)",
|
|
237
|
+
sidebarRing: "oklch(0.723 0.014 214.4)"
|
|
238
|
+
};
|
|
239
|
+
var dark = {
|
|
240
|
+
background: "oklch(0.148 0.004 228.8)",
|
|
241
|
+
foreground: "oklch(0.987 0.002 197.1)",
|
|
242
|
+
card: "oklch(0.218 0.008 223.9)",
|
|
243
|
+
cardForeground: "oklch(0.987 0.002 197.1)",
|
|
244
|
+
popover: "oklch(0.218 0.008 223.9)",
|
|
245
|
+
popoverForeground: "oklch(0.987 0.002 197.1)",
|
|
246
|
+
primary: "oklch(0.455 0.188 13.697)",
|
|
247
|
+
primaryForeground: "oklch(0.969 0.015 12.422)",
|
|
248
|
+
secondary: "oklch(0.274 0.006 286.033)",
|
|
249
|
+
secondaryForeground: "oklch(0.985 0 0)",
|
|
250
|
+
muted: "oklch(0.275 0.011 216.9)",
|
|
251
|
+
mutedForeground: "oklch(0.723 0.014 214.4)",
|
|
252
|
+
accent: "oklch(0.275 0.011 216.9)",
|
|
253
|
+
accentForeground: "oklch(0.987 0.002 197.1)",
|
|
254
|
+
destructive: "oklch(0.704 0.191 22.216)",
|
|
255
|
+
destructiveForeground: "oklch(0.985 0 0)",
|
|
256
|
+
border: "oklch(1 0 0 / 10%)",
|
|
257
|
+
input: "oklch(1 0 0 / 15%)",
|
|
258
|
+
ring: "oklch(0.56 0.021 213.5)",
|
|
259
|
+
chart1: "oklch(0.81 0.117 11.638)",
|
|
260
|
+
chart2: "oklch(0.645 0.246 16.439)",
|
|
261
|
+
chart3: "oklch(0.586 0.253 17.585)",
|
|
262
|
+
chart4: "oklch(0.514 0.222 16.935)",
|
|
263
|
+
chart5: "oklch(0.455 0.188 13.697)",
|
|
264
|
+
sidebar: "oklch(0.17 0.006 228.8)",
|
|
265
|
+
sidebarForeground: "oklch(0.987 0.002 197.1)",
|
|
266
|
+
sidebarPrimary: "oklch(0.514 0.222 16.935)",
|
|
267
|
+
sidebarPrimaryForeground: "oklch(0.969 0.015 12.422)",
|
|
268
|
+
sidebarAccent: "oklch(0.24 0.008 228.8)",
|
|
269
|
+
sidebarAccentForeground: "oklch(0.987 0.002 197.1)",
|
|
270
|
+
sidebarBorder: "oklch(1 0 0 / 10%)",
|
|
271
|
+
sidebarRing: "oklch(0.56 0.021 213.5)"
|
|
272
|
+
};
|
|
273
|
+
var flat = {
|
|
274
|
+
name: "flat",
|
|
275
|
+
variant: "flat",
|
|
276
|
+
colors: { light, dark },
|
|
277
|
+
typography: {
|
|
278
|
+
sans: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
|
|
279
|
+
heading: 'ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif',
|
|
280
|
+
mono: 'ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace',
|
|
281
|
+
googleFonts: []
|
|
282
|
+
},
|
|
283
|
+
radius: {
|
|
284
|
+
base: "0.45rem"
|
|
285
|
+
},
|
|
286
|
+
elevation: {
|
|
287
|
+
shadows: {
|
|
288
|
+
xs: "0 1px 2px 0 oklch(0 0 0 / 0.04)",
|
|
289
|
+
sm: "0 1px 3px 0 oklch(0 0 0 / 0.06), 0 1px 2px -1px oklch(0 0 0 / 0.06)",
|
|
290
|
+
md: "0 2px 6px -1px oklch(0 0 0 / 0.07), 0 1px 4px -2px oklch(0 0 0 / 0.06)",
|
|
291
|
+
lg: "0 8px 16px -4px oklch(0 0 0 / 0.08), 0 2px 6px -2px oklch(0 0 0 / 0.06)",
|
|
292
|
+
xl: "0 16px 32px -8px oklch(0 0 0 / 0.10), 0 4px 10px -4px oklch(0 0 0 / 0.06)"
|
|
293
|
+
},
|
|
294
|
+
borderStrength: 0.1,
|
|
295
|
+
level: "none"
|
|
296
|
+
},
|
|
297
|
+
density: {
|
|
298
|
+
spacing: "0.25rem",
|
|
299
|
+
scale: 1
|
|
300
|
+
},
|
|
301
|
+
motion: {
|
|
302
|
+
duration: 200,
|
|
303
|
+
easing: "cubic-bezier(0.22, 1, 0.36, 1)",
|
|
304
|
+
intensity: 1
|
|
305
|
+
}
|
|
306
|
+
};
|
|
307
|
+
|
|
308
|
+
// src/presets/launch.ts
|
|
309
|
+
var light2 = {
|
|
310
|
+
background: "oklch(0.98 0.003 264)",
|
|
311
|
+
foreground: "oklch(0.21 0.03 264)",
|
|
312
|
+
card: "oklch(1 0 0)",
|
|
313
|
+
cardForeground: "oklch(0.21 0.03 264)",
|
|
314
|
+
popover: "oklch(1 0 0)",
|
|
315
|
+
popoverForeground: "oklch(0.21 0.03 264)",
|
|
316
|
+
primary: "oklch(0.7 0.11 264)",
|
|
317
|
+
primaryForeground: "oklch(0.99 0.002 264)",
|
|
318
|
+
secondary: "oklch(0.965 0.006 264)",
|
|
319
|
+
secondaryForeground: "oklch(0.3 0.03 264)",
|
|
320
|
+
muted: "oklch(0.965 0.006 264)",
|
|
321
|
+
mutedForeground: "oklch(0.55 0.03 264)",
|
|
322
|
+
accent: "oklch(0.95 0.03 264)",
|
|
323
|
+
accentForeground: "oklch(0.42 0.11 264)",
|
|
324
|
+
destructive: "oklch(0.62 0.22 25)",
|
|
325
|
+
destructiveForeground: "oklch(0.99 0 0)",
|
|
326
|
+
border: "oklch(0.92 0.008 264)",
|
|
327
|
+
input: "oklch(0.965 0.006 264)",
|
|
328
|
+
ring: "oklch(0.6 0.19 264)",
|
|
329
|
+
chart1: "oklch(0.7 0.11 264)",
|
|
330
|
+
chart2: "oklch(0.62 0.15 264)",
|
|
331
|
+
chart3: "oklch(0.55 0.19 264)",
|
|
332
|
+
chart4: "oklch(0.72 0.1 210)",
|
|
333
|
+
chart5: "oklch(0.68 0.13 300)",
|
|
334
|
+
sidebar: "oklch(0.985 0.003 264)",
|
|
335
|
+
sidebarForeground: "oklch(0.21 0.03 264)",
|
|
336
|
+
sidebarPrimary: "oklch(0.7 0.11 264)",
|
|
337
|
+
sidebarPrimaryForeground: "oklch(0.99 0.002 264)",
|
|
338
|
+
sidebarAccent: "oklch(0.95 0.03 264)",
|
|
339
|
+
sidebarAccentForeground: "oklch(0.42 0.11 264)",
|
|
340
|
+
sidebarBorder: "oklch(0.92 0.008 264)",
|
|
341
|
+
sidebarRing: "oklch(0.6 0.19 264)"
|
|
342
|
+
};
|
|
343
|
+
var dark2 = {
|
|
344
|
+
background: "oklch(0.19 0.02 264)",
|
|
345
|
+
foreground: "oklch(0.97 0.005 264)",
|
|
346
|
+
card: "oklch(0.23 0.024 264)",
|
|
347
|
+
cardForeground: "oklch(0.97 0.005 264)",
|
|
348
|
+
popover: "oklch(0.23 0.024 264)",
|
|
349
|
+
popoverForeground: "oklch(0.97 0.005 264)",
|
|
350
|
+
primary: "oklch(0.72 0.12 264)",
|
|
351
|
+
primaryForeground: "oklch(0.16 0.03 264)",
|
|
352
|
+
secondary: "oklch(0.28 0.02 264)",
|
|
353
|
+
secondaryForeground: "oklch(0.97 0.005 264)",
|
|
354
|
+
muted: "oklch(0.28 0.02 264)",
|
|
355
|
+
mutedForeground: "oklch(0.72 0.02 264)",
|
|
356
|
+
accent: "oklch(0.32 0.05 264)",
|
|
357
|
+
accentForeground: "oklch(0.9 0.05 264)",
|
|
358
|
+
destructive: "oklch(0.7 0.19 22)",
|
|
359
|
+
destructiveForeground: "oklch(0.99 0 0)",
|
|
360
|
+
border: "oklch(1 0 0 / 10%)",
|
|
361
|
+
input: "oklch(1 0 0 / 12%)",
|
|
362
|
+
ring: "oklch(0.65 0.17 264)",
|
|
363
|
+
chart1: "oklch(0.72 0.12 264)",
|
|
364
|
+
chart2: "oklch(0.64 0.15 264)",
|
|
365
|
+
chart3: "oklch(0.58 0.18 264)",
|
|
366
|
+
chart4: "oklch(0.74 0.1 210)",
|
|
367
|
+
chart5: "oklch(0.7 0.13 300)",
|
|
368
|
+
sidebar: "oklch(0.21 0.022 264)",
|
|
369
|
+
sidebarForeground: "oklch(0.97 0.005 264)",
|
|
370
|
+
sidebarPrimary: "oklch(0.72 0.12 264)",
|
|
371
|
+
sidebarPrimaryForeground: "oklch(0.16 0.03 264)",
|
|
372
|
+
sidebarAccent: "oklch(0.32 0.05 264)",
|
|
373
|
+
sidebarAccentForeground: "oklch(0.9 0.05 264)",
|
|
374
|
+
sidebarBorder: "oklch(1 0 0 / 10%)",
|
|
375
|
+
sidebarRing: "oklch(0.65 0.17 264)"
|
|
376
|
+
};
|
|
377
|
+
var launch = {
|
|
378
|
+
name: "launch",
|
|
379
|
+
variant: "launch",
|
|
380
|
+
colors: { light: light2, dark: dark2 },
|
|
381
|
+
typography: {
|
|
382
|
+
sans: '"Inter", ui-sans-serif, system-ui, -apple-system, "Segoe UI", Roboto, sans-serif',
|
|
383
|
+
heading: '"Plus Jakarta Sans", "Inter", ui-sans-serif, system-ui, -apple-system, sans-serif',
|
|
384
|
+
mono: 'ui-monospace, SFMono-Regular, Menlo, Consolas, "Liberation Mono", monospace',
|
|
385
|
+
googleFonts: ["Inter", "Plus Jakarta Sans"]
|
|
386
|
+
},
|
|
387
|
+
radius: {
|
|
388
|
+
base: "1.25rem",
|
|
389
|
+
// A slightly gentler ramp so large elements do not over-round.
|
|
390
|
+
scale: {
|
|
391
|
+
sm: 0.4,
|
|
392
|
+
md: 0.6,
|
|
393
|
+
lg: 1,
|
|
394
|
+
xl: 1.2,
|
|
395
|
+
"2xl": 1.5,
|
|
396
|
+
"3xl": 1.8,
|
|
397
|
+
"4xl": 2.2
|
|
398
|
+
}
|
|
399
|
+
},
|
|
400
|
+
elevation: {
|
|
401
|
+
shadows: {
|
|
402
|
+
xs: "0 1px 2px 0 oklch(0.55 0.19 264 / 0.06)",
|
|
403
|
+
sm: "0 2px 8px -2px oklch(0.55 0.19 264 / 0.10), 0 1px 3px -1px oklch(0 0 0 / 0.05)",
|
|
404
|
+
md: "0 6px 20px -6px oklch(0.55 0.19 264 / 0.16), 0 2px 6px -2px oklch(0 0 0 / 0.06)",
|
|
405
|
+
lg: "0 14px 34px -10px oklch(0.55 0.19 264 / 0.20), 0 4px 10px -4px oklch(0 0 0 / 0.07)",
|
|
406
|
+
xl: "0 24px 56px -16px oklch(0.55 0.19 264 / 0.26), 0 8px 18px -8px oklch(0 0 0 / 0.08)"
|
|
407
|
+
},
|
|
408
|
+
borderStrength: 0.5,
|
|
409
|
+
level: "md"
|
|
410
|
+
},
|
|
411
|
+
density: {
|
|
412
|
+
spacing: "0.26rem",
|
|
413
|
+
scale: 1.1
|
|
414
|
+
},
|
|
415
|
+
motion: {
|
|
416
|
+
duration: 240,
|
|
417
|
+
easing: "cubic-bezier(0.22, 1, 0.36, 1)",
|
|
418
|
+
intensity: 1
|
|
419
|
+
}
|
|
420
|
+
};
|
|
421
|
+
|
|
422
|
+
// src/presets/index.ts
|
|
423
|
+
var presets = {
|
|
424
|
+
flat,
|
|
425
|
+
launch
|
|
426
|
+
};
|
|
427
|
+
function getPreset(name) {
|
|
428
|
+
return presets[name];
|
|
429
|
+
}
|
|
430
|
+
var defaultPreset = flat;
|
|
431
|
+
var PalletContext = createContext(null);
|
|
432
|
+
function usePalletContext() {
|
|
433
|
+
const ctx = useContext(PalletContext);
|
|
434
|
+
if (!ctx) {
|
|
435
|
+
throw new Error("Pallet hooks must be used within a <ThemeProvider>.");
|
|
436
|
+
}
|
|
437
|
+
return ctx;
|
|
438
|
+
}
|
|
439
|
+
function resolvePreset(preset, registry) {
|
|
440
|
+
if (typeof preset === "string") {
|
|
441
|
+
const found = registry[preset];
|
|
442
|
+
if (!found) {
|
|
443
|
+
throw new Error(`Pallet: unknown preset "${preset}".`);
|
|
444
|
+
}
|
|
445
|
+
return found;
|
|
446
|
+
}
|
|
447
|
+
return preset;
|
|
448
|
+
}
|
|
449
|
+
function getSystemScheme() {
|
|
450
|
+
if (typeof window === "undefined" || !window.matchMedia) return "light";
|
|
451
|
+
return window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light";
|
|
452
|
+
}
|
|
453
|
+
function ThemeProvider({
|
|
454
|
+
children,
|
|
455
|
+
defaultPreset: defaultPreset2 = "flat",
|
|
456
|
+
defaultOverride,
|
|
457
|
+
defaultScheme = "system",
|
|
458
|
+
presets: extraPresets,
|
|
459
|
+
scope = "root",
|
|
460
|
+
storageKey,
|
|
461
|
+
className
|
|
462
|
+
}) {
|
|
463
|
+
const registry = React.useMemo(
|
|
464
|
+
() => ({ ...presets, ...extraPresets }),
|
|
465
|
+
[extraPresets]
|
|
466
|
+
);
|
|
467
|
+
const initialPreset = React.useMemo(
|
|
468
|
+
() => resolvePreset(defaultPreset2, registry),
|
|
469
|
+
// Only resolve the initial preset once from props.
|
|
470
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
471
|
+
[]
|
|
472
|
+
);
|
|
473
|
+
const [basePreset, setBasePreset] = React.useState(initialPreset);
|
|
474
|
+
const [overrides, setOverrides] = React.useState(defaultOverride ?? {});
|
|
475
|
+
const [schemePreference, setSchemePreference] = React.useState(defaultScheme);
|
|
476
|
+
const [systemScheme, setSystemScheme] = React.useState("light");
|
|
477
|
+
const [hydrated, setHydrated] = React.useState(false);
|
|
478
|
+
const selfRef = React.useRef(null);
|
|
479
|
+
React.useEffect(() => {
|
|
480
|
+
setSystemScheme(getSystemScheme());
|
|
481
|
+
if (storageKey) {
|
|
482
|
+
try {
|
|
483
|
+
const raw = window.localStorage.getItem(storageKey);
|
|
484
|
+
if (raw) {
|
|
485
|
+
const parsed = JSON.parse(raw);
|
|
486
|
+
if (parsed.presetName && registry[parsed.presetName]) {
|
|
487
|
+
setBasePreset(registry[parsed.presetName]);
|
|
488
|
+
}
|
|
489
|
+
if (parsed.override) setOverrides(parsed.override);
|
|
490
|
+
if (parsed.scheme) setSchemePreference(parsed.scheme);
|
|
491
|
+
}
|
|
492
|
+
} catch {
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
setHydrated(true);
|
|
496
|
+
}, []);
|
|
497
|
+
React.useEffect(() => {
|
|
498
|
+
if (typeof window === "undefined" || !window.matchMedia) return;
|
|
499
|
+
const mql = window.matchMedia("(prefers-color-scheme: dark)");
|
|
500
|
+
const onChange = () => setSystemScheme(mql.matches ? "dark" : "light");
|
|
501
|
+
onChange();
|
|
502
|
+
mql.addEventListener("change", onChange);
|
|
503
|
+
return () => mql.removeEventListener("change", onChange);
|
|
504
|
+
}, []);
|
|
505
|
+
const theme = React.useMemo(
|
|
506
|
+
() => deepMerge(basePreset, overrides),
|
|
507
|
+
[basePreset, overrides]
|
|
508
|
+
);
|
|
509
|
+
const scheme = schemePreference === "system" ? systemScheme : schemePreference;
|
|
510
|
+
const vars = React.useMemo(() => resolveTheme(theme, scheme), [theme, scheme]);
|
|
511
|
+
React.useEffect(() => {
|
|
512
|
+
if (!storageKey || !hydrated) return;
|
|
513
|
+
const state = {
|
|
514
|
+
presetName: basePreset.name,
|
|
515
|
+
override: overrides,
|
|
516
|
+
scheme: schemePreference
|
|
517
|
+
};
|
|
518
|
+
try {
|
|
519
|
+
window.localStorage.setItem(storageKey, JSON.stringify(state));
|
|
520
|
+
} catch {
|
|
521
|
+
}
|
|
522
|
+
}, [storageKey, hydrated, basePreset, overrides, schemePreference]);
|
|
523
|
+
React.useEffect(() => {
|
|
524
|
+
const target = scope === "self" ? selfRef.current : document.documentElement;
|
|
525
|
+
if (!target) return;
|
|
526
|
+
applyCssVars(target, vars);
|
|
527
|
+
target.setAttribute("data-pallet-variant", theme.variant);
|
|
528
|
+
target.classList.toggle("dark", scheme === "dark");
|
|
529
|
+
}, [scope, vars, theme.variant, scheme]);
|
|
530
|
+
React.useEffect(() => {
|
|
531
|
+
const families = theme.typography.googleFonts ?? [];
|
|
532
|
+
if (families.length > 0) loadGoogleFonts(families);
|
|
533
|
+
}, [theme.typography.googleFonts]);
|
|
534
|
+
const applyPreset = React.useCallback(
|
|
535
|
+
(preset) => {
|
|
536
|
+
setBasePreset(resolvePreset(preset, registry));
|
|
537
|
+
setOverrides({});
|
|
538
|
+
},
|
|
539
|
+
[registry]
|
|
540
|
+
);
|
|
541
|
+
const setTheme = React.useCallback((next) => {
|
|
542
|
+
setBasePreset(next);
|
|
543
|
+
setOverrides({});
|
|
544
|
+
}, []);
|
|
545
|
+
const updateTheme = React.useCallback((override) => {
|
|
546
|
+
setOverrides((prev) => deepMerge(prev, override));
|
|
547
|
+
}, []);
|
|
548
|
+
const resetOverrides = React.useCallback(() => setOverrides({}), []);
|
|
549
|
+
const value = React.useMemo(
|
|
550
|
+
() => ({
|
|
551
|
+
theme,
|
|
552
|
+
basePreset,
|
|
553
|
+
overrides,
|
|
554
|
+
scheme,
|
|
555
|
+
schemePreference,
|
|
556
|
+
vars,
|
|
557
|
+
setTheme,
|
|
558
|
+
applyPreset,
|
|
559
|
+
updateTheme,
|
|
560
|
+
resetOverrides,
|
|
561
|
+
setSchemePreference
|
|
562
|
+
}),
|
|
563
|
+
[
|
|
564
|
+
theme,
|
|
565
|
+
basePreset,
|
|
566
|
+
overrides,
|
|
567
|
+
scheme,
|
|
568
|
+
schemePreference,
|
|
569
|
+
vars,
|
|
570
|
+
setTheme,
|
|
571
|
+
applyPreset,
|
|
572
|
+
updateTheme,
|
|
573
|
+
resetOverrides
|
|
574
|
+
]
|
|
575
|
+
);
|
|
576
|
+
if (scope === "self") {
|
|
577
|
+
const inlineStyle = themeToInlineStyle(theme, scheme);
|
|
578
|
+
return /* @__PURE__ */ jsx(PalletContext.Provider, { value, children: /* @__PURE__ */ jsx(
|
|
579
|
+
"div",
|
|
580
|
+
{
|
|
581
|
+
ref: selfRef,
|
|
582
|
+
"data-pallet-variant": theme.variant,
|
|
583
|
+
className: [className, scheme === "dark" ? "dark" : void 0].filter(Boolean).join(" "),
|
|
584
|
+
style: inlineStyle,
|
|
585
|
+
children
|
|
586
|
+
}
|
|
587
|
+
) });
|
|
588
|
+
}
|
|
589
|
+
return /* @__PURE__ */ jsx(PalletContext.Provider, { value, children });
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
// src/hooks/use-theme.ts
|
|
593
|
+
function useTheme() {
|
|
594
|
+
return usePalletContext();
|
|
595
|
+
}
|
|
596
|
+
function useThemeControls() {
|
|
597
|
+
const { updateTheme, resetOverrides } = usePalletContext();
|
|
598
|
+
return useMemo(() => {
|
|
599
|
+
const colorOverride = (colors, target) => {
|
|
600
|
+
if (target === "both") {
|
|
601
|
+
return { colors: { light: colors, dark: colors } };
|
|
602
|
+
}
|
|
603
|
+
return { colors: { [target]: colors } };
|
|
604
|
+
};
|
|
605
|
+
const setColors = (colors, target = "both") => updateTheme(colorOverride(colors, target));
|
|
606
|
+
return {
|
|
607
|
+
setColors,
|
|
608
|
+
setColor: (role, value, target = "both") => setColors({ [role]: value }, target),
|
|
609
|
+
setPrimary: (value, target = "both") => setColors({ primary: value }, target),
|
|
610
|
+
setAccent: (value, target = "both") => setColors({ accent: value }, target),
|
|
611
|
+
setRadius: (base) => updateTheme({ radius: { base } }),
|
|
612
|
+
setRadiusScale: (scale) => updateTheme({ radius: { scale } }),
|
|
613
|
+
setFont: (kind, family) => updateTheme({ typography: { [kind]: family } }),
|
|
614
|
+
setGoogleFonts: (families) => updateTheme({ typography: { googleFonts: families } }),
|
|
615
|
+
setVariant: (variant) => updateTheme({ variant }),
|
|
616
|
+
setElevationLevel: (level) => updateTheme({ elevation: { level } }),
|
|
617
|
+
setShadow: (key, value) => updateTheme({ elevation: { shadows: { [key]: value } } }),
|
|
618
|
+
setBorderStrength: (value) => updateTheme({ elevation: { borderStrength: value } }),
|
|
619
|
+
setDensity: (density) => updateTheme({ density }),
|
|
620
|
+
setMotion: (motion) => updateTheme({ motion }),
|
|
621
|
+
update: updateTheme,
|
|
622
|
+
reset: resetOverrides
|
|
623
|
+
};
|
|
624
|
+
}, [updateTheme, resetOverrides]);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
// src/hooks/use-preset.ts
|
|
628
|
+
function usePreset() {
|
|
629
|
+
const { basePreset, applyPreset } = usePalletContext();
|
|
630
|
+
return {
|
|
631
|
+
preset: basePreset,
|
|
632
|
+
builtinNames: Object.keys(presets),
|
|
633
|
+
applyPreset
|
|
634
|
+
};
|
|
635
|
+
}
|
|
636
|
+
function useColorScheme() {
|
|
637
|
+
const { scheme, schemePreference, setSchemePreference } = usePalletContext();
|
|
638
|
+
const toggle = useCallback(() => {
|
|
639
|
+
setSchemePreference(scheme === "dark" ? "light" : "dark");
|
|
640
|
+
}, [scheme, setSchemePreference]);
|
|
641
|
+
return {
|
|
642
|
+
scheme,
|
|
643
|
+
preference: schemePreference,
|
|
644
|
+
setPreference: setSchemePreference,
|
|
645
|
+
toggle
|
|
646
|
+
};
|
|
647
|
+
}
|
|
648
|
+
|
|
649
|
+
export { DEFAULT_RADIUS_SCALE, PalletContext, ThemeProvider, applyCssVars, buildGoogleFontsUrl, clearCssVars, colorTokensToVars, cssVarsToString, deepMerge, defaultPreset, deserializeTheme, flat, getPreset, launch, loadGoogleFonts, mergeAll, presets, resolveColors, resolveTheme, serializeTheme, structuralVars, themeToCss, themeToInlineStyle, useColorScheme, usePalletContext, usePreset, useTheme, useThemeControls };
|
|
650
|
+
//# sourceMappingURL=index.js.map
|
|
651
|
+
//# sourceMappingURL=index.js.map
|