@trackunit/react-form-components 1.1.1 → 1.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.js +128 -73
- package/index.esm.js +126 -73
- package/package.json +7 -7
- package/src/components/Checkbox/Checkbox.d.ts +5 -5
- package/src/components/Checkbox/Checkbox.variants.d.ts +0 -1
- package/src/components/Label/Label.variants.d.ts +1 -0
- package/src/components/Label/index.d.ts +1 -0
- package/src/components/RadioGroup/RadioGroup.variants.d.ts +0 -7
- package/src/components/ToggleSwitch/ToggleSwitch.d.ts +51 -0
- package/src/components/ToggleSwitch/ToggleSwitch.variants.d.ts +12 -0
- package/src/components/ToggleSwitch/index.d.ts +1 -0
- package/src/components/ToggleSwitchOption/ToggleSwitchOption.d.ts +31 -0
- package/src/components/ToggleSwitchOption/index.d.ts +1 -0
- package/src/index.d.ts +3 -2
- package/src/shared-cva/BinaryControlItem.variants.d.ts +10 -0
- package/src/components/Toggle/Toggle.d.ts +0 -60
- package/src/components/Toggle/Toggle.variants.d.ts +0 -17
- package/src/components/Toggle/index.d.ts +0 -1
package/index.cjs.js
CHANGED
|
@@ -464,10 +464,41 @@ const BaseInput = React.forwardRef(({ className, isInvalid, dataTestId, prefix,
|
|
|
464
464
|
});
|
|
465
465
|
BaseInput.displayName = "BaseInput";
|
|
466
466
|
|
|
467
|
+
/**
|
|
468
|
+
* Shared CVA for binary control items: Checkbox, RadioItem, ToggleSwitchOption
|
|
469
|
+
*/
|
|
470
|
+
const cvaBinaryControlWrapper = cssClassVarianceUtilities.cvaMerge([
|
|
471
|
+
"grid-rows-subgrid", //* Children align to this parent grid
|
|
472
|
+
"grid-cols-min-fr", //* explicit horizontal placement for input and label/description
|
|
473
|
+
"auto-rows-auto", //* optional extra rows (suffix) will be auto-sized
|
|
474
|
+
"group",
|
|
475
|
+
"grid",
|
|
476
|
+
"gap-x-2",
|
|
477
|
+
]);
|
|
478
|
+
const cvaBinaryControlLabelTooltip = cssClassVarianceUtilities.cvaMerge(["col-start-2", "w-full", "self-center"]);
|
|
479
|
+
const cvaBinaryControlDescriptionTooltip = cssClassVarianceUtilities.cvaMerge(["col-span-2", "col-start-2", "row-start-2", "w-full"]);
|
|
480
|
+
const cvaBinaryControlDescription = cssClassVarianceUtilities.cvaMerge([
|
|
481
|
+
"text-sm",
|
|
482
|
+
"font-normal",
|
|
483
|
+
"text-slate-500",
|
|
484
|
+
"text-left",
|
|
485
|
+
"whitespace-nowrap",
|
|
486
|
+
"select-none",
|
|
487
|
+
"text-ellipsis",
|
|
488
|
+
"overflow-hidden",
|
|
489
|
+
], {
|
|
490
|
+
variants: {
|
|
491
|
+
disabled: {
|
|
492
|
+
true: ["text-slate-400", "hover:text-slate-400", "group-hover:text-slate-400"],
|
|
493
|
+
false: "",
|
|
494
|
+
},
|
|
495
|
+
},
|
|
496
|
+
});
|
|
497
|
+
const cvaBinaryControlSuffixContainer = cssClassVarianceUtilities.cvaMerge(["flex", "col-start-3", "items-center"]);
|
|
498
|
+
|
|
467
499
|
const cvaLabel = cssClassVarianceUtilities.cvaMerge([
|
|
468
500
|
"text-sm",
|
|
469
501
|
"text-slate-700",
|
|
470
|
-
"truncate",
|
|
471
502
|
"hover:text-slate-800",
|
|
472
503
|
"group-hover:text-slate-800",
|
|
473
504
|
"active:text-slate-800",
|
|
@@ -479,13 +510,18 @@ const cvaLabel = cssClassVarianceUtilities.cvaMerge([
|
|
|
479
510
|
false: "",
|
|
480
511
|
},
|
|
481
512
|
disabled: {
|
|
482
|
-
true: "text-slate-400 hover:text-slate-400 group-hover:text-slate-400",
|
|
513
|
+
true: "text-slate-400 hover:text-slate-400 active:text-slate-400 group-hover:text-slate-400 group-active:text-slate-400",
|
|
514
|
+
false: "",
|
|
515
|
+
},
|
|
516
|
+
truncate: {
|
|
517
|
+
true: "truncate",
|
|
483
518
|
false: "",
|
|
484
519
|
},
|
|
485
520
|
},
|
|
486
521
|
defaultVariants: {
|
|
487
522
|
invalid: false,
|
|
488
523
|
disabled: false,
|
|
524
|
+
truncate: true,
|
|
489
525
|
},
|
|
490
526
|
});
|
|
491
527
|
|
|
@@ -596,14 +632,6 @@ const cvaCheckbox = cssClassVarianceUtilities.cvaMerge([
|
|
|
596
632
|
state: "deselected",
|
|
597
633
|
},
|
|
598
634
|
});
|
|
599
|
-
const cvaCheckboxContainer = cssClassVarianceUtilities.cvaMerge([
|
|
600
|
-
"items-center",
|
|
601
|
-
"gap-2",
|
|
602
|
-
"group",
|
|
603
|
-
"grid",
|
|
604
|
-
"grid-cols-min-fr",
|
|
605
|
-
"has-[:nth-child(3)]:grid-cols-min-fr-min", //if there's 3 children
|
|
606
|
-
]);
|
|
607
635
|
const cvaCheckboxInput = cssClassVarianceUtilities.cvaMerge(["absolute", "opacity-0", "m-0", "pointer-events-none", "hidden"]);
|
|
608
636
|
const cvaCheckboxIcon = cssClassVarianceUtilities.cvaMerge(["w-2.5", "h-2.5", "text-white"]);
|
|
609
637
|
|
|
@@ -629,9 +657,9 @@ const IndeterminateIcon = ({ className }) => (jsxRuntime.jsx("svg", { className:
|
|
|
629
657
|
* @param {CheckboxProps} props - The props for the Checkbox component
|
|
630
658
|
* @returns {JSX.Element} Checkbox component
|
|
631
659
|
*/
|
|
632
|
-
const Checkbox =
|
|
660
|
+
const Checkbox = React.forwardRef(({ className, dataTestId = "checkbox", onChange, checked = false, disabled = false, isInvalid = false, readOnly, indeterminate = false, suffix, label, tabIndex = 0, stopPropagation, ...rest }, ref) => {
|
|
633
661
|
const icon = indeterminate ? (jsxRuntime.jsx(IndeterminateIcon, { className: cvaCheckboxIcon() })) : (checked && jsxRuntime.jsx(CheckIcon, { className: cvaCheckboxIcon() }));
|
|
634
|
-
const internalRef =
|
|
662
|
+
const internalRef = React.useRef(null);
|
|
635
663
|
const { isTextTruncated: isLabelCutOff, ref: labelRef } = reactComponents.useIsTextTruncated();
|
|
636
664
|
const isReadonly = disabled || readOnly;
|
|
637
665
|
const onKeyPress = e => {
|
|
@@ -644,14 +672,14 @@ const Checkbox = React__namespace.forwardRef(({ className, dataTestId = "checkbo
|
|
|
644
672
|
}
|
|
645
673
|
};
|
|
646
674
|
const uuid = rest.id;
|
|
647
|
-
return (jsxRuntime.jsxs("label", { className:
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
675
|
+
return (jsxRuntime.jsxs("label", { className: cvaBinaryControlWrapper({ className }), "data-testid": dataTestId ? `${dataTestId}-container` : null, htmlFor: uuid, onClick: e => stopPropagation && e.stopPropagation(), onKeyDown: onKeyPress, ref: internalRef, children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("input", { "aria-checked": !indeterminate && checked, checked: !indeterminate && checked, className: cvaCheckboxInput(), "data-testid": dataTestId, disabled: disabled, id: uuid, onChange: onChange, readOnly: readOnly, type: "checkbox", ...rest, ref: ref }), jsxRuntime.jsx("span", { className: cvaCheckbox({
|
|
676
|
+
disabled: isReadonly,
|
|
677
|
+
invalid: isReadonly ? false : isInvalid,
|
|
678
|
+
state: indeterminate ? "indeterminate" : checked ? "selected" : "deselected",
|
|
679
|
+
}), id: uuid, tabIndex: isReadonly ? -1 : tabIndex, children: icon })] }), jsxRuntime.jsx(reactComponents.Tooltip, { className: cvaBinaryControlLabelTooltip(), disabled: !isLabelCutOff, label: label, placement: "top", children: jsxRuntime.jsx("span", { className: cvaLabel({
|
|
652
680
|
invalid: isReadonly ? false : isInvalid,
|
|
653
681
|
disabled: isReadonly,
|
|
654
|
-
}), id: `checkbox-label-${label}`, ref: labelRef, children: label }) }, "tooltip-" + rest.name), suffix] }));
|
|
682
|
+
}), id: `checkbox-label-${label}`, ref: labelRef, children: label }) }, "tooltip-" + rest.name), suffix ? (jsxRuntime.jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": dataTestId ? `${dataTestId}-suffix-container` : undefined, children: suffix })) : null] }));
|
|
655
683
|
});
|
|
656
684
|
Checkbox.displayName = "Checkbox";
|
|
657
685
|
|
|
@@ -1495,25 +1523,6 @@ const cvaRadioItem = cssClassVarianceUtilities.cvaMerge([
|
|
|
1495
1523
|
},
|
|
1496
1524
|
],
|
|
1497
1525
|
});
|
|
1498
|
-
const cvaRadioItemWrapper = cssClassVarianceUtilities.cvaMerge([
|
|
1499
|
-
"grid-rows-subgrid", //* Children align to this parent grid
|
|
1500
|
-
"grid-cols-min-fr", //* explicit horizontal placement for input and label/description
|
|
1501
|
-
"auto-rows-auto", //* optional extra rows (suffix) will be auto-sized
|
|
1502
|
-
"group",
|
|
1503
|
-
"grid",
|
|
1504
|
-
"gap-x-2",
|
|
1505
|
-
]);
|
|
1506
|
-
const cvaRadioItemDescription = cssClassVarianceUtilities.cvaMerge(["text-sm", "font-normal", "text-slate-500", "text-left", "whitespace-nowrap", "text-ellipsis", "overflow-hidden"], {
|
|
1507
|
-
variants: {
|
|
1508
|
-
disabled: {
|
|
1509
|
-
true: ["text-slate-400", "hover:text-slate-400", "group-hover:text-slate-400"],
|
|
1510
|
-
false: "",
|
|
1511
|
-
},
|
|
1512
|
-
},
|
|
1513
|
-
});
|
|
1514
|
-
const cvaLabelTooltip = cssClassVarianceUtilities.cvaMerge(["col-start-2", "w-full", "self-center"]);
|
|
1515
|
-
const cvaDescriptionTooltip = cssClassVarianceUtilities.cvaMerge(["col-span-2", "col-start-2", "row-start-2", "w-full"]);
|
|
1516
|
-
const cvaSuffixContainer = cssClassVarianceUtilities.cvaMerge(["flex", "col-start-3", "items-center"]);
|
|
1517
1526
|
|
|
1518
1527
|
const RadioGroupContext = React__namespace.createContext(null);
|
|
1519
1528
|
|
|
@@ -1554,14 +1563,14 @@ const RadioItem = ({ label, value, dataTestId, className, description, suffix, .
|
|
|
1554
1563
|
const { ref: descriptionRef, isTextTruncated: isDescriptionTruncated } = reactComponents.useIsTextTruncated();
|
|
1555
1564
|
const descriptionId = description ? `${groupCtx?.id}-${value}-description` : undefined;
|
|
1556
1565
|
const inputId = `${groupCtx?.id}-${value}`;
|
|
1557
|
-
return (jsxRuntime.jsxs("label", { className:
|
|
1566
|
+
return (jsxRuntime.jsxs("label", { className: cvaBinaryControlWrapper({ className }), "data-testid": dataTestId ? `${dataTestId}-Wrapper` : undefined, htmlFor: inputId, children: [jsxRuntime.jsx("input", { "aria-describedby": descriptionId, checked: isChecked, className: cvaRadioItem({
|
|
1558
1567
|
checked: isChecked,
|
|
1559
1568
|
disabled: groupCtx?.disabled,
|
|
1560
1569
|
invalid: groupCtx?.isInvalid,
|
|
1561
|
-
}), "data-testid": dataTestId, id: inputId, onChange: groupCtx?.onChange, type: "radio", value: value, ...rest }), jsxRuntime.jsx(reactComponents.Tooltip, { className:
|
|
1570
|
+
}), "data-testid": dataTestId, id: inputId, onChange: groupCtx?.onChange, type: "radio", value: value, ...rest }), jsxRuntime.jsx(reactComponents.Tooltip, { className: cvaBinaryControlLabelTooltip(), dataTestId: dataTestId ? `${dataTestId}-Label-Tooltip` : undefined, disabled: !isLabelTruncated, label: label, placement: "top", children: jsxRuntime.jsx("span", { className: cvaLabel({
|
|
1562
1571
|
invalid: groupCtx?.isInvalid,
|
|
1563
1572
|
disabled: groupCtx?.disabled,
|
|
1564
|
-
}), "data-testid": dataTestId ? `${dataTestId}-Label` : undefined, ref: labelRef, children: label }) }, "tooltip-" + rest.name), suffix ? (jsxRuntime.jsx("div", { className:
|
|
1573
|
+
}), "data-testid": dataTestId ? `${dataTestId}-Label` : undefined, ref: labelRef, children: label }) }, "tooltip-" + rest.name), suffix ? (jsxRuntime.jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": dataTestId ? `${dataTestId}-suffix-container` : undefined, children: suffix })) : null, description ? (jsxRuntime.jsx(reactComponents.Tooltip, { className: cvaBinaryControlDescriptionTooltip(), dataTestId: dataTestId ? `${dataTestId}-Description-Tooltip` : undefined, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsxRuntime.jsx("span", { className: cvaBinaryControlDescription({ disabled: groupCtx?.disabled }), "data-testid": dataTestId ? `${dataTestId}-Description` : undefined, id: descriptionId, ref: descriptionRef, children: description }) }, "description-tooltip-" + rest.name)) : null] }));
|
|
1565
1574
|
};
|
|
1566
1575
|
|
|
1567
1576
|
const cvaTimeRange = cssClassVarianceUtilities.cvaMerge([
|
|
@@ -2615,9 +2624,9 @@ const TimeRangeField = ({ className, dataTestId, onChange, isInvalid, errorMessa
|
|
|
2615
2624
|
return (jsxRuntime.jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsxRuntime.jsx(TimeRange, { className: className, dataTestId: dataTestId, isInvalid: renderAsInvalid, onChange: onChange, ...rest, children: children }) }));
|
|
2616
2625
|
};
|
|
2617
2626
|
|
|
2618
|
-
const
|
|
2619
|
-
cssClassVarianceUtilities.cvaMerge(["
|
|
2620
|
-
const
|
|
2627
|
+
const cvaToggleSwitchWrapper = cssClassVarianceUtilities.cvaMerge(["grid", "grid-cols-[auto]", "items-center"]);
|
|
2628
|
+
const cvaToggleSwitchInput = cssClassVarianceUtilities.cvaMerge(["absolute", "pointer-events-none", "w-0", "h-0", "opacity-0"]);
|
|
2629
|
+
const cvaToggleSwitchTrack = cssClassVarianceUtilities.cvaMerge(["items-center", "shrink-0", "rounded-full"], {
|
|
2621
2630
|
variants: {
|
|
2622
2631
|
size: {
|
|
2623
2632
|
small: ["w-5", "p-0.5"],
|
|
@@ -2625,13 +2634,18 @@ const cvaToggleTrack = cssClassVarianceUtilities.cvaMerge(["shrink-0", "cursor-p
|
|
|
2625
2634
|
large: ["w-[38px]", "p-[3px]"],
|
|
2626
2635
|
},
|
|
2627
2636
|
disabled: {
|
|
2628
|
-
true: ["cursor-not-allowed", "
|
|
2629
|
-
false: "",
|
|
2637
|
+
true: ["cursor-not-allowed", "bg-slate-200"],
|
|
2638
|
+
false: ["cursor-pointer", "bg-slate-300", "hover:bg-slate-400", "active:bg-slate-500"],
|
|
2630
2639
|
},
|
|
2631
2640
|
toggled: {
|
|
2632
|
-
true:
|
|
2641
|
+
true: "", // classes moved to compoundVariants to avoid conflicts with the disabled variant
|
|
2633
2642
|
false: "",
|
|
2634
2643
|
},
|
|
2644
|
+
focused: {
|
|
2645
|
+
true: "outline-native",
|
|
2646
|
+
false: "outline-0",
|
|
2647
|
+
auto: "[&:has(:focus-visible)]:outline-native",
|
|
2648
|
+
},
|
|
2635
2649
|
},
|
|
2636
2650
|
compoundVariants: [
|
|
2637
2651
|
{
|
|
@@ -2639,12 +2653,19 @@ const cvaToggleTrack = cssClassVarianceUtilities.cvaMerge(["shrink-0", "cursor-p
|
|
|
2639
2653
|
toggled: true,
|
|
2640
2654
|
className: ["bg-slate-400"],
|
|
2641
2655
|
},
|
|
2656
|
+
{
|
|
2657
|
+
disabled: false,
|
|
2658
|
+
toggled: true,
|
|
2659
|
+
className: ["hover:bg-primary-700", "active:bg-primary-800", "bg-primary-600"],
|
|
2660
|
+
},
|
|
2642
2661
|
],
|
|
2643
2662
|
defaultVariants: {
|
|
2644
2663
|
size: "medium",
|
|
2664
|
+
focused: "auto",
|
|
2665
|
+
disabled: false,
|
|
2645
2666
|
},
|
|
2646
2667
|
});
|
|
2647
|
-
const
|
|
2668
|
+
const cvaToggleSwitchThumb = cssClassVarianceUtilities.cvaMerge(["block", "rounded-full", "bg-white", "aspect-square", "translate-x-0", "transition-all"], {
|
|
2648
2669
|
variants: {
|
|
2649
2670
|
toggled: {
|
|
2650
2671
|
true: "",
|
|
@@ -2675,38 +2696,70 @@ const cvaToggleThumb = cssClassVarianceUtilities.cvaMerge(["block", "rounded-ful
|
|
|
2675
2696
|
],
|
|
2676
2697
|
defaultVariants: {},
|
|
2677
2698
|
});
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2699
|
+
|
|
2700
|
+
/**
|
|
2701
|
+
* A checkbox input wrapper with role="switch". Used as an input element for **ToggleSwitchOption**
|
|
2702
|
+
* or custom components.
|
|
2703
|
+
*
|
|
2704
|
+
* Not intended for standalone use.
|
|
2705
|
+
*
|
|
2706
|
+
* @param {ToggleSwitchProps} props - The props for the ToggleSwitch component
|
|
2707
|
+
* @returns {ReactElement} ToggleSwitch component
|
|
2708
|
+
*/
|
|
2709
|
+
const ToggleSwitch = React.forwardRef(({ onChange, onClick, preventDefaultOnClick, className, dataTestId = "toggle-switch", showInputFocus, toggled, size = "medium", tabIndex = 0, readOnly, disabled, ...rest }, ref) => {
|
|
2710
|
+
const localInputRef = React.useRef(null);
|
|
2711
|
+
const inputRef = typeof ref === "function" ? localInputRef : ref || localInputRef;
|
|
2712
|
+
const handleWrapperClick = (e) => {
|
|
2713
|
+
// Prevents double-toggling when wrapped in a label or if preventDefaultOnClick is true
|
|
2714
|
+
const isFromLabel = e.target instanceof Element && e.target.closest("label");
|
|
2715
|
+
if (!isFromLabel && !preventDefaultOnClick && !disabled && !readOnly) {
|
|
2716
|
+
inputRef.current?.click();
|
|
2717
|
+
}
|
|
2718
|
+
onClick?.(e);
|
|
2719
|
+
};
|
|
2720
|
+
const handleKeyPress = e => {
|
|
2721
|
+
if (e.code === "Enter") {
|
|
2722
|
+
e.preventDefault();
|
|
2723
|
+
!readOnly && inputRef.current?.click();
|
|
2724
|
+
}
|
|
2725
|
+
// Space key is already supported natively by the input element
|
|
2726
|
+
};
|
|
2727
|
+
const handleInputChange = (e) => {
|
|
2728
|
+
if (readOnly || disabled) {
|
|
2729
|
+
return;
|
|
2730
|
+
}
|
|
2731
|
+
e.stopPropagation();
|
|
2732
|
+
onChange?.(!toggled, e);
|
|
2733
|
+
};
|
|
2734
|
+
return (jsxRuntime.jsx("span", { className: cvaToggleSwitchWrapper({ className }), "data-testid": `${dataTestId}`, onClick: handleWrapperClick, onKeyDown: handleKeyPress, children: jsxRuntime.jsxs("span", { className: cvaToggleSwitchTrack({
|
|
2735
|
+
toggled,
|
|
2736
|
+
disabled: disabled || readOnly,
|
|
2737
|
+
size,
|
|
2738
|
+
focused: showInputFocus,
|
|
2739
|
+
}), "data-testid": `${dataTestId}-track`, children: [jsxRuntime.jsx("span", { className: cvaToggleSwitchThumb({ toggled, size }), "data-testid": `${dataTestId}-thumb` }), jsxRuntime.jsx("input", { "aria-disabled": disabled || readOnly, checked: toggled, className: cvaToggleSwitchInput(), "data-testid": `${dataTestId}-input`, disabled: disabled, onChange: handleInputChange, onClick: e => e.stopPropagation(), ref: inputRef, role: "switch", type: "checkbox", ...rest })] }) }));
|
|
2688
2740
|
});
|
|
2741
|
+
ToggleSwitch.displayName = "ToggleSwitch";
|
|
2689
2742
|
|
|
2690
2743
|
/**
|
|
2691
|
-
* Use
|
|
2744
|
+
* Use ToggleSwitchOption when you have to only enable/disable a feature.
|
|
2745
|
+
* Wrapper component for ToggleSwitch.
|
|
2692
2746
|
*
|
|
2693
|
-
* _**Do use**
|
|
2747
|
+
* _**Do use** ToggleSwitchOption in forms or settings._
|
|
2694
2748
|
*
|
|
2695
|
-
* _**Do not use**
|
|
2749
|
+
* _**Do not use** ToggleSwitchOption if a user can select multiple options from a list, use checkboxes instead of toggle._
|
|
2696
2750
|
*
|
|
2697
|
-
* @param {
|
|
2698
|
-
* @returns {
|
|
2751
|
+
* @param {ToggleSwitchOptionProps} props - The props for the ToggleSwitchOption component
|
|
2752
|
+
* @returns {ReactElement} ToggleSwitchOption component
|
|
2699
2753
|
*/
|
|
2700
|
-
const
|
|
2701
|
-
const
|
|
2702
|
-
const
|
|
2703
|
-
|
|
2704
|
-
|
|
2705
|
-
|
|
2706
|
-
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
Toggle.displayName = "Toggle";
|
|
2754
|
+
const ToggleSwitchOption = ({ label, className, description, suffix, id, dataTestId = "toggle-switch-option", ...rest }) => {
|
|
2755
|
+
const { ref: labelRef, isTextTruncated: isLabelTruncated } = reactComponents.useIsTextTruncated();
|
|
2756
|
+
const { ref: descriptionRef, isTextTruncated: isDescriptionTruncated } = reactComponents.useIsTextTruncated();
|
|
2757
|
+
return (jsxRuntime.jsxs("label", { className: cvaBinaryControlWrapper({ className }), "data-testid": dataTestId, htmlFor: `${id}-toggle-switch`, tabIndex: -1, children: [jsxRuntime.jsx(ToggleSwitch, { dataTestId: `${dataTestId}-switcher`, id: `${id}-toggle-switch`, ...rest }), jsxRuntime.jsx(reactComponents.Tooltip, { className: cvaBinaryControlLabelTooltip(), dataTestId: `${dataTestId}-label-tooltip`, disabled: !isLabelTruncated, label: label, placement: "top", children: jsxRuntime.jsx("span", { className: cvaLabel({
|
|
2758
|
+
disabled: rest.disabled || rest.readOnly,
|
|
2759
|
+
className: "select-none",
|
|
2760
|
+
}), "data-testid": `${dataTestId}-label`, ref: labelRef, children: label }) }, `${id}-label-tooltip`), suffix ? (jsxRuntime.jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": `${dataTestId}-suffix-container`, children: suffix })) : null, description ? (jsxRuntime.jsx(reactComponents.Tooltip, { className: cvaBinaryControlDescriptionTooltip(), dataTestId: `${dataTestId}-description-tooltip`, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsxRuntime.jsx("span", { className: cvaBinaryControlDescription({ disabled: rest.disabled || rest.readOnly }), "data-testid": `${dataTestId}-description`, id: `${id}-description`, ref: descriptionRef, children: description }) }, `${id}-description-tooltip`)) : null] }));
|
|
2761
|
+
};
|
|
2762
|
+
ToggleSwitchOption.displayName = "ToggleSwitchOption";
|
|
2710
2763
|
|
|
2711
2764
|
const cvaUploadInputField = cssClassVarianceUtilities.cvaMerge([
|
|
2712
2765
|
"px-0",
|
|
@@ -2962,7 +3015,8 @@ exports.TextField = TextField;
|
|
|
2962
3015
|
exports.TextInput = TextInput;
|
|
2963
3016
|
exports.TimeRange = TimeRange;
|
|
2964
3017
|
exports.TimeRangeField = TimeRangeField;
|
|
2965
|
-
exports.
|
|
3018
|
+
exports.ToggleSwitch = ToggleSwitch;
|
|
3019
|
+
exports.ToggleSwitchOption = ToggleSwitchOption;
|
|
2966
3020
|
exports.UploadField = UploadField;
|
|
2967
3021
|
exports.UploadInput = UploadInput;
|
|
2968
3022
|
exports.UrlField = UrlField;
|
|
@@ -2981,6 +3035,7 @@ exports.cvaInputField = cvaInputField;
|
|
|
2981
3035
|
exports.cvaInputItemPlacementManager = cvaInputItemPlacementManager;
|
|
2982
3036
|
exports.cvaInputPrefix = cvaInputPrefix;
|
|
2983
3037
|
exports.cvaInputSuffix = cvaInputSuffix;
|
|
3038
|
+
exports.cvaLabel = cvaLabel;
|
|
2984
3039
|
exports.cvaSelect = cvaSelect;
|
|
2985
3040
|
exports.cvaSelectControl = cvaSelectControl;
|
|
2986
3041
|
exports.cvaSelectCounter = cvaSelectCounter;
|
package/index.esm.js
CHANGED
|
@@ -445,10 +445,41 @@ const BaseInput = forwardRef(({ className, isInvalid, dataTestId, prefix, suffix
|
|
|
445
445
|
});
|
|
446
446
|
BaseInput.displayName = "BaseInput";
|
|
447
447
|
|
|
448
|
+
/**
|
|
449
|
+
* Shared CVA for binary control items: Checkbox, RadioItem, ToggleSwitchOption
|
|
450
|
+
*/
|
|
451
|
+
const cvaBinaryControlWrapper = cvaMerge([
|
|
452
|
+
"grid-rows-subgrid", //* Children align to this parent grid
|
|
453
|
+
"grid-cols-min-fr", //* explicit horizontal placement for input and label/description
|
|
454
|
+
"auto-rows-auto", //* optional extra rows (suffix) will be auto-sized
|
|
455
|
+
"group",
|
|
456
|
+
"grid",
|
|
457
|
+
"gap-x-2",
|
|
458
|
+
]);
|
|
459
|
+
const cvaBinaryControlLabelTooltip = cvaMerge(["col-start-2", "w-full", "self-center"]);
|
|
460
|
+
const cvaBinaryControlDescriptionTooltip = cvaMerge(["col-span-2", "col-start-2", "row-start-2", "w-full"]);
|
|
461
|
+
const cvaBinaryControlDescription = cvaMerge([
|
|
462
|
+
"text-sm",
|
|
463
|
+
"font-normal",
|
|
464
|
+
"text-slate-500",
|
|
465
|
+
"text-left",
|
|
466
|
+
"whitespace-nowrap",
|
|
467
|
+
"select-none",
|
|
468
|
+
"text-ellipsis",
|
|
469
|
+
"overflow-hidden",
|
|
470
|
+
], {
|
|
471
|
+
variants: {
|
|
472
|
+
disabled: {
|
|
473
|
+
true: ["text-slate-400", "hover:text-slate-400", "group-hover:text-slate-400"],
|
|
474
|
+
false: "",
|
|
475
|
+
},
|
|
476
|
+
},
|
|
477
|
+
});
|
|
478
|
+
const cvaBinaryControlSuffixContainer = cvaMerge(["flex", "col-start-3", "items-center"]);
|
|
479
|
+
|
|
448
480
|
const cvaLabel = cvaMerge([
|
|
449
481
|
"text-sm",
|
|
450
482
|
"text-slate-700",
|
|
451
|
-
"truncate",
|
|
452
483
|
"hover:text-slate-800",
|
|
453
484
|
"group-hover:text-slate-800",
|
|
454
485
|
"active:text-slate-800",
|
|
@@ -460,13 +491,18 @@ const cvaLabel = cvaMerge([
|
|
|
460
491
|
false: "",
|
|
461
492
|
},
|
|
462
493
|
disabled: {
|
|
463
|
-
true: "text-slate-400 hover:text-slate-400 group-hover:text-slate-400",
|
|
494
|
+
true: "text-slate-400 hover:text-slate-400 active:text-slate-400 group-hover:text-slate-400 group-active:text-slate-400",
|
|
495
|
+
false: "",
|
|
496
|
+
},
|
|
497
|
+
truncate: {
|
|
498
|
+
true: "truncate",
|
|
464
499
|
false: "",
|
|
465
500
|
},
|
|
466
501
|
},
|
|
467
502
|
defaultVariants: {
|
|
468
503
|
invalid: false,
|
|
469
504
|
disabled: false,
|
|
505
|
+
truncate: true,
|
|
470
506
|
},
|
|
471
507
|
});
|
|
472
508
|
|
|
@@ -577,14 +613,6 @@ const cvaCheckbox = cvaMerge([
|
|
|
577
613
|
state: "deselected",
|
|
578
614
|
},
|
|
579
615
|
});
|
|
580
|
-
const cvaCheckboxContainer = cvaMerge([
|
|
581
|
-
"items-center",
|
|
582
|
-
"gap-2",
|
|
583
|
-
"group",
|
|
584
|
-
"grid",
|
|
585
|
-
"grid-cols-min-fr",
|
|
586
|
-
"has-[:nth-child(3)]:grid-cols-min-fr-min", //if there's 3 children
|
|
587
|
-
]);
|
|
588
616
|
const cvaCheckboxInput = cvaMerge(["absolute", "opacity-0", "m-0", "pointer-events-none", "hidden"]);
|
|
589
617
|
const cvaCheckboxIcon = cvaMerge(["w-2.5", "h-2.5", "text-white"]);
|
|
590
618
|
|
|
@@ -610,9 +638,9 @@ const IndeterminateIcon = ({ className }) => (jsx("svg", { className: className,
|
|
|
610
638
|
* @param {CheckboxProps} props - The props for the Checkbox component
|
|
611
639
|
* @returns {JSX.Element} Checkbox component
|
|
612
640
|
*/
|
|
613
|
-
const Checkbox =
|
|
641
|
+
const Checkbox = forwardRef(({ className, dataTestId = "checkbox", onChange, checked = false, disabled = false, isInvalid = false, readOnly, indeterminate = false, suffix, label, tabIndex = 0, stopPropagation, ...rest }, ref) => {
|
|
614
642
|
const icon = indeterminate ? (jsx(IndeterminateIcon, { className: cvaCheckboxIcon() })) : (checked && jsx(CheckIcon, { className: cvaCheckboxIcon() }));
|
|
615
|
-
const internalRef =
|
|
643
|
+
const internalRef = useRef(null);
|
|
616
644
|
const { isTextTruncated: isLabelCutOff, ref: labelRef } = useIsTextTruncated();
|
|
617
645
|
const isReadonly = disabled || readOnly;
|
|
618
646
|
const onKeyPress = e => {
|
|
@@ -625,14 +653,14 @@ const Checkbox = React.forwardRef(({ className, dataTestId = "checkbox", onChang
|
|
|
625
653
|
}
|
|
626
654
|
};
|
|
627
655
|
const uuid = rest.id;
|
|
628
|
-
return (jsxs("label", { className:
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
656
|
+
return (jsxs("label", { className: cvaBinaryControlWrapper({ className }), "data-testid": dataTestId ? `${dataTestId}-container` : null, htmlFor: uuid, onClick: e => stopPropagation && e.stopPropagation(), onKeyDown: onKeyPress, ref: internalRef, children: [jsxs("div", { children: [jsx("input", { "aria-checked": !indeterminate && checked, checked: !indeterminate && checked, className: cvaCheckboxInput(), "data-testid": dataTestId, disabled: disabled, id: uuid, onChange: onChange, readOnly: readOnly, type: "checkbox", ...rest, ref: ref }), jsx("span", { className: cvaCheckbox({
|
|
657
|
+
disabled: isReadonly,
|
|
658
|
+
invalid: isReadonly ? false : isInvalid,
|
|
659
|
+
state: indeterminate ? "indeterminate" : checked ? "selected" : "deselected",
|
|
660
|
+
}), id: uuid, tabIndex: isReadonly ? -1 : tabIndex, children: icon })] }), jsx(Tooltip, { className: cvaBinaryControlLabelTooltip(), disabled: !isLabelCutOff, label: label, placement: "top", children: jsx("span", { className: cvaLabel({
|
|
633
661
|
invalid: isReadonly ? false : isInvalid,
|
|
634
662
|
disabled: isReadonly,
|
|
635
|
-
}), id: `checkbox-label-${label}`, ref: labelRef, children: label }) }, "tooltip-" + rest.name), suffix] }));
|
|
663
|
+
}), id: `checkbox-label-${label}`, ref: labelRef, children: label }) }, "tooltip-" + rest.name), suffix ? (jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": dataTestId ? `${dataTestId}-suffix-container` : undefined, children: suffix })) : null] }));
|
|
636
664
|
});
|
|
637
665
|
Checkbox.displayName = "Checkbox";
|
|
638
666
|
|
|
@@ -1476,25 +1504,6 @@ const cvaRadioItem = cvaMerge([
|
|
|
1476
1504
|
},
|
|
1477
1505
|
],
|
|
1478
1506
|
});
|
|
1479
|
-
const cvaRadioItemWrapper = cvaMerge([
|
|
1480
|
-
"grid-rows-subgrid", //* Children align to this parent grid
|
|
1481
|
-
"grid-cols-min-fr", //* explicit horizontal placement for input and label/description
|
|
1482
|
-
"auto-rows-auto", //* optional extra rows (suffix) will be auto-sized
|
|
1483
|
-
"group",
|
|
1484
|
-
"grid",
|
|
1485
|
-
"gap-x-2",
|
|
1486
|
-
]);
|
|
1487
|
-
const cvaRadioItemDescription = cvaMerge(["text-sm", "font-normal", "text-slate-500", "text-left", "whitespace-nowrap", "text-ellipsis", "overflow-hidden"], {
|
|
1488
|
-
variants: {
|
|
1489
|
-
disabled: {
|
|
1490
|
-
true: ["text-slate-400", "hover:text-slate-400", "group-hover:text-slate-400"],
|
|
1491
|
-
false: "",
|
|
1492
|
-
},
|
|
1493
|
-
},
|
|
1494
|
-
});
|
|
1495
|
-
const cvaLabelTooltip = cvaMerge(["col-start-2", "w-full", "self-center"]);
|
|
1496
|
-
const cvaDescriptionTooltip = cvaMerge(["col-span-2", "col-start-2", "row-start-2", "w-full"]);
|
|
1497
|
-
const cvaSuffixContainer = cvaMerge(["flex", "col-start-3", "items-center"]);
|
|
1498
1507
|
|
|
1499
1508
|
const RadioGroupContext = React.createContext(null);
|
|
1500
1509
|
|
|
@@ -1535,14 +1544,14 @@ const RadioItem = ({ label, value, dataTestId, className, description, suffix, .
|
|
|
1535
1544
|
const { ref: descriptionRef, isTextTruncated: isDescriptionTruncated } = useIsTextTruncated();
|
|
1536
1545
|
const descriptionId = description ? `${groupCtx?.id}-${value}-description` : undefined;
|
|
1537
1546
|
const inputId = `${groupCtx?.id}-${value}`;
|
|
1538
|
-
return (jsxs("label", { className:
|
|
1547
|
+
return (jsxs("label", { className: cvaBinaryControlWrapper({ className }), "data-testid": dataTestId ? `${dataTestId}-Wrapper` : undefined, htmlFor: inputId, children: [jsx("input", { "aria-describedby": descriptionId, checked: isChecked, className: cvaRadioItem({
|
|
1539
1548
|
checked: isChecked,
|
|
1540
1549
|
disabled: groupCtx?.disabled,
|
|
1541
1550
|
invalid: groupCtx?.isInvalid,
|
|
1542
|
-
}), "data-testid": dataTestId, id: inputId, onChange: groupCtx?.onChange, type: "radio", value: value, ...rest }), jsx(Tooltip, { className:
|
|
1551
|
+
}), "data-testid": dataTestId, id: inputId, onChange: groupCtx?.onChange, type: "radio", value: value, ...rest }), jsx(Tooltip, { className: cvaBinaryControlLabelTooltip(), dataTestId: dataTestId ? `${dataTestId}-Label-Tooltip` : undefined, disabled: !isLabelTruncated, label: label, placement: "top", children: jsx("span", { className: cvaLabel({
|
|
1543
1552
|
invalid: groupCtx?.isInvalid,
|
|
1544
1553
|
disabled: groupCtx?.disabled,
|
|
1545
|
-
}), "data-testid": dataTestId ? `${dataTestId}-Label` : undefined, ref: labelRef, children: label }) }, "tooltip-" + rest.name), suffix ? (jsx("div", { className:
|
|
1554
|
+
}), "data-testid": dataTestId ? `${dataTestId}-Label` : undefined, ref: labelRef, children: label }) }, "tooltip-" + rest.name), suffix ? (jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": dataTestId ? `${dataTestId}-suffix-container` : undefined, children: suffix })) : null, description ? (jsx(Tooltip, { className: cvaBinaryControlDescriptionTooltip(), dataTestId: dataTestId ? `${dataTestId}-Description-Tooltip` : undefined, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsx("span", { className: cvaBinaryControlDescription({ disabled: groupCtx?.disabled }), "data-testid": dataTestId ? `${dataTestId}-Description` : undefined, id: descriptionId, ref: descriptionRef, children: description }) }, "description-tooltip-" + rest.name)) : null] }));
|
|
1546
1555
|
};
|
|
1547
1556
|
|
|
1548
1557
|
const cvaTimeRange = cvaMerge([
|
|
@@ -2596,9 +2605,9 @@ const TimeRangeField = ({ className, dataTestId, onChange, isInvalid, errorMessa
|
|
|
2596
2605
|
return (jsx(FormGroup, { dataTestId: dataTestId ? `${dataTestId}-FormGroup` : undefined, helpText: (renderAsInvalid && errorMessage) || helpText, htmlFor: htmlFor, isInvalid: renderAsInvalid, label: label, tip: tip, children: jsx(TimeRange, { className: className, dataTestId: dataTestId, isInvalid: renderAsInvalid, onChange: onChange, ...rest, children: children }) }));
|
|
2597
2606
|
};
|
|
2598
2607
|
|
|
2599
|
-
const
|
|
2600
|
-
cvaMerge(["
|
|
2601
|
-
const
|
|
2608
|
+
const cvaToggleSwitchWrapper = cvaMerge(["grid", "grid-cols-[auto]", "items-center"]);
|
|
2609
|
+
const cvaToggleSwitchInput = cvaMerge(["absolute", "pointer-events-none", "w-0", "h-0", "opacity-0"]);
|
|
2610
|
+
const cvaToggleSwitchTrack = cvaMerge(["items-center", "shrink-0", "rounded-full"], {
|
|
2602
2611
|
variants: {
|
|
2603
2612
|
size: {
|
|
2604
2613
|
small: ["w-5", "p-0.5"],
|
|
@@ -2606,13 +2615,18 @@ const cvaToggleTrack = cvaMerge(["shrink-0", "cursor-pointer", "rounded-full", "
|
|
|
2606
2615
|
large: ["w-[38px]", "p-[3px]"],
|
|
2607
2616
|
},
|
|
2608
2617
|
disabled: {
|
|
2609
|
-
true: ["cursor-not-allowed", "
|
|
2610
|
-
false: "",
|
|
2618
|
+
true: ["cursor-not-allowed", "bg-slate-200"],
|
|
2619
|
+
false: ["cursor-pointer", "bg-slate-300", "hover:bg-slate-400", "active:bg-slate-500"],
|
|
2611
2620
|
},
|
|
2612
2621
|
toggled: {
|
|
2613
|
-
true:
|
|
2622
|
+
true: "", // classes moved to compoundVariants to avoid conflicts with the disabled variant
|
|
2614
2623
|
false: "",
|
|
2615
2624
|
},
|
|
2625
|
+
focused: {
|
|
2626
|
+
true: "outline-native",
|
|
2627
|
+
false: "outline-0",
|
|
2628
|
+
auto: "[&:has(:focus-visible)]:outline-native",
|
|
2629
|
+
},
|
|
2616
2630
|
},
|
|
2617
2631
|
compoundVariants: [
|
|
2618
2632
|
{
|
|
@@ -2620,12 +2634,19 @@ const cvaToggleTrack = cvaMerge(["shrink-0", "cursor-pointer", "rounded-full", "
|
|
|
2620
2634
|
toggled: true,
|
|
2621
2635
|
className: ["bg-slate-400"],
|
|
2622
2636
|
},
|
|
2637
|
+
{
|
|
2638
|
+
disabled: false,
|
|
2639
|
+
toggled: true,
|
|
2640
|
+
className: ["hover:bg-primary-700", "active:bg-primary-800", "bg-primary-600"],
|
|
2641
|
+
},
|
|
2623
2642
|
],
|
|
2624
2643
|
defaultVariants: {
|
|
2625
2644
|
size: "medium",
|
|
2645
|
+
focused: "auto",
|
|
2646
|
+
disabled: false,
|
|
2626
2647
|
},
|
|
2627
2648
|
});
|
|
2628
|
-
const
|
|
2649
|
+
const cvaToggleSwitchThumb = cvaMerge(["block", "rounded-full", "bg-white", "aspect-square", "translate-x-0", "transition-all"], {
|
|
2629
2650
|
variants: {
|
|
2630
2651
|
toggled: {
|
|
2631
2652
|
true: "",
|
|
@@ -2656,38 +2677,70 @@ const cvaToggleThumb = cvaMerge(["block", "rounded-full", "bg-white", "aspect-sq
|
|
|
2656
2677
|
],
|
|
2657
2678
|
defaultVariants: {},
|
|
2658
2679
|
});
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2680
|
+
|
|
2681
|
+
/**
|
|
2682
|
+
* A checkbox input wrapper with role="switch". Used as an input element for **ToggleSwitchOption**
|
|
2683
|
+
* or custom components.
|
|
2684
|
+
*
|
|
2685
|
+
* Not intended for standalone use.
|
|
2686
|
+
*
|
|
2687
|
+
* @param {ToggleSwitchProps} props - The props for the ToggleSwitch component
|
|
2688
|
+
* @returns {ReactElement} ToggleSwitch component
|
|
2689
|
+
*/
|
|
2690
|
+
const ToggleSwitch = forwardRef(({ onChange, onClick, preventDefaultOnClick, className, dataTestId = "toggle-switch", showInputFocus, toggled, size = "medium", tabIndex = 0, readOnly, disabled, ...rest }, ref) => {
|
|
2691
|
+
const localInputRef = useRef(null);
|
|
2692
|
+
const inputRef = typeof ref === "function" ? localInputRef : ref || localInputRef;
|
|
2693
|
+
const handleWrapperClick = (e) => {
|
|
2694
|
+
// Prevents double-toggling when wrapped in a label or if preventDefaultOnClick is true
|
|
2695
|
+
const isFromLabel = e.target instanceof Element && e.target.closest("label");
|
|
2696
|
+
if (!isFromLabel && !preventDefaultOnClick && !disabled && !readOnly) {
|
|
2697
|
+
inputRef.current?.click();
|
|
2698
|
+
}
|
|
2699
|
+
onClick?.(e);
|
|
2700
|
+
};
|
|
2701
|
+
const handleKeyPress = e => {
|
|
2702
|
+
if (e.code === "Enter") {
|
|
2703
|
+
e.preventDefault();
|
|
2704
|
+
!readOnly && inputRef.current?.click();
|
|
2705
|
+
}
|
|
2706
|
+
// Space key is already supported natively by the input element
|
|
2707
|
+
};
|
|
2708
|
+
const handleInputChange = (e) => {
|
|
2709
|
+
if (readOnly || disabled) {
|
|
2710
|
+
return;
|
|
2711
|
+
}
|
|
2712
|
+
e.stopPropagation();
|
|
2713
|
+
onChange?.(!toggled, e);
|
|
2714
|
+
};
|
|
2715
|
+
return (jsx("span", { className: cvaToggleSwitchWrapper({ className }), "data-testid": `${dataTestId}`, onClick: handleWrapperClick, onKeyDown: handleKeyPress, children: jsxs("span", { className: cvaToggleSwitchTrack({
|
|
2716
|
+
toggled,
|
|
2717
|
+
disabled: disabled || readOnly,
|
|
2718
|
+
size,
|
|
2719
|
+
focused: showInputFocus,
|
|
2720
|
+
}), "data-testid": `${dataTestId}-track`, children: [jsx("span", { className: cvaToggleSwitchThumb({ toggled, size }), "data-testid": `${dataTestId}-thumb` }), jsx("input", { "aria-disabled": disabled || readOnly, checked: toggled, className: cvaToggleSwitchInput(), "data-testid": `${dataTestId}-input`, disabled: disabled, onChange: handleInputChange, onClick: e => e.stopPropagation(), ref: inputRef, role: "switch", type: "checkbox", ...rest })] }) }));
|
|
2669
2721
|
});
|
|
2722
|
+
ToggleSwitch.displayName = "ToggleSwitch";
|
|
2670
2723
|
|
|
2671
2724
|
/**
|
|
2672
|
-
* Use
|
|
2725
|
+
* Use ToggleSwitchOption when you have to only enable/disable a feature.
|
|
2726
|
+
* Wrapper component for ToggleSwitch.
|
|
2673
2727
|
*
|
|
2674
|
-
* _**Do use**
|
|
2728
|
+
* _**Do use** ToggleSwitchOption in forms or settings._
|
|
2675
2729
|
*
|
|
2676
|
-
* _**Do not use**
|
|
2730
|
+
* _**Do not use** ToggleSwitchOption if a user can select multiple options from a list, use checkboxes instead of toggle._
|
|
2677
2731
|
*
|
|
2678
|
-
* @param {
|
|
2679
|
-
* @returns {
|
|
2732
|
+
* @param {ToggleSwitchOptionProps} props - The props for the ToggleSwitchOption component
|
|
2733
|
+
* @returns {ReactElement} ToggleSwitchOption component
|
|
2680
2734
|
*/
|
|
2681
|
-
const
|
|
2682
|
-
const
|
|
2683
|
-
const
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
Toggle.displayName = "Toggle";
|
|
2735
|
+
const ToggleSwitchOption = ({ label, className, description, suffix, id, dataTestId = "toggle-switch-option", ...rest }) => {
|
|
2736
|
+
const { ref: labelRef, isTextTruncated: isLabelTruncated } = useIsTextTruncated();
|
|
2737
|
+
const { ref: descriptionRef, isTextTruncated: isDescriptionTruncated } = useIsTextTruncated();
|
|
2738
|
+
return (jsxs("label", { className: cvaBinaryControlWrapper({ className }), "data-testid": dataTestId, htmlFor: `${id}-toggle-switch`, tabIndex: -1, children: [jsx(ToggleSwitch, { dataTestId: `${dataTestId}-switcher`, id: `${id}-toggle-switch`, ...rest }), jsx(Tooltip, { className: cvaBinaryControlLabelTooltip(), dataTestId: `${dataTestId}-label-tooltip`, disabled: !isLabelTruncated, label: label, placement: "top", children: jsx("span", { className: cvaLabel({
|
|
2739
|
+
disabled: rest.disabled || rest.readOnly,
|
|
2740
|
+
className: "select-none",
|
|
2741
|
+
}), "data-testid": `${dataTestId}-label`, ref: labelRef, children: label }) }, `${id}-label-tooltip`), suffix ? (jsx("div", { className: cvaBinaryControlSuffixContainer(), "data-testid": `${dataTestId}-suffix-container`, children: suffix })) : null, description ? (jsx(Tooltip, { className: cvaBinaryControlDescriptionTooltip(), dataTestId: `${dataTestId}-description-tooltip`, disabled: !isDescriptionTruncated, label: description, placement: "top", children: jsx("span", { className: cvaBinaryControlDescription({ disabled: rest.disabled || rest.readOnly }), "data-testid": `${dataTestId}-description`, id: `${id}-description`, ref: descriptionRef, children: description }) }, `${id}-description-tooltip`)) : null] }));
|
|
2742
|
+
};
|
|
2743
|
+
ToggleSwitchOption.displayName = "ToggleSwitchOption";
|
|
2691
2744
|
|
|
2692
2745
|
const cvaUploadInputField = cvaMerge([
|
|
2693
2746
|
"px-0",
|
|
@@ -2903,4 +2956,4 @@ const useZodValidators = () => {
|
|
|
2903
2956
|
*/
|
|
2904
2957
|
setupLibraryTranslations();
|
|
2905
2958
|
|
|
2906
|
-
export { ActionButton, BaseInput, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DateField, DateInput, DropZone, DropZoneDefaultLabel, EMAIL_REGEX, EmailField, EmailInput, FormFieldSelectAdapter, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PasswordField, PasswordInput, PhoneField, PhoneFieldWithController, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SelectField, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField,
|
|
2959
|
+
export { ActionButton, BaseInput, Checkbox, CheckboxField, ColorField, CreatableSelect, CreatableSelectField, DateField, DateInput, DropZone, DropZoneDefaultLabel, EMAIL_REGEX, EmailField, EmailInput, FormFieldSelectAdapter, FormGroup, Label, MultiSelectMenuItem, NumberField, NumberInput, OptionCard, PasswordField, PasswordInput, PhoneField, PhoneFieldWithController, PhoneInput, RadioGroup, RadioItem, Schedule, ScheduleVariant, Search, Select, SelectField, SingleSelectMenuItem, TextArea, TextAreaField, TextField, TextInput, TimeRange, TimeRangeField, ToggleSwitch, ToggleSwitchOption, UploadField, UploadInput, UrlField, UrlInput, checkIfPhoneNumberHasPlus, countryCodeToFlagEmoji, cvaAccessoriesContainer, cvaActionButton, cvaActionContainer, cvaInput, cvaInputAddon, cvaInputBase, cvaInputBaseDisabled, cvaInputBaseInvalid, cvaInputField, cvaInputItemPlacementManager, cvaInputPrefix, cvaInputSuffix, cvaLabel, cvaSelect, cvaSelectControl, cvaSelectCounter, cvaSelectDynamicTagContainer, cvaSelectIcon, cvaSelectMenu, cvaSelectMenuList, cvaSelectPrefixSuffix, cvaSelectXIcon, getCountryAbbreviation, getPhoneNumberWithPlus, isInvalidCountryCode, isInvalidPhoneNumber, isValidHEXColor, parseSchedule, phoneErrorMessage, serializeSchedule, useCustomComponents, useGetPhoneValidationRules, usePhoneInput, useZodValidators, validateEmailAddress, validatePhoneNumber, weekDay };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@trackunit/react-form-components",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"repository": "https://github.com/Trackunit/manager",
|
|
5
5
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
6
6
|
"engines": {
|
|
@@ -17,12 +17,12 @@
|
|
|
17
17
|
"zod": "3.22.4",
|
|
18
18
|
"react-hook-form": "7.53.1",
|
|
19
19
|
"tailwind-merge": "^2.0.0",
|
|
20
|
-
"@trackunit/css-class-variance-utilities": "1.
|
|
21
|
-
"@trackunit/react-components": "1.
|
|
22
|
-
"@trackunit/ui-icons": "1.
|
|
23
|
-
"@trackunit/shared-utils": "1.
|
|
24
|
-
"@trackunit/ui-design-tokens": "1.
|
|
25
|
-
"@trackunit/i18n-library-translation": "1.
|
|
20
|
+
"@trackunit/css-class-variance-utilities": "1.2.0",
|
|
21
|
+
"@trackunit/react-components": "1.3.0",
|
|
22
|
+
"@trackunit/ui-icons": "1.2.0",
|
|
23
|
+
"@trackunit/shared-utils": "1.4.0",
|
|
24
|
+
"@trackunit/ui-design-tokens": "1.2.0",
|
|
25
|
+
"@trackunit/i18n-library-translation": "1.2.0",
|
|
26
26
|
"string-ts": "^2.0.0"
|
|
27
27
|
},
|
|
28
28
|
"module": "./index.esm.js",
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { CommonProps } from "@trackunit/react-components";
|
|
2
2
|
import { MappedOmit } from "@trackunit/shared-utils";
|
|
3
|
-
import
|
|
4
|
-
export interface CheckboxProps extends CommonProps, MappedOmit<
|
|
3
|
+
import { InputHTMLAttributes, ReactNode } from "react";
|
|
4
|
+
export interface CheckboxProps extends CommonProps, MappedOmit<InputHTMLAttributes<HTMLInputElement>, "prefix"> {
|
|
5
5
|
/**
|
|
6
6
|
* A string element to be displayed as a label
|
|
7
7
|
*/
|
|
8
|
-
label?: string |
|
|
8
|
+
label?: string | ReactNode;
|
|
9
9
|
/**
|
|
10
10
|
* An element to display after the label
|
|
11
11
|
*/
|
|
12
|
-
suffix?:
|
|
12
|
+
suffix?: ReactNode;
|
|
13
13
|
/**
|
|
14
14
|
* An boolean flag to set checkbox to checked state
|
|
15
15
|
*/
|
|
@@ -50,4 +50,4 @@ export interface CheckboxProps extends CommonProps, MappedOmit<React.InputHTMLAt
|
|
|
50
50
|
* @param {CheckboxProps} props - The props for the Checkbox component
|
|
51
51
|
* @returns {JSX.Element} Checkbox component
|
|
52
52
|
*/
|
|
53
|
-
export declare const Checkbox:
|
|
53
|
+
export declare const Checkbox: import("react").ForwardRefExoticComponent<CheckboxProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -3,6 +3,5 @@ export declare const cvaCheckbox: (props?: ({
|
|
|
3
3
|
state?: "selected" | "deselected" | "indeterminate" | null | undefined;
|
|
4
4
|
disabled?: boolean | null | undefined;
|
|
5
5
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
6
|
-
export declare const cvaCheckboxContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
7
6
|
export declare const cvaCheckboxInput: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
8
7
|
export declare const cvaCheckboxIcon: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
@@ -6,10 +6,3 @@ export declare const cvaRadioItem: (props?: ({
|
|
|
6
6
|
invalid?: boolean | null | undefined;
|
|
7
7
|
disabled?: boolean | null | undefined;
|
|
8
8
|
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
9
|
-
export declare const cvaRadioItemWrapper: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
10
|
-
export declare const cvaRadioItemDescription: (props?: ({
|
|
11
|
-
disabled?: boolean | null | undefined;
|
|
12
|
-
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
13
|
-
export declare const cvaLabelTooltip: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
14
|
-
export declare const cvaDescriptionTooltip: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
15
|
-
export declare const cvaSuffixContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import { CommonProps } from "@trackunit/react-components";
|
|
2
|
+
import { MappedOmit, Size } from "@trackunit/shared-utils";
|
|
3
|
+
import { InputHTMLAttributes } from "react";
|
|
4
|
+
export interface ToggleSwitchProps extends CommonProps, MappedOmit<InputHTMLAttributes<HTMLInputElement>, "prefix" | "onChange" | "size" | "children"> {
|
|
5
|
+
/**
|
|
6
|
+
* custom onChange event handler.
|
|
7
|
+
*/
|
|
8
|
+
onChange?: (toggled: boolean, event?: React.ChangeEvent<HTMLInputElement>) => void;
|
|
9
|
+
/**
|
|
10
|
+
* onClick event handler.
|
|
11
|
+
*
|
|
12
|
+
* _**Do not**_ pass onClick handlers to trigger the toggle behavior. Use the onChange handler instead.
|
|
13
|
+
*/
|
|
14
|
+
onClick?: (e: React.MouseEvent<HTMLSpanElement>) => void;
|
|
15
|
+
/**
|
|
16
|
+
* Whether the ToggleSwitch is toggled(active) or not.
|
|
17
|
+
*/
|
|
18
|
+
toggled: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Size of the toggle.
|
|
21
|
+
*/
|
|
22
|
+
size?: Size;
|
|
23
|
+
/**
|
|
24
|
+
* Whether the track should have a focus outline.
|
|
25
|
+
*
|
|
26
|
+
* Set it to false when wrapped by a component that receives focus styles instead (for example in a filter/menu item)
|
|
27
|
+
*
|
|
28
|
+
* @default true
|
|
29
|
+
*/
|
|
30
|
+
showInputFocus?: boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Tab index for the track element
|
|
33
|
+
*
|
|
34
|
+
* @default 0
|
|
35
|
+
*/
|
|
36
|
+
tabIndex?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Prevents the native checkbox toggle behavior of the toggle switch.
|
|
39
|
+
*/
|
|
40
|
+
preventDefaultOnClick?: boolean;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* A checkbox input wrapper with role="switch". Used as an input element for **ToggleSwitchOption**
|
|
44
|
+
* or custom components.
|
|
45
|
+
*
|
|
46
|
+
* Not intended for standalone use.
|
|
47
|
+
*
|
|
48
|
+
* @param {ToggleSwitchProps} props - The props for the ToggleSwitch component
|
|
49
|
+
* @returns {ReactElement} ToggleSwitch component
|
|
50
|
+
*/
|
|
51
|
+
export declare const ToggleSwitch: import("react").ForwardRefExoticComponent<ToggleSwitchProps & import("react").RefAttributes<HTMLInputElement>>;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export declare const cvaToggleSwitchWrapper: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
2
|
+
export declare const cvaToggleSwitchInput: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
3
|
+
export declare const cvaToggleSwitchTrack: (props?: ({
|
|
4
|
+
size?: "small" | "medium" | "large" | null | undefined;
|
|
5
|
+
disabled?: boolean | null | undefined;
|
|
6
|
+
toggled?: boolean | null | undefined;
|
|
7
|
+
focused?: boolean | "auto" | null | undefined;
|
|
8
|
+
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
9
|
+
export declare const cvaToggleSwitchThumb: (props?: ({
|
|
10
|
+
toggled?: boolean | null | undefined;
|
|
11
|
+
size?: "small" | "medium" | "large" | null | undefined;
|
|
12
|
+
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ToggleSwitch";
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { ReactElement } from "react";
|
|
2
|
+
import { ToggleSwitchProps } from "../ToggleSwitch";
|
|
3
|
+
export interface ToggleSwitchOptionProps extends ToggleSwitchProps {
|
|
4
|
+
/**
|
|
5
|
+
* The label of the toggle.
|
|
6
|
+
*/
|
|
7
|
+
label: ReactElement | string;
|
|
8
|
+
/**
|
|
9
|
+
* The description of the toggle.
|
|
10
|
+
*/
|
|
11
|
+
description?: ReactElement | string;
|
|
12
|
+
/**
|
|
13
|
+
* An element to display after the label
|
|
14
|
+
*/
|
|
15
|
+
suffix?: ReactElement;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Use ToggleSwitchOption when you have to only enable/disable a feature.
|
|
19
|
+
* Wrapper component for ToggleSwitch.
|
|
20
|
+
*
|
|
21
|
+
* _**Do use** ToggleSwitchOption in forms or settings._
|
|
22
|
+
*
|
|
23
|
+
* _**Do not use** ToggleSwitchOption if a user can select multiple options from a list, use checkboxes instead of toggle._
|
|
24
|
+
*
|
|
25
|
+
* @param {ToggleSwitchOptionProps} props - The props for the ToggleSwitchOption component
|
|
26
|
+
* @returns {ReactElement} ToggleSwitchOption component
|
|
27
|
+
*/
|
|
28
|
+
export declare const ToggleSwitchOption: {
|
|
29
|
+
({ label, className, description, suffix, id, dataTestId, ...rest }: ToggleSwitchOptionProps): ReactElement;
|
|
30
|
+
displayName: string;
|
|
31
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./ToggleSwitchOption";
|
package/src/index.d.ts
CHANGED
|
@@ -10,7 +10,7 @@ export * from "./components/DropZone/DropZoneDefaultLabel";
|
|
|
10
10
|
export * from "./components/EmailField/EmailField";
|
|
11
11
|
export * from "./components/EmailInput";
|
|
12
12
|
export * from "./components/FormGroup/FormGroup";
|
|
13
|
-
export * from "./components/Label
|
|
13
|
+
export * from "./components/Label";
|
|
14
14
|
export * from "./components/NumberField/NumberField";
|
|
15
15
|
export * from "./components/NumberInput/NumberInput";
|
|
16
16
|
export * from "./components/OptionCard/OptionCard";
|
|
@@ -35,7 +35,8 @@ export * from "./components/TextField";
|
|
|
35
35
|
export * from "./components/TextInput/TextInput";
|
|
36
36
|
export * from "./components/TimeRange";
|
|
37
37
|
export * from "./components/TimeRangeField/TimeRangeField";
|
|
38
|
-
export * from "./components/
|
|
38
|
+
export * from "./components/ToggleSwitch";
|
|
39
|
+
export * from "./components/ToggleSwitchOption";
|
|
39
40
|
export * from "./components/UploadField/UploadField";
|
|
40
41
|
export * from "./components/UploadInput/UploadInput";
|
|
41
42
|
export * from "./components/UrlField/UrlField";
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared CVA for binary control items: Checkbox, RadioItem, ToggleSwitchOption
|
|
3
|
+
*/
|
|
4
|
+
export declare const cvaBinaryControlWrapper: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
5
|
+
export declare const cvaBinaryControlLabelTooltip: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
6
|
+
export declare const cvaBinaryControlDescriptionTooltip: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
7
|
+
export declare const cvaBinaryControlDescription: (props?: ({
|
|
8
|
+
disabled?: boolean | null | undefined;
|
|
9
|
+
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
10
|
+
export declare const cvaBinaryControlSuffixContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
@@ -1,60 +0,0 @@
|
|
|
1
|
-
import { CommonProps } from "@trackunit/react-components";
|
|
2
|
-
import { Size } from "@trackunit/shared-utils";
|
|
3
|
-
import * as React from "react";
|
|
4
|
-
export interface ToggleProps extends CommonProps {
|
|
5
|
-
/**
|
|
6
|
-
* id of the toggle.
|
|
7
|
-
*/
|
|
8
|
-
id: string;
|
|
9
|
-
/**
|
|
10
|
-
* Whether the toggle is toggled(active) or not.
|
|
11
|
-
*/
|
|
12
|
-
toggled: boolean;
|
|
13
|
-
/**
|
|
14
|
-
* onChange event handler.
|
|
15
|
-
*/
|
|
16
|
-
onChange: (toggled: boolean, event?: React.ChangeEvent<HTMLInputElement>) => void;
|
|
17
|
-
/**
|
|
18
|
-
* onClick event handler it is thrown on root element of the component tree.
|
|
19
|
-
*/
|
|
20
|
-
onClick?: React.MouseEventHandler<HTMLDivElement>;
|
|
21
|
-
/**
|
|
22
|
-
* Whether the toggle is disabled or not.
|
|
23
|
-
*/
|
|
24
|
-
disabled?: boolean;
|
|
25
|
-
/**
|
|
26
|
-
* Size of the toggle.
|
|
27
|
-
*/
|
|
28
|
-
size?: Size;
|
|
29
|
-
/**
|
|
30
|
-
* Tab index specifies the keyboard tab order of the toggle relative to the other controls on the page.
|
|
31
|
-
*/
|
|
32
|
-
tabIndex?: number;
|
|
33
|
-
/**
|
|
34
|
-
* Whether the toggle is required or not.
|
|
35
|
-
*/
|
|
36
|
-
required?: boolean;
|
|
37
|
-
/**
|
|
38
|
-
* Name of the toggle.
|
|
39
|
-
*/
|
|
40
|
-
name?: string;
|
|
41
|
-
/**
|
|
42
|
-
* The description of the toggle.
|
|
43
|
-
*/
|
|
44
|
-
description?: string;
|
|
45
|
-
/**
|
|
46
|
-
* onBlur event handler.
|
|
47
|
-
*/
|
|
48
|
-
onBlur?: React.FocusEventHandler<HTMLInputElement>;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Use Toggle when you have to only enable/disable a feature.
|
|
52
|
-
*
|
|
53
|
-
* _**Do use** Toggle in forms or settings._
|
|
54
|
-
*
|
|
55
|
-
* _**Do not use** Toggle if a user can select many option from a list, use checkboxes instead of toggle._
|
|
56
|
-
*
|
|
57
|
-
* @param {ToggleProps} props - The props for the Toggle component
|
|
58
|
-
* @returns {JSX.Element} Toggle component
|
|
59
|
-
*/
|
|
60
|
-
export declare const Toggle: React.ForwardRefExoticComponent<ToggleProps & React.RefAttributes<HTMLInputElement>>;
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
export declare const cvaToggleWrapper: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
2
|
-
export declare const cvaToggleInputContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
3
|
-
export declare const cvaToggleTrack: (props?: ({
|
|
4
|
-
size?: "small" | "medium" | "large" | null | undefined;
|
|
5
|
-
disabled?: boolean | null | undefined;
|
|
6
|
-
toggled?: boolean | null | undefined;
|
|
7
|
-
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
8
|
-
export declare const cvaToggleThumb: (props?: ({
|
|
9
|
-
toggled?: boolean | null | undefined;
|
|
10
|
-
size?: "small" | "medium" | "large" | null | undefined;
|
|
11
|
-
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
12
|
-
export declare const cvaToggleInput: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
13
|
-
export declare const cvaToggleLabelContainer: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
14
|
-
export declare const cvaToggleLabel: (props?: import("class-variance-authority/dist/types").ClassProp | undefined) => string;
|
|
15
|
-
export declare const cvaToggleDescription: (props?: ({
|
|
16
|
-
disabled?: boolean | null | undefined;
|
|
17
|
-
} & import("class-variance-authority/dist/types").ClassProp) | undefined) => string;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export * from "./Toggle";
|