This commit is contained in:
Janus C. H. Knudsen 2026-01-10 20:39:17 +01:00
parent 54b057886c
commit 7fc1ae0650
204 changed files with 4345 additions and 134 deletions

View file

@ -0,0 +1,106 @@
/**
* Search Controller
*
* Handles global search functionality and keyboard shortcuts
*/
export class SearchController {
private input: HTMLInputElement | null = null;
private container: HTMLElement | null = null;
constructor() {
this.input = document.getElementById('globalSearch') as HTMLInputElement | null;
this.container = document.querySelector<HTMLElement>('swp-topbar-search');
this.setupListeners();
}
/**
* Get current search value
*/
get value(): string {
return this.input?.value ?? '';
}
/**
* Set search value
*/
set value(val: string) {
if (this.input) {
this.input.value = val;
}
}
/**
* Focus the search input
*/
focus(): void {
this.input?.focus();
}
/**
* Blur the search input
*/
blur(): void {
this.input?.blur();
}
/**
* Clear the search input
*/
clear(): void {
this.value = '';
}
private setupListeners(): void {
// Keyboard shortcuts
document.addEventListener('keydown', (e) => this.handleKeyboard(e));
// Input handlers
if (this.input) {
this.input.addEventListener('input', (e) => this.handleInput(e));
// Prevent form submission if wrapped in form
const form = this.input.closest('form');
form?.addEventListener('submit', (e) => this.handleSubmit(e));
}
}
private handleKeyboard(e: KeyboardEvent): void {
// Cmd/Ctrl + K to focus search
if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault();
this.focus();
return;
}
// Escape to blur search when focused
if (e.key === 'Escape' && document.activeElement === this.input) {
this.blur();
}
}
private handleInput(e: Event): void {
const target = e.target as HTMLInputElement;
const query = target.value.trim();
// Emit custom event for search
document.dispatchEvent(new CustomEvent('app:search', {
detail: { query },
bubbles: true
}));
}
private handleSubmit(e: Event): void {
e.preventDefault();
const query = this.value.trim();
if (!query) return;
// Emit custom event for search submit
document.dispatchEvent(new CustomEvent('app:search-submit', {
detail: { query },
bubbles: true
}));
}
}