Toggle Group
A group of toggle items where only one can be active at a time, perfect for selection controls like text alignment.
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
export function MyScreen() {
const [value, setValue] = React.useState("center");
return (
<ToggleGroup value={value} onValueChange={setValue}>
<ToggleGroupItem value="left">Left</ToggleGroupItem>
<ToggleGroupItem value="center">Center</ToggleGroupItem>
<ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>
);
}Installation
npx @aniui/cli add toggle-groupUsage
app/index.tsx
import { ToggleGroup, ToggleGroupItem } from "@/components/ui/toggle-group";
export function MyScreen() {
const [value, setValue] = React.useState("center");
return (
<ToggleGroup value={value} onValueChange={setValue}>
<ToggleGroupItem value="left">Left</ToggleGroupItem>
<ToggleGroupItem value="center">Center</ToggleGroupItem>
<ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>
);
}Examples
<ToggleGroup value={value} onValueChange={setValue}>
<ToggleGroupItem value="left">Left</ToggleGroupItem>
<ToggleGroupItem value="center">Center</ToggleGroupItem>
<ToggleGroupItem value="right">Right</ToggleGroupItem>
</ToggleGroup>Props
ToggleGroup
PropTypeDefault
valuestringrequiredonValueChange(value: string) => voidrequiredclassNamestring—Also accepts all View props from React Native.
ToggleGroupItem
PropTypeDefault
valuestringrequiredclassNamestring—childrenReactNoderequiredAlso accepts all Pressable props from React Native.
Source
components/ui/toggle-group.tsx
import React, { createContext, useContext } from "react";
import { View, Pressable, Text } from "react-native";
import { cva, type VariantProps } from "class-variance-authority";
import { cn } from "@/lib/utils";
const itemVariants = cva(
"items-center justify-center rounded-md min-h-12 min-w-12",
{
variants: {
variant: {
default: "bg-transparent",
outline: "border border-input bg-transparent",
},
size: {
sm: "px-2 py-1.5",
md: "px-3 py-2",
lg: "px-4 py-2.5",
},
},
defaultVariants: { variant: "default", size: "md" },
}
);
type GroupCtx = { value: string; onValueChange: (v: string) => void };
const Ctx = createContext<GroupCtx>({ value: "", onValueChange: () => {} });
export interface ToggleGroupProps
extends React.ComponentPropsWithoutRef<typeof View>,
VariantProps<typeof itemVariants> {
className?: string;
value: string;
onValueChange: (value: string) => void;
children: React.ReactNode;
}
export function ToggleGroup({ value, onValueChange, variant, size, className, children, ...props }: ToggleGroupProps) {
return (
<Ctx.Provider value={{ value, onValueChange }}>
<View className={cn("flex-row gap-1", className)} accessibilityRole="radiogroup" {...props}>
{children}
</View>
</Ctx.Provider>
);
}
export interface ToggleGroupItemProps extends React.ComponentPropsWithoutRef<typeof Pressable> {
className?: string;
value: string;
children: React.ReactNode;
}
export function ToggleGroupItem({ value, className, children, ...props }: ToggleGroupItemProps) {
const { value: selected, onValueChange } = useContext(Ctx);
const active = selected === value;
return (
<Pressable
className={cn(itemVariants({ variant: "default", size: "md" }), active && "bg-accent", className)}
onPress={() => onValueChange(value)}
accessibilityRole="radio"
accessibilityState={{ selected: active }}
accessible={true}
{...props}
>
{typeof children === "string" ? (
<Text className={cn("text-sm font-medium", active ? "text-accent-foreground" : "text-muted-foreground")}>
{children}
</Text>
) : children}
</Pressable>
);
}