🔍 A package with components for building your dream command palette for your web application.

Last update: Jun 17, 2022

A command palette for React

A package with components for building your dream command palette for your web application.

Features

✓ Accessible
✓ Flexible
✓ Good looking
✓ Very fast
✓ Dark & light mode

Installation

npm install react-cmdk

Or if you'd rather use Yarn

yarn add react-cmdk

Example usage

You can compose your command palette pretty much however you like with the included components. But here is an example of a command palette that uses some of the included helpers for a very neat solution.

{ const [page, setPage] = useState<"root" | "projects">("root"); const [open, setOpen] = useState(true); const [search, setSearch] = useState(""); const filteredItems = filterItems( [ { heading: "Home", id: "home", items: [ { id: "home", children: "Home", icon: "HomeIcon", href: "#", }, { id: "settings", children: "Settings", icon: "CogIcon", href: "#", }, { id: "projects", children: "Projects", icon: "CollectionIcon", closeOnSelect: false, onClick: () => { setPage("projects"); }, }, ], }, { heading: "Other", id: "advanced", items: [ { id: "developer-settings", children: "Developer settings", icon: "CodeIcon", href: "#", }, { id: "privacy-policy", children: "Privacy policy", icon: "SupportIcon", href: "#", }, { id: "log-out", children: "Log out", icon: "LogoutIcon", onClick: () => { alert("Logging out..."); }, }, ], }, ], search ); return ( {filteredItems.length ? ( filteredItems.map((list) => ( {list.items.map(({ id, ...rest }) => ( ))} )) ) : ( )} {/* Projects page */} ); }; export default Example;">
import "react-cmdk/dist/cmdk.css";
import CommandPalette, { filterItems, getItemIndex } from "react-cmdk";
import { useState } from "react";

const Example = () => {
  const [page, setPage] = useState<"root" | "projects">("root");
  const [open, setOpen] = useState<boolean>(true);
  const [search, setSearch] = useState("");

  const filteredItems = filterItems(
    [
      {
        heading: "Home",
        id: "home",
        items: [
          {
            id: "home",
            children: "Home",
            icon: "HomeIcon",
            href: "#",
          },
          {
            id: "settings",
            children: "Settings",
            icon: "CogIcon",
            href: "#",
          },
          {
            id: "projects",
            children: "Projects",
            icon: "CollectionIcon",
            closeOnSelect: false,
            onClick: () => {
              setPage("projects");
            },
          },
        ],
      },
      {
        heading: "Other",
        id: "advanced",
        items: [
          {
            id: "developer-settings",
            children: "Developer settings",
            icon: "CodeIcon",
            href: "#",
          },
          {
            id: "privacy-policy",
            children: "Privacy policy",
            icon: "SupportIcon",
            href: "#",
          },
          {
            id: "log-out",
            children: "Log out",
            icon: "LogoutIcon",
            onClick: () => {
              alert("Logging out...");
            },
          },
        ],
      },
    ],
    search
  );

  return (
    <CommandPalette
      onChangeSearch={setSearch}
      onChangeOpen={setOpen}
      search={search}
      isOpen={open}
      page={page}
    >
      <CommandPalette.Page id="root">
        {filteredItems.length ? (
          filteredItems.map((list) => (
            <CommandPalette.List key={list.id} heading={list.heading}>
              {list.items.map(({ id, ...rest }) => (
                <CommandPalette.ListItem
                  key={id}
                  index={getItemIndex(filteredItems, id)}
                  {...rest}
                />
              ))}
            </CommandPalette.List>
          ))
        ) : (
          <CommandPalette.FreeSearchAction />
        )}
      </CommandPalette.Page>

      <CommandPalette.Page id="projects">
        {/* Projects page */}
      </CommandPalette.Page>
    </CommandPalette>
  );
};

export default Example;

Opening the command palelette

The package does include a helper hook for opening the command palette, but you can actually open it however you want. Here are some examples.

Helper

const [isOpen, setIsOpen] = useState<boolean>(false);

useHandleOpenCommandPalette(setOpen);

Custom

{ return !currentValue; }); } } document.addEventListener("keydown", handleKeyDown); return () => { document.removeEventListener("keydown", handleKeyDown); }; }, []);">
const [isOpen, setIsOpen] = useState<boolean>(false);

