SegmentedControl

Segmented controls present a small set of exclusive options. The indicator animates between segments with support for horizontal and vertical layouts, optional auto contrast for filled variants, and reduced motion awareness for accessibility.

Basic Usage

Set defaultValue to preselect a segment and let the control manage focus and selection state internally.

Loading demo…

import

 

{

 

SegmentedControl

,

 

Text

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

import

 

{

frameworks

}

 

from

 

'../data'

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<SegmentedControl

 

defaultValue

=

"react"

 

data

=

{

frameworks

}

 

/>

  

)

;

}

Controlled Value

Provide value and onChange to synchronize the selected segment with external state or companion controls.

Loading demo…

import

 

{

useState

}

 

from

 

'react'

;

import

 

{

 

Block

,

 

Button

,

 

Card

,

 

Row

,

 

SegmentedControl

,

 

Text

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

import

 

{

frameworks

}

 

from

 

'../data'

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

value

,

setValue

]

 

=

 

useState

(

'react'

)

;

 

  

return

 

(

    

<Card

 

p

=

"md"

>

      

<Block

>

        

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

          

Drive

the segmented control

from

external state to synchronize its value with other inputs

.

        

</Text

>

        

<SegmentedControl

 

value

=

{

value

}

 

onChange

=

{

setValue

}

 

data

=

{

frameworks

}

 

/>

        

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

          

Selected

value

:

 

<Text

 

as

=

"span"

 

weight

=

"600"

>

{

value

}

</Text

>

        

</Text

>

        

<Row

 

gap

=

"sm"

 

wrap

=

"wrap"

>

          

<Button

 

size

=

"xs"

 

onPress

=

{

(

)

 

=>

 

setValue

(

'react'

)

}

>

            

Select

 

React

          

</Button

>

          

<Button

 

size

=

"xs"

 

variant

=

"outline"

 

onPress

=

{

(

)

 

=>

 

setValue

(

'angular'

)

}

>

            

Select

 

Angular

          

</Button

>

          

<Button

 

size

=

"xs"

 

variant

=

"outline"

 

onPress

=

{

(

)

 

=>

 

setValue

(

'vue'

)

}

>

            

Select

 

Vue

          

</Button

>

        

</Row

>

      

</Block

>

    

</Card

>

  

)

;

}

Sizes

Use the size prop to match dense toolbars or spacious layouts without changing the underlying data.

Loading demo…

import

 

{

 

Block

,

 

SegmentedControl

,

 

Text

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

import

 

{

frameworkNames

}

 

from

 

'../data'

;

 

const

 

SIZES

 

=

 

[

'xs'

,

 

'sm'

,

 

'md'

,

 

'lg'

,

 

'xl'

,

 

'2xl'

,

 

'3xl'

]

as

const

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<Block

>

      

{

SIZES

.

map

(

(

size

)

 

=>

 

(

        

<Block

 

key

=

{

size

}

>

          

<Text

 

variant

=

"small"

 

color

=

"secondary"

>

{

size

}

</Text

>

          

<SegmentedControl

 

size

=

{

size

}

 

data

=

{

frameworkNames

}

 

defaultValue

=

"React"

 

/>

        

</Block

>

      

)

)

}

    

</Block

>

  

)

;

}

Full Width

Apply fullWidth to let segments expand and distribute evenly across the available horizontal space.

Loading demo…

import

 

{

 

SegmentedControl

,

 

Text

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

import

 

{

panes

}

 

from

 

'../data'

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<SegmentedControl

fullWidth

defaultValue

=

"preview"

 

data

=

{

panes

}

 

/>

  

)

;

}

Orientation

Toggle the orientation prop to rotate the control vertically for sidebars or keep it horizontal for toolbars.

Loading demo…

import

 

{

 

Block

,

 

Row

,

 

SegmentedControl

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

import

 

{

frameworks

,

panes

}

 

from

 

'../data'

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

      

<Block

>

        

<Row

 

gap

=

"lg"

 

align

=

"flex-start"

 

wrap

=

"wrap"

>

          

<SegmentedControl

            

label

=

"Horizontal (default)"

            

orientation

=

"horizontal"

            

defaultValue

=

"react"

            

data

=

{

frameworks

}

          

/>

          

<SegmentedControl

            

label

=

"Vertical"

            

orientation

=

"vertical"

            

defaultValue

=

"code"

            

data

=

{

panes

}

          

/>

        

</Row

>

      

</Block

>

  

)

;

}

Custom Colors

Set the color prop to pull semantic tokens or pass custom values, and enable autoContrast when you need readable labels on vivid fills.

Loading demo…

import

 

{

 

Block

,

 

SegmentedControl

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

import

 

{

accountSections

,

frameworks

,

panes

,

priorities

}

 

from

 

'../data'

;

 

const

palettes

=

 

[

  

{

key

:

 

'primary'

,

color

:

 

'primary'

,

defaultValue

:

 

'react'

,

data

:

frameworks

}

,

  

{

key

:

 

'success'

,

color

:

 

'success'

,

defaultValue

:

 

'code'

,

data

:

panes

}

,

  

{

key

:

 

'purple'

,

color

:

 

'purple'

,

defaultValue

:

 

'settings'

,

data

:

accountSections

}

,

  

{

key

:

 

'custom'

,

color

:

 

'#FF6B6B'

,

defaultValue

:

 

'medium'

,

data

:

priorities

}

,

]

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<Block

>

      

{

palettes

.

map

(

(

palette

)

 

=>

 

(

        

<SegmentedControl

          

key

=

{

palette

.

key

}

          

defaultValue

=

{

palette

.

defaultValue

}

          

color

=

{

palette

.

color

}

          

data

=

{

palette

.

data

}

        

/>

      

)

)

}

    

</Block

>

  

)

