fix(a11y): resolve all 15 pre-existing Svelte compiler warnings

- GroupAgentsPanel: add keyboard handler on clickable div, remove unused CSS
- CommsTab: add aria-label on icon button
- CommandPalette: add aria-label on close button
- SettingsTab: add aria-labels on icon buttons, remove unused CSS rules
- AgentPane: fix state_referenced_locally for initialPrompt
- NotificationCenter: add keyboard handler on clickable notification
- ProjectHeader: replace nested <button> with <span> (invalid DOM nesting)
- CodeEditor: fix state_referenced_locally for content and lang
- PdfViewer: fix state_referenced_locally for filePath
This commit is contained in:
Hibryda 2026-03-17 04:53:49 +01:00
parent 2cdc8dddb2
commit 6ca168e336
9 changed files with 23 additions and 31 deletions

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { onMount } from 'svelte';
import { onMount, untrack } from 'svelte';
import { marked, Renderer } from 'marked';
import { queryAgent, stopAgent, isAgentReady, restartAgent } from '../../adapters/agent-bridge';
import {
@ -78,7 +78,7 @@
let { sessionId, projectId, prompt: initialPrompt = '', cwd: initialCwd, profile: profileName, provider: providerId = 'claude', capabilities = DEFAULT_CAPABILITIES, useWorktrees = false, agentSystemPrompt, model: modelOverride, extraEnv, autonomousMode, autoPrompt, onautopromptconsumed, onExit }: Props = $props();
let session = $derived(getAgentSession(sessionId));
let inputPrompt = $state(initialPrompt);
let inputPrompt = $state(untrack(() => initialPrompt));
let scrollContainer: HTMLDivElement | undefined = $state();
let autoScroll = $state(true);
let restarting = $state(false);

View file

@ -82,6 +82,7 @@
{#if open}
<!-- svelte-ignore a11y_no_static_element_interactions -->
<!-- svelte-ignore a11y_click_events_have_key_events -->
<div class="backdrop" onclick={close}></div>
<div class="panel" data-testid="notification-panel">
<div class="panel-header">

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { onMount, onDestroy, untrack } from 'svelte';
import { EditorView, keymap, lineNumbers, highlightActiveLine, highlightActiveLineGutter, drawSelection, rectangularSelection, crosshairCursor, dropCursor } from '@codemirror/view';
import { EditorState } from '@codemirror/state';
import { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands';
@ -234,7 +234,7 @@
});
// When content prop changes externally (different file loaded), replace editor content
let lastContent = $state(content);
let lastContent = $state(untrack(() => content));
$effect(() => {
const c = content;
if (view && c !== lastContent) {
@ -249,7 +249,7 @@
});
// When lang changes, recreate editor
let lastLang = $state(lang);
let lastLang = $state(untrack(() => lang));
$effect(() => {
const l = lang;
if (l !== lastLang && view) {

View file

@ -287,7 +287,7 @@
{#if showShortcuts}
<div class="shortcuts-header">
<h3>Keyboard Shortcuts</h3>
<button class="shortcuts-close" onclick={() => showShortcuts = false}>
<button class="shortcuts-close" onclick={() => showShortcuts = false} aria-label="Close shortcuts">
<svg width="14" height="14" viewBox="0 0 14 14" fill="none">
<path d="M2 2l10 10M12 2L2 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
</svg>

View file

@ -387,7 +387,7 @@
onkeydown={handleKeydown}
rows="1"
></textarea>
<button class="send-btn" onclick={handleSend} disabled={!messageInput.trim()}>
<button class="send-btn" onclick={handleSend} disabled={!messageInput.trim()} aria-label="Send message">
<svg width="16" height="16" viewBox="0 0 24 24" fill="none">
<path d="M22 2L11 13M22 2l-7 20-4-9-9-4 20-7z" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/>
</svg>

View file

@ -176,6 +176,7 @@
class:active={status === 'active'}
class:sleeping={status === 'sleeping'}
onclick={() => setActiveProject(project.id)}
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') setActiveProject(project.id); }}
role="button"
tabindex="0"
>
@ -416,10 +417,6 @@
min-width: 6rem;
}
.agent-card.tier2 .card-actions {
display: none;
}
.unread-badge {
background: var(--ctp-red);
color: var(--ctp-base);

View file

@ -1,5 +1,5 @@
<script lang="ts">
import { onMount, onDestroy } from 'svelte';
import { onMount, onDestroy, untrack } from 'svelte';
import { convertFileSrc } from '@tauri-apps/api/core';
import * as pdfjsLib from 'pdfjs-dist';
@ -164,7 +164,7 @@
});
// React to filePath changes
let lastPath = $state(filePath);
let lastPath = $state(untrack(() => filePath));
$effect(() => {
const p = filePath;
if (p !== lastPath) {

View file

@ -97,23 +97,29 @@
<span class="info-sep">·</span>
{/if}
{#if health && health.externalConflictCount > 0}
<button
<span
class="info-conflict info-conflict-external"
role="button"
tabindex="-1"
title="{health.externalConflictCount} external write{health.externalConflictCount > 1 ? 's' : ''} — files modified outside agent — click to dismiss"
onclick={(e: MouseEvent) => { e.stopPropagation(); acknowledgeConflicts(ProjectId(project.id)); }}
onkeydown={(e: KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { e.stopPropagation(); acknowledgeConflicts(ProjectId(project.id)); } }}
>
{health.externalConflictCount} ext write{health.externalConflictCount > 1 ? 's' : ''}
</button>
</span>
<span class="info-sep">·</span>
{/if}
{#if health && health.fileConflictCount - (health.externalConflictCount ?? 0) > 0}
<button
<span
class="info-conflict"
role="button"
tabindex="-1"
title="{health.fileConflictCount - (health.externalConflictCount ?? 0)} agent conflict{health.fileConflictCount - (health.externalConflictCount ?? 0) > 1 ? 's' : ''} — click to dismiss"
onclick={(e: MouseEvent) => { e.stopPropagation(); acknowledgeConflicts(ProjectId(project.id)); }}
onkeydown={(e: KeyboardEvent) => { if (e.key === 'Enter' || e.key === ' ') { e.stopPropagation(); acknowledgeConflicts(ProjectId(project.id)); } }}
>
{health.fileConflictCount - (health.externalConflictCount ?? 0)} conflict{health.fileConflictCount - (health.externalConflictCount ?? 0) > 1 ? 's' : ''}
</button>
</span>
<span class="info-sep">·</span>
{/if}
{#if contextPct !== null && contextPct > 0}

View file

@ -673,6 +673,7 @@
class:on={filesSaveOnBlur}
role="switch"
aria-checked={filesSaveOnBlur}
aria-label="Save on blur"
onclick={() => { filesSaveOnBlur = !filesSaveOnBlur; saveGlobalSetting('files_save_on_blur', String(filesSaveOnBlur)); }}
>
<span class="toggle-thumb"></span>
@ -737,6 +738,7 @@
class:on={isProviderEnabled(provider.id)}
role="switch"
aria-checked={isProviderEnabled(provider.id)}
aria-label="Toggle {provider.name} enabled"
onclick={() => toggleProviderEnabled(provider.id)}
>
<span class="toggle-thumb"></span>
@ -2575,20 +2577,6 @@
flex-shrink: 0;
}
.card-field-input {
padding: 0.3125rem 0.5rem;
background: var(--ctp-base);
border: 1px solid var(--ctp-surface1);
border-radius: 0.25rem;
color: var(--ctp-text);
font-size: 0.78rem;
}
.card-field-input:focus {
border-color: var(--ctp-blue);
outline: none;
}
.agent-prompt-input {
padding: 0.375rem 0.5rem;
background: var(--ctp-base);