clava 0.1.18 → 0.2.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 +39 -0
- package/dist/index.d.ts +14 -21
- package/dist/index.js +49 -21
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +79 -53
- package/src/types.ts +20 -13
- package/tests/_utils.ts +176 -0
- package/tests/class-style-test.ts +341 -0
- package/tests/component-api-test.ts +214 -0
- package/tests/computed-test.ts +800 -0
- package/tests/computed-variants-test.ts +298 -0
- package/tests/extend-test.ts +253 -0
- package/tests/language-service-test.ts +178 -0
- package/{src/test-react.ts → tests/react-test.ts} +3 -3
- package/{src/test-solid.ts → tests/solid-test.ts} +3 -5
- package/tests/split-props-test.ts +590 -0
- package/tests/variants-test.ts +380 -0
- package/tsconfig.json +1 -1
- package/src/test.ts +0 -2873
|
@@ -0,0 +1,590 @@
|
|
|
1
|
+
import { describe, expect, expectTypeOf, test } from "vitest";
|
|
2
|
+
import { splitProps } from "../src/index.ts";
|
|
3
|
+
import {
|
|
4
|
+
CONFIGS,
|
|
5
|
+
type HTMLProperties,
|
|
6
|
+
createCVFromConfig,
|
|
7
|
+
getClassPropertyName,
|
|
8
|
+
getConfigDescription,
|
|
9
|
+
getConfigMode,
|
|
10
|
+
getModeComponent,
|
|
11
|
+
} from "./_utils.ts";
|
|
12
|
+
|
|
13
|
+
for (const config of Object.values(CONFIGS)) {
|
|
14
|
+
const mode = getConfigMode(config);
|
|
15
|
+
const cv = createCVFromConfig(config);
|
|
16
|
+
|
|
17
|
+
describe(getConfigDescription(config), () => {
|
|
18
|
+
test("splitProps separates variant props", () => {
|
|
19
|
+
const component = getModeComponent(
|
|
20
|
+
mode,
|
|
21
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
22
|
+
);
|
|
23
|
+
const classNameProp = getClassPropertyName(config);
|
|
24
|
+
const props: HTMLProperties<typeof component> = {
|
|
25
|
+
id: "test",
|
|
26
|
+
size: "lg",
|
|
27
|
+
style: { color: "red" },
|
|
28
|
+
[classNameProp]: "extra",
|
|
29
|
+
};
|
|
30
|
+
const [variantProps, otherProps] = splitProps(props, component);
|
|
31
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<
|
|
32
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
33
|
+
>();
|
|
34
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
35
|
+
expect(variantProps).toEqual({
|
|
36
|
+
size: "lg",
|
|
37
|
+
style: { color: "red" },
|
|
38
|
+
[classNameProp]: "extra",
|
|
39
|
+
});
|
|
40
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
test("variantKeys splitProps", () => {
|
|
44
|
+
const component = getModeComponent(
|
|
45
|
+
mode,
|
|
46
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
47
|
+
);
|
|
48
|
+
const classNameProp = getClassPropertyName(config);
|
|
49
|
+
const props: HTMLProperties<typeof component> = {
|
|
50
|
+
size: "lg",
|
|
51
|
+
id: "test",
|
|
52
|
+
style: "color: red;",
|
|
53
|
+
[classNameProp]: "extra",
|
|
54
|
+
};
|
|
55
|
+
const [variantProps, otherProps] = splitProps(
|
|
56
|
+
props,
|
|
57
|
+
component.variantKeys,
|
|
58
|
+
);
|
|
59
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<{
|
|
60
|
+
size?: "sm" | "lg";
|
|
61
|
+
}>();
|
|
62
|
+
expectTypeOf(otherProps).toEqualTypeOf<
|
|
63
|
+
Pick<typeof props, "id" | "style" | "class" | "className">
|
|
64
|
+
>();
|
|
65
|
+
expect(variantProps).toEqual({ size: "lg" });
|
|
66
|
+
expect(otherProps).toEqual({
|
|
67
|
+
id: "test",
|
|
68
|
+
style: "color: red;",
|
|
69
|
+
[classNameProp]: "extra",
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("splitProps does not include defaultVariants", () => {
|
|
74
|
+
const component = getModeComponent(
|
|
75
|
+
mode,
|
|
76
|
+
cv({
|
|
77
|
+
variants: { size: { sm: "sm", lg: "lg" }, color: { red: "red" } },
|
|
78
|
+
defaultVariants: { size: "sm", color: "red" },
|
|
79
|
+
}),
|
|
80
|
+
);
|
|
81
|
+
const props: HTMLProperties<typeof component> = {
|
|
82
|
+
id: "test",
|
|
83
|
+
size: "lg",
|
|
84
|
+
};
|
|
85
|
+
const [variantProps, otherProps] = splitProps(props, component);
|
|
86
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<
|
|
87
|
+
Pick<typeof props, "size" | "color" | "style" | "class" | "className">
|
|
88
|
+
>();
|
|
89
|
+
expect(variantProps).toEqual({
|
|
90
|
+
size: "lg",
|
|
91
|
+
});
|
|
92
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
93
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test("splitProps with key array as second parameter", () => {
|
|
97
|
+
const component = getModeComponent(
|
|
98
|
+
mode,
|
|
99
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
100
|
+
);
|
|
101
|
+
const classNameProp = getClassPropertyName(config);
|
|
102
|
+
const props: HTMLProperties<typeof component> & { disabled?: boolean } = {
|
|
103
|
+
id: "test",
|
|
104
|
+
size: "lg",
|
|
105
|
+
style: { color: "red" },
|
|
106
|
+
[classNameProp]: "extra",
|
|
107
|
+
disabled: true,
|
|
108
|
+
};
|
|
109
|
+
const [variantProps, extraProps, otherProps] = splitProps(
|
|
110
|
+
props,
|
|
111
|
+
component,
|
|
112
|
+
["disabled"],
|
|
113
|
+
);
|
|
114
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<
|
|
115
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
116
|
+
>();
|
|
117
|
+
expect(variantProps).toEqual({
|
|
118
|
+
size: "lg",
|
|
119
|
+
style: { color: "red" },
|
|
120
|
+
[classNameProp]: "extra",
|
|
121
|
+
});
|
|
122
|
+
expectTypeOf(extraProps).branded.toEqualTypeOf<{ disabled?: boolean }>();
|
|
123
|
+
expect(extraProps).toEqual({ disabled: true });
|
|
124
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
125
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
test("splitProps with another component as parameter", () => {
|
|
129
|
+
const component1 = getModeComponent(
|
|
130
|
+
mode,
|
|
131
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
132
|
+
);
|
|
133
|
+
const component2 = getModeComponent(
|
|
134
|
+
mode,
|
|
135
|
+
cv({
|
|
136
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
137
|
+
defaultVariants: { color: "red" },
|
|
138
|
+
}),
|
|
139
|
+
);
|
|
140
|
+
const classNameProp = getClassPropertyName(config);
|
|
141
|
+
const props: HTMLProperties<typeof component1> &
|
|
142
|
+
HTMLProperties<typeof component2> = {
|
|
143
|
+
id: "test",
|
|
144
|
+
size: "lg",
|
|
145
|
+
color: "blue",
|
|
146
|
+
[classNameProp]: "extra",
|
|
147
|
+
};
|
|
148
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
149
|
+
props,
|
|
150
|
+
component1,
|
|
151
|
+
component2,
|
|
152
|
+
);
|
|
153
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<
|
|
154
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
155
|
+
>();
|
|
156
|
+
// First component gets class/style props
|
|
157
|
+
expect(comp1Props).toEqual({
|
|
158
|
+
size: "lg",
|
|
159
|
+
[classNameProp]: "extra",
|
|
160
|
+
});
|
|
161
|
+
// Second component only gets variant props (no class/style)
|
|
162
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<
|
|
163
|
+
Pick<typeof props, "color">
|
|
164
|
+
>();
|
|
165
|
+
expect(comp2Props).toEqual({
|
|
166
|
+
color: "blue",
|
|
167
|
+
});
|
|
168
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
169
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
test("splitProps with component parameter does not include component defaults", () => {
|
|
173
|
+
const component1 = getModeComponent(
|
|
174
|
+
mode,
|
|
175
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
176
|
+
);
|
|
177
|
+
const component2 = getModeComponent(
|
|
178
|
+
mode,
|
|
179
|
+
cv({
|
|
180
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
181
|
+
defaultVariants: { color: "red" },
|
|
182
|
+
}),
|
|
183
|
+
);
|
|
184
|
+
const props: HTMLProperties<typeof component1> &
|
|
185
|
+
HTMLProperties<typeof component2> = {
|
|
186
|
+
id: "test",
|
|
187
|
+
size: "lg",
|
|
188
|
+
};
|
|
189
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
190
|
+
props,
|
|
191
|
+
component1,
|
|
192
|
+
component2,
|
|
193
|
+
);
|
|
194
|
+
// First component gets variant props
|
|
195
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
196
|
+
// Second component gets empty object (no defaults applied)
|
|
197
|
+
expect(comp2Props).toEqual({});
|
|
198
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
test("splitProps second component excludes class and style", () => {
|
|
202
|
+
const component1 = getModeComponent(
|
|
203
|
+
mode,
|
|
204
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
205
|
+
);
|
|
206
|
+
const component2 = getModeComponent(
|
|
207
|
+
mode,
|
|
208
|
+
cv({ variants: { color: { red: "red", blue: "blue" } } }),
|
|
209
|
+
);
|
|
210
|
+
const classNameProp = getClassPropertyName(config);
|
|
211
|
+
const props: HTMLProperties<typeof component1> &
|
|
212
|
+
HTMLProperties<typeof component2> = {
|
|
213
|
+
id: "test",
|
|
214
|
+
size: "lg",
|
|
215
|
+
color: "blue",
|
|
216
|
+
style: { backgroundColor: "yellow" },
|
|
217
|
+
[classNameProp]: "extra",
|
|
218
|
+
};
|
|
219
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
220
|
+
props,
|
|
221
|
+
component1,
|
|
222
|
+
component2,
|
|
223
|
+
);
|
|
224
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<
|
|
225
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
226
|
+
>();
|
|
227
|
+
// First component gets class/style
|
|
228
|
+
expect(comp1Props).toEqual({
|
|
229
|
+
size: "lg",
|
|
230
|
+
style: { backgroundColor: "yellow" },
|
|
231
|
+
[classNameProp]: "extra",
|
|
232
|
+
});
|
|
233
|
+
// Second component only gets variant props
|
|
234
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<{
|
|
235
|
+
color?: "red" | "blue";
|
|
236
|
+
}>();
|
|
237
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
238
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
239
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
240
|
+
});
|
|
241
|
+
|
|
242
|
+
test("splitProps with multiple parameters", () => {
|
|
243
|
+
const component1 = getModeComponent(
|
|
244
|
+
mode,
|
|
245
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
246
|
+
);
|
|
247
|
+
const component2 = getModeComponent(
|
|
248
|
+
mode,
|
|
249
|
+
cv({ variants: { color: { red: "red", blue: "blue" } } }),
|
|
250
|
+
);
|
|
251
|
+
const props: HTMLProperties<typeof component1> &
|
|
252
|
+
HTMLProperties<typeof component2> & { disabled?: boolean } = {
|
|
253
|
+
id: "test",
|
|
254
|
+
size: "lg",
|
|
255
|
+
color: "blue",
|
|
256
|
+
disabled: true,
|
|
257
|
+
};
|
|
258
|
+
const [comp1Props, extraProps, comp2Props, otherProps] = splitProps(
|
|
259
|
+
props,
|
|
260
|
+
component1,
|
|
261
|
+
["disabled"],
|
|
262
|
+
component2,
|
|
263
|
+
);
|
|
264
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<
|
|
265
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
266
|
+
>();
|
|
267
|
+
expectTypeOf(extraProps).branded.toEqualTypeOf<{ disabled?: boolean }>();
|
|
268
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<{
|
|
269
|
+
color?: "red" | "blue";
|
|
270
|
+
}>();
|
|
271
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
272
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
273
|
+
expect(extraProps).toEqual({ disabled: true });
|
|
274
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
275
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
test("splitProps with shared keys between components", () => {
|
|
279
|
+
const component1 = getModeComponent(
|
|
280
|
+
mode,
|
|
281
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
282
|
+
);
|
|
283
|
+
const component2 = getModeComponent(
|
|
284
|
+
mode,
|
|
285
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
286
|
+
);
|
|
287
|
+
const props: HTMLProperties<typeof component1> &
|
|
288
|
+
HTMLProperties<typeof component2> = {
|
|
289
|
+
id: "test",
|
|
290
|
+
size: "lg",
|
|
291
|
+
};
|
|
292
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
293
|
+
props,
|
|
294
|
+
component1,
|
|
295
|
+
component2,
|
|
296
|
+
);
|
|
297
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<
|
|
298
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
299
|
+
>();
|
|
300
|
+
// First component gets class/style + size
|
|
301
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
302
|
+
// Second component only gets variant props (size appears in both)
|
|
303
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<{
|
|
304
|
+
size?: "sm" | "lg";
|
|
305
|
+
}>();
|
|
306
|
+
expect(comp2Props).toEqual({ size: "lg" });
|
|
307
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test("splitProps with defaultVariants from multiple components does not include defaults", () => {
|
|
311
|
+
const component1 = getModeComponent(
|
|
312
|
+
mode,
|
|
313
|
+
cv({
|
|
314
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
315
|
+
defaultVariants: { size: "sm" },
|
|
316
|
+
}),
|
|
317
|
+
);
|
|
318
|
+
const component2 = getModeComponent(
|
|
319
|
+
mode,
|
|
320
|
+
cv({
|
|
321
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
322
|
+
defaultVariants: { color: "red" },
|
|
323
|
+
}),
|
|
324
|
+
);
|
|
325
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
326
|
+
{ id: "test" },
|
|
327
|
+
component1,
|
|
328
|
+
component2,
|
|
329
|
+
);
|
|
330
|
+
// Neither gets defaults - only props that are actually in the input
|
|
331
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<{ size?: "sm" | "lg" }>();
|
|
332
|
+
expect(comp1Props).toEqual({});
|
|
333
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<{
|
|
334
|
+
color?: "red" | "blue";
|
|
335
|
+
}>();
|
|
336
|
+
expect(comp2Props).toEqual({});
|
|
337
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id: string }>();
|
|
338
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
test("variantKeys splitProps does not include defaultVariants", () => {
|
|
342
|
+
const component = getModeComponent(
|
|
343
|
+
mode,
|
|
344
|
+
cv({
|
|
345
|
+
variants: { size: { sm: "sm", lg: "lg" }, color: { red: "red" } },
|
|
346
|
+
defaultVariants: { size: "sm", color: "red" },
|
|
347
|
+
}),
|
|
348
|
+
);
|
|
349
|
+
const classNameProp = getClassPropertyName(config);
|
|
350
|
+
const props: HTMLProperties<typeof component> = {
|
|
351
|
+
id: "test",
|
|
352
|
+
size: "lg",
|
|
353
|
+
[classNameProp]: "extra",
|
|
354
|
+
};
|
|
355
|
+
const [variantProps, otherProps] = splitProps(
|
|
356
|
+
props,
|
|
357
|
+
component.variantKeys,
|
|
358
|
+
);
|
|
359
|
+
// variantKeys is just an array, so no defaults are applied
|
|
360
|
+
expect(variantProps).toEqual({
|
|
361
|
+
size: "lg",
|
|
362
|
+
});
|
|
363
|
+
// color is in variantKeys but not in props, so it's not in either result
|
|
364
|
+
expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
|
|
365
|
+
});
|
|
366
|
+
|
|
367
|
+
test("variantKeys splitProps with key array", () => {
|
|
368
|
+
const component = getModeComponent(
|
|
369
|
+
mode,
|
|
370
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
371
|
+
);
|
|
372
|
+
const classNameProp = getClassPropertyName(config);
|
|
373
|
+
const props: HTMLProperties<typeof component> & { disabled?: boolean } = {
|
|
374
|
+
id: "test",
|
|
375
|
+
size: "lg",
|
|
376
|
+
[classNameProp]: "extra",
|
|
377
|
+
disabled: true,
|
|
378
|
+
};
|
|
379
|
+
const [variantProps, extraProps, otherProps] = splitProps(
|
|
380
|
+
props,
|
|
381
|
+
component.variantKeys,
|
|
382
|
+
["disabled"],
|
|
383
|
+
);
|
|
384
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<{
|
|
385
|
+
size?: "sm" | "lg";
|
|
386
|
+
}>();
|
|
387
|
+
expect(variantProps).toEqual({ size: "lg" });
|
|
388
|
+
expectTypeOf(extraProps).branded.toEqualTypeOf<{ disabled?: boolean }>();
|
|
389
|
+
expect(extraProps).toEqual({ disabled: true });
|
|
390
|
+
expectTypeOf(otherProps).toEqualTypeOf<
|
|
391
|
+
Pick<typeof props, "id" | "class" | "className" | "style">
|
|
392
|
+
>();
|
|
393
|
+
expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
|
|
394
|
+
});
|
|
395
|
+
|
|
396
|
+
test("variantKeys splitProps with component", () => {
|
|
397
|
+
const component1 = getModeComponent(
|
|
398
|
+
mode,
|
|
399
|
+
cv({
|
|
400
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
401
|
+
defaultVariants: { size: "sm" },
|
|
402
|
+
}),
|
|
403
|
+
);
|
|
404
|
+
const component2 = getModeComponent(
|
|
405
|
+
mode,
|
|
406
|
+
cv({
|
|
407
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
408
|
+
defaultVariants: { color: "red" },
|
|
409
|
+
}),
|
|
410
|
+
);
|
|
411
|
+
const classNameProp = getClassPropertyName(config);
|
|
412
|
+
const props: HTMLProperties<typeof component1> &
|
|
413
|
+
HTMLProperties<typeof component2> = {
|
|
414
|
+
id: "test",
|
|
415
|
+
size: "lg",
|
|
416
|
+
color: "blue",
|
|
417
|
+
[classNameProp]: "extra",
|
|
418
|
+
};
|
|
419
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
420
|
+
props,
|
|
421
|
+
component1.variantKeys,
|
|
422
|
+
component2.variantKeys,
|
|
423
|
+
);
|
|
424
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<{ size?: "sm" | "lg" }>();
|
|
425
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
426
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<{
|
|
427
|
+
color?: "red" | "blue";
|
|
428
|
+
}>();
|
|
429
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
430
|
+
expectTypeOf(otherProps).toEqualTypeOf<
|
|
431
|
+
Pick<typeof props, "id" | "class" | "className" | "style">
|
|
432
|
+
>();
|
|
433
|
+
expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
|
|
434
|
+
});
|
|
435
|
+
|
|
436
|
+
test("splitProps with array containing class before component", () => {
|
|
437
|
+
const component = getModeComponent(
|
|
438
|
+
mode,
|
|
439
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
440
|
+
);
|
|
441
|
+
const classNameProp = getClassPropertyName(config);
|
|
442
|
+
const props: HTMLProperties<typeof component> = {
|
|
443
|
+
id: "test",
|
|
444
|
+
size: "lg",
|
|
445
|
+
style: { backgroundColor: "yellow" },
|
|
446
|
+
[classNameProp]: "extra",
|
|
447
|
+
};
|
|
448
|
+
// Array gets class, component still gets class/style (arrays don't claim styling)
|
|
449
|
+
const [arrayProps, compProps, otherProps] = splitProps(
|
|
450
|
+
props,
|
|
451
|
+
[classNameProp],
|
|
452
|
+
component,
|
|
453
|
+
);
|
|
454
|
+
expectTypeOf(arrayProps).branded.toEqualTypeOf<
|
|
455
|
+
Pick<typeof props, "class" | "className">
|
|
456
|
+
>();
|
|
457
|
+
expect(arrayProps).toEqual({ [classNameProp]: "extra" });
|
|
458
|
+
// Component still gets class/style since arrays don't claim them
|
|
459
|
+
expectTypeOf(compProps).branded.toEqualTypeOf<
|
|
460
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
461
|
+
>();
|
|
462
|
+
expect(compProps).toEqual({
|
|
463
|
+
size: "lg",
|
|
464
|
+
style: { backgroundColor: "yellow" },
|
|
465
|
+
[classNameProp]: "extra",
|
|
466
|
+
});
|
|
467
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
test("splitProps with array containing class and style before component", () => {
|
|
471
|
+
const component = getModeComponent(
|
|
472
|
+
mode,
|
|
473
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
474
|
+
);
|
|
475
|
+
const classNameProp = getClassPropertyName(config);
|
|
476
|
+
const props: HTMLProperties<typeof component> = {
|
|
477
|
+
id: "test",
|
|
478
|
+
size: "lg",
|
|
479
|
+
style: { backgroundColor: "yellow" },
|
|
480
|
+
[classNameProp]: "extra",
|
|
481
|
+
};
|
|
482
|
+
// Array gets class and style, component still gets class/style (arrays don't claim styling)
|
|
483
|
+
const [arrayProps, compProps, otherProps] = splitProps(
|
|
484
|
+
props,
|
|
485
|
+
[classNameProp, "style"],
|
|
486
|
+
component,
|
|
487
|
+
);
|
|
488
|
+
expectTypeOf(arrayProps).branded.toEqualTypeOf<
|
|
489
|
+
Pick<typeof props, "class" | "className" | "style">
|
|
490
|
+
>();
|
|
491
|
+
expect(arrayProps).toEqual({
|
|
492
|
+
[classNameProp]: "extra",
|
|
493
|
+
style: { backgroundColor: "yellow" },
|
|
494
|
+
});
|
|
495
|
+
// Component still gets class/style since arrays don't claim them
|
|
496
|
+
expectTypeOf(compProps).branded.toEqualTypeOf<
|
|
497
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
498
|
+
>();
|
|
499
|
+
expect(compProps).toEqual({
|
|
500
|
+
size: "lg",
|
|
501
|
+
style: { backgroundColor: "yellow" },
|
|
502
|
+
[classNameProp]: "extra",
|
|
503
|
+
});
|
|
504
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
test("splitProps with array after component", () => {
|
|
508
|
+
const component = getModeComponent(
|
|
509
|
+
mode,
|
|
510
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
511
|
+
);
|
|
512
|
+
const classNameProp = getClassPropertyName(config);
|
|
513
|
+
const props: HTMLProperties<typeof component> = {
|
|
514
|
+
id: "test",
|
|
515
|
+
size: "lg",
|
|
516
|
+
style: { backgroundColor: "yellow" },
|
|
517
|
+
[classNameProp]: "extra",
|
|
518
|
+
};
|
|
519
|
+
// Component gets class/style first, array also gets them
|
|
520
|
+
const [compProps, arrayProps, otherProps] = splitProps(props, component, [
|
|
521
|
+
classNameProp,
|
|
522
|
+
"style",
|
|
523
|
+
]);
|
|
524
|
+
expectTypeOf(compProps).branded.toEqualTypeOf<
|
|
525
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
526
|
+
>();
|
|
527
|
+
expect(compProps).toEqual({
|
|
528
|
+
size: "lg",
|
|
529
|
+
style: { backgroundColor: "yellow" },
|
|
530
|
+
[classNameProp]: "extra",
|
|
531
|
+
});
|
|
532
|
+
expectTypeOf(arrayProps).branded.toEqualTypeOf<
|
|
533
|
+
Pick<typeof props, "class" | "className" | "style">
|
|
534
|
+
>();
|
|
535
|
+
expect(arrayProps).toEqual({
|
|
536
|
+
[classNameProp]: "extra",
|
|
537
|
+
style: { backgroundColor: "yellow" },
|
|
538
|
+
});
|
|
539
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
540
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
541
|
+
});
|
|
542
|
+
|
|
543
|
+
test("splitProps array before multiple components", () => {
|
|
544
|
+
const component1 = getModeComponent(
|
|
545
|
+
mode,
|
|
546
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
547
|
+
);
|
|
548
|
+
const component2 = getModeComponent(
|
|
549
|
+
mode,
|
|
550
|
+
cv({ variants: { color: { red: "red", blue: "blue" } } }),
|
|
551
|
+
);
|
|
552
|
+
const classNameProp = getClassPropertyName(config);
|
|
553
|
+
const props: HTMLProperties<typeof component1> &
|
|
554
|
+
HTMLProperties<typeof component2> & { disabled?: boolean } = {
|
|
555
|
+
id: "test",
|
|
556
|
+
size: "lg",
|
|
557
|
+
color: "blue",
|
|
558
|
+
disabled: true,
|
|
559
|
+
style: { backgroundColor: "yellow" },
|
|
560
|
+
[classNameProp]: "extra",
|
|
561
|
+
};
|
|
562
|
+
// Array doesn't claim styling, so first component (comp1) gets styling
|
|
563
|
+
const [disabledProps, comp1Props, comp2Props, otherProps] = splitProps(
|
|
564
|
+
props,
|
|
565
|
+
["disabled"],
|
|
566
|
+
component1,
|
|
567
|
+
component2,
|
|
568
|
+
);
|
|
569
|
+
expectTypeOf(disabledProps).branded.toEqualTypeOf<{
|
|
570
|
+
disabled?: boolean;
|
|
571
|
+
}>();
|
|
572
|
+
expect(disabledProps).toEqual({ disabled: true });
|
|
573
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<
|
|
574
|
+
Pick<typeof props, "size" | "style" | "class" | "className">
|
|
575
|
+
>();
|
|
576
|
+
// First component gets class/style
|
|
577
|
+
expect(comp1Props).toEqual({
|
|
578
|
+
size: "lg",
|
|
579
|
+
style: { backgroundColor: "yellow" },
|
|
580
|
+
[classNameProp]: "extra",
|
|
581
|
+
});
|
|
582
|
+
// Second component only gets variant props
|
|
583
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<
|
|
584
|
+
Pick<typeof props, "color">
|
|
585
|
+
>();
|
|
586
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
587
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
588
|
+
});
|
|
589
|
+
});
|
|
590
|
+
}
|