Add errorMessage and hasError props to the TextField component. - #13334
Add errorMessage and hasError props to the TextField component.#13334shervElmi wants to merge 14 commits into
errorMessage and hasError props to the TextField component.#13334Conversation
`TextField` is now a TypeScript file, and it renders `VisuallyHidden` for the error message it keeps off the screen. The plain JavaScript `VisuallyHidden` left `className` required for a TypeScript caller, since a prop with no default value reads as required.
Every `TextField` caller built the error state by hand, setting `mdc-text-field--error`, a warning trailing icon, and `helperText` at the field. `TextField` now takes `errorMessage` for a message it shows under the field, and `hasError` for the error outline and the warning icon alone. Either prop sets `aria-invalid` on the input, and a message the field keeps off the screen still reaches a screen reader through `aria-errormessage`.
The tests cover `errorMessage` alone, `hasError` alone, and the two together. Each test reads the error outline, the warning icon, the error message, and the `aria-invalid` and `aria-errormessage` attributes.
The two error examples set `errorMessage` and `hasError` in place of the `mdc-text-field--error` class and the trailing icon they built by hand. Both examples take a new label, so the three Text Fields reference images need approving again.
The Ads conversion ID field passes the invalid ID message as `errorMessage`, so the error outline and the warning icon come from `TextField`.
The web data stream name field passes each name error as `errorMessage`, so the error outline and the warning icon come from `TextField`. The tests read `aria-invalid` and `aria-errormessage` on the input.
The invalid Client ID message moves to `errorMessage`. The recommendation to use an existing Client ID stays in `helperText`, so that recommendation shows with no error outline.
An empty container name now holds the message a screen reader reads. The container name field shows the error outline and the warning icon alone. A duplicate name keeps its message on the screen.
`CreateAccountField` takes an `errorMessage` prop and passes it to `TextField` with `hasError`. An empty field then names its error for a screen reader, while the screen shows the error outline and the warning icon alone. Dropping the `className` prop also drops a duplicate `mdc-text-field`.
The account, property, and web data stream fields each pass the message a screen reader reads while that field is empty.
The tests read `aria-invalid`, `aria-errormessage`, and the hidden error message on each of the three fields. A field with a name holds none of the three.
📚 Storybook for 47dd401: 📦 Build files for 47dd401:
🎭 Playwright reports for 47dd401: |
|
Size Change: 0 B Total Size: 3.33 MB ℹ️ View Unchanged
|
zutigrm
left a comment
There was a problem hiding this comment.
THanks @shervElmi looks good, left you few comments
There was a problem hiding this comment.
Since TextField is now TS, should this be renamed to TextField.stories.tsx per https://github.com/google/site-kit-wp/blob/develop/docs/context/js/storybook.md?
| ); | ||
| expect( | ||
| getByText( | ||
| 'Tracking for your Ads campaigns won’t work until you insert a valid ID' |
There was a problem hiding this comment.
A few of these (across different test files that were added/updated) assert the full error sentence. Worth matching on a fragment/regex instead (e.q /tracking for your ads campaigns/) so a copy tweak doesn't break the test?
| [ 'Account', 'An account name is required.' ], | ||
| [ 'Property', 'A property name is required.' ], | ||
| [ 'Web data stream', 'A web data stream name is required.' ], |
There was a problem hiding this comment.
Same array is copy-pasted for both it.each calls below. Lets pull it into one const FIELD_ERRORS = [...] and reuse.
| value={ value } | ||
| hasError={ ! value } | ||
| errorMessage={ __( | ||
| 'A web data stream name is required.', |
There was a problem hiding this comment.
This message is identical to the one in
Can we pull it into a shared constant both files import, so it can't drift?
Summary
Related issue(s):
errorMessagefield toTextFieldcomponent that encapsulates error message and icon pattern #12935Relevant technical choices
assets/js/googlesitekit/components-gm2/TextField.tsxerrorMessagein aVisuallyHiddensibling, instead of addingscreen-reader-textto the helper text.TextField,CreateAccountField, andVisuallyHiddento TypeScript.assets/js/modules/sign-in-with-google/components/common/ClientIDTextField.jsPR Author Checklist
Do not alter or remove anything below. The following sections will be managed by moderators only.
Code Reviewer Checklist
Merge Reviewer Checklist