A container registry that uses the AT Protocol for manifest storage and S3 for blob storage.
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

collapse searchbox when not in use

+102 -12
+51 -8
pkg/appview/static/css/style.css
··· 153 153 color: var(--primary); 154 154 } 155 155 156 - .nav-search { 157 - flex: 1; 158 - max-width: 400px; 159 - margin: 0 2rem; 156 + /* Expandable search */ 157 + .nav-search-wrapper { 158 + position: relative; 159 + display: flex; 160 + align-items: center; 161 + } 162 + 163 + .search-toggle-btn { 164 + display: inline-flex; 165 + align-items: center; 166 + justify-content: center; 167 + background: transparent; 168 + border: none; 169 + color: var(--navbar-fg); 170 + cursor: pointer; 171 + padding: 0.5rem; 172 + border-radius: 4px; 173 + } 174 + 175 + .search-toggle-btn:hover { 176 + background: var(--secondary); 160 177 } 161 178 162 - .nav-search input { 179 + .search-toggle-btn .search-icon { 180 + width: 1.25rem; 181 + height: 1.25rem; 182 + } 183 + 184 + .nav-search-form { 185 + position: absolute; 186 + right: 100%; 187 + width: 0; 188 + opacity: 0; 189 + overflow: hidden; 190 + transition: width 0.3s ease, opacity 0.3s ease; 191 + margin-right: 0.5rem; 192 + } 193 + 194 + .nav-search-wrapper.expanded .nav-search-form { 195 + width: 250px; 196 + opacity: 1; 197 + } 198 + 199 + .nav-search-form input { 163 200 width: 100%; 164 201 padding: 0.5rem 1rem; 165 202 border: none; 166 203 border-radius: 4px; 167 204 font-size: 0.95rem; 205 + background: var(--bg); 206 + color: var(--fg); 207 + } 208 + 209 + .nav-search-form input:focus { 210 + outline: 2px solid var(--primary); 211 + outline-offset: -2px; 168 212 } 169 213 170 214 .nav-links { ··· 2078 2122 gap: 1rem; 2079 2123 } 2080 2124 2081 - .nav-search { 2082 - max-width: 100%; 2083 - margin: 0; 2125 + .nav-search-wrapper.expanded .nav-search-form { 2126 + width: 200px; 2084 2127 } 2085 2128 2086 2129 .push-details {
+44
pkg/appview/static/js/app.js
··· 35 35 themeBtn.setAttribute('aria-label', currentTheme === 'dark' ? 'Switch to light mode' : 'Switch to dark mode'); 36 36 } 37 37 38 + // Expandable search 39 + function toggleSearch() { 40 + const wrapper = document.querySelector('.nav-search-wrapper'); 41 + const input = document.getElementById('nav-search-input'); 42 + 43 + if (!wrapper || !input) return; 44 + 45 + wrapper.classList.toggle('expanded'); 46 + 47 + if (wrapper.classList.contains('expanded')) { 48 + input.focus(); 49 + } 50 + } 51 + 52 + function closeSearch() { 53 + const wrapper = document.querySelector('.nav-search-wrapper'); 54 + if (wrapper) { 55 + wrapper.classList.remove('expanded'); 56 + } 57 + } 58 + 59 + // Close search on Escape key and click outside 60 + document.addEventListener('DOMContentLoaded', () => { 61 + const wrapper = document.querySelector('.nav-search-wrapper'); 62 + const input = document.getElementById('nav-search-input'); 63 + 64 + if (!wrapper || !input) return; 65 + 66 + // Close on Escape key 67 + document.addEventListener('keydown', (e) => { 68 + if (e.key === 'Escape' && wrapper.classList.contains('expanded')) { 69 + closeSearch(); 70 + } 71 + }); 72 + 73 + // Close on click outside 74 + document.addEventListener('click', (e) => { 75 + if (wrapper.classList.contains('expanded') && 76 + !wrapper.contains(e.target)) { 77 + closeSearch(); 78 + } 79 + }); 80 + }); 81 + 38 82 // Copy to clipboard 39 83 function copyToClipboard(text) { 40 84 navigator.clipboard.writeText(text).then(() => {
+6 -3
pkg/appview/templates/components/nav-search.html
··· 1 1 {{ define "nav-search" }} 2 - <div class="nav-search"> 3 - <form action="/search" method="get"> 4 - <input type="text" name="q" placeholder="Search images..." value="{{ .Query }}" /> 2 + <div class="nav-search-wrapper"> 3 + <button id="search-toggle" onclick="toggleSearch()" class="btn-link search-toggle-btn" aria-label="Search"> 4 + <i data-lucide="search" class="search-icon"></i> 5 + </button> 6 + <form action="/search" method="get" class="nav-search-form"> 7 + <input type="text" id="nav-search-input" name="q" placeholder="Search images..." value="{{ .Query }}" /> 5 8 </form> 6 9 </div> 7 10 {{ end }}
+1 -1
pkg/appview/templates/components/nav.html
··· 1 1 {{ define "nav" }} 2 2 <nav class="navbar"> 3 3 {{ template "nav-brand" }} 4 - {{ template "nav-search" . }} 5 4 <div class="nav-links"> 5 + {{ template "nav-search" . }} 6 6 {{ template "nav-theme-toggle" }} 7 7 {{ template "nav-user" . }} 8 8 </div>