diff --git a/index.html b/index.html index 7ad12b7..cf6cc0d 100644 --- a/index.html +++ b/index.html @@ -161,10 +161,14 @@ text-decoration: underline; } + .search-wrapper { + position: relative; + margin-bottom: 1.5rem; + } + #filter-input { width: 100%; - padding: 0.75rem 1rem; - margin-bottom: 1.5rem; + padding: 0.75rem 2.5rem 0.75rem 1rem; border: 1px solid #ddd; border-radius: 8px; font-size: 1rem; @@ -178,6 +182,33 @@ outline: none; } + #clear-btn { + position: absolute; + right: 0.5rem; + top: 50%; + transform: translateY(-50%); + background: none; + border: none; + color: #999; + font-size: 1.25rem; + cursor: pointer; + padding: 0.25rem 0.5rem; + border-radius: 4px; + transition: all 0.2s ease; + opacity: 0; + pointer-events: none; + } + + #clear-btn.visible { + opacity: 1; + pointer-events: auto; + } + + #clear-btn:hover { + color: #667eea; + background: rgba(102, 126, 234, 0.1); + } + #version-reload-btn { position: fixed; bottom: 20px; @@ -217,12 +248,173 @@ opacity: 1; } } + + /* Mobile Responsive Styles */ + @media (max-width: 768px) { + body { + padding: 1rem; + } + + .container { + padding: 1rem; + border-radius: 12px; + } + + h1 { + font-size: 1.75rem; + margin-bottom: 1rem; + } + + .search-wrapper { + margin-bottom: 1rem; + } + + #filter-input { + padding: 0.625rem 2.25rem 0.625rem 0.875rem; + font-size: 0.95rem; + } + + #clear-btn { + font-size: 1.1rem; + right: 0.375rem; + } + + .tree ul { + padding-left: 1rem; + } + + .category { + margin: 0.375rem 0; + padding: 0.625rem; + border-left-width: 3px; + } + + .category-header { + gap: 0.75rem; + } + + .category-image { + width: 40px; + height: 40px; + } + + .category-name { + font-size: 1rem; + } + + .category-count { + font-size: 0.85rem; + } + + .toggle { + font-size: 0.9rem; + margin-right: 0.375rem; + } + + .category-products { + padding-left: 2.5rem; + font-size: 0.85rem; + } + + .product-image { + width: 28px; + height: 28px; + } + + .product-item { + padding: 0.375rem 0; + } + + #version-reload-btn { + bottom: 15px; + right: 15px; + padding: 10px 16px; + font-size: 0.85rem; + } + + /* Ensure touch targets are at least 44px */ + .category-header.has-children { + min-height: 44px; + } + } + + @media (max-width: 480px) { + body { + padding: 0.5rem; + } + + .container { + padding: 0.75rem; + border-radius: 8px; + } + + h1 { + font-size: 1.5rem; + margin-bottom: 0.75rem; + } + + #filter-input { + padding: 0.5rem 2rem 0.5rem 0.75rem; + font-size: 0.9rem; + } + + #clear-btn { + font-size: 1rem; + right: 0.25rem; + } + + .tree ul { + padding-left: 0.75rem; + } + + .category { + margin: 0.25rem 0; + padding: 0.5rem; + } + + .category-header { + gap: 0.5rem; + } + + .category-image { + width: 36px; + height: 36px; + } + + .category-name { + font-size: 0.95rem; + } + + .category-count { + font-size: 0.8rem; + } + + .category-products { + padding-left: 2rem; + font-size: 0.8rem; + } + + .product-image { + width: 24px; + height: 24px; + } + + #version-reload-btn { + bottom: 10px; + right: 10px; + padding: 8px 14px; + font-size: 0.8rem; + } + }
- +
+ + +
Loading categories...
@@ -245,6 +437,12 @@ // DOM Elements const container = document.getElementById('tree-container'); const filterInput = document.getElementById('filter-input'); + const clearBtn = document.getElementById('clear-btn'); + + // Auto-focus search field on page load + window.addEventListener('load', () => { + filterInput.focus(); + }); // Version checking const clientEtag = document.querySelector('meta[name="app-version"]')?.content; @@ -294,6 +492,13 @@ const value = e.target.value; state.filter = value; + // Toggle clear button visibility + if (value) { + clearBtn.classList.add('visible'); + } else { + clearBtn.classList.remove('visible'); + } + if (value.trim()) { debouncedSearch(value); } else { @@ -305,6 +510,22 @@ } }); + // Clear button functionality + clearBtn.addEventListener('click', () => { + filterInput.value = ''; + state.filter = ''; + clearBtn.classList.remove('visible'); + + // Clear matches and collapse all categories + resetMatches(state.categories); + resetExpansion(state.categories); + collapseAllProducts(state.categories); + render(); + + // Refocus the input + filterInput.focus(); + }); + socket.on('searchResults', ({ query, matches }) => { if (query !== state.filter) return;