Spotlight

Spotlight provides a searchable command palette for actions, routes, and other items.

npm install @plocks/spotlight

Basics

Open the Spotlight command palette with ⌘K / Ctrl+K, or from a button through its store.

Loading demo…

import { Block, Button } from '@plocks/ui'; import { Spotlight, type SpotlightProps, useSpotlightStoreInstance } from '@plocks/spotlight'; 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> <Button onPress={() => store.open()}>Open spotlight</Button> <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, Icon } from '@plocks/ui'; import { Spotlight, type SpotlightProps, useSpotlightStoreInstance } from '@plocks/spotlight'; const actions: SpotlightProps['actions'] = [ { id: 'deploy', label: 'Deploy service', description: 'Trigger the CI/CD pipeline', icon: <Icon name="bolt" />, onPress: () => console.log('deploy service'), }, { id: 'logs', label: 'Inspect logs', description: 'Open the latest runtime logs', icon: <Icon name="code" />, onPress: () => console.log('view logs'), }, { id: 'alerts', label: 'Review alerts', description: 'Check active incidents', icon: <Icon name="bell" />, onPress: () => console.log('open alerts'), }, ]; export function Demo() { const [store] = useSpotlightStoreInstance(); return ( <Block> <Button onPress={() => store.open()}>Open spotlight</Button> <Spotlight actions={actions} store={store} /> </Block> ); }

Variants

Open Spotlight as a modal, bottom sheet, or fullscreen search panel.

Loading demo…

import { Button, Column } from '@plocks/ui'; import { Spotlight, useSpotlightStoreInstance } from '@plocks/spotlight'; const actions = [{ id: 'home', label: 'Go home', icon: 'home', onPress: () => {} }]; const variants = ['modal', 'bottomsheet', 'fullscreen'] as const; function VariantPreview({ variant }: { variant: typeof variants[number] }) { const [store] = useSpotlightStoreInstance(); return ( <> <Button variant="light" onPress={() => store.open()}>Open {variant}</Button> <Spotlight variant={variant} actions={actions} store={store} /> </> ); } export function Demo() { return <Column gap="sm" align="flex-start">{variants.map(variant => <VariantPreview key={variant} variant={variant} />)}</Column>; }

Grouped Actions

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

Loading demo…

import { Block, Button } from '@plocks/ui'; import { Spotlight, type SpotlightProps, useSpotlightStoreInstance } from '@plocks/spotlight'; 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> <Button onPress={() => store.open()}>Open spotlight</Button> <Spotlight actions={actions} store={store} /> </Block> ); }

Highlight Matches

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

Loading demo…

import { Block, Button } from '@plocks/ui'; import { Spotlight, type SpotlightProps, useSpotlightStoreInstance } from '@plocks/spotlight'; 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> <Button onPress={() => store.open()}>Open spotlight</Button> <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 } from '@plocks/ui'; import { Spotlight, type SpotlightProps, useSpotlightStoreInstance } from '@plocks/spotlight'; 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> <Button onPress={() => store.open()}>Open spotlight</Button> <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 { Block, Button } from '@plocks/ui'; import { Spotlight, type SpotlightProps, useSpotlightStoreInstance } from '@plocks/spotlight'; 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(); return ( <Block> <Button onPress={() => store.open()}>Open spotlight</Button> <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, Row } from '@plocks/ui'; import { spotlight, Spotlight, SpotlightProvider, type SpotlightProps, useSpotlightStoreInstance } from '@plocks/spotlight'; 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> <Row gap="sm" wrap="wrap"> <Button onPress={() => store.open()}>Open scoped store</Button> <Button variant="outline" onPress={() => spotlight.toggle()}> Toggle global spotlight </Button> </Row> <Spotlight actions={actions} store={store} /> <Spotlight actions={globalActions} /> </Block> </SpotlightProvider> ); }
Scan to open this page on your phoneplocks.dev/spotlight/Spotlight