clava 0.1.19 → 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 +31 -0
- package/dist/index.d.ts +13 -20
- 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 +13 -4
- 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/{src/test-language-service.ts → tests/language-service-test.ts} +3 -2
- 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,380 @@
|
|
|
1
|
+
import { describe, expect, test } from "vitest";
|
|
2
|
+
import {
|
|
3
|
+
CONFIGS,
|
|
4
|
+
createCVFromConfig,
|
|
5
|
+
getConfigDescription,
|
|
6
|
+
getConfigMode,
|
|
7
|
+
getConfigTransformClass,
|
|
8
|
+
getModeComponent,
|
|
9
|
+
getStyleClass,
|
|
10
|
+
} from "./_utils.ts";
|
|
11
|
+
|
|
12
|
+
for (const config of Object.values(CONFIGS)) {
|
|
13
|
+
const mode = getConfigMode(config);
|
|
14
|
+
const cv = createCVFromConfig(config);
|
|
15
|
+
const cls = getConfigTransformClass(config);
|
|
16
|
+
|
|
17
|
+
describe(getConfigDescription(config), () => {
|
|
18
|
+
test("variant no value empty class", () => {
|
|
19
|
+
const component = getModeComponent(
|
|
20
|
+
mode,
|
|
21
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
22
|
+
);
|
|
23
|
+
const props = component();
|
|
24
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test("variant no value with class", () => {
|
|
28
|
+
const component = getModeComponent(
|
|
29
|
+
mode,
|
|
30
|
+
cv({ class: "foo", variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
31
|
+
);
|
|
32
|
+
const props = component();
|
|
33
|
+
expect(getStyleClass(props)).toEqual({ class: cls("foo") });
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("variant with value", () => {
|
|
37
|
+
const component = getModeComponent(
|
|
38
|
+
mode,
|
|
39
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
40
|
+
);
|
|
41
|
+
const props = component({ size: "lg" });
|
|
42
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg") });
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test("variant with value and class", () => {
|
|
46
|
+
const component = getModeComponent(
|
|
47
|
+
mode,
|
|
48
|
+
cv({ class: "foo", variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
49
|
+
);
|
|
50
|
+
const props = component({ size: "lg" });
|
|
51
|
+
expect(getStyleClass(props)).toEqual({ class: cls("foo lg") });
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
test("variant with style value", () => {
|
|
55
|
+
const component = getModeComponent(
|
|
56
|
+
mode,
|
|
57
|
+
cv({
|
|
58
|
+
variants: {
|
|
59
|
+
color: {
|
|
60
|
+
red: { style: { backgroundColor: "red" } },
|
|
61
|
+
blue: { style: { backgroundColor: "blue" } },
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
const props = component({ color: "red" });
|
|
67
|
+
expect(getStyleClass(props)).toEqual({
|
|
68
|
+
class: "",
|
|
69
|
+
backgroundColor: "red",
|
|
70
|
+
});
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
test("rejects inline style object without style wrapper", () => {
|
|
74
|
+
const component = getModeComponent(
|
|
75
|
+
mode,
|
|
76
|
+
cv({
|
|
77
|
+
variants: {
|
|
78
|
+
color: {
|
|
79
|
+
// @ts-expect-error old shape requires `style` wrapper
|
|
80
|
+
red: { backgroundColor: "red" },
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
}),
|
|
84
|
+
);
|
|
85
|
+
const props = component({ color: "red" });
|
|
86
|
+
expect(getStyleClass(props)).toEqual({
|
|
87
|
+
class: "",
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test("variant with class and style value", () => {
|
|
92
|
+
const component = getModeComponent(
|
|
93
|
+
mode,
|
|
94
|
+
cv({
|
|
95
|
+
variants: {
|
|
96
|
+
color: {
|
|
97
|
+
red: { class: "text-red", style: { backgroundColor: "red" } },
|
|
98
|
+
blue: { class: "text-blue", style: { backgroundColor: "blue" } },
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
}),
|
|
102
|
+
);
|
|
103
|
+
const props = component({ color: "red" });
|
|
104
|
+
expect(getStyleClass(props)).toEqual({
|
|
105
|
+
class: cls("text-red"),
|
|
106
|
+
backgroundColor: "red",
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
test("multiple variants", () => {
|
|
111
|
+
const component = getModeComponent(
|
|
112
|
+
mode,
|
|
113
|
+
cv({
|
|
114
|
+
variants: {
|
|
115
|
+
size: { sm: "sm", lg: "lg" },
|
|
116
|
+
color: { red: "red", blue: "blue" },
|
|
117
|
+
},
|
|
118
|
+
}),
|
|
119
|
+
);
|
|
120
|
+
const props = component({ size: "lg", color: "red" });
|
|
121
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg red") });
|
|
122
|
+
});
|
|
123
|
+
|
|
124
|
+
test("boolean variant true", () => {
|
|
125
|
+
const component = getModeComponent(
|
|
126
|
+
mode,
|
|
127
|
+
cv({ variants: { disabled: { true: "disabled", false: "enabled" } } }),
|
|
128
|
+
);
|
|
129
|
+
const props = component({ disabled: true });
|
|
130
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
test("boolean variant false", () => {
|
|
134
|
+
const component = getModeComponent(
|
|
135
|
+
mode,
|
|
136
|
+
cv({ variants: { disabled: { true: "disabled", false: "enabled" } } }),
|
|
137
|
+
);
|
|
138
|
+
const props = component({ disabled: false });
|
|
139
|
+
expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("boolean variant true only false", () => {
|
|
143
|
+
const component = getModeComponent(
|
|
144
|
+
mode,
|
|
145
|
+
cv({ variants: { disabled: { true: "disabled" } } }),
|
|
146
|
+
);
|
|
147
|
+
const props = component({ disabled: false });
|
|
148
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
149
|
+
});
|
|
150
|
+
|
|
151
|
+
test("boolean variant true only true", () => {
|
|
152
|
+
const component = getModeComponent(
|
|
153
|
+
mode,
|
|
154
|
+
cv({ variants: { disabled: { true: "disabled" } } }),
|
|
155
|
+
);
|
|
156
|
+
const props = component({ disabled: true });
|
|
157
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
test("boolean variant no value applies false", () => {
|
|
161
|
+
const component = getModeComponent(
|
|
162
|
+
mode,
|
|
163
|
+
cv({ variants: { disabled: { true: "disabled", false: "enabled" } } }),
|
|
164
|
+
);
|
|
165
|
+
const props = component();
|
|
166
|
+
expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("boolean variant false only", () => {
|
|
170
|
+
const component = getModeComponent(
|
|
171
|
+
mode,
|
|
172
|
+
cv({ variants: { disabled: { false: "enabled" } } }),
|
|
173
|
+
);
|
|
174
|
+
const props = component();
|
|
175
|
+
expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
test("boolean variant false only false", () => {
|
|
179
|
+
const component = getModeComponent(
|
|
180
|
+
mode,
|
|
181
|
+
cv({ variants: { disabled: { false: "enabled" } } }),
|
|
182
|
+
);
|
|
183
|
+
const props = component({ disabled: false });
|
|
184
|
+
expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
|
|
185
|
+
});
|
|
186
|
+
|
|
187
|
+
test("boolean variant false only true", () => {
|
|
188
|
+
const component = getModeComponent(
|
|
189
|
+
mode,
|
|
190
|
+
cv({ variants: { disabled: { false: "enabled" } } }),
|
|
191
|
+
);
|
|
192
|
+
const props = component({ disabled: true });
|
|
193
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
194
|
+
});
|
|
195
|
+
|
|
196
|
+
test("boolean variant shorthand true", () => {
|
|
197
|
+
const component = getModeComponent(
|
|
198
|
+
mode,
|
|
199
|
+
cv({ variants: { disabled: "disabled" } }),
|
|
200
|
+
);
|
|
201
|
+
const props = component({ disabled: true });
|
|
202
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
203
|
+
});
|
|
204
|
+
|
|
205
|
+
test("boolean variant shorthand false", () => {
|
|
206
|
+
const component = getModeComponent(
|
|
207
|
+
mode,
|
|
208
|
+
cv({ variants: { disabled: "disabled" } }),
|
|
209
|
+
);
|
|
210
|
+
const props = component({ disabled: false });
|
|
211
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
212
|
+
});
|
|
213
|
+
|
|
214
|
+
test("variant style does not accept numbers", () => {
|
|
215
|
+
const component = getModeComponent(
|
|
216
|
+
mode,
|
|
217
|
+
cv({
|
|
218
|
+
variants: {
|
|
219
|
+
// @ts-expect-error
|
|
220
|
+
size: {
|
|
221
|
+
sm: {
|
|
222
|
+
class: "sm",
|
|
223
|
+
style: { fontSize: 12 },
|
|
224
|
+
},
|
|
225
|
+
lg: { class: "lg", style: { fontSize: "16px" } },
|
|
226
|
+
},
|
|
227
|
+
},
|
|
228
|
+
}),
|
|
229
|
+
);
|
|
230
|
+
const props = component({ size: "sm" });
|
|
231
|
+
expect(getStyleClass(props)).toEqual({
|
|
232
|
+
class: cls("sm"),
|
|
233
|
+
fontSize: expect.toBeOneOf(["12", "12px"]),
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
|
|
237
|
+
test("variant props do not accept invalid values", () => {
|
|
238
|
+
const component = getModeComponent(
|
|
239
|
+
mode,
|
|
240
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
241
|
+
);
|
|
242
|
+
const props = component({
|
|
243
|
+
// @ts-expect-error invalid value
|
|
244
|
+
size:
|
|
245
|
+
// no error
|
|
246
|
+
"invalid",
|
|
247
|
+
});
|
|
248
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
249
|
+
});
|
|
250
|
+
|
|
251
|
+
test("variant props do not accept invalid keys", () => {
|
|
252
|
+
const component = getModeComponent(
|
|
253
|
+
mode,
|
|
254
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
255
|
+
);
|
|
256
|
+
const props = component({
|
|
257
|
+
// @ts-expect-error
|
|
258
|
+
invalidKey: "value",
|
|
259
|
+
});
|
|
260
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
test("defaultVariants", () => {
|
|
264
|
+
const component = getModeComponent(
|
|
265
|
+
mode,
|
|
266
|
+
cv({
|
|
267
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
268
|
+
defaultVariants: { size: "sm" },
|
|
269
|
+
}),
|
|
270
|
+
);
|
|
271
|
+
const props = component();
|
|
272
|
+
expect(getStyleClass(props)).toEqual({ class: cls("sm") });
|
|
273
|
+
});
|
|
274
|
+
|
|
275
|
+
test("defaultVariants overridden by props", () => {
|
|
276
|
+
const component = getModeComponent(
|
|
277
|
+
mode,
|
|
278
|
+
cv({
|
|
279
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
280
|
+
defaultVariants: { size: "sm" },
|
|
281
|
+
}),
|
|
282
|
+
);
|
|
283
|
+
const props = component({ size: "lg" });
|
|
284
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg") });
|
|
285
|
+
});
|
|
286
|
+
|
|
287
|
+
test("defaultVariants boolean false", () => {
|
|
288
|
+
const component = getModeComponent(
|
|
289
|
+
mode,
|
|
290
|
+
cv({
|
|
291
|
+
variants: { disabled: { true: "disabled", false: "enabled" } },
|
|
292
|
+
defaultVariants: { disabled: false },
|
|
293
|
+
}),
|
|
294
|
+
);
|
|
295
|
+
const props = component();
|
|
296
|
+
expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
|
|
297
|
+
});
|
|
298
|
+
|
|
299
|
+
test("defaultVariants boolean true", () => {
|
|
300
|
+
const component = getModeComponent(
|
|
301
|
+
mode,
|
|
302
|
+
cv({
|
|
303
|
+
variants: { disabled: { true: "disabled", false: "enabled" } },
|
|
304
|
+
defaultVariants: { disabled: true },
|
|
305
|
+
}),
|
|
306
|
+
);
|
|
307
|
+
const props = component();
|
|
308
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
test("defaultVariants boolean shorthand", () => {
|
|
312
|
+
const component = getModeComponent(
|
|
313
|
+
mode,
|
|
314
|
+
cv({
|
|
315
|
+
variants: { disabled: "disabled" },
|
|
316
|
+
defaultVariants: { disabled: true },
|
|
317
|
+
}),
|
|
318
|
+
);
|
|
319
|
+
const props = component();
|
|
320
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
321
|
+
});
|
|
322
|
+
|
|
323
|
+
test("defaultVariants does not accept invalid keys", () => {
|
|
324
|
+
const component = getModeComponent(
|
|
325
|
+
mode,
|
|
326
|
+
cv({
|
|
327
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
328
|
+
defaultVariants: {
|
|
329
|
+
size: "sm",
|
|
330
|
+
// @ts-expect-error
|
|
331
|
+
invalidKey: "value",
|
|
332
|
+
},
|
|
333
|
+
}),
|
|
334
|
+
);
|
|
335
|
+
const props = component();
|
|
336
|
+
expect(getStyleClass(props)).toEqual({ class: cls("sm") });
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
test("defaultVariants does not accept invalid values", () => {
|
|
340
|
+
const component = getModeComponent(
|
|
341
|
+
mode,
|
|
342
|
+
cv({
|
|
343
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
344
|
+
defaultVariants: {
|
|
345
|
+
// @ts-expect-error invalid value
|
|
346
|
+
size:
|
|
347
|
+
// no error
|
|
348
|
+
"invalid",
|
|
349
|
+
},
|
|
350
|
+
}),
|
|
351
|
+
);
|
|
352
|
+
const props = component();
|
|
353
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
354
|
+
});
|
|
355
|
+
|
|
356
|
+
test("defaultVariants when explicitly passing undefined", () => {
|
|
357
|
+
const component = getModeComponent(
|
|
358
|
+
mode,
|
|
359
|
+
cv({
|
|
360
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
361
|
+
defaultVariants: { size: "sm" },
|
|
362
|
+
}),
|
|
363
|
+
);
|
|
364
|
+
const props = component({ size: undefined });
|
|
365
|
+
expect(getStyleClass(props)).toEqual({ class: cls("sm") });
|
|
366
|
+
});
|
|
367
|
+
|
|
368
|
+
test("defaultVariants boolean when explicitly passing undefined", () => {
|
|
369
|
+
const component = getModeComponent(
|
|
370
|
+
mode,
|
|
371
|
+
cv({
|
|
372
|
+
variants: { disabled: { true: "disabled", false: "enabled" } },
|
|
373
|
+
defaultVariants: { disabled: true },
|
|
374
|
+
}),
|
|
375
|
+
);
|
|
376
|
+
const props = component({ disabled: undefined });
|
|
377
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
378
|
+
});
|
|
379
|
+
});
|
|
380
|
+
}
|
package/tsconfig.json
CHANGED