fix(redesign): a11y, mobile, perf polish for production push
Comprehensive pre-production sweep across the Aurora redesign — drives svelte-check to 0 errors / 0 warnings (was 61) without changing visual intent. Highlights: - Mobile: hero title shrinks at 480px, signal-list stacks timestamp under sentence below 640px, sidebar icon buttons bumped to 40x40 - Light theme: muted-foreground darkened to #3a3560 to clear WCAG AA on glass surfaces and the modal close button - Perf: topbar backdrop-filter 28→14px, mobile-more sheet 28→12px to cut concurrent blur layers on mid-tier mobile - a11y: prefers-reduced-motion mute for aurora drift / pulses / shimmer / stagger; aria-label on every icon-only button; aria-describedby on Hint; combobox/listbox/aria-activedescendant on SearchPalette; modal dialog tabindex; 47 label-without-control warnings across 14 form pages cleaned up via for=/id= or label→div - Dashboard derived state split into topology- vs status-bound layers so polling no longer re-runs the full provider/wires computation - Mobile bottom nav derived from baseNavEntries by key lookup so adding a top-level nav entry keeps the two trees in sync - Bug: template-configs page now respects the global provider filter for both the count meter and the type pill (was reading the unfiltered cache) - Misc: portal EventChart tooltip and switch its swatches to Aurora tokens; CollapsibleSlot warning state uses warning-fg/-bg tokens instead of #d97706; Hint z-index 99999→9999; element refs across Modal/EntitySelect/MultiEntitySelect/SearchPalette/IconGridSelect/ Hint/targets converted to \$state for reactivity; 4 dead .topbar-cta selectors removed
This commit is contained in:
@@ -26,7 +26,9 @@
|
||||
let query = $state('');
|
||||
let activeIndex = $state(0);
|
||||
let loading = $state(false);
|
||||
let inputEl: HTMLInputElement;
|
||||
let inputEl = $state<HTMLInputElement | undefined>();
|
||||
const listboxId = 'sp-listbox';
|
||||
const optionId = (idx: number) => `sp-option-${idx}`;
|
||||
|
||||
// Expose openPalette to parent via callback
|
||||
$effect(() => { onopen?.(openPalette); });
|
||||
@@ -206,7 +208,7 @@
|
||||
|
||||
{#if open}
|
||||
<!-- Backdrop -->
|
||||
<div class="sp-backdrop" onclick={closePalette} role="presentation"></div>
|
||||
<div class="sp-backdrop" onclick={closePalette} onkeydown={(e) => { if (e.key === 'Escape') closePalette(); }} role="button" tabindex="-1" aria-label={t('searchPalette.close')}></div>
|
||||
|
||||
<!-- Palette -->
|
||||
<div class="sp-container">
|
||||
@@ -218,11 +220,16 @@
|
||||
placeholder={t('searchPalette.placeholder')}
|
||||
class="sp-input"
|
||||
type="text"
|
||||
role="combobox"
|
||||
aria-expanded={flatResults.length > 0}
|
||||
aria-controls={listboxId}
|
||||
aria-activedescendant={flatResults.length > 0 ? optionId(activeIndex) : undefined}
|
||||
aria-autocomplete="list"
|
||||
/>
|
||||
<kbd class="sp-kbd">ESC</kbd>
|
||||
</div>
|
||||
|
||||
<div class="sp-results">
|
||||
<div class="sp-results" id={listboxId} role="listbox">
|
||||
{#if loading}
|
||||
<div class="sp-empty">
|
||||
<div class="w-4 h-4 rounded-full border-2 border-[var(--color-primary)] border-t-transparent animate-spin"></div>
|
||||
@@ -239,9 +246,12 @@
|
||||
<MdiIcon name={group.icon} size={14} />
|
||||
{group.label}
|
||||
</div>
|
||||
{#each group.items as item, i}
|
||||
{#each group.items as item}
|
||||
{@const flatIdx = flatIndexMap.get(item) ?? -1}
|
||||
<button
|
||||
id={optionId(flatIdx)}
|
||||
role="option"
|
||||
aria-selected={flatIdx === activeIndex}
|
||||
class="sp-item"
|
||||
class:sp-active={flatIdx === activeIndex}
|
||||
onclick={() => navigateTo(item)}
|
||||
|
||||
Reference in New Issue
Block a user