From 33f4bb6688f1ca9a1c065bf9ead56a65952862fd Mon Sep 17 00:00:00 2001 From: Daniel Sil Date: Tue, 3 Jan 2023 17:48:49 +0000 Subject: [PATCH] feat(InputField): add aria-invalid and aria-describedby Accessibility properties added to the correct states. --- .../src/InputField/__tests__/index.test.tsx | 3 +++ .../orbit-components/src/InputField/index.tsx | 22 +++++++++++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/packages/orbit-components/src/InputField/__tests__/index.test.tsx b/packages/orbit-components/src/InputField/__tests__/index.test.tsx index 7ecfbf51d9..4e7cca2742 100644 --- a/packages/orbit-components/src/InputField/__tests__/index.test.tsx +++ b/packages/orbit-components/src/InputField/__tests__/index.test.tsx @@ -59,6 +59,7 @@ describe("InputField", () => { expect(input).toHaveAttribute("data-recording-ignore"); expect(input).toHaveAttribute("id", "id"); expect(input).toHaveAttribute("data-state", "ok"); + expect(input).not.toBeInvalid(); expect(screen.getByTestId("test")).toBeInTheDocument(); expect(screen.getByTestId("prefix")).toBeInTheDocument(); expect(screen.getByTestId("suffix")).toBeInTheDocument(); @@ -142,10 +143,12 @@ describe("InputField", () => { expect(input).toHaveAttribute("min", "1"); expect(input).toHaveAttribute("max", "5"); expect(input).toHaveAttribute("data-state", "error"); + expect(input).toBeInvalid(); userEvent.tab(); expect(screen.queryByTestId("help")).not.toBeInTheDocument(); expect(screen.getByTestId("error")).toBeInTheDocument(); + expect(input).toHaveDescription("Something went wrong."); // Needs to flush async `floating-ui` hooks // https://github.com/floating-ui/floating-ui/issues/1520 await act(async () => {}); diff --git a/packages/orbit-components/src/InputField/index.tsx b/packages/orbit-components/src/InputField/index.tsx index 60472c8601..35bd8b95a1 100644 --- a/packages/orbit-components/src/InputField/index.tsx +++ b/packages/orbit-components/src/InputField/index.tsx @@ -255,12 +255,26 @@ interface StyledInputProps extends Partial { autoCorrect: string; autoCapitalize: string; ariaLabelledby?: string; + ariaDescribedby?: string; + ariaInvalid?: boolean; } export const Input = styled( React.forwardRef( ( - { type, size, error, help, inlineLabel, dataAttrs, required, ariaLabelledby, ...props }, + { + type, + size, + error, + help, + inlineLabel, + dataAttrs, + required, + ariaLabelledby, + ariaDescribedby, + ariaInvalid, + ...props + }, ref, ) => { return ( @@ -275,6 +289,8 @@ export const Input = styled( aria-required={required} // in case when there is no label aria-labelledby={ariaLabelledby} + aria-describedby={ariaDescribedby} + aria-invalid={ariaInvalid} /> ); }, @@ -501,6 +517,8 @@ const InputField = React.forwardRef((props, ref) => { ref={ref} tabIndex={tabIndex} ariaLabelledby={!label ? inputId : undefined} + ariaDescribedby={shown ? `${inputId}-feedback` : undefined} + ariaInvalid={error ? true : undefined} inlineLabel={inlineLabel} readOnly={readOnly} autoCapitalize="off" @@ -517,7 +535,7 @@ const InputField = React.forwardRef((props, ref) => { {!insideInputGroup && (