Label Selector
Basic Example - Clothing Sizes
Select size
basic-example.tsx
const [size, setSize] = useState("M")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Label value="Select size" /> <LabelSelector.Content> <LabelSelector.Item value="XS" /> <LabelSelector.Item value="S" /> <LabelSelector.Item value="M" /> <LabelSelector.Item value="L" /> <LabelSelector.Item value="XL" /> </LabelSelector.Content></LabelSelector.Root>Without Label
without-label.tsx
const [size, setSize] = useState("L")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Content> <LabelSelector.Item value="XXS" /> <LabelSelector.Item value="XS" /> <LabelSelector.Item value="S" /> <LabelSelector.Item value="M" /> <LabelSelector.Item value="L" /> <LabelSelector.Item value="XL" /> <LabelSelector.Item value="XXL" /> </LabelSelector.Content></LabelSelector.Root>Variant: Outline
Size
variant-outline.tsx
const [size, setSize] = useState("M")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Label value="Size" /> <LabelSelector.Content> <LabelSelector.Item value="XS" variant="outline" /> <LabelSelector.Item value="S" variant="outline" /> <LabelSelector.Item value="M" variant="outline" /> <LabelSelector.Item value="L" variant="outline" /> <LabelSelector.Item value="XL" variant="outline" /> </LabelSelector.Content></LabelSelector.Root>Variant: Ghost
Size
variant-ghost.tsx
const [size, setSize] = useState("M")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Label value="Size" /> <LabelSelector.Content> <LabelSelector.Item value="XS" variant="ghost" /> <LabelSelector.Item value="S" variant="ghost" /> <LabelSelector.Item value="M" variant="ghost" /> <LabelSelector.Item value="L" variant="ghost" /> <LabelSelector.Item value="XL" variant="ghost" /> </LabelSelector.Content></LabelSelector.Root>Variant: Solid
Size
variant-solid.tsx
const [size, setSize] = useState("M")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Label value="Size" /> <LabelSelector.Content> <LabelSelector.Item value="XS" variant="solid" /> <LabelSelector.Item value="S" variant="solid" /> <LabelSelector.Item value="M" variant="solid" /> <LabelSelector.Item value="L" variant="solid" /> <LabelSelector.Item value="XL" variant="solid" /> </LabelSelector.Content></LabelSelector.Root>Size: Small
Size
size-small.tsx
const [size, setSize] = useState("M")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Label value="Size" /> <LabelSelector.Content> <LabelSelector.Item value="XS" size="sm" /> <LabelSelector.Item value="S" size="sm" /> <LabelSelector.Item value="M" size="sm" /> <LabelSelector.Item value="L" size="sm" /> <LabelSelector.Item value="XL" size="sm" /> </LabelSelector.Content></LabelSelector.Root>Size: Large
Size
size-large.tsx
const [size, setSize] = useState("M")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Label value="Size" /> <LabelSelector.Content> <LabelSelector.Item value="XS" size="lg" /> <LabelSelector.Item value="S" size="lg" /> <LabelSelector.Item value="M" size="lg" /> <LabelSelector.Item value="L" size="lg" /> <LabelSelector.Item value="XL" size="lg" /> </LabelSelector.Content></LabelSelector.Root>Rounded: Full
Size
rounded-full.tsx
const [size, setSize] = useState("M")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Label value="Size" /> <LabelSelector.Content> <LabelSelector.Item value="XS" rounded="full" /> <LabelSelector.Item value="S" rounded="full" /> <LabelSelector.Item value="M" rounded="full" /> <LabelSelector.Item value="L" rounded="full" /> <LabelSelector.Item value="XL" rounded="full" /> </LabelSelector.Content></LabelSelector.Root>Rounded: None
Size
rounded-none.tsx
const [size, setSize] = useState("M")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Label value="Size" /> <LabelSelector.Content> <LabelSelector.Item value="XS" rounded="none" /> <LabelSelector.Item value="S" rounded="none" /> <LabelSelector.Item value="M" rounded="none" /> <LabelSelector.Item value="L" rounded="none" /> <LabelSelector.Item value="XL" rounded="none" /> </LabelSelector.Content></LabelSelector.Root>Custom Gap Spacing
Size
custom-gap.tsx
const [size, setSize] = useState("M")<LabelSelector.Root value={size} onValueChange={setSize}> <LabelSelector.Label value="Size" /> <LabelSelector.Content className="gap-4"> <LabelSelector.Item value="XS" /> <LabelSelector.Item value="S" /> <LabelSelector.Item value="M" /> <LabelSelector.Item value="L" /> <LabelSelector.Item value="XL" /> </LabelSelector.Content></LabelSelector.Root>Custom Size - Larger Items
Plan
custom-size.tsx
const [variant, setVariant] = useState("pro")<LabelSelector.Root value={variant} onValueChange={setVariant}> <LabelSelector.Label value="Plan" /> <LabelSelector.Content className="gap-3"> <LabelSelector.Item value="basic" label="Basic" className="min-w-[5rem] h-12 text-base" /> <LabelSelector.Item value="pro" label="Pro" className="min-w-[5rem] h-12 text-base" /> <LabelSelector.Item value="enterprise" label="Enterprise" className="min-w-[5rem] h-12 text-base" /> </LabelSelector.Content></LabelSelector.Root>With Disabled Option
Select Size
disabled-option.tsx
<LabelSelector.Root defaultValue="M"> <LabelSelector.Label value="Select Size" /> <LabelSelector.Content> <LabelSelector.Item value="XS" /> <LabelSelector.Item value="S" /> <LabelSelector.Item value="M" /> <LabelSelector.Item value="L" disabled /> <LabelSelector.Item value="XL" /> </LabelSelector.Content></LabelSelector.Root>Long Labels
Billing
long-labels.tsx
const [plan, setPlan] = useState("monthly")<LabelSelector.Root value={plan} onValueChange={setPlan}> <LabelSelector.Label value="Billing" /> <LabelSelector.Content className="gap-2"> <LabelSelector.Item value="monthly" label="Monthly" className="min-w-[6rem]" /> <LabelSelector.Item value="quarterly" label="Quarterly" className="min-w-[6rem]" /> <LabelSelector.Item value="annually" label="Annually" className="min-w-[6rem]" /> </LabelSelector.Content></LabelSelector.Root>Numeric Values
EU Size
numeric-values.tsx
<LabelSelector.Root defaultValue="38"> <LabelSelector.Label value="EU Size" /> <LabelSelector.Content className="gap-2"> <LabelSelector.Item value="36" /> <LabelSelector.Item value="37" /> <LabelSelector.Item value="38" /> <LabelSelector.Item value="39" /> <LabelSelector.Item value="40" /> <LabelSelector.Item value="41" /> <LabelSelector.Item value="42" /> <LabelSelector.Item value="43" /> </LabelSelector.Content></LabelSelector.Root>Vertical Layout
Shirt Size
vertical-layout.tsx
<LabelSelector.Root defaultValue="M" className="flex-col items-start"> <LabelSelector.Label value="Shirt Size" /> <LabelSelector.Content className="gap-2"> <LabelSelector.Item value="XS" /> <LabelSelector.Item value="S" /> <LabelSelector.Item value="M" /> <LabelSelector.Item value="L" /> <LabelSelector.Item value="XL" /> </LabelSelector.Content></LabelSelector.Root>Features
- Built on Radix UI Radio Group primitives for accessibility
- Composable architecture with separate Root, Label, Content, and Item components
- Text label display with customizable values
- Multiple visual variants: default, outline, ghost, and solid
- Three size options: sm, default, and lg
- Configurable border radius: none, sm, md, lg, and full
- Visual selection state with border and background color changes
- Support for disabled states
- Flexible layout options (horizontal and vertical)
- Built with class-variance-authority for consistent variant handling
- Smooth transitions and hover effects
- Keyboard navigation and focus management
- Support for separate display labels and internal values
- Fully typed with TypeScript
Component Props
LabelSelector.Root
value- string - Currently selected valueonValueChange- (value: string) => void - Callback when value changesdefaultValue- string - Default selected value (uncontrolled)className- string - Override default container styles
LabelSelector.Label
value- string (required) - The label text to displayclassName- string
LabelSelector.Content
className- string - Useful for customizing gap spacingchildren- React.ReactNode - LabelSelector.Item components
LabelSelector.Item
value- string (required) - The internal value for this optionlabel- string - The display label (defaults to value if not provided)variant- "default" | "outline" | "ghost" | "solid" - Visual style variant (default: "default")size- "sm" | "default" | "lg" - Size of the item (default: "default")rounded- "none" | "sm" | "md" | "lg" | "full" - Border radius (default: "lg")disabled- boolean - Whether the item is disabledclassName- string - Additional custom styles
Use Cases
- Product size selection (clothing, shoes, accessories)
- Plan or tier selection
- Billing frequency options
- Variant selection (colors as text, materials, etc.)
- Quantity or amount selection
- Any scenario requiring labeled options in a compact format