← Components/Overlays

CommandPalette

commandpalette-1779354232008.tsx
'use client';

import { useState, useEffect } from 'react';

interface Command {
  id: number;
  title: string;
  description: string;
}

const commands: Command[] = [
  { id: 1, title: 'New File', description: 'Create a new file' },
  { id: 2, title: 'Open File', description: 'Open an existing file' },
  { id: 3, title: 'Save File', description: 'Save the current file' },
  { id: 4, title: 'Close File', description: 'Close the current file' },
];

const CommandPalette = () => {
  const [isOpen, setIsOpen] = useState(false);
  const [searchQuery, setSearchQuery] = useState('');
  const [selectedCommandIndex, setSelectedCommandIndex] = useState(0);
  const [filteredCommands, setFilteredCommands] = useState(commands);

  useEffect(() => {
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.metaKey && event.key === 'k') {
        setIsOpen(true);
      }
    };

    document.addEventListener('keydown', handleKeyDown);

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

  useEffect(() => {
    const filtered = commands.filter((command) =>
      command.title.toLowerCase().includes(searchQuery.toLowerCase())
    );
    setFilteredCommands(filtered);
  }, [searchQuery]);

  const handleSearchChange = (event: React.ChangeEvent<HTMLInputElement>) => {
    setSearchQuery(event.target.value);
    setSelectedCommandIndex(0);
  };

  const handleKeyDown = (event: React.KeyboardEvent<HTMLInputElement>) => {
    if (event.key === 'ArrowDown') {
      setSelectedCommandIndex(
        (selectedCommandIndex + 1) % filteredCommands.length
      );
    } else if (event.key === 'ArrowUp') {
      setSelectedCommandIndex(
        (selectedCommandIndex - 1 + filteredCommands.length) %
          filteredCommands.length
      );
    } else if (event.key === 'Enter') {
      // Handle command execution
      console.log(`Executing command: ${filteredCommands[selectedCommandIndex].title}`);
      setIsOpen(false);
    }
  };

  return (
    <div
      className={`fixed top-0 left-0 w-full h-full bg-zinc-950 transition-all duration-300 ${
        isOpen ? 'opacity-100' : 'opacity-0 pointer-events-none'
      }`}
    >
      <div
        className="absolute top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-1/2 max-w-sm bg-zinc-900 rounded-lg shadow-lg p-4"
        style={{ boxShadow: '0px 0px 10px 5px rgba(0, 0, 0, 0.5)' }}
      >
        <input
          type="search"
          placeholder="Search commands..."
          className="w-full p-2 pl-10 text-sm text-zinc-200 bg-zinc-800 rounded-lg focus:outline-none focus:ring-2 focus:ring-c9a84c"
          value={searchQuery}
          onChange={handleSearchChange}
          onKeyDown={handleKeyDown}
          autoFocus
        />
        <ul>
          {filteredCommands.map((command, index) => (
            <li
              key={command.id}
              className={`py-2 px-4 text-sm text-zinc-200 cursor-pointer ${
                index === selectedCommandIndex
                  ? 'bg-zinc-800'
                  : 'hover:bg-zinc-700'
              }`}
            >
              <span className="text-c9a84c">{command.title}</span>
              <span className="text-zinc-500 ml-2">{command.description}</span>
            </li>
          ))}
        </ul>
      </div>
    </div>
  );
};

export default CommandPalette;

Component info

CategoryOverlays
Frameworkreact
TierFREE
Views0
Copies0

About

Cmd+K command palette search modal

More from Overlays

import React, { useState } from 'react';
import './SlideDrawer.css';

interface SlideDrawerProps {
  isOpen: boolean;
  onClose: () => void;
  children: React.ReactNode;
}

const SlideDrawer: React.FC<SlideDrawerProps> = ({ isOpen, onClose, children 
SlideDrawer
Overlays
import React, { useState } from 'react';

interface ContextMenuProps {
  children: React.ReactNode;
}

const ContextMenu: React.FC<ContextMenuProps> = ({ children }) => {
  const [showMenu, setShowMenu] = useState(false);
  const [x, setX] = useState
ContextMenu
Overlays
'use client';

import React, { useState } from 'react';

interface AlertDialogProps {
  isOpen: boolean;
  onClose: () => void;
  onConfirm: () => void;
  title: string;
  description: string;
}

const AlertDialog: React.FC<AlertDialogProps> = ({
  i
AlertDialog
Overlays
'use client';

import React, { useState } from 'react';

interface TooltipProps {
  children: React.ReactNode;
  content: string;
  direction?: 'top' | 'bottom' | 'left' | 'right';
}

const Tooltip: React.FC<TooltipProps> = ({ children, content, dire
Tooltip
Overlays