Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DSD-1618: autoComplete prop for TextInput #1457

Merged
merged 2 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,10 @@ Currently, this repo is in Prerelease. When it is released, this project will ad

## Prerelease

### Adds

- Added the `autoComplete` prop to the `TextInput` component for setting the "autocomplete" attribute manually.

## 2.1.1 (October 26, 2023)

### Adds
Expand Down
17 changes: 17 additions & 0 deletions src/components/DatePicker/__snapshots__/DatePicker.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 1`] = `
>
<input
aria-label="From, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="basic-start"
Expand Down Expand Up @@ -103,6 +104,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 1`] = `
>
<input
aria-label="To, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="basic-end"
Expand Down Expand Up @@ -184,6 +186,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 2`] = `
>
<input
aria-label="From, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="no-label-start"
Expand Down Expand Up @@ -237,6 +240,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 2`] = `
>
<input
aria-label="To, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="no-label-end"
Expand Down Expand Up @@ -318,6 +322,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 3`] = `
>
<input
aria-label="From, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="custom-format-start"
Expand Down Expand Up @@ -371,6 +376,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 3`] = `
>
<input
aria-label="To, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="custom-format-end"
Expand Down Expand Up @@ -454,6 +460,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 4`] = `
aria-describedby="invalid-start-helperText"
aria-invalid={true}
aria-label="From, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="invalid-start"
Expand Down Expand Up @@ -525,6 +532,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 4`] = `
aria-describedby="invalid-end-helperText"
aria-invalid={true}
aria-label="To, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="invalid-end"
Expand Down Expand Up @@ -631,6 +639,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 5`] = `
>
<input
aria-label="From, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={true}
id="disabled-start"
Expand Down Expand Up @@ -684,6 +693,7 @@ exports[`DatePicker Date Range renders the UI snapshot correctly 5`] = `
>
<input
aria-label="To, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={true}
id="disabled-end"
Expand Down Expand Up @@ -763,6 +773,7 @@ exports[`DatePicker Single input renders the UI snapshot correctly 1`] = `
>
<input
aria-label="Select the full date you want to visit NYPL, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="basic-start"
Expand Down Expand Up @@ -824,6 +835,7 @@ exports[`DatePicker Single input renders the UI snapshot correctly 2`] = `
>
<input
aria-label="Select the date you want to visit NYPL, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="no-label-start"
Expand Down Expand Up @@ -892,6 +904,7 @@ exports[`DatePicker Single input renders the UI snapshot correctly 3`] = `
>
<input
aria-label="Select the date you want to visit NYPL, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="custom-format-start"
Expand Down Expand Up @@ -962,6 +975,7 @@ exports[`DatePicker Single input renders the UI snapshot correctly 4`] = `
aria-describedby="invalid-start-helperText"
aria-invalid={true}
aria-label="Select the date you want to visit NYPL, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="invalid-start"
Expand Down Expand Up @@ -1047,6 +1061,7 @@ exports[`DatePicker Single input renders the UI snapshot correctly 5`] = `
<input
aria-describedby="disabled-start-helperText"
aria-label="Select the date you want to visit NYPL, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={true}
id="disabled-start"
Expand Down Expand Up @@ -1132,6 +1147,7 @@ exports[`DatePicker Single input renders the UI snapshot correctly 6`] = `
<input
aria-describedby="chakra-start-helperText"
aria-label="Select the date you want to visit NYPL, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="chakra-start"
Expand Down Expand Up @@ -1218,6 +1234,7 @@ exports[`DatePicker Single input renders the UI snapshot correctly 7`] = `
<input
aria-describedby="props-start-helperText"
aria-label="Select the date you want to visit NYPL, Press tab to access the calendar."
autoComplete={null}
className="chakra-input css-0"
disabled={false}
id="props-start"
Expand Down
43 changes: 34 additions & 9 deletions src/components/TextInput/TextInput.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ import { changelogData } from "./textInputChangelogData";

# TextInput

| Component Version | DS Version |
| ----------------- | ---------- |
| Added | `0.22.0` |
| Latest | `2.1.0` |
| Component Version | DS Version |
| ----------------- | ------------ |
| Added | `0.22.0` |
| Latest | `Prerelease` |

## Table of Contents

- {<Link href="#overview" target="_self">Overview</Link>}
- {<Link href="#component-props" target="_self">Component Props</Link>}
- {<Link href="#accessibility" target="_self">Accessibility</Link>}
- {<Link href="#autocomplete" target="_self">Autocomplete</Link>}
- {<Link href="#labelling-variations" target="_self">Labelling Variations</Link>}
- {<Link href="#browser-states" target="_self">Browser States</Link>}
- {<Link href="#isclearable-button" target="_self">isClearable Button</Link>}
Expand Down Expand Up @@ -70,18 +71,42 @@ When the `type` prop is set to `"textarea"`, the `<textarea>` element
is rendered instead of the `<input>` element. This element follows all the same
accessibility rules described above.

If the `type` prop is set to `"email"`, `"tel"`, or `"url"`, the appropriate
`autocomplete` attribute will be added. The autocomplete attribute makes inputs
easier and more efficient to complete for all users.

Resources:

- [MDN input: The Input (Form Input) element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input)
- [MDN textarea: The Textarea element](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea)
- [MDN HTML attribute: Autocomplete](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete)
- [Chakra UI Input](https://chakra-ui.com/docs/components/form/input)
- [Chakra UI Textarea](https://chakra-ui.com/docs/components/form/textarea)

## Autocomplete

The native HTML `autocomplete` attribute is another tool that can be used to
improve accessibility. The `autocomplete` attribute improves the browser's
ability to pre-populate form fields with user-preferred values and makes inputs
easier and more efficient to complete for all users. For ease of use, the
`TextInput` component provides a few methods for incorporating the
`autocomplete` attribute.

If the `type` prop is set to `"email"`, `"tel"`, or `"url"`, the component will
automatically add the `autocomplete` attribute with an appropriate value.

Additionally, the `autoComplete` prop can be used to set the `autocomplete`
attribute manually. When the `autoComplete` prop is set, its value will be used
to set the `autocomplete` attribute on the input field. Furthermore, if the
`type` prop is set to `"email"`, `"tel"`, or `"url"`, the value of the
`autoComplete` prop will override the value automatically added by the
component.

Using the `autoComplete` prop can be helpful when it is necessary to set
`autocomplete` attribute values that are not automatically added by the
component or when privacy is a concern. For example, setting the `autoComplete`
prop to `"off"` will disable the native browser based autocomplete
functionality.

Resources:

- [MDN HTML attribute: Autocomplete](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete)

## Labelling Variations

A TextInput can be rendered with or without visible labels. When `showLabel` is
Expand Down
10 changes: 9 additions & 1 deletion src/components/TextInput/TextInput.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,20 @@ import { useState } from "react";
import { withDesign } from "storybook-addon-designs";

import Heading from "../Heading/Heading";
import TextInput, { textInputTypesArray } from "./TextInput";
import TextInput, {
autoCompleteValuesArray,
textInputTypesArray,
} from "./TextInput";

const meta: Meta<typeof TextInput> = {
title: "Components/Form Elements/TextInput",
component: TextInput,
decorators: [withDesign],
argTypes: {
autoComplete: {
control: { type: "select" },
options: autoCompleteValuesArray,
},
id: { control: false },
isClearable: { table: { defaultValue: { summary: false } } },
isDisabled: { table: { defaultValue: { summary: false } } },
Expand Down Expand Up @@ -47,6 +54,7 @@ type Story = StoryObj<typeof TextInput>;
export const WithControls: Story = {
args: {
additionalHelperTextIds: undefined,
autoComplete: undefined,
className: undefined,
defaultValue: undefined,
helperText: "Choose wisely.",
Expand Down
55 changes: 55 additions & 0 deletions src/components/TextInput/TextInput.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,49 @@ describe("TextInput", () => {
expect(screen.getByRole("textbox")).toHaveAttribute("autocomplete", "url");
});

it("has an 'autocomplete' attribute if the `autoComplete` prop is set", () => {
expect(screen.getByRole("textbox")).not.toHaveAttribute("autocomplete");

utils.rerender(
<TextInput
autoComplete="name"
id="myEmailInput"
labelText="Custom Email Input Label"
onChange={changeHandler}
type="text"
/>
);

expect(screen.getByRole("textbox")).toHaveAttribute("autocomplete", "name");

utils.rerender(
<TextInput
autoComplete="off"
id="myTelInput"
labelText="Custom Tel Input Label"
onChange={changeHandler}
type="text"
/>
);

expect(screen.getByRole("textbox")).toHaveAttribute("autocomplete", "off");

utils.rerender(
<TextInput
autoComplete="username"
id="myURLInput"
labelText="Custom URL Input Label"
onChange={changeHandler}
type="email"
/>
);

expect(screen.getByRole("textbox")).toHaveAttribute(
"autocomplete",
"username"
);
});

it("does not render '(Required)' along with the label text", () => {
utils.rerender(
<TextInput
Expand Down Expand Up @@ -690,6 +733,17 @@ describe("UI Snapshots", () => {
/>
)
.toJSON();
const withCustomAutoComplete = renderer
.create(
<TextInput
autoComplete="name"
id="autocomplete"
labelText="Custom Input Label"
placeholder="Input Placeholder"
type="text"
/>
)
.toJSON();

expect(basicTextarea).toMatchSnapshot();
expect(required).toMatchSnapshot();
Expand All @@ -702,6 +756,7 @@ describe("UI Snapshots", () => {
expect(withClearButton).toMatchSnapshot();
expect(withChakraProps).toMatchSnapshot();
expect(withOtherProps).toMatchSnapshot();
expect(withCustomAutoComplete).toMatchSnapshot();
});

it("passes a ref to the input element", () => {
Expand Down
Loading
Loading