chore(Form): convert examples to TypeScript/functional components#7521
chore(Form): convert examples to TypeScript/functional components#7521nicolethoen merged 4 commits intopatternfly:mainfrom
Conversation
|
Preview: https://patternfly-react-pr-7521.surge.sh A11y report: https://patternfly-react-pr-7521-a11y.surge.sh |
| import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; | ||
|
|
||
| export const SimpleForm: React.FunctionComponent = () => { | ||
| const [value1, setValue1] = React.useState(''); // name |
There was a problem hiding this comment.
Might it be easier to name the state variables as name or even nameValue instead of value1?
| setValidated('success'); | ||
| } else { | ||
| setValidated('error'); | ||
| } // changed noval to default |
There was a problem hiding this comment.
these comments are not necessary, even though they are helpful when reviewing. Future consumers who will be looking at this example code as a guide when implementing forms and won't have the context to know what you're referring to.
There was a problem hiding this comment.
Could you clean up this comment?
| helperText={helperText} | ||
| isHelperTextBeforeField | ||
| hasNoPaddingTop | ||
| fieldId="options" |
There was a problem hiding this comment.
The fieldId prop should map to the id of the form element to which a label is bound. In cases like this one there is no corresponding input or element with the specified id.
I think ideally, in these cases we'd be using a fieldset element and it's associated legend rather than a div.pf-c-form-group and (unofficially) associated label. Here is w3c article for reference. I have opened an issue in core to consider the markup updates.
For now, we may as well remove the fieldId from the places where it is trying to label multiple controls at once.
There was a problem hiding this comment.
I think that eric is actually resolving this exact issue in this PR: #7516 so disregard this :)
| ); | ||
| } | ||
| } | ||
| ```ts file="./FormGrid.tsx" |
There was a problem hiding this comment.
I think you meant to link to the ./FormSections.tsx file
There was a problem hiding this comment.
This is looking great @andyyvo! Nice update to the Validated example with useEffect 👍
I agree with @nicolethoen and was just about to comment the same - for best practice + readability, it would be good to update the hook variable names and value change methods with names that correspond to the fields directly!
Nice work on this!
| import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; | ||
|
|
||
| export const FormGroupLabelInfo: React.FunctionComponent = () => { | ||
| const [value1, setValue1] = React.useState(''); // name |
There was a problem hiding this comment.
Looks like you only have one field here, so you could probably just go with value or name!
| const [value1, setValue1] = React.useState(''); // name | |
| const [name, setName] = React.useState(''); |
| import HelpIcon from '@patternfly/react-icons/dist/esm/icons/help-icon'; | ||
|
|
||
| export const SimpleForm: React.FunctionComponent = () => { | ||
| const [value1, setValue1] = React.useState(''); // name |
There was a problem hiding this comment.
| const [value1, setValue1] = React.useState(''); // name | |
| const [name, setName] = React.useState(''); |
| const [value2, setValue2] = React.useState(''); // email | ||
| const [value3, setValue3] = React.useState(''); // phone | ||
|
|
||
| const handleValue1Change = value1 => { |
There was a problem hiding this comment.
| const handleValue1Change = value1 => { | |
| const handleNameChange = name => { |
|
Sounds great, thanks @nicolethoen and @jenny-s51 !! I have a few questions that I'd love to learn more about for future reference.
Thank you so much!! |
|
Great questions @andyyvo !!
|
|
Just added all the cleaned up files. FormFieldGroups.tsx is still something that needs work. I'm running into an issue with object destructuring. It appears that |
|
Just wrapped up FormFieldGroups.tsx. Thank you so much, @nicolethoen !!! |
nicolethoen
left a comment
There was a problem hiding this comment.
Looks great! one nit
| setValidated('success'); | ||
| } else { | ||
| setValidated('error'); | ||
| } // changed noval to default |
There was a problem hiding this comment.
Could you clean up this comment?
|
@nicolethoen is #5767 the issue that you, me, and Eric were discussing about |
|
@andyyvo it is not - I was talking about this core issue |
jenny-s51
left a comment
There was a problem hiding this comment.
This is looking awesome! Everything seems to work as expected. Left a comment about the initialValues variable names - I think this demo would make a lot more sense to consumers if we cleaned those up a bit 🙂 Should be an easy update! WDYT @andyyvo @nicolethoen ?
| 'form-expandable-field-groups-field-group2-label2': '', | ||
| 'form-expandable-field-groups-field-group3-label1': '', | ||
| 'form-expandable-field-groups-field-group3-label2': '', | ||
| 'form-expandable-field-groupsform-expandable-field-groups-field-group1-label1': '', |
There was a problem hiding this comment.
I think form-expandable-field-groupsform-expandable-field-groups-field-group1-label1 is referring to one of the nested fields?
We could call it field-group1-nested-group1-label1 - would make it more clear 🙂
| 'form-expandable-field-group2-label2': '', | ||
| 'form-expandable-field-group3-label1': '', | ||
| 'form-expandable-field-group3-label2': '', | ||
| 'form-expandable-field-groups-field-group7-label1': '', |
There was a problem hiding this comment.
Same idea for these... it looks like in the demo there's no "Field group 7", "Field Group 8", or "Field group 10" so it's tricky to understand which inputs these are referring to.
We could have something like field-group3-nested-field-group1-label1 here - WDYT?
|
|
||
| export const FieldGroups: React.FunctionComponent = () => { | ||
| const initialValues = { | ||
| 'form-expandable-field-groups-label1': '', |
There was a problem hiding this comment.
Is there any way we could clean these names up? Would be a lot more DRY and readable if we removed the form-expandable-field-groups- text from all of these!
| 'form-expandable-field-groups-label1': '', | |
| 'label1': '', |
There was a problem hiding this comment.
Looks good and I totally agree @jenny-s51 ! The only issue I ran into with this was that the names of the labels in initialValues had to match the id and other props in the components used in order for the state variables to update the input. If I'm able to, I can change all of the id props to match it to something simpler?
| onChange={handlePhoneChange} | ||
| /> | ||
| </FormGroup> | ||
| <FormGroup role="group" isInline fieldId="basic-form-checkbox-group" label="How can we contact you?"> |
There was a problem hiding this comment.
I don't think these fieldId props are service a purpose when you set a role
There was a problem hiding this comment.
I believe that's what the other issue is referencing. If you clean these up you can mark the other issue addressed.
There was a problem hiding this comment.
Should I remove all fieldId where there is a role then? The fieldId prop is currently required in FormGroup components
There was a problem hiding this comment.
@nicolethoen can we imagine a case where a consumer would need/want to pass in their own ID for the form group label? If not, an alternative to having this fieldId prop setting two different things is to just have a random ID created internally to set the aria-labelledby attribute whenever role="group" or role="radiogroup" is passed in.
| 'group3-label1': '', | ||
| 'group3-label2': '', | ||
| 'exapnded-group1-label1': '', | ||
| 'exapnded-group1-label2': '', |
There was a problem hiding this comment.
Looks like we just need to make this is fixed throughout FormFieldGroups.tsx! I'm seeing this in a few places
| 'exapnded-group1-label2': '', | |
| 'expanded-group1-label2': '', |
| isRequired | ||
| id="exapnded-group2-label1" | ||
| name="exapnded-group2-label1" | ||
| value={inputValues['exapnded-group2-label1']} |
There was a problem hiding this comment.
We should make sure the non-expandable example doesn't have a field with expanded in the name
There was a problem hiding this comment.
sounds good! I'll get right on that :D
nicolethoen
left a comment
There was a problem hiding this comment.
Just need to resolve merge conflicts 👍
nicolethoen
left a comment
There was a problem hiding this comment.
Looks like the a11y tests failed because of this:
@patternfly/react-docs: 240/873 /components/form/react/basic
@patternfly/react-docs: violations: duplicate-id-aria
@patternfly/react-docs: 241/873 /components/form/react/horizontal
@patternfly/react-docs: violations: duplicate-id-aria
@patternfly/react-docs: 242/873 /components/form/react/limit-width
@patternfly/react-docs: violations: duplicate-id-aria
More information here: https://patternfly-react-pr-7521-a11y.surge.sh/
|
It appears that the accessibility issue derives from |
thatblindgeye
left a comment
There was a problem hiding this comment.
This is looking good! Had a couple of comments below which are dependent on responses from those I tagged.
One thing that can be updated is the name of the export in each example file. Those should match the file name, so for FormBasic.tsx, the export should be export const FormBasic: React.FunctionComponent... and so on.
| import { Form, FormGroup, TextInput, FormHelperText } from '@patternfly/react-core'; | ||
| import ExclamationCircleIcon from '@patternfly/react-icons/dist/esm/icons/exclamation-circle-icon'; | ||
|
|
||
| export const InvalidForm: React.FunctionComponent = () => { |
There was a problem hiding this comment.
@mcarrano based on your comment for a similar case at #7489 (comment), should the Invalid example for the Form component also be removed since we have the Validated example already?
| /** ID of the included field. It has to be the same for proper working. */ | ||
| fieldId: string; | ||
| fieldId?: string; |
There was a problem hiding this comment.
If we decide to have this prop continue working as-is, i.e. setting that aria-labelledby on FormGroup, then this description could use updating. Something along the lines of below, but I'd hold off until Nicole responds to my other comment regarding this prop.
"ID of an individual field or a group of multiple fields. Required when a role of "group" or "radiogroup" is passed in. If only one field is included, its ID attribute and this prop must be the same."
| onChange={handlePhoneChange} | ||
| /> | ||
| </FormGroup> | ||
| <FormGroup role="group" isInline fieldId="basic-form-checkbox-group" label="How can we contact you?"> |
There was a problem hiding this comment.
@nicolethoen can we imagine a case where a consumer would need/want to pass in their own ID for the form group label? If not, an alternative to having this fieldId prop setting two different things is to just have a random ID created internally to set the aria-labelledby attribute whenever role="group" or role="radiogroup" is passed in.
…generate id for forms
…tternfly#7521) * chore(Form): completed conversion of form examples to ts * chore(Form): added fieldId back to roles to define id and aria-labelledby * chore(Form): renamed form functions, updated fieldId desc, and added generate id for forms * chore(Form): cleaned FormGroup logic and added fieldId to label info example
What: Closes #7466 . Closes #5767 . Converted all Form component React demo examples into TypeScript. Two things to watch: FormInvalid.tsx and FormInvalidWithFormAlert.tsx swapped
novaltodefault; FormValidated.tsx originally had a small bug where thesetTimeoutcallback would stack based on the number of key inputs, but was fixed usinguseEffect.Additional issues: N/A