From 8ffb6a0690cf5c5cca7a7f3c5682d46f63a1a6ea Mon Sep 17 00:00:00 2001 From: mARTin Date: Mon, 6 Apr 2026 00:25:08 +0200 Subject: [PATCH] =?UTF-8?q?feat:=20accessibility=20follow-up=20=E2=80=94?= =?UTF-8?q?=20heading=20hierarchy,=20keyboard=20resize,=20contrast=20fix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Fix heading hierarchy: modal titles h3→h2 (RecurrenceModal, two WeeklyView dialogs), SettingsSidebar h4→h3 for Localisation, Data Export, Backup & Restore sections - Add keyboard resize handle: role=slider, tabIndex, aria-valuemin/max/now/text, ArrowUp/Down keys to adjust task duration in 15-min increments - Add aria-label to CalendarEventModal notes textarea fallback - Color contrast: raise --weekly-text-light from #a6a6a7 (~2.4:1) to #767676 (~4.5:1) on white background to meet WCAG AA v1.86.0 --- package.json | 2 +- src/app/globals.css | 2 +- src/components/CalendarEventModal.tsx | 90 ++++++++++++++++++--------- src/components/GridTaskBlock.tsx | 26 +++++++- src/components/RecurrenceModal.tsx | 2 +- src/components/SettingsSidebar.tsx | 12 ++-- src/components/WeeklyView.tsx | 10 +-- 7 files changed, 98 insertions(+), 46 deletions(-) diff --git a/package.json b/package.json index b0ed7c1..96937a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "my-weekly-todo-list", - "version": "1.85.0", + "version": "1.86.0", "description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view", "main": "index.js", "scripts": { diff --git a/src/app/globals.css b/src/app/globals.css index f8c6dc0..0eac477 100644 --- a/src/app/globals.css +++ b/src/app/globals.css @@ -455,7 +455,7 @@ h3 { --weekly-teal: #009a9a; --weekly-bg: #ffffff; --weekly-text: #000000; - --weekly-text-light: #a6a6a7; + --weekly-text-light: #767676; --weekly-border: #cccccc; --weekly-completed: #cccccc; --weekly-font: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; diff --git a/src/components/CalendarEventModal.tsx b/src/components/CalendarEventModal.tsx index 97bfa92..931ae53 100644 --- a/src/components/CalendarEventModal.tsx +++ b/src/components/CalendarEventModal.tsx @@ -415,7 +415,7 @@ export default function CalendarEventModal({
- {error &&
{error}
} + {error && } {/* Title */} setTitle(e.target.value)} placeholder={language === 'de' ? 'Titel hinzufügen' : 'Add title'} aria-label={language === 'de' ? 'Ereignistitel' : 'Event title'} + aria-describedby={error ? 'cal-event-error' : undefined} autoFocus style={{ width: '100%', padding: '3px 0', fontSize: '1rem', fontWeight: 600, @@ -444,6 +445,9 @@ export default function CalendarEventModal({ type="button" onClick={() => !event && setIsCalendarSelectorOpen(!isCalendarSelectorOpen)} disabled={!!event} + aria-label={language === 'de' ? 'Kalender auswählen' : 'Select calendar'} + aria-expanded={isCalendarSelectorOpen} + aria-haspopup="listbox" style={{ display: 'flex', alignItems: 'center', gap: '4px', background: 'transparent', border: 'none', fontWeight: 500, @@ -502,14 +506,15 @@ export default function CalendarEventModal({ {/* All Day toggle */}
-
+
{language === 'de' ? 'Ganztägig' : 'All day'} -
@@ -879,6 +906,7 @@ export default function CalendarEventModal({ value={description} onChange={e => setDescription(e.target.value)} placeholder={language === 'de' ? 'Notizen' : 'Notes'} + aria-label={language === 'de' ? 'Notizen' : 'Notes'} rows={2} style={{ width: '100%', padding: '3px 0', border: 'none', background: 'transparent', resize: 'none', fontSize: '0.78rem', outline: 'none', color: 'var(--weekly-text)' }} /> diff --git a/src/components/GridTaskBlock.tsx b/src/components/GridTaskBlock.tsx index e7fa473..a5a3645 100644 --- a/src/components/GridTaskBlock.tsx +++ b/src/components/GridTaskBlock.tsx @@ -232,6 +232,19 @@ export function GridTaskBlock({ document.body.style.cursor = "ns-resize"; }; + const onResizeKeyDown = (e: React.KeyboardEvent) => { + if (e.key !== 'ArrowUp' && e.key !== 'ArrowDown') return; + e.preventDefault(); + e.stopPropagation(); + const step = 15; + const newDuration = e.key === 'ArrowUp' + ? Math.min(duration + step, 480) + : Math.max(duration - step, 15); + if (newDuration !== duration) { + updateTaskDuration(task.id, newDuration); + } + }; + return (
)} -
+
); } diff --git a/src/components/RecurrenceModal.tsx b/src/components/RecurrenceModal.tsx index c3bbc3c..a8446e6 100644 --- a/src/components/RecurrenceModal.tsx +++ b/src/components/RecurrenceModal.tsx @@ -75,7 +75,7 @@ export default function RecurrenceModal({ task, onClose, onSave, language = 'en' return (
e.stopPropagation()} style={{ maxWidth: '400px' }}> -

{isDE ? 'Wiederkehrende Aufgabe' : 'Recurring Task'}

+

{isDE ? 'Wiederkehrende Aufgabe' : 'Recurring Task'}

diff --git a/src/components/SettingsSidebar.tsx b/src/components/SettingsSidebar.tsx index 1f5271f..f7465c1 100644 --- a/src/components/SettingsSidebar.tsx +++ b/src/components/SettingsSidebar.tsx @@ -1389,9 +1389,9 @@ function SettingsSidebar({
-

+

{t.localisation || "Localisation"} -

+ {/* Start Week Setting + Start View On */}
@@ -4226,7 +4226,7 @@ function SettingsSidebar({ borderTop: "1px solid var(--weekly-border)", }} > -

{profile.language === "de" ? "Datenexport" : "Data Export"} -

+

-

{t.backupRestore} -

+

{syncError - ? + ? : (isLoading || isSyncing || syncStatus === "syncing") ?

: null} @@ -8208,10 +8208,10 @@ export default function WeeklyView() { className="bg-white dark:bg-zinc-900 p-6 rounded-xl shadow-2xl w-full max-w-md" onClick={(e) => e.stopPropagation()} > -

+

NEW LIST -

+

Create a new section for your tasks

@@ -8426,9 +8426,9 @@ export default function WeeklyView() {
-

+

Recurring Task -

+

Deletion Options