An x in a search box clears it (#291)

Once something is typed: at the box's right end, inside it. One click
handler for every box, which clears it and fires its input event, so each
box's own handler brings its list back whole. The browser's own x, drawn
by some browsers and not others, gives way to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-10-19 14:55:25 +00:00
parent d850c02501
commit 4c1b78408f
7 changed files with 49 additions and 7 deletions

View File

@@ -262,7 +262,7 @@ function drawLogView(){
<option value="WARN">Warnings and errors</option>
<option value="ERROR">Errors only</option>
</select>
<input type="search" id="logq" class="grow" placeholder="Filter…">
${searchBox('<input type="search" id="logq" placeholder="Filter…">','grow')}
<label class="check" style="margin:0"><input type="checkbox" id="logfollow" checked> Follow</label>
<button class="btn ico" id="logcopy" title="Copy what is showing" aria-label="Copy what is showing">${ICON.copy}</button>
</div>

View File

@@ -142,7 +142,7 @@ function signalModal(sg?: Signal){
aria-expanded="false"></button>
<input type="text" id="sgname" value="${esc(sg?.name||'')}" placeholder="Formula 1"></div>
<div id="sgpicker" hidden>
<div class="inline"><input type="search" id="sgiconq" placeholder="Search icons: robot, car, music…" autocomplete="off">
<div class="inline">${searchBox('<input type="search" id="sgiconq" placeholder="Search icons: robot, car, music…" autocomplete="off">')}
<button type="button" class="dlink" id="sgjev" title="Pick an icon for me">Auto</button>
<button type="button" class="dlink" id="sgnoicon">Initials</button></div>
<div class="icongrid" id="sgicons" role="listbox" aria-label="Icons"></div>

View File

@@ -61,6 +61,20 @@ const EQ='<span class="eq" aria-hidden="true"><i></i><i></i><i></i></span>';
// The page's own buttons name their icon; this draws it in, ahead of any label they carry.
for(const b of $$('[data-icon]')) b.insertAdjacentHTML('afterbegin',ICON[b.dataset.icon!]);
/// A search box with an x at its right end that clears it, shown once something is typed (#291).
const searchBox=(input: string, cls='')=>
`<span class="clearable ${cls}">${input}<button type="button" class="clearx" title="Clear" aria-label="Clear">${ICON.close}</button></span>`;
// Every box's x, wherever it is drawn: cleared as if the typing were deleted, so the box's own input
// handler runs and its list comes back whole.
document.addEventListener('click',(e: MouseEvent)=>{
const x=(e.target as Element).closest?.('.clearx');
const box=x?.parentElement?.querySelector('input');
if(!box) return;
box.value='';
box.dispatchEvent(new Event('input',{bubbles:true}));
box.focus();
});
/// An episode whose DeadAir copy is still being made: it plays as it is until then, and the line
/// becomes how much shorter it is once the copy is ready (the dead_air event).
const DEAD_PENDING='<span class="dapend" title="DeadAir is still working on this episode. Until it is done, it plays at its full length.">Cutting dead air…</span>';