Spotlight

The Spotlight component provides a fast, keyboard-driven interface for searching commands, routes, and entities. Supports arrow key navigation, Enter to select, and Escape to dismiss.

Keyboard Palette

Open the Spotlight command palette through the shared store and a primary trigger button.

Loading demo…

import

 

{

 

Block

,

 

Button

,

 

Card

,

 

Spotlight

,

 

Text

,

 

type

 

SpotlightProps

,

useSpotlightStoreInstance

}

 

from

 

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

;

 

const

actions

:

 

SpotlightProps

[

'actions'

]

 

=

 

[

  

{

    id

:

 

'home'

,

    label

:

 

'Go to home'

,

    description

:

 

'Navigate to the home screen'

,

    icon

:

 

'home'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'navigate: home'

)

,

  

}

,

  

{

    id

:

 

'profile'

,

    label

:

 

'Open profile'

,

    description

:

 

'View your account details'

,

    icon

:

 

'user'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'navigate: profile'

)

,

  

}

,

  

{

    id

:

 

'settings'

,

    label

:

 

'Adjust settings'

,

    description

:

 

'Update application preferences'

,

    icon

:

 

'settings'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'navigate: settings'

)

,

  

}

,

]

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

store

]

 

=

 

useSpotlightStoreInstance

(

)

;

 

  

return

 

(

    

<Block

>

      

<Card

 

p

=

"md"

>

        

<Block

>

          

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

            

Spotlight

provides a keyboard

-

driven command palette

.

 

Open

it with

`⌘K`

or

`Ctrl+K`

,

or trigger it imperatively

from

a button

.

          

</Text

>

          

<Button

 

onPress

=

{

(

)

 

=>

store

.

open

(

)

}

>

Open

spotlight

</Button

>

          

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

            

You

can reuse the same store across multiple triggers

.

          

</Text

>

        

</Block

>

      

</Card

>

      

<Spotlight

 

actions

=

{

actions

}

 

store

=

{

store

}

 

/>

    

</Block

>

  

)

;

}

Custom Icons

Swap icon definitions with custom React nodes to render richer action affordances.

Loading demo…

import

 

{

 

Block

,

 

Button

,

 

Card

,

 

Icon

,

 

Spotlight

,

 

Text

,

 

type

 

SpotlightProps

,

useSpotlightStoreInstance

}

 

from

 

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

;

 

const

actions

:

 

SpotlightProps

[

'actions'

]

 

=

 

[

  

{

    id

:

 

'deploy'

,

    label

:

 

'Deploy service'

,

    description

:

 

'Trigger the CI/CD pipeline'

,

    icon

:

 

<Icon

 

name

=

"bolt"

 

size

=

"md"

 

/>

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'deploy service'

)

,

  

}

,

  

{

    id

:

 

'logs'

,

    label

:

 

'Inspect logs'

,

    description

:

 

'Open the latest runtime logs'

,

    icon

:

 

<Icon

 

name

=

"code"

 

size

=

"md"

 

/>

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'view logs'

)

,

  

}

,

  

{

    id

:

 

'alerts'

,

    label

:

 

'Review alerts'

,

    description

:

 

'Check active incidents'

,

    icon

:

 

<Icon

 

name

=

"bell"

 

size

=

"md"

 

/>

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'open alerts'

)

,

  

}

,

]

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

store

]

 

=

 

useSpotlightStoreInstance

(

)

;

 

  

return

 

(

    

<Block

>

      

<Card

 

p

=

"md"

>

        

<Block

>

          

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

            

Icons

accept full

React

nodes

,

so you can swap in composable

UI

like

`Icon`

,

avatars

,

or status badges

for

richer visuals

.

          

</Text

>

          

<Button

 

variant

=

"outline"

 

onPress

=

{

(

)

 

=>

store

.

open

(

)

}

>

            

Open

spotlight

          

</Button

>

        

</Block

>

      

</Card

>

      

<Spotlight

 

actions

=

{

actions

}

 

store

=

{

store

}

 

/>

    

</Block

>

  

)

;

}

Grouped Actions

