Back to Sentry

CommandPalette JSX API

static/app/components/commandPalette/useCommandPaletteActions.mdx

26.4.23.4 KB
Original Source

import {Fragment} from 'react';

import {Button} from '@sentry/scraps/button'; import {Flex, Stack} from '@sentry/scraps/layout';

import {addSuccessMessage} from 'sentry/actionCreators/indicator'; import {toggleCommandPalette} from 'sentry/actionCreators/modal';

import * as Storybook from 'sentry/stories';

import {CommandPaletteDemo} from './stories/components';

Basic Usage

Use CMDKAction JSX components inside your page or feature component to register contextual actions with the global command palette. Actions are registered on mount and automatically unregistered on unmount, so they only appear in the palette while your component is rendered. This is ideal for page‑specific shortcuts.

Wrap your tree in CommandPaletteProvider and place the CommandPalette UI component wherever you want the dialog to render. Then declare actions anywhere inside the provider:

  • Navigation actions: Provide a to prop to navigate when selected.
  • Callback actions: Provide an onAction handler to execute when selected.
  • Grouped actions: Nest CMDKAction children inside another CMDKAction to show a second level. Selecting the parent reveals its children.
  • Async actions: Provide a resource prop and use the render-prop children signature to fetch and populate async results.

<Storybook.Demo> <Flex width="100%"> <CommandPaletteDemo /> </Flex> </Storybook.Demo>

tsx
import {addSuccessMessage} from 'sentry/actionCreators/indicator';
import {
  CMDKAction,
  CommandPaletteProvider,
} from 'sentry/components/commandPalette/ui/cmdk';
import {CommandPalette} from 'sentry/components/commandPalette/ui/commandPalette';

function YourComponent() {
  return (
    <CommandPaletteProvider>
      <CMDKAction display={{label: 'Go to Flex story'}} to="/stories/layout/flex/" />
      <CMDKAction
        display={{label: 'Execute an action'}}
        onAction={() => addSuccessMessage('Action executed')}
      />
      <CMDKAction display={{label: 'Parent action'}}>
        <CMDKAction
          display={{label: 'Child action'}}
          onAction={() => addSuccessMessage('Child action executed')}
        />
      </CMDKAction>
      <CMDKAction display={{label: 'Issues List'}}>
        <CMDKAction
          display={{label: 'Select all'}}
          onAction={() => addSuccessMessage('Select all')}
        />
        <CMDKAction
          display={{label: 'Deselect all'}}
          onAction={() => addSuccessMessage('Deselect all')}
        />
      </CMDKAction>
      <CommandPalette />
    </CommandPaletteProvider>
  );
}

Async / Resource Actions

CMDKAction accepts a resource prop — a function that takes the current search query and returns a TanStack Query options object. The children prop becomes a render function that receives the fetched results:

tsx
import type {CommandPaletteAsyncResult} from 'sentry/components/commandPalette/types';

<CMDKAction
  display={{label: 'Projects'}}
  resource={query => ({
    queryKey: ['/projects/', {query}],
    queryFn: () => fetchProjects(query),
    // transform response into CommandPaletteAsyncResult[]
    select: (data): CommandPaletteAsyncResult[] =>
      data.map(p => ({
        display: {label: p.name},
        to: `/projects/${p.slug}/`,
      })),
  })}
>
  {(results: CommandPaletteAsyncResult[]) =>
    results.map(r => (
      <CMDKAction key={'label' in r.display ? r.display.label : ''} {...r} />
    ))
  }
</CMDKAction>;