When I pass in children and a src
prop to the Avatar
component, both are rendered. This is a change in behaviour that was not expected, and was caused by #17693.
Provide children and a src
to the Avatar component, like so:
<Avatar src={person.avatar} className={classes.avatarPerson}>
{person.name.substr(0, 1)}
</Avatar>
We use this to display user profile images, but fallback to the user name initials if the image doesn't exist.
| Tech | Version |
| ----------- | ------- |
| Material-UI | v4.2.1 |
@ajdaniel It sounds like you have to pick between one of the two approaches. Why do you mix both?
That's how it worked before. The children prop became a fallback and I didn't have to code the logic of showing or hiding the children based on the image availability, it just did that automatically.
The children prop description:
Used to render icon or text elements inside the Avatar. src and alt props will not be used and no img will be rendered by default.
This can be an element, or just a string.
It seems that prior to #17693, the implementation behave the opposite to the documentation.
Okay that's not a problem, I can't argue against undocumented features. I had a feeling this was the case too, but I wanted to raise the point.
Huh, perhaps we need to clarify the props in the component too.
Perhaps we can add it as a feature? Perhaps instead of children we could have a prop like fallbackRender
which renders if the src
or srcSet
is empty?
I would propose that we 1. update the prop description to match reality. 2. I wouldn't be against a customization demo per @lcswillems use case. 3. a test case to it.
Regarding your fallback proposal, imgFallbackChildren?: boolean
has potential. However, I'm wondering if it's not better, for their developer to have the logic visible in their render methods. @mbrookes what do you think?
@oliviertassinari I am not sure to understand what you expect from me?
Nothing, I was including you for context :)
imgFallbackChildren?: boolean
That sounds horrible! 馃檧We should pick one behaviour and stick to it. If #17693 hadn't already been merged, I'd favour @ajdaniel's use case over @lcswillems', and suggest a customization demo for the latter instead.
Not sure what the best path forward is though, short of reverting #17693 and updating the documentation.
@mbrookes Why would you prefer @ajdaniel use case over mine?
@mbrookes What do you think of the behavior in the children prop description? It seems to be a 3rd viable option:
@lcswillems Because displaying one type of content in an Avatar is the norm, whereas your requirement is more of a customisation.
@oliviertassinari Why would 3. be preferable? From my experience, text is always used as a fallback to an image, not the other way around.
The problem with children > img
is that the avatar img behavior will have to be reimplemented.
If we do children + img
, @ajdaniel just have to conditionally display its children if src
is set, that is much easier.
I think @ajdaniel filled an issue just because it broke his code, not necessarily because it was the good use case.
@mbrookes Why not have a fallbackText
property and let the children
be used.
That sounds horrible! 馃檧
@mbrookes Yeah, I agree.
In my opinion, the fallback logic should be on the userland. I think that people should be able to infer it from reading their code:
<Avatar src={person.avatar} className={classes.avatarPerson}>
{person.avatar ? null : person.name.substr(0, 1)}
</Avatar>
Otherwise, it's not obvious what will happen if both information is present, or if one is missing.
I do agree that an avatar image is a piece of superior information to the initial letters in the most common use cases, but what if somebody wants to display both?
Now, I don't have a strong preference between 1. and 2. The avatar was designed to display the information, not to edit it. @lcswillems could write its own logic, at this point, it could be simpler to bypass the Avatar.
I would propose:
<Avatar src={person.avatar} className={classes.avatarPerson}>
{person.avatar ? null : person.name.substr(0, 1)}
</Avatar>
That doesn't seem unreasonable.
what if somebody wants to display both?
In that case should the children be displayed _over_ the image (rather than beside it)?
@mbrookes I don't know, the use case I had in mind is somebody that want to apply customizations. But maybe it's an edge case and more people would benefit from the fallback behavior.
<Avatar src={person.avatar} className={classes.avatarPerson}>
{person.avatar ? null : person.name.substr(0, 1)}
</Avatar>
If this is up for taking can I work on it? :)
Just to clarify my understanding of this thread.
Was wondering if you see fallback, covering the un-happy path, where src does not load and an onError
occurs ?
When using src
(or srcSet
), I saw children
as a fallback for the onError
condition.
Whilst you have the alt
prop, it does not look so great in practice, with style, borderRadius: 50%
Also, worth mentioning one of your other issues. not un-related to this.
https://github.com/mui-org/material-ui/issues/16161
Not sure, how valid that ask is but worth mentioning in this context.
@slipmat In practice is it frequent for the image URL to be broken? I would be in favor to ignore this problem.
@mbrookes In which direction should we go?
Ant Design works that way, although that's not a reason to follow suit.
With MUI you can pass through onError via imgProps, so there are ways around it.
Could be one to cover via the docs, if needed.
The userland fallback approach isn't too onerous. My overriding concern is that #17694 is a breaking change for developers depending on the previous (if incorrectly documented) logic.
@mbrookes OK, I propose that we revert #17694
component
prop or a custom made component. My only fear would be that we break composition, that looking at:
<Avatar src={person.avatar} className={classes.avatarPerson}>
{person.name.substr(0, 1)}
</Avatar>
It's unclear what happen.
component
prop? I don't see how to use it in my case.
And if I have to create a custom made component, I will have to copy paste all the base logic to increment on it.
@lcswillems
const EditAvatar = props => (
<div {...props}>
{props.children}
<div>Edit</div>
</div>
)
const <Avatar src="sef" component={EditAvatar} />
Okay, I see. I think it is the good design choice.
@lcswillems
const EditAvatar = props => ( <div {...props}> {props.children} <div>Edit</div> </div> ) const <Avatar src="sef" component={EditAvatar} />
should this be added in the demo as an example, if yes can I pretty please work on this?
@adeelibr I would rather avoid it, thanks for proposing to help. @eps1lon is looking into how we can get rid of the component prop.
Most helpful comment
Just to clarify my understanding of this thread.
Was wondering if you see fallback, covering the un-happy path, where src does not load and an
onError
occurs ?When using
src
(orsrcSet
), I sawchildren
as a fallback for theonError
condition.Whilst you have the
alt
prop, it does not look so great in practice, with style,borderRadius: 50%
Also, worth mentioning one of your other issues. not un-related to this.
https://github.com/mui-org/material-ui/issues/16161
Not sure, how valid that ask is but worth mentioning in this context.