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

Ux 603 New Radio component #261

Merged
merged 35 commits into from Dec 4, 2019
Merged

Ux 603 New Radio component #261

merged 35 commits into from Dec 4, 2019

Conversation

tristanjasper
Copy link
Contributor

@tristanjasper tristanjasper commented Nov 1, 2019

🛠 Purpose

Add the radio component to Paprika.
http://storybooks.highbond-s3.com/paprika/ux-603-radio-component

Tests to be added in future PR

✏️ Notes to Reviewer


🖥 Screenshots


image

@tristanjasper tristanjasper added WIP 📦 New Package A new shiny Component labels Nov 1, 2019
@tristanjasper tristanjasper changed the title Ux 603 radio component Ux 603 Radio component Nov 1, 2019
@tristanjasper tristanjasper changed the title Ux 603 Radio component Ux 603 New Radio component Nov 1, 2019
@johnpeele
Copy link

@tristanjasper You might already be aware, but the checked state for the Large size is a bit off.

Screen Shot 2019-11-04 at 12 21 24 PM

@tristanjasper tristanjasper removed the WIP label Nov 20, 2019
@tristanjasper tristanjasper marked this pull request as ready for review November 20, 2019 19:25
@tristanjasper
Copy link
Contributor Author

@tristanjasper You might already be aware, but the checked state for the Large size is a bit off.

Screen Shot 2019-11-04 at 12 21 24 PM

@johnpeele What browser were you seeing this out of interest? I'll look into it.

a11yText: text("a11yText", ""),
});

const ExampleStory = props => {
Copy link
Contributor

Choose a reason for hiding this comment

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

To me sound that this Group radio button should be a uncontrolled component, my concern is that is too much boiler plate when what a consumer pretty much wants it o know which component is checked.

I would approach this API like the following:

<Radio.Group 
   defaultCheck={(check) => check.value.id === "something"} 
   onChange={(value) => { console.log(value) }}
>
   <Radio value={whatever}>First</Radio>
   <Radio value={whatever}>second</Radio>
   <Radio value={whatever}>third</Radio>
<Radio.Group>

This achieve two things one removes the need of any state from the consumer and give the ability to set the initial value via a function that can be used to check which checkbox should be initially selected.

what do you think? @mikrotron @tristanjasper

Copy link
Contributor

Choose a reason for hiding this comment

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

Also this way we are more align the way that most input component works like having a onChange value. like the input, select and pretty much any react component.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sure that is another option, I guess there isn't really a case for a single radio component to be needed, ie without the surrounding radioGroup container so yeah would be cleaner. I'll move forward with this suggestion

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also this way we are more align the way that most input component works like having a onChange value. like the input, select and pretty much any react component.

Agreed

@johnpeele
Copy link

@tristanjasper I am using Brave, which is a version of Chrome.

packages/Radio/README.md Outdated Show resolved Hide resolved
size: ShirtSizes.MEDIUM,
};

const Group = ({ a11yLabelledByText, canDeselect, children, defaultCheck, ...moreGroupProps }) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

please switch this to a form a function instead of arrow function and destructured the properties on the body.

function Group(props) {
const {a11yLabelledByText, canDeselect, children, defaultCheck, ...moreGroupProps} = props;
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

ok out of interest what is the reason for the preference?

<Tagline>Use the knobs to tinker with the props.</Tagline>
<Rule />
<Radio.Group
defaultCheck={check => check.props.value.id === "value 1"}
Copy link
Contributor

Choose a reason for hiding this comment

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

💯 thank you 😻

@nahumzs
Copy link
Contributor

nahumzs commented Nov 21, 2019

@johnpeele We officially support chrome, firefox, Edge, Safari, and we try to do our best to make it render as similar as possible on IE11. I think is quite expensive to try to adjust all known browsers apart from them. cc @mikrotron

size: PropTypes.oneOf(ShirtSizes.DEFAULT),
value: PropTypes.shape({ id: PropTypes.string }).isRequired,
Copy link
Contributor

Choose a reason for hiding this comment

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

Hm, how about:

PropTypes.oneOfType([
  PropTypes.bool,
  PropTypes.string,
  PropTypes.number,
  PropTypes.shape({ id: PropTypes.string }),
]).isRequired

Copy link
Contributor

Choose a reason for hiding this comment

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

This would require a bit of logic when you use the value as the key, but gives the consumer more flexibility.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yep, no longer using the value however as consumer can work with the activeIndex to get the data values


function Group(props) {
const { a11yText, canDeselect, children, isDisabled, onChange, ...moreGroupProps } = props;
const defaultCheckedIndex = React.Children.toArray(children).findIndex(child => child.props.defaultIsChecked);
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 assumes Radio is a direct child of Group which defeats the purpose of using context. (Recommend to create a story with code like

<Radio.Group>
  <>
    <Radio />
    <Radio />
  <>
</Radio.Group>

to see that it doesn't work)
If it's acceptable to put the checked status on the group itself (i.e. checkedIndex prop), then I think context can still be used. Otherwise we should revert that change since it's not achieving what we want.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I would have thought it is ok to expect the usage of this component is to always use Radio components as the siblings? I understand that there will be issues if they use a different child but is that a scenario that we need to cover? We do provide storybook examples and a readme to show correct usage... 🤷‍♂

Copy link
Contributor Author

Choose a reason for hiding this comment

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

We could throw an error if the wrong child type was passed as well..

Copy link
Contributor

Choose a reason for hiding this comment

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

What if you need side-by-side radios though? You'll need some flexbox divs in there for layout.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Perhaps we will need to revisit the required api in a future PR. I know in the case of formElement we pass an isInline prop to dictate the layout rather than style the children directly, - https://github.com/acl-services/paprika/blob/master/packages/FormElement/src/FormElement.js#L34 But perhaps we are not too keen on that approach? Will need discussion. For now I have changed it back to use cloneElement rather than context. Discussing with @alexzherdev we have established that if we wanted to retain the index to dictate which radio is selected (we are also need to track which radio is deselectable) we would perhaps have to go down the route of https://gist.github.com/ryanflorence/10e9387f633f9d2e6f444a9bddaabf6e#option-4-the-unholy-option.


return (
<div role="radiogroup" aria-labelledby={a11yText} data-pka-anchor="radio.group">
{children.map((child, index) => {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think we should still use React.Children.map() here, to be a little more defensive.

setCheckedIndex(selectedIndex);
}

const deSelectableIndex = index => (checkedIndex === index ? null : index);
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: deSelectableIndexdeselectableIndex

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ok, i've changed to getDeselectableIndex as it is a function so I think that is more appropriate

Copy link
Contributor

@mikrotron mikrotron left a comment

Choose a reason for hiding this comment

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

llgtm 03

@tristanjasper tristanjasper merged commit 2b12f49 into master Dec 4, 2019
@tristanjasper tristanjasper deleted the ux-603-radio-component branch December 4, 2019 23:43
@allison-c allison-c restored the ux-603-radio-component branch October 24, 2022 21:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
📦 New Package A new shiny Component
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants