Add WCAG 2.1 Level AA accessibility across all components

This commit is contained in:
Your Name
2026-02-07 12:10:10 +02:00
parent 3427c629c0
commit 6d2707770d
18 changed files with 459 additions and 226 deletions

View File

@@ -109,7 +109,7 @@
}
// Day label
ctx.fillStyle = "#444";
ctx.fillStyle = "#8a8a8a";
ctx.font = "10px -apple-system, sans-serif";
ctx.textAlign = "center";
const label = day.date.slice(5); // "MM-DD"
@@ -117,6 +117,14 @@
});
}
// Accessible chart summary
const chartAriaLabel = $derived(() => {
if (history.length === 0) return "No break history data available";
const total = history.reduce((sum, d) => sum + d.breaksCompleted, 0);
const skipped = history.reduce((sum, d) => sum + d.breaksSkipped, 0);
return `Weekly break chart: ${total} completed and ${skipped} skipped over ${history.length} days`;
});
function roundedRect(
ctx: CanvasRenderingContext2D,
x: number,
@@ -149,10 +157,11 @@
aria-label="Back to dashboard"
use:pressable
class="mr-3 flex h-8 w-8 items-center justify-center rounded-full
text-[#444] transition-colors hover:text-white"
text-[#8a8a8a] transition-colors hover:text-white"
onclick={goBack}
>
<svg
aria-hidden="true"
width="16"
height="16"
viewBox="0 0 24 24"
@@ -167,6 +176,7 @@
</button>
<h1
data-tauri-drag-region
tabindex="-1"
class="flex-1 text-lg font-medium text-white"
>
Statistics
@@ -179,7 +189,7 @@
<!-- Today's summary -->
<section class="rounded-2xl p-5 backdrop-blur-xl" style="background: rgba(17,17,17,0.7);" use:inView={{ delay: 0 }}>
<h3
class="mb-4 text-[11px] font-medium tracking-[0.15em] text-[#666] uppercase"
class="mb-4 text-[11px] font-medium tracking-[0.15em] text-[#8a8a8a] uppercase"
>
Today
</h3>
@@ -189,7 +199,7 @@
<div class="text-[28px] font-semibold text-white tabular-nums">
{stats?.todayCompleted ?? 0}
</div>
<div class="text-[11px] text-[#777]">Breaks taken</div>
<div class="text-[11px] text-[#8a8a8a]">Breaks taken</div>
</div>
<div class="text-center">
<div class="text-[28px] font-semibold tabular-nums"
@@ -197,19 +207,19 @@
>
{compliancePercent}%
</div>
<div class="text-[11px] text-[#777]">Compliance</div>
<div class="text-[11px] text-[#8a8a8a]">Compliance</div>
</div>
<div class="text-center">
<div class="text-[28px] font-semibold text-white tabular-nums">
{breakTimeFormatted()}
</div>
<div class="text-[11px] text-[#777]">Break time</div>
<div class="text-[11px] text-[#8a8a8a]">Break time</div>
</div>
<div class="text-center">
<div class="text-[28px] font-semibold text-white tabular-nums">
{stats?.todaySkipped ?? 0}
</div>
<div class="text-[11px] text-[#777]">Skipped</div>
<div class="text-[11px] text-[#8a8a8a]">Skipped</div>
</div>
</div>
</section>
@@ -217,7 +227,7 @@
<!-- Streak -->
<section class="rounded-2xl p-5 backdrop-blur-xl" style="background: rgba(17,17,17,0.7);" use:inView={{ delay: 0.06 }}>
<h3
class="mb-4 text-[11px] font-medium tracking-[0.15em] text-[#666] uppercase"
class="mb-4 text-[11px] font-medium tracking-[0.15em] text-[#8a8a8a] uppercase"
>
Streak
</h3>
@@ -225,7 +235,7 @@
<div class="flex items-center justify-between">
<div>
<div class="text-[13px] text-white">Current streak</div>
<div class="text-[11px] text-[#777]">Consecutive days with breaks</div>
<div class="text-[11px] text-[#8a8a8a]">Consecutive days with breaks</div>
</div>
<div class="text-[24px] font-semibold tabular-nums" style="color: {$config.accent_color}">
{stats?.currentStreak ?? 0}
@@ -237,7 +247,7 @@
<div class="flex items-center justify-between">
<div>
<div class="text-[13px] text-white">Best streak</div>
<div class="text-[11px] text-[#777]">All-time record</div>
<div class="text-[11px] text-[#8a8a8a]">All-time record</div>
</div>
<div class="text-[24px] font-semibold text-white tabular-nums">
{stats?.bestStreak ?? 0}
@@ -248,17 +258,39 @@
<!-- Weekly chart -->
<section class="rounded-2xl p-5 backdrop-blur-xl" style="background: rgba(17,17,17,0.7);" use:inView={{ delay: 0.12 }}>
<h3
class="mb-4 text-[11px] font-medium tracking-[0.15em] text-[#666] uppercase"
class="mb-4 text-[11px] font-medium tracking-[0.15em] text-[#8a8a8a] uppercase"
>
Last 7 Days
</h3>
<!-- svelte-ignore a11y_no_interactive_element_to_noninteractive_role -->
<canvas
bind:this={chartCanvas}
class="h-[140px] w-full"
role="img"
aria-label={chartAriaLabel()}
></canvas>
<div class="mt-3 flex items-center justify-center gap-4 text-[10px] text-[#777]">
<!-- Screen-reader accessible data table for the chart -->
{#if history.length > 0}
<table class="sr-only">
<caption>Break history for the last {history.length} days</caption>
<thead>
<tr><th>Date</th><th>Completed</th><th>Skipped</th></tr>
</thead>
<tbody>
{#each history as day}
<tr>
<td>{day.date}</td>
<td>{day.breaksCompleted}</td>
<td>{day.breaksSkipped}</td>
</tr>
{/each}
</tbody>
</table>
{/if}
<div class="mt-3 flex items-center justify-center gap-4 text-[10px] text-[#8a8a8a]">
<div class="flex items-center gap-1.5">
<div class="h-2 w-2 rounded-sm" style="background: {$config.accent_color}"></div>
Completed