CommandPalette

PreviousNext
Docs
react-ariaui

Preview

Loading preview…
components/ui/CommandPalette.tsx
'use client';
import {
  Autocomplete as AriaAutocomplete,
  AutocompleteProps as AriaAutocompleteProps,
  MenuProps as AriaMenuProps,
  useFilter,
  Dialog
} from 'react-aria-components';
import {Menu} from '@/registry/react-aria/ui/Menu';
import {SearchField} from '@/registry/react-aria/ui/SearchField';
import { Modal } from '@/registry/react-aria/ui/Modal';
import { useEffect } from 'react';
import './CommandPalette.css';

export interface CommandPaletteProps<T extends object> extends Omit<AriaAutocompleteProps, 'children'>, AriaMenuProps<T> {
  isOpen: boolean,
  onOpenChange: (isOpen?: boolean) => void
}

export function CommandPalette<T extends object>(props: CommandPaletteProps<T>) {
  let {isOpen, onOpenChange} = props;
  let {contains} = useFilter({sensitivity: 'base'});

  useEffect(() => {
    let isMacUA = /mac(os|intosh)/i.test(navigator.userAgent);
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'j' && (isMacUA ? e.metaKey : e.ctrlKey)) {
        e.preventDefault();
        onOpenChange(true);
      } else if (e.key === 'Escape') {
        e.preventDefault();
        onOpenChange(false);
      }
    };

    document.addEventListener('keydown', handleKeyDown);
    return () => document.removeEventListener('keydown', handleKeyDown);
  }, [onOpenChange]);

  return (
    <Modal isDismissable isOpen={isOpen} onOpenChange={onOpenChange}>
      <Dialog className="command-palette-dialog">
        <AriaAutocomplete filter={contains} {...props}>
          <SearchField
            autoFocus
            aria-label="Search commands"
            placeholder="Search commands" />
          <Menu
            {...props}
            renderEmptyState={() => 'No results found.'} />
        </AriaAutocomplete>
      </Dialog>
    </Modal>
  );
}

Installation

npx shadcn@latest add @react-aria/css-commandpalette

Usage

import { CssCommandpalette } from "@/components/ui/css-commandpalette"
<CssCommandpalette />