Skip to content
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

feat: add RadioField component, rework RadioInput #537

Merged
merged 13 commits into from
Feb 20, 2019
Merged

Conversation

emmenko
Copy link
Member

@emmenko emmenko commented Feb 13, 2019

This PR aims to rework the RadioInput component API to be consistent with the other input components, as well as to add the RadioField component.

There are a couple of extra changes though, as we decided for example to remove some default styling on the Text components in order to make it easier to apply e.g. some colors on the text.
This became particularly obvious in the radio input options.

`}
/>
{props.children}
</React.Fragment>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To by using the RadioField you "import" the side effect of a global style?

Copy link
Contributor

@montezume montezume left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not really sure I agree with the StylesProvider, or at least with the idea of it being part of this PR. I don't see that it adds any more value that the users just applying that CSS themselves...


| Props | Type | Required | Values | Default | Description |
| -------------- | ------------------ | :------: | ------ | ------- | ------------------------------------------------------------------------------------------------ |
| `baseFontSize` | `PropTypes.string` | - | - | `1rem` | Defines the font size baseline from which the `rem` font sizes of the application are based from |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't make sense to set baseFontSize to 1rem. It should be a pixel value. Maybe name it something like bodyFontSize or htmlFontSize to imply that it's being set on the body...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, I wanted to discuss this with you tomorrow.

@montezume
Copy link
Contributor

I labelled it a breaking change because removing margin, color and font-family from the text components is a breaking visual change.

@emmenko
Copy link
Member Author

emmenko commented Feb 13, 2019

Yes thanks, I didn't finish updating the PR description etc. It should be a breaking change of course.


#### Description

A controlled radio input component with validation states and a label.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This still feels off?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm, that's the same as other field components

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay then. Just read "radio input component" and was like but it's a "radio field component".

it('should disable the input', () => {
const { getByLabelText } = renderRadioField({ isReadOnly: true });
expect(getByLabelText(/RadioField Option 1/)).toHaveAttribute('readonly');
expect(getByLabelText(/RadioField Option 2/)).toHaveAttribute('readonly');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure we need this fuzzy matching everywhere? I understand the intend to have tests potentially more stable/flexible but I don't feel case for it really exists?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I simply like it more like this 🙃 Do you see any problems with this approach?

if (this.props.direction === 'inline') {
return (
<div id={this.props.id}>
<Spacings.Inline
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not here but maybe in the future. I like the notion of components: {} we recently adopted far more. So it would be components: { spacing: <Spacings.Inline scale='' /> } maybe. Is that worth of something to track as an issue?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see your point. In this case though, you really only have 2 choices: stack or inline. I'm not sure having the freedom of passing any component would make sense here 🤔

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, me neither fully. Just wanted to share the thought. One could argue (not saying has to) that having an consistent/expected API is also nice. You should go "How can I customise this?" "Ah, just like everywhere, maybe pass in the components thing.".

| `value` | `string` | ✅ | - | - | Value of the input component. |
| `onChange` | `func` | - | - | - | Called with an event containing the new value. Required when input is not read only. Parent should pass it back as `value`. |
| `onBlur` | `func` | - | - | - | Called when input is blurred |
| `onFocus` | `func` | - | - | - | Called when input is focused |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this right? Or it's called when any of the RadioOptions are focused?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've put it on the each RadioInput.Option. Do you think we should leave them out (onBlur/onFocus) or should we keep them like this?

| `name` | `string` | - | - | - | Used as HTML `name` of the input component. property |
| `value` | `string` | ✅ | - | - | Value of the input component. |
| `onChange` | `func` | - | - | - | Called with an event containing the new value. Required when input is not read only. Parent should pass it back as `value`. |
| `onBlur` | `func` | - | - | - | Called when input is blurred |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ditto

| `touched` | `bool` | - | - | `false` | Indicates whether the field was touched. Errors will only be shown when the field was touched. |
| `name` | `string` | - | - | - | Used as HTML `name` of the input component. property |
| `value` | `string` | ✅ | - | - | Value of the input component. |
| `onChange` | `func` | - | - | - | Called with an event containing the new value. Required when input is not read only. Parent should pass it back as `value`. |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can a RadioGroup be read only?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe, maybe not. I doesn't hurt to have it I suppose, as it's inline with the other inputs/fields.

});

describe('when disabled', () => {
it('should disable the input', () => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inputs?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels weird though. to me it makes more sense to pass isDisabled to the individual RadioOptions rather than the field.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You usually pass isDisabled to the entire group. In some special cases, you can then disable only specific options by passing isDisabled directly to them.

@emmenko emmenko changed the title feat: add RadioField component, rework RadioInput, add (experimental) StylesProvider feat: add RadioField component, rework RadioInput Feb 14, 2019
| `children` | `node` | ✅ | - | - | The `RadioInput.Option` or another node (mixed children are allowed) |
| `value` | `string` | - | - | - | The selected value of the of a `RadioInput.Option` determining its checked status |
| `onChange` | `func` | ✅ | - | - | What will trigger whenever an `RadioInput.Option` is clicked |
| `scale` | `string` | - | ['xs', 's', 'm', 'l', 'xl'] | `m` | Spacing between options |
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically, this is what causes the breaking change, as it's been renamed to directionProps: { scale }

})}
</DirectionWrapper>
<div id={this.props.id}>
<Constraints.Horizontal constraint={this.props.horizontalConstraint}>
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only the stack mode has the horizontal constraint, as it does not make sense to have it in the inline mode.

role="radio"
aria-checked={props.isChecked}
onFocus={props.onFocus}
onBlur={props.onBlur}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I decided to put the onBlur/onFocus event handlers here, as it's what makes more sense to me, because the input is hidden and the entire label is clickable.

Not sure if we really need them though...

<label
css={getLabelStyles(props)}
role="radio"
aria-checked={props.isChecked}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The role and aria-checked are for a11y purposes.
https://www.w3.org/TR/wai-aria/#aria-checked

color: ${props.isDisabled
? vars.fontColorDisabled
: vars.fontColorDefault};
`}
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So I ended up removing the Text.Body wrapper, as it was just causing problems with the HTML markup (e.g. <div> nested inside a <p>).
The styles to apply are actually just a few, I think it's better this way.

