MudBlazor / MudBlazor

Blazor Component Library based on Material design with an emphasis on ease of use. Mainly written in C# with Javascript kept to a bare minimum it empowers .NET developers to easily debug it if needed.
http://mudblazor.com
MIT License
7.39k stars 1.19k forks source link

MudText: Ability to control which HTML tag is used #8898

Closed danielchalmers closed 1 month ago

danielchalmers commented 1 month ago

Feature request type

Enhance component

Component name

MudText

Is your feature request related to a problem?

Typos don't always align with their intended purpose. For instance, the landing page uses subtitle1 heavily.

image

This makes me think most people use it just to have smaller text, but that's not necessarily correct, especially regarding accessibility and SEO.

Describe the solution you'd like

We could repurpose the Inline property (or add a new one) to let the user choose themselves what type of element it should be. It should be automatic by default with the same tags we use now.

MudText.razor.cs

-/// <summary>
-/// If true, Sets display inline
-/// </summary>
-[Parameter]
-[Category(CategoryTypes.Text.Appearance)]
-public bool Inline { get; set; }

+/// <summary>
+/// The HTML element that will be rendered (<c>span</c>, <c>p</c>, <c>h1</c>).
+/// <br/>
+/// If <c>null</c> it is automatically decided based on <see cref="Typo"/>.
+/// </summary>
+/// <remarks>
+/// This can be used to specify the type of content for accessibility and SEO more accurately.
+/// <br/>
+/// https://developer.mozilla.org/en-US/docs/Web/HTML/Element#text_content
+/// </remarks>
+[Parameter]
+[Category(CategoryTypes.Text.Behavior)]
+public string? HtmlTag { get; set; }

We need to add notes to Inline (if we keep it) and Align about potential compatibility issues.

Have you seen this feature anywhere else?

https://developer.mozilla.org/en-US/docs/Web/HTML/Element#text_content https://developer.mozilla.org/en-US/docs/Web/HTML/Element#inline_text_semantics

Describe alternatives you've considered

No response

Pull Request

Code of Conduct

github-actions[bot] commented 1 month ago

Thanks for wanting to do a PR, @danielchalmers !

We try to merge all non-breaking bugfixes and will deliberate the value of new features for the community. Please note there is no guarantee your pull request will be merged, so if you want to be sure before investing the work, feel free to contact the team first.

danielchalmers commented 1 month ago

+1 for keeping it a <p> by default.

Why can't we keep the Inline property in addition to the HtmlTag. To me it looks they are orthogonal to each other, meaning you can set display: block on whatever html tag you choose, no matter whether it is necessary or not.

And it is not uncommon that one parameter disables the function of another parameter. We have that in many components. All we need is documentation pointing this out with a box like

Note

Parameter Align works only if you set parameter Inline bla bla whatever, I don't know what it should say exactly.

Quote from @henon https://github.com/MudBlazor/MudBlazor/issues/8865#issuecomment-2095283444

ScarletKuro commented 1 month ago

Btw, we probably need to use the manual RenderTreeBuilder for this, as we can't do this

<@HtmlTag ...> 
</>

Unless I don't know some feature in the razor syntax.

danielchalmers commented 1 month ago

we probably need to use the manual RenderTreeBuilder for this

protected override void BuildRenderTree(RenderTreeBuilder builder)
{
    base.BuildRenderTree(builder);
    var tagName = HtmlTag ?? GetTagName(Typo);

    builder.OpenElement(0, tagName);

    foreach (var attribute in UserAttributes.Where(a => a.Value != null))
        builder.AddAttribute(1, attribute.Key, attribute.Value);

    builder.AddAttribute(2, "class", Classname);
    builder.AddAttribute(3, "style", Style);
    builder.AddContent(4, ChildContent);
    builder.CloseElement();
}

private static string GetTagName(Typo typo)
{
    return typo switch
    {
        Typo.h1 => "h1",
        Typo.h2 => "h2",
        Typo.h3 => "h3",
        Typo.h4 => "h4",
        Typo.h5 => "h5",
        Typo.h6 => "h6",
        Typo.subtitle1 => "p",
        Typo.subtitle2 => "p",
        Typo.body1 => "p",
        Typo.body2 => "p",
        _ => "span"
    };
}

Like this @ScarletKuro ?

ScarletKuro commented 1 month ago

Yes, something like this.

henon commented 1 month ago

Btw, we probably need to use the manual RenderTreeBuilder for this, as we can't do this

<@HtmlTag ...> 
</>

Unless I don't know some feature in the razor syntax.

@ScarletKuro What about MudElement?

ScarletKuro commented 1 month ago

@ScarletKuro What about MudElement?

What about it, can you elaborate?

henon commented 1 month ago

It was made exactly for that purpose, to be able to switch out the html tag underneath

ScarletKuro commented 1 month ago

It was made exactly for that purpose, to be able to switch out the html tag underneath

Do you mean make MudText utilize MudElement instead of RenderTreeBuilder? That's an option too I guess.