-
Notifications
You must be signed in to change notification settings - Fork 377
chore(Form): convert examples to TypeScript/functional components #7521
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
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might it be easier to name the state variables as name or even nameValue instead of value1?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
across all examples
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1 @nicolethoen
| setValidated('success'); | ||
| } else { | ||
| setValidated('error'); | ||
| } // changed noval to default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you clean up this comment?
| helperText={helperText} | ||
| isHelperTextBeforeField | ||
| hasNoPaddingTop | ||
| fieldId="options" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you meant to link to the ./FormSections.tsx file
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks great! one nit
| setValidated('success'); | ||
| } else { | ||
| setValidated('error'); | ||
| } // changed noval to default |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds like a good plan @andyyvo !
| 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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think these fieldId props are service a purpose when you set a role
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is looking awesome @andyyvo !! Recent updates are excellent 👌
Left a couple comments about some small naming-related things - last few updates I think! Once those are addressed this PR should be good to 🚀!!
| 'group3-label1': '', | ||
| 'group3-label2': '', | ||
| 'exapnded-group1-label1': '', | ||
| 'exapnded-group1-label2': '', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
sounds good! I'll get right on that :D
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @andyyvo !! Great job on this - LGTM 🤩
nicolethoen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just need to resolve merge conflicts 👍
nicolethoen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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
thatblindgeye
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🎉 Looks good!
…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