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

[Toggle Button] Implemented new component for v1-beta (Issue #2863) #7551

Closed
wants to merge 39 commits into from
Closed

[Toggle Button] Implemented new component for v1-beta (Issue #2863) #7551

wants to merge 39 commits into from

Conversation

xsh2047
Copy link

@xsh2047 xsh2047 commented Jul 26, 2017

  • PR has tests / docs demo, and is linted.
  • Commit and PR titles begin with [ComponentName], and are in imperative form: "[Component] Fix leaky abstraction".
  • Description explains the issue / use-case resolved, and auto-closes the related issue(s) (http://tr.im/vFqem).

This is a pull request for the Toggle Button Component specified in the Material UI Design Specifications. So far there are no tests written for this component however I would like to change that with feedback from you, the contributors.

There is a demo for each version of the component included within the documentation. This is apart of the #2863 Issue and is up-to-date with the v1-beta branches changes as of 7/25/2017.

@xsh2047
Copy link
Author

xsh2047 commented Jul 26, 2017

The only lint errors are from another components comment as well as: react/no-array-index-key
which doesn't seem breaking for a component of this nature.

@xsh2047 xsh2047 changed the title Toggle button [Toggle Button] Implemented new component for v1-beta (Issue #2863) Jul 29, 2017
Copy link
Member

@kgregory kgregory left a comment

Choose a reason for hiding this comment

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

This is a very nice implementation, great first contribution. I have a few notes on it and I'm hoping to open a discussion so that we can get this into the package.

},
});

class Option extends Component {
Copy link
Member

Choose a reason for hiding this comment

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

This component is part of the ToggleButton implementation and should have a name that reflects that, similar to List having ListItem, ListItemIcon, etc. The spec indicates the following:

Toggle buttons may be used to group related options.

Maybe ToggleButton and ToggleButtonOption?

Copy link
Author

Choose a reason for hiding this comment

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

How about ToggleOption?

Copy link
Contributor

Choose a reason for hiding this comment

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

I vote for ToggleButtonOption

Copy link
Member

Choose a reason for hiding this comment

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

👍 for ToggleButtonOption.

Copy link
Author

Choose a reason for hiding this comment

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

Updated, it is now ToggleButtonOption

} else {
const items = children.map((child, index) => {
return React.cloneElement(child, {
key: index,
Copy link
Member

Choose a reason for hiding this comment

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

Using index as the key is going to cause an eslint warning and is not a good idea.

Copy link
Author

Choose a reason for hiding this comment

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

Thanks for the link, i will definitely take a look.

Copy link
Member

Choose a reason for hiding this comment

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

This is in fact causing a lint error:

/tmp/material-ui/src/ToggleButton/Option.js
138:16 error Do not use Array index in keys react/no-array-index-key


let optionButton;
let option;
// If there are children available, make it a Dropdown Menu.
Copy link
Member

@kgregory kgregory Jul 31, 2017

Choose a reason for hiding this comment

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

What exactly is being toggled when a toggle button option has a dropdown menu? I'm not sure if this fits in the expected user experience of this component. This seems more like a dropdown button.

In your demo, you need to drop the option down and deselect the selected option to clear the selection. I know it is visually represented in the Toggle Button specification, but I think it was there to flesh out the example of using toggle buttons in a toolbar.

Perhaps if it were made into a segmented dropdown button and the left segment could be toggled with a click?

Copy link
Author

Choose a reason for hiding this comment

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

It doesn't seem to be a segmented drop down button within the specification therefore I would be inclined to agree with your previous statement about it possibly just being there for appearance.

All tings considered, what would the accepted functionality be?

Personally I agree with the dropdown being separated if the current implementation isn't acceptable.

Copy link
Author

Choose a reason for hiding this comment

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

What is the final verdict on this?

color: fade(common.black, 0.3),
},
textSelected: {
color: fade(common.black, 0.54),
Copy link
Member

Choose a reason for hiding this comment

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

When using toggleIcon to present icons as toggle button options, the only indication that an icon has been selected is that the color changes slightly. In the specification, the color of the icon is the same for normal, hover, focus, and pressed states. The visual cue that an icon is in the pressed state is its radial background, which is a function of the icon's color.

The icon toggle focus indicator color and opacity are related to the color of the icon.

For this to work for icons, there will have to be some work done to the background. It would be nice to support a disabled icon as well. Perhaps through a type property, similar to the one implemented for button (primary, accent, disabled, contrast, default).

Copy link
Author

Choose a reason for hiding this comment

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

I will be updating the component accordingly thanks for that note.

Copy link
Author

Choose a reason for hiding this comment

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

For a component such as the Toggle Icon, would it make sense to have the user pass a color directly? Or utilize one from the theme?

Copy link
Member

Choose a reason for hiding this comment

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

Users can always override the value, but I think that we need a default value.

Copy link
Member

Choose a reason for hiding this comment

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

a variation of color as suggested by @kgregory sounds good too.

<MenuItem value={5}>Blue</MenuItem>
<MenuItem value={6}>Green</MenuItem>
</Option>
</ToggleButton>
Copy link
Member

@kgregory kgregory Jul 31, 2017

Choose a reason for hiding this comment

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

I don't think this should be part of the demo because it doesn't seem to be in the scope of a toggle button's user experience. I think this is more like a dropdown button.

It could work if this were a segmented dropdown button and the left segment could be used to toggle the selection.

Hopefully we can open a discussion on this.

Copy link
Author

Choose a reason for hiding this comment

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

Hopefully, based on the discussion for the previously raised query we can resolve this.

@rosskevin rosskevin added the v1 label Aug 2, 2017
/**
** NB: If changed, please update Checkbox, Switch and Radio
** so that the API documentation is updated.
**/
Copy link
Member

Choose a reason for hiding this comment

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

This comment block is causing one of your lint errors:

/tmp/material-ui/src/internal/SwitchBase.js
158:3 error Delete · prettier/prettier
158:4 error Expected space or tab before '*/' in comment spaced-comment

Since the next comment is identical, you should remove it.

Copy link
Member

Choose a reason for hiding this comment

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

This is a duplication, it should be removed.

} else {
const items = children.map((child, index) => {
return React.cloneElement(child, {
key: index,
Copy link
Member

Choose a reason for hiding this comment

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

This is in fact causing a lint error:

/tmp/material-ui/src/ToggleButton/Option.js
138:16 error Do not use Array index in keys react/no-array-index-key

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

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

aside from the code, some issues I have noticed with the component:

  • focus feedback issue
  • changing width when selected
  • docs/yarn.lock is needed
  • No contrast with the dark theme.
  • Some ripple issue, for instance, it can no longer be seen on the Table page

import Paper from 'material-ui/Paper';
import Typography from 'material-ui/Typography';

const styleSheet = createStyleSheet('ExclusiveToggleButton', {
Copy link
Member

Choose a reason for hiding this comment

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

You do no longer need to provide the sheet name. We have removed it from all our demo example. Please do the same here :)

width: '100%',
},
paper: {
padding: 30,
Copy link
Member

Choose a reason for hiding this comment

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

using a multiplier of theme.spacing.unit would be better.

function ExclusiveToggleButton(props) {
const classes = props.classes;

function alignRight() {
Copy link
Member

Choose a reason for hiding this comment

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

Can't those functions be defined in the parent scope? The issue right not is that they are going to be created at each render.

onDeselect={alignReset}
/>
</ToggleButton>

Copy link
Member

Choose a reason for hiding this comment

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

We almost never use blank line between the components.


{{demo='pages/component-demos/toggle-button/ToggleIcons.js'}}


Copy link
Member

Choose a reason for hiding this comment

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

Extra lines


state = {
active: false,
values: [],
Copy link
Member

Choose a reason for hiding this comment

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

That state is not used in the render method, no need.

Copy link
Author

Choose a reason for hiding this comment

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

Please elaborate

Copy link
Member

Choose a reason for hiding this comment

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

It can be an instance property. But then, it feels wrong to have this property at all. We need to remove it.

/**
* Values of the currently selected options on the 'ToggleButton'.
*/
values: PropTypes.arrayOf(
Copy link
Member

Choose a reason for hiding this comment

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

I don't think that we need this property.

/**
* Indexes of the currently selected options on the 'ToggleButton'.
*/
selectedOptions: PropTypes.arrayOf(PropTypes.number),
Copy link
Member

Choose a reason for hiding this comment

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

What about calling that property value?

Copy link
Author

Choose a reason for hiding this comment

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

It doesn't fit with what's stored

Copy link
Member

Choose a reason for hiding this comment

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

We use the value/onChange` couple as much as we can for controlling components. How doesn't that match what's store?

*
* @param {number, boolean, string} value The current value of the selected option.
*/
onDeselect: PropTypes.func,
Copy link
Member

Choose a reason for hiding this comment

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

What about merging onDeselect and onSelect into onChange?

};

state = {
active: false,
Copy link
Member

Choose a reason for hiding this comment

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

I don't think that we need that state. As far as I can see it, it can be extracted from the selectedOptions property.

@oliviertassinari oliviertassinari added the PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI label Aug 3, 2017
@oliviertassinari
Copy link
Member

oliviertassinari commented Aug 3, 2017

@zabieru96 I'm happy to see this PR :).
To put it up-front, it's gonna require some work before we can merge it. Expect it to need a good day full-time.

@oliviertassinari
Copy link
Member

This seems more like a dropdown button.

@kgregory I agree, it seems to be used in a broader context than the ToggleButton. I would be fine with the DropdownButton wording.

your previous statement about it possibly just being there for appearance

@zabieru96 I don't think so, I think that we have to deal with a specific type of DropdownButton. We could implement if from the Paper and the MenuItem components. Something close to the Autocomplete demo. I don't think that we can use the Menu component as it's now. It's covering and hiding the element opening it. We have different options. Either we write an abstraction like the Menu to deal with it, or we expose an implementation in the demo with the Popover. If people want to, they should be able to use another positioning library like popper.js, react-popper.
That's some thoughts I have. I haven't been digging more into it.

@mbrookes
Copy link
Member

mbrookes commented Aug 7, 2017

Appreciate this is still a WIP, but please could you update https://github.com/callemall/material-ui/blob/v1-beta/docs/src/pages/getting-started/supported-components.md as part of this PR?

@stevewillard
Copy link
Contributor

What's the status of this PR? Would love to use this component. Thanks for putting it together!

@xsh2047
Copy link
Author

xsh2047 commented Aug 23, 2017

To clarify should i remove the dropdown functionality and example? Also @stevewillard I have a few test cases i'm writing and would require further feedback.

@xsh2047
Copy link
Author

xsh2047 commented Aug 25, 2017

How do i fix the size limit error?
I'm over by like .75 KB.
Should I just increase it?

@oliviertassinari oliviertassinari added new feature New feature or request and removed PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI labels Aug 26, 2017
@oliviertassinari
Copy link
Member

@zabieru96 Have a look at the size-limit key in the package.json.

@xsh2047
Copy link
Author

xsh2047 commented Aug 26, 2017

@oliviertassinari I'm aware of the key, I'm just not sure if it's advised that I change it.

@oliviertassinari
Copy link
Member

@zabieru96 You can definitely increase the value of the size-limit. It's 100% fine for new components. I'm having a look at this PR now :).

Copy link
Member

@oliviertassinari oliviertassinari left a comment

Choose a reason for hiding this comment

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

Some more feedbacks. I haven't gone through all the changes of this PR. Some other issues I have noticed

  • Missing focus feedback
  • Toggle icon style no following the specs
  • Not vertically centered icon
  • Stateful components. I do think that they should all be stateless.
  • Missing accessibility
  • Need to rebase, we refactored the style handling and the documentation.

If you don't want to go through all those changes, I can understand and we can close the PR.

Thanks again for pushing Material-UI forward!

function alterText(value, selected) {
const div = document.getElementById('dummyDiv2');
if (selected && div !== null) {
if (value === '1') {
Copy link
Member

Choose a reason for hiding this comment

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

I think that a switch case would be better.

}));

function alterText(value, selected) {
const div = document.getElementById('dummyDiv2');
Copy link
Member

Choose a reason for hiding this comment

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

Why not using react for this task?

Copy link
Author

Choose a reason for hiding this comment

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

How do you propose it be done?

<div className={classes.root}>
<ToggleButton exclusive className="toggle">
<ToggleButtonOption
key="1"
Copy link
Member

Choose a reason for hiding this comment

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

What's the key is for? I don't think that you need it.

Copy link
Author

@xsh2047 xsh2047 Aug 27, 2017

Choose a reason for hiding this comment

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

A key has to be specified on the option because i utilize the map function within the ToggleButton component.


return (
<div className={classes.root}>
<ToggleButton exclusive className="toggle">
Copy link
Member

Choose a reason for hiding this comment

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

What's the className is for? I don't think that you need it.

Copy link
Author

Choose a reason for hiding this comment

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

It's so that the paper is full width, without it it's width only spans it's contents.

@@ -15,7 +15,7 @@ export const styleSheet = createStyleSheet('MuiTouchRipple', theme => ({
root: {
display: 'block',
position: 'absolute',
overflow: 'hidden',
// overflow: 'hidden', The ripple should be limited by an external component in my opinion.
Copy link
Member

Choose a reason for hiding this comment

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

This is breaking the other components. I don't see how it's related to this PR. Please add it back. We can discuss it aside from this PR.

it('should render with toggleIcon class', () => {
const wrapper = shallow(
<ToggleButton toggleIcons>
<ToggleButtonOption key="1" />
Copy link
Member

Choose a reason for hiding this comment

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

No need for the key.

});
});

describe('prop : divider', () => {
Copy link
Member

Choose a reason for hiding this comment

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

We use prop: without the space.

/**
* Indexes of the currently selected options on the 'ToggleButton'.
*/
selectedOptions: PropTypes.arrayOf(PropTypes.number),
Copy link
Member

Choose a reason for hiding this comment

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

We use the value/onChange` couple as much as we can for controlling components. How doesn't that match what's store?

color: selected ? fade(common.black, 0.54) : fade(common.black, 0.3),
},
};
const menuProps = {
Copy link
Member

Choose a reason for hiding this comment

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

Please take full advantage of JSX so we write all our components the same way (reducing entropy).

Copy link
Author

@xsh2047 xsh2047 Aug 27, 2017

Choose a reason for hiding this comment

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

It can be an instance property. But then, it feels wrong to have this property at all. We need to remove it.

Which property are you referring to?

We use the value/onChange` couple as much as we can for controlling components. How doesn't that match what's store?

Because what's stored in this property is the position of the selected item, not the value it contains.


state = {
active: false,
values: [],
Copy link
Member

Choose a reason for hiding this comment

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

It can be an instance property. But then, it feels wrong to have this property at all. We need to remove it.

@oliviertassinari oliviertassinari added PR: out-of-date The pull request has merge conflicts and can't be merged PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI and removed PR: out-of-date The pull request has merge conflicts and can't be merged labels Aug 27, 2017
@xsh2047
Copy link
Author

xsh2047 commented Aug 27, 2017

As for the Rebase I am still having trouble accessing the demos and api section of the docs site and that would mean a bottleneck until i can figure out the problem.

@xsh2047
Copy link
Author

xsh2047 commented Aug 28, 2017

Okay so a recent push to the repository solves my previously mentioned error. I just need to know how to migrate my component.

@xsh2047
Copy link
Author

xsh2047 commented Aug 28, 2017

Okay so I have updated the branch to incorporate the code in v1-beta. I guess all thats left is another review.

@oliviertassinari
Copy link
Member

@zabieru96 Will give another look :)

@oliviertassinari
Copy link
Member

@zabieru96 We appreciate the work you have done on this PR so far! Thanks for your time :). However, I don't think that we are near merging it, for instance the build is green and I have been raising some issues that haven't been fixed. I'm going to close it as haven't moved forward for quite some time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
new feature New feature or request PR: needs revision The pull request can't be merged. More details is available on the code review or fails in the CI
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants