From 0e2a05e0ea888102e73870b48bb2bafdd37b1bf8 Mon Sep 17 00:00:00 2001 From: Linus Rath <139418639+rathlinus@users.noreply.github.com> Date: Thu, 29 Oct 2026 16:20:56 +0100 Subject: [PATCH] fix: name the event editor's title, date, time and select fields --- .../__tests__/form-labels-calendar.test.tsx | 25 +++++++++ components/calendar/event-modal.tsx | 51 ++++++++++--------- components/calendar/participant-input.tsx | 5 +- 3 files changed, 57 insertions(+), 24 deletions(-) create mode 100644 components/__tests__/form-labels-calendar.test.tsx diff --git a/components/__tests__/form-labels-calendar.test.tsx b/components/__tests__/form-labels-calendar.test.tsx new file mode 100644 index 000000000..ee46e423c --- /dev/null +++ b/components/__tests__/form-labels-calendar.test.tsx @@ -0,0 +1,25 @@ +import { render, screen } from '@testing-library/react'; +import { describe, expect, it, vi } from 'vitest'; +import { unnamedFields } from '@/lib/__tests__/helpers/form-labels'; +import { EventModal } from '@/components/calendar/event-modal'; +import type { Calendar } from '@/lib/jmap/types'; + +// The event editor names every field (see form-labels.test.tsx). The live +// audit found the title, the date and time fields and two selects unnamed. + +const calendars = [ + { id: 'cal-1', name: 'Work', isDefault: true, myRights: { mayWriteAll: true, mayWriteOwn: true } }, + { id: 'cal-2', name: 'Home', myRights: { mayWriteAll: true, mayWriteOwn: true } }, +] as unknown as Calendar[]; + +describe('event editor fields have labels', () => { + it('names the title, dates, times, calendar and repeat fields', () => { + render(); + expect(screen.getByRole('textbox', { name: 'form.title' })).toBeInTheDocument(); + expect(screen.getByLabelText('form.start_date')).toHaveAttribute('type', 'date'); + expect(screen.getByLabelText('form.end_time')).toHaveAttribute('type', 'time'); + expect(screen.getByRole('combobox', { name: 'form.calendar_select' })).toBeInTheDocument(); + expect(screen.getByRole('combobox', { name: 'recurrence.title' })).toBeInTheDocument(); + expect(unnamedFields()).toEqual([]); + }); +}); diff --git a/components/calendar/event-modal.tsx b/components/calendar/event-modal.tsx index ff3dac654..871acc626 100644 --- a/components/calendar/event-modal.tsx +++ b/components/calendar/event-modal.tsx @@ -1,6 +1,6 @@ "use client"; -import { useState, useEffect, useCallback, useRef, useMemo } from "react"; +import { useState, useEffect, useCallback, useRef, useMemo, useId } from "react"; import { useTranslations, useLocale } from "next-intl"; import { toast } from "@/stores/toast-store"; import { Button } from "@/components/ui/button"; @@ -269,6 +269,9 @@ export function EventModal({ }: EventModalProps) { const t = useTranslations("calendar"); const paint = useCvdColor(); + // Ids that tie each visible label to its field. + const labelIdBase = useId(); + const labelFor = (key: string) => `${labelIdBase}-${key}`; const tCommon = useTranslations("common"); const locale = useLocale(); const timeFormat = useSettingsStore((s) => s.timeFormat); @@ -1218,8 +1221,8 @@ export function EventModal({
- - {t("form.title")} + setTitle(e.target.value)} @@ -1229,8 +1232,8 @@ export function EventModal({
- -