Please use Desktop to view and interact with components
Components200mseaseInOut
Command Palette
Command palette with search and keyboard navigation
commandsearchkeyboardshortcutsshadcn
Useto navigate between components
Preview
This component requires shadcn/ui
This component uses shadcn/ui components. Make sure you have shadcn/ui set up in your project.
- Install shadcn/ui:
npx shadcn-ui@latest init - Install required components based on the imports in the code (e.g.,
npx shadcn-ui@latest add button) - Ensure your
tailwind.config.tsandglobals.cssare configured as per shadcn/ui documentation
Code
TypeScript + React
'use client'
import { useState } from 'react'
import { motion, AnimatePresence } from 'framer-motion'
import { Search, File, Settings, User, X } from 'lucide-react'
const commands = [
{ icon: File, label: 'New File', shortcut: '⌘N' },
{ icon: Settings, label: 'Settings', shortcut: '⌘,' },
{ icon: User, label: 'Profile', shortcut: '⌘P' },
{ icon: Search, label: 'Search', shortcut: '⌘K' },
]
export function CommandPalette() {
const [isOpen, setIsOpen] = useState(false)
const [query, setQuery] = useState('')
const filteredCommands = commands.filter((cmd) =>
cmd.label.toLowerCase().includes(query.toLowerCase())
)
return (
<div>
<motion.button
onClick={() => setIsOpen(true)}
className="flex items-center gap-2 rounded-lg border bg-[var(--card-bg)] px-4 py-2 text-sm text-[var(--foreground)]/60"
whileHover={{ scale: 1.02 }}
whileTap={{ scale: 0.98 }}
>
<Search className="h-4 w-4" />
<span>Search commands...</span>
<kbd className="ml-auto rounded bg-[var(--foreground)]/10 px-2 py-0.5 text-xs">⌘K</kbd>
</motion.button>
<AnimatePresence>
{isOpen && (
<>
<motion.div
initial={{ opacity: 0 }}
animate={{ opacity: 1 }}
exit={{ opacity: 0 }}
className="fixed inset-0 z-50 bg-black/50"
onClick={() => setIsOpen(false)}
/>
<div className="fixed inset-0 z-50 flex items-start justify-center pt-20">
<motion.div
initial={{ opacity: 0, scale: 0.95, y: 20 }}
animate={{ opacity: 1, scale: 1, y: 0 }}
exit={{ opacity: 0, scale: 0.95, y: 20 }}
className="w-full bg-card max-w-lg rounded-2xl border bg-[var(--card-bg)] shadow-2xl"
onClick={(e) => e.stopPropagation()}
>
<div className="flex items-center gap-3 border-b p-4">
<Search className="h-5 w-5 text-[var(--foreground)]/60" />
<input
type="text"
value={query}
onChange={(e) => setQuery(e.target.value)}
placeholder="Type a command..."
className="flex-1 bg-transparent text-sm outline-none"
autoFocus
/>
<motion.button
onClick={() => setIsOpen(false)}
whileHover={{ scale: 1.1 }}
whileTap={{ scale: 0.9 }}
>
<X className="h-5 w-5" />
</motion.button>
</div>
<div className="max-h-96 overflow-y-auto p-2">
{filteredCommands.map((cmd, index) => {
const Icon = cmd.icon
return (
<motion.button
key={cmd.label}
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: index * 0.05 }}
className="flex w-full items-center justify-between rounded-lg px-4 py-3 text-left text-sm hover:bg-accent/10"
whileHover={{ x: 4 }}
>
<div className="flex items-center gap-3">
<Icon className="h-4 w-4" />
<span>{cmd.label}</span>
</div>
<kbd className="rounded bg-[var(--foreground)]/10 px-2 py-0.5 text-xs">
{cmd.shortcut}
</kbd>
</motion.button>
)
})}
</div>
</motion.div>
</div>
</>
)}
</AnimatePresence>
</div>
)
}
How to Use
- 1Install Framer Motion:
npm install framer-motion - 2Set up shadcn/ui: Install shadcn/ui components used in this code. Check the imports in the code above and install the required components (e.g.,
npx shadcn-ui@latest add button card) - 3Copy the code from above
- 4Paste it into your project and customize as needed
- 5Colors are customizable via Tailwind CSS classes. The default theme uses dark mode colors defined in your globals.css file