Segmented Control
Used to pick one choice from a linear set of options
import { SegmentGroup } from "@chakra-ui/react" const Demo = () => { return ( <SegmentGroup.Root defaultValue="React"> <SegmentGroup.Indicator /> <SegmentGroup.Items items={["React", "Vue", "Solid"]} /> </SegmentGroup.Root> ) }
Usage
import { SegmentGroup } from "@chakra-ui/react"
<SegmentGroup.Root> <SegmentGroup.Indicator /> <SegmentGroup.Item> <SegmentGroup.ItemText /> <SegmentGroup.ItemHiddenInput /> </SegmentGroup.Item> </SegmentGroup.Root>
Shortcuts
The SegmentGroup
component also provides a set of shortcuts for common use cases.
SegmentGroupItems
The SegmentGroupItems
shortcut renders a list of items based on the items
prop.
This works:
<> {items.map((item) => ( <SegmentGroup.Item key={item.value} value={item.value}> <SegmentGroup.ItemText>{item.label}</SegmentGroup.ItemText> <SegmentGroup.ItemHiddenInput /> </SegmentGroup.Item> ))} </>
This might be more concise, if you don't need to customize the items:
<SegmentGroup.Items items={items} />
Examples
Sizes
Use the size
prop to change the size of the segmented control.
size = xs
size = sm
size = md
size = lg
import { For, SegmentGroup, Stack, Text, VStack } from "@chakra-ui/react" const Demo = () => { return ( <Stack gap="5" align="flex-start"> <For each={["xs", "sm", "md", "lg"]}> {(size) => ( <VStack key={size} align="flex-start"> <SegmentGroup.Root size={size} defaultValue="React"> <SegmentGroup.Indicator /> <SegmentGroup.Items items={["React", "Vue", "Solid"]} /> </SegmentGroup.Root> <Text>size = {size}</Text> </VStack> )} </For> </Stack> ) }
Controlled
Use the value
and onValueChange
props to control the selected item.
"use client" import { SegmentGroup } from "@chakra-ui/react" import { useState } from "react" const Demo = () => { const [value, setValue] = useState<string | null>("React") return ( <SegmentGroup.Root value={value} onValueChange={(e) => setValue(e.value)}> <SegmentGroup.Indicator /> <SegmentGroup.Items items={["React", "Vue", "Solid"]} /> </SegmentGroup.Root> ) }
Hook Form
Here's an example of how to use the SegmentedControl
with react-hook-form
.
"use client" import { Button, Field, SegmentGroup, Stack } from "@chakra-ui/react" import { zodResolver } from "@hookform/resolvers/zod" import { Controller, useForm } from "react-hook-form" import { z } from "zod" const formSchema = z.object({ fontSize: z.string({ message: "Font size is required" }), }) type FormValues = z.infer<typeof formSchema> const Demo = () => { const { handleSubmit, formState: { errors }, control, } = useForm<FormValues>({ defaultValues: { fontSize: "md" }, resolver: zodResolver(formSchema), }) const onSubmit = handleSubmit((data) => console.log(data)) return ( <form onSubmit={onSubmit}> <Stack gap="4" align="flex-start"> <Controller control={control} name="fontSize" render={({ field }) => ( <Field.Root invalid={!!errors.fontSize}> <Field.Label>Font size</Field.Label> <SegmentGroup.Root size="sm" onBlur={field.onBlur} name={field.name} value={field.value} onValueChange={({ value }) => field.onChange(value)} > <SegmentGroup.Items items={["sm", "md", "lg"]} /> <SegmentGroup.Indicator /> </SegmentGroup.Root> <Field.ErrorText>{errors.fontSize?.message}</Field.ErrorText> </Field.Root> )} /> <Button size="sm" type="submit"> Submit </Button> </Stack> </form> ) }
Vertical
By default, the segmented control is horizontal. Set the orientation
prop to vertical
to change the orientation of the segmented control.
import { SegmentGroup } from "@chakra-ui/react" const Demo = () => { return ( <SegmentGroup.Root defaultValue="React" orientation="vertical"> <SegmentGroup.Indicator /> <SegmentGroup.Items items={["React", "Vue", "Solid"]} /> </SegmentGroup.Root> ) }
Disabled
Use the disabled
prop to disable the segmented control.
import { SegmentGroup } from "@chakra-ui/react" const Demo = () => { return ( <SegmentGroup.Root disabled defaultValue="React"> <SegmentGroup.Indicator /> <SegmentGroup.Items items={["React", "Vue", "Solid"]} /> </SegmentGroup.Root> ) }
Disabled Item
Use the disabled
prop on the item to disable it.
import { SegmentGroup } from "@chakra-ui/react" const Demo = () => { return ( <SegmentGroup.Root defaultValue="React"> <SegmentGroup.Indicator /> <SegmentGroup.Items items={[ { label: "React", value: "React" }, { label: "Vue", value: "Vue", disabled: true }, { label: "Solid", value: "Solid" }, ]} /> </SegmentGroup.Root> ) }
Icon
Render the label
as a ReactNode
to render an icon.
import { HStack, SegmentGroup } from "@chakra-ui/react" import { LuGrid2X2, LuList, LuTable } from "react-icons/lu" const Demo = () => { return ( <SegmentGroup.Root defaultValue="table"> <SegmentGroup.Indicator /> <SegmentGroup.Items items={[ { value: "table", label: ( <HStack> <LuTable /> Table </HStack> ), }, { value: "board", label: ( <HStack> <LuGrid2X2 /> Board </HStack> ), }, { value: "list", label: ( <HStack> <LuList /> List </HStack> ), }, ]} /> </SegmentGroup.Root> ) }
Card
Here's an example of how to use the SegmentedControl
within a Card
.
Find your dream home
import { Button, Card, Field, Heading, SegmentGroup } from "@chakra-ui/react" import { LuSearch } from "react-icons/lu" const Demo = () => { return ( <Card.Root width="320px"> <Card.Header> <Heading size="lg">Find your dream home</Heading> </Card.Header> <Card.Body gap="6"> <Field.Root> <Field.Label>Bedrooms</Field.Label> <SegmentGroup.Root defaultValue="Any"> <SegmentGroup.Indicator /> <SegmentGroup.Items items={["Any", "1", "2", "3", "3+"]} /> </SegmentGroup.Root> </Field.Root> <Field.Root> <Field.Label>Beds</Field.Label> <SegmentGroup.Root defaultValue="1"> <SegmentGroup.Indicator /> <SegmentGroup.Items items={["Any", "1", "2", "2+"]} /> </SegmentGroup.Root> </Field.Root> <Field.Root> <Field.Label>Bathrooms</Field.Label> <SegmentGroup.Root defaultValue="3"> <SegmentGroup.Indicator /> <SegmentGroup.Items items={["Any", "1", "2", "3"]} /> </SegmentGroup.Root> </Field.Root> </Card.Body> <Card.Footer justifyContent="space-between" mt="3"> <Button variant="surface">Reset</Button> <Button> <LuSearch /> 20 results </Button> </Card.Footer> </Card.Root> ) }
Props
Root
Prop | Default | Type |
---|---|---|
colorPalette | 'gray' | 'gray' | 'red' | 'orange' | 'yellow' | 'green' | 'teal' | 'blue' | 'cyan' | 'purple' | 'pink' The color palette of the component |
size | 'md' | 'xs' | 'sm' | 'md' | 'lg' The size of the component |
as | React.ElementType The underlying element to render. | |
asChild | boolean Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
unstyled | boolean Whether to remove the component's style. | |
defaultValue | string The initial value of the checked radio when rendered. Use when you don't need to control the value of the radio group. | |
disabled | boolean If `true`, the radio group will be disabled | |
form | string The associate form of the underlying input. | |
id | string The unique identifier of the machine. | |
ids | Partial<{ root: string label: string indicator: string item: (value: string) => string itemLabel: (value: string) => string itemControl: (value: string) => string itemHiddenInput: (value: string) => string }> The ids of the elements in the radio. Useful for composition. | |
name | string The name of the input fields in the radio (Useful for form submission). | |
onValueChange | (details: ValueChangeDetails) => void Function called once a radio is checked | |
orientation | 'horizontal' | 'vertical' Orientation of the radio group | |
readOnly | boolean Whether the checkbox is read-only | |
value | string The controlled value of the radio group |