;

}

Interaction States

Combine disabled, readOnly, or per-item disabled flags to signal availability without changing layout or selection rules.

Loading demo…

import

 

{

 

Block

,

 

Card

,

 

SegmentedControl

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

import

 

{

frameworks

,

languages

,

panes

,

priorities

}

 

from

 

'../data'

;

 

const

scenarios

=

 

[

  

{

key

:

 

'default'

,

label

:

 

'Interactive'

,

props

:

 

{

}

,

defaultValue

:

 

'react'

,

data

:

frameworks

}

,

  

{

key

:

 

'disabled'

,

label

:

 

'Disabled'

,

props

:

 

{

disabled

:

 

true

 

}

,

defaultValue

:

 

'code'

,

data

:

panes

}

,

  

{

key

:

 

'readOnly'

,

label

:

 

'Read only'

,

props

:

 

{

readOnly

:

 

true

 

}

,

defaultValue

:

 

'medium'

,

data

:

priorities

}

,

  

// `languages` carries the disabled flag on its last item.

  

{

key

:

 

'itemDisabled'

,

label

:

 

'Single option disabled'

,

props

:

 

{

}

,

defaultValue

:

 

'typescript'

,

data

:

languages

}

,

]

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<Card

 

p

=

"md"

>

      

<Block

>

        

<Block

>

          

{

scenarios

.

map

(

(

scenario

)

 

=>

 

(

            

<SegmentedControl

              

key

=

{

scenario

.

key

}

              

label

=

{

scenario

.

label

}

              

defaultValue

=

{

scenario

.

defaultValue

}

              

data

=

{

scenario

.

data

}

              

{

.

.

.

scenario

.

props

}

            

/>

          

)

)

}

        

</Block

>

      

</Block

>

    

</Card

>

  

)

;

}

Visual Variants

Choose between default, filled, outline, or ghost variants and pair them with semantic color tokens to match the surrounding surface.

Loading demo…

import

 

{

 

Block

,

 

Card

,

 

SegmentedControl

,

 

Text

 

}

 

from

 

'@platform-blocks/react-ui-library'

;

 

import

 

{

cadences

,

frameworks

,

panes

,

priorities

,

publishStates

}

 

from

 

'../data'

;

 

const

variants

=

 

[

  

{

    key

:

 

'default'

,

    label

:

 

'Default'

,

    props

:

 

{

variant

:

 

'default'

as

const

 

}

,

    defaultValue

:

 

'react'

,

    description

:

 

'Baseline segmented control with tonal contrast.'

,

    data

:

frameworks

,

  

}

,

  

{

    key

:

 

'filledPrimary'

,

    label

:

 

'Filled'

,

    props

:

 

{

variant

:

 

'filled'

as

const

,

color

:

 

'primary'

as

const

 

}

,

    defaultValue

:

 

'code'

,

    description

:

 

'Solid background that matches the selected color token.'

,

    data

:

panes

,

  

}

,

  

{

    key

:

 

'filledContrast'

,

    label

:

 

'Filled with auto-contrast'

,

    props

:

 

{

      variant

:

 

'filled'

as

const

,

      color

:

 

'warning'

as

const

,

      autoContrast

:

 

true

,

    

}

,

    defaultValue

:

 

'medium'

,

    description

:

 

'Enable autoContrast when using vivid palettes to keep labels legible.'

,

    data

:

priorities

,

  

}

,

  

{

    key

:

 

'outline'

,

    label

:

 

'Outline'

,

    props

:

 

{

variant

:

 

'outline'

as

const

,

color

:

 

'secondary'

as

const

 

}

,

    defaultValue

:

 

'weekly'

,

    description

:

 

'Focus on outlining the chosen tab while keeping the surface quiet.'

,

    data

:

cadences

,

  

}

,

  

{

    key

:

 

'ghost'

,

    label

:

 

'Ghost'

,

    props

:

 

{

variant

:

 

'ghost'

as

const

,

color

:

 

'success'

as

const

 

}

,

    defaultValue

:

 

'published'

,

    description

:

 

'Ghost removes the segment background until selection, ideal on tinted surfaces.'

,

    data

:

publishStates

,

  

}

,

]

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<Card

 

p

=

"md"

>

      

<Block

>

        

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

          

Change

the variant to match the surface and emphasis level of the surrounding layout

.

        

</Text

>

        

<Block

>

          

{

variants

.

map

(

(

variant

)

 

=>

 

(

            

<Block

 

key

=

{

variant

.

key

}

>

              

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

                

{

variant

.

label

}

              

</Text

>

              

<SegmentedControl

                

defaultValue

=

{

variant

.

defaultValue

}

                

data

=

{

variant

.

data

}

                

{

.

.

.

variant

.

props

}

              

/>

              

<Text

 

size

=

"xs"

 

color

=

"muted"

>

                

{

variant

.

description

}

              

</Text

>

            

</Block

>

          

)

)

}

        

</Block

>

      

</Block

>

    

</Card

>

  

)

;

}

Scan to open this page on your phonereact-ui-library.com/components/SegmentedControl

</>

react-ui-library

100+ accessible, themeable components that work seamlessly across iOS, Android, and Web.

A Platform Blocks product.