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:
@@ -21,6 +21,16 @@ export function relativeTime(iso: string | null | undefined): string {
|
||||
return `${d}d ago`;
|
||||
}
|
||||
|
||||
// debounce wraps fn so rapid calls (e.g. keystrokes in a filter input)
|
||||
// collapse into one invocation after `wait`ms of silence.
|
||||
export function debounce<T extends (...args: never[]) => void>(fn: T, wait = 300): T {
|
||||
let timer: ReturnType<typeof setTimeout> | undefined;
|
||||
return ((...args: Parameters<T>) => {
|
||||
clearTimeout(timer);
|
||||
timer = setTimeout(() => fn(...args), wait);
|
||||
}) as T;
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
export type WithoutChild<T> = T extends { child?: any } ? Omit<T, "child"> : T;
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
|
||||
Reference in New Issue
Block a user