[FluentPersona] Add support for icons
Pull Request
📖 Description
The FluentPersona component only supports displaying images and initials in its circular avatar area.
This pull request adds additional support for icons to be displayed.
Images will always be preferred over icons, which themselves will always be preferred over initials.
This pull request further fixes the RTL margin for the FluentPersona component.
✅ Checklist
General
- [ ] I have added tests for my changes.
- [x] I have tested my changes.
- [x] I have updated the project documentation to reflect my changes.
- [x] I have read the CONTRIBUTING documentation and followed the standards for this project.
Component-specific
- [ ] I have added a new component
- [ ] I have added Unit Tests for my new compontent
- [x] I have modified an existing component
- [ ] I have validate Unit Tests for an existing component
It might be a good idea to allow icon content (SVG) in this image part of the component. But I'm a bit scared by the complexity of the available properties: Image vs Icon and ImageSize vs IconSize.
We'll need to explain the "priority" of the properties (Icon then Image) and also how to specify sizes.
It would be more "logical" to allow an icon (SVG) to be included in the Image property.
It would be more "logical" to allow an icon (SVG) to be included in the
Imageproperty.
Funnily, that's the first thing I tried today, when I needed an icon avatar 😄
So, you say no new properties should be added but instead it should be checked whether Image contains an SVG (i.e. Image.StartsWith("<svg>")? At least, I wouldn't know how else this could be implemented)?
We could convert an Icon to an img src (used in FluentPersona), adding this part of code in Icon.cs file
public virtual string ToDataUri(string? size = null, string? color = null)
{
var svg = ToMarkup(size, color).Value;
// Attribute xmlns="http://www.w3.org/2000/svg" is required for SVG data URI.
svg = svg.Contains("http://www.w3.org/2000/svg") ? svg : svg.Replace("<svg ", "<svg xmlns=\"http://www.w3.org/2000/svg\" ");
var base64Svg = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(svg));
return $"data:image/svg+xml;base64,{base64Svg}";
}
So, the usage will be
<FluentPersona Name="Bill Gates"
Status="PresenceStatus.Available"
StatusSize="PresenceBadgeSize.Small"
StatusTitle="He is available"
Image="@(new Icons.Regular.Size48.Person().ToDataUri(color: "white"))"
ImageSize="50px">
</FluentPersona>
Can you update your PR? Or I can create a new one if you prefer.
I can update my PR, but I just tested this and it does neither seem to work with custom sizes nor with variable colors (e.g. var(--fill-color)) :/
We could convert an Icon to an
img src(used in FluentPersona), adding this part of code inIcon.csfilepublic virtual string ToDataUri(string? size = null, string? color = null) { var svg = ToMarkup(size, color).Value; // Attribute xmlns="http://www.w3.org/2000/svg" is required for SVG data URI. svg = svg.Contains("http://www.w3.org/2000/svg") ? svg : svg.Replace("<svg ", "<svg xmlns=\"http://www.w3.org/2000/svg\" "); var base64Svg = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(svg)); return $"data:image/svg+xml;base64,{base64Svg}"; }So, the usage will be
<FluentPersona Name="Bill Gates" Status="PresenceStatus.Available" StatusSize="PresenceBadgeSize.Small" StatusTitle="He is available" Image="@(new Icons.Regular.Size48.Person().ToDataUri(color: "white"))" ImageSize="50px"> </FluentPersona>Can you update your PR? Or I can create a new one if you prefer.
What if, in addition to your suggested changes, a RenderFragment named "ImageContent" (or something similar) is provided. This would allow customization of the image without adding any new parameters (except the RenderFragment) or worrying about explaining the priority of parameters.
With a RenderFragment we can't control and/or check if an actual image is being supplied. I rather add some parameters and be 'in control'.
With a
RenderFragmentwe can't control and/or check if an actual image is being supplied. I rather add some parameters and be 'in control'.
So, how should we proceed with this? I guess this feature would be of great use, but I would like to get it done right (and conforming to your library).
I'd say we go with the solution @dvoituron provided (and make it work)
Yes, I think this solution does not (yet) cover all cases, but it does cover a large proportion. The advantage is that it can also be used for other types of problem. We can always think later about additional options to manage the "system" color.
Alright, I've update the code to use @dvoituron's solution. I also tinkered around with how to support custom sizes for icons. The only problem left is that images smaller than the specified ImageSize do not fill up the full image area. Maybe you can come up with a solution to this problem?
@hksalessio can you check the Unit Tests. Some are failing and because of that the pipline that build the code won't run.
We are merging this as-is and then do some checks ourselves on the dev branch