Pull form fields and alert banners into shared components

FormField owns the .field markup and wires id/aria-invalid/aria-describedby
onto its control; Alert owns role=alert banners. Auth, Join and the partner
invite panel drop their one-off error classes for the shared alert style.
VacationDaysInput and ParentProfileInput move onto the .field primitives.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
2026-09-22 22:02:09 +02:00
parent 1a02bdcdbf
commit e9d7cee66b
21 changed files with 348 additions and 277 deletions
+5 -12
View File
@@ -23,6 +23,7 @@ import { VacationDaysTable, type VacationDaysTableRow } from '@/components/vacat
import { CalendarExceptions } from '@/components/calendar/CalendarExceptions'
import { BalanceFlow } from '@/components/balance/BalanceFlow'
import { PartnerInvitePanel } from '@/components/settings/PartnerInvitePanel'
import { Alert } from '@/components/common/Alert'
import { orderSelfFirst } from '@/utils/members'
import type { VacationDays } from '@/types'
import './settings.css'
@@ -647,13 +648,9 @@ export function Settings(): ReactNode {
<h1>{t('settings.title')}</h1>
{saveMessage && (
<div
className={`alert alert--${saveMessage.type}`}
data-testid="save-message"
role="alert"
>
<Alert variant={saveMessage.type} testId="save-message">
{saveMessage.text}
</div>
</Alert>
)}
<section className="settings-panel">
@@ -815,13 +812,9 @@ export function Settings(): ReactNode {
</>
)}
{memberActionError?.uuid === member.uuid && (
<p
role="alert"
className="alert alert--error"
data-testid={`member-action-error-${member.uuid}`}
>
<Alert variant="error" testId={`member-action-error-${member.uuid}`}>
{memberActionError.text}
</p>
</Alert>
)}
</li>
)