tailwind-variants 0.0.20 → 0.0.21

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.
@@ -0,0 +1,1019 @@
1
+ import {tv} from "../index";
2
+
3
+ const resultArray = (result: string) => result.split(" ");
4
+
5
+ const expectTv = (result: string, expectedResult: string[]) => {
6
+ expect(resultArray(result)).toEqual(expect.arrayContaining(expectedResult));
7
+ };
8
+
9
+ const expectKeys = (result: string[], expectedResult: string[]) => {
10
+ expect(result).toEqual(expect.arrayContaining(expectedResult));
11
+ };
12
+
13
+ describe("Tailwind Variants (TV)", () => {
14
+ test("should work without variants", () => {
15
+ const h1 = tv({
16
+ base: "text-3xl font-bold",
17
+ });
18
+
19
+ const expectedResult = "text-3xl font-bold";
20
+ const result = h1();
21
+
22
+ expect(result).toBe(expectedResult);
23
+ });
24
+
25
+ test("should work with variants", () => {
26
+ const h1 = tv({
27
+ base: "text-3xl font-bold",
28
+ variants: {
29
+ isBig: {
30
+ true: "text-5xl",
31
+ false: "text-2xl",
32
+ },
33
+ color: {
34
+ red: "text-red-500",
35
+ blue: "text-blue-500",
36
+ },
37
+ },
38
+ });
39
+
40
+ const result = h1({
41
+ isBig: true,
42
+ color: "blue",
43
+ });
44
+
45
+ const expectedResult = ["text-5xl", "font-bold", "text-blue-500"];
46
+
47
+ expectTv(result, expectedResult);
48
+ });
49
+
50
+ test("should work with variantkeys", () => {
51
+ const h1 = tv({
52
+ base: "text-3xl font-bold",
53
+ variants: {
54
+ isBig: {
55
+ true: "text-5xl",
56
+ false: "text-2xl",
57
+ },
58
+ color: {
59
+ red: "text-red-500",
60
+ blue: "text-blue-500",
61
+ },
62
+ },
63
+ });
64
+
65
+ const expectedResult = ["isBig", "color"];
66
+
67
+ expectKeys(h1.variantkeys, expectedResult);
68
+ });
69
+
70
+ test("should work with compoundVariants", () => {
71
+ const h1 = tv({
72
+ base: "text-3xl font-bold",
73
+ variants: {
74
+ isBig: {
75
+ true: "text-5xl",
76
+ false: "text-2xl",
77
+ },
78
+ color: {
79
+ red: "text-red-500",
80
+ blue: "text-blue-500",
81
+ },
82
+ },
83
+ compoundVariants: [
84
+ {
85
+ isBig: true,
86
+ color: "red",
87
+ class: "bg-red-500",
88
+ },
89
+ ],
90
+ });
91
+
92
+ const result = h1({
93
+ isBig: true,
94
+ color: "red",
95
+ });
96
+
97
+ const expectedResult = ["text-5xl", "font-bold", "text-red-500", "bg-red-500"];
98
+
99
+ expectTv(result, expectedResult);
100
+ });
101
+
102
+ test("should throw error if the compoundVariants is not an array", () => {
103
+ expect(
104
+ tv({
105
+ base: "text-3xl font-bold",
106
+ variants: {
107
+ isBig: {
108
+ true: "text-5xl",
109
+ false: "text-2xl",
110
+ },
111
+ color: {
112
+ red: "text-red-500",
113
+ blue: "text-blue-500",
114
+ },
115
+ },
116
+ // @ts-expect-error
117
+ compoundVariants: {},
118
+ }),
119
+ ).toThrow();
120
+ });
121
+
122
+ test("should work with custom class & className", () => {
123
+ const h1 = tv({
124
+ base: "text-3xl font-bold",
125
+ });
126
+
127
+ const expectedResult = ["text-3xl", "font-bold"];
128
+
129
+ const result1 = h1({
130
+ className: "my-class",
131
+ });
132
+ const result2 = h1({
133
+ class: "my-class",
134
+ });
135
+
136
+ expectTv(result1, expectedResult);
137
+ expectTv(result2, expectedResult);
138
+ });
139
+
140
+ test("should work without anything", () => {
141
+ const styles = tv({});
142
+ const expectedResult = "";
143
+
144
+ expect(styles()).toBe(expectedResult);
145
+ });
146
+
147
+ test("should work correctly with twMerge", () => {
148
+ const h1 = tv({
149
+ base: "text-3xl font-bold text-blue-400 text-xl text-blue-200",
150
+ });
151
+
152
+ const expectedResult = ["font-bold", "text-xl", "text-blue-200"];
153
+
154
+ expectTv(h1(), expectedResult);
155
+ });
156
+
157
+ test("should work correctly without twMerge", () => {
158
+ const h1 = tv(
159
+ {
160
+ base: "text-3xl font-bold text-blue-400 text-xl text-blue-200",
161
+ },
162
+ {
163
+ twMerge: false,
164
+ },
165
+ );
166
+
167
+ const expectedResult = ["text-3xl", "font-bold", "text-blue-400", "text-xl", "text-blue-200"];
168
+
169
+ expectTv(h1(), expectedResult);
170
+ });
171
+
172
+ test("should work without defaultsVariants", () => {
173
+ const button = tv({
174
+ base: "button",
175
+ variants: {
176
+ variant: {
177
+ primary: "button--primary",
178
+ secondary: "button--secondary",
179
+ warning: "button--warning",
180
+ error: "button--danger",
181
+ },
182
+ isDisabled: {
183
+ true: "button--disabled",
184
+ false: "button--enabled",
185
+ },
186
+ size: {
187
+ small: "button--small",
188
+ medium: "button--medium",
189
+ large: "button--large",
190
+ },
191
+ },
192
+ compoundVariants: [
193
+ {
194
+ variant: "secondary",
195
+ size: "small",
196
+ class: "button--secondary-small",
197
+ },
198
+ {
199
+ variant: "warning",
200
+ isDisabled: false,
201
+ class: "button--warning-enabled",
202
+ },
203
+ {
204
+ variant: "warning",
205
+ isDisabled: true,
206
+ class: "button--warning-disabled",
207
+ },
208
+ {
209
+ variant: ["warning", "error"],
210
+ class: "button--warning-danger",
211
+ },
212
+ {
213
+ variant: ["warning", "error"],
214
+ size: "medium",
215
+ class: "button--warning-danger-medium",
216
+ },
217
+ ],
218
+ });
219
+
220
+ const expectedResult = [
221
+ "button",
222
+ "button--secondary",
223
+ "button--small",
224
+ "button--enabled",
225
+ "button--secondary-small",
226
+ ];
227
+
228
+ expectTv(button({variant: "secondary", size: "small", isDisabled: false}), expectedResult);
229
+ });
230
+
231
+ test("should work with simple variants", () => {
232
+ const h1 = tv({
233
+ base: "text-3xl font-bold underline",
234
+ variants: {
235
+ color: {
236
+ red: "text-red-500",
237
+ blue: "text-blue-500",
238
+ green: "text-green-500",
239
+ },
240
+ isUnderline: {
241
+ true: "underline",
242
+ false: "no-underline",
243
+ },
244
+ },
245
+ });
246
+
247
+ const expectedResult = "text-3xl font-bold text-green-500 no-underline";
248
+
249
+ expect(h1({color: "green", isUnderline: false})).toBe(expectedResult);
250
+ });
251
+
252
+ test("should work with slots -- default variants", () => {
253
+ const menu = tv({
254
+ base: "text-3xl font-bold underline",
255
+ slots: {
256
+ title: "text-2xl",
257
+ item: "text-xl",
258
+ list: "list-none",
259
+ wrapper: "flex flex-col",
260
+ },
261
+ variants: {
262
+ color: {
263
+ primary: "color--primary",
264
+ secondary: {
265
+ title: "color--primary-title",
266
+ item: "color--primary-item",
267
+ list: "color--primary-list",
268
+ wrapper: "color--primary-wrapper",
269
+ },
270
+ },
271
+ size: {
272
+ xs: "size--xs",
273
+ sm: "size--sm",
274
+ md: {
275
+ title: "size--md-title",
276
+ },
277
+ },
278
+ isDisabled: {
279
+ true: {
280
+ title: "disabled--title",
281
+ },
282
+ false: {
283
+ item: "enabled--item",
284
+ },
285
+ },
286
+ },
287
+ defaultVariants: {
288
+ color: "primary",
289
+ size: "sm",
290
+ isDisabled: false,
291
+ },
292
+ });
293
+
294
+ // with default values
295
+ const {base, title, item, list, wrapper} = menu();
296
+
297
+ expectTv(base(), ["text-3xl", "font-bold", "underline", "color--primary", "size--sm"]);
298
+ expectTv(title(), ["text-2xl"]);
299
+ expectTv(item(), ["text-xl", "enabled--item"]);
300
+ expectTv(list(), ["list-none"]);
301
+ expectTv(wrapper(), ["flex", "flex-col"]);
302
+ });
303
+
304
+ test("should work with empty slots", () => {
305
+ const menu = tv({
306
+ slots: {
307
+ base: "",
308
+ title: "",
309
+ item: "",
310
+ list: "",
311
+ },
312
+ });
313
+
314
+ const {base, title, item, list} = menu();
315
+
316
+ expectTv(base(), []);
317
+ expectTv(title(), []);
318
+ expectTv(item(), []);
319
+ expectTv(list(), []);
320
+ });
321
+
322
+ test("should work with slots -- default variants -- custom class & className", () => {
323
+ const menu = tv({
324
+ base: "text-3xl font-bold underline",
325
+ slots: {
326
+ title: "text-2xl",
327
+ item: "text-xl",
328
+ list: "list-none",
329
+ wrapper: "flex flex-col",
330
+ },
331
+ variants: {
332
+ color: {
333
+ primary: "color--primary",
334
+ secondary: {
335
+ title: "color--primary-title",
336
+ item: "color--primary-item",
337
+ list: "color--primary-list",
338
+ wrapper: "color--primary-wrapper",
339
+ },
340
+ },
341
+ size: {
342
+ xs: "size--xs",
343
+ sm: "size--sm",
344
+ md: {
345
+ title: "size--md-title",
346
+ },
347
+ },
348
+ isDisabled: {
349
+ true: {
350
+ title: "disabled--title",
351
+ },
352
+ false: {
353
+ item: "enabled--item",
354
+ },
355
+ },
356
+ },
357
+ defaultVariants: {
358
+ color: "primary",
359
+ size: "sm",
360
+ isDisabled: false,
361
+ },
362
+ });
363
+
364
+ // with default values
365
+ const {base, title, item, list, wrapper} = menu();
366
+
367
+ expectTv(base({class: "class--base"}), [
368
+ "text-3xl",
369
+ "font-bold",
370
+ "underline",
371
+ "color--primary",
372
+ "size--sm",
373
+ "class--base",
374
+ ]);
375
+ expectTv(title({className: "classname--title"}), ["text-2xl", "classname--title"]);
376
+ expectTv(item({class: "class--item"}), ["text-xl", "enabled--item", "class--item"]);
377
+ expectTv(list({className: "classname--list"}), ["list-none", "classname--list"]);
378
+ expectTv(wrapper({class: "class--wrapper"}), ["flex", "flex-col", "class--wrapper"]);
379
+ });
380
+
381
+ test("should work with slots -- custom variants", () => {
382
+ const menu = tv({
383
+ base: "text-3xl font-bold underline",
384
+ slots: {
385
+ title: "text-2xl",
386
+ item: "text-xl",
387
+ list: "list-none",
388
+ wrapper: "flex flex-col",
389
+ },
390
+ variants: {
391
+ color: {
392
+ primary: "color--primary",
393
+ secondary: {
394
+ base: "color--secondary-base",
395
+ title: "color--secondary-title",
396
+ item: "color--secondary-item",
397
+ list: "color--secondary-list",
398
+ wrapper: "color--secondary-wrapper",
399
+ },
400
+ },
401
+ size: {
402
+ xs: "size--xs",
403
+ sm: "size--sm",
404
+ md: {
405
+ title: "size--md-title",
406
+ },
407
+ },
408
+ isDisabled: {
409
+ true: {
410
+ title: "disabled--title",
411
+ },
412
+ false: {
413
+ item: "enabled--item",
414
+ },
415
+ },
416
+ },
417
+ defaultVariants: {
418
+ color: "primary",
419
+ size: "sm",
420
+ isDisabled: false,
421
+ },
422
+ });
423
+
424
+ // with custom props
425
+ const {base, title, item, list, wrapper} = menu({
426
+ color: "secondary",
427
+ size: "md",
428
+ });
429
+
430
+ expectTv(base(), ["text-3xl", "font-bold", "underline", "color--secondary-base"]);
431
+ expectTv(title(), ["size--md-title", "color--secondary-title"]);
432
+ expectTv(item(), ["text-xl", "color--secondary-item"]);
433
+ expectTv(list(), ["list-none", "color--secondary-list"]);
434
+ expectTv(wrapper(), ["flex", "flex-col", "color--secondary-wrapper"]);
435
+ });
436
+
437
+ test("should work with slots -- custom variants -- custom class & className", () => {
438
+ const menu = tv({
439
+ base: "text-3xl font-bold underline",
440
+ slots: {
441
+ title: "text-2xl",
442
+ item: "text-xl",
443
+ list: "list-none",
444
+ wrapper: "flex flex-col",
445
+ },
446
+ variants: {
447
+ color: {
448
+ primary: "color--primary",
449
+ secondary: {
450
+ base: "color--secondary-base",
451
+ title: "color--secondary-title",
452
+ item: "color--secondary-item",
453
+ list: "color--secondary-list",
454
+ wrapper: "color--secondary-wrapper",
455
+ },
456
+ },
457
+ size: {
458
+ xs: "size--xs",
459
+ sm: "size--sm",
460
+ md: {
461
+ title: "size--md-title",
462
+ },
463
+ },
464
+ isDisabled: {
465
+ true: {
466
+ title: "disabled--title",
467
+ },
468
+ false: {
469
+ item: "enabled--item",
470
+ },
471
+ },
472
+ },
473
+ defaultVariants: {
474
+ color: "primary",
475
+ size: "sm",
476
+ isDisabled: false,
477
+ },
478
+ });
479
+
480
+ // with default values
481
+ const {base, title, item, list, wrapper} = menu({
482
+ color: "secondary",
483
+ size: "md",
484
+ });
485
+
486
+ expectTv(base({class: "class--base"}), [
487
+ "text-3xl",
488
+ "font-bold",
489
+ "underline",
490
+ "color--secondary-base",
491
+ "class--base",
492
+ ]);
493
+ expectTv(
494
+ title({
495
+ className: "classname--title",
496
+ }),
497
+ ["size--md-title", "color--secondary-title", "classname--title"],
498
+ );
499
+ expectTv(
500
+ item({
501
+ class: "class--item",
502
+ }),
503
+ ["text-xl", "color--secondary-item", "class--item"],
504
+ );
505
+ expectTv(
506
+ list({
507
+ className: "classname--list",
508
+ }),
509
+ ["list-none", "color--secondary-list", "classname--list"],
510
+ );
511
+ expectTv(
512
+ wrapper({
513
+ class: "class--wrapper",
514
+ }),
515
+ ["flex", "flex-col", "color--secondary-wrapper", "class--wrapper"],
516
+ );
517
+ });
518
+
519
+ test("should work with slots and compoundVariants", () => {
520
+ const menu = tv({
521
+ base: "text-3xl font-bold underline",
522
+ slots: {
523
+ title: "text-2xl",
524
+ item: "text-xl",
525
+ list: "list-none",
526
+ wrapper: "flex flex-col",
527
+ },
528
+ variants: {
529
+ color: {
530
+ primary: "color--primary",
531
+ secondary: {
532
+ base: "color--secondary-base",
533
+ title: "color--secondary-title",
534
+ item: "color--secondary-item",
535
+ list: "color--secondary-list",
536
+ wrapper: "color--secondary-wrapper",
537
+ },
538
+ },
539
+ size: {
540
+ xs: "size--xs",
541
+
542
+ sm: "size--sm",
543
+ md: {
544
+ title: "size--md-title",
545
+ },
546
+ },
547
+ isDisabled: {
548
+ true: {
549
+ title: "disabled--title",
550
+ },
551
+ false: {
552
+ item: "enabled--item",
553
+ },
554
+ },
555
+ },
556
+ defaultVariants: {
557
+ color: "primary",
558
+ size: "sm",
559
+ isDisabled: false,
560
+ },
561
+ compoundVariants: [
562
+ {
563
+ color: "secondary",
564
+ size: "md",
565
+ class: {
566
+ base: "compound--base",
567
+ title: "compound--title",
568
+ item: "compound--item",
569
+ list: "compound--list",
570
+ wrapper: "compound--wrapper",
571
+ },
572
+ },
573
+ ],
574
+ });
575
+
576
+ const {base, title, item, list, wrapper} = menu({
577
+ color: "secondary",
578
+ size: "md",
579
+ });
580
+
581
+ expectTv(base(), [
582
+ "text-3xl",
583
+ "font-bold",
584
+ "underline",
585
+ "color--secondary-base",
586
+ "compound--base",
587
+ ]);
588
+ expectTv(title(), ["size--md-title", "color--secondary-title", "compound--title"]);
589
+ expectTv(item(), ["text-xl", "color--secondary-item", "enabled--item", "compound--item"]);
590
+ expectTv(list(), ["list-none", "color--secondary-list", "compound--list"]);
591
+ expectTv(wrapper(), ["flex", "flex-col", "color--secondary-wrapper", "compound--wrapper"]);
592
+ });
593
+
594
+ test("should work with screenVariants/initial screen", () => {
595
+ const button = tv({
596
+ base: "text-xs font-bold",
597
+ variants: {
598
+ color: {
599
+ primary: "text-blue-500",
600
+ secondary: "text-purple-500",
601
+ success: "text-green-500",
602
+ danger: "text-red-500",
603
+ },
604
+ size: {
605
+ sm: "text-sm",
606
+ md: "text-md",
607
+ lg: "text-lg",
608
+ },
609
+ variant: {
610
+ outline: "border border-blue-500",
611
+ solid: "bg-blue-500",
612
+ ghost: "bg-transparent hover:bg-blue-500",
613
+ },
614
+ },
615
+ });
616
+
617
+ const result = button({
618
+ color: {
619
+ initial: "primary",
620
+ xs: "danger",
621
+ sm: "success",
622
+ },
623
+ });
624
+
625
+ const expectedResult = [
626
+ "text-xs",
627
+ "font-bold",
628
+ "text-blue-500",
629
+ "xs:text-red-500",
630
+ "sm:text-green-500",
631
+ ];
632
+
633
+ expectTv(result, expectedResult);
634
+ });
635
+
636
+ test("the screenVariants/initial should override the defaultVariants", () => {
637
+ const button = tv({
638
+ base: "text-xs font-bold",
639
+ variants: {
640
+ color: {
641
+ primary: "text-blue-500",
642
+ secondary: "text-purple-500",
643
+ success: "text-green-500",
644
+ danger: "text-red-500",
645
+ },
646
+ size: {
647
+ sm: "text-sm",
648
+ md: "text-md",
649
+ lg: "text-lg",
650
+ },
651
+ variant: {
652
+ outline: "border border-blue-500",
653
+ solid: "bg-blue-500",
654
+ ghost: "bg-transparent hover:bg-blue-500",
655
+ },
656
+ },
657
+ defaultVariants: {
658
+ color: "primary",
659
+ size: "sm",
660
+ },
661
+ });
662
+
663
+ const result = button({
664
+ color: {
665
+ initial: "secondary",
666
+ },
667
+ size: {
668
+ initial: "md",
669
+ },
670
+ });
671
+
672
+ const expectedResult = ["font-bold", "text-purple-500", "text-md"];
673
+
674
+ expectTv(result, expectedResult);
675
+ });
676
+
677
+ test("should work with multiple screenVariants single values", () => {
678
+ const button = tv({
679
+ base: "base--styles",
680
+ variants: {
681
+ color: {
682
+ primary: "color--primary",
683
+ secondary: "color--secondary",
684
+ success: "color--success",
685
+ danger: "color--danger",
686
+ },
687
+ size: {
688
+ mini: "size--mini",
689
+ small: "size--small",
690
+ medium: "size--medium",
691
+ large: "size--large",
692
+ },
693
+ variant: {
694
+ outline: "variant--outline",
695
+ solid: "variant--solid",
696
+ ghost: "variant--ghost",
697
+ },
698
+ },
699
+ });
700
+
701
+ const result = button({
702
+ color: {
703
+ initial: "primary",
704
+ xs: "success",
705
+ sm: "secondary",
706
+ md: "danger",
707
+ },
708
+ size: {
709
+ initial: "medium",
710
+ xs: "mini",
711
+ sm: "small",
712
+ md: "medium",
713
+ },
714
+ variant: {
715
+ initial: "solid",
716
+ xs: "outline",
717
+ sm: "outline",
718
+ md: "solid",
719
+ },
720
+ });
721
+
722
+ const expectedResult = [
723
+ "base--styles",
724
+ "color--primary",
725
+ "xs:color--success",
726
+ "sm:color--secondary",
727
+ "md:color--danger",
728
+ "size--medium",
729
+ "xs:size--mini",
730
+ "sm:size--small",
731
+ "md:size--medium",
732
+ "variant--solid",
733
+ "xs:variant--outline",
734
+ "sm:variant--outline",
735
+ "md:variant--solid",
736
+ ];
737
+
738
+ expectTv(result, expectedResult);
739
+ });
740
+
741
+ test("should work with multiple screenVariants multiple values (strings)", () => {
742
+ const button = tv({
743
+ base: "base--styles",
744
+ variants: {
745
+ color: {
746
+ primary: "color--primary-1 color--primary-2 color--primary-3",
747
+ secondary: "color--secondary-1 color--secondary-2 color--secondary-3",
748
+ success: "color--success-1 color--success-2 color--success-3",
749
+ danger: "color--danger color--danger-2 color--danger-3",
750
+ },
751
+ size: {
752
+ mini: "size--mini-1 size--mini-2 size--mini-3",
753
+ small: "size--small-1 size--small-2 size--small-3",
754
+ medium: "size--medium-1 size--medium-2 size--medium-3",
755
+ large: "size--large-1 size--large-2 size--large-3",
756
+ },
757
+ variant: {
758
+ outline: "variant--outline-1 variant--outline-2 variant--outline-3",
759
+ solid: "variant--solid-1 variant--solid-2 variant--solid-3",
760
+ ghost: "variant--ghost-1 variant--ghost-2 variant--ghost-3",
761
+ },
762
+ },
763
+ });
764
+
765
+ const result = button({
766
+ color: {
767
+ initial: "primary",
768
+ xs: "success",
769
+ sm: "secondary",
770
+ md: "danger",
771
+ },
772
+ size: {
773
+ initial: "medium",
774
+ xs: "mini",
775
+ sm: "small",
776
+ md: "medium",
777
+ },
778
+ variant: {
779
+ initial: "solid",
780
+ xs: "outline",
781
+ sm: "outline",
782
+ md: "solid",
783
+ },
784
+ });
785
+
786
+ const expectedResult = [
787
+ "base--styles",
788
+ "color--primary-1",
789
+ "color--primary-2",
790
+ "color--primary-3",
791
+ "xs:color--success-1",
792
+ "xs:color--success-2",
793
+ "xs:color--success-3",
794
+ "sm:color--secondary-1",
795
+ "sm:color--secondary-2",
796
+ "sm:color--secondary-3",
797
+ "md:color--danger",
798
+ "md:color--danger-2",
799
+ "md:color--danger-3",
800
+ "size--medium-1",
801
+ "size--medium-2",
802
+ "size--medium-3",
803
+ "xs:size--mini-1",
804
+ "xs:size--mini-2",
805
+ "xs:size--mini-3",
806
+ "sm:size--small-1",
807
+ "sm:size--small-2",
808
+ "sm:size--small-3",
809
+ "md:size--medium-1",
810
+ "md:size--medium-2",
811
+ "md:size--medium-3",
812
+ "variant--solid-1",
813
+ "variant--solid-2",
814
+ "variant--solid-3",
815
+ "xs:variant--outline-1",
816
+ "xs:variant--outline-2",
817
+ "xs:variant--outline-3",
818
+ "sm:variant--outline-1",
819
+ "sm:variant--outline-2",
820
+ "sm:variant--outline-3",
821
+ "md:variant--solid-1",
822
+ "md:variant--solid-2",
823
+ "md:variant--solid-3",
824
+ ];
825
+
826
+ expectTv(result, expectedResult);
827
+ });
828
+
829
+ test("should work with multiple screenVariants multiple values (array)", () => {
830
+ const button = tv({
831
+ base: "base--styles",
832
+ variants: {
833
+ color: {
834
+ primary: ["color--primary-1", "color--primary-2", "color--primary-3"],
835
+ secondary: ["color--secondary-1", "color--secondary-2", "color--secondary-3"],
836
+ success: ["color--success-1", "color--success-2", "color--success-3"],
837
+ danger: ["color--danger", "color--danger-2", "color--danger-3"],
838
+ },
839
+ size: {
840
+ mini: ["size--mini-1", "size--mini-2", "size--mini-3"],
841
+ small: ["size--small-1", "size--small-2", "size--small-3"],
842
+ medium: ["size--medium-1", "size--medium-2", "size--medium-3"],
843
+ large: ["size--large-1", "size--large-2", "size--large-3"],
844
+ },
845
+ variant: {
846
+ outline: ["variant--outline-1", "variant--outline-2", "variant--outline-3"],
847
+ solid: ["variant--solid-1", "variant--solid-2", "variant--solid-3"],
848
+ ghost: ["variant--ghost-1", "variant--ghost-2", "variant--ghost-3"],
849
+ },
850
+ },
851
+ });
852
+
853
+ const result = button({
854
+ color: {
855
+ initial: "primary",
856
+ xs: "success",
857
+ sm: "secondary",
858
+ md: "danger",
859
+ },
860
+ size: {
861
+ initial: "medium",
862
+ xs: "mini",
863
+ sm: "small",
864
+ md: "medium",
865
+ },
866
+ variant: {
867
+ initial: "solid",
868
+ xs: "outline",
869
+ sm: "outline",
870
+ md: "solid",
871
+ },
872
+ });
873
+
874
+ const expectedResult = [
875
+ "base--styles",
876
+ "color--primary-1",
877
+ "color--primary-2",
878
+ "color--primary-3",
879
+ "xs:color--success-1",
880
+ "xs:color--success-2",
881
+ "xs:color--success-3",
882
+ "sm:color--secondary-1",
883
+ "sm:color--secondary-2",
884
+ "sm:color--secondary-3",
885
+ "md:color--danger",
886
+ "md:color--danger-2",
887
+ "md:color--danger-3",
888
+ "size--medium-1",
889
+ "size--medium-2",
890
+ "size--medium-3",
891
+ "xs:size--mini-1",
892
+ "xs:size--mini-2",
893
+ "xs:size--mini-3",
894
+ "sm:size--small-1",
895
+ "sm:size--small-2",
896
+ "sm:size--small-3",
897
+ "md:size--medium-1",
898
+ "md:size--medium-2",
899
+ "md:size--medium-3",
900
+ "variant--solid-1",
901
+ "variant--solid-2",
902
+ "variant--solid-3",
903
+ "xs:variant--outline-1",
904
+ "xs:variant--outline-2",
905
+ "xs:variant--outline-3",
906
+ "sm:variant--outline-1",
907
+ "sm:variant--outline-2",
908
+ "sm:variant--outline-3",
909
+ "md:variant--solid-1",
910
+ "md:variant--solid-2",
911
+ "md:variant--solid-3",
912
+ ];
913
+
914
+ expectTv(result, expectedResult);
915
+ });
916
+
917
+ test("should work with multiple screenVariants single values and slots", () => {
918
+ const menu = tv({
919
+ base: "base--styles",
920
+ slots: {
921
+ title: "slots--title",
922
+ item: "slots--item",
923
+ list: "slots--list",
924
+ wrapper: "slots--wrapper",
925
+ },
926
+ variants: {
927
+ color: {
928
+ primary: {
929
+ title: "title--color--primary",
930
+ item: "item--color--primary",
931
+ list: "list--color--primary",
932
+ wrapper: "wrapper--color--primary",
933
+ },
934
+ secondary: {
935
+ title: "title--color--secondary",
936
+ item: "item--color--secondary",
937
+ list: "list--color--secondary",
938
+ wrapper: "wrapper--color--secondary",
939
+ },
940
+ },
941
+ size: {
942
+ small: {
943
+ title: "title--size--small",
944
+ item: "item--size--small",
945
+ list: "list--size--small",
946
+ wrapper: "wrapper--size--small",
947
+ },
948
+ medium: {
949
+ title: "title--size--medium",
950
+ item: "item--size--medium",
951
+ list: "list--size--medium",
952
+ wrapper: "wrapper--size--medium",
953
+ },
954
+ },
955
+ },
956
+ });
957
+
958
+ const {base, title, item, list, wrapper} = menu({
959
+ color: {
960
+ initial: "primary",
961
+ xs: "secondary",
962
+ sm: "primary",
963
+ md: "secondary",
964
+ },
965
+ size: {
966
+ initial: "medium",
967
+ xs: "small",
968
+ sm: "medium",
969
+ md: "medium",
970
+ },
971
+ });
972
+
973
+ expectTv(base(), ["base--styles"]);
974
+ expectTv(title(), [
975
+ "slots--title",
976
+ "xs:title--color--secondary",
977
+ "sm:title--color--primary",
978
+ "md:title--color--secondary",
979
+ "title--color--primary",
980
+ "xs:title--size--small",
981
+ "sm:title--size--medium",
982
+ "md:title--size--medium",
983
+ "title--size--medium",
984
+ ]);
985
+ expectTv(item(), [
986
+ "slots--item",
987
+ "xs:item--color--secondary",
988
+ "sm:item--color--primary",
989
+ "md:item--color--secondary",
990
+ "item--color--primary",
991
+ "xs:item--size--small",
992
+ "sm:item--size--medium",
993
+ "md:item--size--medium",
994
+ "item--size--medium",
995
+ ]);
996
+ expectTv(list(), [
997
+ "slots--list",
998
+ "xs:list--color--secondary",
999
+ "sm:list--color--primary",
1000
+ "md:list--color--secondary",
1001
+ "list--color--primary",
1002
+ "xs:list--size--small",
1003
+ "sm:list--size--medium",
1004
+ "md:list--size--medium",
1005
+ "list--size--medium",
1006
+ ]);
1007
+ expectTv(wrapper(), [
1008
+ "slots--wrapper",
1009
+ "xs:wrapper--color--secondary",
1010
+ "sm:wrapper--color--primary",
1011
+ "md:wrapper--color--secondary",
1012
+ "wrapper--color--primary",
1013
+ "xs:wrapper--size--small",
1014
+ "sm:wrapper--size--medium",
1015
+ "md:wrapper--size--medium",
1016
+ "wrapper--size--medium",
1017
+ ]);
1018
+ });
1019
+ });