Default SegmentedControl displays a short list of options for users to choose from. It's usually best to have an option selected by default, but the component also supports an null
initial selected value for when an initial selection can't be determined.
Editable example
( ) => {
const [ selected , setSelected ] = React . useState ( "s" ) ;
return (
< SegmentedControl
label = " Block width "
onChange = { setSelected }
value = { selected }
>
< SegmentedControlOption label = " Small " value = " s " />
< SegmentedControlOption label = " Medium " value = " m " />
< SegmentedControlOption label = " Large " value = " l " />
</ SegmentedControl >
) ;
}
Best practices Don't use a SegmentedControl as a binary switch (e.g. "on" and "off"). Don't use for more than 4 options, or less than 2 options. Make sure your labels are short enough to fit comfortably in the available width. Sizes By default, SegmentedControls are medium sized. For using in context with other large sized controls, or in less dense UIs such as onboarding flows, use the large SegmentedControlSize
.
Editable example
( ) => {
const [ control1 , setControl1 ] = React . useState ( 1 ) ;
const [ control2 , setControl2 ] = React . useState ( 1 ) ;
const [ control3 , setControl3 ] = React . useState ( 1 ) ;
const [ control4 , setControl4 ] = React . useState ( 1 ) ;
return (
< React.Fragment >
< SegmentedControl
label = " Extra small "
size = " xs "
onChange = { setControl1 }
value = { control1 }
>
< SegmentedControlOption label = " Option 1 " value = { 1 } />
< SegmentedControlOption label = " Option 2 " value = { 2 } />
</ SegmentedControl >
< SegmentedControl
label = " Small "
size = " s "
onChange = { setControl2 }
value = { control2 }
>
< SegmentedControlOption label = " Option 1 " value = { 1 } />
< SegmentedControlOption label = " Option 2 " value = { 2 } />
</ SegmentedControl >
< SegmentedControl
label = " Medium "
onChange = { setControl3 }
value = { control3 }
>
< SegmentedControlOption label = " Option 1 " value = { 1 } />
< SegmentedControlOption label = " Option 2 " value = { 2 } />
</ SegmentedControl >
< SegmentedControl
label = " Large "
size = " l "
onChange = { setControl4 }
value = { control4 }
>
< SegmentedControlOption label = " Option 1 " value = { 1 } />
< SegmentedControlOption label = " Option 2 " value = { 2 } />
</ SegmentedControl >
</ React.Fragment >
)
}
Number of options SegmentedControls are best suited to 2—4 options. Anything beyond that you should consider using another component such as a RadioGroup or Select . If you only have a single option use a Toggle .
Keep in mind the available space for each option's label. Consider abbreviating labels or using icons when space is limited.
Editable example
( ) => {
const [ control1 , setControl1 ] = React . useState ( 1 ) ;
const [ control2 , setControl2 ] = React . useState ( 1 ) ;
const [ control3 , setControl3 ] = React . useState ( 1 ) ;
return (
< React.Fragment >
< SegmentedControl
label = " Two options "
onChange = { setControl1 }
value = { control1 }
>
< SegmentedControlOption label = " Option 1 " value = { 1 } />
< SegmentedControlOption label = " Option 2 " value = { 2 } />
</ SegmentedControl >
< SegmentedControl
label = " Three options "
onChange = { setControl2 }
value = { control2 }
>
< SegmentedControlOption label = " Option 1 " value = { 1 } />
< SegmentedControlOption label = " Option 2 " value = { 2 } />
< SegmentedControlOption label = " Option 3 " value = { 3 } />
</ SegmentedControl >
< SegmentedControl
label = " Four options "
onChange = { setControl3 }
value = { control3 }
>
< SegmentedControlOption label = " Option 1 " value = { 1 } />
< SegmentedControlOption label = " Option 2 " value = { 2 } />
< SegmentedControlOption label = " Option 3 " value = { 3 } />
< SegmentedControlOption label = " Option 4 " value = { 4 } />
</ SegmentedControl >
</ React.Fragment >
) ;
}
Icon options Use icons for options that can be clearly identified with a simple icon. Include a visible label within the option, or pair icon options with a tooltip
using the baked in tooltip prop for extra clarity, particularly for less common or more ambiguous icons.
Editable example
( ) => {
const [ selectedView , setSelectedView ] = React . useState ( "library" ) ;
const [ selectedAlign , setSelectedAlign ] = React . useState ( "left" ) ;
const [ selectedFrame , setSelectedFrame ] = React . useState ( "none" ) ;
return (
< React.Fragment >
< SegmentedControl
labelHidden
label = " Library "
onChange = { setSelectedView }
value = { selectedView }
>
< SegmentedControlOption icon = { < Library /> } label = " Library " value = " library " />
< SegmentedControlOption icon = { < Explore /> } label = " Explore " value = " explore " />
</ SegmentedControl >
< SegmentedControl
label = " Alignment "
onChange = { setSelectedAlign }
value = { selectedAlign }
>
< SegmentedControlOption labelHidden icon = { < AlignLeft /> } label = " Left " value = " left " />
< SegmentedControlOption labelHidden icon = { < AlignCenter /> } label = " Center " value = " center " />
</ SegmentedControl >
< SegmentedControl
label = " Image frame "
onChange = { setSelectedFrame }
options = { [
{
label : "None" ,
value : "none" ,
icon : < FrameNone /> ,
tooltipMessage : "No frame" ,
} ,
{
label : "Circle" ,
value : "circle" ,
icon : < FrameCircle /> ,
tooltipMessage : "Circular frame" ,
} ,
] }
value = { selectedFrame }
>
< SegmentedControlOption labelHidden tooltip = { { content : "No frame" } } icon = { < FrameNone /> } label = " None " value = " none " />
< SegmentedControlOption labelHidden tooltip = { { content : "Circular frame" } } icon = { < FrameCircle /> } label = " Circle " value = " circle " />
</ SegmentedControl >
</ React.Fragment >
) ;
}
End element To render content at the end of a SegmentedControlOption, use the endElement
prop.
Editable example
( ) => {
const [ value , setValue ] = React . useState ( 1 ) ;
return (
< React.Fragment >
< SegmentedControl
label = " End element "
onChange = { setValue }
value = { value }
>
< SegmentedControlOption
label = " First option "
value = { 1 }
endElement = {
< Label
size = " s "
style = { {
borderRadius : 32 ,
background : tokens . color . surfaceSuccess ,
paddingInline : tokens . spacing . xs ,
paddingBlock : tokens . spacing . xxxs ,
color : tokens . color . textSuccess ,
} }
>
New
</ Label >
}
/>
< SegmentedControlOption label = " Second option " value = { 2 } />
</ SegmentedControl >
</ React.Fragment >
) ;
}
Asymmetric By default, SegmentedControl options are equal width. To allow options to be of variable widths, use the asymmetric
prop.
Editable example
( ) => {
const [ value , setValue ] = React . useState ( 1 ) ;
return (
< React.Fragment >
< SegmentedControl
asymmetric
label = " Asymmetric "
onChange = { setValue }
value = { value }
>
< SegmentedControlOption label = " First option " value = { 1 } />
< SegmentedControlOption label = " Second option with a long label " value = { 2 } />
</ SegmentedControl >
</ React.Fragment >
) ;
}
Errors Use the error
prop to set any validation errors.
Editable example
( ) => {
const [ value , setValue ] = React . useState ( null ) ;
return (
< SegmentedControl
label = " Select an option "
onChange = { setValue }
value = { value }
error = { value === null ? "Please select an option" : undefined }
>
< SegmentedControlOption label = " First option " value = { 1 } />
< SegmentedControlOption label = " Second option " value = { 2 } />
</ SegmentedControl >
) ;
}
Accessibility Always include a label that describes the group of choices, e.g. "Block width". If the grouping of options is self-evident or implied by context, use the labelHidden
prop so the label will not appear visually but still be read by assistive technology. Always include labels for options, even icon options. The label is used as the aria-label
attribute for icon options. You can also use a tooltip for icon options.