CommandMenu
commandmenu-1779378412752.tsx
'use client'
import { useState, useEffect, useRef } from 'react'
const items = [
{ id: 1, label: 'Browse Components', icon: '🎨', group: 'Navigation', shortcut: 'G C' },
{ id: 2, label: 'View Categories', icon: '📂', group: 'Navigation', shortcut: 'G K' },
{ id: 3, label: 'Open Documentation', icon: '📖', group: 'Navigation', shortcut: 'G D' },
{ id: 4, label: 'Go to Pricing', icon: '💳', group: 'Navigation', shortcut: 'G P' },
{ id: 5, label: 'New Component (Generate)', icon: '⚡', group: 'Actions', shortcut: '⌘ N' },
{ id: 6, label: 'Copy API Key', icon: '🔑', group: 'Actions', shortcut: '⌘ K' },
{ id: 7, label: 'Toggle Dark Mode', icon: '🌙', group: 'Preferences' },
{ id: 8, label: 'Keyboard Shortcuts', icon: '⌨️', group: 'Preferences', shortcut: '?' },
]
export default function CommandMenu() {
const [open, setOpen] = useState(false)
const [q, setQ] = useState('')
const [selected, setSelected] = useState(0)
const inputRef = useRef<HTMLInputElement>(null)
const filtered = items.filter(i => i.label.toLowerCase().includes(q.toLowerCase()))
useEffect(() => {
function handler(e: KeyboardEvent) {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') { e.preventDefault(); setOpen(o => !o) }
if (e.key === 'Escape') setOpen(false)
}
window.addEventListener('keydown', handler)
return () => window.removeEventListener('keydown', handler)
}, [])
useEffect(() => { if (open) { setQ(''); setSelected(0); setTimeout(() => inputRef.current?.focus(), 50) } }, [open])
function handleKey(e: React.KeyboardEvent) {
if (e.key === 'ArrowDown') { e.preventDefault(); setSelected(s => Math.min(s + 1, filtered.length - 1)) }
if (e.key === 'ArrowUp') { e.preventDefault(); setSelected(s => Math.max(s - 1, 0)) }
if (e.key === 'Enter') setOpen(false)
}
const groups = [...new Set(filtered.map(i => i.group))]
return (
<div style={{ padding: 48, background: '#0A0A0A', minHeight: 300, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 20 }}>
<button onClick={() => setOpen(true)} style={{
background: 'rgba(255,255,255,0.06)', border: '1px solid rgba(255,255,255,0.1)',
color: '#aaa', padding: '10px 16px', borderRadius: 8, cursor: 'pointer',
display: 'flex', alignItems: 'center', gap: 10, fontSize: 14,
}}>
<span>🔍 Search commands...</span>
<span style={{ background: 'rgba(255,255,255,0.08)', padding: '2px 8px', borderRadius: 4, fontSize: 11 }}>⌘K</span>
</button>
{open && (
<div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.7)', zIndex: 1000, display: 'flex', alignItems: 'flex-start', justifyContent: 'center', paddingTop: '15vh' }}
onClick={() => setOpen(false)}>
<div style={{ background: '#111', border: '1px solid rgba(255,255,255,0.1)', borderRadius: 14, width: 520, overflow: 'hidden', boxShadow: '0 24px 80px rgba(0,0,0,0.8)' }}
onClick={e => e.stopPropagation()}>
<div style={{ padding: '12px 16px', borderBottom: '1px solid rgba(255,255,255,0.06)', display: 'flex', gap: 10, alignItems: 'center' }}>
<span style={{ color: '#555' }}>🔍</span>
<input ref={inputRef} value={q} onChange={e => { setQ(e.target.value); setSelected(0) }}
onKeyDown={handleKey} placeholder="Search commands..."
style={{ background: 'none', border: 'none', outline: 'none', color: '#F5F5F0', fontSize: 15, flex: 1 }} />
<kbd style={{ background: 'rgba(255,255,255,0.06)', color: '#555', padding: '2px 8px', borderRadius: 4, fontSize: 11, cursor: 'pointer' }}
onClick={() => setOpen(false)}>ESC</kbd>
</div>
<div style={{ maxHeight: 320, overflowY: 'auto', padding: '8px 0' }}>
{filtered.length === 0 && (
<div style={{ padding: '20px 16px', color: '#555', textAlign: 'center', fontSize: 14 }}>No results for "{q}"</div>
)}
{groups.map(g => (
<div key={g}>
<div style={{ padding: '6px 16px 4px', color: '#444', fontSize: 11, fontWeight: 600, textTransform: 'uppercase', letterSpacing: '0.08em' }}>{g}</div>
{filtered.filter(i => i.group === g).map(item => {
const idx = filtered.indexOf(item)
return (
<div key={item.id}
onMouseEnter={() => setSelected(idx)}
onClick={() => setOpen(false)}
style={{
display: 'flex', alignItems: 'center', gap: 12, padding: '10px 16px',
cursor: 'pointer', background: idx === selected ? 'rgba(201,168,76,0.1)' : 'transparent',
borderLeft: idx === selected ? '2px solid #C9A84C' : '2px solid transparent',
transition: 'all 0.1s',
}}>
<span style={{ fontSize: 18 }}>{item.icon}</span>
<span style={{ color: '#F5F5F0', fontSize: 14, flex: 1 }}>{item.label}</span>
{item.shortcut && <kbd style={{ color: '#555', fontSize: 11, background: 'rgba(255,255,255,0.06)', padding: '2px 8px', borderRadius: 4 }}>{item.shortcut}</kbd>}
</div>
)
})}
</div>
))}
</div>
</div>
</div>
)}
</div>
)
}Component info
CategoryNavigation
Frameworkreact
TierFREE
Views0
Copies0
About
Cmd+K command palette with search, recent items, and keyboard navigation
More from Navigation
import * as React from 'react';
import * as ReactDOM from 'react-dom';
interface FloatingDockProps {
icons: { id: number; src: string; }[];
}
class FloatingDock extends React.Component<FloatingDockProps, {}> {
constructor(props: FloatingDockProFloatingDock
Navigation
'use client'
import { useState } from 'react'
const NAV = [
{ id: 'home', icon: '◉', label: 'Overview', shortcut: 'G H' },
{ id: 'components', icon: '⬡', label: 'Components', shortcut: 'G C', badge: 120, children: [
{ id: 'buttons', label: 'SidebarNav
Navigation
'use client';
import React from 'react';
interface PaginationNavProps {
currentPage: number;
totalPages: number;
onPageChange: (page: number) => void;
}
const PaginationNav: React.FC<PaginationNavProps> = ({ currentPage, totalPages, onPageChPaginationNav
Navigation
'use client';
import React, { useState } from 'react';
interface Tab {
id: number;
label: string;
}
const tabs: Tab[] = [
{ id: 1, label: 'Tab 1' },
{ id: 2, label: 'Tab 2' },
{ id: 3, label: 'Tab 3' },
{ id: 4, label: 'Tab 4' },
];
cTabsNav
Navigation