Toggle Group
Groups related toggle buttons into a single selection control.
Preview
Example code
Playground
sizeSets item height and horizontal padding.
schemeApplies a semantic color to selected items.
disabledPrevents every item from being toggled.
Usage
tsx
import { ToggleGroup, ToggleGroupItem } from "earthling-ui/toggle-group";
export function Example() {
return (
<>
<ToggleGroup type="single" defaultValue="list" aria-label="View">
<ToggleGroupItem value="list">List</ToggleGroupItem>
<ToggleGroupItem value="grid">Grid</ToggleGroupItem>
</ToggleGroup>
</>
);
}
- Choose type single for one selection or multiple for independent selections.
- Give the group and icon-only items accessible labels.
- Keep choices short and mutually understandable at a glance.
Installation
Start with the project setup for React and Tailwind CSS 4. Both paths use the same component and theme.
Import package
Own the source
bash
npm install earthling-uiUse the component import shown above. Package updates keep the implementation current.
API reference
Declarations from the current library build, including inherited primitive props. Playground controls above show selected options; they are not the complete API.
tsx
// Generated by dts-bundle-generator v9.5.1
import * as ToggleGroupPrimitive from '@radix-ui/react-toggle-group';
import { VariantProps } from 'class-variance-authority';
import { ComponentPropsWithoutRef } from 'react';
export declare const ToggleGroup: import("react").ForwardRefExoticComponent<(ComponentPropsWithoutRef<import("react").ForwardRefExoticComponent<(ToggleGroupPrimitive.ToggleGroupSingleProps | ToggleGroupPrimitive.ToggleGroupMultipleProps) & import("react").RefAttributes<HTMLDivElement>>> & VariantProps<(props?: ({
material?: "paper" | null | undefined;
scheme?: "default" | "primary" | "secondary" | "tertiary" | "neutral" | "muted" | "good" | "caution" | "bad" | null | undefined;
size?: "sm" | "md" | "lg" | null | undefined;
} & import("class-variance-authority/types").ClassProp) | undefined) => string>) & import("react").RefAttributes<HTMLDivElement>>;
export declare const ToggleGroupItem: import("react").ForwardRefExoticComponent<Omit<ToggleGroupPrimitive.ToggleGroupItemProps & import("react").RefAttributes<HTMLButtonElement>, "ref"> & VariantProps<(props?: ({
material?: "paper" | null | undefined;
scheme?: "default" | "primary" | "secondary" | "tertiary" | "neutral" | "muted" | "good" | "caution" | "bad" | null | undefined;
size?: "sm" | "md" | "lg" | null | undefined;
} & import("class-variance-authority/types").ClassProp) | undefined) => string> & import("react").RefAttributes<HTMLButtonElement>>;
export {};Runtime dependencies: @radix-ui/react-toggle-group, class-variance-authority, cnfast.
Source
Use the eject command to copy this implementation with its required helpers and project-specific imports.
View Toggle Group implementation
tsx
"use client";
import {
createContext,
forwardRef,
useContext,
type ComponentPropsWithoutRef,
type ComponentRef,
} from "react";
import * as ToggleGroupPrimitive from "@radix-ui/react-toggle-group";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/utils/cn";
import { schemes } from "@/utils/variants";
const toggleGroupVariants = cva("flex items-center justify-center", {
variants: {
material: {
paper: "rounded-(--radius-control) bg-muted text-muted-foreground",
},
scheme: schemes,
size: { sm: "p-1", md: "p-1", lg: "p-1" },
},
defaultVariants: { material: "paper", size: "md", scheme: "primary" },
});
const ToggleGroupContext = createContext<
VariantProps<typeof toggleGroupVariants>
>({ size: "md", material: "paper", scheme: "primary" });
const ToggleGroup = forwardRef<
ComponentRef<typeof ToggleGroupPrimitive.Root>,
ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Root> &
VariantProps<typeof toggleGroupVariants>
>(
(
{
className,
material = "paper",
size = "md",
scheme = "primary",
children,
...props
},
ref,
) => (
<ToggleGroupPrimitive.Root
ref={ref}
className={cn(toggleGroupVariants({ material, size, scheme }), className)}
{...props}
>
<ToggleGroupContext.Provider value={{ material, scheme, size }}>
{children}
</ToggleGroupContext.Provider>
</ToggleGroupPrimitive.Root>
),
);
ToggleGroup.displayName = ToggleGroupPrimitive.Root.displayName;
const toggleGroupItemVariants = cva(
"inline-flex cursor-pointer items-center justify-center gap-1.5 text-sm font-medium ring-offset-background hover:bg-(--scheme-tint)/5 focus-visible:relative focus-visible:z-10 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-outline focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
{
variants: {
material: {
paper:
"data-[state=on]:bg-(--scheme-tint) data-[state=on]:text-(--scheme-foreground) data-[state=on]:shadow-xs rounded-[max(0px,calc(var(--radius-control)-0.25rem))]",
},
scheme: schemes,
size: {
sm: "h-7 px-2.5 min-w-9",
md: "h-8 px-3 min-w-10",
lg: "h-9 px-5 min-w-11",
},
},
defaultVariants: { material: "paper", size: "md" },
},
);
const ToggleGroupItem = forwardRef<
ComponentRef<typeof ToggleGroupPrimitive.Item>,
ComponentPropsWithoutRef<typeof ToggleGroupPrimitive.Item> &
VariantProps<typeof toggleGroupVariants>
>(({ className, children, material, scheme, size, ...props }, ref) => {
const context = useContext(ToggleGroupContext);
return (
<ToggleGroupPrimitive.Item
ref={ref}
className={cn(
toggleGroupItemVariants({
material: material ?? context.material,
scheme: scheme ?? context.scheme,
size: size ?? context.size,
}),
className,
)}
{...props}
>
{children}
</ToggleGroupPrimitive.Item>
);
});
ToggleGroupItem.displayName = ToggleGroupPrimitive.Item.displayName;
export { ToggleGroup, ToggleGroupItem };