@marcoschwartz/lite-ui 0.27.0 → 0.27.3
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/dist/index.js +21 -44
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +129 -152
- package/dist/index.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -3757,54 +3757,23 @@ var SegmentedControl = ({
|
|
|
3757
3757
|
}) => {
|
|
3758
3758
|
const groupId = (0, import_react20.useId)();
|
|
3759
3759
|
const groupName = name || `segmented-control-${groupId}`;
|
|
3760
|
-
const
|
|
3761
|
-
const [indicatorStyle, setIndicatorStyle] = (0, import_react20.useState)({});
|
|
3762
|
-
const options = normalizeData(data);
|
|
3760
|
+
const options = (0, import_react20.useMemo)(() => normalizeData(data), [data]);
|
|
3763
3761
|
const [internalValue, setInternalValue] = (0, import_react20.useState)(
|
|
3764
3762
|
defaultValue || options[0]?.value || ""
|
|
3765
3763
|
);
|
|
3766
3764
|
const isControlled = controlledValue !== void 0;
|
|
3767
3765
|
const currentValue = isControlled ? controlledValue : internalValue;
|
|
3766
|
+
const [hasInteracted, setHasInteracted] = (0, import_react20.useState)(false);
|
|
3767
|
+
const activeIndex = options.findIndex((opt) => opt.value === currentValue);
|
|
3768
3768
|
const handleChange = (0, import_react20.useCallback)((newValue) => {
|
|
3769
3769
|
if (disabled) return;
|
|
3770
|
+
setHasInteracted(true);
|
|
3770
3771
|
if (!isControlled) {
|
|
3771
3772
|
setInternalValue(newValue);
|
|
3772
3773
|
}
|
|
3773
3774
|
onChange?.(newValue);
|
|
3774
3775
|
}, [disabled, isControlled, onChange]);
|
|
3775
|
-
const
|
|
3776
|
-
if (!containerRef.current) return;
|
|
3777
|
-
const container = containerRef.current;
|
|
3778
|
-
const activeIndex = options.findIndex((opt) => opt.value === currentValue);
|
|
3779
|
-
if (activeIndex === -1) return;
|
|
3780
|
-
const buttons = container.querySelectorAll("[data-segment-button]");
|
|
3781
|
-
const activeButton = buttons[activeIndex];
|
|
3782
|
-
if (!activeButton) return;
|
|
3783
|
-
const containerRect = container.getBoundingClientRect();
|
|
3784
|
-
const buttonRect = activeButton.getBoundingClientRect();
|
|
3785
|
-
if (orientation === "horizontal") {
|
|
3786
|
-
setIndicatorStyle({
|
|
3787
|
-
width: buttonRect.width,
|
|
3788
|
-
height: "100%",
|
|
3789
|
-
transform: `translateX(${buttonRect.left - containerRect.left}px)`,
|
|
3790
|
-
transition: `transform ${transitionDuration}ms ease, width ${transitionDuration}ms ease`
|
|
3791
|
-
});
|
|
3792
|
-
} else {
|
|
3793
|
-
setIndicatorStyle({
|
|
3794
|
-
width: "100%",
|
|
3795
|
-
height: buttonRect.height,
|
|
3796
|
-
transform: `translateY(${buttonRect.top - containerRect.top}px)`,
|
|
3797
|
-
transition: `transform ${transitionDuration}ms ease, height ${transitionDuration}ms ease`
|
|
3798
|
-
});
|
|
3799
|
-
}
|
|
3800
|
-
}, [currentValue, options, orientation, transitionDuration]);
|
|
3801
|
-
(0, import_react20.useEffect)(() => {
|
|
3802
|
-
updateIndicator();
|
|
3803
|
-
const handleResize = () => updateIndicator();
|
|
3804
|
-
window.addEventListener("resize", handleResize);
|
|
3805
|
-
return () => window.removeEventListener("resize", handleResize);
|
|
3806
|
-
}, [updateIndicator]);
|
|
3807
|
-
const handleKeyDown = (0, import_react20.useCallback)((e, index) => {
|
|
3776
|
+
const handleKeyDown = (0, import_react20.useCallback)((e) => {
|
|
3808
3777
|
const enabledOptions = options.filter((opt) => !opt.disabled);
|
|
3809
3778
|
const currentEnabledIndex = enabledOptions.findIndex((opt) => opt.value === currentValue);
|
|
3810
3779
|
let nextIndex = -1;
|
|
@@ -3830,15 +3799,24 @@ var SegmentedControl = ({
|
|
|
3830
3799
|
e.preventDefault();
|
|
3831
3800
|
const nextOption = enabledOptions[nextIndex];
|
|
3832
3801
|
handleChange(nextOption.value);
|
|
3833
|
-
const buttons = containerRef.current?.querySelectorAll("[data-segment-button]");
|
|
3834
|
-
const nextButton = Array.from(buttons || []).find(
|
|
3835
|
-
(btn) => btn.getAttribute("data-value") === nextOption.value
|
|
3836
|
-
);
|
|
3837
|
-
nextButton?.focus();
|
|
3838
3802
|
}
|
|
3839
3803
|
}, [options, currentValue, orientation, handleChange]);
|
|
3840
3804
|
const sizeStyles2 = sizeConfig[size];
|
|
3841
3805
|
const radiusStyle = radiusConfig[radius];
|
|
3806
|
+
const totalOptions = options.length;
|
|
3807
|
+
const indicatorStyle = activeIndex >= 0 ? orientation === "horizontal" ? {
|
|
3808
|
+
width: `calc(${100 / totalOptions}% - ${totalOptions > 1 ? 0 : 0}px)`,
|
|
3809
|
+
height: "calc(100% - 8px)",
|
|
3810
|
+
left: `calc(${activeIndex / totalOptions * 100}% + 4px)`,
|
|
3811
|
+
top: "4px",
|
|
3812
|
+
transition: hasInteracted ? `left ${transitionDuration}ms ease, width ${transitionDuration}ms ease` : "none"
|
|
3813
|
+
} : {
|
|
3814
|
+
width: "calc(100% - 8px)",
|
|
3815
|
+
height: `calc(${100 / totalOptions}% - ${totalOptions > 1 ? 0 : 0}px)`,
|
|
3816
|
+
left: "4px",
|
|
3817
|
+
top: `calc(${activeIndex / totalOptions * 100}% + 4px)`,
|
|
3818
|
+
transition: hasInteracted ? `top ${transitionDuration}ms ease, height ${transitionDuration}ms ease` : "none"
|
|
3819
|
+
} : { display: "none" };
|
|
3842
3820
|
const containerClasses = [
|
|
3843
3821
|
"relative inline-flex p-1",
|
|
3844
3822
|
"bg-[hsl(var(--muted))]",
|
|
@@ -3851,7 +3829,6 @@ var SegmentedControl = ({
|
|
|
3851
3829
|
return /* @__PURE__ */ (0, import_jsx_runtime99.jsxs)(
|
|
3852
3830
|
"div",
|
|
3853
3831
|
{
|
|
3854
|
-
ref: containerRef,
|
|
3855
3832
|
role: "radiogroup",
|
|
3856
3833
|
"aria-label": ariaLabel || "Segmented control",
|
|
3857
3834
|
className: containerClasses,
|
|
@@ -3860,7 +3837,7 @@ var SegmentedControl = ({
|
|
|
3860
3837
|
"div",
|
|
3861
3838
|
{
|
|
3862
3839
|
className: [
|
|
3863
|
-
"absolute
|
|
3840
|
+
"absolute z-0",
|
|
3864
3841
|
radiusStyle,
|
|
3865
3842
|
colorConfig[color],
|
|
3866
3843
|
"shadow-sm"
|
|
@@ -3897,7 +3874,7 @@ var SegmentedControl = ({
|
|
|
3897
3874
|
tabIndex: isActive ? 0 : -1,
|
|
3898
3875
|
className: buttonClasses,
|
|
3899
3876
|
onClick: () => !isDisabled && handleChange(option.value),
|
|
3900
|
-
onKeyDown:
|
|
3877
|
+
onKeyDown: handleKeyDown,
|
|
3901
3878
|
children: [
|
|
3902
3879
|
option.label,
|
|
3903
3880
|
/* @__PURE__ */ (0, import_jsx_runtime99.jsx)(
|