@cyclone-ui/theme-builder 0.0.4 → 0.0.6
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 +18 -0
- package/dist/index.cjs +1 -1
- package/dist/preprocessor.cjs +1 -1
- package/dist/preprocessor.d.cts +25 -1
- package/dist/preprocessor.d.cts.map +1 -1
- package/dist/preprocessor.d.mts +24 -1
- package/dist/preprocessor.mjs +1 -1
- package/dist/preprocessor.mjs.map +1 -1
- package/package.json +1 -1
- package/src/preprocessor.ts +258 -238
- package/test/preprocessor.spec.ts +170 -191
- package/test/shiki-theme-mapping.spec.ts +26 -27
- package/test/storybook-theme-mapping.spec.ts +31 -29
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, it } from "vitest";
|
|
2
2
|
|
|
3
|
-
import { tamaguiPreprocessor } from "
|
|
3
|
+
import { tamaguiPreprocessor } from "../src/preprocessor";
|
|
4
4
|
|
|
5
5
|
const colorToken = (value: string) => ({
|
|
6
6
|
$type: "color",
|
|
@@ -56,41 +56,41 @@ const hueDistance = (first: number, second: number): number => {
|
|
|
56
56
|
};
|
|
57
57
|
|
|
58
58
|
describe("tamaguiPreprocessor", () => {
|
|
59
|
-
it("generates missing on
|
|
59
|
+
it("generates missing on-primary text colors for theme color groups", () => {
|
|
60
60
|
const result = tamaguiPreprocessor({
|
|
61
61
|
color: {
|
|
62
|
-
danger: colorToken("#336699"),
|
|
63
|
-
warning: colorToken("#ffee99")
|
|
62
|
+
danger: { primary: colorToken("#336699") },
|
|
63
|
+
warning: { primary: colorToken("#ffee99") }
|
|
64
64
|
}
|
|
65
65
|
}) as any;
|
|
66
66
|
|
|
67
|
-
expect(result.color["on-
|
|
67
|
+
expect(result.color.danger["on-primary"]).toMatchObject({
|
|
68
68
|
$value: "#FAFAFA",
|
|
69
|
-
$description:
|
|
69
|
+
$description:
|
|
70
|
+
"Generated text and icon color on danger primary backgrounds"
|
|
70
71
|
});
|
|
71
|
-
expect(result.color["on-
|
|
72
|
-
expect(result.color).not.toHaveProperty("on-danger");
|
|
72
|
+
expect(result.color.warning["on-primary"].$value).toBe("#151518");
|
|
73
73
|
});
|
|
74
74
|
|
|
75
|
-
it("generates missing
|
|
75
|
+
it("generates missing secondary backgrounds from the parent theme", () => {
|
|
76
76
|
const lightDanger = "#336699";
|
|
77
77
|
const darkDanger = "#99ccff";
|
|
78
78
|
const result = tamaguiPreprocessor({
|
|
79
79
|
light: {
|
|
80
80
|
color: {
|
|
81
81
|
$description: "The light theme colors",
|
|
82
|
-
danger: colorToken(lightDanger)
|
|
82
|
+
danger: { primary: colorToken(lightDanger) }
|
|
83
83
|
}
|
|
84
84
|
},
|
|
85
85
|
dark: {
|
|
86
86
|
color: {
|
|
87
87
|
$description: "The dark theme colors",
|
|
88
|
-
danger: colorToken(darkDanger)
|
|
88
|
+
danger: { primary: colorToken(darkDanger) }
|
|
89
89
|
}
|
|
90
90
|
}
|
|
91
91
|
}) as any;
|
|
92
|
-
const light = result.light.color
|
|
93
|
-
const dark = result.dark.color
|
|
92
|
+
const light = result.light.color.danger.secondary;
|
|
93
|
+
const dark = result.dark.color.danger.secondary;
|
|
94
94
|
|
|
95
95
|
expect(light.$description).toBe(
|
|
96
96
|
"Generated low-emphasis danger background for the light theme"
|
|
@@ -105,29 +105,34 @@ describe("tamaguiPreprocessor", () => {
|
|
|
105
105
|
relativeLuminance(darkDanger)
|
|
106
106
|
);
|
|
107
107
|
expect(
|
|
108
|
-
contrastRatio(
|
|
109
|
-
|
|
108
|
+
contrastRatio(
|
|
109
|
+
light.$value,
|
|
110
|
+
result.light.color.danger["on-secondary"].$value
|
|
111
|
+
)
|
|
112
|
+
).toBeGreaterThanOrEqual(7.25);
|
|
110
113
|
});
|
|
111
114
|
|
|
112
|
-
it("preserves explicit
|
|
115
|
+
it("preserves explicit companions and skips root colors", () => {
|
|
113
116
|
const result = tamaguiPreprocessor({
|
|
114
117
|
color: {
|
|
115
118
|
$description: "The light theme colors",
|
|
116
|
-
|
|
117
|
-
info:
|
|
118
|
-
|
|
119
|
-
|
|
119
|
+
emphasis: colorToken("#336699"),
|
|
120
|
+
info: {
|
|
121
|
+
primary: colorToken("#336699"),
|
|
122
|
+
"on-primary": colorToken("#f0f0f0"),
|
|
123
|
+
secondary: colorToken("#abcdef")
|
|
124
|
+
}
|
|
120
125
|
}
|
|
121
126
|
}) as any;
|
|
122
127
|
|
|
123
|
-
expect(result.color["on-
|
|
128
|
+
expect(result.color.info["on-primary"]).toMatchObject({
|
|
124
129
|
$value: "#f0f0f0",
|
|
125
130
|
theme: "info"
|
|
126
131
|
});
|
|
127
|
-
expect(result.color).
|
|
128
|
-
expect(result.color["
|
|
129
|
-
expect(result.color).not.toHaveProperty("on-
|
|
130
|
-
expect(result.color).not.toHaveProperty("
|
|
132
|
+
expect(result.color.info.secondary.$value).toBe("#abcdef");
|
|
133
|
+
expect(result.color.info["on-secondary"].$value).toBe("#151518");
|
|
134
|
+
expect(result.color).not.toHaveProperty("on-emphasis");
|
|
135
|
+
expect(result.color).not.toHaveProperty("emphasis-active");
|
|
131
136
|
});
|
|
132
137
|
|
|
133
138
|
it("preserves the status hue when generated colors require gamut mapping", () => {
|
|
@@ -136,46 +141,48 @@ describe("tamaguiPreprocessor", () => {
|
|
|
136
141
|
light: {
|
|
137
142
|
color: {
|
|
138
143
|
$description: "The light theme colors",
|
|
139
|
-
danger: colorToken(danger)
|
|
144
|
+
danger: { primary: colorToken(danger) }
|
|
140
145
|
}
|
|
141
146
|
},
|
|
142
147
|
dark: {
|
|
143
148
|
color: {
|
|
144
149
|
$description: "The dark theme colors",
|
|
145
|
-
danger: colorToken(danger)
|
|
150
|
+
danger: { primary: colorToken(danger) }
|
|
146
151
|
}
|
|
147
152
|
}
|
|
148
153
|
}) as any;
|
|
149
154
|
|
|
150
155
|
for (const color of [
|
|
151
|
-
result.light.color
|
|
152
|
-
result.dark.color
|
|
156
|
+
result.light.color.danger.secondary.$value,
|
|
157
|
+
result.dark.color.danger.secondary.$value
|
|
153
158
|
]) {
|
|
154
159
|
expect(
|
|
155
160
|
hueDistance(oklchHue(color), oklchHue(danger))
|
|
156
|
-
).toBeLessThanOrEqual(1);
|
|
161
|
+
).toBeLessThanOrEqual(1.5);
|
|
157
162
|
}
|
|
158
163
|
});
|
|
159
164
|
|
|
160
|
-
it("resolves
|
|
165
|
+
it("resolves primary references before generating companions", () => {
|
|
161
166
|
const result = tamaguiPreprocessor({
|
|
162
167
|
palette: { red: colorToken("#336699") },
|
|
163
168
|
light: {
|
|
164
169
|
color: {
|
|
165
170
|
$description: "The light theme colors",
|
|
166
|
-
danger: colorToken("{palette.red}")
|
|
171
|
+
danger: { primary: colorToken("{palette.red}") }
|
|
167
172
|
}
|
|
168
173
|
}
|
|
169
174
|
}) as any;
|
|
170
175
|
|
|
171
|
-
expect(result.light.color["on-
|
|
172
|
-
expect(result.light.color
|
|
176
|
+
expect(result.light.color.danger["on-primary"].$value).toBe("#FAFAFA");
|
|
177
|
+
expect(result.light.color.danger.secondary.$value).toMatch(
|
|
178
|
+
/^#[0-9a-f]{6}$/
|
|
179
|
+
);
|
|
173
180
|
});
|
|
174
181
|
|
|
175
182
|
it("derives low-saturation states from the contrast primitive and scales saturated colors", () => {
|
|
176
183
|
const color = {
|
|
177
|
-
primary: colorToken("#777777"),
|
|
178
|
-
danger: colorToken("#336699")
|
|
184
|
+
base: { primary: colorToken("#777777") },
|
|
185
|
+
danger: { primary: colorToken("#336699") }
|
|
179
186
|
};
|
|
180
187
|
const result = tamaguiPreprocessor({
|
|
181
188
|
dark: { color: { $description: "The dark theme colors", ...color } },
|
|
@@ -185,169 +192,155 @@ describe("tamaguiPreprocessor", () => {
|
|
|
185
192
|
const light = result.light.color;
|
|
186
193
|
|
|
187
194
|
expect({
|
|
188
|
-
darkActive: dark["
|
|
189
|
-
lightActive: light["
|
|
190
|
-
darkActiveDescription: dark["
|
|
191
|
-
darkInactive: dark["
|
|
192
|
-
darkDanger: dark["
|
|
193
|
-
lightDanger: light["
|
|
194
|
-
dangerInactive: dark["
|
|
195
|
+
darkActive: dark.base["primary-active"].$value,
|
|
196
|
+
lightActive: light.base["primary-active"].$value,
|
|
197
|
+
darkActiveDescription: dark.base["primary-active"].$description,
|
|
198
|
+
darkInactive: dark.base["primary-inactive"].$description,
|
|
199
|
+
darkDanger: dark.danger["primary-active"].$description,
|
|
200
|
+
lightDanger: light.danger["primary-active"].$description,
|
|
201
|
+
dangerInactive: dark.danger["primary-inactive"].$description
|
|
195
202
|
}).toEqual({
|
|
196
203
|
darkActive: "#ffffff",
|
|
197
204
|
lightActive: "#0c0c0d",
|
|
198
205
|
darkActiveDescription: "active state at dark contrast primitive",
|
|
199
206
|
darkInactive: "inactive state at 40% darker",
|
|
200
|
-
darkDanger: "active state at
|
|
201
|
-
lightDanger: "active state at
|
|
207
|
+
darkDanger: "active state at 25% brighter",
|
|
208
|
+
lightDanger: "active state at 25% darker",
|
|
202
209
|
dangerInactive: "inactive state at 20% darker"
|
|
203
210
|
});
|
|
204
211
|
});
|
|
205
212
|
|
|
206
|
-
it("shifts
|
|
213
|
+
it("shifts hovered colors near the contrast primitive toward the middle", () => {
|
|
207
214
|
const result = tamaguiPreprocessor({
|
|
208
215
|
dark: {
|
|
209
216
|
color: {
|
|
210
217
|
$description: "The dark theme colors",
|
|
211
|
-
primary: colorToken("#f1f1f1")
|
|
218
|
+
base: { primary: colorToken("#f1f1f1") }
|
|
212
219
|
}
|
|
213
220
|
},
|
|
214
221
|
light: {
|
|
215
222
|
color: {
|
|
216
223
|
$description: "The light theme colors",
|
|
217
|
-
primary: colorToken("#1f1f21")
|
|
224
|
+
base: { primary: colorToken("#1f1f21") }
|
|
218
225
|
}
|
|
219
226
|
}
|
|
220
227
|
}) as any;
|
|
228
|
+
const dark = result.dark.color.base;
|
|
229
|
+
const light = result.light.color.base;
|
|
221
230
|
|
|
222
231
|
expect({
|
|
223
|
-
|
|
224
|
-
|
|
232
|
+
darkHovered: dark["primary-hovered"].$description,
|
|
233
|
+
lightHovered: light["primary-hovered"].$description,
|
|
234
|
+
darkActive: dark["primary-active"].$value,
|
|
235
|
+
lightActive: light["primary-active"].$value
|
|
225
236
|
}).toEqual({
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
relativeLuminance(result.dark.color["base-active"].$value)
|
|
231
|
-
).toBeLessThan(relativeLuminance("#f1f1f1"));
|
|
232
|
-
expect(
|
|
233
|
-
relativeLuminance(result.light.color["base-active"].$value)
|
|
234
|
-
).toBeGreaterThan(relativeLuminance("#1f1f21"));
|
|
235
|
-
});
|
|
236
|
-
|
|
237
|
-
it("keeps low-saturation surface states subtler than other neutral colors", () => {
|
|
238
|
-
const result = tamaguiPreprocessor({
|
|
239
|
-
color: {
|
|
240
|
-
$description: "The dark theme colors",
|
|
241
|
-
primary: colorToken("#333333"),
|
|
242
|
-
surface: { canvas: colorToken("#333333") }
|
|
243
|
-
}
|
|
244
|
-
}) as any;
|
|
245
|
-
|
|
246
|
-
expect({
|
|
247
|
-
primaryActive: result.color["base-active"].$value,
|
|
248
|
-
canvasActive: result.color.surface["canvas-active"].$description,
|
|
249
|
-
canvasInactive: result.color.surface["canvas-inactive"].$description
|
|
250
|
-
}).toEqual({
|
|
251
|
-
primaryActive: "#ffffff",
|
|
252
|
-
canvasActive: "active state at 10% brighter",
|
|
253
|
-
canvasInactive: "inactive state at 20% darker"
|
|
237
|
+
darkHovered: "hovered state at 25% darker",
|
|
238
|
+
lightHovered: "hovered state at 25% lighter",
|
|
239
|
+
darkActive: "#ffffff",
|
|
240
|
+
lightActive: "#000000"
|
|
254
241
|
});
|
|
242
|
+
expect(relativeLuminance(dark["primary-hovered"].$value)).toBeLessThan(
|
|
243
|
+
relativeLuminance("#f1f1f1")
|
|
244
|
+
);
|
|
245
|
+
expect(relativeLuminance(light["primary-hovered"].$value)).toBeGreaterThan(
|
|
246
|
+
relativeLuminance("#1f1f21")
|
|
247
|
+
);
|
|
255
248
|
});
|
|
256
249
|
|
|
257
|
-
it("increases
|
|
250
|
+
it("increases hairline active strength", () => {
|
|
258
251
|
const result = tamaguiPreprocessor({
|
|
259
|
-
color: {
|
|
260
|
-
outline: colorToken("#333333")
|
|
261
|
-
}
|
|
252
|
+
color: { hairline: colorToken("#333333") }
|
|
262
253
|
}) as any;
|
|
263
254
|
const saturated = tamaguiPreprocessor({
|
|
264
|
-
color: {
|
|
255
|
+
color: { hairline: colorToken("#336699") }
|
|
265
256
|
}) as any;
|
|
266
257
|
|
|
267
258
|
expect({
|
|
268
|
-
|
|
269
|
-
|
|
259
|
+
hairline: result.color["hairline-active"].$description,
|
|
260
|
+
hairlineSaturated: saturated.color["hairline-active"].$description
|
|
270
261
|
}).toEqual({
|
|
271
|
-
|
|
272
|
-
|
|
262
|
+
hairline: "active state at 80% brighter",
|
|
263
|
+
hairlineSaturated: "active state at 40% brighter"
|
|
273
264
|
});
|
|
265
|
+
expect(result.color["hairline-active"].group).toBe("hairline");
|
|
274
266
|
});
|
|
275
267
|
|
|
276
|
-
it("generates active, inactive, and disabled states only for target colors", () => {
|
|
268
|
+
it("generates hovered, active, inactive, and disabled states only for target colors", () => {
|
|
277
269
|
const result = tamaguiPreprocessor({
|
|
278
270
|
color: {
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
271
|
+
sunken: { ...colorToken("#111111"), group: "background" },
|
|
272
|
+
canvas: { ...colorToken("#222222"), group: "background" },
|
|
273
|
+
emphasis: { ...colorToken("#f5f5f5"), group: "foreground" },
|
|
274
|
+
ink: { ...colorToken("#777777"), group: "foreground" },
|
|
275
|
+
subtle: { ...colorToken("#777777"), group: "foreground" },
|
|
276
|
+
subtlest: colorToken("#777777"),
|
|
277
|
+
hairline: colorToken("#777777"),
|
|
278
|
+
base: {
|
|
279
|
+
primary: colorToken("#f5f5f5"),
|
|
280
|
+
secondary: colorToken("#777777")
|
|
281
|
+
},
|
|
282
|
+
danger: {
|
|
283
|
+
primary: colorToken("#ff0000"),
|
|
284
|
+
"on-primary": colorToken("#ffffff"),
|
|
285
|
+
secondary: colorToken("#330000")
|
|
282
286
|
},
|
|
283
|
-
primary: colorToken("#f5f5f5"),
|
|
284
|
-
"on-primary": colorToken("#111111"),
|
|
285
|
-
secondary: colorToken("#777777"),
|
|
286
|
-
tertiary: colorToken("#777777"),
|
|
287
|
-
outline: colorToken("#777777"),
|
|
288
|
-
danger: colorToken("#ff0000"),
|
|
289
|
-
"on-danger": colorToken("#ffffff"),
|
|
290
|
-
"danger-muted": colorToken("#330000"),
|
|
291
287
|
backdrop: colorToken("#00000066"),
|
|
292
288
|
data: { red: { emphasis: colorToken("#555555") } }
|
|
293
289
|
}
|
|
294
290
|
}) as any;
|
|
291
|
+
const states = ["hovered", "active", "inactive", "disabled"];
|
|
295
292
|
|
|
296
|
-
|
|
297
|
-
"
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
"
|
|
303
|
-
"
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
293
|
+
for (const group of [result.color.base, result.color.danger]) {
|
|
294
|
+
for (const key of ["primary", "secondary"]) {
|
|
295
|
+
for (const state of states) {
|
|
296
|
+
expect(group).toHaveProperty(`${key}-${state}`);
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
expect(group).not.toHaveProperty("on-primary-active");
|
|
300
|
+
expect(group).not.toHaveProperty("on-secondary-active");
|
|
301
|
+
}
|
|
302
|
+
for (const state of states) {
|
|
303
|
+
for (const key of [
|
|
304
|
+
"hairline",
|
|
305
|
+
"emphasis",
|
|
306
|
+
"ink",
|
|
307
|
+
"subtle",
|
|
308
|
+
"sunken",
|
|
309
|
+
"canvas"
|
|
310
|
+
]) {
|
|
314
311
|
expect(result.color).toHaveProperty(`${key}-${state}`);
|
|
315
312
|
}
|
|
316
|
-
expect(result.color).not.toHaveProperty(`${key}-hover`);
|
|
317
313
|
}
|
|
314
|
+
expect(result.color["ink-active"].group).toBe("foreground");
|
|
318
315
|
|
|
319
|
-
for (const key of ["
|
|
316
|
+
for (const key of ["subtlest", "backdrop"]) {
|
|
320
317
|
expect(result.color).toHaveProperty(key);
|
|
321
318
|
expect(result.color).not.toHaveProperty(`${key}-active`);
|
|
322
319
|
}
|
|
323
|
-
expect(result.color).not.toHaveProperty("base-accent-active");
|
|
324
|
-
expect(result.color).not.toHaveProperty("on-base-accent-active");
|
|
325
|
-
expect(result.color).not.toHaveProperty("on-danger-active");
|
|
326
|
-
expect(result.color).not.toHaveProperty("backdrop-active");
|
|
327
320
|
expect(result.color.data.red).not.toHaveProperty("emphasis-active");
|
|
328
321
|
});
|
|
329
322
|
|
|
330
323
|
it("does not overwrite explicit state colors", () => {
|
|
331
324
|
const result = tamaguiPreprocessor({
|
|
332
325
|
color: {
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
326
|
+
hairline: colorToken("#336699"),
|
|
327
|
+
"hairline-active": colorToken("#fedcba"),
|
|
328
|
+
danger: {
|
|
329
|
+
primary: colorToken("#336699"),
|
|
330
|
+
"primary-active": colorToken("#abcdef")
|
|
331
|
+
}
|
|
339
332
|
}
|
|
340
333
|
}) as any;
|
|
341
334
|
|
|
342
|
-
expect(result.color
|
|
343
|
-
expect(result.color["
|
|
335
|
+
expect(result.color["hairline-active"].$value).toBe("#fedcba");
|
|
336
|
+
expect(result.color.danger["primary-active"].$value).toBe("#abcdef");
|
|
344
337
|
});
|
|
345
338
|
|
|
346
|
-
it("
|
|
339
|
+
it("skips theme color groups whose primary is not a color", () => {
|
|
347
340
|
const result = tamaguiPreprocessor({
|
|
348
341
|
color: {
|
|
349
|
-
|
|
350
|
-
|
|
342
|
+
danger: {
|
|
343
|
+
primary: {
|
|
351
344
|
$type: "shadow",
|
|
352
345
|
$value: { color: "#336699", offsetX: 0 }
|
|
353
346
|
}
|
|
@@ -355,88 +348,74 @@ describe("tamaguiPreprocessor", () => {
|
|
|
355
348
|
}
|
|
356
349
|
}) as any;
|
|
357
350
|
|
|
358
|
-
expect(result.color.
|
|
359
|
-
expect(result.color.
|
|
351
|
+
expect(result.color.danger).not.toHaveProperty("primary-active");
|
|
352
|
+
expect(result.color.danger).not.toHaveProperty("on-primary");
|
|
353
|
+
expect(result.color.danger.primary.$value.color).toBe("#336699");
|
|
360
354
|
});
|
|
361
355
|
|
|
362
356
|
it("desaturates colored disabled variants and fades them over the disabled base", () => {
|
|
363
357
|
const result = tamaguiPreprocessor({
|
|
364
|
-
color: { danger: colorToken("#ff000080") }
|
|
358
|
+
color: { danger: { primary: colorToken("#ff000080") } }
|
|
365
359
|
}) as any;
|
|
366
360
|
|
|
367
|
-
expect(result.color["
|
|
361
|
+
expect(result.color.danger["primary-disabled"]).toMatchObject({
|
|
368
362
|
$description:
|
|
369
|
-
"disabled state at 85% saturation,
|
|
363
|
+
"disabled state at 85% saturation, 35% over oklch(0.3839 0.0045 286.26)",
|
|
370
364
|
$value: expect.stringMatching(/^#[0-9a-f]{6}$/)
|
|
371
365
|
});
|
|
372
366
|
});
|
|
373
367
|
|
|
374
|
-
it("
|
|
375
|
-
const result = tamaguiPreprocessor({
|
|
376
|
-
color: { surface: { canvas: colorToken("#ffffff") } }
|
|
377
|
-
}) as any;
|
|
378
|
-
|
|
379
|
-
expect(result.color.surface["canvas-disabled"]).toMatchObject({
|
|
380
|
-
$description: "disabled state at 13% over oklch(0.3839 0.0045 286.26)",
|
|
381
|
-
$value: "#5b5b5d"
|
|
382
|
-
});
|
|
383
|
-
});
|
|
384
|
-
|
|
385
|
-
it("assigns themes to base aliases and status colors", () => {
|
|
368
|
+
it("assigns the group name as theme and group to theme color tokens", () => {
|
|
386
369
|
const result = tamaguiPreprocessor({
|
|
387
370
|
color: {
|
|
388
371
|
$description: "The dark theme colors",
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
372
|
+
emphasis: colorToken("#eeeeee"),
|
|
373
|
+
hairline: colorToken("#777777"),
|
|
374
|
+
base: {
|
|
375
|
+
primary: colorToken("#eeeeee"),
|
|
376
|
+
"on-primary": colorToken("#111111"),
|
|
377
|
+
secondary: { ...colorToken("#444444"), theme: "custom" }
|
|
378
|
+
},
|
|
379
|
+
warning: { primary: colorToken("#ffee99") }
|
|
394
380
|
}
|
|
395
381
|
}) as any;
|
|
382
|
+
const { base, warning } = result.color;
|
|
396
383
|
|
|
397
|
-
expect(result.color.
|
|
398
|
-
expect(result.color
|
|
399
|
-
expect(
|
|
384
|
+
expect(result.color.emphasis.theme).toBeUndefined();
|
|
385
|
+
expect(result.color.hairline.theme).toBeUndefined();
|
|
386
|
+
expect(base.primary).toMatchObject({
|
|
400
387
|
$value: "#eeeeee",
|
|
401
388
|
theme: "base",
|
|
402
389
|
group: "base"
|
|
403
390
|
});
|
|
404
|
-
expect(
|
|
405
|
-
$value: "{color.base}",
|
|
406
|
-
theme: "base"
|
|
407
|
-
});
|
|
408
|
-
expect(result.color["base-active"].theme).toBe("base");
|
|
409
|
-
expect(result.color).not.toHaveProperty("on-base");
|
|
410
|
-
expect(result.color["on-base-accent"]).toMatchObject({
|
|
391
|
+
expect(base["on-primary"]).toMatchObject({
|
|
411
392
|
$value: "#111111",
|
|
412
393
|
theme: "base"
|
|
413
394
|
});
|
|
414
|
-
expect(
|
|
415
|
-
expect(
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
expect(result.color["warning-muted-active"].theme).toBe("warning");
|
|
430
|
-
expect(result.color["warning-inactive"].theme).toBe("warning");
|
|
395
|
+
expect(base["primary-active"].theme).toBe("base");
|
|
396
|
+
expect(base.secondary.theme).toBe("custom");
|
|
397
|
+
for (const key of [
|
|
398
|
+
"primary",
|
|
399
|
+
"on-primary",
|
|
400
|
+
"secondary",
|
|
401
|
+
"on-secondary",
|
|
402
|
+
"secondary-active",
|
|
403
|
+
"primary-inactive"
|
|
404
|
+
]) {
|
|
405
|
+
expect(warning[key]).toMatchObject({
|
|
406
|
+
theme: "warning",
|
|
407
|
+
group: "warning"
|
|
408
|
+
});
|
|
409
|
+
}
|
|
431
410
|
});
|
|
432
411
|
|
|
433
|
-
it("generates focus rings for
|
|
412
|
+
it("generates focus rings for theme color groups", () => {
|
|
434
413
|
const result = tamaguiPreprocessor({
|
|
435
414
|
color: {
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
danger: colorToken("#336699")
|
|
415
|
+
elevated: { ...colorToken("#222222"), group: "background" },
|
|
416
|
+
emphasis: colorToken("#eeeeee"),
|
|
417
|
+
base: { primary: colorToken("#eeeeee") },
|
|
418
|
+
danger: { primary: colorToken("#336699") }
|
|
440
419
|
}
|
|
441
420
|
}) as any;
|
|
442
421
|
|
|
@@ -453,12 +432,12 @@ describe("tamaguiPreprocessor", () => {
|
|
|
453
432
|
expect(result.ring["base-offset"]).toMatchObject({ theme: "base" });
|
|
454
433
|
expect(result.ring.base).toMatchObject({
|
|
455
434
|
theme: "base",
|
|
456
|
-
$value: [{ color: "#
|
|
435
|
+
$value: [{ color: "#eeeeee1a", spread: { value: 3, unit: "px" } }]
|
|
457
436
|
});
|
|
458
437
|
expect(result.ring["danger-offset"]).toMatchObject({
|
|
459
438
|
theme: "danger",
|
|
460
439
|
$value: [
|
|
461
|
-
{ color: "{color.
|
|
440
|
+
{ color: "{color.elevated}" },
|
|
462
441
|
{ color: "#33669926", spread: { value: 6, unit: "px" } }
|
|
463
442
|
]
|
|
464
443
|
});
|
|
@@ -503,7 +482,7 @@ describe("tamaguiPreprocessor", () => {
|
|
|
503
482
|
expect(result).toMatchObject({
|
|
504
483
|
semantic: {
|
|
505
484
|
ring: {
|
|
506
|
-
neutral: { $value: { color: "#
|
|
485
|
+
neutral: { $value: { color: "#7777771a" } },
|
|
507
486
|
saturated: { $value: { color: "#33669926" } },
|
|
508
487
|
layered: {
|
|
509
488
|
$value: [{ color: "#ff0000" }, { color: "#00ff0026" }]
|
|
@@ -62,24 +62,23 @@ const color = ($value: string): Token => ({ $value });
|
|
|
62
62
|
|
|
63
63
|
const semanticColors = (prefix: string) => ({
|
|
64
64
|
color: {
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
65
|
+
emphasis: color(`${prefix}-emphasis`),
|
|
66
|
+
ink: color(`${prefix}-ink`),
|
|
67
|
+
subtle: color(`${prefix}-subtle`),
|
|
68
|
+
subtlest: color(`${prefix}-subtlest`),
|
|
69
|
+
outline: color(`${prefix}-outline`),
|
|
70
|
+
hairline: color(`${prefix}-hairline`),
|
|
71
|
+
canvas: color(`${prefix}-canvas`),
|
|
72
|
+
sunken: color(`${prefix}-sunken`),
|
|
73
|
+
danger: { primary: color(`${prefix}-danger`) },
|
|
74
|
+
warning: { primary: color(`${prefix}-warning`) },
|
|
75
|
+
success: { primary: color(`${prefix}-success`) },
|
|
76
|
+
info: { primary: color(`${prefix}-info`) },
|
|
77
|
+
discovery: { primary: color(`${prefix}-discovery`) }
|
|
78
|
+
} as Record<string, unknown>
|
|
77
79
|
});
|
|
78
80
|
|
|
79
|
-
const setting = (
|
|
80
|
-
theme: MappedTheme,
|
|
81
|
-
scope: string
|
|
82
|
-
) =>
|
|
81
|
+
const setting = (theme: MappedTheme, scope: string) =>
|
|
83
82
|
theme.settings.find(candidate => candidate.scope.includes(scope))?.settings
|
|
84
83
|
.foreground;
|
|
85
84
|
|
|
@@ -107,17 +106,17 @@ describe("Shiki theme mapping", () => {
|
|
|
107
106
|
tokens: semanticColors("light")
|
|
108
107
|
}) as MappedTheme;
|
|
109
108
|
|
|
110
|
-
expect(dark.fg).toBe("dark-
|
|
109
|
+
expect(dark.fg).toBe("dark-emphasis");
|
|
111
110
|
expect(dark.colors).toMatchObject({
|
|
112
|
-
"editor.background": "dark-
|
|
111
|
+
"editor.background": "dark-canvas",
|
|
113
112
|
"editorCursor.foreground": "dark-info",
|
|
114
|
-
"editor.selectionBackground": "dark-
|
|
115
|
-
"editor.selectionForeground": "dark-
|
|
116
|
-
"editor.inactiveSelectionBackground": "dark-
|
|
117
|
-
"editorIndentGuide.background1": "dark-
|
|
118
|
-
"editorIndentGuide.activeBackground1": "dark-
|
|
113
|
+
"editor.selectionBackground": "dark-emphasis",
|
|
114
|
+
"editor.selectionForeground": "dark-canvas",
|
|
115
|
+
"editor.inactiveSelectionBackground": "dark-sunken",
|
|
116
|
+
"editorIndentGuide.background1": "dark-hairline",
|
|
117
|
+
"editorIndentGuide.activeBackground1": "dark-subtle"
|
|
119
118
|
});
|
|
120
|
-
expect(setting(dark, "comment")).toBe("dark-
|
|
119
|
+
expect(setting(dark, "comment")).toBe("dark-subtle");
|
|
121
120
|
expect(setting(dark, "string")).toBe("dark-success");
|
|
122
121
|
expect(setting(dark, "constant")).toBe("dark-warning");
|
|
123
122
|
expect(setting(dark, "keyword")).toBe("dark-info");
|
|
@@ -126,8 +125,8 @@ describe("Shiki theme mapping", () => {
|
|
|
126
125
|
expect(setting(dark, "entity.other.attribute-name")).toBe("dark-info");
|
|
127
126
|
expect(setting(dark, "invalid")).toBe("dark-danger");
|
|
128
127
|
|
|
129
|
-
expect(light.fg).toBe("light-
|
|
130
|
-
expect(light.colors["editor.background"]).toBe("light-
|
|
128
|
+
expect(light.fg).toBe("light-emphasis");
|
|
129
|
+
expect(light.colors["editor.background"]).toBe("light-canvas");
|
|
131
130
|
expect(setting(light, "string")).toBe("light-success");
|
|
132
131
|
});
|
|
133
132
|
|
|
@@ -144,7 +143,7 @@ describe("Shiki theme mapping", () => {
|
|
|
144
143
|
);
|
|
145
144
|
const tokens = semanticColors("light");
|
|
146
145
|
|
|
147
|
-
tokens.color.
|
|
146
|
+
tokens.color.subtle = color("{color.neutral.7}");
|
|
148
147
|
Object.assign(tokens.color, {
|
|
149
148
|
neutral: { 7: color("#959698") }
|
|
150
149
|
});
|