/cc @montezume

@emmenko
Copy link
Member Author

emmenko commented Feb 14, 2019

Alright, VRTs have been approved by design, I'd be happy to get another round of review here. Thanks!

@tdeekens
Copy link
Contributor

I lost track of this with the other PRs in app-kit. Where are we here? Looks like some sort of walkthrough was supposed to happen?

@emmenko
Copy link
Member Author

emmenko commented Feb 19, 2019

What do you mean "walkthrough"?

@tdeekens
Copy link
Contributor

I just read somewhere that Malcolm and you wanted a call. Maybe that happened. Sorry then. I was just wondering how we wanted to proceed...

@emmenko
Copy link
Member Author

emmenko commented Feb 19, 2019

Ah yeah, I guess we talked about it last week when I was in Berlin

Copy link
Contributor

@tdeekens tdeekens left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at the code again, this looks good to me know. Is there anything missing from another side: UX, PO or functionality? Asking cause it's not marked as in dev review.

@emmenko
Copy link
Member Author

emmenko commented Feb 19, 2019

I'll check it with Filip tomorrow (the percy diffs), otherwise there is nothing else to block this.

@emmenko
Copy link
Member Author

emmenko commented Feb 20, 2019

@tdeekens @montezume this is now ready to go (VRTs have been approved by design).

Is there anything left from your side?

Copy link
Contributor

@montezume montezume left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks!

@emmenko emmenko merged commit c2fcaf7 into master Feb 20, 2019
@emmenko emmenko deleted the nm-radio-field branch February 20, 2019 10:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants