-
Notifications
You must be signed in to change notification settings - Fork 3
Conversation
This lets us only define "name" once (as a prop for CheckboxGroup) and have it be shared by all the child components (Checkboxes).
@@ -0,0 +1,4 @@ | |||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> |
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.
are we pulling svg from a website? is it reliable? why not save it as part of this repo?
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.
xmlns
is XML namespacing, which iirc is used to do the svg magic - all svg's will have it
const InputContext = React.createContext(); | ||
|
||
const Checkbox = ({ name, value, label, checked, disabled, onChange }) => ( | ||
<InputContext.Consumer> |
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 pretty cool, never seen this pattern before.
Would you still be able to render a Checkbox
without CheckboxGroup
?
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.
IKR, it's the new context API and I like it a lot. 😃
I intended for Checkbox
to be used on its own but currently it's failing without a parent CheckboxGroup
. I'll fix this tomorrow, thanks!
<input | ||
type="checkbox" | ||
name={name || context.name} | ||
value={value} |
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.
Why do we need value
? Couldn't onChange
just supply the value in the callback?
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 sure if I follow. Normally in regular forms you can have an input without an onChange
function (the value is passed on form submit) and so I wanted to support that use case. I haven't played around with forms in React before, is there a reason to have the onChange
without the value
?
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 this goes for any checkbox form - checkbox is just a toggle, onChange
just needs to notify if value is true
or false
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.
OH SHOOT, I've mixed up my logic, the shared name
prop is only useful to radio buttons (where there is only a single answer), hence why value
is there so you can distinguish between radio button options.
But this is a checkbox... 💀 , I'll fix all of this tomorrow.
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.
Actually nevermind, the normal way of handling a group of checkboxes is to group them with the same name
but have unique (string) values. Then when you submit the form, all the checked values are passed under the same name and you parse them.
<input type="checkbox" name="diet" value="vegetarian"> Vegetarian
<input type="checkbox" name="diet" value="gluten-free" checked> Gluten Free
<input type="checkbox" name="diet" value="vegan" checked> Vegan
- On form submit this becomes
diet=gluten-free&diet=vegan
We can also have unique names for each checkbox and no value (and then parse each one individually by name) but this doesn't feel right if you have a group of checkboxes because you have to prefix them to understand how they're grouped on the front-end (if you don't do this they can conflict with other names in the form which is bad practice).
<input type="checkbox" name="vegetarian"> Vegetarian
<input type="checkbox" name="gluten-free" checked> Gluten Free
<input type="checkbox" name="vegan" checked> Vegan
- On form submit this becomes
gluten-free=on&vegan=on
I'm going to stick with the first approach, any objections?
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 fair actually, I think you're right
name: PropTypes.string, | ||
|
||
// input value for checkbox | ||
value: PropTypes.string.isRequired, |
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.
wouldn't this be a boolean?
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.
Which part are you 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.
checkbox value is either true or false, right? unless value is the label, but it looks like that's covered by name || context.name
Bad news lol, |
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!
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.
jk linter errors:
https://travis-ci.com/nwhacks/nwhacks2019/builds/80827030#L498
web/.eslintrc.json
Outdated
@@ -17,6 +17,7 @@ | |||
"react/jsx-filename-extension": 0, | |||
"react/require-default-props": 0, | |||
"react/forbid-prop-types": 0, | |||
"react/destructuring-assignment": 0, |
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.
Destructuring is awesome - why not enforce it?
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 fixed CheckboxGroup
to use destructuring (const { children, ...rest } = props;
) but that broke another rule which was no-unused-vars
(since ...rest
wasn't used).
But now I realize that ...rest
is optional 😛 , I'll make this change.
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 be good to go
web/.eslintrc.json
Outdated
"customValidators": "customValidator" | ||
} | ||
], | ||
"jsx-a11y/label-has-for": [ |
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 be fine, but do you mind quickly explain what these were added for?
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've removed the prop-types
config (it allowed me to not have to write propTypes
for CheckboxGroup
).
The jsx-a11y/label-has-for
config was for dealing with the error related to not having a for
attribute for the label. There are two ways I know of to associate labels with checkboxes (which makes the labels clickable):
<input id="some_id">
<label for="some_id">Some label<label>
<label>
<input /> Some label
</label>
And I chose the second option. With the first one we have to either require that a unique id
is passed in to each Checkbox
(or we generate one for each Checkbox if it's not provided) which seemed unnecessary. The config I added allows us to use either approach - without the config it forces us to use both, which would look like this:
<label for="some_id">
<input id="some_id" /> Some label
</label>
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.
(it allowed me to not have to write propTypes for CheckboxGroup).
Why would you not want this?
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.
Pure laziness 🐢
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.
oh wait you removed it, nevermind :D
👷 Changes
This PR adds the
Checkbox
andCheckboxGroup
components.Usage:
You can use
Checkbox
on its own but it's cleaner when wrapped withCheckboxGroup
because you can have a sharedname
attribute (as well as shareddefaultChecked
,disabled
, andonChange
attributes). You can override a shared prop by passing a specific value for that prop to the child component.💭 Notes
If you're curious as to what the pure CSS implementation looked like...
TODO
🔦 Testing Instructions
make web
& go tolocalhost:8080/ui_demo