I'm using the Toggle component from Shadcn in my React project to implement a set of stroke toggles. The goal is to have four toggles where only one can be active (pressed) at a time. When a toggle is pressed, it should update the state and reflect the change visually.
Here is my current implementation:
type StrokeToggleType = "stroke-none" | "stroke-solid" | "stroke-dash-1" | "stroke-dash-2";
...
const [strokeToggle, setStrokeToggle] = useState<StrokeToggleType>("stroke-none")
const handleToggleChange = (type: StrokeToggleType) => {
setStrokeToggle(type)
}
...
return (
<div className='flex justify-between'>
<Toggle
aria-label="stroke-none"
pressed={strokeToggle === "stroke-none"}
onPressedChange={() => handleToggleChange("stroke-none")}
>
<AiOutlineStop className='w-[56px] h-[40px]' />
</Toggle>
<Toggle
aria-label="stroke-solid"
pressed={strokeToggle === "stroke-solid"}
onPressedChange={() => handleToggleChange("stroke-solid")}
>
<GoDash className='w-[56px] h-[40px]' />
</Toggle>
<Toggle
aria-label="stroke-dash-1"
pressed={strokeToggle === "stroke-dash-1"}
onPressedChange={() => handleToggleChange("stroke-dash-1")}
>
<CgBorderStyleDashed className='w-[56px] h-[40px]' />
</Toggle>
<Toggle
aria-label="stroke-dash-2"
pressed={strokeToggle === "stroke-dash-2"}
onPressedChange={() => handleToggleChange("stroke-dash-2")}
>
<AiOutlineSmallDash className='w-[56px] h-[40px]' />
</Toggle>
</div>
);
};
The problem is that when I click on a toggle other than "stroke-none", the state doesn't seem to update correctly. The pressed state doesn't transfer to the other toggles.
I added console.log for debugging:
useEffect(() => {
console.log("Current stroke type:", strokeToggle);
}, [strokeToggle]);
The log printed is always "stroke-none" first then followed by the toggle being pressed. What did I do wrong here? Any help or suggestions would be greatly appreciated!
You should be using ToggleGroup
instead of individual Toggle
s if the goal is to manage single value. In your case it should look like this:
<ToggleGroup
type="single"
value={strokeToggle}
onValueChange={setStrokeToggle}
className="gap-2"
>
<ToggleGroupItem value="stroke-none" aria-label="stroke-none">
<AiOutlineStop className="w-[56px] h-[40px]" />
</ToggleGroupItem>
<ToggleGroupItem value="stroke-solid" aria-label="stroke-solid">
<GoDash className="w-[56px] h-[40px]" />
</ToggleGroupItem>
<ToggleGroupItem value="stroke-dash-1" aria-label="stroke-dash-1">
<CgBorderStyleDashed className="w-[56px] h-[40px]" />
</ToggleGroupItem>
<ToggleGroupItem value="stroke-dash-2" aria-label="stroke-dash-2">
<AiOutlineSmallDash className="w-[56px] h-[40px]" />
</ToggleGroupItem>
</ToggleGroup>
Also as of March of 2015, with latest dependencies and icons within the Toggle
replaced with text, this is no longer reproducible. I'm guessing this used to be bug within Shadcn-ui