Skip to content

Commit

Permalink
fix(PPDSC-2164): assistive text (#249)
Browse files Browse the repository at this point in the history
* fix(PPDSC-2164): add tests for bug expected outcome

* fix(PPDSC-2164): do not set aria-describedby if no assistive text

- Update assistiveTextId context value inside AssistiveText component so that it is only set if this component exists within the parent.

* fix(PPDSC-2164): update failing fieldset snapshots
  • Loading branch information
mstuartf authored Jul 1, 2022
1 parent bf662e1 commit 4fbda6c
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 11 deletions.
6 changes: 0 additions & 6 deletions src/fieldset/__tests__/__snapshots__/fieldset.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -647,7 +647,6 @@ exports[`Fieldset renders fieldset with large form inputs 1`] = `
class="emotion-2"
>
<input
aria-describedby="mock-nk-1-assistive-text"
aria-invalid="false"
class="emotion-3"
id="mock-nk-1"
Expand All @@ -670,7 +669,6 @@ exports[`Fieldset renders fieldset with large form inputs 1`] = `
class="emotion-7"
>
<input
aria-describedby="mock-nk-1-assistive-text"
class="emotion-8"
data-testid="checkbox-input"
id="mock-nk-1"
Expand Down Expand Up @@ -1337,7 +1335,6 @@ exports[`Fieldset renders fieldset with medium form inputs 1`] = `
class="emotion-2"
>
<input
aria-describedby="mock-nk-1-assistive-text"
aria-invalid="false"
class="emotion-3"
id="mock-nk-1"
Expand All @@ -1360,7 +1357,6 @@ exports[`Fieldset renders fieldset with medium form inputs 1`] = `
class="emotion-7"
>
<input
aria-describedby="mock-nk-1-assistive-text"
class="emotion-8"
data-testid="checkbox-input"
id="mock-nk-1"
Expand Down Expand Up @@ -2027,7 +2023,6 @@ exports[`Fieldset renders fieldset with small form inputs 1`] = `
class="emotion-2"
>
<input
aria-describedby="mock-nk-1-assistive-text"
aria-invalid="false"
class="emotion-3"
id="mock-nk-1"
Expand All @@ -2050,7 +2045,6 @@ exports[`Fieldset renders fieldset with small form inputs 1`] = `
class="emotion-7"
>
<input
aria-describedby="mock-nk-1-assistive-text"
class="emotion-8"
data-testid="checkbox-input"
id="mock-nk-1"
Expand Down
60 changes: 60 additions & 0 deletions src/form/__tests__/form.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -708,4 +708,64 @@ describe('FormInput', () => {
});
expect(await findByTestId('error-icon')).not.toBeNull();
});

describe('input.aria-describedby', () => {
const INPUT_ID = 'test-input-1';
let assistiveTextId;

test('is set to assistive text id in default state', () => {
const {getByText, getByTestId} = renderWithImplementation(Form, {
onSubmit: () => {},
children: (
<FormInput id={INPUT_ID} name="test-input">
<FormInputLabel>Test input</FormInputLabel>
<FormInputTextField data-testid="text-field-test-input" />
<FormInputAssistiveText>Assistive Text</FormInputAssistiveText>
</FormInput>
),
});

assistiveTextId = `${INPUT_ID}-assistive-text`;

const assistiveText = getByText('Assistive Text');
expect(assistiveText).toHaveAttribute('id', assistiveTextId);
const input = getByTestId('text-field-test-input');
expect(input).toHaveAttribute('aria-describedby', assistiveTextId);
});

test('is not set if no assistive text is provided', () => {
const {getByTestId} = renderWithImplementation(Form, {
onSubmit: () => {},
children: (
<FormInput id={INPUT_ID} name="test-input">
<FormInputLabel>Test input</FormInputLabel>
<FormInputTextField data-testid="text-field-test-input" />
</FormInput>
),
});

const input = getByTestId('text-field-test-input');
expect(input).not.toHaveAttribute('aria-describedby');
});

test('is set to assistive text id in invalid state', () => {
const {getByText, getByTestId} = renderWithImplementation(Form, {
onSubmit: () => {},
children: (
<FormInput id={INPUT_ID} state="invalid" name="test-input">
<FormInputLabel>Test input</FormInputLabel>
<FormInputTextField data-testid="text-field-test-input" />
<FormInputAssistiveText>Assistive Text</FormInputAssistiveText>
</FormInput>
),
});

assistiveTextId = `${INPUT_ID}-error-text`;

const assistiveText = getByText('Assistive Text');
expect(assistiveText).toHaveAttribute('id', assistiveTextId);
const input = getByTestId('text-field-test-input');
expect(input).toHaveAttribute('aria-describedby', assistiveTextId);
});
});
});
1 change: 1 addition & 0 deletions src/form/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ export const FormInputContext = createContext<{
id?: string;
labelId?: string;
assistiveTextId?: string;
setAssistiveTextId?: (id: string) => void;
statusIcon?: React.ReactNode;
isRequired?: boolean;
}>({});
24 changes: 19 additions & 5 deletions src/form/form-input.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, {useContext} from 'react';
import React, {useContext, useEffect, useState} from 'react';
import composeRefs from '@seznam/compose-react-refs';
import {Label, LabelProps} from '../label';
import {TextField} from '../text-field/text-field';
Expand Down Expand Up @@ -45,6 +45,7 @@ const ThemelessFormInput = ({
const [autoGeneratedId] = useReactKeys(1);

const currentID = id || autoGeneratedId;
const [assistiveTextId, setAssistiveTextId] = useState<string | undefined>();

const theme = useTheme();

Expand All @@ -61,9 +62,6 @@ const ThemelessFormInput = ({
<FormEntry name={name} rules={rules}>
{({ref, state: stateContext, onChange, onBlur, error}) => {
const state = stateProp || stateContext;
const assistiveTextId =
(state === 'invalid' && `${currentID}-error-text`) ||
`${currentID}-assistive-text`;
const labelId = `${currentID}-label`;

const statusIcon = getStatusIcon({state, iconSize: validationIconSize});
Expand All @@ -80,6 +78,7 @@ const ThemelessFormInput = ({
ref,
id: currentID,
assistiveTextId,
setAssistiveTextId,
labelId,
statusIcon,
isRequired,
Expand Down Expand Up @@ -202,7 +201,22 @@ export const FormInputAssistiveText = ({
overrides,
...props
}: AssistiveTextProps & {validationIcon?: boolean}) => {
const {size, state, error, assistiveTextId} = useFormFieldContext();
const {
size,
state,
error,
assistiveTextId,
setAssistiveTextId,
id,
} = useFormFieldContext();

useEffect(() => {
if (setAssistiveTextId) {
setAssistiveTextId(
state === 'invalid' ? `${id}-error-text` : `${id}-assistive-text`,
);
}
}, [state, id, setAssistiveTextId]);

const theme = useTheme();

Expand Down

0 comments on commit 4fbda6c

Please sign in to comment.