@trackunit/react-form-components 2.6.47 → 2.6.49

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/index.esm.js CHANGED
@@ -3,7 +3,7 @@ import { registerTranslations, useNamespaceTranslation, NamespaceTrans } from '@
3
3
  import { IconButton, Icon, Tooltip, Button, Popover, PopoverTrigger, PopoverContent, cvaMenu, cvaMenuList, Tag, useIsTextTruncated, ZStack, MenuItem, useMeasure, useDebounce, useMergeRefs, Spinner, useScrollBlock, Text, Heading } from '@trackunit/react-components';
4
4
  import { useMemo, useRef, useEffect, useImperativeHandle, useState, useCallback, useLayoutEffect, isValidElement, cloneElement, useReducer, createContext, useContext, useId } from 'react';
5
5
  import { twMerge } from 'tailwind-merge';
6
- import { cvaMerge } from '@trackunit/css-class-variance-utilities';
6
+ import { cva } from '@trackunit/css-class-variance-utilities';
7
7
  import { themeSpacing } from '@trackunit/ui-design-tokens';
8
8
  import { titleCase } from 'string-ts';
9
9
  import { useCopyToClipboard } from 'usehooks-ts';
@@ -397,7 +397,8 @@ const useDateFieldLocale = () => {
397
397
  }, [browserLocale, selectedLanguage]);
398
398
  };
399
399
 