useEffect(() => {
  function handleKeyDown(e: KeyboardEvent) {
    if (e.metaKey && e.key === "k") {
      e.preventDefault();
      e.stopPropagation();

      setIsOpen((currentValue) => {
        return !currentValue;
      });
    }
  }

  document.addEventListener("keydown", handleKeyDown);

  return () => {
    document.removeEventListener("keydown", handleKeyDown);
  };
}, []);

API

CommandPalette

name type required default description
onChangeSearch (value: string) => void true Function for setting search value
onChangeOpen (value: boolean) => void true Function for setting open state
children React.ReactNode true Children of command palette
isOpen boolean true Open state
search string true Search state
placeholder string false "Search" Search field placeholder
page string false The current page id
renderLink RenderLink false Function for customizing rendering of links
footer React.ReactNode false Footer component
selected number false The current selected item index
onChangeSelected (value: number) => void false Function for setting selected item index

CommandPalette.Page

FYI. Using pages is completely optional

name type required default description
id string true A unique page id
children React.ReactNode true Children of the list
searchPrefix string[] false Prefix to the left of the search bar
onEscape () => void false Function that runs upon clicking escape

CommandPalette.List

name type required default description
children React.ReactNode true Children of the list
heading string false Heading of the list

CommandPalette.ListItem

name type required default description
index number true Index for list item
closeOnSelect boolean false Whether to close the command palette upon click
icon (IconName, React.FC) false false Icon for list item
iconType IconType false "solid" Icon for list item
showType boolean false true Whether to show the item type
disabled boolean false Whether the item is disabled
keywords Array false Underlying search keywords for the list item

The list item also extends the HTMLAnchorElement & HTMLButtonElement types

CommandPalette.FreeSearchAction

name type required default description
index number false 0 Index for list item
label string false "Search for" Button label

The search action also extends the HTMLAnchorElement & HTMLButtonElement types

RenderLink

(
  props: DetailedHTMLProps<
    AnchorHTMLAttributes<HTMLAnchorElement>,
    HTMLAnchorElement
  >
) => ReactNode;

JsonStructure

Array of

name type required default description
id string true Id for list
items Array<JsonStructureItem> true Items for list
heading string false Heading for list

JsonStructureItem

CommandPalette.ListItem

Omits index & extends

name type required default description
id string true Id for list item

Utils

getItemIndex

A function for getting the current index of a item within the json structure

(items: JsonStructure, listItemId: string, startIndex = 0) => number;

filterItems

A function for filtering the json structure from a search string

(
  items: JsonStructure,
  search: string,
  options?: { filterOnListHeading: boolean }
) => JsonStructure;

renderJsonStructure

A function for rendering a json structure

(items: JsonStructure) => JSX.Element[]

useHandleOpenCommandPalette

(fn: React.Dispatch<React.SetStateAction<boolean>>) => void

Maintainers

GitHub

https://github.com/albingroen/react-cmdk
You might also like...

my-watchlist is a web application for creating your own watchlist.

my-watchlist is a web application for creating your own watchlist.

my-watchlist is a web application for creating your own watchlist. The website tracks your created watchlist, so that you can comeback anytime and pick from where you left.

Jan 6, 2022

The react UI component for building complex filter criteria

 The react UI component for building complex filter criteria

React Filter Control The React component for building the composite filter criteria Demo (JS) | Demo (TS) Together With Data Table Overview Installati

May 22, 2022

A powerful toolkit for building websites with beautiful design

Typography.js A powerful toolkit for building websites with beautiful typography. Typography.js A powerful toolkit for building websites with beautifu

Jun 17, 2022

:fire: An extremely fast, React-like JavaScript library for building modern user interfaces

:fire: An extremely fast, React-like JavaScript library for building modern user interfaces

Inferno is an insanely fast, React-like library for building high-performance user interfaces on both the client and server. Description The main obje

Jun 25, 2022

The LinkedIn Learning course React.js: Building an Interface

The LinkedIn Learning course React.js: Building an Interface

React.js: Building an Interface This is the repository for the LinkedIn Learning course React.js: Building an Interface. The full course is available

Oct 14, 2021

Node.js library for building systematic trading strategies in reactive way.

Node.js library for building systematic trading strategies in reactive way. Use the power of TypeScript and Reactive Programming to research, develop

