Segment Group
Organizes and navigates between sections in a view.
Anatomy
To set up the segmented control correctly, you'll need to understand its anatomy and how we name its parts.
Each part includes a
data-part
attribute to help identify them in the DOM.
Examples
Learn how to use the SegmentGroup
component in your project. Let's take a look at the most basic
example:
import { SegmentGroup } from '@ark-ui/react/segment-group'
export const Basic = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
return (
<SegmentGroup.Root>
<SegmentGroup.Indicator />
{frameworks.map((framework) => (
<SegmentGroup.Item key={framework} value={framework}>
<SegmentGroup.ItemText>{framework}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
))}
</SegmentGroup.Root>
)
}
import { SegmentGroup } from '@ark-ui/solid/segment-group'
import { Index } from 'solid-js'
export const Basic = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
return (
<SegmentGroup.Root>
<SegmentGroup.Indicator />
<Index each={frameworks}>
{(framework) => (
<SegmentGroup.Item value={framework()}>
<SegmentGroup.ItemText>{framework()}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
)}
</Index>
</SegmentGroup.Root>
)
}
<script setup lang="ts">
import { SegmentGroup } from '@ark-ui/vue/segment-group'
import { ref } from 'vue'
const frameworks = ref(['React', 'Solid', 'Svelte', 'Vue'])
</script>
<template>
<SegmentGroup.Root>
<SegmentGroup.Indicator />
<SegmentGroup.Item v-for="framework in frameworks" :key="framework" :value="framework">
<SegmentGroup.ItemText>{{ framework }}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
</SegmentGroup.Root>
</template>
Initial Value
To set a default segment on initial render, use the defaultValue
prop:
import { SegmentGroup } from '@ark-ui/react/segment-group'
export const InitialValue = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
return (
<SegmentGroup.Root defaultValue="React">
<SegmentGroup.Indicator />
{frameworks.map((framework) => (
<SegmentGroup.Item key={framework} value={framework}>
<SegmentGroup.ItemText>{framework}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
))}
</SegmentGroup.Root>
)
}
import { SegmentGroup } from '@ark-ui/solid/segment-group'
import { Index } from 'solid-js'
export const InitialValue = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
return (
<SegmentGroup.Root value="React">
<SegmentGroup.Indicator />
<Index each={frameworks}>
{(framework) => (
<SegmentGroup.Item value={framework()}>
<SegmentGroup.ItemText>{framework()}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
)}
</Index>
</SegmentGroup.Root>
)
}
<script setup lang="ts">
import { SegmentGroup } from '@ark-ui/vue/segment-group'
import { ref } from 'vue'
const frameworks = ref(['React', 'Solid', 'Svelte', 'Vue'])
</script>
<template>
<SegmentGroup.Root model-value="React">
<SegmentGroup.Indicator />
<SegmentGroup.Item v-for="framework in frameworks" :key="framework" :value="framework">
<SegmentGroup.ItemText>{{ framework }}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
</SegmentGroup.Root>
</template>
Controlled Segment Group
To create a controlled SegmentGroup component, manage the current selected segment using the value
prop and update it when the onValueChange
event handler is called:
import { SegmentGroup } from '@ark-ui/react/segment-group'
import { useState } from 'react'
export const Controlled = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
const [value, setValue] = useState('React')
return (
<SegmentGroup.Root value={value} onValueChange={(e) => setValue(e.value)}>
<SegmentGroup.Indicator />
{frameworks.map((framework) => (
<SegmentGroup.Item key={framework} value={framework}>
<SegmentGroup.ItemText>{framework}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
))}
</SegmentGroup.Root>
)
}
import { SegmentGroup } from '@ark-ui/solid/segment-group'
import { Index, createSignal } from 'solid-js'
export const Controlled = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
const [value, setValue] = createSignal('React')
return (
<SegmentGroup.Root value={value()} onValueChange={(e) => setValue(e.value)}>
<SegmentGroup.Indicator />
<Index each={frameworks}>
{(framework) => (
<SegmentGroup.Item value={framework()}>
<SegmentGroup.ItemText>{framework()}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
)}
</Index>
</SegmentGroup.Root>
)
}
<script setup lang="ts">
import { SegmentGroup } from '@ark-ui/vue/segment-group'
import { ref } from 'vue'
const frameworks = ref(['React', 'Solid', 'Svelte', 'Vue'])
const value = ref('React')
</script>
<template>
<SegmentGroup.Root v-model="value">
<SegmentGroup.Indicator />
<SegmentGroup.Item v-for="framework in frameworks" :key="framework" :value="framework">
<SegmentGroup.ItemText>{{ framework }}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
</SegmentGroup.Root>
</template>
Disabled Segment
To disable a segment, simply pass the disabled
prop to the SegmentGroup.Item
component:
import { SegmentGroup } from '@ark-ui/react/segment-group'
export const Disabled = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
return (
<SegmentGroup.Root defaultValue="React">
<SegmentGroup.Indicator />
{frameworks.map((framework) => (
<SegmentGroup.Item key={framework} value={framework} disabled={framework === 'Svelte'}>
<SegmentGroup.ItemText>{framework}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
))}
</SegmentGroup.Root>
)
}
import { SegmentGroup } from '@ark-ui/solid/segment-group'
import { Index } from 'solid-js'
export const Disabled = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
return (
<SegmentGroup.Root value={'React'}>
<SegmentGroup.Indicator />
<Index each={frameworks}>
{(framework) => (
<SegmentGroup.Item value={framework()} disabled={framework() === 'Svelte'}>
<SegmentGroup.ItemText>{framework()}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
)}
</Index>
</SegmentGroup.Root>
)
}
<script setup lang="ts">
import { SegmentGroup } from '@ark-ui/vue/segment-group'
import { ref } from 'vue'
const frameworks = ref(['React', 'Solid', 'Svelte', 'Vue'])
</script>
<template>
<SegmentGroup.Root model-value="React">
<SegmentGroup.Indicator />
<SegmentGroup.Item
v-for="framework in frameworks"
:key="framework"
:value="framework"
:disabled="framework === 'Svelte'"
>
<SegmentGroup.ItemText>{{ framework }}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
</SegmentGroup.Root>
</template>
Using the Root Provider
The RootProvider
component provides a context for the radio-group. It accepts the value of the useRadio-group
hook.
You can leverage it to access the component state and methods from outside the radio-group.
import { SegmentGroup, useSegmentGroup } from '@ark-ui/react/segment-group'
export const RootProvider = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
const segmentGroup = useSegmentGroup()
return (
<>
<button onClick={() => segmentGroup.focus()}>Focus</button>
<SegmentGroup.RootProvider value={segmentGroup}>
<SegmentGroup.Indicator />
{frameworks.map((framework) => (
<SegmentGroup.Item key={framework} value={framework}>
<SegmentGroup.ItemText>{framework}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
))}
</SegmentGroup.RootProvider>
</>
)
}
import { SegmentGroup, useSegmentGroup } from '@ark-ui/solid/segment-group'
import { Index } from 'solid-js'
export const RootProvider = () => {
const frameworks = ['React', 'Solid', 'Svelte', 'Vue']
const segmentGroup = useSegmentGroup()
return (
<>
<button onClick={() => segmentGroup().focus()}>Focus</button>
<SegmentGroup.RootProvider value={segmentGroup}>
<SegmentGroup.Indicator />
<Index each={frameworks}>
{(framework) => (
<SegmentGroup.Item value={framework()}>
<SegmentGroup.ItemText>{framework()}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
)}
</Index>
</SegmentGroup.RootProvider>
</>
)
}
<script setup lang="ts">
import { SegmentGroup, useSegmentGroup } from '@ark-ui/vue/segment-group'
import { ref } from 'vue'
const frameworks = ref(['React', 'Solid', 'Svelte', 'Vue'])
const segmentGroup = useSegmentGroup()
</script>
<template>
<button @click="segmentGroup.focus()">Focus</button>
<SegmentGroup.RootProvider :value="segmentGroup">
<SegmentGroup.Indicator />
<SegmentGroup.Item v-for="framework in frameworks" :key="framework" :value="framework">
<SegmentGroup.ItemText>{{ framework }}</SegmentGroup.ItemText>
<SegmentGroup.ItemControl />
<SegmentGroup.ItemHiddenInput />
</SegmentGroup.Item>
</SegmentGroup.RootProvider>
</template>
If you're using the
RootProvider
component, you don't need to use theRoot
component.
API Reference
Root
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
defaultValue | string The initial value of the radio group when it is first rendered. Use when you do not need to control the state of the radio group. | |
disabled | boolean If `true`, the radio group will be disabled | |
form | string The associate form of the underlying input. | |
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 value of the checked radio |
Data Attribute | Value |
---|---|
[data-scope] | radio-group |
[data-part] | root |
[data-orientation] | The orientation of the radio-group |
[data-disabled] | Present when disabled |
Indicator
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Data Attribute | Value |
---|---|
[data-scope] | radio-group |
[data-part] | indicator |
[data-disabled] | Present when disabled |
[data-orientation] | The orientation of the indicator |
ItemControl
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Data Attribute | Value |
---|---|
[data-scope] | radio-group |
[data-part] | item-control |
[data-active] | Present when active or pressed |
ItemHiddenInput
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'input'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Item
Prop | Default | Type |
---|---|---|
value | string | |
asChild | (props: ParentProps<'label'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. | |
disabled | boolean | |
invalid | boolean |
ItemText
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'span'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Label
Prop | Default | Type |
---|---|---|
asChild | (props: ParentProps<'label'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Data Attribute | Value |
---|---|
[data-scope] | radio-group |
[data-part] | label |
[data-orientation] | The orientation of the label |
[data-disabled] | Present when disabled |
RootProvider
Prop | Default | Type |
---|---|---|
value | UseRadioGroupReturn | |
asChild | (props: ParentProps<'div'>) => Element Use the provided child element as the default rendered element, combining their props and behavior. For more details, read our Composition guide. |
Accessibility
Complies with the Radio WAI-ARIA design pattern.
Keyboard Support
Key | Description |
---|---|
Tab | Moves focus to either the checked radio item or the first radio item in the group. |
Space | When focus is on an unchecked radio item, checks it. |
ArrowDown | Moves focus and checks the next radio item in the group. |
ArrowRight | Moves focus and checks the next radio item in the group. |
ArrowUp | Moves focus to the previous radio item in the group. |
ArrowLeft | Moves focus to the previous radio item in the group. |