-
-
Notifications
You must be signed in to change notification settings - Fork 32.4k
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
Conversation
…nto toggle-button
…nto toggle-button
…to toggle-button
…to toggle-button
The only lint errors are from another components comment as well as: react/no-array-index-key |
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 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.
src/ToggleButton/Option.js
Outdated
}, | ||
}); | ||
|
||
class Option extends Component { |
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 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?
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.
How about ToggleOption?
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 vote for ToggleButtonOption
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.
👍 for ToggleButtonOption
.
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.
Updated, it is now ToggleButtonOption
src/ToggleButton/Option.js
Outdated
} else { | ||
const items = children.map((child, index) => { | ||
return React.cloneElement(child, { | ||
key: index, |
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.
Using index as the key is going to cause an eslint warning and is not a good idea.
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 for the link, i will definitely take a look.
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 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
src/ToggleButton/Option.js
Outdated
|
||
let optionButton; | ||
let option; | ||
// If there are children available, make it a Dropdown Menu. |
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.
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?
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 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.
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.
What is the final verdict on this?
src/ToggleButton/Option.js
Outdated
color: fade(common.black, 0.3), | ||
}, | ||
textSelected: { | ||
color: fade(common.black, 0.54), |
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.
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).
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 will be updating the component accordingly thanks for that note.
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.
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?
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.
Users can always override the value, but I think that we need a default 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.
a variation of color as suggested by @kgregory sounds good too.
<MenuItem value={5}>Blue</MenuItem> | ||
<MenuItem value={6}>Green</MenuItem> | ||
</Option> | ||
</ToggleButton> |
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 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.
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.
Hopefully, based on the discussion for the previously raised query we can resolve this.
src/internal/SwitchBase.js
Outdated
/** | ||
** NB: If changed, please update Checkbox, Switch and Radio | ||
** so that the API documentation is updated. | ||
**/ |
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 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.
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 a duplication, it should be removed.
src/ToggleButton/Option.js
Outdated
} else { | ||
const items = children.map((child, index) => { | ||
return React.cloneElement(child, { | ||
key: index, |
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 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
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.
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', { |
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.
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, |
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.
using a multiplier of theme.spacing.unit
would be better.
function ExclusiveToggleButton(props) { | ||
const classes = props.classes; | ||
|
||
function alignRight() { |
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.
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> | ||
|
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.
We almost never use blank line between the components.
|
||
{{demo='pages/component-demos/toggle-button/ToggleIcons.js'}} | ||
|
||
|
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.
Extra lines
|
||
state = { | ||
active: false, | ||
values: [], |
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 state is not used in the render method, no need.
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.
Please elaborate
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 can be an instance property. But then, it feels wrong to have this property at all. We need to remove it.
src/ToggleButton/ToggleButton.js
Outdated
/** | ||
* Values of the currently selected options on the 'ToggleButton'. | ||
*/ | ||
values: PropTypes.arrayOf( |
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 don't think that we need this property.
/** | ||
* Indexes of the currently selected options on the 'ToggleButton'. | ||
*/ | ||
selectedOptions: PropTypes.arrayOf(PropTypes.number), |
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.
What about calling that property 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.
It doesn't fit with what's stored
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.
We use the value
/onChange` couple as much as we can for controlling components. How doesn't that match what's store?
src/ToggleButton/Option.js
Outdated
* | ||
* @param {number, boolean, string} value The current value of the selected option. | ||
*/ | ||
onDeselect: PropTypes.func, |
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.
What about merging onDeselect
and onSelect
into onChange
?
}; | ||
|
||
state = { | ||
active: 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.
I don't think that we need that state. As far as I can see it, it can be extracted from the selectedOptions
property.
@zabieru96 I'm happy to see this PR :). |
@kgregory I agree, it seems to be used in a broader context than the ToggleButton. I would be fine with the
@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. |
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? |
What's the status of this PR? Would love to use this component. Thanks for putting it together! |
… the specification and setup basic tests
…on non-exclusive toggle button
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. |
How do i fix the size limit error? |
@zabieru96 Have a look at the |
@oliviertassinari I'm aware of the key, I'm just not sure if it's advised that I change it. |
@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 :). |
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.
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') { |
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 that a switch case would be better.
})); | ||
|
||
function alterText(value, selected) { | ||
const div = document.getElementById('dummyDiv2'); |
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 not using react for this task?
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.
How do you propose it be done?
<div className={classes.root}> | ||
<ToggleButton exclusive className="toggle"> | ||
<ToggleButtonOption | ||
key="1" |
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.
What's the key is for? I don't think that you need 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.
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"> |
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.
What's the className is for? I don't think that you need 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.
It's so that the paper is full width, without it it's width only spans it's contents.
src/internal/TouchRipple.js
Outdated
@@ -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. |
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 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" /> |
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.
No need for the key.
}); | ||
}); | ||
|
||
describe('prop : divider', () => { |
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.
We use prop:
without the space.
/** | ||
* Indexes of the currently selected options on the 'ToggleButton'. | ||
*/ | ||
selectedOptions: PropTypes.arrayOf(PropTypes.number), |
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.
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 = { |
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.
Please take full advantage of JSX so we write all our components the same way (reducing entropy).
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 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: [], |
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 can be an instance property. But then, it feels wrong to have this property at all. We need to remove it.
…ed size check from 120KB to 121KB
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. |
Okay so a recent push to the repository solves my previously mentioned error. I just need to know how to migrate my component. |
Okay so I have updated the branch to incorporate the code in v1-beta. I guess all thats left is another review. |
@zabieru96 Will give another look :) |
@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. |
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.