fix(ui): implement UI review findings — a11y, IA, and consistency fixes

Fixes the reviewed gaps: keyboard-inaccessible delete controls (SessionRail,
Entities row), case-sensitive entity filter, two competing entity-detail
navigation patterns (standardize on EntitySheet), non-clickable Overview KPI
cards, a bare button bypassing the shared Button component, inconsistent
blur-only vs live filtering, and an unenforced sanitization assumption on
search snippet HTML (now using the already-present dompurify dependency).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-11 21:52:59 +02:00
parent b72267bd72
commit fb4c76ba82
12 changed files with 404 additions and 88 deletions

View File

@@ -44,13 +44,14 @@
const types = $derived(Array.from(new Set(entities.map((e) => e.type))).sort())
const filtered = $derived(
entities.filter((e) => {
const filtered = $derived.by(() => {
const q = query.trim().toLowerCase()
return entities.filter((e) => {
if (typeFilter !== 'all' && e.type !== typeFilter) return false
if (query && !e.slug.includes(query) && !e.name.includes(query)) return false
if (q && !e.slug.toLowerCase().includes(q) && !e.name.toLowerCase().includes(q)) return false
return true
})
)
})
function stateVariant(state?: string | null): 'default' | 'secondary' | 'outline' {
if (!state) return 'outline'
@@ -116,7 +117,10 @@
{#each filtered as entity (entity.id)}
<Table.Row
class="cursor-pointer"
role="button"
tabindex={0}
onclick={() => openEntity(entity.slug)}
onkeydown={(e) => { if (e.key === 'Enter' || e.key === ' ') { e.preventDefault(); openEntity(entity.slug) } }}
>
<Table.Cell class="font-mono text-xs">{entity.slug}</Table.Cell>
<Table.Cell><Badge variant="outline">{entity.type}</Badge></Table.Cell>