import { Component, OnInit, OnDestroy, ViewChild, inject } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Router } from '@angular/router';
import { FontAwesomeModule } from '@fortawesome/angular-fontawesome';
import {
faHome,
faCog,
faUser,
faSearch,
faFile,
faEdit,
faEye,
faTools,
faQuestion,
faPlus,
faSave,
faCopy,
faPaste,
faUndo,
faRedo,
faKeyboard,
faPalette,
faRocket
} from '@fortawesome/free-solid-svg-icons';
import { Command, CommandCategory, CommandExecutionContext, CommandPaletteComponent, CommandPaletteService, createShortcuts, GlobalKeyboardDirective } from '../../../../../ui-essentials/src/lib/components/overlays/command-palette';
@Component({
selector: 'ui-command-palette-demo',
standalone: true,
imports: [
CommonModule,
FontAwesomeModule,
CommandPaletteComponent,
GlobalKeyboardDirective
],
template: `
Quick Start
Features
Keyboard Navigation
Full keyboard support with arrow keys, Enter, and Escape
Fuzzy Search
Intelligent search with typo tolerance and keyword matching
Quick Actions
Execute commands instantly with global keyboard shortcuts
Categorization
Organize commands by category for better discoverability
Recent Commands
Track and show recently used commands for quick access
Context Aware
Commands can be shown or hidden based on application state
Usage Statistics
{{ registeredCommandsCount }}
Registered Commands
{{ recentCommandsCount }}
Recent Commands
{{ executionCount }}
Commands Executed
Keyboard Shortcuts
Ctrl + K
Open Command Palette
↑ / ↓
Navigate Results
Enter
Execute Selected Command
Esc
Close Palette
Tab
Navigate Results (Alternative)
/
Quick Search
`,
styleUrl: './command-palette-demo.component.scss'
})
export class CommandPaletteDemoComponent implements OnInit, OnDestroy {
@ViewChild('commandPalette') commandPalette!: CommandPaletteComponent;
private router = inject(Router);
private commandService = inject(CommandPaletteService);
// Icons
readonly faPalette = faPalette;
readonly faKeyboard = faKeyboard;
readonly faPlus = faPlus;
readonly faSearch = faSearch;
readonly faRocket = faRocket;
readonly faCog = faCog;
readonly faCopy = faCopy;
readonly faEye = faEye;
readonly faHome = faHome;
readonly faUser = faUser;
readonly faFile = faFile;
readonly faEdit = faEdit;
readonly faTools = faTools;
readonly faQuestion = faQuestion;
readonly faSave = faSave;
readonly faUndo = faUndo;
readonly faRedo = faRedo;
readonly faPaste = faPaste;
// Component state
paletteSize: 'md' | 'lg' | 'xl' = 'lg';
executionCount = 0;
config = {
showCategories: true,
showShortcuts: true,
showRecent: true,
maxResults: 20,
recentLimit: 5
};
globalShortcuts = [
createShortcuts().commandPalette(),
createShortcuts().quickSearch(),
createShortcuts().create('/', { preventDefault: true })
];
get registeredCommandsCount(): number {
return this.commandService.commands().length;
}
get recentCommandsCount(): number {
return this.commandService.recentCommands().length;
}
ngOnInit(): void {
this.registerSampleCommands();
this.applyConfig();
}
ngOnDestroy(): void {
// Clean up registered commands
this.commandService.clearCommands();
}
openCommandPalette(): void {
this.commandPalette.open();
}
handleGlobalShortcut(event: any): void {
const shortcut = event.shortcut;
if (shortcut.key === 'k' && (shortcut.ctrlKey || shortcut.metaKey)) {
this.commandPalette.toggle();
} else if (shortcut.key === '/') {
this.commandPalette.open();
}
}
registerSampleCommands(): void {
const sampleCommands: Command[] = [
// Navigation Commands
{
id: 'nav-home',
title: 'Go Home',
description: 'Navigate to the home page',
icon: faHome,
category: CommandCategory.NAVIGATION,
keywords: ['home', 'dashboard', 'main'],
shortcut: ['Ctrl', 'H'],
handler: () => this.showToast('Navigating to home...'),
order: 1
},
{
id: 'nav-profile',
title: 'View Profile',
description: 'Go to user profile page',
icon: faUser,
category: CommandCategory.NAVIGATION,
keywords: ['profile', 'user', 'account'],
handler: () => this.showToast('Opening profile...'),
order: 2
},
{
id: 'nav-settings',
title: 'Open Settings',
description: 'Access application settings',
icon: faCog,
category: CommandCategory.SETTINGS,
keywords: ['settings', 'preferences', 'config'],
shortcut: ['Ctrl', ','],
handler: () => this.showToast('Opening settings...'),
order: 1
},
// File Commands
{
id: 'file-new',
title: 'New File',
description: 'Create a new file',
icon: faFile,
category: CommandCategory.FILE,
keywords: ['new', 'create', 'file', 'document'],
shortcut: ['Ctrl', 'N'],
handler: () => this.showToast('Creating new file...'),
order: 1
},
{
id: 'file-save',
title: 'Save File',
description: 'Save the current file',
icon: faSave,
category: CommandCategory.FILE,
keywords: ['save', 'file', 'document'],
shortcut: ['Ctrl', 'S'],
handler: () => this.showToast('Saving file...'),
order: 2
},
// Edit Commands
{
id: 'edit-copy',
title: 'Copy',
description: 'Copy selected content',
icon: faCopy,
category: CommandCategory.EDIT,
keywords: ['copy', 'clipboard'],
shortcut: ['Ctrl', 'C'],
handler: () => this.showToast('Content copied!'),
order: 1
},
{
id: 'edit-paste',
title: 'Paste',
description: 'Paste from clipboard',
icon: faPaste,
category: CommandCategory.EDIT,
keywords: ['paste', 'clipboard'],
shortcut: ['Ctrl', 'V'],
handler: () => this.showToast('Content pasted!'),
order: 2
},
{
id: 'edit-undo',
title: 'Undo',
description: 'Undo last action',
icon: faUndo,
category: CommandCategory.EDIT,
keywords: ['undo', 'revert'],
shortcut: ['Ctrl', 'Z'],
handler: () => this.showToast('Action undone!'),
order: 3
},
{
id: 'edit-redo',
title: 'Redo',
description: 'Redo last undone action',
icon: faRedo,
category: CommandCategory.EDIT,
keywords: ['redo', 'repeat'],
shortcut: ['Ctrl', 'Y'],
handler: () => this.showToast('Action redone!'),
order: 4
},
// Search Commands
{
id: 'search-global',
title: 'Global Search',
description: 'Search across all content',
icon: faSearch,
category: CommandCategory.SEARCH,
keywords: ['search', 'find', 'global'],
shortcut: ['Ctrl', 'Shift', 'F'],
handler: () => this.showToast('Opening global search...'),
order: 1
},
// Tools Commands
{
id: 'tools-theme',
title: 'Toggle Theme',
description: 'Switch between light and dark theme',
icon: faTools,
category: CommandCategory.TOOLS,
keywords: ['theme', 'dark', 'light', 'toggle'],
handler: () => this.showToast('Theme toggled!'),
order: 1
},
// Help Commands
{
id: 'help-docs',
title: 'Documentation',
description: 'Open help documentation',
icon: faQuestion,
category: CommandCategory.HELP,
keywords: ['help', 'docs', 'documentation'],
handler: () => this.showToast('Opening documentation...'),
order: 1
},
// Action Commands
{
id: 'action-refresh',
title: 'Refresh Page',
description: 'Reload the current page',
icon: faRocket,
category: CommandCategory.ACTIONS,
keywords: ['refresh', 'reload', 'update'],
shortcut: ['F5'],
handler: () => this.showToast('Page refreshed!'),
order: 1
}
];
this.commandService.registerCommands(sampleCommands);
}
clearCommands(): void {
this.commandService.clearCommands();
this.commandService.clearRecentCommands();
}
updateConfig(key: string, event: Event): void {
const target = event.target as HTMLInputElement;
let value: any = target.type === 'checkbox' ? target.checked :
target.type === 'number' ? parseInt(target.value, 10) :
target.value;
(this.config as any)[key] = value;
this.applyConfig();
}
updatePaletteSize(event: Event): void {
const target = event.target as HTMLSelectElement;
this.paletteSize = target.value as 'md' | 'lg' | 'xl';
}
private applyConfig(): void {
this.commandService.updateConfig({
showCategories: this.config.showCategories,
showShortcuts: this.config.showShortcuts,
showRecent: this.config.showRecent,
maxResults: this.config.maxResults,
recentLimit: this.config.recentLimit
});
}
onPaletteOpened(): void {
console.log('Command palette opened');
}
onPaletteClosed(): void {
console.log('Command palette closed');
}
onCommandExecuted(event: { commandId: string; context: CommandExecutionContext }): void {
this.executionCount++;
console.log('Command executed:', event);
}
private showToast(message: string): void {
// Simple toast implementation for demo
const toast = document.createElement('div');
toast.className = 'demo-toast';
toast.textContent = message;
toast.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #333;
color: white;
padding: 12px 24px;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0,0,0,0.1);
z-index: 10000;
font-size: 14px;
animation: slideIn 0.3s ease;
`;
document.body.appendChild(toast);
setTimeout(() => {
toast.style.animation = 'slideOut 0.3s ease forwards';
setTimeout(() => document.body.removeChild(toast), 300);
}, 3000);
}
}