search-filter.ts (2298B)
1 export interface FilterState { 2 search: string; 3 year: string; 4 archetype: string; 5 tag: string; 6 minScore: number; 7 maxScore: number; 8 } 9 10 export function createFilters( 11 archetypes: string[], 12 tags: string[], 13 onChange: (state: FilterState) => void 14 ): HTMLElement { 15 const div = document.createElement('div'); 16 div.className = 'filters'; 17 18 div.innerHTML = ` 19 <input type="text" id="f-search" placeholder="Search titles..."> 20 <select id="f-year"><option value="">All years</option></select> 21 <select id="f-archetype"><option value="">All archetypes</option></select> 22 <select id="f-tag"><option value="">All tags</option></select> 23 <label style="font-size:0.8rem;color:var(--text-dim)">Score: 24 <input type="number" id="f-min" value="0" min="0" max="100" style="width:50px"> – 25 <input type="number" id="f-max" value="100" min="0" max="100" style="width:50px"> 26 </label> 27 <span class="filter-count" id="f-count"></span> 28 `; 29 30 // Populate selects 31 const yearSel = div.querySelector('#f-year') as HTMLSelectElement; 32 for (let y = 2026; y >= 2017; y--) { 33 yearSel.innerHTML += `<option value="${y}">${y}</option>`; 34 } 35 36 const archSel = div.querySelector('#f-archetype') as HTMLSelectElement; 37 archetypes.forEach(a => archSel.innerHTML += `<option value="${a}">${a}</option>`); 38 39 const tagSel = div.querySelector('#f-tag') as HTMLSelectElement; 40 tags.forEach(t => tagSel.innerHTML += `<option value="${t}">${t}</option>`); 41 42 function emit() { 43 onChange({ 44 search: (div.querySelector('#f-search') as HTMLInputElement).value.toLowerCase(), 45 year: (div.querySelector('#f-year') as HTMLSelectElement).value, 46 archetype: (div.querySelector('#f-archetype') as HTMLSelectElement).value, 47 tag: (div.querySelector('#f-tag') as HTMLSelectElement).value, 48 minScore: parseInt((div.querySelector('#f-min') as HTMLInputElement).value) || 0, 49 maxScore: parseInt((div.querySelector('#f-max') as HTMLInputElement).value) || 100, 50 }); 51 } 52 53 div.addEventListener('input', emit); 54 div.addEventListener('change', emit); 55 56 return div; 57 } 58 59 export function updateFilterCount(container: HTMLElement, count: number, total: number) { 60 const el = container.querySelector('#f-count'); 61 if (el) el.textContent = `${count} / ${total}`; 62 }