()
| 101 | } |
| 102 | |
| 103 | private createModal(): void { |
| 104 | this.overlay = document.createElement('div'); |
| 105 | this.overlay.className = 'search-overlay'; |
| 106 | this.overlay.innerHTML = ` |
| 107 | <div class="search-modal"> |
| 108 | <div class="search-header"> |
| 109 | <span class="search-icon">⌘</span> |
| 110 | <input type="text" class="search-input" placeholder="${this.placeholder}" autofocus /> |
| 111 | <kbd class="search-kbd">ESC</kbd> |
| 112 | </div> |
| 113 | <div class="search-results"></div> |
| 114 | <div class="search-footer"> |
| 115 | <span><kbd>↑↓</kbd> ${t('modals.search.navigate')}</span> |
| 116 | <span><kbd>↵</kbd> ${t('modals.search.select')}</span> |
| 117 | <span><kbd>esc</kbd> ${t('modals.search.close')}</span> |
| 118 | </div> |
| 119 | </div> |
| 120 | `; |
| 121 | |
| 122 | this.overlay.addEventListener('click', (e) => { |
| 123 | if (e.target === this.overlay) this.close(); |
| 124 | }); |
| 125 | |
| 126 | this.input = this.overlay.querySelector('.search-input'); |
| 127 | this.resultsList = this.overlay.querySelector('.search-results'); |
| 128 | |
| 129 | this.input?.addEventListener('input', () => this.handleSearch()); |
| 130 | this.input?.addEventListener('keydown', (e) => this.handleKeydown(e)); |
| 131 | |
| 132 | this.container.appendChild(this.overlay); |
| 133 | } |
| 134 | |
| 135 | private matchCommands(query: string): CommandResult[] { |
| 136 | if (query.length < 2) return []; |
no test coverage detected