Dec 22, 2021

Code demo from "Building Design Systems With React" talk

Code demo from

React Button This repository is the code demo from my "Building Design Systems With React" talk I will give at ReactJS Girls London. I will link the d

May 29, 2022

Calypso is the new WordPress.com front-end – a beautiful redesign of the WordPress dashboard using a single-page web application

Calypso is the new WordPress.com front-end – a beautiful redesign of the WordPress dashboard using a single-page web application

Calypso is the new WordPress.com front-end – a beautiful redesign of the WordPress dashboard using a single-page web application, powered by the WordPress.com REST API. Calypso is built for reading, writing, and managing all of your WordPress sites in one place.

Jun 19, 2022

A web application that allows you to create and share wall of gifs! Built on top of solana blockchain.

Wall of gif with Solana A web application that allows you to create and share wall of gifs! Built on top of solana blockchain. Installation and Usage

Jan 1, 2022
Comments
  • 1. Microbundle error? No exported member

    This looks awesome. Cloned the main branch to see if I could get it to work and after yarn install and then yarn start I'm getting this error

    Can you help

    (rpt2 plugin) Error: /Users/x/workspace/react-cmdk/src/index.tsx(5,10): semantic error TS2724: Module '"../node_modules/twind/twind"' has no exported member 'tw'. Did you mean 'TW'?
    
    Reviewed by markojak at 2022-03-02 19:58
  • 2. Add support for hitting backspace to go up a page

    Changes

    • Hitting Backspace when the search field is empty will run the onEscape function on the CommandPalette.Page component now.

    Demo

    https://user-images.githubusercontent.com/19674362/175822065-263f1014-bd33-415f-bb59-91426b04d935.mp4

    Reviewed by albingroen at 2022-06-26 15:39
  • 3. Navigation to previous commands.

    Whenever a user navigates to a command with sub-commands, there's nothing to tell the user to press the Escape key to go back. I think showing some sort of help message can make the user navigate back from deep sub-commands, without trying to figure out which key to press. This is a huge problem on mobile phones

    Reviewed by lucky-chap at 2022-06-15 16:33
Quickly load Vue, React, SpriteJS components via command line

Faster way to render & interact react & vue3 components with command line interface.

Mar 9, 2022
semantic-release automates the whole package release workflow including: determining the next version number, generating the release notes, and publishing the package.
semantic-release automates the whole package release workflow including: determining the next version number, generating the release notes, and publishing the package.

?? ?? semantic-release Fully automated version management and package publishing semantic-release automates the whole package release workflow includi

Jun 19, 2022
Write down a shell command-line to see how it works in details.

shell.how Write down a shell command-line to see how it works in details. Design Stack TypeScript Next.js Tailwind CSS Recoil for state management, it

Jun 19, 2022
Trong ORM is a JavaScript library for building reactive SQLite queries for web, mobile and desktop

Trong ORM is a JavaScript library for building reactive SQLite queries for web, mobile and desktop

Jun 21, 2022
React-NFT-App - NFT-Web-Application built using Third web , ReactJs and use Crypto Punks with API

Getting Started with Create React App This project was bootstrapped with Create React App. Available Scripts In the project directory, you can run: np

Apr 25, 2022
Repo for the react-borders NPM package.

React Borders Basic Usage You can attach a border to an element using the border component exported from react-borders. The below code will generate a

Mar 11, 2022
Package library for common React functionalities.

Primors Package library for common React functionalities. Live documentation Storybook docs deployed on GH Pages: https://dagerikhl.github.io/primors

Aug 27, 2021
Firerr - A package for catching Firebase Errors that often pop in development

FirErr FirErr is a package for catching Firebase Errors that often pop in develo

Feb 28, 2022
We have updated our application over to using hooks and functional components to replace any class components we had before.
We have updated our application over to using hooks and functional components to replace any class components we had before.

Crwn hooks We have updated our application over to using hooks and functional components to replace any class components we had before. How to fork an

Feb 10, 2022
A guide to building your own React stack, explaining options and tradeoffs along the way
A guide to building your own React stack, explaining options and tradeoffs along the way

Custom React Stack React has a very rich ecosystem. For anything you want to do, there is probably a library or a framework available for it. That's g

Jun 6, 2022