Command Palette
Relevant source files
The following files were used as context for generating this wiki page:
The Command Palette is a central navigation and action hub within Augenblick, accessible via the ⌘K keyboard shortcut. It provides a searchable interface that allows users to execute application commands and jump directly to specific notes. By consolidating functionality into a single modal interface, it enables a keyboard-centric workflow for managing notes, settings, and file operations.
The system is built using the cmdk primitive, styled with Tailwind CSS, and integrated into the React application shell. It distinguishes between global application commands (like "New note" or "Save") and dynamic content search (filtering through active notes).
Sources: src/features/command/CommandPalette.tsx:37-45, plans/migration.inventory.md:195-201, src/App.tsx:431-443
Architecture and Components
The Command Palette architecture consists of a UI layer built on top of Radix UI and cmdk, a logic layer for command definition, and an integration layer within the main App component.
UI Components
The visual structure is defined in a set of reusable UI components that wrap the cmdk primitives.
| Component | Description |
|---|---|
CommandDialog | A modal wrapper that renders the palette at the top third of the screen. |
CommandInput | A search field with a built-in search icon and custom styling. |
CommandList | A scrollable container for result items with a maximum height of 72 units. |
CommandGroup | Categorizes items into "Commands" and "Notes" sections. |
CommandItem | Represents an executable action or a note link. Supports keyboard selection. |
CommandShortcut | Displays keyboard hints (e.g., ⌘N) aligned to the right of the item label. |
Sources: src/components/ui/command.tsx:11-137, src/features/command/CommandPalette.tsx:156-193
Data Flow and State Management
The Command Palette is toggled via the showCommandPalette state in the main App component. When active, it receives a list of active notes as props and a set of callback functions (actions) defined in the application's routing logic.
The diagram shows the flow from user input to state execution and subsequent modal closure.
Sources: src/App.tsx:37-39, src/App.tsx:431-443, src/features/command/CommandPalette.tsx:13-33
Command Definitions
Commands are defined as a memoized array of CommandItemDef objects. Each definition includes metadata for searching (keywords), visual representation (icons), and execution logic.
Standard Application Commands
The following commands are available by default:
| Command | Shortcut | Keywords | Action |
|---|---|---|---|
| New note | ⌘N | new, note | Creates a new draft note. |
| Pin / Unpin | ⌘P | pin, unpin | Toggles pin status of the current note. |
| Save | ⌘S | save | Saves the current note to disk. |
| Save As… | ⇧⌘S | save, as | Saves note with a new file path. |
| Open… | ⌘O | open, import | Imports a Markdown file. |
| Settings | ⌘, | settings | Opens the application settings dialog. |
| Trash | Delete | trash, close | Moves the current note to trash. |
Sources: src/features/command/CommandPalette.tsx:55-117
Dynamic Note Search
The palette iterates through the notes array passed from the NotesStore. Notes are searchable by their title and preview text. Each note item displays its storage status ("Draft" or "Saved") as a shortcut label for visual context.
Sources: src/features/command/CommandPalette.tsx:180-193, src/test/features/CommandPalette.test.tsx:75-76
Implementation Details
Focus Management
Upon mounting, the Command Palette uses a setTimeout with a 0ms delay to shift focus to the CommandInput element. This ensures that the user can start typing immediately after pressing ⌘K.
// src/features/command/CommandPalette.tsx:119-123
useEffect(() => {
const id = window.setTimeout(() => {
inputRef.current?.focus();
}, 0);
return () => window.clearTimeout(id);
}, []);
Sources: src/features/command/CommandPalette.tsx:119-124
Selection Logic
The CommandItem component uses the onSelect event to trigger the associated action. When a command is selected, the palette executes the specific callback (e.g., onNewNote()) and then immediately calls the onClose() handler to dismiss the modal.
This sequence ensures that actions are executed cleanly before the UI state is reset.
Sources: src/features/command/CommandPalette.tsx:126-130, src/test/features/CommandPalette.test.tsx:88-92
Summary
The Command Palette serves as the primary navigation interface for power users in Augenblick. It leverages the cmdk library to provide a fast, filtered search experience across both application functionality and user content. Its integration with the global hotkey system and the centralized App state allows it to act as a reactive bridge between the user's intent and the underlying backend commands handled by Tauri and the SQLite database.
Sources: src/features/command/CommandPalette.tsx src/components/ui/command.tsx plans/migration.inventory.md Assistant:
Relevant source files
The following files were used as context for generating this wiki page:
The Command Palette is a central navigation and action hub within Augenblick, providing users with a keyboard-centric interface to execute application commands and search for specific notes. Accessible via the ⌘K shortcut, it serves as a unified entry point for core features such as creating notes, managing settings, and navigating the note library.
Built using React and the cmdk primitive, the Command Palette integrates directly with the application's global state and action handlers. It presents a filtered list of results categorized into "Commands" and "Notes," allowing for rapid interaction without leaving the keyboard.
Sources: src/features/command/CommandPalette.tsx:13-35, plans/migration.inventory.md:195-201
Component Architecture
The Command Palette is implemented as a modal dialog that leverages a composition of specialized UI components. These components wrap the cmdk (Command Menu) primitives to provide a styled, consistent experience.
Core UI Components
| Component | Description |
|---|---|
CommandDialog | A modal wrapper that renders the palette at the top third of the screen using Radix UI Dialog primitives. |
CommandInput | The search field, equipped with a search icon and auto-focus logic. |
CommandList | A scrollable container for grouped results with a maximum height of 72 units. |
CommandGroup | A sectioning component used to divide "Commands" and "Notes". |
CommandItem | Individual selectable rows that represent either an action or a note. |
CommandShortcut | Displays keyboard hints (e.g., ⌘N) on the right side of command items. |
Sources: src/components/ui/command.tsx:11-137, src/features/command/CommandPalette.tsx:156-193
Logical Structure and Props
The CommandPalette component receives several callback functions and a list of active notes from the parent App component. It uses these to populate its two primary groups.
The diagram shows how data flows from the main application into the Command Palette's hierarchical structure.
Sources: src/features/command/CommandPalette.tsx:13-33, src/App.tsx:431-443
Command Definitions and Keywords
Actions within the palette are defined as CommandItemDef objects. Each definition contains metadata used by the search engine to match user queries.
Standard Commands
The following static commands are hardcoded within the memoized commands array:
| Label | Icon | Shortcut | Keywords |
|---|---|---|---|
| New note | file-text | ⌘N | new, note |
| Pin / Unpin | pin | ⌘P | pin, unpin |
| Save | save | ⌘S | save |
| Save As… | save | ⇧⌘S | save, as |
| Open… | folder-open | ⌘O | open, import, markdown, md |
| Settings | settings | ⌘, | settings, preferences |
| Trash | trash | Delete | trash, close |
Sources: src/features/command/CommandPalette.tsx:55-117
Search and Filtering Logic
The palette utilizes the built-in filtering of cmdk. For each CommandItem, a keywords array is provided:
- Commands: Matches against the label and specific action-related keywords.
- Notes: Matches against the note
titleandpreviewtext.
Sources: src/features/command/CommandPalette.tsx:165-191
Interaction Flow
The Command Palette manages its own open state and ensures that focus is correctly trapped and handled.
Sequence of Operation
When the user triggers the palette, a specific sequence occurs to prepare the interface:
This sequence demonstrates the lifecycle of the palette from invocation to execution.
Sources: src/features/command/CommandPalette.tsx:119-124, src/App.tsx:431-443, src/test/features/CommandPalette.test.tsx:88-92
Implementation Snippet: Focus Logic
The component uses a useEffect with a timeout to ensure the input field is focused after the dialog animation begins.
// src/features/command/CommandPalette.tsx:119-123
useEffect(() => {
const id = window.setTimeout(() => {
inputRef.current?.focus();
}, 0);
return () => window.clearTimeout(id);
}, []);
Sources: src/features/command/CommandPalette.tsx:119-124
Summary
The Command Palette is a high-efficiency interface component that centralizes Augenblick's functionality. By combining static application commands with dynamic content searching of the user's note library, it provides a powerful tool for navigation and note management. It relies on the cmdk library for robust filtering and Radix UI for accessible modal behavior, ensuring a seamless experience within the React-based frontend.
Sources: src/features/command/CommandPalette.tsx, src/components/ui/command.tsx, plans/migration.inventory.md