Button

The Button component provides a flexible interactive element supporting variants, sizes, icons, loading state, and full-width layout. The inner label <Text> accepts the full Text-prop API via labelProps (ff, weight, tracking, uppercase, color, style).
Buttons default to the default variant — a neutral button (card surface, hairline border, body text) that sizes to its content. Reach for variant="filled" on the primary action of a view, and fullWidth (or w) when the button should span its container.

Basics

Invokes a primary action and surfaces feedback through a toast helper.

Loading demo…

import

 

{

 

Block

,

 

Button

,

useToast

}

 

from

 

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

;

 

export

 

function

 

Demo

(

)

 

{

  

const

toast

=

 

useToast

(

)

;

 

  

return

 

(

    

<Block

 

align

=

"flex-start"

>

      

<Button

        

title

=

"Launch mission"

        

onPress

=

{

(

)

 

=>

toast

.

success

(

'Launch command sent'

)

}

      

/>

      

<Button

        

title

=

"Abort"

        

onPress

=

{

(

)

 

=>

toast

.

error

(

'Sequence aborted'

)

}

      

/>

    

</Block

>

  

)

;

}

Colors

Pair color with a color-bearing variant (filled, light, subtle, outline, gradient) to align actions with brand intent. The default variant is neutral chrome and ignores color.

Loading demo…

import

 

{

 

Button

,

 

Row

 

}

 

from

 

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

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<Row

 

gap

=

"md"

 

wrap

=

"wrap"

>

      

<Button

 

variant

=

"filled"

 

color

=

"primary"

>

Primary

</Button

>

      

<Button

 

variant

=

"filled"

 

color

=

"secondary"

>

Secondary

</Button

>

      

<Button

 

variant

=

"filled"

 

color

=

"success"

>

Success

</Button

>

      

<Button

 

variant

=

"filled"

 

color

=

"warning"

>

Warning

</Button

>

      

<Button

 

variant

=

"filled"

 

color

=

"error"

>

Error

</Button

>

    

</Row

>

  

)

;

}

Loading state

Demonstrates consistent width preservation, custom loadingTitle, and disabling actions while background work completes.

Loading demo…

import

 

{

useEffect

,

useRef

,

useState

}

 

from

 

'react'

;

import

 

{

 

Button

,

 

Row

 

}

 

from

 

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

;

 

const

LOADING_DURATION_MS

=

 

2000

;

 

export

 

function

 

Demo

(

)

 

{

  

const

timeoutRef

=

useRef

<ReturnType

<

typeof setTimeout

>

 

|

 

null

>

(

null

)

;

  

const

 

[

activeKey

,

setActiveKey

]

 

=

useState

<

string

 

|

 

null

>

(

null

)

;

 

  

useEffect

(

(

)

 

=>

 

(

)

 

=>

 

{

    

if

 

(

timeoutRef

.

current

)

 

{

      

clearTimeout

(

timeoutRef

.

current

)

;

    

}

  

}

,

 

[

]

)

;

 

  

const

triggerLoading

=

 

(

key

:

 

string

)

 

=>

 

{

    

if

 

(

timeoutRef

.

current

)

 

{

      

clearTimeout

(

timeoutRef

.

current

)

;

    

}

 

    

setActiveKey

(

key

)

;

    timeoutRef

.

current

=

 

setTimeout

(

(

)

 

=>

 

{

      

setActiveKey

(

null

)

;

      timeoutRef

.

current

=

 

null

;

    

}

,

LOADING_DURATION_MS

)

;

  

}

;

 

  

return

 

(

    

<Row

 

gap

=

"md"

 

wrap

=

"wrap"

 

align

=

"flex-start"

>

      

<Button

 

loading

=

{

activeKey

===

 

'default'

}

 

onPress

=

{

(

)

 

=>

 

triggerLoading

(

'default'

)

}

>

        

Submit

application

      

</Button

>

      

<Button

        

loading

=

{

activeKey

===

 

'custom'

}

        

loadingTitle

=

"Submitting…"

        

onPress

=

{

(

)

 

=>

 

triggerLoading

(

'custom'

)

}

      

>

        

Submit

application

      

</Button

>

      

<Button

        

loading

=

{

activeKey

===

 

'disabled'

}

        

disabled

=

{

activeKey

===

 

'disabled'

}

        

loadingTitle

=

"Loading"

        

onPress

=

{

(

)

 

=>

 

triggerLoading

(

'disabled'

)

}

      

>

        

Submit

application

      

</Button

>

    

</Row

>

  

)

;

}

Variants

Preview the available button variants to match the desired emphasis level.

Loading demo…

import

 

{

 

Button

,

 

Row

 

}

 

from

 

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

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<Row

 

gap

=

"md"

 

wrap

=

"wrap"

>

      

<Button

 

variant

=

"default"

>

Default

</Button

>

      

<Button

 

variant

=

"filled"

>

Filled

</Button

>

      

<Button

 

variant

=

"light"

>

Light

</Button

>

      

<Button

 

variant

=

"subtle"

>

Subtle

</Button

>

      

<Button

 

variant

=

"secondary"

>

Secondary

</Button

>

      

<Button

 

variant

=

"outline"

>

Outline

</Button

>

      

<Button

 

variant

=

"gradient"

>

Gradient

</Button

>

      

<Button

 

variant

=

"ghost"

>

Ghost

</Button

>

      

<Button

 

variant

=

"none"

>

Text

only

</Button

>

    

</Row

>

  

)

;

}

Sizes

Preview the available button size tokens for different density requirements.

Loading demo…

import

 

{

 

Button

,

 

Row

 

}

 

from

 

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

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<Row

 

gap

=

"md"

 

wrap

=

"wrap"

 

align

=

"flex-end"

>

      

<Button

 

size

=

"sm"

>

Small

</Button

>

      

<Button

 

size

=

"md"

>

Medium

</Button

>

      

<Button

 

size

=

"lg"

>

Large

</Button

>

      

<Button

 

size

=

"xl"

>

Extra

large

</Button

>

    

</Row

>

  

)

;

}

Localized labels

Switch locales at runtime and render translated button copy with useI18n helpers.

Loading demo…

import

 

{

 

Block

,

 

Button

,

 

Flex

,

 

Select

,

useI18n

}

 

from

 

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

;

 

const

 

LOCALES

 

=

 

[

  

{

label

:

 

'English'

,

value

:

 

'en'

 

}

,

  

{

label

:

 

'Español'

,

value

:

 

'es'

 

}

,

  

{

label

:

 

'Français'

,

value

:

 

'fr'

 

}

,

]

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

{

t

,

locale

,

setLocale

}

 

=

 

useI18n

(

)

;

 

  

return

 

(

    

<Flex

>

      

<Select

        

options

=

{

LOCALES

}

        

value

=

{

locale

}

        

onChange

=

{

(

value

)

 

=>

 

{

 

if

 

(

value

)

 

setLocale

(

value

)

;

 

}

}

      

/>

      

<Button

        

title

=

{

t

(

'button.demo.submit'

)

}

        

w

=

{

200

}

      

/>

    

</Flex

>

  

)

;

}

Tooltips

Add contextual hints to buttons with tooltip and optional placement overrides.

Loading demo…

import

 

{

 

Block

,

 

Button

,

 

Icon

,

 

Row

 

}

 

from

 

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

;

 

export

 

function

 

Demo

(

)

 

