Hone logo
Hone
Problems

React Command Palette Implementation

A command palette is a powerful UI element that allows users to quickly access various actions and features within an application using keyboard shortcuts. This challenge asks you to build a basic command palette component in React using TypeScript, enabling users to trigger actions by typing commands. This is a common feature in many modern applications, improving user efficiency and discoverability.

Problem Description

You are tasked with creating a React component that implements a simple command palette. The component should:

  1. Display a Search Input: A text input field where the user can type commands.
  2. Display Command Suggestions: As the user types, display a list of suggested commands based on the input. These suggestions should be rendered as clickable items.
  3. Execute Commands: When a user selects a command (either by clicking a suggestion or pressing Enter), execute the corresponding action.
  4. Toggle Visibility: The command palette should be initially hidden. A keyboard shortcut (e.g., Ctrl/Cmd + K) should toggle the visibility of the palette.
  5. Clear Input: After a command is executed or a suggestion is selected, the input field should be cleared.

Key Requirements:

  • The component must be written in TypeScript.
  • The component should be reusable and configurable (e.g., allow passing in a list of commands and their corresponding actions).
  • The component should handle keyboard input gracefully.
  • The component should be visually appealing and user-friendly.

Expected Behavior:

  • When the keyboard shortcut is pressed, the command palette should appear, and the input field should receive focus.
  • As the user types, the list of suggestions should update dynamically, filtering the available commands.
  • Clicking a suggestion or pressing Enter should execute the associated action and close the palette.
  • If no matching suggestions are found, an empty state should be displayed.
  • The palette should disappear when the keyboard shortcut is pressed again or when the user clicks outside the palette.

Edge Cases to Consider:

  • Empty command list.
  • No matching commands for the input.
  • Keyboard shortcut conflicts with other application shortcuts.
  • Handling of special characters in the input.
  • Performance with a large number of commands.

Examples

Example 1:

Input: commands = [{ label: "New File", action: () => alert("Creating new file") }, { label: "Open File", action: () => alert("Opening file") }], shortcut = "Ctrl+K"
Output: A command palette appears when "Ctrl+K" is pressed, displaying "New File" and "Open File" as suggestions. Selecting "New File" triggers the alert "Creating new file" and closes the palette.
Explanation: The component correctly displays the commands and executes the associated action upon selection.

Example 2:

Input: commands = [{ label: "Settings", action: () => alert("Opening settings") }], shortcut = "Cmd+K"
Output: A command palette appears when "Cmd+K" is pressed, displaying "Settings" as a suggestion. Typing "set" filters the suggestions to only show "Settings". Selecting "Settings" triggers the alert "Opening settings" and closes the palette.
Explanation: The component correctly filters the commands based on the input and executes the action.

Example 3:

Input: commands = [], shortcut = "Ctrl+K"
Output: A command palette appears when "Ctrl+K" is pressed, but the suggestion list is empty.
Explanation: The component handles the edge case of an empty command list gracefully.

Constraints

  • The component should be implemented using functional components and React hooks.
  • The component should be reasonably performant, even with a command list of up to 100 items.
  • The keyboard shortcut should be configurable via a prop.
  • The component should not rely on external libraries for core functionality (styling is acceptable).
  • The component should be able to handle asynchronous actions (though not required for the basic implementation).

Notes

  • Consider using a state management solution (e.g., useState) to manage the visibility of the palette and the input value.
  • You can use a simple filtering algorithm to find matching commands.
  • Focus on creating a clean and well-structured component.
  • Styling is not the primary focus of this challenge, but a basic visual presentation is expected.
  • Think about how to make the component extensible and configurable for different use cases.
  • Consider using useRef to manage focus on the input field.
Loading editor...
typescript