Skip to content

Commit

Permalink
refactor: improve accessibility and error handling for single field c…
Browse files Browse the repository at this point in the history
…omponents tckt-393
  • Loading branch information
kalasgarov committed Nov 27, 2024
1 parent 9d270c3 commit 81d49d2
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 23 deletions.
47 changes: 29 additions & 18 deletions packages/design/src/Form/components/DateOfBirth/DateOfBirth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ const months = [
{ value: '12', label: 'December' },
];

const getAriaDescribedBy = (
errorId: string | null,
hintId: string | null
): string | undefined => {
const ids = [errorId, hintId].filter(Boolean).join(' ');
return ids || undefined;
};

export const DateOfBirthPattern: PatternComponent<DateOfBirthProps> = ({
monthId,
dayId,
Expand All @@ -29,6 +37,8 @@ export const DateOfBirthPattern: PatternComponent<DateOfBirthProps> = ({
error,
}) => {
const { register } = useFormContext();
const errorId = `input-error-message-${monthId}`;
const hintId = `hint-${monthId}`;

return (
<fieldset className="usa-fieldset">
Expand All @@ -37,16 +47,12 @@ export const DateOfBirthPattern: PatternComponent<DateOfBirthProps> = ({
{required && <span className="required-indicator">*</span>}
</legend>
{hint && (
<span className="usa-hint" id={`hint-${monthId}`}>
<span className="usa-hint" id={hintId}>
{hint}
</span>
)}
{error && (
<div
className="usa-error-message"
id={`input-error-message-${monthId}`}
role="alert"
>
<div className="usa-error-message" id={errorId} role="alert">
{error.message}
</div>
)}
Expand All @@ -57,12 +63,15 @@ export const DateOfBirthPattern: PatternComponent<DateOfBirthProps> = ({
</label>
<select
className={classNames('usa-input', {
'usa-input--error': error,
'usa-input--error': !!error,
})}
id={monthId}
{...register(monthId)}
aria-describedby={
error ? `${monthId} input-error-message-${monthId}}` : monthId
getAriaDescribedBy(
error ? errorId : null,
hint ? hintId : null
) || undefined
}
>
<option key="default" value="">
Expand All @@ -81,17 +90,18 @@ export const DateOfBirthPattern: PatternComponent<DateOfBirthProps> = ({
</label>
<input
className={classNames('usa-input', {
'usa-input--error': error,
'usa-input--error': !!error,
})}
id={dayId}
{...register(dayId)}
{...register(dayId, { required })}
minLength={2}
maxLength={2}
pattern="[0-9]*"
inputMode="numeric"
aria-describedby={
error ? `${dayId} input-error-message-${dayId}}}` : dayId
}
aria-describedby={getAriaDescribedBy(
error ? `input-error-message-${dayId}` : null,
hint ? hintId : null
)}
/>
</div>
<div className="usa-form-group usa-form-group--year">
Expand All @@ -100,17 +110,18 @@ export const DateOfBirthPattern: PatternComponent<DateOfBirthProps> = ({
</label>
<input
className={classNames('usa-input', {
'usa-input--error': error,
'usa-input--error': !!error,
})}
id={yearId}
{...register(yearId)}
{...register(yearId, { required })}
minLength={4}
maxLength={4}
pattern="[0-9]*"
inputMode="numeric"
aria-describedby={
error ? `${yearId} input-error-message-${yearId}}}` : yearId
}
aria-describedby={getAriaDescribedBy(
error ? `input-error-message-${yearId}` : null,
hint ? hintId : null
)}
/>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export const EmailInputPattern: PatternComponent<EmailInputProps> = ({
autoCapitalize="off"
autoCorrect="off"
{...register(emailId, { required })}
aria-describedby={error ? `${emailId} ${errorId}}` : emailId}
aria-describedby={error ? errorId : undefined}
/>
</div>
</fieldset>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ export const PhoneNumberPattern: PatternComponent<PhoneNumberProps> = ({
}) => {
const { register } = useFormContext();
const errorId = `input-error-message-${phoneId}`;
const hintId = `hint-${phoneId}`;

return (
<fieldset className="usa-fieldset">
Expand All @@ -22,14 +23,13 @@ export const PhoneNumberPattern: PatternComponent<PhoneNumberProps> = ({
className={classNames('usa-label', {
'usa-label--error': error,
})}
id={`input-message-${phoneId}`}
htmlFor={phoneId}
>
{label}
{required && <span className="required-indicator">*</span>}
</label>
{hint && (
<div className="usa-hint" id={`hint-${phoneId}`}>
<div className="usa-hint" id={hintId}>
{hint}
</div>
)}
Expand All @@ -46,7 +46,10 @@ export const PhoneNumberPattern: PatternComponent<PhoneNumberProps> = ({
type="tel"
defaultValue={value}
{...register(phoneId, { required })}
aria-describedby={error ? `${phoneId} ${errorId}` : phoneId}
aria-describedby={
`${hint ? `${hintId}` : ''}${error ? ` ${errorId}` : ''}`.trim() ||
undefined
}
/>
</div>
</fieldset>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const SelectDropdownPattern: PatternComponent<SelectDropdownProps> = ({
})}
id={selectId}
{...register(selectId, { required })}
aria-describedby={error ? `${selectId} ${errorId}` : selectId}
aria-describedby={error ? errorId : undefined}
>
<option key="default" value="">
- Select -
Expand Down

0 comments on commit 81d49d2

Please sign in to comment.