{

  

return

 

(

    

<Block

>

      

<Row

 

gap

=

"md"

 

wrap

=

"wrap"

 

align

=

"flex-start"

>

        

<Button

 

tooltip

=

"Save your current work."

>

Save

</Button

>

        

<Button

          

variant

=

"outline"

          

tooltip

=

"Permanently delete this item."

          

tooltipPosition

=

"bottom"

        

>

          

Delete

        

</Button

>

        

<Button

          

variant

=

"ghost"

          

tooltip

=

"Get help and support resources."

          

tooltipPosition

=

"right"

        

>

          

Help

        

</Button

>

      

</Row

>

 

      

<Row

 

gap

=

"md"

 

wrap

=

"wrap"

 

align

=

"flex-start"

>

        

<Button

 

tooltip

=

"Download the file to your device."

 

tooltipPosition

=

"left"

>

          

Download

        

</Button

>

        

<Button

 

icon

=

{

<Icon

 

name

=

"settings"

 

/>

}

 

tooltip

=

"Open the settings panel."

 

accessibilityLabel

=

"Open settings"

 

/>

        

<Button

disabled

tooltip

=

"Feature not available in demo mode."

>

          

Upload

        

</Button

>

      

</Row

>

    

</Block

>

  

)

;

}

Width

Demonstrates fixed, percentage, and full-width buttons alongside loading states that preserve dimensions.

Loading demo…

import

 

{

useEffect

,

useRef

,

useState

}

 

from

 

'react'

;

import

 

{

 

Block

,

 

Button

,

 

Row

,

 

Text

 

}

 

from

 

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

;

 

const

LOADING_DURATION_MS

=

 

2000

;

 

export

 

function

 

Demo

(

)

 

{

  

const

timeoutRef

=

useRef

<ReturnType

<

typeof setTimeout

>

 

|

 

null

>

(

null

)

;

  

const

 

[

loadingKey

,

setLoadingKey

]

 

=

useState

<

string

 

|

 

null

>

(

null

)

;

 

  

useEffect

(

(

)

 

=>

 

(

)

 

=>

 

{

    

if

 

(

timeoutRef

.

current

)

 

{

      

clearTimeout

(

timeoutRef

.

current

)

;

    

}

  

}

,

 

[

]

)

;

 

  

const

triggerLoading

=

 

(

key

:

 

string

)

 

=>

 

{

    

if

 

(

timeoutRef

.

current

)

 

{

      

clearTimeout

(

timeoutRef

.

current

)

;

    

}

 

    

setLoadingKey

(

key

)

;

    timeoutRef

.

current

=

 

setTimeout

(

(

)

 

=>

 

{

      

setLoadingKey

(

null

)

;

      timeoutRef

.

current

=

 

null

;

    

}

,

LOADING_DURATION_MS

)

;

  

}

;

 

  

return

 

(

    

<Block

>

      

<Block

>

 

        

<Block

>

          

<Button

>

Default

width

</Button

>

          

<Text

 

variant

=

"small"

 

color

=

"muted"

>

            

Buttons

size themselves to the label length by

default

.

          

</Text

>

        

</Block

>

 

        

<Block

>

          

<Button

 

w

=

{

200

}

>

Fixed

 

width

 

(

200

)

</Button

>

          

<Text

 

variant

=

"small"

 

color

=

"muted"

>

            

Provide

an exact

`w`

value

for

pixel

-

perfect toolbars

.

          

</Text

>

        

</Block

>

 

      

</Block

>

 

      

<Block

>

        

<Row

 

gap

=

"md"

 

wrap

=

"wrap"

 

align

=

"flex-start"

>

          

<Button

            

loading

=

{

loadingKey

===

 

'long'

}

            

loadingTitle

=

"Loading…"

            

onPress

=

{

(

)

 

=>

 

triggerLoading

(

'long'

)

}

          

>

            

Preserve

width

while

loading

          

</Button

>

          

<Button

 

loading

=

{

loadingKey

===

 

'short'

}

 

onPress

=

{

(

)

 

=>

 

triggerLoading

(

'short'

)

}

>

            

Short

text

          

</Button

>

        

</Row

>

        

<Text

 

variant

=

"small"

 

color

=

"muted"

>

          

When

 

`loading`

is

true

,

the button keeps its original width so layouts stay stable

.

        

</Text

>

      

</Block

>

    

</Block

>

  

)

;

}

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

</>

react-ui-library

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

A Platform Blocks product.