Skip to content
CodeAtlas UI

Navigation

Command Palette

A spotlight-style navigation overlay opened with Cmd+K or Ctrl+K from anywhere.

<script>
  import { CommandPalette } from "@codeatlasdev/ui";
  import { goto } from "$app/navigation";
  let open = $state(false);
</script>

<CommandPalette modules={NAV} onNavigate={(path) => goto(path)} bind:open />

The palette searches the same NavModule[] you pass to AppShellLayout. It registers Cmd+K and Ctrl+K itself, so mount it once near the root. Results are a listbox: arrow keys move the selection, Enter confirms and Escape closes.

Open the palette

Click the button or press Cmd+K / Ctrl+K while this page is focused. Picking an item shows its path instead of navigating.

⌘K
Code
svelte
<script lang="ts">
  import { CommandPalette, Button, Kbd, type NavModule } from '@codeatlasdev/ui';
  import { Keyboard, Home, Users, Settings, BarChart3, FileText, CreditCard } from '@lucide/svelte';

  let open = $state(false);
  let picked = $state('');

  const modules: NavModule[] = [
    {
      id: 'app',
      label: 'App',
      icon: Home,
      basePath: '/app',
      items: [
        { id: 'dashboard', label: 'Dashboard', icon: Home, path: '/app/dashboard' },
        { id: 'users', label: 'Users', icon: Users, path: '/app/users' },
        { id: 'reports', label: 'Reports', icon: BarChart3, path: '/app/reports' },
      ],
    },
    {
      id: 'account',
      label: 'Account',
      icon: Settings,
      basePath: '/account',
      items: [
        { id: 'settings', label: 'Settings', icon: Settings, path: '/account/settings' },
        { id: 'billing', label: 'Billing', icon: CreditCard, path: '/account/billing' },
        { id: 'docs', label: 'Documentation', icon: FileText, path: '/account/docs' },
      ],
    },
  ];
</script>

<CommandPalette {modules} onNavigate={(path) => (picked = path)} bind:open />

<Button variant="filled" onclick={() => (open = true)}>
  {#snippet leading()}<Keyboard size={16} />{/snippet}
  Open command palette
</Button>
<Kbd>⌘K</Kbd>
{#if picked}<span class="picked" aria-live="polite">Selected: <code>{picked}</code></span>{/if}

<style>
  .picked { font-size: var(--ca-font-size-body2); color: var(--ca-text-secondary); }
  .picked code { font-family: var(--ca-font-mono); color: var(--ca-brand-text); }
</style>

Keyboard

Type to filter across every module. Queries shorter than minQueryLength keep the full grouped list.

  • TypeFilter by label or module name
  • ↑ ↓Move through the results
  • ↵Navigate to the selected item
  • ESCClose the palette
Code
svelte
<script lang="ts">
  import { Kbd } from '@codeatlasdev/ui';

  const keys = [
    { key: 'Type', desc: 'Filter by label or module name' },
    { key: '↑ ↓', desc: 'Move through the results' },
    { key: '↵', desc: 'Navigate to the selected item' },
    { key: 'ESC', desc: 'Close the palette' },
  ];
</script>

<ul class="list">
  {#each keys as k}
    <li><Kbd>{k.key}</Kbd><span>{k.desc}</span></li>
  {/each}
</ul>

<style>
  .list { list-style: none; margin: 0; padding: 0; display: grid; gap: 4px; width: 100%; max-width: 480px; }
  li { display: flex; align-items: center; gap: 16px; padding: 8px 4px; }
  span { font-size: var(--ca-font-size-body2); color: var(--ca-text-secondary); }
</style>

Props

PropTypeDefaultDescription
modulesNavModule[]–Navigation tree to search. Same format as AppShellLayout.
onNavigate(path: string) => void–Called with the selected item's path. Use goto() in SvelteKit or location in static sites.
openbooleanfalseBindable. Controls visibility. Cmd+K and Ctrl+K also toggle it.
minQueryLengthnumber1Trimmed characters needed before the list is filtered. Shorter queries keep the full grouped list.