diff --git a/index.html b/index.html index 233b51d..7ec8866 100644 --- a/index.html +++ b/index.html @@ -1073,6 +1073,14 @@ autocapitalize="off" spellcheck="false" /> + @@ -1649,6 +1657,9 @@ placeholder="Search tracks..." class="track-list-search-input" /> +
diff --git a/js/app.js b/js/app.js index 43cb84c..78f9661 100644 --- a/js/app.js +++ b/js/app.js @@ -1274,6 +1274,9 @@ document.addEventListener('DOMContentLoaded', async () => { const searchForm = document.getElementById('search-form'); const searchInput = document.getElementById('search-input'); + // Setup clear button for search bar + ui.setupSearchClearButton(searchInput); + const performSearch = debounce((query) => { if (query) { navigate(`/search/${encodeURIComponent(query)}`); diff --git a/js/ui.js b/js/ui.js index ad3d21a..e674067 100644 --- a/js/ui.js +++ b/js/ui.js @@ -539,6 +539,33 @@ export class UIRenderer { .join('')}`; } + setupSearchClearButton(inputElement, clearBtnSelector = '.search-clear-btn') { + if (!inputElement) return; + + const clearBtn = inputElement.parentElement?.querySelector(clearBtnSelector); + if (!clearBtn) return; + + // Remove old listener if exists + const oldListener = clearBtn._clearListener; + if (oldListener) clearBtn.removeEventListener('click', oldListener); + + // Toggle visibility based on input value + const toggleVisibility = () => { + clearBtn.style.display = inputElement.value.trim() ? 'flex' : 'none'; + }; + + // Clear input on click + const clearListener = () => { + inputElement.value = ''; + inputElement.dispatchEvent(new Event('input')); + inputElement.focus(); + }; + + inputElement.addEventListener('input', toggleVisibility); + clearBtn._clearListener = clearListener; + clearBtn.addEventListener('click', clearListener); + } + setupTracklistSearch( searchInputId = 'track-list-search-input', tracklistContainerId = 'playlist-detail-tracklist' @@ -548,6 +575,9 @@ export class UIRenderer { if (!searchInput || !tracklistContainer) return; + // Setup clear button + this.setupSearchClearButton(searchInput); + // Remove previous listener if exists const oldListener = searchInput._searchListener; if (oldListener) { diff --git a/styles.css b/styles.css index 1501260..a8b764f 100644 --- a/styles.css +++ b/styles.css @@ -585,7 +585,7 @@ kbd { .search-bar input { width: 100%; - padding: 0.75rem 0.75rem 0.75rem 2.5rem; + padding: 0.75rem 2.5rem 0.75rem 2.5rem; background-color: var(--input); border: 1px solid var(--border); border-radius: var(--radius); @@ -597,6 +597,17 @@ kbd { background-color var(--transition-fast); } +/* Clear button for search inputs */ +.search-clear-btn { + position: absolute; + right: 0.25rem; + top: 50%; + transform: translateY(-50%); + font-size: 1.5rem; + line-height: 1; + z-index: 1; +} + .search-bar input:focus { outline: none; border-color: var(--ring); @@ -5519,11 +5530,12 @@ textarea:focus { /* Track List Search */ .track-list-search-container { margin: 1rem 0; + position: relative; } .track-list-search-input { width: 100%; - padding: 0.75rem 1rem; + padding: 0.75rem 2.5rem 0.75rem 1rem; background-color: var(--input); border: 1px solid var(--border); border-radius: var(--radius);