@styleframe/theme 1.0.1 → 1.0.3
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/CHANGELOG.md +12 -0
- package/LICENSE +21 -0
- package/dist/theme.d.ts +772 -0
- package/dist/theme.js +2507 -0
- package/dist/theme.umd.cjs +4 -0
- package/package.json +14 -4
- package/.tsbuildinfo +0 -1
- package/src/constants/border.ts +0 -0
- package/src/constants/breakpoint.ts +0 -0
- package/src/constants/color.ts +0 -0
- package/src/constants/index.ts +0 -4
- package/src/constants/scale.ts +0 -3
- package/src/constants/typography.ts +0 -0
- package/src/index.ts +0 -4
- package/src/shims.d.ts +0 -8
- package/src/types.ts +0 -32
- package/src/utils/createUseVariable.test.ts +0 -928
- package/src/utils/createUseVariable.ts +0 -107
- package/src/utils/index.ts +0 -1
- package/src/variables/index.ts +0 -20
- package/src/variables/useBorderColor.ts +0 -27
- package/src/variables/useBorderRadius.test.ts +0 -335
- package/src/variables/useBorderRadius.ts +0 -26
- package/src/variables/useBorderStyle.test.ts +0 -569
- package/src/variables/useBorderStyle.ts +0 -49
- package/src/variables/useBorderWidth.test.ts +0 -535
- package/src/variables/useBorderWidth.ts +0 -38
- package/src/variables/useBoxShadow.test.ts +0 -336
- package/src/variables/useBoxShadow.ts +0 -54
- package/src/variables/useBreakpoint.test.ts +0 -447
- package/src/variables/useBreakpoint.ts +0 -38
- package/src/variables/useColor.test.ts +0 -360
- package/src/variables/useColor.ts +0 -35
- package/src/variables/useColorLightness.test.ts +0 -168
- package/src/variables/useColorLightness.ts +0 -59
- package/src/variables/useColorShade.test.ts +0 -166
- package/src/variables/useColorShade.ts +0 -52
- package/src/variables/useColorTint.test.ts +0 -164
- package/src/variables/useColorTint.ts +0 -52
- package/src/variables/useEasing.ts +0 -0
- package/src/variables/useFontFamily.test.ts +0 -228
- package/src/variables/useFontFamily.ts +0 -33
- package/src/variables/useFontSize.test.ts +0 -299
- package/src/variables/useFontSize.ts +0 -32
- package/src/variables/useFontStyle.test.ts +0 -555
- package/src/variables/useFontStyle.ts +0 -37
- package/src/variables/useFontWeight.test.ts +0 -650
- package/src/variables/useFontWeight.ts +0 -55
- package/src/variables/useLetterSpacing.test.ts +0 -455
- package/src/variables/useLetterSpacing.ts +0 -41
- package/src/variables/useLineHeight.test.ts +0 -410
- package/src/variables/useLineHeight.ts +0 -41
- package/src/variables/useMultiplier.test.ts +0 -722
- package/src/variables/useMultiplier.ts +0 -44
- package/src/variables/useScale.test.ts +0 -393
- package/src/variables/useScale.ts +0 -52
- package/src/variables/useScalePowers.test.ts +0 -412
- package/src/variables/useScalePowers.ts +0 -35
- package/src/variables/useSpacing.test.ts +0 -309
- package/src/variables/useSpacing.ts +0 -26
- package/src/vite-env.d.ts +0 -1
- package/test-scale.js +0 -22
- package/tsconfig.json +0 -7
- package/vite.config.ts +0 -5
|
@@ -1,360 +0,0 @@
|
|
|
1
|
-
import type { Variable } from "@styleframe/core";
|
|
2
|
-
import { styleframe } from "@styleframe/core";
|
|
3
|
-
import { consume } from "@styleframe/transpiler";
|
|
4
|
-
import { oklch } from "culori";
|
|
5
|
-
import { useColor } from "./useColor";
|
|
6
|
-
import { useColorLightness } from "./useColorLightness";
|
|
7
|
-
import { useColorShade } from "./useColorShade";
|
|
8
|
-
import { useColorTint } from "./useColorTint";
|
|
9
|
-
|
|
10
|
-
// Helper function to convert color to expected OKLCH format
|
|
11
|
-
function toOklch(color: string): string {
|
|
12
|
-
const result = oklch(color);
|
|
13
|
-
if (!result) return color;
|
|
14
|
-
const { l, c, h, alpha = 1 } = result;
|
|
15
|
-
return `oklch(${l} ${c} ${h} / ${alpha})`;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
describe("useColor", () => {
|
|
19
|
-
it("should create a single color variable with correct naming", () => {
|
|
20
|
-
const s = styleframe();
|
|
21
|
-
const { colorPrimary } = useColor(s, {
|
|
22
|
-
primary: "#007bff",
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
expect(colorPrimary).toEqual({
|
|
26
|
-
type: "variable",
|
|
27
|
-
name: "color--primary",
|
|
28
|
-
value: toOklch("#007bff"),
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
const css = consume(colorPrimary, s.options);
|
|
32
|
-
expect(css).toBe(`--color--primary: ${toOklch("#007bff")};`);
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
it("should create multiple color variables", () => {
|
|
36
|
-
const s = styleframe();
|
|
37
|
-
const { colorPrimary, colorSecondary, colorTertiary } = useColor(s, {
|
|
38
|
-
primary: "#007bff",
|
|
39
|
-
secondary: "#6c757d",
|
|
40
|
-
tertiary: "#28a745",
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
expect(colorPrimary).toEqual({
|
|
44
|
-
type: "variable",
|
|
45
|
-
name: "color--primary",
|
|
46
|
-
value: toOklch("#007bff"),
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
expect(colorSecondary).toEqual({
|
|
50
|
-
type: "variable",
|
|
51
|
-
name: "color--secondary",
|
|
52
|
-
value: toOklch("#6c757d"),
|
|
53
|
-
});
|
|
54
|
-
|
|
55
|
-
expect(colorTertiary).toEqual({
|
|
56
|
-
type: "variable",
|
|
57
|
-
name: "color--tertiary",
|
|
58
|
-
value: toOklch("#28a745"),
|
|
59
|
-
});
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
it("should add variables to root", () => {
|
|
63
|
-
const s = styleframe();
|
|
64
|
-
useColor(s, {
|
|
65
|
-
primary: "#007bff",
|
|
66
|
-
secondary: "#6c757d",
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
expect(s.root.variables).toHaveLength(2);
|
|
70
|
-
expect(s.root.variables[0]?.name).toBe("color--primary");
|
|
71
|
-
expect(s.root.variables[1]?.name).toBe("color--secondary");
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
it("should handle kebab-case color names", () => {
|
|
75
|
-
const s = styleframe();
|
|
76
|
-
const { colorPrimaryDark } = useColor(s, {
|
|
77
|
-
"primary-dark": "#0056b3",
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
expect(colorPrimaryDark).toEqual({
|
|
81
|
-
type: "variable",
|
|
82
|
-
name: "color--primary-dark",
|
|
83
|
-
value: toOklch("#0056b3"),
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
it("should handle snake_case color names", () => {
|
|
88
|
-
const s = styleframe();
|
|
89
|
-
const { colorPrimaryLight } = useColor(s, {
|
|
90
|
-
primary_light: "#80bdff",
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
expect(colorPrimaryLight).toEqual({
|
|
94
|
-
type: "variable",
|
|
95
|
-
name: "color--primary_light",
|
|
96
|
-
value: toOklch("#80bdff"),
|
|
97
|
-
});
|
|
98
|
-
});
|
|
99
|
-
|
|
100
|
-
it("should handle numeric color names", () => {
|
|
101
|
-
const s = styleframe();
|
|
102
|
-
const { color500 } = useColor(s, {
|
|
103
|
-
"500": "#007bff",
|
|
104
|
-
});
|
|
105
|
-
|
|
106
|
-
expect(color500).toEqual({
|
|
107
|
-
type: "variable",
|
|
108
|
-
name: "color--500",
|
|
109
|
-
value: toOklch("#007bff"),
|
|
110
|
-
});
|
|
111
|
-
});
|
|
112
|
-
|
|
113
|
-
it("should handle rgb color values", () => {
|
|
114
|
-
const s = styleframe();
|
|
115
|
-
const { colorPrimary } = useColor(s, {
|
|
116
|
-
primary: "rgb(0, 123, 255)",
|
|
117
|
-
});
|
|
118
|
-
|
|
119
|
-
expect(colorPrimary).toEqual({
|
|
120
|
-
type: "variable",
|
|
121
|
-
name: "color--primary",
|
|
122
|
-
value: toOklch("rgb(0, 123, 255)"),
|
|
123
|
-
});
|
|
124
|
-
});
|
|
125
|
-
|
|
126
|
-
it("should handle rgba color values", () => {
|
|
127
|
-
const s = styleframe();
|
|
128
|
-
const { colorPrimary } = useColor(s, {
|
|
129
|
-
primary: "rgba(0, 123, 255, 0.5)",
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
expect(colorPrimary).toEqual({
|
|
133
|
-
type: "variable",
|
|
134
|
-
name: "color--primary",
|
|
135
|
-
value: toOklch("rgba(0, 123, 255, 0.5)"),
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
|
|
139
|
-
it("should handle hsl color values", () => {
|
|
140
|
-
const s = styleframe();
|
|
141
|
-
const { colorPrimary } = useColor(s, {
|
|
142
|
-
primary: "hsl(211, 100%, 50%)",
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
expect(colorPrimary).toEqual({
|
|
146
|
-
type: "variable",
|
|
147
|
-
name: "color--primary",
|
|
148
|
-
value: toOklch("hsl(211, 100%, 50%)"),
|
|
149
|
-
});
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("should handle empty color object", () => {
|
|
153
|
-
const s = styleframe();
|
|
154
|
-
const result = useColor(s, {});
|
|
155
|
-
|
|
156
|
-
expect(result).toEqual({});
|
|
157
|
-
expect(s.root.variables).toHaveLength(0);
|
|
158
|
-
});
|
|
159
|
-
|
|
160
|
-
it("should handle color references", () => {
|
|
161
|
-
const s = styleframe();
|
|
162
|
-
const baseColor = s.variable("base-color", "#007bff");
|
|
163
|
-
const { colorPrimary } = useColor(s, {
|
|
164
|
-
primary: s.ref(baseColor),
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
expect(colorPrimary.value).toEqual({
|
|
168
|
-
type: "reference",
|
|
169
|
-
name: "base-color",
|
|
170
|
-
fallback: undefined,
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it("should compile to correct CSS output using consume", () => {
|
|
175
|
-
const s = styleframe();
|
|
176
|
-
useColor(s, {
|
|
177
|
-
primary: "#007bff",
|
|
178
|
-
secondary: "#6c757d",
|
|
179
|
-
tertiary: "#28a745",
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
const css = consume(s.root, s.options);
|
|
183
|
-
|
|
184
|
-
expect(css).toBe(`:root {
|
|
185
|
-
--color--primary: ${toOklch("#007bff")};
|
|
186
|
-
--color--secondary: ${toOklch("#6c757d")};
|
|
187
|
-
--color--tertiary: ${toOklch("#28a745")};
|
|
188
|
-
}`);
|
|
189
|
-
});
|
|
190
|
-
|
|
191
|
-
describe("type safety", () => {
|
|
192
|
-
it("should preserve exact color names in return type", () => {
|
|
193
|
-
const s = styleframe();
|
|
194
|
-
const colors = useColor(s, {
|
|
195
|
-
primary: "#007bff",
|
|
196
|
-
secondary: "#6c757d",
|
|
197
|
-
});
|
|
198
|
-
|
|
199
|
-
// Type assertions to verify the generic types are preserved
|
|
200
|
-
const primary: Variable<"color--primary"> = colors.colorPrimary;
|
|
201
|
-
const secondary: Variable<"color--secondary"> = colors.colorSecondary;
|
|
202
|
-
|
|
203
|
-
expect(primary.name).toBe("color--primary");
|
|
204
|
-
expect(secondary.name).toBe("color--secondary");
|
|
205
|
-
});
|
|
206
|
-
|
|
207
|
-
it("should maintain type information for kebab-case names", () => {
|
|
208
|
-
const s = styleframe();
|
|
209
|
-
const { colorPrimaryDark } = useColor(s, {
|
|
210
|
-
"primary-dark": "#0056b3",
|
|
211
|
-
});
|
|
212
|
-
|
|
213
|
-
const typed: Variable<"color--primary-dark"> = colorPrimaryDark;
|
|
214
|
-
expect(typed.name).toBe("color--primary-dark");
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
it("should work with const assertion", () => {
|
|
218
|
-
const s = styleframe();
|
|
219
|
-
const colorConfig = {
|
|
220
|
-
primary: "#007bff",
|
|
221
|
-
secondary: "#6c757d",
|
|
222
|
-
} as const;
|
|
223
|
-
|
|
224
|
-
const colors = useColor(s, colorConfig);
|
|
225
|
-
|
|
226
|
-
expect(colors.colorPrimary.name).toBe("color--primary");
|
|
227
|
-
expect(colors.colorSecondary.name).toBe("color--secondary");
|
|
228
|
-
});
|
|
229
|
-
});
|
|
230
|
-
});
|
|
231
|
-
|
|
232
|
-
describe("integration", () => {
|
|
233
|
-
it("should work together to create a complete color system", () => {
|
|
234
|
-
const s = styleframe();
|
|
235
|
-
|
|
236
|
-
// Create base colors
|
|
237
|
-
const { colorPrimary, colorSecondary } = useColor(s, {
|
|
238
|
-
primary: "#007bff",
|
|
239
|
-
secondary: "#6c757d",
|
|
240
|
-
});
|
|
241
|
-
|
|
242
|
-
// Create lightness levels for primary
|
|
243
|
-
const primaryLevels = useColorLightness(s, colorPrimary, {
|
|
244
|
-
100: 10,
|
|
245
|
-
500: 50,
|
|
246
|
-
900: 90,
|
|
247
|
-
} as const);
|
|
248
|
-
|
|
249
|
-
// Create shade levels for secondary
|
|
250
|
-
const secondaryShades = useColorShade(s, colorSecondary, {
|
|
251
|
-
50: 5,
|
|
252
|
-
100: 10,
|
|
253
|
-
} as const);
|
|
254
|
-
|
|
255
|
-
// Create tint levels for secondary
|
|
256
|
-
const secondaryTints = useColorTint(s, colorSecondary, {
|
|
257
|
-
50: 5,
|
|
258
|
-
100: 10,
|
|
259
|
-
} as const);
|
|
260
|
-
|
|
261
|
-
// Verify all variables are created
|
|
262
|
-
expect(colorPrimary.name).toBe("color--primary");
|
|
263
|
-
expect(colorSecondary.name).toBe("color--secondary");
|
|
264
|
-
expect(primaryLevels.colorPrimary100.name).toBe("color--primary-100");
|
|
265
|
-
expect(primaryLevels.colorPrimary500.name).toBe("color--primary-500");
|
|
266
|
-
expect(primaryLevels.colorPrimary900.name).toBe("color--primary-900");
|
|
267
|
-
expect(secondaryShades.colorSecondaryShade50.name).toBe(
|
|
268
|
-
"color--secondary-shade-50",
|
|
269
|
-
);
|
|
270
|
-
expect(secondaryShades.colorSecondaryShade100.name).toBe(
|
|
271
|
-
"color--secondary-shade-100",
|
|
272
|
-
);
|
|
273
|
-
expect(secondaryTints.colorSecondaryTint50.name).toBe(
|
|
274
|
-
"color--secondary-tint-50",
|
|
275
|
-
);
|
|
276
|
-
expect(secondaryTints.colorSecondaryTint100.name).toBe(
|
|
277
|
-
"color--secondary-tint-100",
|
|
278
|
-
);
|
|
279
|
-
|
|
280
|
-
// All variables should be in root
|
|
281
|
-
expect(s.root.variables.length).toBe(9);
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
it("should handle complex naming scenarios", () => {
|
|
285
|
-
const s = styleframe();
|
|
286
|
-
|
|
287
|
-
const { colorBrandPrimary } = useColor(s, {
|
|
288
|
-
"brand-primary": "#007bff",
|
|
289
|
-
});
|
|
290
|
-
|
|
291
|
-
const levels = useColorLightness(s, colorBrandPrimary, {
|
|
292
|
-
400: 40,
|
|
293
|
-
} as const);
|
|
294
|
-
|
|
295
|
-
const shades = useColorShade(s, colorBrandPrimary, {
|
|
296
|
-
50: 5,
|
|
297
|
-
} as const);
|
|
298
|
-
|
|
299
|
-
const tints = useColorTint(s, colorBrandPrimary, {
|
|
300
|
-
50: 5,
|
|
301
|
-
} as const);
|
|
302
|
-
|
|
303
|
-
expect(colorBrandPrimary).toEqual({
|
|
304
|
-
type: "variable",
|
|
305
|
-
name: "color--brand-primary",
|
|
306
|
-
value: toOklch("#007bff"),
|
|
307
|
-
});
|
|
308
|
-
expect(levels.colorBrandPrimary400).toEqual({
|
|
309
|
-
type: "variable",
|
|
310
|
-
name: "color--brand-primary-400",
|
|
311
|
-
value: expect.objectContaining({ type: "css" }),
|
|
312
|
-
});
|
|
313
|
-
expect(shades.colorBrandPrimaryShade50).toEqual({
|
|
314
|
-
type: "variable",
|
|
315
|
-
name: "color--brand-primary-shade-50",
|
|
316
|
-
value: expect.objectContaining({ type: "css" }),
|
|
317
|
-
});
|
|
318
|
-
expect(tints.colorBrandPrimaryTint50).toEqual({
|
|
319
|
-
type: "variable",
|
|
320
|
-
name: "color--brand-primary-tint-50",
|
|
321
|
-
value: expect.objectContaining({ type: "css" }),
|
|
322
|
-
});
|
|
323
|
-
});
|
|
324
|
-
|
|
325
|
-
it("should compile complete color system to correct CSS output using consume", () => {
|
|
326
|
-
const s = styleframe();
|
|
327
|
-
|
|
328
|
-
const { colorPrimary } = useColor(s, {
|
|
329
|
-
primary: "#007bff",
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
const levels = useColorLightness(s, colorPrimary, {
|
|
333
|
-
100: 10,
|
|
334
|
-
200: 20,
|
|
335
|
-
});
|
|
336
|
-
|
|
337
|
-
const shades = useColorShade(s, colorPrimary, {
|
|
338
|
-
50: 5,
|
|
339
|
-
});
|
|
340
|
-
|
|
341
|
-
const tints = useColorTint(s, colorPrimary, {
|
|
342
|
-
50: 5,
|
|
343
|
-
});
|
|
344
|
-
|
|
345
|
-
const css = consume(s.root, s.options);
|
|
346
|
-
|
|
347
|
-
expect(css).toBe(`:root {
|
|
348
|
-
--color--primary: ${toOklch("#007bff")};
|
|
349
|
-
--color--primary-100: oklch(from var(--color--primary) 0.1 c h / a);
|
|
350
|
-
--color--primary-200: oklch(from var(--color--primary) 0.2 c h / a);
|
|
351
|
-
--color--primary-shade-50: oklch(from var(--color--primary) calc(l - 0.05) c h / a);
|
|
352
|
-
--color--primary-tint-50: oklch(from var(--color--primary) calc(l + 0.05) c h / a);
|
|
353
|
-
}`);
|
|
354
|
-
|
|
355
|
-
// Verify all variables are present
|
|
356
|
-
expect(levels.colorPrimary100).toBeDefined();
|
|
357
|
-
expect(shades.colorPrimaryShade50).toBeDefined();
|
|
358
|
-
expect(tints.colorPrimaryTint50).toBeDefined();
|
|
359
|
-
});
|
|
360
|
-
});
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
import { oklch } from "culori";
|
|
2
|
-
import { createUseVariable } from "../utils";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Create a set of color variables for use in a Styleframe instance.
|
|
6
|
-
*
|
|
7
|
-
* @usage
|
|
8
|
-
* ```typescript
|
|
9
|
-
* import { styleframe } from "styleframe";
|
|
10
|
-
* import { useColors } from "styleframe/theme";
|
|
11
|
-
*
|
|
12
|
-
* const s = styleframe();
|
|
13
|
-
*
|
|
14
|
-
* const {
|
|
15
|
-
* colorPrimary, // Variable<'color--primary'>
|
|
16
|
-
* colorSecondary, // Variable<'color--secondary'>
|
|
17
|
-
* } = useColors(s, {
|
|
18
|
-
* primary: "#007bff",
|
|
19
|
-
* secondary: "#6c757d",
|
|
20
|
-
* });
|
|
21
|
-
* ```
|
|
22
|
-
*/
|
|
23
|
-
|
|
24
|
-
export const useColor = createUseVariable("color", {
|
|
25
|
-
transform: (value) => {
|
|
26
|
-
let transformedValue = value;
|
|
27
|
-
|
|
28
|
-
if (typeof value === "string") {
|
|
29
|
-
const { l, c, h, alpha = 1 } = oklch(value);
|
|
30
|
-
transformedValue = `oklch(${l} ${c} ${h} / ${alpha})`;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return transformedValue;
|
|
34
|
-
},
|
|
35
|
-
});
|
|
@@ -1,168 +0,0 @@
|
|
|
1
|
-
import type { Variable } from "@styleframe/core";
|
|
2
|
-
import { styleframe } from "@styleframe/core";
|
|
3
|
-
import { consume } from "@styleframe/transpiler";
|
|
4
|
-
import {
|
|
5
|
-
useColorLightness,
|
|
6
|
-
defaultColorLightnessValues,
|
|
7
|
-
} from "./useColorLightness";
|
|
8
|
-
|
|
9
|
-
describe("useColorLightness", () => {
|
|
10
|
-
it("should create lightness levels with default values", () => {
|
|
11
|
-
const s = styleframe();
|
|
12
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
13
|
-
const levels = useColorLightness(
|
|
14
|
-
s,
|
|
15
|
-
colorPrimary,
|
|
16
|
-
defaultColorLightnessValues,
|
|
17
|
-
);
|
|
18
|
-
|
|
19
|
-
// Test some of the default levels (we know they exist from the default parameter)
|
|
20
|
-
expect(levels.colorPrimary50).toEqual({
|
|
21
|
-
type: "variable",
|
|
22
|
-
name: "color--primary-50",
|
|
23
|
-
value: expect.objectContaining({ type: "css" }),
|
|
24
|
-
});
|
|
25
|
-
expect(levels.colorPrimary500).toEqual({
|
|
26
|
-
type: "variable",
|
|
27
|
-
name: "color--primary-500",
|
|
28
|
-
value: expect.objectContaining({ type: "css" }),
|
|
29
|
-
});
|
|
30
|
-
expect(levels.colorPrimary950).toEqual({
|
|
31
|
-
type: "variable",
|
|
32
|
-
name: "color--primary-950",
|
|
33
|
-
value: expect.objectContaining({ type: "css" }),
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
const css = consume(levels.colorPrimary100, s.options);
|
|
37
|
-
expect(css).toBe(
|
|
38
|
-
`--color--primary-100: oklch(from var(--color--primary) 0.1 c h / a);`,
|
|
39
|
-
);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
it("should compile lightness levels to correct CSS output using consume", () => {
|
|
43
|
-
const s = styleframe();
|
|
44
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
45
|
-
useColorLightness(s, colorPrimary, {
|
|
46
|
-
100: 10,
|
|
47
|
-
200: 20,
|
|
48
|
-
300: 30,
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const css = consume(s.root, s.options);
|
|
52
|
-
|
|
53
|
-
expect(css).toBe(`:root {
|
|
54
|
-
--color--primary: #007bff;
|
|
55
|
-
--color--primary-100: oklch(from var(--color--primary) 0.1 c h / a);
|
|
56
|
-
--color--primary-200: oklch(from var(--color--primary) 0.2 c h / a);
|
|
57
|
-
--color--primary-300: oklch(from var(--color--primary) 0.3 c h / a);
|
|
58
|
-
}`);
|
|
59
|
-
});
|
|
60
|
-
|
|
61
|
-
it("should create lightness levels with custom values", () => {
|
|
62
|
-
const s = styleframe();
|
|
63
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
64
|
-
const levels = useColorLightness(s, colorPrimary, {
|
|
65
|
-
100: 10,
|
|
66
|
-
200: 20,
|
|
67
|
-
300: 30,
|
|
68
|
-
} as const);
|
|
69
|
-
|
|
70
|
-
expect(levels.colorPrimary100).toEqual({
|
|
71
|
-
type: "variable",
|
|
72
|
-
name: "color--primary-100",
|
|
73
|
-
value: expect.objectContaining({ type: "css" }),
|
|
74
|
-
});
|
|
75
|
-
expect(levels.colorPrimary200).toEqual({
|
|
76
|
-
type: "variable",
|
|
77
|
-
name: "color--primary-200",
|
|
78
|
-
value: expect.objectContaining({ type: "css" }),
|
|
79
|
-
});
|
|
80
|
-
expect(levels.colorPrimary300).toEqual({
|
|
81
|
-
type: "variable",
|
|
82
|
-
name: "color--primary-300",
|
|
83
|
-
value: expect.objectContaining({ type: "css" }),
|
|
84
|
-
});
|
|
85
|
-
|
|
86
|
-
const css = consume(levels.colorPrimary200, s.options);
|
|
87
|
-
expect(css).toBe(
|
|
88
|
-
"--color--primary-200: oklch(from var(--color--primary) 0.2 c h / a);",
|
|
89
|
-
);
|
|
90
|
-
});
|
|
91
|
-
|
|
92
|
-
it("should add variables to root", () => {
|
|
93
|
-
const s = styleframe();
|
|
94
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
95
|
-
useColorLightness(s, colorPrimary, {
|
|
96
|
-
100: 10,
|
|
97
|
-
200: 20,
|
|
98
|
-
} as const);
|
|
99
|
-
|
|
100
|
-
// +1 for the original color variable
|
|
101
|
-
expect(s.root.variables.length).toBeGreaterThanOrEqual(3);
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
it("should handle color with kebab-case name", () => {
|
|
105
|
-
const s = styleframe();
|
|
106
|
-
const colorPrimaryDark = s.variable("color--primary-dark", "#0056b3");
|
|
107
|
-
const levels = useColorLightness(s, colorPrimaryDark, {
|
|
108
|
-
100: 10,
|
|
109
|
-
} as const);
|
|
110
|
-
|
|
111
|
-
expect(levels.colorPrimaryDark100.name).toBe("color--primary-dark-100");
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it("should handle empty levels object", () => {
|
|
115
|
-
const s = styleframe();
|
|
116
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
117
|
-
const levels = useColorLightness(s, colorPrimary, {} as const);
|
|
118
|
-
|
|
119
|
-
expect(levels).toEqual({});
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it("should work with different variable name patterns", () => {
|
|
123
|
-
const s = styleframe();
|
|
124
|
-
const customColor = s.variable("custom-color", "#ff0000");
|
|
125
|
-
const levels = useColorLightness(s, customColor, {
|
|
126
|
-
500: 50,
|
|
127
|
-
} as const);
|
|
128
|
-
|
|
129
|
-
expect(levels.customColor500).toEqual({
|
|
130
|
-
type: "variable",
|
|
131
|
-
name: "custom-color-500",
|
|
132
|
-
value: expect.objectContaining({ type: "css" }),
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
const css = consume(levels.customColor500, s.options);
|
|
136
|
-
expect(css).toBe(
|
|
137
|
-
`--custom-color-500: oklch(from var(--custom-color) 0.5 c h / a);`,
|
|
138
|
-
);
|
|
139
|
-
});
|
|
140
|
-
|
|
141
|
-
describe("type safety", () => {
|
|
142
|
-
it("should preserve variable name in return type", () => {
|
|
143
|
-
const s = styleframe();
|
|
144
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
145
|
-
const levels = useColorLightness(s, colorPrimary, {
|
|
146
|
-
100: 10,
|
|
147
|
-
200: 20,
|
|
148
|
-
} as const);
|
|
149
|
-
|
|
150
|
-
const level100: Variable<"color--primary-100"> = levels.colorPrimary100;
|
|
151
|
-
const level200: Variable<"color--primary-200"> = levels.colorPrimary200;
|
|
152
|
-
|
|
153
|
-
expect(level100.name).toBe("color--primary-100");
|
|
154
|
-
expect(level200.name).toBe("color--primary-200");
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it("should work with generic variable names", () => {
|
|
158
|
-
const s = styleframe();
|
|
159
|
-
const colorSecondary = s.variable("color--secondary", "#6c757d");
|
|
160
|
-
const levels = useColorLightness(s, colorSecondary, {
|
|
161
|
-
300: 30,
|
|
162
|
-
} as const);
|
|
163
|
-
|
|
164
|
-
const typed: Variable<"color--secondary-300"> = levels.colorSecondary300;
|
|
165
|
-
expect(typed.name).toBe("color--secondary-300");
|
|
166
|
-
});
|
|
167
|
-
});
|
|
168
|
-
});
|
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import type { Styleframe, Variable } from "@styleframe/core";
|
|
2
|
-
import type { ExportKeys } from "../types";
|
|
3
|
-
import { createUseVariable } from "../utils";
|
|
4
|
-
|
|
5
|
-
export const defaultColorLightnessValues = {
|
|
6
|
-
50: 5,
|
|
7
|
-
100: 10,
|
|
8
|
-
200: 20,
|
|
9
|
-
300: 30,
|
|
10
|
-
400: 40,
|
|
11
|
-
500: 50,
|
|
12
|
-
600: 60,
|
|
13
|
-
700: 70,
|
|
14
|
-
800: 80,
|
|
15
|
-
900: 90,
|
|
16
|
-
950: 95,
|
|
17
|
-
} as const;
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Create a set of lightness levels for a color variable.
|
|
21
|
-
*
|
|
22
|
-
* @usage
|
|
23
|
-
* ```typescript
|
|
24
|
-
* import { styleframe } from "styleframe";
|
|
25
|
-
* import { useColors } from "styleframe/theme";
|
|
26
|
-
*
|
|
27
|
-
* const s = styleframe();
|
|
28
|
-
*
|
|
29
|
-
* const colorPrimary = s.variable("color--primary", "#007bff");
|
|
30
|
-
*
|
|
31
|
-
* const {
|
|
32
|
-
* colorPrimary100, // Variable<'color--primary-100'>
|
|
33
|
-
* colorPrimary200, // Variable<'color--primary-200'>
|
|
34
|
-
* colorPrimary300, // Variable<'color--primary-300'>
|
|
35
|
-
* ...
|
|
36
|
-
* } = useColorLightnessLevels(s, colorPrimary, {
|
|
37
|
-
* 100: 10,
|
|
38
|
-
* 200: 20,
|
|
39
|
-
* 300: 30,
|
|
40
|
-
* ...
|
|
41
|
-
* });
|
|
42
|
-
* ```
|
|
43
|
-
*/
|
|
44
|
-
export function useColorLightness<
|
|
45
|
-
Name extends string,
|
|
46
|
-
T extends Record<string | number, number>,
|
|
47
|
-
>(s: Styleframe, color: Variable<Name>, levels: T): ExportKeys<Name, T, "-"> {
|
|
48
|
-
return createUseVariable(color.name, {
|
|
49
|
-
defaults: defaultColorLightnessValues,
|
|
50
|
-
transform: (value) => {
|
|
51
|
-
if (typeof value !== "number") {
|
|
52
|
-
return 0;
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
return s.css`oklch(from ${s.ref(color)} ${value / 100} c h / a)`;
|
|
56
|
-
},
|
|
57
|
-
delimiter: "-" as const,
|
|
58
|
-
})(s, levels);
|
|
59
|
-
}
|