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 { standardSchemaResolver } from "@hookform/resolvers/standard-schema"
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: standardSchemaResolver(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>
)
}
Color Palette
By default, the segment control doesn't support changing the design via the
colorPalette
prop. This example shows how to customize the segmented control
to make the colorPalette
prop work.
import { Center, For, SegmentGroup } from "@chakra-ui/react"
const Demo = () => {
return (
<Center minH="dvh">
<SegmentGroup.Root
bg="colorPalette.50"
colorPalette="orange"
defaultValue="Monthly"
>
<SegmentGroup.Indicator />
<For each={["Monthly", "Yearly"]}>
{(item) => (
<SegmentGroup.Item key={item} value={item}>
<SegmentGroup.ItemText
_checked={{ color: "colorPalette.fg", fontWeight: "medium" }}
>
{item}
</SegmentGroup.ItemText>
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
)}
</For>
</SegmentGroup.Root>
</Center>
)
}
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 |