Organize actions into named groups so related commands render under semantic headers.

Loading demo…

import

 

{

 

Block

,

 

Button

,

 

Card

,

 

Spotlight

,

 

Text

,

 

type

 

SpotlightProps

,

useSpotlightStoreInstance

}

 

from

 

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

;

 

const

actions

:

 

SpotlightProps

[

'actions'

]

 

=

 

[

  

{

    group

:

 

'Navigation'

,

    actions

:

 

[

      

{

id

:

 

'home'

,

label

:

 

'Home'

,

icon

:

 

'home'

,

onPress

:

 

(

)

 

=>

console

.

log

(

'navigate: home'

)

 

}

,

      

{

        id

:

 

'dashboard'

,

        label

:

 

'Dashboard'

,

        description

:

 

'Jump to the analytics overview'

,

        icon

:

 

'star'

,

        onPress

:

 

(

)

 

=>

console

.

log

(

'navigate: dashboard'

)

,

      

}

,

    

]

,

  

}

,

  

{

    group

:

 

'Settings'

,

    actions

:

 

[

      

{

id

:

 

'profile'

,

label

:

 

'Profile'

,

icon

:

 

'user'

,

onPress

:

 

(

)

 

=>

console

.

log

(

'navigate: profile'

)

 

}

,

      

{

        id

:

 

'billing'

,

        label

:

 

'Billing settings'

,

        description

:

 

'Manage payment methods'

,

        icon

:

 

'settings'

,

        onPress

:

 

(

)

 

=>

console

.

log

(

'navigate: billing'

)

,

      

}

,

    

]

,

  

}

,

]

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

store

]

 

=

 

useSpotlightStoreInstance

(

)

;

 

  

return

 

(

    

<Block

>

      

<Card

 

p

=

"md"

>

        

<Block

>

          

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

            

Group

actions to create semantic sections inside the results list

.

 

Each

group renders a header before its nested actions

.

          

</Text

>

          

<Button

 

variant

=

"secondary"

 

onPress

=

{

(

)

 

=>

store

.

open

(

)

}

>

            

Open

spotlight

          

</Button

>

        

</Block

>

      

</Card

>

      

<Spotlight

 

actions

=

{

actions

}

 

store

=

{

store

}

 

/>

    

</Block

>

  

)

;

}

Highlight Matches

Enable highlightQuery so matching substrings glow while you refine command searches.

Loading demo…

import

 

{

 

Block

,

 

Button

,

 

Card

,

 

Spotlight

,

 

Text

,

 

type

 

SpotlightProps

,

useSpotlightStoreInstance

}

 

from

 

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

;

 

// Actions intentionally share overlapping substrings to show highlighting effect

const

actions

:

 

SpotlightProps

[

'actions'

]

 

=

 

[

  

{

    id

:

 

'create-project'

,

    label

:

 

'Create project'

,

    description

:

 

'Start a new project workspace'

,

    icon

:

 

'plus'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'action: create project'

)

,

  

}

,

  

{

    id

:

 

'create-branch'

,

    label

:

 

'Create branch'

,

    description

:

 

'Open branch creation workflow'

,

    icon

:

 

'code'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'action: create branch'

)

,

  

}

,

  

{

    id

:

 

'open-recent'

,

    label

:

 

'Open recent project'

,

    description

:

 

'Choose from recently opened projects'

,

    icon

:

 

'folder'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'action: open recent'

)

,

  

}

,

  

{

    id

:

 

'project-settings'

,

    label

:

 

'Project settings'

,

    description

:

 

'Configure repository options'

,

    icon

:

 

'settings'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'action: project settings'

)

,

  

}

,

]

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

store

]

 

=

 

useSpotlightStoreInstance

(

)

;

 

  

return

 

(

    

<Block

>

      

<Card

 

p

=

"md"

>

        

<Block

>

          

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

            

Passing

 

`highlightQuery`

emphasizes matching substrings across labels and descriptions

,

reinforcing why a result surfaced

.

          

</Text

>

          

<Button

 

onPress

=

{

(

)

 

=>

store

.

open

(

)

}

>

Open

spotlight

</Button

>

          

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

            

Try

typing “proj” or “create” to see the inline highlights

.

          

</Text

>

        

</Block

>

      

</Card

>

      

<Spotlight

 

actions

=

{

actions

}

highlightQuery

store

=

{

store

}

 

/>

    

</Block

>

  

)

;

}

Limit Results

Restrict how many matching actions render by applying the limit prop.

Loading demo…

import

 

{

 

Block

,

 

Button

,

 

Card

,

 

Spotlight

,

 

Text

,

 

type

 

SpotlightProps

,

useSpotlightStoreInstance

}

 

from

 

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

;

 

const

actions

:

 

SpotlightProps

[

'actions'

]

 

=

 

Array

.

from

(

{

length

:

 

25

 

}

)

.

map

(

(

_

,

index

)

 

=>

 

(

{

  id

:

 

`command-${index}`

,

  label

:

 

`Command ${index + 1}`

,

  description

:

 

`Example action #${index + 1}`

,

  icon

:

 

'star'

,

  onPress

:

 

(

)

 

=>

console

.

log

(

'command'

,

index

+

 

1

)

,

}

)

)

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

store

]

 

=

 

useSpotlightStoreInstance

(

)

;

 

  

return

 

(

    

<Block

>

      

<Card

 

p

=

"md"

>

        

<Block

>

          

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

            

Set

the

`limit`

prop to constrain how many results render

,

even

if

more actions match the query

.

          

</Text

>

          

<Button

 

onPress

=

{

(

)

 

=>

store

.

open

(

)

}

>

Open

spotlight

</Button

>

          

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

            

This

demo caps the list at

8

items

.

          

</Text

>

        

</Block

>

      

</Card

>

      

<Spotlight

 

actions

=

{

actions

}

 

limit

=

{

8

}

 

store

=

{

store

}

 

/>

    

</Block

>

  

)

;

}

Fullscreen Mobile

Pin the fullscreen variant to mimic native command palettes on handheld devices.

Loading demo…

import

 

{

 

Platform

 

}

 

from

 

'react-native'

;

import

 

{

 

Block

,

 

Button

,

 

Card

,

 

Spotlight

,

 

Text

,

 

type

 

SpotlightProps

,

useSpotlightStoreInstance

}

 

from

 

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

;

 

// Reuse a moderate list to showcase vertical scroll in fullscreen

const

actions

:

 

SpotlightProps

[

'actions'

]

 

=

 

Array

.

from

(

{

length

:

 

18

 

}

)

.

map

(

(

_

,

index

)

 

=>

 

(

{

  id

:

 

`mobile-action-${index}`

,

  label

:

 

`Mobile action ${index + 1}`

,

  description

:

 

'Available on every screen'

,

  icon

:

 

'star'

,

  onPress

:

 

(

)

 

=>

console

.

log

(

'mobile action'

,

index

+

 

1

)

,

}

)

)

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

store

]

 

=

 

useSpotlightStoreInstance

(

)

;

  

const

isMobile

=

 

Platform

.

OS

 

!==

 

'web'

;

 

  

return

 

(

    

<Block

>

      

<Card

 

p

=

"md"

>

        

<Block

>

          

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

            

Force

the

`fullscreen`

variant to mimic a native sheet on touch devices

while

keeping the modal layout on web

for

comparison

.

          

</Text

>

          

<Button

 

onPress

=

{

(

)

 

=>

store

.

open

(

)

}

>

            

{

isMobile

?

 

'Open fullscreen spotlight'

 

:

 

'Open spotlight'

}

          

</Button

>

          

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

            

The

component already auto

-

detects mobile surfaces

;

 

this

demo pins the variant

for

clarity

.

          

</Text

>

        

</Block

>

      

</Card

>

      

<Spotlight

 

actions

=

{

actions

}

 

variant

=

"fullscreen"

 

store

=

{

store

}

 

/>

    

</Block

>

  

)

;

}

Programmatic Stores

Showcase scoped Spotlight stores, dynamic actions, and the global spotlight helper working together.

Loading demo…

import

 

{

useMemo

,

useState

}

 

from

 

'react'

;

import

 

{

  

Block

,

  

Button

,

  

Card

,

  

Row

,

  spotlight

,

  

Spotlight

,

  

SpotlightProvider

,

  

Text

,

  

type

 

SpotlightProps

,

  useSpotlightStoreInstance

,

}

 

from

 

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

;

 

const

baseActions

:

 

SpotlightProps

[

'actions'

]

 

=

 

[

  

{

    id

:

 

'ping'

,

    label

:

 

'Ping server'

,

    description

:

 

'Send a ping to the backend'

,

    icon

:

 

'bolt'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'ping'

)

,

  

}

,

  

{

    id

:

 

'refresh'

,

    label

:

 

'Refresh data'

,

    description

:

 

'Reload cached domain data'

,

    icon

:

 

'refresh'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'refresh'

)

,

  

}

,

]

;

 

const

globalActions

:

 

SpotlightProps

[

'actions'

]

 

=

 

[

  

{

    id

:

 

'global-home'

,

    label

:

 

'Global home'

,

    description

:

 

'Navigate home via the shared store'

,

    icon

:

 

'home'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'global home'

)

,

  

}

,

  

{

    id

:

 

'global-settings'

,

    label

:

 

'Global settings'

,

    description

:

 

'Open the account-wide preferences'

,

    icon

:

 

'settings'

,

    onPress

:

 

(

)

 

=>

console

.

log

(

'global settings'

)

,

  

}

,

]

;

 

export

 

function

 

Demo

(

)

 

{

  

const

 

[

store

]

 

=

 

useSpotlightStoreInstance

(

)

;

  

const

 

[

dynamicCount

,

setDynamicCount

]

 

=

 

useState

(

0

)

;

 

  

const

actions

=

useMemo

<SpotlightProps

[

'actions'

]

>

(

    

(

)

 

=>

 

[

      

.

.

.

baseActions

,

      

{

        id

:

 

'add-dynamic'

,

        label

:

 

'Add dynamic action'

,

        icon

:

 

'plus'

,

        onPress

:

 

(

)

 

=>

 

setDynamicCount

(

(

count

)

 

=>

count

+

 

1

)

,

      

}

,

      

.

.

.

Array

.

from

(

{

length

:

dynamicCount

}

)

.

map

(

(

_

,

index

)

 

=>

 

(

{

        id

:

 

`dynamic-${index}`

,

        label

:

 

`Dynamic action ${index + 1}`

,

        description

:

 

'Added at runtime to the local store'

,

        icon

:

 

'star'

,

        onPress

:

 

(

)

 

=>

console

.

log

(

'dynamic'

,

index

+

 

1

)

,

      

}

)

)

,

    

]

,

    

[

dynamicCount

]

  

)

;

 

  

return

 

(

    

<SpotlightProvider

>

      

<Block

>

        

<Card

 

p

=

"md"

>

          

<Block

>

            

<Text

 

size

=

"sm"

 

color

=

"secondary"

>

              

Combine

local stores with the global

`spotlight`

helper

.

 

This

demo adds actions to its scoped store

while

still toggling the shared palette

.

            

</Text

>

            

<Row

 

gap

=

"sm"

 

wrap

=

"wrap"

>

              

<Button

 

onPress

=

{

(

)

 

=>

store

.

open

(

)

}

>

Open

demo store

</Button

>

              

<Button

 

variant

=

"outline"

 

onPress

=

{

(

)

 

=>

spotlight

.

toggle

(

)

}

>

                

Toggle

global spotlight

              

</Button

>

            

</Row

>

            

<Text

 

size

=

"xs"

 

color

=

"secondary"

>

              

Select

Add

dynamic action” to append more commands on the fly

.

            

</Text

>

          

</Block

>

        

</Card

>

        

<Spotlight

 

actions

=

{

actions

}

 

store

=

{

store

}

 

/>

        

<Spotlight

 

actions

=

{

globalActions

}

 

/>

      

</Block

>

    

</SpotlightProvider

>

  

)

;

}

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

</>

react-ui-library

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

A Platform Blocks product.