Toggle Group
A group of toggle buttons that allows single or multiple selection from a set of options, commonly used for formatting toolbars like text alignment.
import { ToggleGroup, ToggleGroupItem } from "~/components/toggle-group";
export default function ToggleGroupBasicDemo() {
return (
<ToggleGroup defaultValue={["left"]}>
<ToggleGroupItem value="left" aria-label="Align Left">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="17" y1="10" x2="3" y2="10" />
<line x1="21" y1="6" x2="3" y2="6" />
<line x1="21" y1="14" x2="3" y2="14" />
<line x1="17" y1="18" x2="3" y2="18" />
</svg>
</ToggleGroupItem>
<ToggleGroupItem value="center" aria-label="Align Center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="18" y1="10" x2="6" y2="10" />
<line x1="21" y1="6" x2="3" y2="6" />
<line x1="21" y1="14" x2="3" y2="14" />
<line x1="18" y1="18" x2="6" y2="18" />
</svg>
</ToggleGroupItem>
<ToggleGroupItem value="right" aria-label="Align Right">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="21" y1="10" x2="7" y2="10" />
<line x1="21" y1="6" x2="3" y2="6" />
<line x1="21" y1="14" x2="3" y2="14" />
<line x1="21" y1="18" x2="7" y2="18" />
</svg>
</ToggleGroupItem>
</ToggleGroup>
);
}Installation
CLI
Run the following command to add the component to your project:
npx @ark-preset/cli@latest add toggle-groupManual
Create the recipe file at src/components/recipes/toggle-group.ts:
import { tv, type VariantProps } from "tailwind-variants";
export const toggleGroupVariants = tv({
slots: {
root: "inline-flex items-center gap-1 data-[orientation=vertical]:flex-col",
item: "inline-flex items-center justify-center gap-2 rounded-md text-sm font-medium border border-input bg-transparent text-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-1 transition duration-300 motion-safe:hover:-translate-y-0.5 motion-safe:active:translate-y-0.5 active:duration-150 data-[state=on]:bg-primary data-[state=on]:text-primary-foreground data-[state=on]:border-transparent data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
},
variants: {
size: {
sm: { item: "h-8 p-2" },
md: { item: "h-9 p-2.5" },
lg: { item: "h-10 p-3" },
},
},
defaultVariants: {
size: "sm",
},
});
export type ToggleGroupVariants = VariantProps<typeof toggleGroupVariants>;Create the component directory and files.
src/components/toggle-group/toggle-group.base.tsx:
import { ToggleGroup as ArkToggleGroup } from "@ark-ui/solid/toggle-group";
import { splitProps, type Component } from "solid-js";
import { toggleGroupVariants, type ToggleGroupVariants } from "../recipes/toggle-group";
const styles = toggleGroupVariants();
const Root: Component<ArkToggleGroup.RootProps> = (props) => {
const [local, others] = splitProps(props, ["class"]);
return <ArkToggleGroup.Root class={styles.root({ class: local.class })} {...others} />;
};
const RootProvider: Component<ArkToggleGroup.RootProviderProps> = (props) => {
const [local, others] = splitProps(props, ["class"]);
return <ArkToggleGroup.RootProvider class={styles.root({ class: local.class })} {...others} />;
};
const Item: Component<ArkToggleGroup.ItemProps & ToggleGroupVariants> = (props) => {
const [local, others] = splitProps(props, ["class", "size"]);
return (
<ArkToggleGroup.Item
class={styles.item({ class: local.class, size: local.size })}
{...others}
/>
);
};
export const ToggleGroup = { Root, RootProvider, Item };src/components/toggle-group/index.tsx:
import { ToggleGroup as ToggleGroupBase } from "./toggle-group.base";
const ToggleGroup = ToggleGroupBase.Root;
const ToggleGroupItem = ToggleGroupBase.Item;
export { ToggleGroup, ToggleGroupItem, ToggleGroupBase };
export { toggleGroupVariants, type ToggleGroupVariants } from "../recipes/toggle-group";Note: Make sure your project has the Tailwind CSS theme variables set up (
--background,--foreground,--ring,--border, etc.) or override the utility classes to match your design system.
Usage
Basic Usage
import { ToggleGroup, ToggleGroupItem } from "~/components/toggle-group";
export default function ToggleGroupBasicDemo() {
return (
<ToggleGroup defaultValue={["left"]}>
<ToggleGroupItem value="left" aria-label="Align Left">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="17" y1="10" x2="3" y2="10" />
<line x1="21" y1="6" x2="3" y2="6" />
<line x1="21" y1="14" x2="3" y2="14" />
<line x1="17" y1="18" x2="3" y2="18" />
</svg>
</ToggleGroupItem>
<ToggleGroupItem value="center" aria-label="Align Center">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="18" y1="10" x2="6" y2="10" />
<line x1="21" y1="6" x2="3" y2="6" />
<line x1="21" y1="14" x2="3" y2="14" />
<line x1="18" y1="18" x2="6" y2="18" />
</svg>
</ToggleGroupItem>
<ToggleGroupItem value="right" aria-label="Align Right">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="21" y1="10" x2="7" y2="10" />
<line x1="21" y1="6" x2="3" y2="6" />
<line x1="21" y1="14" x2="3" y2="14" />
<line x1="21" y1="18" x2="7" y2="18" />
</svg>
</ToggleGroupItem>
</ToggleGroup>
);
}Multiple Selection
Use the multiple prop to allow selecting multiple items.
import { ToggleGroup, ToggleGroupItem } from "~/components/toggle-group";
export default function ToggleGroupMultipleDemo() {
return (
<ToggleGroup defaultValue={["bold"]} multiple>
<ToggleGroupItem value="bold" aria-label="Toggle bold">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M6 4h8a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z" />
<path d="M6 12h9a4 4 0 0 1 4 4 4 4 0 0 1-4 4H6z" />
</svg>
</ToggleGroupItem>
<ToggleGroupItem value="italic" aria-label="Toggle italic">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<line x1="19" y1="4" x2="10" y2="4" />
<line x1="14" y1="20" x2="5" y2="20" />
<line x1="15" y1="4" x2="9" y2="20" />
</svg>
</ToggleGroupItem>
<ToggleGroupItem value="underline" aria-label="Toggle underline">
<svg
xmlns="http://www.w3.org/2000/svg"
width="18"
height="18"
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
>
<path d="M6 3v7a6 6 0 0 0 6 6 6 6 0 0 0 6-6V3" />
<line x1="4" y1="21" x2="20" y2="21" />
</svg>
</ToggleGroupItem>
</ToggleGroup>
);
}Sizes
Use the size prop to change the toggle group item size.
import { ToggleGroup, ToggleGroupItem } from "~/components/toggle-group";
export default function ToggleGroupSizesDemo() {
return (
<div class="flex flex-col gap-6">
<ToggleGroup defaultValue={["sm"]}>
<ToggleGroupItem size="sm" value="sm">
Sm
</ToggleGroupItem>
<ToggleGroupItem size="sm" value="md">
Sm
</ToggleGroupItem>
<ToggleGroupItem size="sm" value="lg">
Sm
</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup defaultValue={["md"]}>
<ToggleGroupItem size="md" value="sm">
Md
</ToggleGroupItem>
<ToggleGroupItem size="md" value="md">
Md
</ToggleGroupItem>
<ToggleGroupItem size="md" value="lg">
Md
</ToggleGroupItem>
</ToggleGroup>
<ToggleGroup defaultValue={["lg"]}>
<ToggleGroupItem size="lg" value="sm">
Lg
</ToggleGroupItem>
<ToggleGroupItem size="lg" value="md">
Lg
</ToggleGroupItem>
<ToggleGroupItem size="lg" value="lg">
Lg
</ToggleGroupItem>
</ToggleGroup>
</div>
);
}Advanced Usage
Root Provider
Use ToggleGroupBase.RootProvider when you need to control the toggle group state externally.
Selected: left
import { Index, createMemo } from "solid-js";
import { ToggleGroupBase, ToggleGroupItem } from "~/components/toggle-group";
import { useToggleGroup } from "@ark-ui/solid/toggle-group";
const alignments = [
{ value: "left", label: "Left" },
{ value: "center", label: "Center" },
{ value: "right", label: "Right" },
];
export default function ToggleGroupRootProviderDemo() {
const toggleGroup = useToggleGroup({ defaultValue: ["left"] });
const value = createMemo(() => toggleGroup().value);
return (
<div>
<p class="text-sm text-muted-foreground">Selected: {value().join(", ")}</p>
<ToggleGroupBase.RootProvider value={toggleGroup}>
<Index each={alignments}>
{(alignment) => (
<ToggleGroupItem value={alignment().value}>{alignment().label}</ToggleGroupItem>
)}
</Index>
</ToggleGroupBase.RootProvider>
</div>
);
}import { useToggleGroup } from "@ark-ui/solid/toggle-group";
import { ToggleGroupBase, ToggleGroupItem } from "~/components/toggle-group";
const tg = useToggleGroup({ defaultValue: ["left"] });
<ToggleGroupBase.RootProvider value={tg}>
<ToggleGroupItem value="left"><AlignLeftIcon /></ToggleGroupItem>
<ToggleGroupItem value="center"><AlignCenterIcon /></ToggleGroupItem>
<ToggleGroupItem value="right"><AlignRightIcon /></ToggleGroupItem>
</ToggleGroupBase.RootProvider>API Reference
See the Ark UI Toggle Group documentation.