Master CMDK command palette patterns for Google Antigravity IDE keyboard-first interfaces
# CMDK Command Palette Patterns for Google Antigravity IDE
Build keyboard-first interfaces with CMDK using Google Antigravity IDE. This guide covers command menus, search patterns, and integration with React.
## Basic Command Menu
```typescript
// src/components/CommandMenu.tsx
"use client";
import { useEffect, useState, useCallback } from "react";
import { Command } from "cmdk";
import { useRouter } from "next/navigation";
import { Search, FileText, Settings, User, LogOut, Moon, Sun, Home, Folder } from "lucide-react";
import { useTheme } from "next-themes";
interface CommandItem {
id: string;
label: string;
icon: React.ReactNode;
shortcut?: string;
action: () => void;
group: string;
}
export function CommandMenu() {
const [open, setOpen] = useState(false);
const [search, setSearch] = useState("");
const router = useRouter();
const { setTheme, theme } = useTheme();
useEffect(() => {
const down = (e: KeyboardEvent) => {
if (e.key === "k" && (e.metaKey || e.ctrlKey)) {
e.preventDefault();
setOpen((open) => !open);
}
};
document.addEventListener("keydown", down);
return () => document.removeEventListener("keydown", down);
}, []);
const runCommand = useCallback((command: () => void) => {
setOpen(false);
command();
}, []);
const commands: CommandItem[] = [
{ id: "home", label: "Go to Home", icon: <Home className="h-4 w-4" />, action: () => router.push("/"), group: "Navigation" },
{ id: "dashboard", label: "Go to Dashboard", icon: <Folder className="h-4 w-4" />, shortcut: "G D", action: () => router.push("/dashboard"), group: "Navigation" },
{ id: "settings", label: "Open Settings", icon: <Settings className="h-4 w-4" />, shortcut: "G S", action: () => router.push("/settings"), group: "Navigation" },
{ id: "profile", label: "View Profile", icon: <User className="h-4 w-4" />, action: () => router.push("/profile"), group: "Navigation" },
{ id: "theme-light", label: "Light Mode", icon: <Sun className="h-4 w-4" />, action: () => setTheme("light"), group: "Theme" },
{ id: "theme-dark", label: "Dark Mode", icon: <Moon className="h-4 w-4" />, action: () => setTheme("dark"), group: "Theme" },
{ id: "logout", label: "Log Out", icon: <LogOut className="h-4 w-4" />, action: () => signOut(), group: "Account" },
];
const groups = [...new Set(commands.map((c) => c.group))];
return (
<Command.Dialog
open={open}
onOpenChange={setOpen}
label="Command Menu"
className="fixed inset-0 z-50"
>
<div className="fixed inset-0 bg-black/50" onClick={() => setOpen(false)} />
<div className="fixed left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-lg bg-background rounded-lg shadow-2xl border">
<Command.Input
value={search}
onValueChange={setSearch}
placeholder="Type a command or search..."
className="w-full px-4 py-3 border-b text-base outline-none"
/>
<Command.List className="max-h-80 overflow-y-auto p-2">
<Command.Empty className="py-6 text-center text-sm text-muted-foreground">
No results found.
</Command.Empty>
{groups.map((group) => (
<Command.Group key={group} heading={group} className="px-2 py-1.5 text-xs font-semibold text-muted-foreground">
{commands
.filter((c) => c.group === group)
.map((command) => (
<Command.Item
key={command.id}
value={command.label}
onSelect={() => runCommand(command.action)}
className="flex items-center gap-2 px-2 py-1.5 rounded-sm cursor-pointer aria-selected:bg-accent"
>
{command.icon}
<span className="flex-1">{command.label}</span>
{command.shortcut && (
<kbd className="px-1.5 py-0.5 text-xs bg-muted rounded">{command.shortcut}</kbd>
)}
</Command.Item>
))}
</Command.Group>
))}
</Command.List>
</div>
</Command.Dialog>
);
}
```
## Search with Results
```typescript
// src/components/SearchCommand.tsx
"use client";
import { Command } from "cmdk";
import { useState, useEffect } from "react";
import { useDebounce } from "@/hooks/useDebounce";
interface SearchResult {
id: string;
title: string;
description: string;
type: "page" | "post" | "user";
url: string;
}
export function SearchCommand() {
const [search, setSearch] = useState("");
const [results, setResults] = useState<SearchResult[]>([]);
const [loading, setLoading] = useState(false);
const debouncedSearch = useDebounce(search, 300);
useEffect(() => {
if (!debouncedSearch) {
setResults([]);
return;
}
setLoading(true);
fetch("/api/search?q=" + encodeURIComponent(debouncedSearch))
.then((res) => res.json())
.then((data) => setResults(data.results))
.finally(() => setLoading(false));
}, [debouncedSearch]);
return (
<Command className="rounded-lg border shadow-md">
<Command.Input
value={search}
onValueChange={setSearch}
placeholder="Search..."
className="w-full px-4 py-3 border-b outline-none"
/>
<Command.List className="max-h-80 overflow-y-auto p-2">
{loading && <Command.Loading>Searching...</Command.Loading>}
<Command.Empty>No results found.</Command.Empty>
{results.map((result) => (
<Command.Item
key={result.id}
value={result.title}
onSelect={() => (window.location.href = result.url)}
className="flex flex-col gap-1 px-2 py-2 rounded-sm cursor-pointer aria-selected:bg-accent"
>
<span className="font-medium">{result.title}</span>
<span className="text-sm text-muted-foreground">{result.description}</span>
</Command.Item>
))}
</Command.List>
</Command>
);
}
```
## Best Practices for Google Antigravity IDE
When using CMDK with Google Antigravity, group commands logically. Add keyboard shortcuts for common actions. Implement search with debouncing. Use proper ARIA labels. Let Gemini 3 generate command items from your routes.
Google Antigravity excels at building command palettes with CMDK.This CMDK prompt is ideal for developers working on:
By using this prompt, you can save hours of manual coding and ensure best practices are followed from the start. It's particularly valuable for teams looking to maintain consistency across their cmdk implementations.
Yes! All prompts on Antigravity AI Directory are free to use for both personal and commercial projects. No attribution required, though it's always appreciated.
This prompt works excellently with Claude, ChatGPT, Cursor, GitHub Copilot, and other modern AI coding assistants. For best results, use models with large context windows.
You can modify the prompt by adding specific requirements, constraints, or preferences. For CMDK projects, consider mentioning your framework version, coding style, and any specific libraries you're using.