refactor(global-search): improve event handling and cleanup in global search component

- Replaced inline event listener functions with named handlers for better readability and maintainability.
- Added cleanup logic to remove event listeners on component destruction, preventing potential memory leaks.
- Updated the styling of search result items for improved visual feedback and consistency.
This commit is contained in:
Andras Bacsai
2025-10-01 20:03:51 +02:00
parent f0a532407b
commit 89c4f83bc5
@@ -31,21 +31,15 @@
} }
}, },
init() { init() {
// Listen for custom event from navbar search button at window level // Create named handlers for proper cleanup
window.addEventListener('open-global-search', () => { const openGlobalSearchHandler = () => this.openModal();
this.openModal(); const slashKeyHandler = (e) => {
});
// Listen for / key press globally
document.addEventListener('keydown', (e) => {
if (e.key === '/' && !['INPUT', 'TEXTAREA'].includes(e.target.tagName) && !this.modalOpen) { if (e.key === '/' && !['INPUT', 'TEXTAREA'].includes(e.target.tagName) && !this.modalOpen) {
e.preventDefault(); e.preventDefault();
this.openModal(); this.openModal();
} }
}); };
const cmdKHandler = (e) => {
// Listen for Cmd+K or Ctrl+K globally
document.addEventListener('keydown', (e) => {
if ((e.metaKey || e.ctrlKey) && e.key === 'k') { if ((e.metaKey || e.ctrlKey) && e.key === 'k') {
e.preventDefault(); e.preventDefault();
if (this.modalOpen) { if (this.modalOpen) {
@@ -54,17 +48,13 @@
this.openModal(); this.openModal();
} }
} }
}); };
const escapeKeyHandler = (e) => {
// Listen for Escape key to close modal
document.addEventListener('keydown', (e) => {
if (e.key === 'Escape' && this.modalOpen) { if (e.key === 'Escape' && this.modalOpen) {
this.closeModal(); this.closeModal();
} }
}); };
const arrowKeyHandler = (e) => {
// Listen for arrow keys when modal is open
document.addEventListener('keydown', (e) => {
if (!this.modalOpen) return; if (!this.modalOpen) return;
if (e.key === 'ArrowDown') { if (e.key === 'ArrowDown') {
e.preventDefault(); e.preventDefault();
@@ -73,6 +63,22 @@
e.preventDefault(); e.preventDefault();
this.navigateResults('up'); this.navigateResults('up');
} }
};
// Add event listeners
window.addEventListener('open-global-search', openGlobalSearchHandler);
document.addEventListener('keydown', slashKeyHandler);
document.addEventListener('keydown', cmdKHandler);
document.addEventListener('keydown', escapeKeyHandler);
document.addEventListener('keydown', arrowKeyHandler);
// Cleanup on component destroy
this.$el.addEventListener('alpine:destroy', () => {
window.removeEventListener('open-global-search', openGlobalSearchHandler);
document.removeEventListener('keydown', slashKeyHandler);
document.removeEventListener('keydown', cmdKHandler);
document.removeEventListener('keydown', escapeKeyHandler);
document.removeEventListener('keydown', arrowKeyHandler);
}); });
} }
}"> }">
@@ -138,7 +144,7 @@
<div class="py-2"> <div class="py-2">
@foreach ($searchResults as $index => $result) @foreach ($searchResults as $index => $result)
<a href="{{ $result['link'] ?? '#' }}" <a href="{{ $result['link'] ?? '#' }}"
class="search-result-item block px-4 py-3 hover:bg-neutral-50 dark:hover:bg-coolgray-200 transition-colors focus:outline-none focus:bg-neutral-100 dark:focus:bg-coolgray-200 border-l-2 border-transparent hover:border-coollabs focus:border-coollabs"> class="search-result-item block px-4 py-3 hover:bg-neutral-50 dark:hover:bg-coolgray-200 transition-colors focus:outline-none focus:bg-yellow-50 dark:focus:bg-yellow-900/20 border-transparent hover:border-coollabs focus:border-yellow-500 dark:focus:border-yellow-400">
<div class="flex items-center justify-between gap-3"> <div class="flex items-center justify-between gap-3">
<div class="flex-1 min-w-0"> <div class="flex-1 min-w-0">
<div class="flex items-center gap-2 mb-1"> <div class="flex items-center gap-2 mb-1">