-
Notifications
You must be signed in to change notification settings - Fork 526
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
Add FormControl component #1836
Conversation
🦋 Changeset detectedLatest commit: acb9a8c The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
size-limit report 📦
|
@mperrotti - not sure if it's just me but on the preview url I can't see any labels. Any ideas why? https://primer-react-efgapobji-primer.vercel.app/react/FormControl |
src/FormControl/FormControl.tsx
Outdated
/** | ||
* Changes the layout of the form control | ||
*/ | ||
variant?: 'stack' | 'choice' // TODO: come up with a better name for 'stack' |
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 we just go with "stack" for the vertically stacked label+input+caption/validation? Or does anybody have an idea for a better 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.
Could it be more abstract like vertical
and horizontal
with prop called alignment
instead?
Taking that further, do we need a variant prop at all?
E.g.
<FormControl variant="stack">
<FormControl.Label>Checkbox option one</FormControl.Label>
<Checkbox />
</FormControl>
☝️ This is incorrect usage for checkboxes and breakslayout, but is what happens by default unless the user manually changes to choice
.
Can we read children via React.Children
to see if there's a type of Checkbox
or Radio
, which automatically applies choice
for them without needing it via prop?
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.
@rezrah We discussed that after you left one of our meetings. We decided that reading from React.Children
felt like a little too much magic and would prevent people from using custom checkboxes/radios
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 @colebemis. Should the values be more explicit to the type of child instead then? It's not immediately clear (to me at least) which values (stacked/choice) to use for variant
, even though there are restrictions on types of input to variant. E.g. You can't use stacked with checkbox children.
Example of explicit values...
<FormControl variant="checkbox">
<FormControl.Label>Checkbox option one</FormControl.Label>
<Checkbox />
</FormControl>
Although I personally find for
even more readable...
<FormControl for="checkbox">
<FormControl.Label>Checkbox option one</FormControl.Label>
<Checkbox />
</FormControl>
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.
@colebemis - I went with Reza's suggestion to remove variant
. I won't merge this until you either say this is ok, or we come up with a solution everybody is comfortable with.
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.
Given this component only supports internal form inputs, I think it makes sense to remove variant
. Less customisation for the user to worry about.
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.
Given this component only supports internal form inputs, I think it makes sense to remove variant.
When we were looking at the API, we talked about supporting custom form inputs and that's where an explicit layout variant
came from, because there is no non-hacky way for the user to get a vertical layout on their own.
If we are choosing to not support custom input elements for now, we can remove the variant prop. I'm always up for a little magic. I imagine the need for custom inputs will come up at some point and then we can bring back the variant
prop, it's nice that we already have a solution.
2c6fd02
to
801000a
Compare
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 excellent! ✨
I left a lot of comments but they're mostly nitpicks or questions. I didn't notice any serious blockers
![Checkbox, Radio].some(inputComponent => child.type === inputComponent) | ||
)} | ||
</Box> | ||
{slots.LeadingVisual && ( |
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.
Not a blocker for this PR:
@mperrotti and @siddharthkp how do y'all feel about not capitalizing slot names (slots.leadingVisual
instead of slots.LeadingVisual
)? The PascalCase makes me think I can do something like this <slots.LeadingVisual>
(which wouldn't work)
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's a good point, I'm not sure 🤔
I called it slots.LeadingVisual
in ActionList because I wanted to call it the exact same name from the component API. <ActionList.LeadingVisual>
→ slots.LeadingVisual
const {Slots, Slot} = createSlots(['LeadingVisual', 'InlineDescription', 'BlockDescription', 'TrailingVisual'])
https://github.com/primer/react/blob/main/src/ActionList2/Item.tsx#L79
Side note: It would be really cool if we could actually call the render the slot with <Slots.LeadingVisual props="too">
but I couldn't figure out how to make that work
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'm cool with that change, but I'd rather make it across all components instead of just this one.
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'd like to keep slots.LeadingVisual
until we know what changes in #1690 in the hopes we can actually have <Slots.LeadingVisual props="too">
😅
const captionId = captionChildren?.length ? `${id}-caption` : undefined | ||
const InputComponent = React.Children.toArray(children).find(child => | ||
expectedInputComponents.some(inputComponent => React.isValidElement(child) && child.type === inputComponent) | ||
) |
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.
Does this implementation prevent people from passing custom input 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.
Yes. We can open it up later if we need to.
Co-authored-by: Cole Bemis <colebemis@github.com>
Co-authored-by: Cole Bemis <colebemis@github.com>
Co-authored-by: Cole Bemis <colebemis@github.com>
Co-authored-by: Cole Bemis <colebemis@github.com>
Co-authored-by: Cole Bemis <colebemis@github.com>
Co-authored-by: Rez <rezrah@github.com>
429076b
to
260ca68
Compare
const mockErrorFn = jest.fn() | ||
|
||
beforeAll(() => { | ||
jest.spyOn(global.console, 'warn').mockImplementation(mockWarningFn) |
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
FormControl
component combines the functionality ofInputField
andChoiceInputField
, and will replaceFormGroup
,InputField
, andChoiceInputField
.Relates to https://github.com/github/primer/issues/679
Screenshots
Merge checklist
Take a look at the What we look for in reviews section of the contributing guidelines for more information on how we review PRs.