Shadcn Toggle Group for React and Tailwind
Toggle buttons for selecting a value.
Installation
bunx --bun shadcn@latest add https://kit.dev/r/toggle-group.jsonpnpm dlx shadcn@latest add https://kit.dev/r/toggle-group.jsonnpx shadcn@latest add https://kit.dev/r/toggle-group.jsonyarn shadcn@latest add https://kit.dev/r/toggle-group.json<Step>This component depends on Toggle. Install them first if you haven't already.</Step>
Install the following dependencies:
bun add @ark-ui/react tailwind-variantspnpm add @ark-ui/react tailwind-variantsnpm install @ark-ui/react tailwind-variantsyarn add @ark-ui/react tailwind-variantsCopy and paste the following code into your project.
"use client";
import {
ToggleGroup as ArkToggleGroup,
useToggleGroupContext as useArkToggleGroupContext,
} from "@ark-ui/react/toggle-group";
import React from "react";
import { tv } from "tailwind-variants";
import { cn } from "@/lib/utils";
import { Toggle, type ToggleProps } from "@/components/ui/toggle";
export const useToggleGroup = useArkToggleGroupContext;
type ToggleGroupContextProps = Pick<ToggleProps, "variant" | "size"> & {
/**
* Gap between items.
*
* @default 0
*/
spacing?: number;
};
const ToggleGroupContext = React.createContext({} as ToggleGroupContextProps);
interface ToggleGroupProps
extends React.ComponentProps<typeof ArkToggleGroup.Root>,
ToggleGroupContextProps {}
const toggleGroupVariants = tv({
base: [
"w-fit",
"flex items-center gap-[--spacing(var(--gap))]",
"rounded-lg",
],
variants: {
orientation: {
horizontal: "flex-row pointer-coarse:*:after:min-w-auto",
vertical: "flex-col items-stretch pointer-coarse:*:after:min-h-auto",
},
},
defaultVariants: {
orientation: "horizontal",
},
});
export const ToggleGroup = (props: ToggleGroupProps) => {
const {
multiple = true,
orientation = "horizontal",
variant = "ghost",
size = "md",
spacing = 0,
className,
style,
...rest
} = props;
return (
<ToggleGroupContext.Provider value={{ variant, size, spacing }}>
<ArkToggleGroup.Root
className={cn(toggleGroupVariants({ orientation }), className)}
data-slot="toggle-group"
multiple={multiple}
orientation={orientation}
style={
{
...style,
"--gap": spacing,
} as React.CSSProperties
}
{...rest}
/>
</ToggleGroupContext.Provider>
);
};
interface ToggleGroupItemProps
extends React.ComponentProps<typeof ArkToggleGroup.Item> {}
export const ToggleGroupItem = (props: ToggleGroupItemProps) => {
const { value, className, ...rest } = props;
const { variant, size, spacing } = _useToggleGroup();
return (
<ArkToggleGroup.Item asChild data-slot="toggle-group-item" value={value}>
<Toggle
className={cn(
"shrink-0 focus:z-10 focus-visible:z-10",
"data-[spacing=0]:rounded-none",
"data-[spacing=0]:px-2",
"data-[orientation=horizontal]:data-[spacing=0]:first:rounded-l-lg",
"data-[orientation=vertical]:data-[spacing=0]:first:rounded-t-lg",
"data-[orientation=horizontal]:data-[spacing=0]:last:rounded-r-lg",
"data-[orientation=vertical]:data-[spacing=0]:last:rounded-b-lg",
"data-[orientation=horizontal]:data-[spacing=0]:data-[variant=outline]:border-l-0",
"data-[orientation=vertical]:data-[spacing=0]:data-[variant=outline]:border-t-0",
"data-[orientation=horizontal]:data-[spacing=0]:data-[variant=outline]:first:border-l",
className
)}
data-spacing={spacing}
data-variant={variant}
size={size}
variant={variant}
{...rest}
/>
</ArkToggleGroup.Item>
);
};
const _useToggleGroup = () => {
const context = React.useContext(ToggleGroupContext);
if (!context) {
throw new Error("useToggleGroupContext must be used within a ToggleGroup");
}
return context;
};Update the import paths to match your project setup.
Anatomy
ToggleGroup
└── ToggleGroupItemUsage
import {
ToggleGroup,
ToggleGroupItem
} from "@/components/ui/toggle-group"; <ToggleGroup>
<ToggleGroupItem value="1">Item 1</ToggleGroupItem>
<ToggleGroupItem value="2">Item 2</ToggleGroupItem>
</ToggleGroup>Controlled
Use the value and onValueChange props to control the toggle group state programmatically.
States
Disabled
Disable the entire group with the disabled prop.
With disabled toggle
Disable individual toggles by setting disabled on a specific item.
Orientation
Use orientation to change the orientation of the toggle group.
Horizontal
Vertical
Variant
Use variant to change the visual style of the toggle buttons.
Ghost
Outline
Examples
With spacing
Use spacing to add space between buttons.
Single selection
Use multiple={false} to allow only one toggle to be selected at a time.
Custom toggle group
A custom toggle group example with a custom styling for font weight selection.
API Reference
ToggleGroup
Root component. Provides shared variant and size to child toggles via context.
| Prop | Type | Default |
|---|---|---|
variant | "outline" | "ghost" | "ghost" |
size | "sm" | "md" | "lg" | "md" |
spacing | "0" | "1" | "2" | "3" | "4" | "5" | "6" | "8" | "10" | "0" |
multiple | boolean | true |
defaultValue | string[] | - |
value | string[] | - |
onValueChange | (details: ValueChangeDetails) => void | - |
orientation | "horizontal" | "vertical" | "horizontal" |
disabled | boolean | false |
className | string | - |
| Attribute | Default |
|---|---|
--gap | Set from the spacing prop (default 0) |
ToggleGroupItem
Single toggle in the group. Uses Toggle internally.
| Prop | Type | Default |
|---|---|---|
value | string | required |
disabled | boolean | false |
className | string | - |
aria-label | string | - |
For a complete list of props, see the Ark UI documentation.