fix(reminders): Cursor springt beim Schreiben nicht mehr in den Titel
Tessera CI/CD / Lint & Type Check (push) Successful in 47s
Tessera CI/CD / Tests (push) Successful in 1m24s
Tessera CI/CD / Desktop-Pakete bauen (push) Successful in 18s
Tessera CI/CD / Build & Publish Images (push) Successful in 2m56s

Der Fokus auf das Titelfeld lag im selben Effekt wie der Escape-Listener
mit Abhaengigkeit onClose. Die Kachel uebergibt onClose inline und
zeichnet alle 10 s neu (NOW_TICK_MS) - der Effekt lief jedes Mal erneut
und holte den Cursor aus der Beschreibung zurueck in den Titel. Fokus
jetzt nur beim Oeffnen, Escape ueber eine Ref.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-10-01 11:38:58 +02:00
parent 5919a55cbf
commit 59b8cd43fc
6 changed files with 63 additions and 2 deletions
+1
View File
@@ -484,6 +484,7 @@ Gerettet aus `.continue-here.md`. Relevant fuer die noch offenen Live-Tests.
| 260929-if2 | **Erinnerungen-Widget (Reminder).** Modell `Reminder` + RLS, API /reminders (anlegen/listen/bearbeiten/loeschen/erledigt/snooze, 409/404-Regeln), E-Mail-Scheduler alle 30 s mit Claim-once + max. 3 Versuche, globaler ReminderNotifier (Browser-Notification, Desktop via Tauri-Notification mit Laufzeit-Capability nur fuer die Server-Origin, Pattern escaped + vorab geprueft). Verifier human_needed (Windows-Toast offen); Browser dunkel bestanden inkl. echter Mail ueber MailHog. api 1570, web 1069, cargo 57. Nebenbei: eigene Module ohne Kopfzeile (cd1f8f6), Update-Klick prueft frisch (41d00a3). | 2026-09-29 | 325c5dd,709b41a,6879c75 | [260929-if2-reminder-widget-mit-benachrichtigung](./quick/260929-if2-reminder-widget-mit-benachrichtigung/) |
| 260929-lh3 | **Favoriten: eigene Symbol-Adresse wirkt.** Neue iconUrl ersetzt Upload + bumpt iconVersion; iconUrl wird auch gespeichert, wenn nur der Browser sie laden kann (kein 422 mehr, nur Formpruefung); Kachel: Proxy -> iconUrl direkt -> origin/favicon -> Buchstabe; Discovery liest <link rel=icon> auch aus Nicht-2xx-Seiten (docuvita 400). | 2026-09-29 | 7188c5b,b15c746,0e72ad4 | [260929-lh3-favoriten-eigenes-symbol-wirkt-nicht](./quick/260929-lh3-favoriten-eigenes-symbol-wirkt-nicht/) |
| 261001-cxo | Desktop-Client: Links mit target=_blank (Favoriten) oeffnen jetzt im System-Browser (DesktopExternalLinks -> window.open) | 2026-10-01 | 61a971c | [261001-cxo](./quick/261001-cxo-desktop-client-links-mit-target-blank-oe/) |
| 261001-g68 | Erinnerung: Cursor sprang beim Schreiben der Beschreibung in den Titel (Fokus-Effekt hing an inline onClose, Kachel zeichnet alle 10 s neu) – Fokus nur beim Oeffnen | 2026-10-01 | siehe git log | [261001-g68](./quick/261001-g68-erinnerung-cursor-springt-aus-beschreibu/) |
## Deferred Items
@@ -0,0 +1,14 @@
---
quick_id: 261001-g68
description: "Erinnerung: Cursor springt aus Beschreibung in Titel"
date: 2026-10-01
---
# Erinnerung: Cursor springt aus Beschreibung in Titel
**Befund:** `ReminderFormModal` setzte den Fokus auf den Titel im selben Effekt wie den Escape-Listener, Abhaengigkeit `[onClose]`. `onClose` ist in der Kachel eine Inline-Funktion; die Kachel zeichnet alle 10 s neu (NOW_TICK_MS) und bei jedem Neuladen → Effekt laeuft erneut → Cursor springt in den Titel (User: beim Schreiben, und bei Loeschen-Taste in leerer Beschreibung).
## Task 1
- Fokus-Effekt nur beim Oeffnen (`[]`), Escape-Listener ueber `onCloseRef`.
- Test im Widget: Formular oeffnen, Beschreibung fokussieren, 30 s Takt → Fokus bleibt.
- CHANGELOG „Unveröffentlicht → Behoben“.
@@ -0,0 +1,10 @@
---
quick_id: 261001-g68
status: complete
date: 2026-10-01
---
# Summary
- `reminder-form-modal.tsx`: Fokus auf Titel nur einmal beim Oeffnen; Escape ueber Ref statt `[onClose]`-Abhaengigkeit.
- Neuer Test in `reminder-widget.test.tsx` – schlaegt ohne Fix fehl, mit Fix gruen; 28/28 Erinnerungs-Tests, tsc, biome sauber.
- Andere Dialoge mit `[onClose]`-Fokus (Widget-Katalog, Bilderrahmen-Lightbox) fokussieren nur den Dialog ohne Eingabefelder – nicht betroffen.
+1
View File
@@ -7,6 +7,7 @@ Diese Liste beschreibt in einfachen Worten, was sich von Version zu Version an T
### Behoben
- Desktop-App: Favoriten und andere Links, die sich in einem neuen Fenster öffnen (etwa „In neuem Tab öffnen“ oder Quellen im Ausschreibungs-Radar), öffnen sich jetzt in Ihrem normalen Browser. Bisher passierte beim Klick in der Desktop-App nichts.
- Erinnerungen: Beim Schreiben der Beschreibung springt der Cursor nicht mehr in die Titelzeile zurück. Bisher passierte das alle paar Sekunden, weil sich die Kachel regelmäßig neu aufbaut.
## 1.9.0 – 2026-09-30
@@ -65,14 +65,23 @@ export function ReminderFormModal({
const [error, setError] = useState<string | null>(null);
const titleRef = useRef<HTMLInputElement>(null);
// Fokus nur EINMAL beim Oeffnen (quick-261001-g68): `onClose` kommt aus der
// Kachel als neue Funktion bei jedem Neuzeichnen — die Kachel zeichnet alle
// 10 s neu (NOW_TICK_MS). Hing der Fokus mit am `onClose`-Effekt, sprang der
// Cursor beim Schreiben der Beschreibung immer wieder in den Titel.
useEffect(() => {
titleRef.current?.focus();
}, []);
const onCloseRef = useRef(onClose);
onCloseRef.current = onClose;
useEffect(() => {
const onKey = (e: KeyboardEvent) => {
if (e.key === 'Escape') onClose();
if (e.key === 'Escape') onCloseRef.current();
};
document.addEventListener('keydown', onKey);
return () => document.removeEventListener('keydown', onKey);
}, [onClose]);
}, []);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
@@ -349,6 +349,32 @@ describe('ReminderWidget — Faelligkeit ohne Neuladen', () => {
});
});
describe('ReminderWidget — Formular behaelt den Fokus (quick-261001-g68)', () => {
afterEach(() => {
vi.useRealTimers();
});
it('der 10-s-Takt der Kachel holt den Cursor nicht aus der Beschreibung zurueck in den Titel', async () => {
vi.useFakeTimers();
vi.setSystemTime(new Date('2026-09-29T12:00:00.000Z'));
mockList.mockResolvedValue([]);
render(<ReminderWidget {...props} />);
await act(async () => {
await vi.advanceTimersByTimeAsync(0);
});
fireEvent.click(screen.getByText('reminder.add'));
expect(document.activeElement).toBe(screen.getByLabelText('reminder.titleLabel'));
const description = screen.getByLabelText('reminder.descriptionLabel');
description.focus();
fireEvent.change(description, { target: { value: 'Unterlagen mitnehmen' } });
await act(async () => {
await vi.advanceTimersByTimeAsync(30_000);
});
expect(document.activeElement).toBe(description);
});
});
describe('ReminderWidget — Spaeter erinnern kurz nach Mitternacht', () => {
afterEach(() => {
vi.useRealTimers();