From 4a5fe3bee876853857c91fd1fca13b678f3cc50a Mon Sep 17 00:00:00 2001 From: Till JS Date: Mon, 30 Mar 2026 21:37:56 +0200 Subject: [PATCH] feat(ux): notepad design, keyboard navigation, contenteditable across todo/calendar/contacts Todo: Notepad redesign (A4 width, lined paper, red margin), contenteditable titles, Arrow/Tab navigation between tasks, circular navigation with QuickInputBar, debug borders (Ctrl+Shift+D), removed hover effects, collapsed completed section. Calendar Agenda: contenteditable event titles, Arrow/Tab navigation, circular navigation with InputBar, removed hover effects, separate detail button. Contacts Alphabet: contenteditable contact names, Arrow/Tab navigation, circular navigation with InputBar, removed card hover, avatar as detail button. Guidelines: new sections for list navigation, contenteditable patterns, debug borders. Co-Authored-By: Claude Opus 4.6 (1M context) --- .claude/guidelines/design-ux.md | 130 ++++ .../lib/components/calendar/AgendaView.svelte | 125 +++- .../apps/web/src/routes/(app)/+page.svelte | 18 + .../views/ContactAlphabetView.svelte | 105 ++- .../apps/web/src/routes/(app)/+page.svelte | 16 + .../2026-03-30-todo-ux-keyboard-navigation.md | 166 +++++ apps/todo/apps/web/src/app.css | 68 +- .../web/src/lib/components/TaskItem.svelte | 134 ++-- .../web/src/lib/components/TaskList.svelte | 8 +- .../apps/web/src/lib/stores/debug.svelte.ts | 21 + .../web/src/lib/stores/settings.svelte.ts | 25 + .../apps/web/src/routes/(app)/+layout.svelte | 14 +- .../apps/web/src/routes/(app)/+page.svelte | 655 ++++++++++++------ apps/todo/apps/web/src/routes/+layout.svelte | 30 +- 14 files changed, 1150 insertions(+), 365 deletions(-) create mode 100644 apps/manacore/apps/landing/src/content/devlog/2026-03-30-todo-ux-keyboard-navigation.md create mode 100644 apps/todo/apps/web/src/lib/stores/debug.svelte.ts diff --git a/.claude/guidelines/design-ux.md b/.claude/guidelines/design-ux.md index 260844dbc..6aba53434 100644 --- a/.claude/guidelines/design-ux.md +++ b/.claude/guidelines/design-ux.md @@ -346,6 +346,132 @@ Text: "Diese Aufgabe wird unwiderruflich gelöscht." | Abbrechen/Schließen | `Escape` | | Navigation | `Tab` / `Shift+Tab` | +### Listen-Navigation mit Tastatur + +In Listen (Tasks, Kontakte, Favoriten etc.) soll der Nutzer sich nahtlos per Tastatur bewegen können, ohne dass Fokus auf nicht-editierbare Elemente (Checkboxes, Drag-Handles) springt. + +**Prinzip: Zirkuläre Navigation zwischen Input und Liste** + +``` +InputBar → ArrowUp/Tab → Erster Listeneintrag + ↕ ArrowUp/Down/Tab/Shift+Tab +Letzter Eintrag → ArrowDown/Tab → InputBar +``` + +**Implementierung mit `contenteditable`:** + +```svelte + + + {item.title} + +``` + +**Keydown-Handler für Listen-Navigation:** + +```typescript +function handleKeydown(e: KeyboardEvent) { + if (e.key === 'Enter') { + e.preventDefault(); + currentRef?.blur(); // Speichert via onblur + } else if (e.key === 'Escape') { + currentRef.textContent = originalValue; // Verwerfen + currentRef?.blur(); + } else if (e.key === 'Tab' || e.key === 'ArrowDown' || e.key === 'ArrowUp') { + const direction = e.key === 'ArrowUp' || (e.key === 'Tab' && e.shiftKey) ? -1 : 1; + e.preventDefault(); + // Alle editierbaren Elemente auf der Seite sammeln + const allEditable = Array.from( + document.querySelectorAll('.item-title[contenteditable]') + ); + const currentIndex = allEditable.indexOf(currentRef!); + const next = allEditable[currentIndex + direction]; + currentRef?.blur(); + if (next) { + next.focus(); + } else { + // Am Rand der Liste: Fokus zur InputBar + document.querySelector('.quick-input-bar input')?.focus(); + } + } +} +``` + +**Von der InputBar in die Liste (Page-Level Handler):** + +```svelte + { + const target = e.target as HTMLElement; + if (target.closest('.quick-input-bar') && (e.key === 'ArrowUp' || e.key === 'Tab')) { + const first = document.querySelector('.item-title[contenteditable]'); + if (first) { + e.preventDefault(); + first.focus(); + } + } +}} /> +``` + +**Regeln:** + +- `contenteditable` statt Input-Toggle: Cursor landet direkt an Klick-Position +- Kein visueller Unterschied zwischen Lese- und Edit-Modus (kein Border, kein Hintergrund) +- Speichern via `blur`-Event (Auto-Save), nicht via explizitem Save-Button +- ArrowDown/Up navigiert vertikal, Tab/Shift+Tab ebenfalls (gleiche Richtung) +- Am Listenende/-anfang springt Fokus zurück zur InputBar (zirkulär) +- Hover-Effekte auf Listeneinträgen vermeiden (ruhige UI) + +### Inline-Editing mit contenteditable + +**Bevorzuge `contenteditable` statt Input-Toggle** für Texte, die direkt in der Ansicht editiert werden. + +| Aspekt | Input-Toggle | contenteditable | +| -------------------- | ------------------------------ | ---------------------------- | +| Klicks zum Editieren | 2 (aktivieren + positionieren) | 1 (Cursor an Klick-Position) | +| DOM-Wechsel | `` ↔ `` | Keiner | +| Mehrzeilig | Braucht `