clava 0.4.2 → 0.6.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/CHANGELOG.md +85 -2
- package/README.md +78 -31
- package/dist/index.d.ts +193 -3
- package/dist/index.js +187 -115
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/index.ts +451 -214
- package/src/refine-warning.ts +2 -2
- package/src/types.ts +129 -2
- package/tests/component-api.test.ts +81 -55
- package/tests/extend.test.ts +44 -10
- package/tests/language-service.test.ts +12 -1
- package/tests/prototype-pollution.test.ts +3 -4
- package/tests/refine.test.ts +267 -369
- package/tests/variants-inference.test.ts +149 -0
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { describe, expectTypeOf, test } from "vitest";
|
|
2
2
|
import { cv } from "../src/index.ts";
|
|
3
3
|
|
|
4
|
+
const callback = (value: string) => value.toUpperCase();
|
|
5
|
+
|
|
4
6
|
describe("variants type inference", () => {
|
|
5
7
|
test("function variant infers parameter type as prop type", () => {
|
|
6
8
|
const button = cv({
|
|
@@ -18,6 +20,25 @@ describe("variants type inference", () => {
|
|
|
18
20
|
});
|
|
19
21
|
});
|
|
20
22
|
|
|
23
|
+
test("method variant infers optional parameter type as prop type", () => {
|
|
24
|
+
const grid = cv({
|
|
25
|
+
variants: {
|
|
26
|
+
columns(value?: number) {
|
|
27
|
+
return `columns-${value}`;
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
});
|
|
31
|
+
expectTypeOf(grid.getVariants()).branded.toEqualTypeOf<{
|
|
32
|
+
columns?: number;
|
|
33
|
+
}>();
|
|
34
|
+
grid({ columns: 3 });
|
|
35
|
+
grid({ columns: undefined });
|
|
36
|
+
grid({
|
|
37
|
+
// @ts-expect-error string is not assignable to number
|
|
38
|
+
columns: "3",
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
21
42
|
test("function variant infers union parameter type", () => {
|
|
22
43
|
const button = cv({
|
|
23
44
|
variants: {
|
|
@@ -173,6 +194,116 @@ describe("variants type inference", () => {
|
|
|
173
194
|
});
|
|
174
195
|
});
|
|
175
196
|
|
|
197
|
+
test("computed defaultVariants infer defaultValue and variants", () => {
|
|
198
|
+
cv({
|
|
199
|
+
variants: {
|
|
200
|
+
size: (value: number) => `s-${value}`,
|
|
201
|
+
color: { red: "r", blue: "b" },
|
|
202
|
+
},
|
|
203
|
+
defaultVariants: {
|
|
204
|
+
size: (defaultValue, variants) => {
|
|
205
|
+
expectTypeOf(defaultValue).toEqualTypeOf<number | undefined>();
|
|
206
|
+
expectTypeOf(variants.color).toEqualTypeOf<
|
|
207
|
+
"red" | "blue" | undefined
|
|
208
|
+
>();
|
|
209
|
+
return variants.color === "red" ? 10 : defaultValue;
|
|
210
|
+
},
|
|
211
|
+
},
|
|
212
|
+
});
|
|
213
|
+
cv({
|
|
214
|
+
variants: { size: (value: number) => `s-${value}` },
|
|
215
|
+
defaultVariants: {
|
|
216
|
+
// @ts-expect-error string is not assignable to number
|
|
217
|
+
size: () => "10",
|
|
218
|
+
},
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
test("computed defaultVariants method infers defaultValue and variants", () => {
|
|
223
|
+
cv({
|
|
224
|
+
variants: {
|
|
225
|
+
compact: { true: "compact", false: "" },
|
|
226
|
+
size(value?: number) {
|
|
227
|
+
return `s-${value}`;
|
|
228
|
+
},
|
|
229
|
+
},
|
|
230
|
+
defaultVariants: {
|
|
231
|
+
size(defaultValue, variants) {
|
|
232
|
+
expectTypeOf(defaultValue).toEqualTypeOf<number | undefined>();
|
|
233
|
+
expectTypeOf(variants.compact).toEqualTypeOf<boolean | undefined>();
|
|
234
|
+
return variants.compact ? 2 : defaultValue;
|
|
235
|
+
},
|
|
236
|
+
},
|
|
237
|
+
});
|
|
238
|
+
cv({
|
|
239
|
+
variants: {
|
|
240
|
+
size(value?: number) {
|
|
241
|
+
return `s-${value}`;
|
|
242
|
+
},
|
|
243
|
+
},
|
|
244
|
+
defaultVariants: {
|
|
245
|
+
// @ts-expect-error string is not assignable to number
|
|
246
|
+
size() {
|
|
247
|
+
return "10";
|
|
248
|
+
},
|
|
249
|
+
},
|
|
250
|
+
});
|
|
251
|
+
});
|
|
252
|
+
|
|
253
|
+
test("function-valued defaultVariants must return the function", () => {
|
|
254
|
+
cv({
|
|
255
|
+
variants: {
|
|
256
|
+
transform: (value: (value: string) => string) => value("a"),
|
|
257
|
+
},
|
|
258
|
+
defaultVariants: {
|
|
259
|
+
transform: () => callback,
|
|
260
|
+
},
|
|
261
|
+
});
|
|
262
|
+
cv({
|
|
263
|
+
variants: {
|
|
264
|
+
transform: (value: (value: string) => string) => value("a"),
|
|
265
|
+
},
|
|
266
|
+
defaultVariants: {
|
|
267
|
+
// @ts-expect-error function values must be returned from a computed default
|
|
268
|
+
transform: callback,
|
|
269
|
+
},
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
test("mixed function-valued defaultVariants must return the function", () => {
|
|
274
|
+
cv({
|
|
275
|
+
variants: {
|
|
276
|
+
transform: (value: ((value: string) => string) | "none") => {
|
|
277
|
+
return value === "none" ? "none" : value("a");
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
defaultVariants: {
|
|
281
|
+
transform: "none",
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
cv({
|
|
285
|
+
variants: {
|
|
286
|
+
transform: (value: ((value: string) => string) | "none") => {
|
|
287
|
+
return value === "none" ? "none" : value("a");
|
|
288
|
+
},
|
|
289
|
+
},
|
|
290
|
+
defaultVariants: {
|
|
291
|
+
transform: () => callback,
|
|
292
|
+
},
|
|
293
|
+
});
|
|
294
|
+
cv({
|
|
295
|
+
variants: {
|
|
296
|
+
transform: (value: ((value: string) => string) | "none") => {
|
|
297
|
+
return value === "none" ? "none" : value("a");
|
|
298
|
+
},
|
|
299
|
+
},
|
|
300
|
+
defaultVariants: {
|
|
301
|
+
// @ts-expect-error function values must be returned from a computed default
|
|
302
|
+
transform: callback,
|
|
303
|
+
},
|
|
304
|
+
});
|
|
305
|
+
});
|
|
306
|
+
|
|
176
307
|
test("refine callback sees function variant param type", () => {
|
|
177
308
|
cv({
|
|
178
309
|
variants: { size: (value: number) => `s-${value}` },
|
|
@@ -187,6 +318,24 @@ describe("variants type inference", () => {
|
|
|
187
318
|
});
|
|
188
319
|
});
|
|
189
320
|
|
|
321
|
+
test("refine method infers context from method variants", () => {
|
|
322
|
+
cv({
|
|
323
|
+
variants: {
|
|
324
|
+
size(value?: number) {
|
|
325
|
+
return `s-${value}`;
|
|
326
|
+
},
|
|
327
|
+
},
|
|
328
|
+
refine({ variants, setVariants }) {
|
|
329
|
+
expectTypeOf(variants.size).toEqualTypeOf<number | undefined>();
|
|
330
|
+
setVariants({ size: 10 });
|
|
331
|
+
setVariants({
|
|
332
|
+
// @ts-expect-error string not assignable to number
|
|
333
|
+
size: "10",
|
|
334
|
+
});
|
|
335
|
+
},
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
190
339
|
test("function variant return type accepts ClassValue and StyleClassValue", () => {
|
|
191
340
|
cv({
|
|
192
341
|
variants: {
|