400
- const cvaActionButton = cvaMerge(["drop-shadow-none", "rounded-md"], {
400
+ const cvaActionButton = cva({
401
+ base: ["drop-shadow-none", "rounded-md"],
401
402
  variants: {
402
403
  size: {
403
404
  small: ["w-6", "h-6", "min-h-0"],
@@ -409,7 +410,8 @@ const cvaActionButton = cvaMerge(["drop-shadow-none", "rounded-md"], {
409
410
  size: "medium",
410
411
  },
411
412
  });
412
- const cvaActionContainer = cvaMerge(["flex", "items-center"], {
413
+ const cvaActionContainer = cva({
414
+ base: ["flex", "items-center"],
413
415
  variants: {
414
416
  size: {
415
417
  //I just measured manually the top/bottom spacing
@@ -425,24 +427,24 @@ const cvaActionContainer = cvaMerge(["flex", "items-center"], {
425
427
  },
426
428
  });
427
429
 
428
- const cvaInputBase = cvaMerge([
429
- "component-baseInput-shadow",
430
- "component-baseInput-border",
431
- "component-baseInput-background",
432
- "border-neutral-300",
433
- "hover:border-neutral-400",
434
- "hover:bg-neutral-50",
435
- "transition",
436
- ]);
437
- const cvaInputBaseDisabled = cvaMerge([
438
- "bg-neutral-100",
439
- "hover:bg-neutral-100",
440
- "hover:border-neutral-300",
441
- "text-neutral-400",
442
- ]);
443
- const cvaInputBaseInvalid = cvaMerge(["border-danger-600"]);
444
- const cvaInputBaseReadOnly = cvaMerge(["text-neutral-500"]);
445
- const cvaInputBaseSize = cvaMerge("", {
430
+ const cvaInputBase = cva({
431
+ base: [
432
+ "component-baseInput-shadow",
433
+ "component-baseInput-border",
434
+ "component-baseInput-background",
435
+ "border-neutral-300",
436
+ "hover:border-neutral-400",
437
+ "hover:bg-neutral-50",
438
+ "transition",
439
+ ],
440
+ });
441
+ const cvaInputBaseDisabled = cva({
442
+ base: ["bg-neutral-100", "hover:bg-neutral-100", "hover:border-neutral-300", "text-neutral-400"],
443
+ });
444
+ const cvaInputBaseInvalid = cva({ base: ["border-danger-600"] });
445
+ const cvaInputBaseReadOnly = cva({ base: ["text-neutral-500"] });
446
+ const cvaInputBaseSize = cva({
447
+ base: "",
446
448
  variants: {
447
449
  size: {
448
450
  small: ["h-7", "text-xs"],
@@ -454,18 +456,19 @@ const cvaInputBaseSize = cvaMerge("", {
454
456
  },
455
457
  },
456
458
  });
457
- const cvaInput$1 = cvaMerge([
458
- "overflow-clip",
459
- "grid",
460
- // ! The layout of the grid is critical to the functioning of the cvaInputItemPlacementManager 👇
461
- // The min restriction of the middle column (--spacing-20) is
462
- // effectively the minimum width available for the text input
463
- "grid-cols-[min-content_minmax(var(--spacing-20),1fr)_min-content]",
464
- "grid-rows-1",
465
- cvaInputBase(),
466
- "focus-within:outline-native",
467
- "text-neutral-900",
468
- ], {
459
+ const cvaInput$1 = cva({
460
+ base: [
461
+ "overflow-clip",
462
+ "grid",
463
+ // ! The layout of the grid is critical to the functioning of the cvaInputItemPlacementManager 👇
464
+ // The min restriction of the middle column (--spacing-20) is
465
+ // effectively the minimum width available for the text input
466
+ "grid-cols-[min-content_minmax(var(--spacing-20),1fr)_min-content]",
467
+ "grid-rows-1",
468
+ cvaInputBase(),
469
+ "focus-within:outline-native",
470
+ "text-neutral-900",
471
+ ],
469
472
  variants: {
470
473
  size: {
471
474
  small: cvaInputBaseSize({ size: "small" }),
@@ -513,7 +516,8 @@ const cvaInput$1 = cvaMerge([
513
516
  * The span position is used for the input field, which spans the entire grid.
514
517
  *! Relies on the specific grid layout of cvaInput ☝️
515
518
  */
516
- const cvaInputItemPlacementManager = cvaMerge([], {
519
+ const cvaInputItemPlacementManager = cva({
520
+ base: [],
517
521
  variants: {
518
522
  position: {
519
523
  before: ["col-start-1", "col-end-2", "row-start-1", "row-end-1"],
@@ -525,11 +529,12 @@ const cvaInputItemPlacementManager = cvaMerge([], {
525
529
  position: "span",
526
530
  },
527
531
  });
528
- const cvaAccessoriesContainer = cvaMerge(["grid", "h-full", "w-min", "auto-cols-min", "grid-flow-col"]);
532
+ const cvaAccessoriesContainer = cva({ base: ["grid", "h-full", "w-min", "auto-cols-min", "grid-flow-col"] });
529
533
  /**
530
534
  * Text size and color is handled by cvaInput
531
535
  */
532
- const cvaInputElement = cvaMerge(["w-full", "px-3", "border-0", "bg-transparent", "placeholder-neutral-400", "truncate"], {
536
+ const cvaInputElement = cva({
537
+ base: ["w-full", "px-3", "border-0", "bg-transparent", "placeholder-neutral-400", "truncate"],
533
538
  variants: {
534
539
  size: {
535
540
  small: ["py-0.5"],
@@ -541,16 +546,17 @@ const cvaInputElement = cvaMerge(["w-full", "px-3", "border-0", "bg-transparent"
541
546
  size: "medium",
542
547
  },
543
548
  });
544
- const cvaInputAddon = cvaMerge([
545
- "flex",
546
- "justify-center",
547
- "items-center",
548
- "px-3",
549
- "border-neutral-300",
550
- "text-neutral-500",
551
- "bg-neutral-50",
552
- "text-nowrap",
553
- ], {
549
+ const cvaInputAddon = cva({
550
+ base: [
551
+ "flex",
552
+ "justify-center",
553
+ "items-center",
554
+ "px-3",
555
+ "border-neutral-300",
556
+ "text-neutral-500",
557
+ "bg-neutral-50",
558
+ "text-nowrap",
559
+ ],
554
560
  variants: {
555
561
  size: {
556
562
  small: ["text-xs"],
@@ -566,16 +572,17 @@ const cvaInputAddon = cvaMerge([
566
572
  size: "medium",
567
573
  },
568
574
  });
569
- const cvaInputPrefix = cvaMerge([
570
- "flex",
571
- "justify-center",
572
- "items-center",
573
- "text-neutral-400",
574
- "hover:component-search-prefix",
575
- "component-baseInput-prefix",
576
- "component-search-borderless",
577
- "pl-2",
578
- ], {
575
+ const cvaInputPrefix = cva({
576
+ base: [
577
+ "flex",
578
+ "justify-center",
579
+ "items-center",
580
+ "text-neutral-400",
581
+ "hover:component-search-prefix",
582
+ "component-baseInput-prefix",
583
+ "component-search-borderless",
584
+ "pl-2",
585
+ ],
579
586
  variants: {
580
587
  disabled: {
581
588
  true: ["text-neutral-500"],
@@ -586,7 +593,8 @@ const cvaInputPrefix = cvaMerge([
586
593
  disabled: false,
587
594
  },
588
595
  });
589
- const cvaInputSuffix = cvaMerge(["flex", "justify-center", "items-center", "text-neutral-400", "pr-2"], {
596
+ const cvaInputSuffix = cva({
597
+ base: ["flex", "justify-center", "items-center", "text-neutral-400", "pr-2"],
590
598
  variants: {
591
599
  disabled: {
592
600
  true: ["text-neutral-500"],
@@ -1516,20 +1524,21 @@ const PhoneBaseInput = ({ "data-testid": dataTestId, isInvalid, disabled = false
1516
1524
  return (jsx("div", { className: "grid grid-cols-1 gap-2", "data-testid": dataTestId ? `${dataTestId}-container` : null, children: jsx(BaseInput, { ...rest, actions: !disableAction && innerValue && innerValue.length > 0 ? (jsx(ActionButton, { "data-testid": dataTestId ? `${dataTestId}-phoneIcon` : undefined, disabled: isInvalid, size: fieldSize, title: t("phoneField.phoneNumber.label"), type: "PHONE_NUMBER", value: value?.toString() || "" })) : null, "data-testid": dataTestId ? `${dataTestId}-phoneNumberInput` : undefined, disabled: disabled, fieldSize: fieldSize, id: "phoneInput-number", isInvalid: isInvalid, name: name, onBlur: handleBlur, onChange: handleChange, onFocus: handleFocus, prefix: (countryCode && countryCodeToFlagEmoji(countryCode)) || undefined, readOnly: readOnly, ref: ref, type: "tel", value: innerValue }) }));
1517
1525
  };
1518
1526
 
1519
- const cvaTextAreaBaseInput = cvaMerge([
1520
- cvaInputBase(),
1521
- "block",
1522
- "overflow-auto",
1523
- "appearance-none",
1524
- "px-3",
1525
- "py-2",
1526
- "text-sm",
1527
- "text-neutral-900",
1528
- "placeholder-neutral-400",
1529
- "w-full",
1530
- "h-20",
1531
- "transition",
1532
- ], {
1527
+ const cvaTextAreaBaseInput = cva({
1528
+ base: [
1529
+ cvaInputBase(),
1530
+ "block",
1531
+ "overflow-auto",
1532
+ "appearance-none",
1533
+ "px-3",
1534
+ "py-2",
1535
+ "text-sm",
1536
+ "text-neutral-900",
1537
+ "placeholder-neutral-400",
1538
+ "w-full",
1539
+ "h-20",
1540
+ "transition",
1541
+ ],
1533
1542
  variants: {
1534
1543
  disabled: {
1535
1544
  true: cvaInputBaseDisabled(),
@@ -1567,7 +1576,8 @@ const TextBaseInput = ({ ref, ...rest }) => jsx(BaseInput, { ref: ref, type: "te
1567
1576
  * The container for the select component — with state styling
1568
1577
  * !This is _the_ place in select styles to manage the aperance of the text and background
1569
1578
  */
1570
- const cvaSelectContainer = cvaMerge([cvaInputBase(), "relative", "transition", "min-h-0"], {
1579
+ const cvaSelectContainer = cva({
1580
+ base: [cvaInputBase(), "relative", "transition", "min-h-0"],
1571
1581
  variants: {
1572
1582
  fieldSize: {
1573
1583
  small: cvaInputBaseSize({ size: "small" }),
@@ -1599,26 +1609,18 @@ const cvaSelectContainer = cvaMerge([cvaInputBase(), "relative", "transition", "
1599
1609
  },
1600
1610
  },
1601
1611
  });
1602
- const cvaSelectControl = cvaMerge(["px-3", "gap-x-1", "flex", "h-full"]);
1603
- const cvaSelectLoadingMessage = cvaMerge(["text-neutral-400", "text-center"]);
1604
- const cvaSelectNoOptionsMessage = cvaMerge(["text-neutral-400", "text-center"]);
1605
- const cvaSelectDropdownIconContainer = cvaMerge([
1606
- "flex",
1607
- "cursor-pointer",
1608
- "place-items-center",
1609
- "text-neutral-400",
1610
- "hover:text-neutral-500",
1611
- ]);
1612
- const cvaSelectPrefixSuffix = cvaMerge(["flex", "items-center", "text-neutral-400"]);
1613
- const cvaSelectClearIndicator = cvaMerge([
1614
- "flex",
1615
- "cursor-pointer",
1616
- "items-center",
1617
- "justify-center",
1618
- "text-neutral-400",
1619
- "hover:text-neutral-500",
1620
- ]);
1621
- const cvaSelectDropdownIndicator = cvaMerge(["transition-transform", "duration-200"], {
1612
+ const cvaSelectControl = cva({ base: ["px-3", "gap-x-1", "flex", "h-full"] });
1613
+ const cvaSelectLoadingMessage = cva({ base: ["text-neutral-400", "text-center"] });
1614
+ const cvaSelectNoOptionsMessage = cva({ base: ["text-neutral-400", "text-center"] });
1615
+ const cvaSelectDropdownIconContainer = cva({
1616
+ base: ["flex", "cursor-pointer", "place-items-center", "text-neutral-400", "hover:text-neutral-500"],
1617
+ });
1618
+ const cvaSelectPrefixSuffix = cva({ base: ["flex", "items-center", "text-neutral-400"] });
1619
+ const cvaSelectClearIndicator = cva({
1620
+ base: ["flex", "cursor-pointer", "items-center", "justify-center", "text-neutral-400", "hover:text-neutral-500"],
1621
+ });
1622
+ const cvaSelectDropdownIndicator = cva({
1623
+ base: ["transition-transform", "duration-200"],
1622
1624
  variants: {
1623
1625
  menuIsOpen: {
1624
1626
  true: "rotate-180",
@@ -1626,29 +1628,20 @@ const cvaSelectDropdownIndicator = cvaMerge(["transition-transform", "duration-2
1626
1628
  },
1627
1629
  },
1628
1630
  });
1629
- const cvaSelectValueContainer = cvaMerge([
1630
- "flex",
1631
- "flex-nowrap",
1632
- "items-center",
1633
- "grow",
1634
- "overflow-hidden",
1635
- "relative",
1636
- "gap-x-1",
1637
- ]);
1631
+ const cvaSelectValueContainer = cva({
1632
+ base: ["flex", "flex-nowrap", "items-center", "grow", "overflow-hidden", "relative", "gap-x-1"],
1633
+ });
1638
1634
  // for the placement of items inside the value container
1639
- const insideValueContainerClasses = cvaMerge(["col-start-1", "col-end-3", "row-start-1", "row-end-2"]);
1640
- const cvaSelectSingleValue = cvaMerge([
1641
- insideValueContainerClasses(),
1642
- "max-w-full",
1643
- "overflow-hidden",
1644
- "text-ellipsis",
1645
- "whitespace-nowrap",
1646
- ]);
1635
+ const insideValueContainerClasses = cva({ base: ["col-start-1", "col-end-3", "row-start-1", "row-end-2"] });
1636
+ const cvaSelectSingleValue = cva({
1637
+ base: [insideValueContainerClasses(), "max-w-full", "overflow-hidden", "text-ellipsis", "whitespace-nowrap"],
1638
+ });
1647
1639
  // No `w-full`: useCustomComponents.tsx's custom `Menu` applies edge-aware min/max-width and
1648
1640
  // left/right alignment as an inline style (see utils/computeMenuGeometry.ts), so a
1649
1641
  // static Tailwind width class here would just compete with that. The menu sizes intrinsically
1650
1642
  // (shrink-to-fit, bounded by that inline min/max-width) as a result.
1651
- const cvaSelectMenu = cvaMerge([cvaMenu({ limitWidth: false }), "absolute"], {
1643
+ const cvaSelectMenu = cva({
1644
+ base: [cvaMenu({ limitWidth: false }), "absolute"],
1652
1645
  variants: {
1653
1646
  placement: {
1654
1647
  bottom: "top-[calc(100%+var(--spacing-1))]",
@@ -1659,10 +1652,11 @@ const cvaSelectMenu = cvaMerge([cvaMenu({ limitWidth: false }), "absolute"], {
1659
1652
  placement: "bottom",
1660
1653
  },
1661
1654
  });
1662
- const cvaSelectMenuList = cvaMerge([cvaMenuList(), "relative", "w-full"]);
1663
- const cvaSelectPlaceholder = cvaMerge(["absolute", "text-neutral-400"]);
1664
- const cvaSelectIndicatorsContainer = cvaMerge(["flex", "items-center", "gap-x-1"]);
1665
- const cvaSelectMultiValue = cvaMerge([], {
1655
+ const cvaSelectMenuList = cva({ base: [cvaMenuList(), "relative", "w-full"] });
1656
+ const cvaSelectPlaceholder = cva({ base: ["absolute", "text-neutral-400"] });
1657
+ const cvaSelectIndicatorsContainer = cva({ base: ["flex", "items-center", "gap-x-1"] });
1658
+ const cvaSelectMultiValue = cva({
1659
+ base: [],
1666
1660
  variants: {
1667
1661
  hidden: {
1668
1662
  true: "!hidden",
@@ -1711,26 +1705,29 @@ const MultiValue = ({ data, children, onClose, className, disabled, fieldSize, g
1711
1705
  /**
1712
1706
  * Shared CVA for binary control items: Checkbox, RadioItem, ToggleSwitchOption
1713
1707
  */
1714
- const cvaBinaryControlWrapper = cvaMerge([
1715
- "grid-rows-subgrid", //* Children align to this parent grid
1716
- "grid-cols-min-fr", //* explicit horizontal placement for input and label/description
1717
- "auto-rows-auto", //* optional extra rows (suffix) will be auto-sized
1718
- "group",
1719
- "grid",
1720
- "gap-x-2",
1721
- ]);
1722
- const cvaBinaryControlLabelTooltip = cvaMerge(["col-start-2", "w-full", "min-w-0", "self-center"]);
1723
- const cvaBinaryControlDescriptionTooltip = cvaMerge(["col-span-2", "col-start-2", "row-start-2", "w-full"]);
1724
- const cvaBinaryControlDescription = cvaMerge([
1725
- "text-sm",
1726
- "font-normal",
1727
- "text-neutral-500",
1728
- "text-left",
1729
- "whitespace-nowrap",
1730
- "select-none",
1731
- "text-ellipsis",
1732
- "overflow-hidden",
1733
- ], {
1708
+ const cvaBinaryControlWrapper = cva({
1709
+ base: [
1710
+ "grid-rows-subgrid", //* Children align to this parent grid
1711
+ "grid-cols-min-fr", //* explicit horizontal placement for input and label/description
1712
+ "auto-rows-auto", //* optional extra rows (suffix) will be auto-sized
1713
+ "group",
1714
+ "grid",
1715
+ "gap-x-2",
1716
+ ],
1717
+ });
1718
+ const cvaBinaryControlLabelTooltip = cva({ base: ["col-start-2", "w-full", "min-w-0", "self-center"] });
1719
+ const cvaBinaryControlDescriptionTooltip = cva({ base: ["col-span-2", "col-start-2", "row-start-2", "w-full"] });
1720
+ const cvaBinaryControlDescription = cva({
1721
+ base: [
1722
+ "text-sm",
1723
+ "font-normal",
1724
+ "text-neutral-500",
1725
+ "text-left",
1726
+ "whitespace-nowrap",
1727
+ "select-none",
1728
+ "text-ellipsis",
1729
+ "overflow-hidden",
1730
+ ],
1734
1731
  variants: {
1735
1732
  disabled: {
1736
1733
  true: ["text-neutral-400", "hover:text-neutral-400", "group-hover:text-neutral-400"],
@@ -1738,16 +1735,17 @@ const cvaBinaryControlDescription = cvaMerge([
1738
1735
  },
1739
1736
  },
1740
1737
  });
1741
- const cvaBinaryControlSuffixContainer = cvaMerge(["flex", "col-start-3", "items-center"]);
1738
+ const cvaBinaryControlSuffixContainer = cva({ base: ["flex", "col-start-3", "items-center"] });
1742
1739
 
1743
- const cvaLabel = cvaMerge([
1744
- "text-sm",
1745
- "text-neutral-700",
1746
- "hover:text-neutral-800",
1747
- "group-hover:text-neutral-800",
1748
- "active:text-neutral-800",
1749
- "group-active:text-neutral-800",
1750
- ], {
1740
+ const cvaLabel = cva({
1741
+ base: [
1742
+ "text-sm",
1743
+ "text-neutral-700",
1744
+ "hover:text-neutral-800",
1745
+ "group-hover:text-neutral-800",
1746
+ "active:text-neutral-800",
1747
+ "group-active:text-neutral-800",
1748
+ ],
1751
1749
  variants: {
1752
1750
  invalid: {
1753
1751
  true: "text-danger-600 hover:text-danger-700 active:text-danger-700 group-hover:text-danger-700 group-active:text-danger-700",
@@ -1783,30 +1781,31 @@ const CheckIcon = ({ className, "data-testid": dataTestId }) => {
1783
1781
  * Checkbox input styling - directly styles the input element (no wrapper span needed).
1784
1782
  * Uses appearance-none to remove native styling, similar to RadioItem.
1785
1783
  */
1786
- const cvaCheckbox = cvaMerge([
1787
- "appearance-none",
1788
- "w-4",
1789
- "h-4",
1790
- "border-solid",
1791
- "border",
1792
- "shrink-0",
1793
- "border-neutral-300",
1794
- "rounded",
1795
- "hover:bg-neutral-100",
1796
- "bg-white",
1797
- "shadow-sm",
1798
- "box-border",
1799
- "transition",
1800
- "cursor-pointer",
1801
- "active:bg-neutral-200",
1802
- "active:ring-2",
1803
- "active:ring-inset",
1804
- "active:ring-primary-700",
1805
- "group-active:ring-2",
1806
- "group-active:ring-inset",
1807
- "group-active:ring-primary-700",
1808
- "focus:outline-native",
1809
- ], {
1784
+ const cvaCheckbox = cva({
1785
+ base: [
1786
+ "appearance-none",
1787
+ "w-4",
1788
+ "h-4",
1789
+ "border-solid",
1790
+ "border",
1791
+ "shrink-0",
1792
+ "border-neutral-300",
1793
+ "rounded",
1794
+ "hover:bg-neutral-100",
1795
+ "bg-white",
1796
+ "shadow-sm",
1797
+ "box-border",
1798
+ "transition",
1799
+ "cursor-pointer",
1800
+ "active:bg-neutral-200",
1801
+ "active:ring-2",
1802
+ "active:ring-inset",
1803
+ "active:ring-primary-700",
1804
+ "group-active:ring-2",
1805
+ "group-active:ring-inset",
1806
+ "group-active:ring-primary-700",
1807
+ "focus:outline-native",
1808
+ ],
1810
1809
  variants: {
1811
1810
  invalid: {
1812
1811
  true: ["border-danger-600", "active:ring-danger-700", "group-focus:ring-2", "group-focus:ring-inset"],
@@ -1881,15 +1880,10 @@ const cvaCheckbox = cvaMerge([
1881
1880
  /**
1882
1881
  * Icon overlay container - positioned on top of the input, receives no pointer events
1883
1882
  */
1884
- const cvaCheckboxIconOverlay = cvaMerge([
1885
- "flex",
1886
- "items-center",
1887
- "justify-center",
1888
- "w-4",
1889
- "h-4",
1890
- "pointer-events-none",
1891
- ]);
1892
- const cvaCheckboxIcon = cvaMerge(["w-2.5", "h-2.5", "text-white"]);
1883
+ const cvaCheckboxIconOverlay = cva({
1884
+ base: ["flex", "items-center", "justify-center", "w-4", "h-4", "pointer-events-none"],
1885
+ });
1886
+ const cvaCheckboxIcon = cva({ base: ["w-2.5", "h-2.5", "text-white"] });
1893
1887
 
1894
1888
  /**
1895
1889
  * The IndeterminateIcon component is used by the checkbox to display the Indeterminate state.
@@ -3066,9 +3060,10 @@ const Label = ({ id, htmlFor, children, className, "data-testid": dataTestId, di
3066
3060
  return (jsx("label", { className: cvaLabel({ invalid: isInvalid, disabled, className }), "data-testid": dataTestId, htmlFor: htmlFor || "", id: id || "", ref: ref, style: style, children: children }));
3067
3061
  };
3068
3062
 
3069
- const cvaFormGroup = cvaMerge(["component-formGroup-gap", "group", "form-group"]);
3070
- const cvaFormGroupContainerBefore = cvaMerge(["flex", "mb-1", "items-center"]);
3071
- const cvaFormGroupContainerAfter = cvaMerge(["flex", "justify-between", "mt-1", "text-xs", "text-neutral-500"], {
3063
+ const cvaFormGroup = cva({ base: ["component-formGroup-gap", "group", "form-group"] });
3064
+ const cvaFormGroupContainerBefore = cva({ base: ["flex", "mb-1", "items-center"] });
3065
+ const cvaFormGroupContainerAfter = cva({
3066
+ base: ["flex", "justify-between", "mt-1", "text-xs", "text-neutral-500"],
3072
3067
  variants: {
3073
3068
  invalid: {
3074
3069
  true: "text-danger-500",
@@ -3087,7 +3082,7 @@ const cvaFormGroupContainerAfter = cvaMerge(["flex", "justify-between", "mt-1",
3087
3082
  },
3088
3083
  ],
3089
3084
  });
3090
- const cvaHelpAddon = cvaMerge(["ml-auto"]);
3085
+ const cvaHelpAddon = cva({ base: ["ml-auto"] });
3091
3086
 
3092
3087
  /**
3093
3088
  * FormGroup wraps an input element with a label, optional tooltip, help text, and validation styling.
@@ -3192,16 +3187,17 @@ const validateColorCode = (colorCode, required) => {
3192
3187
  return "INVALID_HEX_CODE";
3193
3188
  };
3194
3189
 
3195
- const cvaInputColorField = cvaMerge([
3196
- "ml-3",
3197
- "h-4",
3198
- "w-4",
3199
- "self-center",
3200
- "bg-inherit",
3201
- "disabled:opacity-50",
3202
- "disabled:pointer-events-none",
3203
- "rounded-[4px]",
3204
- ], {
3190
+ const cvaInputColorField = cva({
3191
+ base: [
3192
+ "ml-3",
3193
+ "h-4",
3194
+ "w-4",
3195
+ "self-center",
3196
+ "bg-inherit",
3197
+ "disabled:opacity-50",
3198
+ "disabled:pointer-events-none",
3199
+ "rounded-[4px]",
3200
+ ],
3205
3201
  variants: {
3206
3202
  readOnly: {
3207
3203
  true: "pointer-events-none",
@@ -3399,19 +3395,20 @@ const DateField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInvali
3399
3395
  };
3400
3396
  DateField.displayName = "DateField";
3401
3397
 
3402
- const cvaDropZone = cvaMerge([
3403
- "flex",
3404
- "component-baseInput-background",
3405
- "justify-center",
3406
- "text-neutral-500",
3407
- "rounded-lg",
3408
- "border-2",
3409
- "border-neutral-200",
3410
- "border-dashed",
3411
- "hover:bg-neutral-100",
3412
- "hover:border-solid",
3413
- "hover:border-primary-500",
3414
- ], {
3398
+ const cvaDropZone = cva({
3399
+ base: [
3400
+ "flex",
3401
+ "component-baseInput-background",
3402
+ "justify-center",
3403
+ "text-neutral-500",
3404
+ "rounded-lg",
3405
+ "border-2",
3406
+ "border-neutral-200",
3407
+ "border-dashed",
3408
+ "hover:bg-neutral-100",
3409
+ "hover:border-solid",
3410
+ "hover:border-primary-500",
3411
+ ],
3415
3412
  variants: {
3416
3413
  size: {
3417
3414
  small: ["p-2"],
@@ -3421,29 +3418,17 @@ const cvaDropZone = cvaMerge([
3421
3418
  disabled: { true: ["bg-neutral-100", "hover:bg-neutral-100"], false: "" },
3422
3419
  dragActive: { true: ["border-neutral-200", "bg-neutral-100"], false: "" },
3423
3420
  dropComplete: {
3424
- true: [
3425
- "border-solid",
3426
- "border-primary-500",
3427
- "bg-neutral-100",
3428
- "hover:border-solid",
3429
- "hover:border-neutral-200",
3430
- ],
3421
+ true: ["border-solid", "border-primary-500", "bg-neutral-100", "hover:border-solid", "hover:border-neutral-200"],
3431
3422
  false: "",
3432
3423
  },
3433
3424
  invalid: { true: ["border-danger-600", "text-danger-500"], false: "" },
3434
3425
  },
3435
3426
  });
3436
- const cvaDropZoneLabel = cvaMerge([
3437
- "h-full",
3438
- "pt-1",
3439
- "pb-1",
3440
- "gap-2",
3441
- "items-center",
3442
- "flex-col",
3443
- "flex",
3444
- "justify-center",
3445
- ]);
3446
- const cvaDropZoneIconBackground = cvaMerge(["relative", "flex", "items-center", "justify-center", "rounded-full", "p-3"], {
3427
+ const cvaDropZoneLabel = cva({
3428
+ base: ["h-full", "pt-1", "pb-1", "gap-2", "items-center", "flex-col", "flex", "justify-center"],
3429
+ });
3430
+ const cvaDropZoneIconBackground = cva({
3431
+ base: ["relative", "flex", "items-center", "justify-center", "rounded-full", "p-3"],
3447
3432
  variants: {
3448
3433
  invalid: { true: ["bg-danger-100"], false: ["bg-neutral-200"] },
3449
3434
  },
@@ -4004,27 +3989,28 @@ const NumberField = ({ label, id, tip, helpText, errorMessage, helpAddon, isInva
4004
3989
  };
4005
3990
  NumberField.displayName = "NumberField";
4006
3991
 
4007
- const cvaOptionCardLabel = cvaMerge([
4008
- "group",
4009
- "transition",
4010
- "bg-white",
4011
- "outline",
4012
- "outline-1",
4013
- "outline-neutral-300",
4014
- "hover:bg-neutral-100",
4015
- "focus:bg-neutral-200",
4016
- "active:bg-neutral-200",
4017
- "peer-checked:bg-primary-50",
4018
- "peer-checked:outline-primary-600",
4019
- "peer-checked:outline-2",
4020
- "flex",
4021
- "gap-2",
4022
- "justify-center",
4023
- "items-center",
4024
- "text-center",
4025
- "rounded-md",
4026
- "relative",
4027
- ], {
3992
+ const cvaOptionCardLabel = cva({
3993
+ base: [
3994
+ "group",
3995
+ "transition",
3996
+ "bg-white",
3997
+ "outline",
3998
+ "outline-1",
3999
+ "outline-neutral-300",
4000
+ "hover:bg-neutral-100",
4001
+ "focus:bg-neutral-200",
4002
+ "active:bg-neutral-200",
4003
+ "peer-checked:bg-primary-50",
4004
+ "peer-checked:outline-primary-600",
4005
+ "peer-checked:outline-2",
4006
+ "flex",
4007
+ "gap-2",
4008
+ "justify-center",
4009
+ "items-center",
4010
+ "text-center",
4011
+ "rounded-md",
4012
+ "relative",
4013
+ ],
4028
4014
  variants: {
4029
4015
  disabled: {
4030
4016
  true: ["cursor-not-allowed", "bg-neutral-100"],
@@ -4036,9 +4022,10 @@ const cvaOptionCardLabel = cvaMerge([
4036
4022
  },
4037
4023
  },
4038
4024
  });
4039
- const cvaOptionCardContent = cvaMerge(["flex", "flex-col", "items-center"]);
4040
- const cvaOptionCardContainer = cvaMerge(["flex", "grow-0"]);
4041
- const cvaOptionCardTitle = cvaMerge(["text-neutral-600"], {
4025
+ const cvaOptionCardContent = cva({ base: ["flex", "flex-col", "items-center"] });
4026
+ const cvaOptionCardContainer = cva({ base: ["flex", "grow-0"] });
4027
+ const cvaOptionCardTitle = cva({
4028
+ base: ["text-neutral-600"],
4042
4029
  variants: {
4043
4030
  layout: {
4044
4031
  default: ["text-lg", "line-clamp-2"],
@@ -4050,7 +4037,8 @@ const cvaOptionCardTitle = cvaMerge(["text-neutral-600"], {
4050
4037
  },
4051
4038
  },
4052
4039
  });
4053
- const cvaOptionCardText = cvaMerge(["text-neutral-600", "text-sm"], {
4040
+ const cvaOptionCardText = cva({
4041
+ base: ["text-neutral-600", "text-sm"],
4054
4042
  variants: {
4055
4043
  type: {
4056
4044
  subheading: ["font-medium"],
@@ -4062,8 +4050,9 @@ const cvaOptionCardText = cvaMerge(["text-neutral-600", "text-sm"], {
4062
4050
  },
4063
4051
  },
4064
4052
  });
4065
- const cvaInput = cvaMerge(["peer", "absolute", "h-0", "w-0", "opacity-0"]);
4066
- const cvaCustomImage = cvaMerge(["text-neutral-400"], {
4053
+ const cvaInput = cva({ base: ["peer", "absolute", "h-0", "w-0", "opacity-0"] });
4054
+ const cvaCustomImage = cva({
4055
+ base: ["text-neutral-400"],
4067
4056
  variants: {
4068
4057
  disabled: {
4069
4058
  true: ["!text-neutral-400"],
@@ -4071,7 +4060,8 @@ const cvaCustomImage = cvaMerge(["text-neutral-400"], {
4071
4060
  },
4072
4061
  },
4073
4062
  });
4074
- const cvaTag = cvaMerge([], {
4063
+ const cvaTag = cva({
4064
+ base: [],
4075
4065
  variants: {
4076
4066
  layout: {
4077
4067
  default: ["absolute", "top-2", "right-2"],
@@ -4342,31 +4332,33 @@ const PhoneFieldWithController = ({ control, controllerProps, name, value, ref,
4342
4332
  };
4343
4333
  PhoneFieldWithController.displayName = "PhoneFieldWithController";
4344
4334
 
4345
- const cvaInputGroup = cvaMerge(["flex", "gap-2", "flex-col", "items-start"], {
4335
+ const cvaInputGroup = cva({
4336
+ base: ["flex", "gap-2", "flex-col", "items-start"],
4346
4337
  variants: {
4347
4338
  layout: {
4348
4339
  inline: ["flex", "gap-3", "flex-row", "items-center"],
4349
4340
  },
4350
4341
  },
4351
4342
  });
4352
- const cvaRadioItem = cvaMerge([
4353
- "self-center",
4354
- "w-4",
4355
- "h-4",
4356
- "appearance-none",
4357
- "rounded-3xl",
4358
- "bg-white",
4359
- "border-solid",
4360
- "border",
4361
- "border-neutral-300",
4362
- "shadow-sm",
4363
- "shrink-0",
4364
- "transition",
4365
- "box-border",
4366
- "hover:cursor-pointer",
4367
- "hover:bg-neutral-100",
4368
- "focus:outline-native",
4369
- ], {
4343
+ const cvaRadioItem = cva({
4344
+ base: [
4345
+ "self-center",
4346
+ "w-4",
4347
+ "h-4",
4348
+ "appearance-none",
4349
+ "rounded-3xl",
4350
+ "bg-white",
4351
+ "border-solid",
4352
+ "border",
4353
+ "border-neutral-300",
4354
+ "shadow-sm",
4355
+ "shrink-0",
4356
+ "transition",
4357
+ "box-border",
4358
+ "hover:cursor-pointer",
4359
+ "hover:bg-neutral-100",
4360
+ "focus:outline-native",
4361
+ ],
4370
4362
  variants: {
4371
4363
  checked: {
4372
4364
  true: [
@@ -4466,7 +4458,7 @@ const RadioGroupContext = createContext(null);
4466
4458
  * @returns {ReactElement} RadioGroup component
4467
4459
  */
4468
4460
  const RadioGroup = ({ children, id, name, value, disabled, onChange, label, inline = false, className, "data-testid": dataTestId, isInvalid, style, ref, }) => {
4469
- return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, label: label, children: jsx("div", { className: cvaInputGroup({ layout: inline ? "inline" : null, className }), "data-testid": dataTestId, ref: ref, role: "radiogroup", style: style, children: jsx(RadioGroupContext.Provider, { value: {
4461
+ return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, label: label, children: jsx("div", { className: cvaInputGroup({ layout: inline ? "inline" : undefined, className }), "data-testid": dataTestId, ref: ref, role: "radiogroup", style: style, children: jsx(RadioGroupContext.Provider, { value: {
4470
4462
  id,
4471
4463
  value,
4472
4464
  name: name || id,
@@ -4530,15 +4522,9 @@ const useRadioItemChecked = (value) => {
4530
4522
  return radioGroupContext?.value === value;
4531
4523
  };
4532
4524
 
4533
- const cvaTimeRange = cvaMerge([
4534
- "flex",
4535
- "flex-1",
4536
- "items-center",
4537
- "gap-4",
4538
- "max-sm:gap-2",
4539
- "border-transparent",
4540
- "rounded-md",
4541
- ]);
4525
+ const cvaTimeRange = cva({
4526
+ base: ["flex", "flex-1", "items-center", "gap-4", "max-sm:gap-2", "border-transparent", "rounded-md"],
4527
+ });
4542
4528
 
4543
4529
  /**
4544
4530
  * TimeRange renders a pair of native `<input type="time">` fields for selecting a start and end time.
@@ -4580,14 +4566,10 @@ const TimeRange = ({ id, className, "data-testid": dataTestId, children, range,
4580
4566
  };
4581
4567
  const DEFAULT_TIME = "12:00";
4582
4568
 
4583
- const cvaScheduleItem = cvaMerge([
4584
- "grid",
4585
- "pb-4",
4586
- "gap-2",
4587
- "grid-cols-[60px_200px_60px_2fr]",
4588
- "max-sm:grid-cols-1",
4589
- ]);
4590
- const cvaScheduleItemText = cvaMerge(["flex", "font-bold", "self-center"]);
4569
+ const cvaScheduleItem = cva({
4570
+ base: ["grid", "pb-4", "gap-2", "grid-cols-[60px_200px_60px_2fr]", "max-sm:grid-cols-1"],
4571
+ });
4572
+ const cvaScheduleItemText = cva({ base: ["flex", "font-bold", "self-center"] });
4591
4573
 
4592
4574
  /**
4593
4575
  * Schedule renders a weekly time-range editor where each row represents a day with an active toggle,
@@ -4779,15 +4761,16 @@ const hasConsecutiveDays = (schedule) => {
4779
4761
  return schedule.every(({ day }, index) => day === days[index]);
4780
4762
  };
4781
4763
 
4782
- const cvaSearch = cvaMerge([
4783
- "shadow-none",
4784
- "component-search-border",
4785
- "component-search-background",
4786
- "hover:component-search-background",
4787
- "hover:component-search-focus-hover",
4788
- "transition-all",
4789
- "duration-300",
4790
- ], {
4764
+ const cvaSearch = cva({
4765
+ base: [
4766
+ "shadow-none",
4767
+ "component-search-border",
4768
+ "component-search-background",
4769
+ "hover:component-search-background",
4770
+ "hover:component-search-focus-hover",
4771
+ "transition-all",
4772
+ "duration-300",
4773
+ ],
4791
4774
  variants: {
4792
4775
  border: { true: ["!component-search-borderless"], false: "" },
4793
4776
  widenOnFocus: {
@@ -5245,9 +5228,10 @@ const TimeRangeField = ({ className, "data-testid": dataTestId, onChange, isInva
5245
5228
  return (jsx(FormGroup, { "data-testid": dataTestId ? `${dataTestId}-FormGroup` : undefined, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, ref: ref, style: style, tip: tip, children: jsx(TimeRange, { className: className, "data-testid": dataTestId, isInvalid: renderAsInvalid, onChange: onChange, ...rest, children: children }) }));
5246
5229
  };
5247
5230
 
5248
- const cvaToggleSwitchWrapper = cvaMerge(["grid", "grid-cols-[auto]", "items-center"]);
5249
- const cvaToggleSwitchInput = cvaMerge(["absolute", "pointer-events-none", "w-0", "h-0", "opacity-0"]);
5250
- const cvaToggleSwitchTrack = cvaMerge(["items-center", "shrink-0", "rounded-full", "transition-colors"], {
5231
+ const cvaToggleSwitchWrapper = cva({ base: ["grid", "grid-cols-[auto]", "items-center"] });
5232
+ const cvaToggleSwitchInput = cva({ base: ["absolute", "pointer-events-none", "w-0", "h-0", "opacity-0"] });
5233
+ const cvaToggleSwitchTrack = cva({
5234
+ base: ["items-center", "shrink-0", "rounded-full", "transition-colors"],
5251
5235
  variants: {
5252
5236
  size: {
5253
5237
  small: ["w-5", "p-0.5"],
@@ -5286,7 +5270,8 @@ const cvaToggleSwitchTrack = cvaMerge(["items-center", "shrink-0", "rounded-full
5286
5270
  disabled: false,
5287
5271
  },
5288
5272
  });
5289
- const cvaToggleSwitchThumb = cvaMerge(["block", "rounded-full", "bg-white", "aspect-square", "translate-x-0", "transition-all"], {
5273
+ const cvaToggleSwitchThumb = cva({
5274
+ base: ["block", "rounded-full", "bg-white", "aspect-square", "translate-x-0", "transition-all"],
5290
5275
  variants: {
5291
5276
  toggled: {
5292
5277
  true: "",
@@ -5484,16 +5469,9 @@ const ToggleSwitchOption = ({ label, className, description, suffix, id, "data-t
5484
5469
  };
5485
5470
  ToggleSwitchOption.displayName = "ToggleSwitchOption";
5486
5471
 
5487
- const cvaUploadInputField = cvaMerge([
5488
- "px-0",
5489
- "py-0",
5490
- "file:w-0",
5491
- "file:h-0",
5492
- "file:invisible",
5493
- "file:px-0",
5494
- "dark:text-neutral-400",
5495
- "self-center",
5496
- ]);
5472
+ const cvaUploadInputField = cva({
5473
+ base: ["px-0", "py-0", "file:w-0", "file:h-0", "file:invisible", "file:px-0", "dark:text-neutral-400", "self-center"],
5474
+ });
5497
5475
 
5498
5476
  /**
5499
5477
  * UploadInput renders a file upload input with a styled button label. It wraps `BaseInput` with `type="file"`