Skip to content

Commit 0ad05f1

Browse files
Add results tab keyboard navigation (imDarshanGK#152)
* Add confirmation dialog before clearing history and favorites * Add keyboard navigation for reults tabs --------- Co-authored-by: Darshan G K <122042809+imDarshanGK@users.noreply.github.com>
1 parent 5b21e5e commit 0ad05f1

1 file changed

Lines changed: 102 additions & 0 deletions

File tree

frontend/index.html

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2043,6 +2043,18 @@ <h4>File Upload</h4>
20432043
</div>
20442044
</div>
20452045

2046+
<!-- Result tabs -->
2047+
<div class="result-tabs" role="tablist" aria-label="Analysis Results">
2048+
<button class="result-tab active" data-rtab="explain" role="tab" aria-selected="true" aria-controls="pane-explain" tabindex="0">
2049+
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M2 3h6a4 4 0 0 1 4 4v14a3 3 0 0 0-3-3H2z"/><path d="M22 3h-6a4 4 0 0 0-4 4v14a3 3 0 0 1 3-3h7z"/></svg> Explain <span class="tab-badge" id="explainBadge"></span>
2050+
</button>
2051+
<button class="result-tab" data-rtab="debug" role="tab" aria-selected="false" aria-controls="pane-debug" tabindex="-1">
2052+
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><path d="M8 2l1.5 1.5"/><path d="M14.5 3.5L16 2"/><path d="M9 7.5A3 3 0 0 1 12 5a3 3 0 0 1 3 2.5"/><path d="M6.5 9H4a1 1 0 0 0-1 1v1a8 8 0 0 0 16 0v-1a1 1 0 0 0-1-1h-2.5"/><line x1="12" y1="12" x2="12" y2="16"/><path d="M4.5 15H2"/><path d="M22 15h-2.5"/><path d="M4.5 19l-2 2"/><path d="M19.5 19l2 2"/></svg> Debug <span class="tab-badge" id="debugBadge"></span>
2053+
</button>
2054+
<button class="result-tab" data-rtab="suggest" role="tab" aria-selected="false" aria-controls="pane-suggest" tabindex="-1">
2055+
<svg width="15" height="15" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true"><polygon points="13,2 3,14 12,14 11,22 21,10 12,10"/></svg> Improve <span class="tab-badge" id="suggestBadge"></span>
2056+
</button>
2057+
</div>
20462058
<!-- Results Panel -->
20472059
<div class="panel">
20482060
<div class="panel-header">
@@ -2392,6 +2404,96 @@ <h3>No suggestions yet</h3>
23922404
}
23932405
}
23942406

2407+
/* ═══════════════════════════════════════════════════════════════
2408+
MODE BUTTONS
2409+
═══════════════════════════════════════════════════════════════ */
2410+
document.querySelectorAll('.mode-btn').forEach(b => {
2411+
b.addEventListener('click', () => {
2412+
selectedMode = b.dataset.mode;
2413+
document.querySelectorAll('.mode-btn').forEach(x => {
2414+
x.classList.remove('active');
2415+
x.setAttribute('aria-pressed', 'false');
2416+
});
2417+
b.classList.add('active');
2418+
b.setAttribute('aria-pressed', 'true');
2419+
});
2420+
});
2421+
2422+
/* ═══════════════════════════════════════════════════════════════
2423+
RESULT TABS
2424+
═══════════════════════════════════════════════════════════════ */
2425+
document.querySelectorAll('.result-tab').forEach((t, index, tabs) => {
2426+
t.addEventListener('click', () => {
2427+
const tab = t.dataset.rtab;
2428+
2429+
document.querySelectorAll('.result-tab').forEach(x => {
2430+
x.classList.remove('active');
2431+
x.setAttribute('aria-selected', 'false');
2432+
});
2433+
2434+
document.querySelectorAll('.result-pane').forEach(x =>
2435+
x.classList.remove('active')
2436+
);
2437+
2438+
t.classList.add('active');
2439+
t.setAttribute('aria-selected', 'true');
2440+
2441+
document.getElementById(`pane-${tab}`).classList.add('active');
2442+
});
2443+
2444+
t.addEventListener('keydown', (e) => {
2445+
if (e.key === 'ArrowRight') {
2446+
e.preventDefault();
2447+
tabs[(index + 1) % tabs.length].focus();
2448+
}
2449+
2450+
if (e.key === 'ArrowLeft') {
2451+
e.preventDefault();
2452+
tabs[(index - 1 + tabs.length) % tabs.length].focus();
2453+
}
2454+
2455+
if (e.key === 'Enter' || e.key === ' ') {
2456+
e.preventDefault();
2457+
t.click();
2458+
}
2459+
});
2460+
});
2461+
2462+
/* ═══════════════════════════════════════════════════════════════
2463+
CLEAR / COPY
2464+
═══════════════════════════════════════════════════════════════ */
2465+
document.getElementById('clearBtn').addEventListener('click', () => {
2466+
editor.value = '';
2467+
updateEditor();
2468+
resetResults();
2469+
});
2470+
document.getElementById('copyBtn').addEventListener('click', () => {
2471+
if (!editor.value.trim()) return;
2472+
navigator.clipboard.writeText(editor.value).then(() => toast('Code copied!', 'success'));
2473+
});
2474+
2475+
/* ═══════════════════════════════════════════════════════════════
2476+
API PING
2477+
═══════════════════════════════════════════════════════════════ */
2478+
async function pingApi() {
2479+
const base = apiUrlInput.value.replace(/\/$/, '');
2480+
try {
2481+
const r = await fetch(`${base}/health`, {signal: AbortSignal.timeout(5000)});
2482+
if (r.ok) {
2483+
apiDot.classList.add('connected');
2484+
apiStatusText.textContent = 'Connected';
2485+
toast('API is reachable', 'success');
2486+
} else {
2487+
apiDot.classList.remove('connected');
2488+
apiStatusText.textContent = 'Error ' + r.status;
2489+
}
2490+
} catch {
2491+
apiDot.classList.remove('connected');
2492+
apiStatusText.textContent = 'Unreachable';
2493+
toast('Cannot reach API. Check the URL.', 'error');
2494+
}
2495+
}
2496+
document.getElementById('pingBtn').addEventListener('click', pingApi);
23952497
// CTRL + ENTER
23962498
else if (
23972499
e.key === 'Enter' &&

0 commit comments

Comments
 (0)