microsoft / fluentui-blazor

Microsoft Fluent UI Blazor components library. For use with ASP.NET Core Blazor applications
https://www.fluentui-blazor.net
MIT License
3.49k stars 322 forks source link

fix: Value "[object Object]" is set to css variable when using WithDefault/ToSwatch #2158

Closed guimabdo closed 1 month ago

guimabdo commented 1 month ago

🐛 Bug Report

When using .WithDefault on a color value Design Token, the related css variable is set with an invalid value [object Object] image

💻 Repro or Code Sample

<FluentCard>
    Test
</FluentCard>
<FluentDivider />
<FluentButton OnClick="ChangeUsingCsharp">
    WithDefault (C#)
</FluentButton>
<FluentButton OnClick="ChangeUsingJs">
    WithDefault (JS)
</FluentButton>
@code {
    [Inject]
    public NeutralStrokeLayerRest NeutralStrokeLayerRest { get; set; } = default!;
    [Inject]
    public IJSRuntime JSRuntime { get; set; } = default!;

    // This produces invalid css variable value
    private async Task ChangeUsingCsharp()
    {
        await NeutralStrokeLayerRest.WithDefault("red".ToSwatch());
    }

    // This one works correctly
    private async Task ChangeUsingJs()
    {
        var module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./_content/Microsoft.FluentUI.AspNetCore.Components/Microsoft.FluentUI.AspNetCore.Components.lib.module.js");
        await module.InvokeVoidAsync("neutralStrokeLayerRest.withDefault", "red");
    }
}

🤔 Expected Behavior

When clicking "WithDefault (C#)" the --neutral-stroke-layer-rest should be set to red: image

😯 Current Behavior

--neutral-stroke-layer-rest is set to [object Object] image

💁 Possible Solution

I currently don't have a suggestion for the fix. But as a warkaround it is possible to load the JS module and call the design token .withDefault directly:

var module = await JSRuntime.InvokeAsync<IJSObjectReference>("import", "./_content/Microsoft.FluentUI.AspNetCore.Components/Microsoft.FluentUI.AspNetCore.Components.lib.module.js");
await module.InvokeVoidAsync("neutralStrokeLayerRest.withDefault", "red");

🔦 Context

🌍 Your Environment

vnbaaij commented 1 month ago

As described on https://fluentui-blazor.net/DesignTokens:

For Design Tokens that work with a color value, you must call the ToSwatch() extension method on a string value or use one of the Swatch constructors. This makes sure the color is using a format that Design Tokens can handle. A Swatch has a lot of commonality with the System.Drawing.Color struct. Instead of the values of the components being between 0 and 255, in a Swatch the components are expressed as a value between 0 and 1.

What it does not mention but should be clear, is that this won't work on a 'named' color. So instead of "red" use "#ff0000" and it should work.

vnbaaij commented 1 month ago

Apparently, there is an issue when passing a Swatch to WithDefault. I addded an overload that takes a string value (see PR #2159). Your code will work once this addition is released.