clava 0.1.0 → 0.1.2

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/src/test.ts CHANGED
@@ -1,22 +1,20 @@
1
1
  import { describe, expect, expectTypeOf, test } from "vitest";
2
-
3
2
  import type {
4
3
  AnyComponent,
4
+ Component,
5
5
  ComponentResult,
6
- StyleClassValue,
6
+ ComputedVariants,
7
7
  HTMLCSSProperties,
8
8
  JSXCSSProperties,
9
- Variants,
10
- ComputedVariants,
11
- Component,
9
+ StyleClassValue,
12
10
  StyleProperty,
11
+ Variants,
13
12
  } from "./types.ts";
14
-
15
13
  import {
16
- cv as cvBase,
14
+ type VariantProps,
17
15
  create,
16
+ cv as cvBase,
18
17
  splitProps,
19
- type VariantProps,
20
18
  } from "./index.ts";
21
19
  import {
22
20
  htmlObjStyleToStyleValue,
@@ -88,17 +86,19 @@ function getConfigDescription(config: Config) {
88
86
  return "custom";
89
87
  }
90
88
 
91
- function createCVFromConfig<T extends Config>(config: T) {
89
+ function createCVFromConfig<T extends Config>(
90
+ config: T,
91
+ ): T["defaultMode"] & T["transformClass"] extends never
92
+ ? typeof cvBase
93
+ : ReturnType<typeof create>["cv"] {
92
94
  const defaultMode = getConfigDefaultMode(config);
93
95
  const transformClass = getConfigTransformClass(config);
94
96
  const hasTransform = "transformClass" in config && config.transformClass;
95
97
  if (!defaultMode && !hasTransform) {
96
98
  return cvBase;
97
99
  }
98
- return create({
99
- defaultMode: defaultMode ?? undefined,
100
- transformClass,
101
- }).cv;
100
+ const { cv } = create({ defaultMode: defaultMode ?? "jsx", transformClass });
101
+ return cv as any;
102
102
  }
103
103
 
104
104
  function getModalComponent<
@@ -1038,6 +1038,63 @@ for (const config of Object.values(CONFIGS)) {
1038
1038
  expect(getStyleClass(props)).toEqual({ class: cls("lg blue") });
1039
1039
  });
1040
1040
 
1041
+ test("computed setDefaultVariants overrides 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: "sm", color: "red" },
1050
+ computed: ({ setDefaultVariants }) => {
1051
+ setDefaultVariants({ color: "blue" });
1052
+ },
1053
+ }),
1054
+ );
1055
+ const props = component();
1056
+ expect(getStyleClass(props)).toEqual({ class: cls("sm blue") });
1057
+ });
1058
+
1059
+ test("computed setDefaultVariants overrides extended defaultVariants", () => {
1060
+ const base = cv({
1061
+ variants: { color: { red: "red", blue: "blue" } },
1062
+ defaultVariants: { color: "red" },
1063
+ });
1064
+ const component = getModalComponent(
1065
+ mode,
1066
+ cv({
1067
+ extend: [base],
1068
+ variants: { size: { sm: "sm", lg: "lg" } },
1069
+ defaultVariants: { size: "sm" },
1070
+ computed: ({ setDefaultVariants }) => {
1071
+ setDefaultVariants({ color: "blue" });
1072
+ },
1073
+ }),
1074
+ );
1075
+ const props = component();
1076
+ expect(getStyleClass(props)).toEqual({ class: cls("blue sm") });
1077
+ });
1078
+
1079
+ test("computed setDefaultVariants overrides child defaultVariants", () => {
1080
+ const base = cv({
1081
+ variants: { size: { sm: "sm", lg: "lg" } },
1082
+ });
1083
+ const component = getModalComponent(
1084
+ mode,
1085
+ cv({
1086
+ extend: [base],
1087
+ variants: { color: { red: "red", blue: "blue" } },
1088
+ defaultVariants: { size: "sm", color: "red" },
1089
+ computed: ({ setDefaultVariants }) => {
1090
+ setDefaultVariants({ size: "lg" });
1091
+ },
1092
+ }),
1093
+ );
1094
+ const props = component();
1095
+ expect(getStyleClass(props)).toEqual({ class: cls("lg red") });
1096
+ });
1097
+
1041
1098
  test("computed with defaultVariants", () => {
1042
1099
  const component = getModalComponent(
1043
1100
  mode,
@@ -1306,10 +1363,7 @@ for (const config of Object.values(CONFIGS)) {
1306
1363
  };
1307
1364
  const [variantProps, otherProps] = splitProps(props, component);
1308
1365
  expectTypeOf(variantProps).branded.toEqualTypeOf<
1309
- Pick<
1310
- HTMLProperties<typeof component>,
1311
- "size" | "style" | "class" | "className"
1312
- >
1366
+ Pick<typeof props, "size" | "style" | "class" | "className">
1313
1367
  >();
1314
1368
  expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
1315
1369
  expect(variantProps).toEqual({
@@ -1320,7 +1374,7 @@ for (const config of Object.values(CONFIGS)) {
1320
1374
  expect(otherProps).toEqual({ id: "test" });
1321
1375
  });
1322
1376
 
1323
- test("onlyVariants splitProps", () => {
1377
+ test("variantKeys splitProps", () => {
1324
1378
  const component = getModalComponent(
1325
1379
  mode,
1326
1380
  cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
@@ -1334,16 +1388,13 @@ for (const config of Object.values(CONFIGS)) {
1334
1388
  };
1335
1389
  const [variantProps, otherProps] = splitProps(
1336
1390
  props,
1337
- component.onlyVariants,
1391
+ component.variantKeys,
1338
1392
  );
1339
1393
  expectTypeOf(variantProps).branded.toEqualTypeOf<{
1340
1394
  size?: "sm" | "lg";
1341
1395
  }>();
1342
1396
  expectTypeOf(otherProps).toEqualTypeOf<
1343
- Pick<
1344
- HTMLProperties<typeof component>,
1345
- "id" | "style" | "class" | "className"
1346
- >
1397
+ Pick<typeof props, "id" | "style" | "class" | "className">
1347
1398
  >();
1348
1399
  expect(variantProps).toEqual({ size: "lg" });
1349
1400
  expect(otherProps).toEqual({
@@ -1353,28 +1404,41 @@ for (const config of Object.values(CONFIGS)) {
1353
1404
  });
1354
1405
  });
1355
1406
 
1356
- test("onlyVariants getVariants", () => {
1407
+ test("variantKeys property", () => {
1357
1408
  const component = getModalComponent(
1358
1409
  mode,
1359
1410
  cv({
1360
- variants: { size: { sm: "sm", lg: "lg" } },
1361
- defaultVariants: { size: "sm" },
1411
+ variants: { size: { sm: "sm" }, color: { red: "red" } },
1362
1412
  }),
1363
1413
  );
1364
- const variants = component.onlyVariants.getVariants({ size: "lg" });
1365
- expect(variants).toEqual({ size: "lg" });
1414
+ expectTypeOf(component.variantKeys).toEqualTypeOf<("size" | "color")[]>();
1415
+ expect(component.variantKeys).toEqual(["size", "color"]);
1366
1416
  });
1367
1417
 
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")[]
1418
+ test("propKeys property", () => {
1419
+ const component = getModalComponent(
1420
+ mode,
1421
+ cv({ variants: { size: { sm: "sm" }, color: { red: "red" } } }),
1422
+ );
1423
+ const classNameProp = getClassPropertyName(config);
1424
+ expectTypeOf(component.propKeys).toExtend<
1425
+ ("class" | "className" | "style" | "size" | "color")[]
1374
1426
  >();
1375
- expect(component.onlyVariants.keys).toEqual(
1376
- expect.arrayContaining(["size", "color"]),
1427
+ expect(component.propKeys).toEqual([
1428
+ classNameProp,
1429
+ "style",
1430
+ "size",
1431
+ "color",
1432
+ ]);
1433
+ });
1434
+
1435
+ test("propKeys on different modes", () => {
1436
+ const component = getModalComponent(
1437
+ mode,
1438
+ cv({ variants: { size: { sm: "sm" } } }),
1377
1439
  );
1440
+ const classNameProp = getClassPropertyName(config);
1441
+ expect(component.propKeys).toEqual([classNameProp, "style", "size"]);
1378
1442
  });
1379
1443
 
1380
1444
  test("splitProps includes defaultVariants", () => {
@@ -1391,10 +1455,7 @@ for (const config of Object.values(CONFIGS)) {
1391
1455
  };
1392
1456
  const [variantProps, otherProps] = splitProps(props, component);
1393
1457
  expectTypeOf(variantProps).branded.toEqualTypeOf<
1394
- Pick<
1395
- HTMLProperties<typeof component>,
1396
- "size" | "color" | "style" | "class" | "className"
1397
- >
1458
+ Pick<typeof props, "size" | "color" | "style" | "class" | "className">
1398
1459
  >();
1399
1460
  expect(variantProps).toEqual({
1400
1461
  size: "lg",
@@ -1423,10 +1484,7 @@ for (const config of Object.values(CONFIGS)) {
1423
1484
  ["disabled"],
1424
1485
  );
1425
1486
  expectTypeOf(variantProps).branded.toEqualTypeOf<
1426
- Pick<
1427
- HTMLProperties<typeof component>,
1428
- "size" | "style" | "class" | "className"
1429
- >
1487
+ Pick<typeof props, "size" | "style" | "class" | "className">
1430
1488
  >();
1431
1489
  expect(variantProps).toEqual({
1432
1490
  size: "lg",
@@ -1465,24 +1523,19 @@ for (const config of Object.values(CONFIGS)) {
1465
1523
  component2,
1466
1524
  );
1467
1525
  expectTypeOf(comp1Props).branded.toEqualTypeOf<
1468
- Pick<
1469
- HTMLProperties<typeof component1>,
1470
- "size" | "style" | "class" | "className"
1471
- >
1526
+ Pick<typeof props, "size" | "style" | "class" | "className">
1472
1527
  >();
1528
+ // First component gets class/style props
1473
1529
  expect(comp1Props).toEqual({
1474
1530
  size: "lg",
1475
1531
  [classNameProp]: "extra",
1476
1532
  });
1533
+ // Second component only gets variant props (no class/style)
1477
1534
  expectTypeOf(comp2Props).branded.toEqualTypeOf<
1478
- Pick<
1479
- HTMLProperties<typeof component2>,
1480
- "color" | "style" | "class" | "className"
1481
- >
1535
+ Pick<typeof props, "color">
1482
1536
  >();
1483
1537
  expect(comp2Props).toEqual({
1484
1538
  color: "blue",
1485
- [classNameProp]: "extra",
1486
1539
  });
1487
1540
  expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
1488
1541
  expect(otherProps).toEqual({ id: "test" });
@@ -1510,12 +1563,15 @@ for (const config of Object.values(CONFIGS)) {
1510
1563
  component1,
1511
1564
  component2,
1512
1565
  );
1566
+ // First component gets variant props
1513
1567
  expect(comp1Props).toEqual({ size: "lg" });
1568
+ // Second component only gets its own variant defaults (no class/style
1569
+ // since first claimed them)
1514
1570
  expect(comp2Props).toEqual({ color: "red" });
1515
1571
  expect(otherProps).toEqual({ id: "test" });
1516
1572
  });
1517
1573
 
1518
- test("splitProps with onlyVariants component excludes class and style", () => {
1574
+ test("splitProps second component excludes class and style", () => {
1519
1575
  const component1 = getModalComponent(
1520
1576
  mode,
1521
1577
  cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
@@ -1536,19 +1592,18 @@ for (const config of Object.values(CONFIGS)) {
1536
1592
  const [comp1Props, comp2Props, otherProps] = splitProps(
1537
1593
  props,
1538
1594
  component1,
1539
- component2.onlyVariants,
1595
+ component2,
1540
1596
  );
1541
1597
  expectTypeOf(comp1Props).branded.toEqualTypeOf<
1542
- Pick<
1543
- HTMLProperties<typeof component1>,
1544
- "size" | "style" | "class" | "className"
1545
- >
1598
+ Pick<typeof props, "size" | "style" | "class" | "className">
1546
1599
  >();
1600
+ // First component gets class/style
1547
1601
  expect(comp1Props).toEqual({
1548
1602
  size: "lg",
1549
1603
  style: { backgroundColor: "yellow" },
1550
1604
  [classNameProp]: "extra",
1551
1605
  });
1606
+ // Second component only gets variant props
1552
1607
  expectTypeOf(comp2Props).branded.toEqualTypeOf<{
1553
1608
  color?: "red" | "blue";
1554
1609
  }>();
@@ -1577,8 +1632,16 @@ for (const config of Object.values(CONFIGS)) {
1577
1632
  props,
1578
1633
  component1,
1579
1634
  ["disabled"],
1580
- component2.onlyVariants,
1635
+ component2,
1581
1636
  );
1637
+ expectTypeOf(comp1Props).branded.toEqualTypeOf<
1638
+ Pick<typeof props, "size" | "style" | "class" | "className">
1639
+ >();
1640
+ expectTypeOf(extraProps).branded.toEqualTypeOf<{ disabled?: boolean }>();
1641
+ expectTypeOf(comp2Props).branded.toEqualTypeOf<{
1642
+ color?: "red" | "blue";
1643
+ }>();
1644
+ expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
1582
1645
  expect(comp1Props).toEqual({ size: "lg" });
1583
1646
  expect(extraProps).toEqual({ disabled: true });
1584
1647
  expect(comp2Props).toEqual({ color: "blue" });
@@ -1602,15 +1665,14 @@ for (const config of Object.values(CONFIGS)) {
1602
1665
  const [comp1Props, comp2Props, otherProps] = splitProps(
1603
1666
  props,
1604
1667
  component1,
1605
- component2.onlyVariants,
1668
+ component2,
1606
1669
  );
1607
1670
  expectTypeOf(comp1Props).branded.toEqualTypeOf<
1608
- Pick<
1609
- HTMLProperties<typeof component1>,
1610
- "size" | "style" | "class" | "className"
1611
- >
1671
+ Pick<typeof props, "size" | "style" | "class" | "className">
1612
1672
  >();
1673
+ // First component gets class/style + size
1613
1674
  expect(comp1Props).toEqual({ size: "lg" });
1675
+ // Second component only gets variant props (size appears in both)
1614
1676
  expectTypeOf(comp2Props).branded.toEqualTypeOf<{
1615
1677
  size?: "sm" | "lg";
1616
1678
  }>();
@@ -1636,15 +1698,20 @@ for (const config of Object.values(CONFIGS)) {
1636
1698
  const [comp1Props, comp2Props, otherProps] = splitProps(
1637
1699
  { id: "test" },
1638
1700
  component1,
1639
- component2.onlyVariants,
1701
+ component2,
1640
1702
  );
1641
1703
  // Each gets its own defaults
1704
+ expectTypeOf(comp1Props).branded.toEqualTypeOf<{ size?: "sm" | "lg" }>();
1642
1705
  expect(comp1Props).toEqual({ size: "sm" });
1706
+ expectTypeOf(comp2Props).branded.toEqualTypeOf<{
1707
+ color?: "red" | "blue";
1708
+ }>();
1643
1709
  expect(comp2Props).toEqual({ color: "red" });
1710
+ expectTypeOf(otherProps).toEqualTypeOf<{ id: string }>();
1644
1711
  expect(otherProps).toEqual({ id: "test" });
1645
1712
  });
1646
1713
 
1647
- test("onlyVariants splitProps includes defaultVariants", () => {
1714
+ test("variantKeys splitProps includes defaultVariants", () => {
1648
1715
  const component = getModalComponent(
1649
1716
  mode,
1650
1717
  cv({
@@ -1660,16 +1727,17 @@ for (const config of Object.values(CONFIGS)) {
1660
1727
  };
1661
1728
  const [variantProps, otherProps] = splitProps(
1662
1729
  props,
1663
- component.onlyVariants,
1730
+ component.variantKeys,
1664
1731
  );
1732
+ // variantKeys is just an array, so no defaults are applied
1665
1733
  expect(variantProps).toEqual({
1666
1734
  size: "lg",
1667
- color: "red",
1668
1735
  });
1736
+ // color is in variantKeys but not in props, so it's not in either result
1669
1737
  expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
1670
1738
  });
1671
1739
 
1672
- test("onlyVariants splitProps with key array", () => {
1740
+ test("variantKeys splitProps with key array", () => {
1673
1741
  const component = getModalComponent(
1674
1742
  mode,
1675
1743
  cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
@@ -1683,15 +1751,22 @@ for (const config of Object.values(CONFIGS)) {
1683
1751
  };
1684
1752
  const [variantProps, extraProps, otherProps] = splitProps(
1685
1753
  props,
1686
- component.onlyVariants,
1754
+ component.variantKeys,
1687
1755
  ["disabled"],
1688
1756
  );
1757
+ expectTypeOf(variantProps).branded.toEqualTypeOf<{
1758
+ size?: "sm" | "lg";
1759
+ }>();
1689
1760
  expect(variantProps).toEqual({ size: "lg" });
1761
+ expectTypeOf(extraProps).branded.toEqualTypeOf<{ disabled?: boolean }>();
1690
1762
  expect(extraProps).toEqual({ disabled: true });
1763
+ expectTypeOf(otherProps).toEqualTypeOf<
1764
+ Pick<typeof props, "id" | "class" | "className" | "style">
1765
+ >();
1691
1766
  expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
1692
1767
  });
1693
1768
 
1694
- test("onlyVariants splitProps with component", () => {
1769
+ test("variantKeys splitProps with component", () => {
1695
1770
  const component1 = getModalComponent(
1696
1771
  mode,
1697
1772
  cv({
@@ -1716,164 +1791,129 @@ for (const config of Object.values(CONFIGS)) {
1716
1791
  };
1717
1792
  const [comp1Props, comp2Props, otherProps] = splitProps(
1718
1793
  props,
1719
- component1.onlyVariants,
1720
- component2.onlyVariants,
1794
+ component1.variantKeys,
1795
+ component2.variantKeys,
1721
1796
  );
1797
+ expectTypeOf(comp1Props).branded.toEqualTypeOf<{ size?: "sm" | "lg" }>();
1722
1798
  expect(comp1Props).toEqual({ size: "lg" });
1799
+ expectTypeOf(comp2Props).branded.toEqualTypeOf<{
1800
+ color?: "red" | "blue";
1801
+ }>();
1723
1802
  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
- >
1803
+ expectTypeOf(otherProps).toEqualTypeOf<
1804
+ Pick<typeof props, "id" | "class" | "className" | "style">
1745
1805
  >();
1746
- expect(variantProps).toEqual({ size: "lg", color: "red" });
1747
- expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
1748
- expect(otherProps).toEqual({ id: "test" });
1806
+ expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
1749
1807
  });
1750
1808
 
1751
- test("splitProps with key array as second parameter", () => {
1809
+ test("splitProps with array containing class before component", () => {
1752
1810
  const component = getModalComponent(
1753
1811
  mode,
1754
1812
  cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
1755
1813
  );
1756
1814
  const classNameProp = getClassPropertyName(config);
1757
- const props: HTMLProperties<typeof component> & { disabled?: boolean } = {
1815
+ const props: HTMLProperties<typeof component> = {
1758
1816
  id: "test",
1759
1817
  size: "lg",
1760
- style: { color: "red" },
1818
+ style: { backgroundColor: "yellow" },
1761
1819
  [classNameProp]: "extra",
1762
- disabled: true,
1763
1820
  };
1764
- const [variantProps, extraProps, otherProps] = splitProps(
1821
+ // Array gets class, component still gets class/style (arrays don't claim styling)
1822
+ const [arrayProps, compProps, otherProps] = splitProps(
1765
1823
  props,
1824
+ [classNameProp],
1766
1825
  component,
1767
- ["disabled"],
1768
1826
  );
1769
- expect(variantProps).toEqual({
1827
+ expectTypeOf(arrayProps).branded.toEqualTypeOf<
1828
+ Pick<typeof props, "class" | "className">
1829
+ >();
1830
+ expect(arrayProps).toEqual({ [classNameProp]: "extra" });
1831
+ // Component still gets class/style since arrays don't claim them
1832
+ expectTypeOf(compProps).branded.toEqualTypeOf<
1833
+ Pick<typeof props, "size" | "style" | "class" | "className">
1834
+ >();
1835
+ expect(compProps).toEqual({
1770
1836
  size: "lg",
1771
- style: { color: "red" },
1837
+ style: { backgroundColor: "yellow" },
1772
1838
  [classNameProp]: "extra",
1773
1839
  });
1774
- expect(extraProps).toEqual({ disabled: true });
1775
1840
  expect(otherProps).toEqual({ id: "test" });
1776
1841
  });
1777
1842
 
1778
- test("splitProps with another component as parameter", () => {
1779
- const component1 = getModalComponent(
1843
+ test("splitProps with array containing class and style before component", () => {
1844
+ const component = getModalComponent(
1780
1845
  mode,
1781
1846
  cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
1782
1847
  );
1783
- const component2 = getModalComponent(
1784
- mode,
1785
- cv({
1786
- variants: { color: { red: "red", blue: "blue" } },
1787
- defaultVariants: { color: "red" },
1788
- }),
1789
- );
1790
1848
  const classNameProp = getClassPropertyName(config);
1791
- const props: HTMLProperties<typeof component1> &
1792
- HTMLProperties<typeof component2> = {
1849
+ const props: HTMLProperties<typeof component> = {
1793
1850
  id: "test",
1794
1851
  size: "lg",
1795
- color: "blue",
1852
+ style: { backgroundColor: "yellow" },
1796
1853
  [classNameProp]: "extra",
1797
1854
  };
1798
- const [comp1Props, comp2Props, otherProps] = splitProps(
1855
+ // Array gets class and style, component still gets class/style (arrays don't claim styling)
1856
+ const [arrayProps, compProps, otherProps] = splitProps(
1799
1857
  props,
1800
- component1,
1801
- component2,
1858
+ [classNameProp, "style"],
1859
+ component,
1802
1860
  );
1803
- expect(comp1Props).toEqual({
1804
- size: "lg",
1861
+ expectTypeOf(arrayProps).branded.toEqualTypeOf<
1862
+ Pick<typeof props, "class" | "className" | "style">
1863
+ >();
1864
+ expect(arrayProps).toEqual({
1805
1865
  [classNameProp]: "extra",
1866
+ style: { backgroundColor: "yellow" },
1806
1867
  });
1807
- // component2 has class/style keys too, and defaultVariants
1808
- expect(comp2Props).toEqual({
1809
- color: "blue",
1868
+ // Component still gets class/style since arrays don't claim them
1869
+ expectTypeOf(compProps).branded.toEqualTypeOf<
1870
+ Pick<typeof props, "size" | "style" | "class" | "className">
1871
+ >();
1872
+ expect(compProps).toEqual({
1873
+ size: "lg",
1874
+ style: { backgroundColor: "yellow" },
1810
1875
  [classNameProp]: "extra",
1811
1876
  });
1812
1877
  expect(otherProps).toEqual({ id: "test" });
1813
1878
  });
1814
1879
 
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(
1880
+ test("splitProps with array after component", () => {
1881
+ const component = getModalComponent(
1845
1882
  mode,
1846
1883
  cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
1847
1884
  );
1848
- const component2 = getModalComponent(
1849
- mode,
1850
- cv({ variants: { color: { red: "red", blue: "blue" } } }),
1851
- );
1852
1885
  const classNameProp = getClassPropertyName(config);
1853
- const props: HTMLProperties<typeof component1> &
1854
- HTMLProperties<typeof component2> = {
1886
+ const props: HTMLProperties<typeof component> = {
1855
1887
  id: "test",
1856
1888
  size: "lg",
1857
- color: "blue",
1858
1889
  style: { backgroundColor: "yellow" },
1859
1890
  [classNameProp]: "extra",
1860
1891
  };
1861
- const [comp1Props, comp2Props, otherProps] = splitProps(
1862
- props,
1863
- component1,
1864
- component2.onlyVariants,
1865
- );
1866
- expect(comp1Props).toEqual({
1892
+ // Component gets class/style first, array also gets them
1893
+ const [compProps, arrayProps, otherProps] = splitProps(props, component, [
1894
+ classNameProp,
1895
+ "style",
1896
+ ]);
1897
+ expectTypeOf(compProps).branded.toEqualTypeOf<
1898
+ Pick<typeof props, "size" | "style" | "class" | "className">
1899
+ >();
1900
+ expect(compProps).toEqual({
1867
1901
  size: "lg",
1868
1902
  style: { backgroundColor: "yellow" },
1869
1903
  [classNameProp]: "extra",
1870
1904
  });
1871
- // onlyVariants only gets color, not class/style
1872
- expect(comp2Props).toEqual({ color: "blue" });
1905
+ expectTypeOf(arrayProps).branded.toEqualTypeOf<
1906
+ Pick<typeof props, "class" | "className" | "style">
1907
+ >();
1908
+ expect(arrayProps).toEqual({
1909
+ [classNameProp]: "extra",
1910
+ style: { backgroundColor: "yellow" },
1911
+ });
1912
+ expectTypeOf(otherProps).toEqualTypeOf<{ id?: string }>();
1873
1913
  expect(otherProps).toEqual({ id: "test" });
1874
1914
  });
1875
1915
 
1876
- test("splitProps with multiple parameters", () => {
1916
+ test("splitProps array before multiple components", () => {
1877
1917
  const component1 = getModalComponent(
1878
1918
  mode,
1879
1919
  cv({ variants: { size: { sm: "sm", lg: "lg" } } }),
@@ -1882,158 +1922,42 @@ for (const config of Object.values(CONFIGS)) {
1882
1922
  mode,
1883
1923
  cv({ variants: { color: { red: "red", blue: "blue" } } }),
1884
1924
  );
1925
+ const classNameProp = getClassPropertyName(config);
1885
1926
  const props: HTMLProperties<typeof component1> &
1886
1927
  HTMLProperties<typeof component2> & { disabled?: boolean } = {
1887
1928
  id: "test",
1888
1929
  size: "lg",
1889
1930
  color: "blue",
1890
1931
  disabled: true,
1932
+ style: { backgroundColor: "yellow" },
1933
+ [classNameProp]: "extra",
1891
1934
  };
1892
- const [comp1Props, extraProps, comp2Props, otherProps] = splitProps(
1935
+ // Array doesn't claim styling, so first component (comp1) gets styling
1936
+ const [disabledProps, comp1Props, comp2Props, otherProps] = splitProps(
1893
1937
  props,
1894
- component1,
1895
1938
  ["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
1939
  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
- }),
1940
+ component2,
1966
1941
  );
1967
- const classNameProp = getClassPropertyName(config);
1968
- const props: HTMLProperties<typeof component> = {
1969
- id: "test",
1942
+ expectTypeOf(disabledProps).branded.toEqualTypeOf<{
1943
+ disabled?: boolean;
1944
+ }>();
1945
+ expect(disabledProps).toEqual({ disabled: true });
1946
+ expectTypeOf(comp1Props).branded.toEqualTypeOf<
1947
+ Pick<typeof props, "size" | "style" | "class" | "className">
1948
+ >();
1949
+ // First component gets class/style
1950
+ expect(comp1Props).toEqual({
1970
1951
  size: "lg",
1952
+ style: { backgroundColor: "yellow" },
1971
1953
  [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
1954
  });
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" });
1955
+ // Second component only gets variant props
1956
+ expectTypeOf(comp2Props).branded.toEqualTypeOf<
1957
+ Pick<typeof props, "color">
1958
+ >();
2035
1959
  expect(comp2Props).toEqual({ color: "blue" });
2036
- expect(otherProps).toEqual({ id: "test", [classNameProp]: "extra" });
1960
+ expect(otherProps).toEqual({ id: "test" });
2037
1961
  });
2038
1962
  });
2039
1963
  }