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 -4
View File
@@ -29,6 +29,7 @@ import { VacationRescueTip } from '@/components/dashboard/VacationRescueTip'
import { ParentalLeaveBreakdown } from '@/components/dashboard/ParentalLeaveBreakdown'
import { TipCard } from '@/components/inputs/TipCard'
import { Onboarding } from '@/pages/Onboarding'
import { Alert } from '@/components/common/Alert'
import type { RescueDay, Tip } from '@/types'
/** Key matching `rescueDayGroups`' own `Map` key below — shared so a
@@ -332,9 +333,9 @@ export function Dashboard(): ReactNode {
<Layout>
<div data-testid="dashboard" className="dashboard">
{analyticsError && (
<div className="alert alert--error" data-testid="error-banner" role="alert">
<Alert variant="error" testId="error-banner">
{analyticsError}
</div>
</Alert>
)}
{analytics && selectedChild && (
@@ -371,9 +372,9 @@ export function Dashboard(): ReactNode {
<h2>{t('dashboard.leaveOverviewTitle')}</h2>
{age4Bars.length > 0 && <Age4Bars bars={age4Bars} />}
{proposalError && (
<div className="alert alert--error" role="alert" data-testid="dashboard-proposal-error">
<Alert variant="error" testId="dashboard-proposal-error">
{proposalError}
</div>
</Alert>
)}
<YearRows
parents={yearRowParents}