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) <noreply@anthropic.com>
This commit is contained in:
Till JS 2026-03-30 21:37:56 +02:00
parent b9232438cf
commit 4a5fe3bee8
14 changed files with 1150 additions and 365 deletions

View file

@ -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
<!-- Immer editierbar, kein Mode-Switch -->
<span
contenteditable="true"
role="textbox"
spellcheck="true"
onkeydown={handleKeydown}
onblur={handleBlur}
>
{item.title}
</span>
```
**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<HTMLElement>('.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<HTMLInputElement>('.quick-input-bar input')?.focus();
}
}
}
```
**Von der InputBar in die Liste (Page-Level Handler):**
```svelte
<svelte:window onkeydown={(e) => {
const target = e.target as HTMLElement;
if (target.closest('.quick-input-bar') && (e.key === 'ArrowUp' || e.key === 'Tab')) {
const first = document.querySelector<HTMLElement>('.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 | `<span>``<input>` | Keiner |
| Mehrzeilig | Braucht `<textarea>` | Nativ |
| Styling | Muss Input an Span anpassen | Gleich |
**Wann Input statt contenteditable:**
- Formular-Felder mit Validierung (Datum, Zahl, E-Mail)
- Wenn `type="date"`, `type="number"` etc. benötigt wird
- In Expanded-Forms/Modals (nicht inline)
### Debug-Borders (Entwickler-Tool)
`Ctrl+Shift+D` aktiviert farbkodierte Outlines für alle UI-Elemente. Nutzt `outline` statt `border` um Layout nicht zu beeinflussen. State wird in localStorage persistiert.
```css
.debug-mode * {
outline: 1px solid rgba(255, 0, 0, 0.3) !important;
}
.debug-mode div {
outline-color: rgba(255, 0, 0, 0.4) !important;
}
.debug-mode section {
outline-color: rgba(0, 100, 255, 0.5) !important;
}
.debug-mode nav {
outline-color: rgba(0, 180, 0, 0.5) !important;
}
.debug-mode button {
outline-color: rgba(255, 220, 0, 0.6) !important;
}
.debug-mode input,
.debug-mode textarea {
outline-color: rgba(139, 92, 246, 0.6) !important;
}
```
Aktuell in Todo implementiert, geplant als `@manacore/shared-debug` Package.
## Z-Index-Hierarchie
Konsistente Schichtung für Overlays:
@ -390,6 +516,10 @@ font-bold: 700 /* Wichtige Titel */
- [ ] Inline-Interaktion statt Modal möglich?
- [ ] Loading/Error/Empty States vorhanden?
- [ ] Tastatur-Navigation funktioniert?
- [ ] Listen: Arrow/Tab-Navigation zwischen Einträgen?
- [ ] Listen: Zirkuläre Navigation zu InputBar?
- [ ] Inline-Editing: contenteditable statt Input-Toggle?
- [ ] Keine Hover-Effekte auf Listeneinträgen?
- [ ] Animations sparsam und sinnvoll?
- [ ] CSS-Variablen statt hardcoded Farben?
- [ ] Konsistente Spacing-Werte?