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:
parent
2cdc8dddb2
commit
6ca168e336
9 changed files with 23 additions and 31 deletions
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount } from 'svelte';
|
import { onMount, untrack } from 'svelte';
|
||||||
import { marked, Renderer } from 'marked';
|
import { marked, Renderer } from 'marked';
|
||||||
import { queryAgent, stopAgent, isAgentReady, restartAgent } from '../../adapters/agent-bridge';
|
import { queryAgent, stopAgent, isAgentReady, restartAgent } from '../../adapters/agent-bridge';
|
||||||
import {
|
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 { 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 session = $derived(getAgentSession(sessionId));
|
||||||
let inputPrompt = $state(initialPrompt);
|
let inputPrompt = $state(untrack(() => initialPrompt));
|
||||||
let scrollContainer: HTMLDivElement | undefined = $state();
|
let scrollContainer: HTMLDivElement | undefined = $state();
|
||||||
let autoScroll = $state(true);
|
let autoScroll = $state(true);
|
||||||
let restarting = $state(false);
|
let restarting = $state(false);
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@
|
||||||
|
|
||||||
{#if open}
|
{#if open}
|
||||||
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
<!-- svelte-ignore a11y_no_static_element_interactions -->
|
||||||
|
<!-- svelte-ignore a11y_click_events_have_key_events -->
|
||||||
<div class="backdrop" onclick={close}></div>
|
<div class="backdrop" onclick={close}></div>
|
||||||
<div class="panel" data-testid="notification-panel">
|
<div class="panel" data-testid="notification-panel">
|
||||||
<div class="panel-header">
|
<div class="panel-header">
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<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 { EditorView, keymap, lineNumbers, highlightActiveLine, highlightActiveLineGutter, drawSelection, rectangularSelection, crosshairCursor, dropCursor } from '@codemirror/view';
|
||||||
import { EditorState } from '@codemirror/state';
|
import { EditorState } from '@codemirror/state';
|
||||||
import { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands';
|
import { defaultKeymap, history, historyKeymap, indentWithTab } from '@codemirror/commands';
|
||||||
|
|
@ -234,7 +234,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// When content prop changes externally (different file loaded), replace editor content
|
// When content prop changes externally (different file loaded), replace editor content
|
||||||
let lastContent = $state(content);
|
let lastContent = $state(untrack(() => content));
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const c = content;
|
const c = content;
|
||||||
if (view && c !== lastContent) {
|
if (view && c !== lastContent) {
|
||||||
|
|
@ -249,7 +249,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// When lang changes, recreate editor
|
// When lang changes, recreate editor
|
||||||
let lastLang = $state(lang);
|
let lastLang = $state(untrack(() => lang));
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const l = lang;
|
const l = lang;
|
||||||
if (l !== lastLang && view) {
|
if (l !== lastLang && view) {
|
||||||
|
|
|
||||||
|
|
@ -287,7 +287,7 @@
|
||||||
{#if showShortcuts}
|
{#if showShortcuts}
|
||||||
<div class="shortcuts-header">
|
<div class="shortcuts-header">
|
||||||
<h3>Keyboard Shortcuts</h3>
|
<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">
|
<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"/>
|
<path d="M2 2l10 10M12 2L2 12" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
|
||||||
|
|
@ -387,7 +387,7 @@
|
||||||
onkeydown={handleKeydown}
|
onkeydown={handleKeydown}
|
||||||
rows="1"
|
rows="1"
|
||||||
></textarea>
|
></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">
|
<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"/>
|
<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>
|
</svg>
|
||||||
|
|
|
||||||
|
|
@ -176,6 +176,7 @@
|
||||||
class:active={status === 'active'}
|
class:active={status === 'active'}
|
||||||
class:sleeping={status === 'sleeping'}
|
class:sleeping={status === 'sleeping'}
|
||||||
onclick={() => setActiveProject(project.id)}
|
onclick={() => setActiveProject(project.id)}
|
||||||
|
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') setActiveProject(project.id); }}
|
||||||
role="button"
|
role="button"
|
||||||
tabindex="0"
|
tabindex="0"
|
||||||
>
|
>
|
||||||
|
|
@ -416,10 +417,6 @@
|
||||||
min-width: 6rem;
|
min-width: 6rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.agent-card.tier2 .card-actions {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.unread-badge {
|
.unread-badge {
|
||||||
background: var(--ctp-red);
|
background: var(--ctp-red);
|
||||||
color: var(--ctp-base);
|
color: var(--ctp-base);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { onMount, onDestroy } from 'svelte';
|
import { onMount, onDestroy, untrack } from 'svelte';
|
||||||
import { convertFileSrc } from '@tauri-apps/api/core';
|
import { convertFileSrc } from '@tauri-apps/api/core';
|
||||||
import * as pdfjsLib from 'pdfjs-dist';
|
import * as pdfjsLib from 'pdfjs-dist';
|
||||||
|
|
||||||
|
|
@ -164,7 +164,7 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
// React to filePath changes
|
// React to filePath changes
|
||||||
let lastPath = $state(filePath);
|
let lastPath = $state(untrack(() => filePath));
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const p = filePath;
|
const p = filePath;
|
||||||
if (p !== lastPath) {
|
if (p !== lastPath) {
|
||||||
|
|
|
||||||
|
|
@ -97,23 +97,29 @@
|
||||||
<span class="info-sep">·</span>
|
<span class="info-sep">·</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if health && health.externalConflictCount > 0}
|
{#if health && health.externalConflictCount > 0}
|
||||||
<button
|
<span
|
||||||
class="info-conflict info-conflict-external"
|
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"
|
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)); }}
|
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' : ''} ✕
|
⚡ {health.externalConflictCount} ext write{health.externalConflictCount > 1 ? 's' : ''} ✕
|
||||||
</button>
|
</span>
|
||||||
<span class="info-sep">·</span>
|
<span class="info-sep">·</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if health && health.fileConflictCount - (health.externalConflictCount ?? 0) > 0}
|
{#if health && health.fileConflictCount - (health.externalConflictCount ?? 0) > 0}
|
||||||
<button
|
<span
|
||||||
class="info-conflict"
|
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"
|
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)); }}
|
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' : ''} ✕
|
⚠ {health.fileConflictCount - (health.externalConflictCount ?? 0)} conflict{health.fileConflictCount - (health.externalConflictCount ?? 0) > 1 ? 's' : ''} ✕
|
||||||
</button>
|
</span>
|
||||||
<span class="info-sep">·</span>
|
<span class="info-sep">·</span>
|
||||||
{/if}
|
{/if}
|
||||||
{#if contextPct !== null && contextPct > 0}
|
{#if contextPct !== null && contextPct > 0}
|
||||||
|
|
|
||||||
|
|
@ -673,6 +673,7 @@
|
||||||
class:on={filesSaveOnBlur}
|
class:on={filesSaveOnBlur}
|
||||||
role="switch"
|
role="switch"
|
||||||
aria-checked={filesSaveOnBlur}
|
aria-checked={filesSaveOnBlur}
|
||||||
|
aria-label="Save on blur"
|
||||||
onclick={() => { filesSaveOnBlur = !filesSaveOnBlur; saveGlobalSetting('files_save_on_blur', String(filesSaveOnBlur)); }}
|
onclick={() => { filesSaveOnBlur = !filesSaveOnBlur; saveGlobalSetting('files_save_on_blur', String(filesSaveOnBlur)); }}
|
||||||
>
|
>
|
||||||
<span class="toggle-thumb"></span>
|
<span class="toggle-thumb"></span>
|
||||||
|
|
@ -737,6 +738,7 @@
|
||||||
class:on={isProviderEnabled(provider.id)}
|
class:on={isProviderEnabled(provider.id)}
|
||||||
role="switch"
|
role="switch"
|
||||||
aria-checked={isProviderEnabled(provider.id)}
|
aria-checked={isProviderEnabled(provider.id)}
|
||||||
|
aria-label="Toggle {provider.name} enabled"
|
||||||
onclick={() => toggleProviderEnabled(provider.id)}
|
onclick={() => toggleProviderEnabled(provider.id)}
|
||||||
>
|
>
|
||||||
<span class="toggle-thumb"></span>
|
<span class="toggle-thumb"></span>
|
||||||
|
|
@ -2575,20 +2577,6 @@
|
||||||
flex-shrink: 0;
|
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 {
|
.agent-prompt-input {
|
||||||
padding: 0.375rem 0.5rem;
|
padding: 0.375rem 0.5rem;
|
||||||
background: var(--ctp-base);
|
background: var(--ctp-base);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue