clava 0.0.1 → 0.1.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 +13 -0
- package/dist/index.d.ts +133 -0
- package/dist/index.js +534 -0
- package/dist/index.js.map +1 -0
- package/license +21 -0
- package/package.json +31 -14
- package/rolldown.config.ts +12 -0
- package/src/index.ts +692 -0
- package/src/test.ts +2039 -0
- package/src/types.ts +325 -0
- package/src/utils.ts +164 -0
- package/tsconfig.json +7 -0
package/src/test.ts
ADDED
|
@@ -0,0 +1,2039 @@
|
|
|
1
|
+
import { describe, expect, expectTypeOf, test } from "vitest";
|
|
2
|
+
|
|
3
|
+
import type {
|
|
4
|
+
AnyComponent,
|
|
5
|
+
ComponentResult,
|
|
6
|
+
StyleClassValue,
|
|
7
|
+
HTMLCSSProperties,
|
|
8
|
+
JSXCSSProperties,
|
|
9
|
+
Variants,
|
|
10
|
+
ComputedVariants,
|
|
11
|
+
Component,
|
|
12
|
+
StyleProperty,
|
|
13
|
+
} from "./types.ts";
|
|
14
|
+
|
|
15
|
+
import {
|
|
16
|
+
cv as cvBase,
|
|
17
|
+
create,
|
|
18
|
+
splitProps,
|
|
19
|
+
type VariantProps,
|
|
20
|
+
} from "./index.ts";
|
|
21
|
+
import {
|
|
22
|
+
htmlObjStyleToStyleValue,
|
|
23
|
+
htmlStyleToStyleValue,
|
|
24
|
+
isHTMLObjStyle,
|
|
25
|
+
jsxStyleToStyleValue,
|
|
26
|
+
} from "./utils.ts";
|
|
27
|
+
|
|
28
|
+
const MODES = ["jsx", "html", "htmlObj"] as const;
|
|
29
|
+
type Mode = (typeof MODES)[number] | null;
|
|
30
|
+
|
|
31
|
+
type HTMLProperties<T extends AnyComponent> = VariantProps<T> & {
|
|
32
|
+
id?: string;
|
|
33
|
+
class?: string;
|
|
34
|
+
className?: string;
|
|
35
|
+
style?: StyleProperty;
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
type ConfigParams = NonNullable<Parameters<typeof create>[0]>;
|
|
39
|
+
|
|
40
|
+
interface Config {
|
|
41
|
+
mode: Mode;
|
|
42
|
+
defaultMode: Mode;
|
|
43
|
+
transformClass?: ConfigParams["transformClass"];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type ConfigMode<T extends Config> = NonNullable<T["mode"] | T["defaultMode"]>;
|
|
47
|
+
|
|
48
|
+
const transformClass = {
|
|
49
|
+
uppercase: (className) => className.toUpperCase(),
|
|
50
|
+
} satisfies Record<string, Config["transformClass"]>;
|
|
51
|
+
|
|
52
|
+
const CONFIGS = {
|
|
53
|
+
default: { mode: null, defaultMode: null },
|
|
54
|
+
jsx: { mode: "jsx", defaultMode: null },
|
|
55
|
+
html: { mode: "html", defaultMode: null },
|
|
56
|
+
htmlObj: { mode: "htmlObj", defaultMode: null },
|
|
57
|
+
htmlDefault: { mode: null, defaultMode: "html" },
|
|
58
|
+
htmlObjDefault: { mode: null, defaultMode: "htmlObj" },
|
|
59
|
+
uppercase: {
|
|
60
|
+
mode: null,
|
|
61
|
+
defaultMode: null,
|
|
62
|
+
transformClass: transformClass.uppercase,
|
|
63
|
+
},
|
|
64
|
+
} satisfies Record<string, Config>;
|
|
65
|
+
|
|
66
|
+
function getConfigMode<T extends Config>(config: T): T["mode"] {
|
|
67
|
+
if (!("mode" in config)) return null;
|
|
68
|
+
return config.mode;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
function getConfigDefaultMode<T extends Config>(config: T): T["defaultMode"] {
|
|
72
|
+
if (!("defaultMode" in config)) return null;
|
|
73
|
+
return config.defaultMode;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function getConfigTransformClass(config: Config) {
|
|
77
|
+
if (!("transformClass" in config) || !config.transformClass) {
|
|
78
|
+
return (className: string) => className;
|
|
79
|
+
}
|
|
80
|
+
return config.transformClass;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function getConfigDescription(config: Config) {
|
|
84
|
+
for (const [name, cfg] of Object.entries(CONFIGS)) {
|
|
85
|
+
if (cfg !== config) continue;
|
|
86
|
+
return name;
|
|
87
|
+
}
|
|
88
|
+
return "custom";
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function createCVFromConfig<T extends Config>(config: T) {
|
|
92
|
+
const defaultMode = getConfigDefaultMode(config);
|
|
93
|
+
const transformClass = getConfigTransformClass(config);
|
|
94
|
+
const hasTransform = "transformClass" in config && config.transformClass;
|
|
95
|
+
if (!defaultMode && !hasTransform) {
|
|
96
|
+
return cvBase;
|
|
97
|
+
}
|
|
98
|
+
return create({
|
|
99
|
+
defaultMode: defaultMode ?? undefined,
|
|
100
|
+
transformClass,
|
|
101
|
+
}).cv;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
function getModalComponent<
|
|
105
|
+
M extends Mode,
|
|
106
|
+
V extends Variants = {},
|
|
107
|
+
CV extends ComputedVariants = {},
|
|
108
|
+
const E extends AnyComponent[] = [],
|
|
109
|
+
>(mode: M, component: Component<V, CV, E>) {
|
|
110
|
+
if (!mode) return component;
|
|
111
|
+
return component[mode];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function getClass(props: ComponentResult) {
|
|
115
|
+
if ("class" in props) return props.class;
|
|
116
|
+
return props.className;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
function getClassPropertyName(config: Config) {
|
|
120
|
+
const mode = config.mode ?? config.defaultMode;
|
|
121
|
+
// null defaults to jsx mode
|
|
122
|
+
if (mode === "jsx" || mode === null) return "className";
|
|
123
|
+
return "class";
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function assertClassProperty<T extends Config>(
|
|
127
|
+
config: T,
|
|
128
|
+
props: ComponentResult,
|
|
129
|
+
): asserts props is ConfigMode<T> extends "html" | "htmlObj"
|
|
130
|
+
? Extract<ComponentResult, { class: string }>
|
|
131
|
+
: Extract<ComponentResult, { className: string }> {
|
|
132
|
+
const mode = config.mode ?? config.defaultMode;
|
|
133
|
+
if (mode === "html" || mode === "htmlObj") {
|
|
134
|
+
if (!("class" in props)) {
|
|
135
|
+
expect.fail(`Expected ${mode} props to have class`);
|
|
136
|
+
}
|
|
137
|
+
} else {
|
|
138
|
+
if (!("className" in props)) {
|
|
139
|
+
expect.fail(`Expected ${mode ?? "jsx"} props to have className`);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function assertStyleProperty<T extends Config>(
|
|
145
|
+
config: T,
|
|
146
|
+
props: ComponentResult,
|
|
147
|
+
): asserts props is ConfigMode<T> extends "html"
|
|
148
|
+
? Extract<ComponentResult, { style: string }>
|
|
149
|
+
: ConfigMode<T> extends "htmlObj"
|
|
150
|
+
? Extract<ComponentResult, { style: HTMLCSSProperties }>
|
|
151
|
+
: Extract<ComponentResult, { style: JSXCSSProperties }> {
|
|
152
|
+
if (!("style" in props)) {
|
|
153
|
+
const mode = config.mode ?? config.defaultMode;
|
|
154
|
+
expect.fail(`Expected ${mode ?? "jsx"} props to have style`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
function getStyle(props: Pick<ComponentResult, "style">) {
|
|
159
|
+
if (typeof props.style === "string") {
|
|
160
|
+
return htmlStyleToStyleValue(props.style);
|
|
161
|
+
}
|
|
162
|
+
if (typeof props.style === "object") {
|
|
163
|
+
if (isHTMLObjStyle(props.style)) {
|
|
164
|
+
return htmlObjStyleToStyleValue(props.style);
|
|
165
|
+
}
|
|
166
|
+
return jsxStyleToStyleValue(props.style);
|
|
167
|
+
}
|
|
168
|
+
return {};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function getStyleClass(props: ComponentResult): StyleClassValue {
|
|
172
|
+
return {
|
|
173
|
+
...getStyle(props),
|
|
174
|
+
class: getClass(props),
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
for (const config of [CONFIGS.default, CONFIGS.jsx, CONFIGS.uppercase]) {
|
|
179
|
+
const mode = getConfigMode(config);
|
|
180
|
+
const cv = createCVFromConfig(config);
|
|
181
|
+
const cls = getConfigTransformClass(config);
|
|
182
|
+
|
|
183
|
+
describe(getConfigDescription(config), () => {
|
|
184
|
+
test("style has correct shape for mode", () => {
|
|
185
|
+
const component = getModalComponent(
|
|
186
|
+
mode,
|
|
187
|
+
cv({ class: "base", style: { backgroundColor: "red" } }),
|
|
188
|
+
);
|
|
189
|
+
const props = component();
|
|
190
|
+
assertClassProperty(config, props);
|
|
191
|
+
expect(props).not.toHaveProperty("class");
|
|
192
|
+
expect(props.className).toBe(cls("base"));
|
|
193
|
+
expect(props.style.backgroundColor).toBe("red");
|
|
194
|
+
expectTypeOf(props.style).toEqualTypeOf<JSXCSSProperties>();
|
|
195
|
+
});
|
|
196
|
+
|
|
197
|
+
test("no argument still returns jsx shape", () => {
|
|
198
|
+
const component = getModalComponent(mode, cv());
|
|
199
|
+
const props = component();
|
|
200
|
+
assertClassProperty(config, props);
|
|
201
|
+
expect(props).not.toHaveProperty("class");
|
|
202
|
+
expect(props.className).toBe("");
|
|
203
|
+
expect(props.style).toEqual({});
|
|
204
|
+
expectTypeOf(props.style).toEqualTypeOf<JSXCSSProperties>();
|
|
205
|
+
});
|
|
206
|
+
});
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
for (const config of [CONFIGS.html, CONFIGS.htmlDefault]) {
|
|
210
|
+
const mode = getConfigMode(config);
|
|
211
|
+
const cv = createCVFromConfig(config);
|
|
212
|
+
const cls = getConfigTransformClass(config);
|
|
213
|
+
|
|
214
|
+
describe(getConfigDescription(config), () => {
|
|
215
|
+
test("style has correct shape for mode", () => {
|
|
216
|
+
const component = getModalComponent(
|
|
217
|
+
mode,
|
|
218
|
+
cv({ class: "base", style: { backgroundColor: "red" } }),
|
|
219
|
+
);
|
|
220
|
+
const props = component();
|
|
221
|
+
assertClassProperty(config, props);
|
|
222
|
+
expect(props).not.toHaveProperty("className");
|
|
223
|
+
expect(props.class).toBe(cls("base"));
|
|
224
|
+
expect(props.style).toBe("background-color: red;");
|
|
225
|
+
});
|
|
226
|
+
|
|
227
|
+
test("no argument still returns html shape", () => {
|
|
228
|
+
const component = getModalComponent(mode, cv());
|
|
229
|
+
const props = component();
|
|
230
|
+
assertClassProperty(config, props);
|
|
231
|
+
expect(props).not.toHaveProperty("className");
|
|
232
|
+
expect(props.class).toBe("");
|
|
233
|
+
expect(props.style).toBe("");
|
|
234
|
+
});
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
for (const config of [CONFIGS.htmlObj, CONFIGS.htmlObjDefault]) {
|
|
239
|
+
const mode = getConfigMode(config);
|
|
240
|
+
const cv = createCVFromConfig(config);
|
|
241
|
+
const cls = getConfigTransformClass(config);
|
|
242
|
+
|
|
243
|
+
describe(getConfigDescription(config), () => {
|
|
244
|
+
test("style has correct shape for mode", () => {
|
|
245
|
+
const component = getModalComponent(
|
|
246
|
+
mode,
|
|
247
|
+
cv({ class: "base", style: { backgroundColor: "red" } }),
|
|
248
|
+
);
|
|
249
|
+
const props = component();
|
|
250
|
+
assertClassProperty(config, props);
|
|
251
|
+
assertStyleProperty(config, props);
|
|
252
|
+
expect(props).not.toHaveProperty("className");
|
|
253
|
+
expect(props.class).toBe(cls("base"));
|
|
254
|
+
expect(props.style["background-color"]).toBe("red");
|
|
255
|
+
expectTypeOf(props.style).toEqualTypeOf<HTMLCSSProperties>();
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
test("no argument still returns htmlObj shape", () => {
|
|
259
|
+
const component = getModalComponent(mode, cv());
|
|
260
|
+
const props = component();
|
|
261
|
+
assertClassProperty(config, props);
|
|
262
|
+
assertStyleProperty(config, props);
|
|
263
|
+
expect(props).not.toHaveProperty("className");
|
|
264
|
+
expect(props.class).toBe("");
|
|
265
|
+
expect(props.style).toEqual({});
|
|
266
|
+
expectTypeOf(props.style).toEqualTypeOf<HTMLCSSProperties>();
|
|
267
|
+
});
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
|
|
271
|
+
for (const config of Object.values(CONFIGS)) {
|
|
272
|
+
const mode = getConfigMode(config);
|
|
273
|
+
const cv = createCVFromConfig(config);
|
|
274
|
+
const cls = getConfigTransformClass(config);
|
|
275
|
+
|
|
276
|
+
describe(getConfigDescription(config), () => {
|
|
277
|
+
test("no argument", () => {
|
|
278
|
+
const component = getModalComponent(mode, cv());
|
|
279
|
+
const props = component();
|
|
280
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
test("null class", () => {
|
|
284
|
+
const component = getModalComponent(mode, cv({ class: null }));
|
|
285
|
+
const props = component();
|
|
286
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
287
|
+
});
|
|
288
|
+
|
|
289
|
+
test("empty array class", () => {
|
|
290
|
+
const component = getModalComponent(mode, cv({ class: [] }));
|
|
291
|
+
const props = component();
|
|
292
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
test("string class", () => {
|
|
296
|
+
const component = getModalComponent(mode, cv({ class: "foo bar" }));
|
|
297
|
+
const props = component();
|
|
298
|
+
expect(getStyleClass(props)).toEqual({ class: cls("foo bar") });
|
|
299
|
+
});
|
|
300
|
+
|
|
301
|
+
test("nested array class", () => {
|
|
302
|
+
const component = getModalComponent(
|
|
303
|
+
mode,
|
|
304
|
+
cv({ class: ["foo", ["bar", ["baz"]]] }),
|
|
305
|
+
);
|
|
306
|
+
const props = component();
|
|
307
|
+
expect(getStyleClass(props)).toEqual({ class: cls("foo bar baz") });
|
|
308
|
+
});
|
|
309
|
+
|
|
310
|
+
test("nested array class with falsy values", () => {
|
|
311
|
+
const component = getModalComponent(
|
|
312
|
+
mode,
|
|
313
|
+
cv({ class: ["foo", null, ["bar", false, ["baz", 0]]] }),
|
|
314
|
+
);
|
|
315
|
+
const props = component();
|
|
316
|
+
expect(getStyleClass(props)).toEqual({ class: cls("foo bar baz") });
|
|
317
|
+
});
|
|
318
|
+
|
|
319
|
+
test("merge class from props", () => {
|
|
320
|
+
const component = getModalComponent(mode, cv({ class: "foo bar" }));
|
|
321
|
+
const props = component({ class: "baz qux" });
|
|
322
|
+
expect(getStyleClass(props)).toEqual({ class: cls("foo bar baz qux") });
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
test("merge className from props", () => {
|
|
326
|
+
const component = getModalComponent(mode, cv({ class: "foo bar" }));
|
|
327
|
+
const props = component({ className: "baz qux" });
|
|
328
|
+
expect(getStyleClass(props)).toEqual({ class: cls("foo bar baz qux") });
|
|
329
|
+
});
|
|
330
|
+
|
|
331
|
+
test("merge class and className from props", () => {
|
|
332
|
+
const component = getModalComponent(mode, cv({ class: "foo bar" }));
|
|
333
|
+
const props = component({ class: "baz qux", className: "quux corge" });
|
|
334
|
+
expect(getStyleClass(props)).toEqual({
|
|
335
|
+
class: cls("foo bar baz qux quux corge"),
|
|
336
|
+
});
|
|
337
|
+
});
|
|
338
|
+
|
|
339
|
+
test("empty style", () => {
|
|
340
|
+
const component = getModalComponent(mode, cv({ style: {} }));
|
|
341
|
+
const props = component();
|
|
342
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
343
|
+
});
|
|
344
|
+
|
|
345
|
+
test("style with properties", () => {
|
|
346
|
+
const component = getModalComponent(
|
|
347
|
+
mode,
|
|
348
|
+
cv({ style: { backgroundColor: "red", fontSize: "16px" } }),
|
|
349
|
+
);
|
|
350
|
+
const props = component();
|
|
351
|
+
expect(getStyleClass(props)).toEqual({
|
|
352
|
+
class: "",
|
|
353
|
+
backgroundColor: "red",
|
|
354
|
+
fontSize: "16px",
|
|
355
|
+
});
|
|
356
|
+
});
|
|
357
|
+
|
|
358
|
+
test("style does not accept numbers", () => {
|
|
359
|
+
const component = getModalComponent(
|
|
360
|
+
mode,
|
|
361
|
+
cv({
|
|
362
|
+
style: {
|
|
363
|
+
backgroundColor: "red",
|
|
364
|
+
// @ts-expect-error
|
|
365
|
+
fontSize: 16,
|
|
366
|
+
},
|
|
367
|
+
}),
|
|
368
|
+
);
|
|
369
|
+
const props = component();
|
|
370
|
+
expect(getStyleClass(props)).toEqual({
|
|
371
|
+
class: "",
|
|
372
|
+
backgroundColor: "red",
|
|
373
|
+
fontSize: expect.toBeOneOf(["16", "16px"]),
|
|
374
|
+
});
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
test("style with custom property", () => {
|
|
378
|
+
const component = getModalComponent(
|
|
379
|
+
mode,
|
|
380
|
+
cv({ style: { backgroundColor: "red", "--custom-var": "value" } }),
|
|
381
|
+
);
|
|
382
|
+
const props = component();
|
|
383
|
+
expect(getStyleClass(props)).toEqual({
|
|
384
|
+
class: "",
|
|
385
|
+
backgroundColor: "red",
|
|
386
|
+
"--custom-var": "value",
|
|
387
|
+
});
|
|
388
|
+
});
|
|
389
|
+
|
|
390
|
+
test("merge style from props", () => {
|
|
391
|
+
const component = getModalComponent(
|
|
392
|
+
mode,
|
|
393
|
+
cv({ style: { backgroundColor: "red" } }),
|
|
394
|
+
);
|
|
395
|
+
const props = component({ style: { fontSize: "16px" } });
|
|
396
|
+
expect(getStyleClass(props)).toEqual({
|
|
397
|
+
class: "",
|
|
398
|
+
backgroundColor: "red",
|
|
399
|
+
fontSize: "16px",
|
|
400
|
+
});
|
|
401
|
+
});
|
|
402
|
+
|
|
403
|
+
test("merge jsx style from props", () => {
|
|
404
|
+
const component = getModalComponent(
|
|
405
|
+
mode,
|
|
406
|
+
cv({ style: { backgroundColor: "red" } }),
|
|
407
|
+
);
|
|
408
|
+
const props = component({ style: { fontSize: 16 } });
|
|
409
|
+
expect(getStyleClass(props)).toEqual({
|
|
410
|
+
class: "",
|
|
411
|
+
backgroundColor: "red",
|
|
412
|
+
fontSize: "16px",
|
|
413
|
+
});
|
|
414
|
+
});
|
|
415
|
+
|
|
416
|
+
test("merge html style from props", () => {
|
|
417
|
+
const component = getModalComponent(
|
|
418
|
+
mode,
|
|
419
|
+
cv({ style: { backgroundColor: "red" } }),
|
|
420
|
+
);
|
|
421
|
+
const props = component({ style: "font-size: 16px" });
|
|
422
|
+
expect(getStyleClass(props)).toEqual({
|
|
423
|
+
class: "",
|
|
424
|
+
backgroundColor: "red",
|
|
425
|
+
fontSize: "16px",
|
|
426
|
+
});
|
|
427
|
+
});
|
|
428
|
+
|
|
429
|
+
test("merge htmlObj style from props", () => {
|
|
430
|
+
const component = getModalComponent(
|
|
431
|
+
mode,
|
|
432
|
+
cv({ style: { backgroundColor: "red" } }),
|
|
433
|
+
);
|
|
434
|
+
const props = component({ style: { "font-size": 16 } });
|
|
435
|
+
expect(getStyleClass(props)).toEqual({
|
|
436
|
+
class: "",
|
|
437
|
+
backgroundColor: "red",
|
|
438
|
+
fontSize: "16px",
|
|
439
|
+
});
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
test("variant no value empty class", () => {
|
|
443
|
+
const component = getModalComponent(
|
|
444
|
+
mode,
|
|
445
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
446
|
+
);
|
|
447
|
+
const props = component();
|
|
448
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
449
|
+
});
|
|
450
|
+
|
|
451
|
+
test("variant no value with class", () => {
|
|
452
|
+
const component = getModalComponent(
|
|
453
|
+
mode,
|
|
454
|
+
cv({ class: "foo", variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
455
|
+
);
|
|
456
|
+
const props = component();
|
|
457
|
+
expect(getStyleClass(props)).toEqual({ class: cls("foo") });
|
|
458
|
+
});
|
|
459
|
+
|
|
460
|
+
test("variant with value", () => {
|
|
461
|
+
const component = getModalComponent(
|
|
462
|
+
mode,
|
|
463
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
464
|
+
);
|
|
465
|
+
const props = component({ size: "lg" });
|
|
466
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg") });
|
|
467
|
+
});
|
|
468
|
+
|
|
469
|
+
test("variant with value and class", () => {
|
|
470
|
+
const component = getModalComponent(
|
|
471
|
+
mode,
|
|
472
|
+
cv({ class: "foo", variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
473
|
+
);
|
|
474
|
+
const props = component({ size: "lg" });
|
|
475
|
+
expect(getStyleClass(props)).toEqual({ class: cls("foo lg") });
|
|
476
|
+
});
|
|
477
|
+
|
|
478
|
+
test("variant with style value", () => {
|
|
479
|
+
const component = getModalComponent(
|
|
480
|
+
mode,
|
|
481
|
+
cv({
|
|
482
|
+
variants: {
|
|
483
|
+
color: {
|
|
484
|
+
red: { backgroundColor: "red" },
|
|
485
|
+
blue: { backgroundColor: "blue" },
|
|
486
|
+
},
|
|
487
|
+
},
|
|
488
|
+
}),
|
|
489
|
+
);
|
|
490
|
+
const props = component({ color: "red" });
|
|
491
|
+
expect(getStyleClass(props)).toEqual({
|
|
492
|
+
class: "",
|
|
493
|
+
backgroundColor: "red",
|
|
494
|
+
});
|
|
495
|
+
});
|
|
496
|
+
|
|
497
|
+
test("variant with class and style value", () => {
|
|
498
|
+
const component = getModalComponent(
|
|
499
|
+
mode,
|
|
500
|
+
cv({
|
|
501
|
+
variants: {
|
|
502
|
+
color: {
|
|
503
|
+
red: { class: "text-red", backgroundColor: "red" },
|
|
504
|
+
blue: { class: "text-blue", backgroundColor: "blue" },
|
|
505
|
+
},
|
|
506
|
+
},
|
|
507
|
+
}),
|
|
508
|
+
);
|
|
509
|
+
const props = component({ color: "red" });
|
|
510
|
+
expect(getStyleClass(props)).toEqual({
|
|
511
|
+
class: cls("text-red"),
|
|
512
|
+
backgroundColor: "red",
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
|
|
516
|
+
test("multiple variants", () => {
|
|
517
|
+
const component = getModalComponent(
|
|
518
|
+
mode,
|
|
519
|
+
cv({
|
|
520
|
+
variants: {
|
|
521
|
+
size: { sm: "sm", lg: "lg" },
|
|
522
|
+
color: { red: "red", blue: "blue" },
|
|
523
|
+
},
|
|
524
|
+
}),
|
|
525
|
+
);
|
|
526
|
+
const props = component({ size: "lg", color: "red" });
|
|
527
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg red") });
|
|
528
|
+
});
|
|
529
|
+
|
|
530
|
+
test("boolean variant true", () => {
|
|
531
|
+
const component = getModalComponent(
|
|
532
|
+
mode,
|
|
533
|
+
cv({ variants: { disabled: { true: "disabled", false: "enabled" } } }),
|
|
534
|
+
);
|
|
535
|
+
const props = component({ disabled: true });
|
|
536
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
537
|
+
});
|
|
538
|
+
|
|
539
|
+
test("boolean variant false", () => {
|
|
540
|
+
const component = getModalComponent(
|
|
541
|
+
mode,
|
|
542
|
+
cv({ variants: { disabled: { true: "disabled", false: "enabled" } } }),
|
|
543
|
+
);
|
|
544
|
+
const props = component({ disabled: false });
|
|
545
|
+
expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
|
|
546
|
+
});
|
|
547
|
+
|
|
548
|
+
test("boolean variant true only false", () => {
|
|
549
|
+
const component = getModalComponent(
|
|
550
|
+
mode,
|
|
551
|
+
cv({ variants: { disabled: { true: "disabled" } } }),
|
|
552
|
+
);
|
|
553
|
+
const props = component({ disabled: false });
|
|
554
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
555
|
+
});
|
|
556
|
+
|
|
557
|
+
test("boolean variant true only true", () => {
|
|
558
|
+
const component = getModalComponent(
|
|
559
|
+
mode,
|
|
560
|
+
cv({ variants: { disabled: { true: "disabled" } } }),
|
|
561
|
+
);
|
|
562
|
+
const props = component({ disabled: true });
|
|
563
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
564
|
+
});
|
|
565
|
+
|
|
566
|
+
test("boolean variant false only", () => {
|
|
567
|
+
const component = getModalComponent(
|
|
568
|
+
mode,
|
|
569
|
+
cv({ variants: { disabled: { false: "enabled" } } }),
|
|
570
|
+
);
|
|
571
|
+
const props = component();
|
|
572
|
+
expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
|
|
573
|
+
});
|
|
574
|
+
|
|
575
|
+
test("boolean variant false only false", () => {
|
|
576
|
+
const component = getModalComponent(
|
|
577
|
+
mode,
|
|
578
|
+
cv({ variants: { disabled: { false: "enabled" } } }),
|
|
579
|
+
);
|
|
580
|
+
const props = component({ disabled: false });
|
|
581
|
+
expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
|
|
582
|
+
});
|
|
583
|
+
|
|
584
|
+
test("boolean variant false only true", () => {
|
|
585
|
+
const component = getModalComponent(
|
|
586
|
+
mode,
|
|
587
|
+
cv({ variants: { disabled: { false: "enabled" } } }),
|
|
588
|
+
);
|
|
589
|
+
const props = component({ disabled: true });
|
|
590
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
591
|
+
});
|
|
592
|
+
|
|
593
|
+
test("boolean variant shorthand true", () => {
|
|
594
|
+
const component = getModalComponent(
|
|
595
|
+
mode,
|
|
596
|
+
cv({ variants: { disabled: "disabled" } }),
|
|
597
|
+
);
|
|
598
|
+
const props = component({ disabled: true });
|
|
599
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
test("boolean variant shorthand false", () => {
|
|
603
|
+
const component = getModalComponent(
|
|
604
|
+
mode,
|
|
605
|
+
cv({ variants: { disabled: "disabled" } }),
|
|
606
|
+
);
|
|
607
|
+
const props = component({ disabled: false });
|
|
608
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
609
|
+
});
|
|
610
|
+
|
|
611
|
+
test("variant style does not accept numbers", () => {
|
|
612
|
+
const component = getModalComponent(
|
|
613
|
+
mode,
|
|
614
|
+
cv({
|
|
615
|
+
variants: {
|
|
616
|
+
// @ts-expect-error
|
|
617
|
+
size: {
|
|
618
|
+
sm: {
|
|
619
|
+
class: "sm",
|
|
620
|
+
fontSize: 12,
|
|
621
|
+
},
|
|
622
|
+
lg: { class: "lg", fontSize: "16px" },
|
|
623
|
+
},
|
|
624
|
+
},
|
|
625
|
+
}),
|
|
626
|
+
);
|
|
627
|
+
const props = component({ size: "sm" });
|
|
628
|
+
expect(getStyleClass(props)).toEqual({
|
|
629
|
+
class: cls("sm"),
|
|
630
|
+
fontSize: expect.toBeOneOf(["12", "12px"]),
|
|
631
|
+
});
|
|
632
|
+
});
|
|
633
|
+
|
|
634
|
+
test("variant props do not accept invalid values", () => {
|
|
635
|
+
const component = getModalComponent(
|
|
636
|
+
mode,
|
|
637
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
638
|
+
);
|
|
639
|
+
const props = component({
|
|
640
|
+
// @ts-expect-error
|
|
641
|
+
size: "invalid",
|
|
642
|
+
});
|
|
643
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
644
|
+
});
|
|
645
|
+
|
|
646
|
+
test("variant props do not accept invalid keys", () => {
|
|
647
|
+
const component = getModalComponent(
|
|
648
|
+
mode,
|
|
649
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
650
|
+
);
|
|
651
|
+
const props = component({
|
|
652
|
+
// @ts-expect-error
|
|
653
|
+
invalidKey: "value",
|
|
654
|
+
});
|
|
655
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
656
|
+
});
|
|
657
|
+
|
|
658
|
+
test("defaultVariants", () => {
|
|
659
|
+
const component = getModalComponent(
|
|
660
|
+
mode,
|
|
661
|
+
cv({
|
|
662
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
663
|
+
defaultVariants: { size: "sm" },
|
|
664
|
+
}),
|
|
665
|
+
);
|
|
666
|
+
const props = component();
|
|
667
|
+
expect(getStyleClass(props)).toEqual({ class: cls("sm") });
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
test("defaultVariants overridden by props", () => {
|
|
671
|
+
const component = getModalComponent(
|
|
672
|
+
mode,
|
|
673
|
+
cv({
|
|
674
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
675
|
+
defaultVariants: { size: "sm" },
|
|
676
|
+
}),
|
|
677
|
+
);
|
|
678
|
+
const props = component({ size: "lg" });
|
|
679
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg") });
|
|
680
|
+
});
|
|
681
|
+
|
|
682
|
+
test("defaultVariants boolean false", () => {
|
|
683
|
+
const component = getModalComponent(
|
|
684
|
+
mode,
|
|
685
|
+
cv({
|
|
686
|
+
variants: { disabled: { true: "disabled", false: "enabled" } },
|
|
687
|
+
defaultVariants: { disabled: false },
|
|
688
|
+
}),
|
|
689
|
+
);
|
|
690
|
+
const props = component();
|
|
691
|
+
expect(getStyleClass(props)).toEqual({ class: cls("enabled") });
|
|
692
|
+
});
|
|
693
|
+
|
|
694
|
+
test("defaultVariants boolean true", () => {
|
|
695
|
+
const component = getModalComponent(
|
|
696
|
+
mode,
|
|
697
|
+
cv({
|
|
698
|
+
variants: { disabled: { true: "disabled", false: "enabled" } },
|
|
699
|
+
defaultVariants: { disabled: true },
|
|
700
|
+
}),
|
|
701
|
+
);
|
|
702
|
+
const props = component();
|
|
703
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
704
|
+
});
|
|
705
|
+
|
|
706
|
+
test("defaultVariants boolean shorthand", () => {
|
|
707
|
+
const component = getModalComponent(
|
|
708
|
+
mode,
|
|
709
|
+
cv({
|
|
710
|
+
variants: { disabled: "disabled" },
|
|
711
|
+
defaultVariants: { disabled: true },
|
|
712
|
+
}),
|
|
713
|
+
);
|
|
714
|
+
const props = component();
|
|
715
|
+
expect(getStyleClass(props)).toEqual({ class: cls("disabled") });
|
|
716
|
+
});
|
|
717
|
+
|
|
718
|
+
test("defaultVariants does not accept invalid keys", () => {
|
|
719
|
+
const component = getModalComponent(
|
|
720
|
+
mode,
|
|
721
|
+
cv({
|
|
722
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
723
|
+
defaultVariants: {
|
|
724
|
+
size: "sm",
|
|
725
|
+
// @ts-expect-error
|
|
726
|
+
invalidKey: "value",
|
|
727
|
+
},
|
|
728
|
+
}),
|
|
729
|
+
);
|
|
730
|
+
const props = component();
|
|
731
|
+
expect(getStyleClass(props)).toEqual({ class: cls("sm") });
|
|
732
|
+
});
|
|
733
|
+
|
|
734
|
+
test("defaultVariants does not accept invalid values", () => {
|
|
735
|
+
const component = getModalComponent(
|
|
736
|
+
mode,
|
|
737
|
+
cv({
|
|
738
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
739
|
+
defaultVariants: {
|
|
740
|
+
// @ts-expect-error
|
|
741
|
+
size: "invalid",
|
|
742
|
+
},
|
|
743
|
+
}),
|
|
744
|
+
);
|
|
745
|
+
const props = component();
|
|
746
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
747
|
+
});
|
|
748
|
+
|
|
749
|
+
test("computedVariants", () => {
|
|
750
|
+
const component = getModalComponent(
|
|
751
|
+
mode,
|
|
752
|
+
cv({
|
|
753
|
+
computedVariants: {
|
|
754
|
+
size: (value: "sm" | "lg") => (value === "sm" ? "small" : "large"),
|
|
755
|
+
},
|
|
756
|
+
}),
|
|
757
|
+
);
|
|
758
|
+
const props = component({ size: "lg" });
|
|
759
|
+
expect(getStyleClass(props)).toEqual({ class: cls("large") });
|
|
760
|
+
});
|
|
761
|
+
|
|
762
|
+
test("computedVariants with style", () => {
|
|
763
|
+
const component = getModalComponent(
|
|
764
|
+
mode,
|
|
765
|
+
cv({
|
|
766
|
+
computedVariants: {
|
|
767
|
+
size: (value: "sm" | "lg") => ({
|
|
768
|
+
class: value === "sm" ? "small" : "large",
|
|
769
|
+
fontSize: value === "sm" ? "12px" : "16px",
|
|
770
|
+
}),
|
|
771
|
+
},
|
|
772
|
+
}),
|
|
773
|
+
);
|
|
774
|
+
const props = component({ size: "lg" });
|
|
775
|
+
expect(getStyleClass(props)).toEqual({
|
|
776
|
+
class: cls("large"),
|
|
777
|
+
fontSize: "16px",
|
|
778
|
+
});
|
|
779
|
+
});
|
|
780
|
+
|
|
781
|
+
test("computedVariants overrides extended object variants", () => {
|
|
782
|
+
const base = cv({
|
|
783
|
+
variants: {
|
|
784
|
+
size: {
|
|
785
|
+
sm: { class: "base-sm", fontSize: "12px" },
|
|
786
|
+
lg: { class: "base-lg", fontSize: "16px" },
|
|
787
|
+
},
|
|
788
|
+
},
|
|
789
|
+
});
|
|
790
|
+
const component = getModalComponent(
|
|
791
|
+
mode,
|
|
792
|
+
cv({
|
|
793
|
+
extend: [base],
|
|
794
|
+
computedVariants: {
|
|
795
|
+
size: (value: "sm" | "lg") => ({
|
|
796
|
+
class: value === "sm" ? "extended-sm" : "extended-lg",
|
|
797
|
+
backgroundColor: value === "sm" ? "lightgray" : "gray",
|
|
798
|
+
}),
|
|
799
|
+
},
|
|
800
|
+
}),
|
|
801
|
+
);
|
|
802
|
+
const props = component({ size: "lg" });
|
|
803
|
+
expect(getStyleClass(props)).toEqual({
|
|
804
|
+
class: cls("extended-lg"),
|
|
805
|
+
backgroundColor: "gray",
|
|
806
|
+
});
|
|
807
|
+
});
|
|
808
|
+
|
|
809
|
+
test("computedVariants overrides extended computedVariants", () => {
|
|
810
|
+
const base = cv({
|
|
811
|
+
computedVariants: {
|
|
812
|
+
size: (value: "sm" | "lg") => ({
|
|
813
|
+
class: value === "sm" ? "base-sm" : "base-lg",
|
|
814
|
+
fontSize: value === "sm" ? "12px" : "16px",
|
|
815
|
+
}),
|
|
816
|
+
},
|
|
817
|
+
});
|
|
818
|
+
const component = getModalComponent(
|
|
819
|
+
mode,
|
|
820
|
+
cv({
|
|
821
|
+
extend: [base],
|
|
822
|
+
computedVariants: {
|
|
823
|
+
size: (value: "sm" | "lg") => ({
|
|
824
|
+
class: value === "sm" ? "extended-sm" : "extended-lg",
|
|
825
|
+
backgroundColor: value === "sm" ? "lightgray" : "gray",
|
|
826
|
+
}),
|
|
827
|
+
},
|
|
828
|
+
}),
|
|
829
|
+
);
|
|
830
|
+
const props = component({ size: "lg" });
|
|
831
|
+
expect(getStyleClass(props)).toEqual({
|
|
832
|
+
class: cls("extended-lg"),
|
|
833
|
+
backgroundColor: "gray",
|
|
834
|
+
});
|
|
835
|
+
});
|
|
836
|
+
|
|
837
|
+
test("computedVariants style does not accept numbers", () => {
|
|
838
|
+
const component = getModalComponent(
|
|
839
|
+
mode,
|
|
840
|
+
cv({
|
|
841
|
+
computedVariants: {
|
|
842
|
+
// @ts-expect-error
|
|
843
|
+
size: (value: "sm" | "lg") => ({
|
|
844
|
+
class: value === "sm" ? "small" : "large",
|
|
845
|
+
fontSize: value === "sm" ? 12 : 16,
|
|
846
|
+
}),
|
|
847
|
+
},
|
|
848
|
+
}),
|
|
849
|
+
);
|
|
850
|
+
const props = component({ size: "lg" });
|
|
851
|
+
expect(getStyleClass(props)).toEqual({
|
|
852
|
+
class: cls("large"),
|
|
853
|
+
fontSize: expect.toBeOneOf(["16", "16px"]),
|
|
854
|
+
});
|
|
855
|
+
});
|
|
856
|
+
|
|
857
|
+
test("computedVariants changes extended boolean variant to string", () => {
|
|
858
|
+
const base = cv({
|
|
859
|
+
variants: { disabled: { true: "disabled", false: "enabled" } },
|
|
860
|
+
});
|
|
861
|
+
const component = getModalComponent(
|
|
862
|
+
mode,
|
|
863
|
+
cv({
|
|
864
|
+
extend: [base],
|
|
865
|
+
computedVariants: {
|
|
866
|
+
disabled: (value: "yes" | "no" | "maybe") => {
|
|
867
|
+
if (value === "yes") return "state-disabled";
|
|
868
|
+
if (value === "no") return "state-enabled";
|
|
869
|
+
return "state-pending";
|
|
870
|
+
},
|
|
871
|
+
},
|
|
872
|
+
}),
|
|
873
|
+
);
|
|
874
|
+
component({
|
|
875
|
+
// @ts-expect-error
|
|
876
|
+
disabled: true,
|
|
877
|
+
});
|
|
878
|
+
const props = component({ disabled: "maybe" });
|
|
879
|
+
expect(getStyleClass(props)).toEqual({ class: cls("state-pending") });
|
|
880
|
+
});
|
|
881
|
+
|
|
882
|
+
test("computedVariants changes extended string variant to boolean", () => {
|
|
883
|
+
const base = cv({ variants: { size: { sm: "sm", md: "md", lg: "lg" } } });
|
|
884
|
+
const component = getModalComponent(
|
|
885
|
+
mode,
|
|
886
|
+
cv({
|
|
887
|
+
extend: [base],
|
|
888
|
+
computedVariants: {
|
|
889
|
+
size: (value: boolean) => (value ? "size-large" : "size-small"),
|
|
890
|
+
},
|
|
891
|
+
}),
|
|
892
|
+
);
|
|
893
|
+
component({
|
|
894
|
+
// @ts-expect-error
|
|
895
|
+
size: "sm",
|
|
896
|
+
});
|
|
897
|
+
const propsTrue = component({ size: true });
|
|
898
|
+
expect(getStyleClass(propsTrue)).toEqual({ class: cls("size-large") });
|
|
899
|
+
const propsFalse = component({ size: false });
|
|
900
|
+
expect(getStyleClass(propsFalse)).toEqual({ class: cls("size-small") });
|
|
901
|
+
});
|
|
902
|
+
|
|
903
|
+
test("computedVariants with number type", () => {
|
|
904
|
+
const component = getModalComponent(
|
|
905
|
+
mode,
|
|
906
|
+
cv({
|
|
907
|
+
computedVariants: {
|
|
908
|
+
columns: (value: number) => ({
|
|
909
|
+
class: `grid-cols-${value}`,
|
|
910
|
+
"--grid-columns": `${value}`,
|
|
911
|
+
}),
|
|
912
|
+
},
|
|
913
|
+
}),
|
|
914
|
+
);
|
|
915
|
+
const props = component({ columns: 3 });
|
|
916
|
+
expect(getStyleClass(props)).toEqual({
|
|
917
|
+
class: cls("grid-cols-3"),
|
|
918
|
+
"--grid-columns": "3",
|
|
919
|
+
});
|
|
920
|
+
});
|
|
921
|
+
|
|
922
|
+
test("computedVariants with number type returns dynamic styles", () => {
|
|
923
|
+
const component = getModalComponent(
|
|
924
|
+
mode,
|
|
925
|
+
cv({
|
|
926
|
+
computedVariants: {
|
|
927
|
+
gap: (value: number) => ({
|
|
928
|
+
"--gap": `${value * 4}px`,
|
|
929
|
+
}),
|
|
930
|
+
padding: (value: number) => ({
|
|
931
|
+
"--padding-x": `${value}px`,
|
|
932
|
+
"--padding-y": `${value * 0.5}px`,
|
|
933
|
+
}),
|
|
934
|
+
},
|
|
935
|
+
}),
|
|
936
|
+
);
|
|
937
|
+
const props = component({ gap: 4, padding: 16 });
|
|
938
|
+
expect(getStyleClass(props)).toEqual({
|
|
939
|
+
class: "",
|
|
940
|
+
"--gap": "16px",
|
|
941
|
+
"--padding-x": "16px",
|
|
942
|
+
"--padding-y": "8px",
|
|
943
|
+
});
|
|
944
|
+
});
|
|
945
|
+
|
|
946
|
+
test("computedVariants changes extended variant from string to number", () => {
|
|
947
|
+
const base = cv({
|
|
948
|
+
variants: { size: { sm: "text-sm", md: "text-md", lg: "text-lg" } },
|
|
949
|
+
});
|
|
950
|
+
const component = getModalComponent(
|
|
951
|
+
mode,
|
|
952
|
+
cv({
|
|
953
|
+
extend: [base],
|
|
954
|
+
computedVariants: {
|
|
955
|
+
size: (value: number) => ({
|
|
956
|
+
class: "text-custom",
|
|
957
|
+
fontSize: `${value}px`,
|
|
958
|
+
}),
|
|
959
|
+
},
|
|
960
|
+
}),
|
|
961
|
+
);
|
|
962
|
+
component({
|
|
963
|
+
// @ts-expect-error
|
|
964
|
+
size: "sm",
|
|
965
|
+
});
|
|
966
|
+
const props = component({ size: 18 });
|
|
967
|
+
expect(getStyleClass(props)).toEqual({
|
|
968
|
+
class: cls("text-custom"),
|
|
969
|
+
fontSize: "18px",
|
|
970
|
+
});
|
|
971
|
+
});
|
|
972
|
+
|
|
973
|
+
test("computed", () => {
|
|
974
|
+
const component = getModalComponent(
|
|
975
|
+
mode,
|
|
976
|
+
cv({
|
|
977
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
978
|
+
computed: ({ variants }) =>
|
|
979
|
+
variants.size === "lg" ? "computed-lg" : null,
|
|
980
|
+
}),
|
|
981
|
+
);
|
|
982
|
+
const props = component({ size: "lg" });
|
|
983
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg computed-lg") });
|
|
984
|
+
});
|
|
985
|
+
|
|
986
|
+
test("computed with setVariants", () => {
|
|
987
|
+
const component = getModalComponent(
|
|
988
|
+
mode,
|
|
989
|
+
cv({
|
|
990
|
+
variants: {
|
|
991
|
+
size: { sm: "sm", lg: "lg" },
|
|
992
|
+
color: { red: "red", blue: "blue" },
|
|
993
|
+
},
|
|
994
|
+
computed: ({ variants, setVariants }) => {
|
|
995
|
+
if (variants.size === "lg") {
|
|
996
|
+
setVariants({ color: "red" });
|
|
997
|
+
}
|
|
998
|
+
},
|
|
999
|
+
}),
|
|
1000
|
+
);
|
|
1001
|
+
const props = component({ size: "lg" });
|
|
1002
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg red") });
|
|
1003
|
+
});
|
|
1004
|
+
|
|
1005
|
+
test("computed with setDefaultVariants", () => {
|
|
1006
|
+
const component = getModalComponent(
|
|
1007
|
+
mode,
|
|
1008
|
+
cv({
|
|
1009
|
+
variants: {
|
|
1010
|
+
size: { sm: "sm", lg: "lg" },
|
|
1011
|
+
color: { red: "red", blue: "blue" },
|
|
1012
|
+
},
|
|
1013
|
+
computed: ({ variants, setDefaultVariants }) => {
|
|
1014
|
+
if (variants.size === "lg") {
|
|
1015
|
+
setDefaultVariants({ color: "red" });
|
|
1016
|
+
}
|
|
1017
|
+
},
|
|
1018
|
+
}),
|
|
1019
|
+
);
|
|
1020
|
+
const props = component({ size: "lg" });
|
|
1021
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg red") });
|
|
1022
|
+
});
|
|
1023
|
+
|
|
1024
|
+
test("computed setDefaultVariants does not override props", () => {
|
|
1025
|
+
const component = getModalComponent(
|
|
1026
|
+
mode,
|
|
1027
|
+
cv({
|
|
1028
|
+
variants: {
|
|
1029
|
+
size: { sm: "sm", lg: "lg" },
|
|
1030
|
+
color: { red: "red", blue: "blue" },
|
|
1031
|
+
},
|
|
1032
|
+
computed: ({ setDefaultVariants }) => {
|
|
1033
|
+
setDefaultVariants({ color: "red" });
|
|
1034
|
+
},
|
|
1035
|
+
}),
|
|
1036
|
+
);
|
|
1037
|
+
const props = component({ size: "lg", color: "blue" });
|
|
1038
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg blue") });
|
|
1039
|
+
});
|
|
1040
|
+
|
|
1041
|
+
test("computed with defaultVariants", () => {
|
|
1042
|
+
const component = getModalComponent(
|
|
1043
|
+
mode,
|
|
1044
|
+
cv({
|
|
1045
|
+
variants: {
|
|
1046
|
+
size: { sm: "sm", lg: "lg" },
|
|
1047
|
+
color: { red: "red", blue: "blue" },
|
|
1048
|
+
},
|
|
1049
|
+
defaultVariants: { size: "lg" },
|
|
1050
|
+
computed: ({ variants }) =>
|
|
1051
|
+
variants.size === "lg" ? "computed-lg" : null,
|
|
1052
|
+
}),
|
|
1053
|
+
);
|
|
1054
|
+
const props = component();
|
|
1055
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg computed-lg") });
|
|
1056
|
+
});
|
|
1057
|
+
|
|
1058
|
+
test("computed with defaultVariants from extended", () => {
|
|
1059
|
+
const base = cv({
|
|
1060
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1061
|
+
defaultVariants: { size: "lg" },
|
|
1062
|
+
});
|
|
1063
|
+
const component = getModalComponent(
|
|
1064
|
+
mode,
|
|
1065
|
+
cv({
|
|
1066
|
+
extend: [base],
|
|
1067
|
+
computed: ({ variants }) =>
|
|
1068
|
+
variants.size === "lg" ? "computed-lg" : null,
|
|
1069
|
+
}),
|
|
1070
|
+
);
|
|
1071
|
+
const props = component();
|
|
1072
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg computed-lg") });
|
|
1073
|
+
});
|
|
1074
|
+
|
|
1075
|
+
test("computed with style", () => {
|
|
1076
|
+
const component = getModalComponent(
|
|
1077
|
+
mode,
|
|
1078
|
+
cv({
|
|
1079
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1080
|
+
computed: ({ variants }) =>
|
|
1081
|
+
variants.size === "lg" ? { fontSize: "20px" } : null,
|
|
1082
|
+
}),
|
|
1083
|
+
);
|
|
1084
|
+
const props = component({ size: "lg" });
|
|
1085
|
+
expect(getStyleClass(props)).toEqual({
|
|
1086
|
+
class: cls("lg"),
|
|
1087
|
+
fontSize: "20px",
|
|
1088
|
+
});
|
|
1089
|
+
});
|
|
1090
|
+
|
|
1091
|
+
test("computed with class and style", () => {
|
|
1092
|
+
const component = getModalComponent(
|
|
1093
|
+
mode,
|
|
1094
|
+
cv({
|
|
1095
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1096
|
+
computed: ({ variants }) =>
|
|
1097
|
+
variants.size === "lg"
|
|
1098
|
+
? { class: "computed-lg", fontSize: "20px" }
|
|
1099
|
+
: null,
|
|
1100
|
+
}),
|
|
1101
|
+
);
|
|
1102
|
+
const props = component({ size: "lg" });
|
|
1103
|
+
expect(getStyleClass(props)).toEqual({
|
|
1104
|
+
class: cls("lg computed-lg"),
|
|
1105
|
+
fontSize: "20px",
|
|
1106
|
+
});
|
|
1107
|
+
});
|
|
1108
|
+
|
|
1109
|
+
test("computed style does not accept numbers", () => {
|
|
1110
|
+
const component = getModalComponent(
|
|
1111
|
+
mode,
|
|
1112
|
+
cv({
|
|
1113
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1114
|
+
// @ts-expect-error
|
|
1115
|
+
computed: ({ variants }) =>
|
|
1116
|
+
variants.size === "lg"
|
|
1117
|
+
? {
|
|
1118
|
+
class: "computed-lg",
|
|
1119
|
+
fontSize: 20,
|
|
1120
|
+
}
|
|
1121
|
+
: null,
|
|
1122
|
+
}),
|
|
1123
|
+
);
|
|
1124
|
+
const props = component({ size: "lg" });
|
|
1125
|
+
expect(getStyleClass(props)).toEqual({
|
|
1126
|
+
class: cls("lg computed-lg"),
|
|
1127
|
+
fontSize: expect.toBeOneOf(["20", "20px"]),
|
|
1128
|
+
});
|
|
1129
|
+
});
|
|
1130
|
+
|
|
1131
|
+
test("computed setVariants does not accept invalid keys", () => {
|
|
1132
|
+
const component = getModalComponent(
|
|
1133
|
+
mode,
|
|
1134
|
+
cv({
|
|
1135
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1136
|
+
computed: ({ setVariants }) => {
|
|
1137
|
+
setVariants({
|
|
1138
|
+
// @ts-expect-error
|
|
1139
|
+
invalidKey: "value",
|
|
1140
|
+
});
|
|
1141
|
+
},
|
|
1142
|
+
}),
|
|
1143
|
+
);
|
|
1144
|
+
const props = component({ size: "lg" });
|
|
1145
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg") });
|
|
1146
|
+
});
|
|
1147
|
+
|
|
1148
|
+
test("computed setVariants does not accept invalid values", () => {
|
|
1149
|
+
const component = getModalComponent(
|
|
1150
|
+
mode,
|
|
1151
|
+
cv({
|
|
1152
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1153
|
+
computed: ({ setVariants }) => {
|
|
1154
|
+
setVariants({
|
|
1155
|
+
// @ts-expect-error
|
|
1156
|
+
size: "invalid",
|
|
1157
|
+
});
|
|
1158
|
+
},
|
|
1159
|
+
}),
|
|
1160
|
+
);
|
|
1161
|
+
const props = component({ size: "lg" });
|
|
1162
|
+
// Invalid value overrides the valid one, resulting in no match
|
|
1163
|
+
expect(getStyleClass(props)).toEqual({ class: "" });
|
|
1164
|
+
});
|
|
1165
|
+
|
|
1166
|
+
test("extend single component", () => {
|
|
1167
|
+
const base = cv({ class: "base", variants: { size: { sm: "sm" } } });
|
|
1168
|
+
const component = getModalComponent(
|
|
1169
|
+
mode,
|
|
1170
|
+
cv({ extend: [base], class: "extended" }),
|
|
1171
|
+
);
|
|
1172
|
+
const props = component({ size: "sm" });
|
|
1173
|
+
expect(getStyleClass(props)).toEqual({ class: cls("base extended sm") });
|
|
1174
|
+
});
|
|
1175
|
+
|
|
1176
|
+
test("extend multiple components", () => {
|
|
1177
|
+
const base1 = cv({ class: "base1" });
|
|
1178
|
+
const base2 = cv({ class: "base2" });
|
|
1179
|
+
const component = getModalComponent(
|
|
1180
|
+
mode,
|
|
1181
|
+
cv({ extend: [base1, base2], class: "extended" }),
|
|
1182
|
+
);
|
|
1183
|
+
const props = component();
|
|
1184
|
+
expect(getStyleClass(props)).toEqual({
|
|
1185
|
+
class: cls("base1 base2 extended"),
|
|
1186
|
+
});
|
|
1187
|
+
});
|
|
1188
|
+
|
|
1189
|
+
test("extend with variant merging", () => {
|
|
1190
|
+
const base = cv({ variants: { size: { sm: "base-sm", lg: "base-lg" } } });
|
|
1191
|
+
const component = getModalComponent(
|
|
1192
|
+
mode,
|
|
1193
|
+
cv({ extend: [base], variants: { size: { sm: "extended-sm" } } }),
|
|
1194
|
+
);
|
|
1195
|
+
const props = component({ size: "sm" });
|
|
1196
|
+
expect(getStyleClass(props)).toEqual({
|
|
1197
|
+
class: cls("base-sm extended-sm"),
|
|
1198
|
+
});
|
|
1199
|
+
});
|
|
1200
|
+
|
|
1201
|
+
test("extend with variant merging setting base variant", () => {
|
|
1202
|
+
const base = cv({ variants: { size: { sm: "base-sm", lg: "base-lg" } } });
|
|
1203
|
+
const component = getModalComponent(
|
|
1204
|
+
mode,
|
|
1205
|
+
cv({
|
|
1206
|
+
extend: [base],
|
|
1207
|
+
variants: { size: { sm: "extended-sm" } },
|
|
1208
|
+
}),
|
|
1209
|
+
);
|
|
1210
|
+
const props = component({ size: "lg" });
|
|
1211
|
+
expect(getStyleClass(props)).toEqual({ class: cls("base-lg") });
|
|
1212
|
+
});
|
|
1213
|
+
|
|
1214
|
+
test("extend inherits defaultVariants", () => {
|
|
1215
|
+
const base = cv({
|
|
1216
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1217
|
+
defaultVariants: { size: "sm" },
|
|
1218
|
+
});
|
|
1219
|
+
const component = getModalComponent(mode, cv({ extend: [base] }));
|
|
1220
|
+
const props = component();
|
|
1221
|
+
expect(getStyleClass(props)).toEqual({ class: cls("sm") });
|
|
1222
|
+
});
|
|
1223
|
+
|
|
1224
|
+
test("extend override defaultVariants", () => {
|
|
1225
|
+
const base = cv({
|
|
1226
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1227
|
+
defaultVariants: { size: "sm" },
|
|
1228
|
+
});
|
|
1229
|
+
const component = getModalComponent(
|
|
1230
|
+
mode,
|
|
1231
|
+
cv({ extend: [base], defaultVariants: { size: "lg" } }),
|
|
1232
|
+
);
|
|
1233
|
+
const props = component();
|
|
1234
|
+
expect(getStyleClass(props)).toEqual({ class: cls("lg") });
|
|
1235
|
+
});
|
|
1236
|
+
|
|
1237
|
+
test("class method", () => {
|
|
1238
|
+
const component = getModalComponent(
|
|
1239
|
+
mode,
|
|
1240
|
+
cv({ class: "foo", variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1241
|
+
);
|
|
1242
|
+
const className = component.class({ size: "lg" });
|
|
1243
|
+
expect(className).toBe(cls("foo lg"));
|
|
1244
|
+
});
|
|
1245
|
+
|
|
1246
|
+
test("style method", () => {
|
|
1247
|
+
const component = getModalComponent(
|
|
1248
|
+
mode,
|
|
1249
|
+
cv({ style: { backgroundColor: "red" } }),
|
|
1250
|
+
);
|
|
1251
|
+
const style = component.style();
|
|
1252
|
+
expect(getStyle({ style })).toEqual({ backgroundColor: "red" });
|
|
1253
|
+
});
|
|
1254
|
+
|
|
1255
|
+
test("getVariants returns variant values", () => {
|
|
1256
|
+
const component = getModalComponent(
|
|
1257
|
+
mode,
|
|
1258
|
+
cv({
|
|
1259
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1260
|
+
defaultVariants: { size: "sm" },
|
|
1261
|
+
}),
|
|
1262
|
+
);
|
|
1263
|
+
const variants = component.getVariants({ size: "lg" });
|
|
1264
|
+
expect(variants).toEqual({ size: "lg" });
|
|
1265
|
+
});
|
|
1266
|
+
|
|
1267
|
+
test("getVariants returns default variants", () => {
|
|
1268
|
+
const component = getModalComponent(
|
|
1269
|
+
mode,
|
|
1270
|
+
cv({
|
|
1271
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1272
|
+
defaultVariants: { size: "sm" },
|
|
1273
|
+
}),
|
|
1274
|
+
);
|
|
1275
|
+
const variants = component.getVariants();
|
|
1276
|
+
expect(variants).toEqual({ size: "sm" });
|
|
1277
|
+
});
|
|
1278
|
+
|
|
1279
|
+
test("keys returns props keys", () => {
|
|
1280
|
+
const component = getModalComponent(
|
|
1281
|
+
mode,
|
|
1282
|
+
cv({ variants: { size: { sm: "sm" }, color: { red: "red" } } }),
|
|
1283
|
+
);
|
|
1284
|
+
expectTypeOf(component.keys).toExtend<
|
|
1285
|
+
("class" | "className" | "style" | "size" | "color")[]
|
|
1286
|
+
>();
|
|
1287
|
+
expect(component.keys).toEqual([
|
|
1288
|
+
getClassPropertyName(config),
|
|
1289
|
+
"style",
|
|
1290
|
+
"size",
|
|
1291
|
+
"color",
|
|
1292
|
+
]);
|
|
1293
|
+
});
|
|
1294
|
+
|
|
1295
|
+
test("splitProps separates variant props", () => {
|
|
1296
|
+
const component = getModalComponent(
|
|
1297
|
+
mode,
|
|
1298
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1299
|
+
);
|
|
1300
|
+
const classNameProp = getClassPropertyName(config);
|
|
1301
|
+
const props: HTMLProperties<typeof component> = {
|
|
1302
|
+
id: "test",
|
|
1303
|
+
size: "lg",
|
|
1304
|
+
style: { color: "red" },
|
|
1305
|
+
[classNameProp]: "extra",
|
|
1306
|
+
};
|
|
1307
|
+
const [variantProps, otherProps] = splitProps(props, component);
|
|
1308
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<
|
|
1309
|
+
Pick<
|
|
1310
|
+
HTMLProperties<typeof component>,
|
|
1311
|
+
"size" | "style" | "class" | "className"
|
|
1312
|
+
>
|
|
1313
|
+
>();
|
|
1314
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
1315
|
+
expect(variantProps).toEqual({
|
|
1316
|
+
size: "lg",
|
|
1317
|
+
style: { color: "red" },
|
|
1318
|
+
[classNameProp]: "extra",
|
|
1319
|
+
});
|
|
1320
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1321
|
+
});
|
|
1322
|
+
|
|
1323
|
+
test("onlyVariants splitProps", () => {
|
|
1324
|
+
const component = getModalComponent(
|
|
1325
|
+
mode,
|
|
1326
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1327
|
+
);
|
|
1328
|
+
const classNameProp = getClassPropertyName(config);
|
|
1329
|
+
const props: HTMLProperties<typeof component> = {
|
|
1330
|
+
size: "lg",
|
|
1331
|
+
id: "test",
|
|
1332
|
+
style: "color: red;",
|
|
1333
|
+
[classNameProp]: "extra",
|
|
1334
|
+
};
|
|
1335
|
+
const [variantProps, otherProps] = splitProps(
|
|
1336
|
+
props,
|
|
1337
|
+
component.onlyVariants,
|
|
1338
|
+
);
|
|
1339
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<{
|
|
1340
|
+
size?: "sm" | "lg";
|
|
1341
|
+
}>();
|
|
1342
|
+
expectTypeOf(otherProps).toEqualTypeOf<
|
|
1343
|
+
Pick<
|
|
1344
|
+
HTMLProperties<typeof component>,
|
|
1345
|
+
"id" | "style" | "class" | "className"
|
|
1346
|
+
>
|
|
1347
|
+
>();
|
|
1348
|
+
expect(variantProps).toEqual({ size: "lg" });
|
|
1349
|
+
expect(otherProps).toEqual({
|
|
1350
|
+
id: "test",
|
|
1351
|
+
style: "color: red;",
|
|
1352
|
+
[classNameProp]: "extra",
|
|
1353
|
+
});
|
|
1354
|
+
});
|
|
1355
|
+
|
|
1356
|
+
test("onlyVariants getVariants", () => {
|
|
1357
|
+
const component = getModalComponent(
|
|
1358
|
+
mode,
|
|
1359
|
+
cv({
|
|
1360
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1361
|
+
defaultVariants: { size: "sm" },
|
|
1362
|
+
}),
|
|
1363
|
+
);
|
|
1364
|
+
const variants = component.onlyVariants.getVariants({ size: "lg" });
|
|
1365
|
+
expect(variants).toEqual({ size: "lg" });
|
|
1366
|
+
});
|
|
1367
|
+
|
|
1368
|
+
test("onlyVariants keys", () => {
|
|
1369
|
+
const component = cv({
|
|
1370
|
+
variants: { size: { sm: "sm" }, color: { red: "red" } },
|
|
1371
|
+
});
|
|
1372
|
+
expectTypeOf(component.onlyVariants.keys).toEqualTypeOf<
|
|
1373
|
+
("size" | "color")[]
|
|
1374
|
+
>();
|
|
1375
|
+
expect(component.onlyVariants.keys).toEqual(
|
|
1376
|
+
expect.arrayContaining(["size", "color"]),
|
|
1377
|
+
);
|
|
1378
|
+
});
|
|
1379
|
+
|
|
1380
|
+
test("splitProps includes defaultVariants", () => {
|
|
1381
|
+
const component = getModalComponent(
|
|
1382
|
+
mode,
|
|
1383
|
+
cv({
|
|
1384
|
+
variants: { size: { sm: "sm", lg: "lg" }, color: { red: "red" } },
|
|
1385
|
+
defaultVariants: { size: "sm", color: "red" },
|
|
1386
|
+
}),
|
|
1387
|
+
);
|
|
1388
|
+
const props: HTMLProperties<typeof component> = {
|
|
1389
|
+
id: "test",
|
|
1390
|
+
size: "lg",
|
|
1391
|
+
};
|
|
1392
|
+
const [variantProps, otherProps] = splitProps(props, component);
|
|
1393
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<
|
|
1394
|
+
Pick<
|
|
1395
|
+
HTMLProperties<typeof component>,
|
|
1396
|
+
"size" | "color" | "style" | "class" | "className"
|
|
1397
|
+
>
|
|
1398
|
+
>();
|
|
1399
|
+
expect(variantProps).toEqual({
|
|
1400
|
+
size: "lg",
|
|
1401
|
+
color: "red",
|
|
1402
|
+
});
|
|
1403
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
1404
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1405
|
+
});
|
|
1406
|
+
|
|
1407
|
+
test("splitProps with key array as second parameter", () => {
|
|
1408
|
+
const component = getModalComponent(
|
|
1409
|
+
mode,
|
|
1410
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1411
|
+
);
|
|
1412
|
+
const classNameProp = getClassPropertyName(config);
|
|
1413
|
+
const props: HTMLProperties<typeof component> & { disabled?: boolean } = {
|
|
1414
|
+
id: "test",
|
|
1415
|
+
size: "lg",
|
|
1416
|
+
style: { color: "red" },
|
|
1417
|
+
[classNameProp]: "extra",
|
|
1418
|
+
disabled: true,
|
|
1419
|
+
};
|
|
1420
|
+
const [variantProps, extraProps, otherProps] = splitProps(
|
|
1421
|
+
props,
|
|
1422
|
+
component,
|
|
1423
|
+
["disabled"],
|
|
1424
|
+
);
|
|
1425
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<
|
|
1426
|
+
Pick<
|
|
1427
|
+
HTMLProperties<typeof component>,
|
|
1428
|
+
"size" | "style" | "class" | "className"
|
|
1429
|
+
>
|
|
1430
|
+
>();
|
|
1431
|
+
expect(variantProps).toEqual({
|
|
1432
|
+
size: "lg",
|
|
1433
|
+
style: { color: "red" },
|
|
1434
|
+
[classNameProp]: "extra",
|
|
1435
|
+
});
|
|
1436
|
+
expectTypeOf(extraProps).branded.toEqualTypeOf<{ disabled?: boolean }>();
|
|
1437
|
+
expect(extraProps).toEqual({ disabled: true });
|
|
1438
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
1439
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1440
|
+
});
|
|
1441
|
+
|
|
1442
|
+
test("splitProps with another component as parameter", () => {
|
|
1443
|
+
const component1 = getModalComponent(
|
|
1444
|
+
mode,
|
|
1445
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1446
|
+
);
|
|
1447
|
+
const component2 = getModalComponent(
|
|
1448
|
+
mode,
|
|
1449
|
+
cv({
|
|
1450
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
1451
|
+
defaultVariants: { color: "red" },
|
|
1452
|
+
}),
|
|
1453
|
+
);
|
|
1454
|
+
const classNameProp = getClassPropertyName(config);
|
|
1455
|
+
const props: HTMLProperties<typeof component1> &
|
|
1456
|
+
HTMLProperties<typeof component2> = {
|
|
1457
|
+
id: "test",
|
|
1458
|
+
size: "lg",
|
|
1459
|
+
color: "blue",
|
|
1460
|
+
[classNameProp]: "extra",
|
|
1461
|
+
};
|
|
1462
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1463
|
+
props,
|
|
1464
|
+
component1,
|
|
1465
|
+
component2,
|
|
1466
|
+
);
|
|
1467
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<
|
|
1468
|
+
Pick<
|
|
1469
|
+
HTMLProperties<typeof component1>,
|
|
1470
|
+
"size" | "style" | "class" | "className"
|
|
1471
|
+
>
|
|
1472
|
+
>();
|
|
1473
|
+
expect(comp1Props).toEqual({
|
|
1474
|
+
size: "lg",
|
|
1475
|
+
[classNameProp]: "extra",
|
|
1476
|
+
});
|
|
1477
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<
|
|
1478
|
+
Pick<
|
|
1479
|
+
HTMLProperties<typeof component2>,
|
|
1480
|
+
"color" | "style" | "class" | "className"
|
|
1481
|
+
>
|
|
1482
|
+
>();
|
|
1483
|
+
expect(comp2Props).toEqual({
|
|
1484
|
+
color: "blue",
|
|
1485
|
+
[classNameProp]: "extra",
|
|
1486
|
+
});
|
|
1487
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
1488
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1489
|
+
});
|
|
1490
|
+
|
|
1491
|
+
test("splitProps with component parameter includes component defaults", () => {
|
|
1492
|
+
const component1 = getModalComponent(
|
|
1493
|
+
mode,
|
|
1494
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1495
|
+
);
|
|
1496
|
+
const component2 = getModalComponent(
|
|
1497
|
+
mode,
|
|
1498
|
+
cv({
|
|
1499
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
1500
|
+
defaultVariants: { color: "red" },
|
|
1501
|
+
}),
|
|
1502
|
+
);
|
|
1503
|
+
const props: HTMLProperties<typeof component1> &
|
|
1504
|
+
HTMLProperties<typeof component2> = {
|
|
1505
|
+
id: "test",
|
|
1506
|
+
size: "lg",
|
|
1507
|
+
};
|
|
1508
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1509
|
+
props,
|
|
1510
|
+
component1,
|
|
1511
|
+
component2,
|
|
1512
|
+
);
|
|
1513
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
1514
|
+
expect(comp2Props).toEqual({ color: "red" });
|
|
1515
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1516
|
+
});
|
|
1517
|
+
|
|
1518
|
+
test("splitProps with onlyVariants component excludes class and style", () => {
|
|
1519
|
+
const component1 = getModalComponent(
|
|
1520
|
+
mode,
|
|
1521
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1522
|
+
);
|
|
1523
|
+
const component2 = getModalComponent(
|
|
1524
|
+
mode,
|
|
1525
|
+
cv({ variants: { color: { red: "red", blue: "blue" } } }),
|
|
1526
|
+
);
|
|
1527
|
+
const classNameProp = getClassPropertyName(config);
|
|
1528
|
+
const props: HTMLProperties<typeof component1> &
|
|
1529
|
+
HTMLProperties<typeof component2> = {
|
|
1530
|
+
id: "test",
|
|
1531
|
+
size: "lg",
|
|
1532
|
+
color: "blue",
|
|
1533
|
+
style: { backgroundColor: "yellow" },
|
|
1534
|
+
[classNameProp]: "extra",
|
|
1535
|
+
};
|
|
1536
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1537
|
+
props,
|
|
1538
|
+
component1,
|
|
1539
|
+
component2.onlyVariants,
|
|
1540
|
+
);
|
|
1541
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<
|
|
1542
|
+
Pick<
|
|
1543
|
+
HTMLProperties<typeof component1>,
|
|
1544
|
+
"size" | "style" | "class" | "className"
|
|
1545
|
+
>
|
|
1546
|
+
>();
|
|
1547
|
+
expect(comp1Props).toEqual({
|
|
1548
|
+
size: "lg",
|
|
1549
|
+
style: { backgroundColor: "yellow" },
|
|
1550
|
+
[classNameProp]: "extra",
|
|
1551
|
+
});
|
|
1552
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<{
|
|
1553
|
+
color?: "red" | "blue";
|
|
1554
|
+
}>();
|
|
1555
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
1556
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
1557
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1558
|
+
});
|
|
1559
|
+
|
|
1560
|
+
test("splitProps with multiple parameters", () => {
|
|
1561
|
+
const component1 = getModalComponent(
|
|
1562
|
+
mode,
|
|
1563
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1564
|
+
);
|
|
1565
|
+
const component2 = getModalComponent(
|
|
1566
|
+
mode,
|
|
1567
|
+
cv({ variants: { color: { red: "red", blue: "blue" } } }),
|
|
1568
|
+
);
|
|
1569
|
+
const props: HTMLProperties<typeof component1> &
|
|
1570
|
+
HTMLProperties<typeof component2> & { disabled?: boolean } = {
|
|
1571
|
+
id: "test",
|
|
1572
|
+
size: "lg",
|
|
1573
|
+
color: "blue",
|
|
1574
|
+
disabled: true,
|
|
1575
|
+
};
|
|
1576
|
+
const [comp1Props, extraProps, comp2Props, otherProps] = splitProps(
|
|
1577
|
+
props,
|
|
1578
|
+
component1,
|
|
1579
|
+
["disabled"],
|
|
1580
|
+
component2.onlyVariants,
|
|
1581
|
+
);
|
|
1582
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
1583
|
+
expect(extraProps).toEqual({ disabled: true });
|
|
1584
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
1585
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1586
|
+
});
|
|
1587
|
+
|
|
1588
|
+
test("splitProps with shared keys between components", () => {
|
|
1589
|
+
const component1 = getModalComponent(
|
|
1590
|
+
mode,
|
|
1591
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1592
|
+
);
|
|
1593
|
+
const component2 = getModalComponent(
|
|
1594
|
+
mode,
|
|
1595
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1596
|
+
);
|
|
1597
|
+
const props: HTMLProperties<typeof component1> &
|
|
1598
|
+
HTMLProperties<typeof component2> = {
|
|
1599
|
+
id: "test",
|
|
1600
|
+
size: "lg",
|
|
1601
|
+
};
|
|
1602
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1603
|
+
props,
|
|
1604
|
+
component1,
|
|
1605
|
+
component2.onlyVariants,
|
|
1606
|
+
);
|
|
1607
|
+
expectTypeOf(comp1Props).branded.toEqualTypeOf<
|
|
1608
|
+
Pick<
|
|
1609
|
+
HTMLProperties<typeof component1>,
|
|
1610
|
+
"size" | "style" | "class" | "className"
|
|
1611
|
+
>
|
|
1612
|
+
>();
|
|
1613
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
1614
|
+
expectTypeOf(comp2Props).branded.toEqualTypeOf<{
|
|
1615
|
+
size?: "sm" | "lg";
|
|
1616
|
+
}>();
|
|
1617
|
+
expect(comp2Props).toEqual({ size: "lg" });
|
|
1618
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1619
|
+
});
|
|
1620
|
+
|
|
1621
|
+
test("splitProps with defaultVariants from multiple components", () => {
|
|
1622
|
+
const component1 = getModalComponent(
|
|
1623
|
+
mode,
|
|
1624
|
+
cv({
|
|
1625
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1626
|
+
defaultVariants: { size: "sm" },
|
|
1627
|
+
}),
|
|
1628
|
+
);
|
|
1629
|
+
const component2 = getModalComponent(
|
|
1630
|
+
mode,
|
|
1631
|
+
cv({
|
|
1632
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
1633
|
+
defaultVariants: { color: "red" },
|
|
1634
|
+
}),
|
|
1635
|
+
);
|
|
1636
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1637
|
+
{ id: "test" },
|
|
1638
|
+
component1,
|
|
1639
|
+
component2.onlyVariants,
|
|
1640
|
+
);
|
|
1641
|
+
// Each gets its own defaults
|
|
1642
|
+
expect(comp1Props).toEqual({ size: "sm" });
|
|
1643
|
+
expect(comp2Props).toEqual({ color: "red" });
|
|
1644
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1645
|
+
});
|
|
1646
|
+
|
|
1647
|
+
test("onlyVariants splitProps includes defaultVariants", () => {
|
|
1648
|
+
const component = getModalComponent(
|
|
1649
|
+
mode,
|
|
1650
|
+
cv({
|
|
1651
|
+
variants: { size: { sm: "sm", lg: "lg" }, color: { red: "red" } },
|
|
1652
|
+
defaultVariants: { size: "sm", color: "red" },
|
|
1653
|
+
}),
|
|
1654
|
+
);
|
|
1655
|
+
const classNameProp = getClassPropertyName(config);
|
|
1656
|
+
const props: HTMLProperties<typeof component> = {
|
|
1657
|
+
id: "test",
|
|
1658
|
+
size: "lg",
|
|
1659
|
+
[classNameProp]: "extra",
|
|
1660
|
+
};
|
|
1661
|
+
const [variantProps, otherProps] = splitProps(
|
|
1662
|
+
props,
|
|
1663
|
+
component.onlyVariants,
|
|
1664
|
+
);
|
|
1665
|
+
expect(variantProps).toEqual({
|
|
1666
|
+
size: "lg",
|
|
1667
|
+
color: "red",
|
|
1668
|
+
});
|
|
1669
|
+
expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
|
|
1670
|
+
});
|
|
1671
|
+
|
|
1672
|
+
test("onlyVariants splitProps with key array", () => {
|
|
1673
|
+
const component = getModalComponent(
|
|
1674
|
+
mode,
|
|
1675
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1676
|
+
);
|
|
1677
|
+
const classNameProp = getClassPropertyName(config);
|
|
1678
|
+
const props: HTMLProperties<typeof component> & { disabled?: boolean } = {
|
|
1679
|
+
id: "test",
|
|
1680
|
+
size: "lg",
|
|
1681
|
+
[classNameProp]: "extra",
|
|
1682
|
+
disabled: true,
|
|
1683
|
+
};
|
|
1684
|
+
const [variantProps, extraProps, otherProps] = splitProps(
|
|
1685
|
+
props,
|
|
1686
|
+
component.onlyVariants,
|
|
1687
|
+
["disabled"],
|
|
1688
|
+
);
|
|
1689
|
+
expect(variantProps).toEqual({ size: "lg" });
|
|
1690
|
+
expect(extraProps).toEqual({ disabled: true });
|
|
1691
|
+
expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
|
|
1692
|
+
});
|
|
1693
|
+
|
|
1694
|
+
test("onlyVariants splitProps with component", () => {
|
|
1695
|
+
const component1 = getModalComponent(
|
|
1696
|
+
mode,
|
|
1697
|
+
cv({
|
|
1698
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1699
|
+
defaultVariants: { size: "sm" },
|
|
1700
|
+
}),
|
|
1701
|
+
);
|
|
1702
|
+
const component2 = getModalComponent(
|
|
1703
|
+
mode,
|
|
1704
|
+
cv({
|
|
1705
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
1706
|
+
defaultVariants: { color: "red" },
|
|
1707
|
+
}),
|
|
1708
|
+
);
|
|
1709
|
+
const classNameProp = getClassPropertyName(config);
|
|
1710
|
+
const props: HTMLProperties<typeof component1> &
|
|
1711
|
+
HTMLProperties<typeof component2> = {
|
|
1712
|
+
id: "test",
|
|
1713
|
+
size: "lg",
|
|
1714
|
+
color: "blue",
|
|
1715
|
+
[classNameProp]: "extra",
|
|
1716
|
+
};
|
|
1717
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1718
|
+
props,
|
|
1719
|
+
component1.onlyVariants,
|
|
1720
|
+
component2.onlyVariants,
|
|
1721
|
+
);
|
|
1722
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
1723
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
1724
|
+
expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
|
|
1725
|
+
});
|
|
1726
|
+
|
|
1727
|
+
test("splitProps includes defaultVariants", () => {
|
|
1728
|
+
const component = getModalComponent(
|
|
1729
|
+
mode,
|
|
1730
|
+
cv({
|
|
1731
|
+
variants: { size: { sm: "sm", lg: "lg" }, color: { red: "red" } },
|
|
1732
|
+
defaultVariants: { size: "sm", color: "red" },
|
|
1733
|
+
}),
|
|
1734
|
+
);
|
|
1735
|
+
const props: HTMLProperties<typeof component> = {
|
|
1736
|
+
id: "test",
|
|
1737
|
+
size: "lg",
|
|
1738
|
+
};
|
|
1739
|
+
const [variantProps, otherProps] = splitProps(props, component);
|
|
1740
|
+
expectTypeOf(variantProps).branded.toEqualTypeOf<
|
|
1741
|
+
Pick<
|
|
1742
|
+
HTMLProperties<typeof component>,
|
|
1743
|
+
"size" | "color" | "style" | "class" | "className"
|
|
1744
|
+
>
|
|
1745
|
+
>();
|
|
1746
|
+
expect(variantProps).toEqual({ size: "lg", color: "red" });
|
|
1747
|
+
expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
|
|
1748
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1749
|
+
});
|
|
1750
|
+
|
|
1751
|
+
test("splitProps with key array as second parameter", () => {
|
|
1752
|
+
const component = getModalComponent(
|
|
1753
|
+
mode,
|
|
1754
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1755
|
+
);
|
|
1756
|
+
const classNameProp = getClassPropertyName(config);
|
|
1757
|
+
const props: HTMLProperties<typeof component> & { disabled?: boolean } = {
|
|
1758
|
+
id: "test",
|
|
1759
|
+
size: "lg",
|
|
1760
|
+
style: { color: "red" },
|
|
1761
|
+
[classNameProp]: "extra",
|
|
1762
|
+
disabled: true,
|
|
1763
|
+
};
|
|
1764
|
+
const [variantProps, extraProps, otherProps] = splitProps(
|
|
1765
|
+
props,
|
|
1766
|
+
component,
|
|
1767
|
+
["disabled"],
|
|
1768
|
+
);
|
|
1769
|
+
expect(variantProps).toEqual({
|
|
1770
|
+
size: "lg",
|
|
1771
|
+
style: { color: "red" },
|
|
1772
|
+
[classNameProp]: "extra",
|
|
1773
|
+
});
|
|
1774
|
+
expect(extraProps).toEqual({ disabled: true });
|
|
1775
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1776
|
+
});
|
|
1777
|
+
|
|
1778
|
+
test("splitProps with another component as parameter", () => {
|
|
1779
|
+
const component1 = getModalComponent(
|
|
1780
|
+
mode,
|
|
1781
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1782
|
+
);
|
|
1783
|
+
const component2 = getModalComponent(
|
|
1784
|
+
mode,
|
|
1785
|
+
cv({
|
|
1786
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
1787
|
+
defaultVariants: { color: "red" },
|
|
1788
|
+
}),
|
|
1789
|
+
);
|
|
1790
|
+
const classNameProp = getClassPropertyName(config);
|
|
1791
|
+
const props: HTMLProperties<typeof component1> &
|
|
1792
|
+
HTMLProperties<typeof component2> = {
|
|
1793
|
+
id: "test",
|
|
1794
|
+
size: "lg",
|
|
1795
|
+
color: "blue",
|
|
1796
|
+
[classNameProp]: "extra",
|
|
1797
|
+
};
|
|
1798
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1799
|
+
props,
|
|
1800
|
+
component1,
|
|
1801
|
+
component2,
|
|
1802
|
+
);
|
|
1803
|
+
expect(comp1Props).toEqual({
|
|
1804
|
+
size: "lg",
|
|
1805
|
+
[classNameProp]: "extra",
|
|
1806
|
+
});
|
|
1807
|
+
// component2 has class/style keys too, and defaultVariants
|
|
1808
|
+
expect(comp2Props).toEqual({
|
|
1809
|
+
color: "blue",
|
|
1810
|
+
[classNameProp]: "extra",
|
|
1811
|
+
});
|
|
1812
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1813
|
+
});
|
|
1814
|
+
|
|
1815
|
+
test("splitProps with component parameter includes component defaults", () => {
|
|
1816
|
+
const component1 = getModalComponent(
|
|
1817
|
+
mode,
|
|
1818
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1819
|
+
);
|
|
1820
|
+
const component2 = getModalComponent(
|
|
1821
|
+
mode,
|
|
1822
|
+
cv({
|
|
1823
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
1824
|
+
defaultVariants: { color: "red" },
|
|
1825
|
+
}),
|
|
1826
|
+
);
|
|
1827
|
+
const props: HTMLProperties<typeof component1> &
|
|
1828
|
+
HTMLProperties<typeof component2> = {
|
|
1829
|
+
id: "test",
|
|
1830
|
+
size: "lg",
|
|
1831
|
+
};
|
|
1832
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1833
|
+
props,
|
|
1834
|
+
component1,
|
|
1835
|
+
component2,
|
|
1836
|
+
);
|
|
1837
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
1838
|
+
// component2's defaults should be included
|
|
1839
|
+
expect(comp2Props).toEqual({ color: "red" });
|
|
1840
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1841
|
+
});
|
|
1842
|
+
|
|
1843
|
+
test("splitProps with onlyVariants component excludes class and style", () => {
|
|
1844
|
+
const component1 = getModalComponent(
|
|
1845
|
+
mode,
|
|
1846
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1847
|
+
);
|
|
1848
|
+
const component2 = getModalComponent(
|
|
1849
|
+
mode,
|
|
1850
|
+
cv({ variants: { color: { red: "red", blue: "blue" } } }),
|
|
1851
|
+
);
|
|
1852
|
+
const classNameProp = getClassPropertyName(config);
|
|
1853
|
+
const props: HTMLProperties<typeof component1> &
|
|
1854
|
+
HTMLProperties<typeof component2> = {
|
|
1855
|
+
id: "test",
|
|
1856
|
+
size: "lg",
|
|
1857
|
+
color: "blue",
|
|
1858
|
+
style: { backgroundColor: "yellow" },
|
|
1859
|
+
[classNameProp]: "extra",
|
|
1860
|
+
};
|
|
1861
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1862
|
+
props,
|
|
1863
|
+
component1,
|
|
1864
|
+
component2.onlyVariants,
|
|
1865
|
+
);
|
|
1866
|
+
expect(comp1Props).toEqual({
|
|
1867
|
+
size: "lg",
|
|
1868
|
+
style: { backgroundColor: "yellow" },
|
|
1869
|
+
[classNameProp]: "extra",
|
|
1870
|
+
});
|
|
1871
|
+
// onlyVariants only gets color, not class/style
|
|
1872
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
1873
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1874
|
+
});
|
|
1875
|
+
|
|
1876
|
+
test("splitProps with multiple parameters", () => {
|
|
1877
|
+
const component1 = getModalComponent(
|
|
1878
|
+
mode,
|
|
1879
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1880
|
+
);
|
|
1881
|
+
const component2 = getModalComponent(
|
|
1882
|
+
mode,
|
|
1883
|
+
cv({ variants: { color: { red: "red", blue: "blue" } } }),
|
|
1884
|
+
);
|
|
1885
|
+
const props: HTMLProperties<typeof component1> &
|
|
1886
|
+
HTMLProperties<typeof component2> & { disabled?: boolean } = {
|
|
1887
|
+
id: "test",
|
|
1888
|
+
size: "lg",
|
|
1889
|
+
color: "blue",
|
|
1890
|
+
disabled: true,
|
|
1891
|
+
};
|
|
1892
|
+
const [comp1Props, extraProps, comp2Props, otherProps] = splitProps(
|
|
1893
|
+
props,
|
|
1894
|
+
component1,
|
|
1895
|
+
["disabled"],
|
|
1896
|
+
component2.onlyVariants,
|
|
1897
|
+
);
|
|
1898
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
1899
|
+
expect(extraProps).toEqual({ disabled: true });
|
|
1900
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
1901
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1902
|
+
});
|
|
1903
|
+
|
|
1904
|
+
test("splitProps with shared keys between components", () => {
|
|
1905
|
+
const component1 = getModalComponent(
|
|
1906
|
+
mode,
|
|
1907
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1908
|
+
);
|
|
1909
|
+
const component2 = getModalComponent(
|
|
1910
|
+
mode,
|
|
1911
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1912
|
+
);
|
|
1913
|
+
const props: HTMLProperties<typeof component1> &
|
|
1914
|
+
HTMLProperties<typeof component2> = {
|
|
1915
|
+
id: "test",
|
|
1916
|
+
size: "lg",
|
|
1917
|
+
};
|
|
1918
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1919
|
+
props,
|
|
1920
|
+
component1,
|
|
1921
|
+
component2.onlyVariants,
|
|
1922
|
+
);
|
|
1923
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
1924
|
+
// size should appear in both
|
|
1925
|
+
expect(comp2Props).toEqual({ size: "lg" });
|
|
1926
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1927
|
+
});
|
|
1928
|
+
|
|
1929
|
+
test("splitProps with defaultVariants from multiple components", () => {
|
|
1930
|
+
const component1 = getModalComponent(
|
|
1931
|
+
mode,
|
|
1932
|
+
cv({
|
|
1933
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
1934
|
+
defaultVariants: { size: "sm" },
|
|
1935
|
+
}),
|
|
1936
|
+
);
|
|
1937
|
+
const component2 = getModalComponent(
|
|
1938
|
+
mode,
|
|
1939
|
+
cv({
|
|
1940
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
1941
|
+
defaultVariants: { color: "red" },
|
|
1942
|
+
}),
|
|
1943
|
+
);
|
|
1944
|
+
const props: HTMLProperties<typeof component1> &
|
|
1945
|
+
HTMLProperties<typeof component2> = {
|
|
1946
|
+
id: "test",
|
|
1947
|
+
};
|
|
1948
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
1949
|
+
props,
|
|
1950
|
+
component1,
|
|
1951
|
+
component2.onlyVariants,
|
|
1952
|
+
);
|
|
1953
|
+
// Each gets its own defaults
|
|
1954
|
+
expect(comp1Props).toEqual({ size: "sm" });
|
|
1955
|
+
expect(comp2Props).toEqual({ color: "red" });
|
|
1956
|
+
expect(otherProps).toEqual({ id: "test" });
|
|
1957
|
+
});
|
|
1958
|
+
|
|
1959
|
+
test("onlyVariants splitProps includes defaultVariants", () => {
|
|
1960
|
+
const component = getModalComponent(
|
|
1961
|
+
mode,
|
|
1962
|
+
cv({
|
|
1963
|
+
variants: { size: { sm: "sm", lg: "lg" }, color: { red: "red" } },
|
|
1964
|
+
defaultVariants: { size: "sm", color: "red" },
|
|
1965
|
+
}),
|
|
1966
|
+
);
|
|
1967
|
+
const classNameProp = getClassPropertyName(config);
|
|
1968
|
+
const props: HTMLProperties<typeof component> = {
|
|
1969
|
+
id: "test",
|
|
1970
|
+
size: "lg",
|
|
1971
|
+
[classNameProp]: "extra",
|
|
1972
|
+
};
|
|
1973
|
+
const [variantProps, otherProps] = splitProps(
|
|
1974
|
+
props,
|
|
1975
|
+
component.onlyVariants,
|
|
1976
|
+
);
|
|
1977
|
+
expect(variantProps).toEqual({
|
|
1978
|
+
size: "lg",
|
|
1979
|
+
color: "red",
|
|
1980
|
+
});
|
|
1981
|
+
expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
|
|
1982
|
+
});
|
|
1983
|
+
|
|
1984
|
+
test("onlyVariants splitProps with key array", () => {
|
|
1985
|
+
const component = getModalComponent(
|
|
1986
|
+
mode,
|
|
1987
|
+
cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
|
|
1988
|
+
);
|
|
1989
|
+
const classNameProp = getClassPropertyName(config);
|
|
1990
|
+
const props: HTMLProperties<typeof component> & { disabled?: boolean } = {
|
|
1991
|
+
id: "test",
|
|
1992
|
+
size: "lg",
|
|
1993
|
+
[classNameProp]: "extra",
|
|
1994
|
+
disabled: true,
|
|
1995
|
+
};
|
|
1996
|
+
const [variantProps, extraProps, otherProps] = splitProps(
|
|
1997
|
+
props,
|
|
1998
|
+
component.onlyVariants,
|
|
1999
|
+
["disabled"],
|
|
2000
|
+
);
|
|
2001
|
+
expect(variantProps).toEqual({ size: "lg" });
|
|
2002
|
+
expect(extraProps).toEqual({ disabled: true });
|
|
2003
|
+
expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
|
|
2004
|
+
});
|
|
2005
|
+
|
|
2006
|
+
test("onlyVariants splitProps with component", () => {
|
|
2007
|
+
const component1 = getModalComponent(
|
|
2008
|
+
mode,
|
|
2009
|
+
cv({
|
|
2010
|
+
variants: { size: { sm: "sm", lg: "lg" } },
|
|
2011
|
+
defaultVariants: { size: "sm" },
|
|
2012
|
+
}),
|
|
2013
|
+
);
|
|
2014
|
+
const component2 = getModalComponent(
|
|
2015
|
+
mode,
|
|
2016
|
+
cv({
|
|
2017
|
+
variants: { color: { red: "red", blue: "blue" } },
|
|
2018
|
+
defaultVariants: { color: "red" },
|
|
2019
|
+
}),
|
|
2020
|
+
);
|
|
2021
|
+
const classNameProp = getClassPropertyName(config);
|
|
2022
|
+
const props: HTMLProperties<typeof component1> &
|
|
2023
|
+
HTMLProperties<typeof component2> = {
|
|
2024
|
+
id: "test",
|
|
2025
|
+
size: "lg",
|
|
2026
|
+
color: "blue",
|
|
2027
|
+
[classNameProp]: "extra",
|
|
2028
|
+
};
|
|
2029
|
+
const [comp1Props, comp2Props, otherProps] = splitProps(
|
|
2030
|
+
props,
|
|
2031
|
+
component1.onlyVariants,
|
|
2032
|
+
component2.onlyVariants,
|
|
2033
|
+
);
|
|
2034
|
+
expect(comp1Props).toEqual({ size: "lg" });
|
|
2035
|
+
expect(comp2Props).toEqual({ color: "blue" });
|
|
2036
|
+
expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
|
|
2037
|
+
});
|
|
2038
|
+
});
|
|
2039
|
+
}
|