-
-
Notifications
You must be signed in to change notification settings - Fork 32.3k
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
[Chip] Migrate component [Avatar] Support children, change default colors #5852
Conversation
circleci is barfing on |
Looks like whatever was up with the coverage test got fixed and the tests automatically re-run, but it was still failing on the visual regression test due to my changes to Avatar, so I was premature in removing "PR: Needs Revision". I've updated the Avatar baseline images for 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.
That looks really great overall 😄 .
<Avatar className={classes.pinkAvatar}> | ||
<span className="material-icons">pageview</span> | ||
</Avatar> | ||
|
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.
Blank line, it's not longer used to separate examples in the jsx.
</SvgIcon> | ||
); | ||
const NavigationCancel = pure(NavigationCancelIcon); | ||
NavigationCancel.displayName = 'NavigationCancel'; |
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 line.
Same for the other svg icons.
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.
Any idea why we had it then? Isn't it used in React dev tools?
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.
the pure
Higher order component is already providing enough information. I think that we can save that line.
|
||
it('should render a div containing an Avatar div, span and svg', () => { | ||
assert.strictEqual(wrapper.is('div'), true, 'should be a div'); | ||
assert.strictEqual(wrapper.childAt(0).prop('component'), 'div', 'should be a div'); |
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 much prefer the other API:
assert.strictEqual(wrapper.childAt(0).props().component, 'div', 'should be a div');
I'm curious to get your though on that.
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 was struggling to find the right target for the test, and arrived at that syntax blindly, so more than happy to change to that API if this is the right thing to test 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.
That looks good to me 👍 .
if (childCount > 1) { | ||
children = React.Children.toArray(children); | ||
|
||
if (React.isValidElement(children[0]) && children[0].type.muiName === 'Avatar') { |
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 see @nathanmarks coming. I know we had this discussion before.
If we had an avatar
property we could save an iteration on the children and make the rendering logic simpler / faster.
Additionally, we could rely on CSS child resolution handling. A bit more fragile, but we have regressions tests.
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 did catch one comment about muiName
, but not the full discussion. I may be mistaken, but I don't think we save an iteration by moving from children to an avatar
prop, as still you have to check it's is a valid element, and clone it to apply styling.
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 may be mistaken, but I don't think we save an iteration
My bad, I have underestimated the number of iterations.
We would save a Children.count
and Children.toArray
call. Look at the implementation:
- toArray https://github.com/facebook/react/blob/master/src/isomorphic/children/ReactChildren.js#L196
- count https://github.com/facebook/react/blob/master/src/shared/utils/traverseAllChildren.js#L213
It's iterating twice.
Also, from an API point of view, I would rather depend on a named avatar
property than a less obvious muiName
checking when possible.
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 missed this comment - I'll give it a go tomorrow.
label: { | ||
color: palette.text, | ||
// display: 'inline-flex', // For broken avatar | ||
// alignItems: 'center', // For broken avatar |
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.
dead style?
@@ -77,6 +94,10 @@ Avatar.propTypes = { | |||
*/ | |||
alt: PropTypes.string, | |||
/** | |||
* Used to render icon and text elements inside the Avatar. | |||
*/ | |||
children: PropTypes.node, |
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 was the issue with the icon property? I mean, we could have simply renamed it children. Why keeping both or do we need a different logic?
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 keeping both, I just didn't want to barge in and change the API without discussing it first, so it left both options in place until everyone was agreed. I'll strip it back to just children
.
margin: 6, | ||
}, | ||
svgIcon: { | ||
color: '#444', |
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 a grey
variation?
|
||
const styleSheet = createStyleSheet('Chips', () => ({ | ||
chip: { | ||
margin: 6, |
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.
the smallest unity of margin / gutter is 8dp
. Can we use 8 here?
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 it would be good to have a theme property for that. We could use it on the Layout
component.
|
||
it('should render a div containing an Avatar div, span and svg', () => { | ||
assert.strictEqual(wrapper.is('div'), true, 'should be a div'); | ||
assert.strictEqual(wrapper.childAt(0).prop('component'), 'div', 'should be a div'); |
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 looks good to me 👍 .
const avatarClassName = classNames(classes.avatar); | ||
const avatarIconClassName = classNames(classes.avatarIcon); | ||
const labelClassName = classNames(classes.label, labelClassNameProp); | ||
const deleteIconClassName = classNames({ [classes.deleteIcon]: onRequestDelete }, deleteIconClassNameProp); |
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.
Might worse only computing that variable only when onRequestDelete
is truthy.
const classes = context.styleManager.render(styleSheet); | ||
const className = classNames(classes.root, { [classes.clickable]: onClick }, classNameProp); | ||
const avatarClassName = classNames(classes.avatar); | ||
const avatarIconClassName = classNames(classes.avatarIcon); |
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 to call classNames
with a single argument.
|
||
const classes = context.styleManager.render(styleSheet); | ||
const className = classNames(classes.root, { [classes.clickable]: onClick }, classNameProp); | ||
const avatarClassName = classNames(classes.avatar); |
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 to call classNames
with a single argument.
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 I need to read the jss docs. :)
Is classNames
just concatenating them?
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.
classNames is an helper. That has nothing to do with jss. https://github.com/JedWatson/classnames.
}, | ||
avatarIcon: { | ||
width: 19.2, // Added for jss avatar | ||
height: 19.2, // Added for jss avatar |
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.
Don't we have layouting issues with non-integer?
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 - in master
this is a dynamic style in Avatar, where the icon is 0.6 * avatar size
. Since Avatar no longer supports this, we have to calculate it manually (32 * 0.6 = 19.2).
Happy to round it down if you think it could cause a problem.
justifyContent: 'center', | ||
height: 32, | ||
outline: 'none', | ||
border: 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.
It's applied on a div
do we need that property?
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.
Ditto.
alignItems: 'center', | ||
justifyContent: 'center', | ||
height: 32, | ||
outline: 'none', |
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 applied on a div
do we need that property?
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 was carried over from master
, but can't imagine why it was needed. Removed.
@@ -110,3 +135,5 @@ Avatar.defaultProps = { | |||
Avatar.contextTypes = { | |||
styleManager: PropTypes.object.isRequired, | |||
}; | |||
|
|||
Avatar.muiName = 'Avatar'; |
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 could remove that line with the avatar
api.
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.
At the moment it's used in Chip to determine the child type - I'll leave it until the Chip API is solidified.
borderRadius: '50%', | ||
overflow: 'hidden', | ||
}, | ||
defaultColor: { | ||
color: palette.getContrastText(palette.text.disabled), | ||
background: palette.text.disabled, | ||
color: 'white', |
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.
Could be using
import { white } from './colors';
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.
Is it really worth importing 'white'? 😄
|
||
const styleSheet = createStyleSheet('Chips', () => ({ | ||
chip: { | ||
margin: 6, |
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 it would be good to have a theme property for that. We could use it on the Layout
component.
@oliviertassinari I've switched to your preferred API. Take a look! In doing so, I also removed the This makes Avatar simpler, and removes an otherwise redundant prop from Avatar (users can style the Avatar icon directly), but it does make the Chip code more complex. I'm open to your suggestion on what's preferable here. |
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 changing the API 👍 .
Think we are close to get it merged.
<Chip | ||
avatar={<Avatar>MB</Avatar>} | ||
label="SvgIcon Chip" | ||
onClick={() => {}} |
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 we need that for the regression test.
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.
Right, no - copy pasted from the docs demo. Although that makes me curious - is it possible to regression test the hover / focus / active styles?
<SvgIcon {...props}> | ||
<path | ||
d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 | ||
8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z" |
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.
Is a breaking line affecting the path? I have not idea. Let's keep it that way if not.
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.
Is a breaking line affeIs a breaking line affecting the path?
No it isn't, and in the next-docs-svg-icons PR I had manually fixed the linting errors in about half the icons which included the line-length rule, but then decided instead to add /* eslint-disable */ (I guess I could have added
src/svg-icons to .eslintignore
instead) and returned the icons to their generated form. For consistency I should revert this one too.
MB | ||
</Avatar>} | ||
label="Text Avatar Chip" | ||
onClick={() => {}} |
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 we need that for the unit test.
color: palette.background.default, | ||
backgroundColor: emphasize(palette.background.default, 0.26), | ||
}, | ||
icon: { |
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 need for this style? It seems to be working fine with font and svg icons.
That would allow us to avoid the cloneElement.
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 would allow us to avoid the cloneElement.
It would, but I've had to put it back for childrenClassName
.
I agree the styles are redundant though - they're an artefact from Avatar on master
where these were dynamic based on the size
prop.
if (avatarChildren) { | ||
// If Avatar has an icon, style it. | ||
if (React.isValidElement(avatarChildren)) { | ||
const avatarIconClassName = classNames(classes.avatarIcon, avatarChildren.props.className); |
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 are accessing avatarProp.props.children.props.className
, dear lord, that sounds really wrong.
What about moving the responsibility by exposing a childrenClassName
property to the <Avatar />
? Then, we can use it here.
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.
dear lord, that sounds really wrong.
LOL 😆 I wasn't so hot on it myself!
What about moving the responsibility by exposing a childrenClassName property to the ?
Yup, that's how I did it in a previous commit (well, iconClassName
) - see my comment above:
In doing so, I also removed the iconClassName prop that I previously added to Avatar.
This makes Avatar simpler, and removes an otherwise redundant prop from Avatar (users can style the Avatar icon directly), but it does make the Chip code more complex. I'm open to your suggestion on what's preferable here.
I think making childrenClassName
in Avatar hidden in the docs is probably the best compromise.
@oliviertassinari Okay, I've pushed those updates. My replies to your review comments may be hidden now. A few outstanding things:
|
I don't think that we need that feature at the
Good question, looking at the other implementation, I would answer no.
No, it's not because we broke a test that we should delete it. Fixing it would be much better.
You can reproduce that on the list demo. I think that we are close 🚢 . |
children = icon; | ||
if (childrenProp) { | ||
// If it's an icon, style it. | ||
if (React.isValidElement(childrenProp)) { |
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.
Good, we just miss that:
if (childrenClassName && React.isValidElement(childrenProp)) {
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 your patience! - It seems like my coding ability has regressed 2 years in 6 months, 😟
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.
Done.
@@ -110,3 +126,4 @@ Avatar.defaultProps = { | |||
Avatar.contextTypes = { | |||
styleManager: PropTypes.object.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.
two empty lines 😬 .
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('should render a div containing an icon', () => { | ||
assert.strictEqual(wrapper.is('div'), true, 'should be a div'); | ||
// assert.strictEqual(wrapper.childAt(0).is('svg'), true, 'should be an svg'); // OT - help please! :) |
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.
assert.strictEqual(wrapper.find(FaceIcon).length, 1, 'should contains the icon');
let deleteIcon = null; | ||
if (onRequestDelete) { | ||
deleteIconClassName = classNames(classes.deleteIcon, deleteIconClassNameProp); | ||
deleteIcon = |
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.
deleteIcon = (
<DeleteIcon
className={deleteIconClassName}
onClick={onRequestDelete}
/>
);
or
deleteIcon = <DeleteIcon className={deleteIconClassName} onClick={onRequestDelete} />;
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.
👍
* | ||
* ```jsx | ||
* <Chip> | ||
* <Avatar> |
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 need to update that example.
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.
Yes.
Going to pick up these loose ends tomorrow. Thanks so much for putting up with me! |
No, thanks for taking care of that component! |
I wouldn't read too much in to what material.angularjs.org are doing - it's a pretty ugly implementation. Are you saying we shouldn't apply any focus style, and let the parent component watch for focus and apply focus styles to chip? That doesn't seem right to me.
Again, I wouldn't ready too much into that - they don't apply hover or active styes to the chip or close button, so there's no difference anyway. react-toolbox applies hover style to the close button, but nothing else.
Edit: NVM, we hashed that out last time, so unless there's any change of opinion, Iet's leave the name as is. HOWEVER - there's also this: #2957. Should we channel all events through I do still think standardizing the callback signature is a good idea though - it's a bit of a mess on
I didn't say delete, I said disable. 😄 Edit: I thought this was the race condition you mentioned, but I needed to update that test for the revised Avatar API. Edit2: Now that I've fixed the What do we do with |
I realised the reason keyboard focus wasn't working is that I have started to implement the relevant functionality in Chip, but I'm wonder if I should instead use |
Well, at least, it's kind of do the job. A co-worker started implementing that component at the office with our product style guides. I will see what we can learn from that.
For the use case I was thinking of, chips wouldn't be keyboard focusable. The parent component would manually apply the focus state depending on it's own state.
I'm not convinced. I don't think that some variations are going to hurt. Users will still have to look at the documentation to know how to use it correctly. Either it's the right callback property name or how to filter events.
Ewww, we gonna need to address that flaky test.
I think that I would definitely use the |
True - they have a By "ugly" though, I meant the visual appearance of the chip - I notice they have hover and click styling on their todo-list.
👍
I know they're not directly comparable, but thinking of Chip as a subcomponent, I'm looking at If you're happy for me to leave it as is for now, we can revisit this in the context of a
It doesn't need to ripple, or focus ripple. It should probably be a button though as it's an interactive element that can be clicked etc. That would fix the I don't think we need to use |
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 left some minor comments. That's some great stuff 🎉 .
|
||
const chipData = this.state.chipData; | ||
const chipToDelete = chipData.map((chip) => chip.key).indexOf(key); | ||
chipData.splice(chipToDelete, 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'm not sure it's a great example. splice
mutate the array. It would be good to clone chipData
first 😁 .
const chipData = [...this.state.chipData];
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.
Line 47? (Or am I misunderstanding?)
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.
Yes, indeed
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.
Right, right. I'm surprised React doesn't scream about that!
const classes = context.styleManager.render(styleSheet); | ||
return ( | ||
<div className={classes.row}> | ||
<Chip |
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.
| onClick | function | | Callback function fired when the `Chip` element is clicked.<br><br>**Signature:**<br>`function(event: object) => void`<br>*event:* TouchTap event targeting the element. | | ||
| onRequestDelete | function | | Callback function fired when the delete icon is clicked. If set, the delete icon will be shown.<br><br>**Signature:**<br>`function(event: object) => void`<br>*event:* `touchTap` event targeting the element. | | ||
|
||
Other properties (not documented) are applied to the root element. |
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 might need to rebase on next
as I think we have improved that wording thanks to you 👍
<ListItemText primary="Photos" secondary="Jan 9, 2016" /> | ||
</ListItem> | ||
<ListItem button> | ||
<Avatar icon={<span className="material-icons">folder</span>} /> | ||
<Avatar ><span className="material-icons">folder</span></Avatar> |
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.
<Avatar><span className="material-icons">folder</span></Avatar>
|
||
let chipRef; | ||
|
||
const handleDeleteIconClick = (event) => { |
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 have never seen that pattern before. Interesting.
We could also share the function definition between renders by accepting a props
argument.
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 could also share the function definition between renders by accepting a props argument.
Sorry, could you explain please?
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.
If we change the signature to the following, I think that we would be able to allocate the function once.
const handleDeleteIconClick = (event, props) => {
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.
Sorry you're going to have to spell it out. 😊
Why pass props
when we're not using it, and how does that affect allocation?
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.
Right, my bad, that's not going to change anything as used like this onClick={handleDeleteIconClick} />;
.
Using a class, on the other hand, could help.
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 class, on the other hand, could help.
For Chip
?
It's a trade-off I guess. I wonder how much difference it would make, as instead we're dragging lifecycle methods along for the ride.
let deleteIcon = null; | ||
if (onRequestDelete) { | ||
deleteIconClassName = classNames(classes.deleteIcon, deleteIconClassNameProp); | ||
deleteIcon = (<DeleteIcon className={deleteIconClassName} onClick={handleDeleteIconClick} />); |
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 we need the parentheses ()
.
<button | ||
className={className} | ||
onClick={onClick} | ||
tabIndex={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.
I'm wondering if it shouldn't be -1
when the element don't have onClick
or onRequestClose
callbacks.
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.
Yes, that should fix the focus issue you mentioned.
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 fixed the issue, but now I'm wondering if there should no tabIndex
at all when the element don't have onClick
or onRequestClose
callbacks?
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'm wondering, isn't tabIndex={0}
doing nothing on an enable button. In that case yes, it could be undefined.
|
||
const chipData = this.state.chipData; | ||
const chipToDelete = chipData.map((chip) => chip.key).indexOf(key); | ||
chipData.splice(chipToDelete, 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.
Yes, indeed
} | ||
|
||
const chipData = this.state.chipData; | ||
const chipToDelete = chipData.map((chip) => chip.key).indexOf(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.
I think that it would be better like this, only reading memory and not allocating anything.
const chipToDelete = chipData.indexOf(chipData.find((chip) => chip.key === key)));
<ListItemText primary="Photos" secondary="Jan 9, 2016" /> | ||
</ListItem> | ||
<ListItem button> | ||
<Avatar icon={<FolderIcon />} /> | ||
<Avatar> <FolderIcon /></Avatar> |
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.
<Avatar><FolderIcon /></Avatar>
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.
Merge conflict foobar. Fixed.
return; | ||
} | ||
|
||
const chipData = Object.assign([], this.state.chipData); |
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 probably the only the only reference to Object.assign
in the code base. I would rather use the destructuration.
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, interesting. That sounds like a much better idea.
(I did wonder where all the Object.assign
s were in next
given how heavily we used it on master
😄 )
[Avatar] Support children, change default colors
Issues:
I've changes the default colours forAvatar
, but directly, not with palette - I could use some guidance on what should or shouldn't be added to palette.Not sure I'm applying styles to sub-components in the most optimal way - I've had to add a bunch ofSubComponentClassName
props. Not sure that's such a bad thing in and of itself, but again would welcome guidance.I should probably separate theAvatar
andChip
changes, but one was dependant on the other, so are lumped together for now.I had some difficulty finding the right selector one of the tests: Chip.spec.js:64Oh, and to agree onchildren
vsicon
prop (or both) forAvatar
- I've addedchildren
so we can compare, but I'm wide open on it.