@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,166 +0,0 @@
|
|
|
1
|
-
import type { Variable } from "@styleframe/core";
|
|
2
|
-
import { styleframe } from "@styleframe/core";
|
|
3
|
-
import { consume } from "@styleframe/transpiler";
|
|
4
|
-
import { useColorShade, defaultColorShadeValues } from "./useColorShade";
|
|
5
|
-
|
|
6
|
-
describe("useColorShade", () => {
|
|
7
|
-
it("should create shade levels with default values", () => {
|
|
8
|
-
const s = styleframe();
|
|
9
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
10
|
-
const shades = useColorShade(s, colorPrimary, defaultColorShadeValues);
|
|
11
|
-
|
|
12
|
-
expect(shades.colorPrimaryShade50).toEqual({
|
|
13
|
-
type: "variable",
|
|
14
|
-
name: "color--primary-shade-50",
|
|
15
|
-
value: expect.objectContaining({ type: "css" }),
|
|
16
|
-
});
|
|
17
|
-
expect(shades.colorPrimaryShade100).toEqual({
|
|
18
|
-
type: "variable",
|
|
19
|
-
name: "color--primary-shade-100",
|
|
20
|
-
value: expect.objectContaining({ type: "css" }),
|
|
21
|
-
});
|
|
22
|
-
expect(shades.colorPrimaryShade150).toEqual({
|
|
23
|
-
type: "variable",
|
|
24
|
-
name: "color--primary-shade-150",
|
|
25
|
-
value: expect.objectContaining({ type: "css" }),
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const css = consume(shades.colorPrimaryShade100, s.options);
|
|
29
|
-
expect(css).toBe(
|
|
30
|
-
`--color--primary-shade-100: oklch(from var(--color--primary) calc(l - 0.1) c h / a);`,
|
|
31
|
-
);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("should create shade levels with custom values", () => {
|
|
35
|
-
const s = styleframe();
|
|
36
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
37
|
-
const shades = useColorShade(s, colorPrimary, {
|
|
38
|
-
25: 2.5,
|
|
39
|
-
50: 5,
|
|
40
|
-
75: 7.5,
|
|
41
|
-
100: 10,
|
|
42
|
-
} as const);
|
|
43
|
-
|
|
44
|
-
expect(shades.colorPrimaryShade25).toEqual({
|
|
45
|
-
type: "variable",
|
|
46
|
-
name: "color--primary-shade-25",
|
|
47
|
-
value: expect.objectContaining({ type: "css" }),
|
|
48
|
-
});
|
|
49
|
-
expect(shades.colorPrimaryShade50).toEqual({
|
|
50
|
-
type: "variable",
|
|
51
|
-
name: "color--primary-shade-50",
|
|
52
|
-
value: expect.objectContaining({ type: "css" }),
|
|
53
|
-
});
|
|
54
|
-
expect(shades.colorPrimaryShade75).toEqual({
|
|
55
|
-
type: "variable",
|
|
56
|
-
name: "color--primary-shade-75",
|
|
57
|
-
value: expect.objectContaining({ type: "css" }),
|
|
58
|
-
});
|
|
59
|
-
expect(shades.colorPrimaryShade100).toEqual({
|
|
60
|
-
type: "variable",
|
|
61
|
-
name: "color--primary-shade-100",
|
|
62
|
-
value: expect.objectContaining({ type: "css" }),
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("should compile shade levels to correct CSS output using consume", () => {
|
|
67
|
-
const s = styleframe();
|
|
68
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
69
|
-
|
|
70
|
-
useColorShade(s, colorPrimary, {
|
|
71
|
-
50: 5,
|
|
72
|
-
100: 10,
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
const css = consume(s.root, s.options);
|
|
76
|
-
|
|
77
|
-
expect(css).toBe(`:root {
|
|
78
|
-
--color--primary: #007bff;
|
|
79
|
-
--color--primary-shade-50: oklch(from var(--color--primary) calc(l - 0.05) c h / a);
|
|
80
|
-
--color--primary-shade-100: oklch(from var(--color--primary) calc(l - 0.1) c h / a);
|
|
81
|
-
}`);
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it("should add variables to root", () => {
|
|
85
|
-
const s = styleframe();
|
|
86
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
87
|
-
|
|
88
|
-
useColorShade(s, colorPrimary, {
|
|
89
|
-
50: 5,
|
|
90
|
-
100: 10,
|
|
91
|
-
} as const);
|
|
92
|
-
|
|
93
|
-
// +1 for the original color variable
|
|
94
|
-
expect(s.root.variables.length).toBeGreaterThanOrEqual(3);
|
|
95
|
-
});
|
|
96
|
-
|
|
97
|
-
it("should handle color with kebab-case name", () => {
|
|
98
|
-
const s = styleframe();
|
|
99
|
-
const colorPrimaryDark = s.variable("color--primary-dark", "#0056b3");
|
|
100
|
-
const shades = useColorShade(s, colorPrimaryDark, { 50: 5 });
|
|
101
|
-
|
|
102
|
-
expect(shades.colorPrimaryDarkShade50).toEqual({
|
|
103
|
-
type: "variable",
|
|
104
|
-
name: "color--primary-dark-shade-50",
|
|
105
|
-
value: expect.objectContaining({ type: "css" }),
|
|
106
|
-
});
|
|
107
|
-
});
|
|
108
|
-
|
|
109
|
-
it("should handle empty levels object", () => {
|
|
110
|
-
const s = styleframe();
|
|
111
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
112
|
-
const shades = useColorShade(s, colorPrimary, {} as const);
|
|
113
|
-
|
|
114
|
-
expect(shades).toEqual({});
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
it("should work with different variable name patterns", () => {
|
|
118
|
-
const s = styleframe();
|
|
119
|
-
const customColor = s.variable("custom-color", "#ff0000");
|
|
120
|
-
const shades = useColorShade(s, customColor, {
|
|
121
|
-
100: 10,
|
|
122
|
-
} as const);
|
|
123
|
-
|
|
124
|
-
expect(shades.customColorShade100).toEqual({
|
|
125
|
-
type: "variable",
|
|
126
|
-
name: "custom-color-shade-100",
|
|
127
|
-
value: expect.objectContaining({ type: "css" }),
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
const css = consume(shades.customColorShade100, s.options);
|
|
131
|
-
expect(css).toBe(
|
|
132
|
-
`--custom-color-shade-100: oklch(from var(--custom-color) calc(l - 0.1) c h / a);`,
|
|
133
|
-
);
|
|
134
|
-
});
|
|
135
|
-
|
|
136
|
-
describe("type safety", () => {
|
|
137
|
-
it("should preserve variable name in return type", () => {
|
|
138
|
-
const s = styleframe();
|
|
139
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
140
|
-
const shades = useColorShade(s, colorPrimary, {
|
|
141
|
-
50: 5,
|
|
142
|
-
100: 10,
|
|
143
|
-
} as const);
|
|
144
|
-
|
|
145
|
-
const shade50: Variable<"color--primary-shade-50"> =
|
|
146
|
-
shades.colorPrimaryShade50;
|
|
147
|
-
const shade100: Variable<"color--primary-shade-100"> =
|
|
148
|
-
shades.colorPrimaryShade100;
|
|
149
|
-
|
|
150
|
-
expect(shade50.name).toBe("color--primary-shade-50");
|
|
151
|
-
expect(shade100.name).toBe("color--primary-shade-100");
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
it("should work with generic variable names", () => {
|
|
155
|
-
const s = styleframe();
|
|
156
|
-
const colorSecondary = s.variable("color--secondary", "#6c757d");
|
|
157
|
-
const shades = useColorShade(s, colorSecondary, {
|
|
158
|
-
75: 7.5,
|
|
159
|
-
} as const);
|
|
160
|
-
|
|
161
|
-
const typed: Variable<"color--secondary-shade-75"> =
|
|
162
|
-
shades.colorSecondaryShade75;
|
|
163
|
-
expect(typed.name).toBe("color--secondary-shade-75");
|
|
164
|
-
});
|
|
165
|
-
});
|
|
166
|
-
});
|
|
@@ -1,52 +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 defaultColorShadeValues = {
|
|
6
|
-
50: 5,
|
|
7
|
-
100: 10,
|
|
8
|
-
150: 15,
|
|
9
|
-
200: 20,
|
|
10
|
-
} as const;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Create a set of relative color shade (darker) levels
|
|
14
|
-
*
|
|
15
|
-
* @usage
|
|
16
|
-
* const s = styleframe();
|
|
17
|
-
*
|
|
18
|
-
* const colorPrimary = s.variable("color--primary", "#007bff");
|
|
19
|
-
*
|
|
20
|
-
* const {
|
|
21
|
-
* colorPrimaryShade50, // Variable<'color--primary-shade-50'>
|
|
22
|
-
* colorPrimaryShade100, // Variable<'color--primary-shade-100'>
|
|
23
|
-
* colorPrimaryShade150, // Variable<'color--primary-shade-150'>
|
|
24
|
-
* ...
|
|
25
|
-
* } = useColorShadeLevels(s, colorPrimary, {
|
|
26
|
-
* 50: 5,
|
|
27
|
-
* 100: 10,
|
|
28
|
-
* 150: 15,
|
|
29
|
-
* ...
|
|
30
|
-
* });
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export function useColorShade<
|
|
34
|
-
Name extends string,
|
|
35
|
-
T extends Record<string | number, number>,
|
|
36
|
-
>(
|
|
37
|
-
s: Styleframe,
|
|
38
|
-
color: Variable<Name>,
|
|
39
|
-
levels: T,
|
|
40
|
-
): ExportKeys<`${Name}-shade`, T, "-"> {
|
|
41
|
-
return createUseVariable(`${color.name}-shade`, {
|
|
42
|
-
defaults: defaultColorShadeValues,
|
|
43
|
-
transform: (value) => {
|
|
44
|
-
if (typeof value !== "number") {
|
|
45
|
-
return 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return s.css`oklch(from ${s.ref(color)} calc(l - ${value / 100}) c h / a)`;
|
|
49
|
-
},
|
|
50
|
-
delimiter: "-" as const,
|
|
51
|
-
})(s, levels);
|
|
52
|
-
}
|
|
@@ -1,164 +0,0 @@
|
|
|
1
|
-
import type { Variable } from "@styleframe/core";
|
|
2
|
-
import { styleframe } from "@styleframe/core";
|
|
3
|
-
import { consume } from "@styleframe/transpiler";
|
|
4
|
-
import { useColorTint, defaultColorTintValues } from "./useColorTint";
|
|
5
|
-
|
|
6
|
-
describe("useColorTint", () => {
|
|
7
|
-
it("should create tint levels with default values", () => {
|
|
8
|
-
const s = styleframe();
|
|
9
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
10
|
-
const tints = useColorTint(s, colorPrimary, defaultColorTintValues);
|
|
11
|
-
|
|
12
|
-
expect(tints.colorPrimaryTint50).toEqual({
|
|
13
|
-
type: "variable",
|
|
14
|
-
name: "color--primary-tint-50",
|
|
15
|
-
value: expect.objectContaining({ type: "css" }),
|
|
16
|
-
});
|
|
17
|
-
expect(tints.colorPrimaryTint100).toEqual({
|
|
18
|
-
type: "variable",
|
|
19
|
-
name: "color--primary-tint-100",
|
|
20
|
-
value: expect.objectContaining({ type: "css" }),
|
|
21
|
-
});
|
|
22
|
-
expect(tints.colorPrimaryTint150).toEqual({
|
|
23
|
-
type: "variable",
|
|
24
|
-
name: "color--primary-tint-150",
|
|
25
|
-
value: expect.objectContaining({ type: "css" }),
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
const css = consume(tints.colorPrimaryTint100, s.options);
|
|
29
|
-
expect(css).toBe(
|
|
30
|
-
`--color--primary-tint-100: oklch(from var(--color--primary) calc(l + 0.1) c h / a);`,
|
|
31
|
-
);
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
it("should create tint levels with custom values", () => {
|
|
35
|
-
const s = styleframe();
|
|
36
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
37
|
-
const tints = useColorTint(s, colorPrimary, {
|
|
38
|
-
25: 2.5,
|
|
39
|
-
50: 5,
|
|
40
|
-
75: 7.5,
|
|
41
|
-
100: 10,
|
|
42
|
-
} as const);
|
|
43
|
-
|
|
44
|
-
expect(tints.colorPrimaryTint25).toEqual({
|
|
45
|
-
type: "variable",
|
|
46
|
-
name: "color--primary-tint-25",
|
|
47
|
-
value: expect.objectContaining({ type: "css" }),
|
|
48
|
-
});
|
|
49
|
-
expect(tints.colorPrimaryTint50).toEqual({
|
|
50
|
-
type: "variable",
|
|
51
|
-
name: "color--primary-tint-50",
|
|
52
|
-
value: expect.objectContaining({ type: "css" }),
|
|
53
|
-
});
|
|
54
|
-
expect(tints.colorPrimaryTint75).toEqual({
|
|
55
|
-
type: "variable",
|
|
56
|
-
name: "color--primary-tint-75",
|
|
57
|
-
value: expect.objectContaining({ type: "css" }),
|
|
58
|
-
});
|
|
59
|
-
expect(tints.colorPrimaryTint100).toEqual({
|
|
60
|
-
type: "variable",
|
|
61
|
-
name: "color--primary-tint-100",
|
|
62
|
-
value: expect.objectContaining({ type: "css" }),
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it("should compile tint levels to correct CSS output using consume", () => {
|
|
67
|
-
const s = styleframe();
|
|
68
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
69
|
-
useColorTint(s, colorPrimary, {
|
|
70
|
-
50: 5,
|
|
71
|
-
100: 10,
|
|
72
|
-
});
|
|
73
|
-
|
|
74
|
-
const css = consume(s.root, s.options);
|
|
75
|
-
|
|
76
|
-
expect(css).toBe(`:root {
|
|
77
|
-
--color--primary: #007bff;
|
|
78
|
-
--color--primary-tint-50: oklch(from var(--color--primary) calc(l + 0.05) c h / a);
|
|
79
|
-
--color--primary-tint-100: oklch(from var(--color--primary) calc(l + 0.1) c h / a);
|
|
80
|
-
}`);
|
|
81
|
-
});
|
|
82
|
-
|
|
83
|
-
it("should add variables to root", () => {
|
|
84
|
-
const s = styleframe();
|
|
85
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
86
|
-
useColorTint(s, colorPrimary, {
|
|
87
|
-
50: 5,
|
|
88
|
-
100: 10,
|
|
89
|
-
} as const);
|
|
90
|
-
|
|
91
|
-
// +1 for the original color variable
|
|
92
|
-
expect(s.root.variables.length).toBeGreaterThanOrEqual(3);
|
|
93
|
-
});
|
|
94
|
-
|
|
95
|
-
it("should handle color with kebab-case name", () => {
|
|
96
|
-
const s = styleframe();
|
|
97
|
-
const colorPrimaryLight = s.variable("color--primary-light", "#80bdff");
|
|
98
|
-
const tints = useColorTint(s, colorPrimaryLight, {
|
|
99
|
-
50: 5,
|
|
100
|
-
} as const);
|
|
101
|
-
|
|
102
|
-
expect(tints.colorPrimaryLightTint50.name).toBe(
|
|
103
|
-
"color--primary-light-tint-50",
|
|
104
|
-
);
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
it("should handle empty levels object", () => {
|
|
108
|
-
const s = styleframe();
|
|
109
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
110
|
-
const tints = useColorTint(s, colorPrimary, {} as const);
|
|
111
|
-
|
|
112
|
-
expect(tints).toEqual({});
|
|
113
|
-
});
|
|
114
|
-
|
|
115
|
-
it("should work with different variable name patterns", () => {
|
|
116
|
-
const s = styleframe();
|
|
117
|
-
const customColor = s.variable("custom-color", "#ff0000");
|
|
118
|
-
const tints = useColorTint(s, customColor, {
|
|
119
|
-
100: 10,
|
|
120
|
-
} as const);
|
|
121
|
-
|
|
122
|
-
expect(tints.customColorTint100).toEqual({
|
|
123
|
-
type: "variable",
|
|
124
|
-
name: "custom-color-tint-100",
|
|
125
|
-
value: expect.objectContaining({ type: "css" }),
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
const css = consume(tints.customColorTint100, s.options);
|
|
129
|
-
expect(css).toBe(
|
|
130
|
-
`--custom-color-tint-100: oklch(from var(--custom-color) calc(l + 0.1) c h / a);`,
|
|
131
|
-
);
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
describe("type safety", () => {
|
|
135
|
-
it("should preserve variable name in return type", () => {
|
|
136
|
-
const s = styleframe();
|
|
137
|
-
const colorPrimary = s.variable("color--primary", "#007bff");
|
|
138
|
-
const tints = useColorTint(s, colorPrimary, {
|
|
139
|
-
50: 5,
|
|
140
|
-
100: 10,
|
|
141
|
-
} as const);
|
|
142
|
-
|
|
143
|
-
const tint50: Variable<"color--primary-tint-50"> =
|
|
144
|
-
tints.colorPrimaryTint50;
|
|
145
|
-
const tint100: Variable<"color--primary-tint-100"> =
|
|
146
|
-
tints.colorPrimaryTint100;
|
|
147
|
-
|
|
148
|
-
expect(tint50.name).toBe("color--primary-tint-50");
|
|
149
|
-
expect(tint100.name).toBe("color--primary-tint-100");
|
|
150
|
-
});
|
|
151
|
-
|
|
152
|
-
it("should work with generic variable names", () => {
|
|
153
|
-
const s = styleframe();
|
|
154
|
-
const colorSecondary = s.variable("color--secondary", "#6c757d");
|
|
155
|
-
const tints = useColorTint(s, colorSecondary, {
|
|
156
|
-
75: 7.5,
|
|
157
|
-
} as const);
|
|
158
|
-
|
|
159
|
-
const typed: Variable<"color--secondary-tint-75"> =
|
|
160
|
-
tints.colorSecondaryTint75;
|
|
161
|
-
expect(typed.name).toBe("color--secondary-tint-75");
|
|
162
|
-
});
|
|
163
|
-
});
|
|
164
|
-
});
|
|
@@ -1,52 +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 defaultColorTintValues = {
|
|
6
|
-
50: 5,
|
|
7
|
-
100: 10,
|
|
8
|
-
150: 15,
|
|
9
|
-
200: 20,
|
|
10
|
-
} as const;
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Create a set of relative color tint (lighter) levels
|
|
14
|
-
*
|
|
15
|
-
* @usage
|
|
16
|
-
* const s = styleframe();
|
|
17
|
-
*
|
|
18
|
-
* const colorPrimary = s.variable("color--primary", "#007bff");
|
|
19
|
-
*
|
|
20
|
-
* const {
|
|
21
|
-
* colorPrimaryTint50, // Variable<'color--primary-tint-50'>
|
|
22
|
-
* colorPrimaryTint100, // Variable<'color--primary-tint-100'>
|
|
23
|
-
* colorPrimaryTint150, // Variable<'color--primary-tint-150'>
|
|
24
|
-
* ...
|
|
25
|
-
* } = useColorTintLevels(s, colorPrimary, {
|
|
26
|
-
* 50: 5,
|
|
27
|
-
* 100: 10,
|
|
28
|
-
* 150: 15,
|
|
29
|
-
* ...
|
|
30
|
-
* });
|
|
31
|
-
* ```
|
|
32
|
-
*/
|
|
33
|
-
export function useColorTint<
|
|
34
|
-
Name extends string,
|
|
35
|
-
T extends Record<string | number, number>,
|
|
36
|
-
>(
|
|
37
|
-
s: Styleframe,
|
|
38
|
-
color: Variable<Name>,
|
|
39
|
-
levels: T,
|
|
40
|
-
): ExportKeys<`${Name}-tint`, T, "-"> {
|
|
41
|
-
return createUseVariable(`${color.name}-tint`, {
|
|
42
|
-
defaults: defaultColorTintValues,
|
|
43
|
-
transform: (value) => {
|
|
44
|
-
if (typeof value !== "number") {
|
|
45
|
-
return 0;
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
return s.css`oklch(from ${s.ref(color)} calc(l + ${value / 100}) c h / a)`;
|
|
49
|
-
},
|
|
50
|
-
delimiter: "-" as const,
|
|
51
|
-
})(s, levels);
|
|
52
|
-
}
|
|
File without changes
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
import type { Variable } from "@styleframe/core";
|
|
2
|
-
import { styleframe } from "@styleframe/core";
|
|
3
|
-
import { consume } from "@styleframe/transpiler";
|
|
4
|
-
import { useFontFamily } from "./useFontFamily";
|
|
5
|
-
|
|
6
|
-
describe("useFontFamily", () => {
|
|
7
|
-
it("should create a single font family variable with 'default' key", () => {
|
|
8
|
-
const s = styleframe();
|
|
9
|
-
const { fontFamily } = useFontFamily(s, {
|
|
10
|
-
default: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto",
|
|
11
|
-
});
|
|
12
|
-
|
|
13
|
-
expect(fontFamily).toEqual({
|
|
14
|
-
type: "variable",
|
|
15
|
-
name: "font-family",
|
|
16
|
-
value: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto",
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
const css = consume(fontFamily, s.options);
|
|
20
|
-
expect(css).toBe(
|
|
21
|
-
`--font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto;`,
|
|
22
|
-
);
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
it("should create font family variable with modifier for non-default keys", () => {
|
|
26
|
-
const s = styleframe();
|
|
27
|
-
const { fontFamilyMono } = useFontFamily(s, {
|
|
28
|
-
mono: "'SFMono-Regular', Menlo, Monaco, Consolas",
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
expect(fontFamilyMono).toEqual({
|
|
32
|
-
type: "variable",
|
|
33
|
-
name: "font-family--mono",
|
|
34
|
-
value: "'SFMono-Regular', Menlo, Monaco, Consolas",
|
|
35
|
-
});
|
|
36
|
-
|
|
37
|
-
const css = consume(fontFamilyMono, s.options);
|
|
38
|
-
expect(css).toBe(
|
|
39
|
-
`--font-family--mono: 'SFMono-Regular', Menlo, Monaco, Consolas;`,
|
|
40
|
-
);
|
|
41
|
-
});
|
|
42
|
-
|
|
43
|
-
it("should create multiple font family variables", () => {
|
|
44
|
-
const s = styleframe();
|
|
45
|
-
const { fontFamily, fontFamilyPrint, fontFamilyMono } = useFontFamily(s, {
|
|
46
|
-
default:
|
|
47
|
-
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif",
|
|
48
|
-
print: "'Georgia', 'Times New Roman', 'Times', serif",
|
|
49
|
-
mono: "'SFMono-Regular', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
expect(fontFamily).toEqual({
|
|
53
|
-
type: "variable",
|
|
54
|
-
name: "font-family",
|
|
55
|
-
value:
|
|
56
|
-
"-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif",
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
expect(fontFamilyPrint).toEqual({
|
|
60
|
-
type: "variable",
|
|
61
|
-
name: "font-family--print",
|
|
62
|
-
value: "'Georgia', 'Times New Roman', 'Times', serif",
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
expect(fontFamilyMono).toEqual({
|
|
66
|
-
type: "variable",
|
|
67
|
-
name: "font-family--mono",
|
|
68
|
-
value:
|
|
69
|
-
"'SFMono-Regular', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
|
|
70
|
-
});
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it("should add variables to root", () => {
|
|
74
|
-
const s = styleframe();
|
|
75
|
-
useFontFamily(s, {
|
|
76
|
-
default: "Arial, sans-serif",
|
|
77
|
-
mono: "Courier, monospace",
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
expect(s.root.variables).toHaveLength(2);
|
|
81
|
-
expect(s.root.variables[0]?.name).toBe("font-family");
|
|
82
|
-
expect(s.root.variables[1]?.name).toBe("font-family--mono");
|
|
83
|
-
});
|
|
84
|
-
|
|
85
|
-
it("should handle kebab-case font family names", () => {
|
|
86
|
-
const s = styleframe();
|
|
87
|
-
const { fontFamilySerifDisplay } = useFontFamily(s, {
|
|
88
|
-
"serif-display": "'Playfair Display', Georgia, serif",
|
|
89
|
-
});
|
|
90
|
-
|
|
91
|
-
expect(fontFamilySerifDisplay).toEqual({
|
|
92
|
-
type: "variable",
|
|
93
|
-
name: "font-family--serif-display",
|
|
94
|
-
value: "'Playfair Display', Georgia, serif",
|
|
95
|
-
});
|
|
96
|
-
});
|
|
97
|
-
|
|
98
|
-
it("should handle snake_case font family names", () => {
|
|
99
|
-
const s = styleframe();
|
|
100
|
-
const { fontFamilyHeadingPrimary } = useFontFamily(s, {
|
|
101
|
-
heading_primary: "'Inter', sans-serif",
|
|
102
|
-
});
|
|
103
|
-
|
|
104
|
-
expect(fontFamilyHeadingPrimary).toEqual({
|
|
105
|
-
type: "variable",
|
|
106
|
-
name: "font-family--heading_primary",
|
|
107
|
-
value: "'Inter', sans-serif",
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
it("should handle numeric font family names", () => {
|
|
112
|
-
const s = styleframe();
|
|
113
|
-
const { fontFamily100 } = useFontFamily(s, {
|
|
114
|
-
"100": "'Roboto', sans-serif",
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
expect(fontFamily100).toEqual({
|
|
118
|
-
type: "variable",
|
|
119
|
-
name: "font-family--100",
|
|
120
|
-
value: "'Roboto', sans-serif",
|
|
121
|
-
});
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
it("should handle single font family without fallback", () => {
|
|
125
|
-
const s = styleframe();
|
|
126
|
-
const { fontFamilyCustom } = useFontFamily(s, {
|
|
127
|
-
custom: "Arial",
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
expect(fontFamilyCustom).toEqual({
|
|
131
|
-
type: "variable",
|
|
132
|
-
name: "font-family--custom",
|
|
133
|
-
value: "Arial",
|
|
134
|
-
});
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
it("should handle complex font family stacks", () => {
|
|
138
|
-
const s = styleframe();
|
|
139
|
-
const { fontFamilySystem } = useFontFamily(s, {
|
|
140
|
-
system:
|
|
141
|
-
"system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'",
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
expect(fontFamilySystem.value).toBe(
|
|
145
|
-
"system-ui, -apple-system, 'Segoe UI', Roboto, 'Helvetica Neue', 'Noto Sans', 'Liberation Sans', Arial, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji', 'Segoe UI Symbol', 'Noto Color Emoji'",
|
|
146
|
-
);
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
it("should handle empty font family object", () => {
|
|
150
|
-
const s = styleframe();
|
|
151
|
-
const result = useFontFamily(s, {});
|
|
152
|
-
|
|
153
|
-
expect(result).toEqual({});
|
|
154
|
-
expect(s.root.variables).toHaveLength(0);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it("should handle font family references", () => {
|
|
158
|
-
const s = styleframe();
|
|
159
|
-
const baseFont = s.variable("base-font", "Arial, sans-serif");
|
|
160
|
-
const { fontFamily } = useFontFamily(s, {
|
|
161
|
-
default: s.ref(baseFont),
|
|
162
|
-
});
|
|
163
|
-
|
|
164
|
-
expect(fontFamily.value).toEqual({
|
|
165
|
-
type: "reference",
|
|
166
|
-
name: "base-font",
|
|
167
|
-
fallback: undefined,
|
|
168
|
-
});
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
it("should compile to correct CSS output using consume", () => {
|
|
172
|
-
const s = styleframe();
|
|
173
|
-
useFontFamily(s, {
|
|
174
|
-
default: "Arial, sans-serif",
|
|
175
|
-
mono: "Courier, monospace",
|
|
176
|
-
display: "'Playfair Display', Georgia, serif",
|
|
177
|
-
});
|
|
178
|
-
|
|
179
|
-
const css = consume(s.root, s.options);
|
|
180
|
-
|
|
181
|
-
expect(css).toBe(`:root {
|
|
182
|
-
--font-family: Arial, sans-serif;
|
|
183
|
-
--font-family--mono: Courier, monospace;
|
|
184
|
-
--font-family--display: 'Playfair Display', Georgia, serif;
|
|
185
|
-
}`);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
describe("type safety", () => {
|
|
189
|
-
it("should preserve exact font family names in return type", () => {
|
|
190
|
-
const s = styleframe();
|
|
191
|
-
const fonts = useFontFamily(s, {
|
|
192
|
-
default: "Arial, sans-serif",
|
|
193
|
-
mono: "Courier, monospace",
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
// Type assertions to verify the generic types are preserved
|
|
197
|
-
const defaultFont: Variable<"font-family"> = fonts.fontFamily;
|
|
198
|
-
const monoFont: Variable<"font-family--mono"> = fonts.fontFamilyMono;
|
|
199
|
-
|
|
200
|
-
expect(defaultFont.name).toBe("font-family");
|
|
201
|
-
expect(monoFont.name).toBe("font-family--mono");
|
|
202
|
-
});
|
|
203
|
-
|
|
204
|
-
it("should maintain type information for kebab-case names", () => {
|
|
205
|
-
const s = styleframe();
|
|
206
|
-
const { fontFamilySerifDisplay } = useFontFamily(s, {
|
|
207
|
-
"serif-display": "'Playfair Display', Georgia, serif",
|
|
208
|
-
});
|
|
209
|
-
|
|
210
|
-
const typed: Variable<"font-family--serif-display"> =
|
|
211
|
-
fontFamilySerifDisplay;
|
|
212
|
-
expect(typed.name).toBe("font-family--serif-display");
|
|
213
|
-
});
|
|
214
|
-
|
|
215
|
-
it("should work with const assertion", () => {
|
|
216
|
-
const s = styleframe();
|
|
217
|
-
const fontConfig = {
|
|
218
|
-
default: "Arial, sans-serif",
|
|
219
|
-
mono: "Courier, monospace",
|
|
220
|
-
} as const;
|
|
221
|
-
|
|
222
|
-
const fonts = useFontFamily(s, fontConfig);
|
|
223
|
-
|
|
224
|
-
expect(fonts.fontFamily.name).toBe("font-family");
|
|
225
|
-
expect(fonts.fontFamilyMono.name).toBe("font-family--mono");
|
|
226
|
-
});
|
|
227
|
-
});
|
|
228
|
-
});
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import { createUseVariable } from "../utils";
|
|
2
|
-
|
|
3
|
-
export const defaultFontFamilyValues = {
|
|
4
|
-
default: "@base",
|
|
5
|
-
base: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif",
|
|
6
|
-
print: "'Georgia', 'Times New Roman', 'Times', serif",
|
|
7
|
-
mono: "'SFMono-Regular', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Create a set of font family variables for use in a Styleframe instance.
|
|
12
|
-
*
|
|
13
|
-
* @usage
|
|
14
|
-
* ```typescript
|
|
15
|
-
* import { styleframe } from "styleframe";
|
|
16
|
-
* import { useFontFamily } from "styleframe/theme";
|
|
17
|
-
*
|
|
18
|
-
* const s = styleframe();
|
|
19
|
-
*
|
|
20
|
-
* const {
|
|
21
|
-
* fontFamily, // Variable<'font-family'>
|
|
22
|
-
* fontFamilyPrint, // Variable<'font-family--print'>
|
|
23
|
-
* fontFamilyMono, // Variable<'font-family--mono'>
|
|
24
|
-
* } = useFontFamily(s, {
|
|
25
|
-
* default: "-apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen-Sans, Ubuntu, Cantarell, 'Helvetica Neue', sans-serif",
|
|
26
|
-
* print: "'Georgia', 'Times New Roman', 'Times', serif",
|
|
27
|
-
* mono: "'SFMono-Regular', Menlo, Monaco, Consolas, 'Liberation Mono', 'Courier New', monospace",
|
|
28
|
-
* });
|
|
29
|
-
* ```
|
|
30
|
-
*/
|
|
31
|
-
export const useFontFamily = createUseVariable("font-family", {
|
|
32
|
-
defaults: defaultFontFamilyValues,
|
|
33
|
-
});
|