Skip to content

fix: Initial Value not respected in [Wizard] #3759

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

Closed
davhdavh opened this issue May 8, 2025 · 11 comments
Closed

fix: Initial Value not respected in [Wizard] #3759

davhdavh opened this issue May 8, 2025 · 11 comments
Labels
status:blocked Any issue blocked by another
Milestone

Comments

@davhdavh
Copy link

davhdavh commented May 8, 2025

🐛 Bug Report

The Value on FluentWizard evaluates its guard check BEFORE steps are actually added. It therefore always fails the _steps.Count <= 0 check and you always start on step 0.

💻 Repro or Code Sample

<FluentWizard StepSequence="Any" @bind-Value="Step" ..

🤔 Expected Behavior

Wizard respects the initial step

😯 Current Behavior

Initial step value is ignored

🌍 Your Environment

4.11.8

@microsoft-github-policy-service microsoft-github-policy-service bot added the triage New issue. Needs to be looked at label May 8, 2025
@MarvinKlein1508
Copy link
Contributor

MarvinKlein1508 commented May 8, 2025

I can reproduce this as well.

_steps.Count is in fact 0 which leads to _value = 0;.

if (value < 0 || _steps.Count <= 0)

Note after the component has been initiliazed this works just fine when the bound value has been changed from outside the component. It's only the initial value which will be ignored.

@vnbaaij
Copy link
Collaborator

vnbaaij commented May 8, 2025

@MarvinKlein1508 any idea how to fix it (asking because you've already investigated)? If so, can you create a PR in the next few hours? If yes we can take this in for 4.11.9. Otherwise it will go into next next release

@MarvinKlein1508
Copy link
Contributor

@vnbaaij

The main issue is that the FluentWizardStep is initialized after the FluentWizard component has already been initialized. This makes sense, since the step is a subcomponent within the parent component. However, during its initialization, the FluentWizardStep attempts to register itself with the parent component. Because this occurs after the parent has already been fully initialized, the provided Value gets reset to 0—as the steps haven’t been registered yet.

I’m actually not sure how this could be fixed in a way that ensures subcomponents are initialized before the parent component finishes initializing. I’m not even sure that it’s possible.

I did some testing, and the only workaround I found is to ignore steps.Count altogether and assume that if steps.Count == 0, it simply hasn’t been initialized yet.

So, if I change

if (value < 0 || _steps.Count <= 0)

to:

/// <summary>
/// Gets or sets the step index of the current step.
/// This value is bindable.
/// </summary>
[Parameter]
public int Value
{
    get
    {
        return _value;
    }

    set
    {
        if (_steps.Count is 0)
        {
            _value = value;
        }
        else if (value < 0 || _steps.Count <= 0)
        {
            _value = 0;
        }
        else if (value > _steps.Count - 1)
        {
            _value = _steps.Count - 1;
        }
        else
        {
            _value = value;
        }

        _maxStepVisited = Math.Max(_value, _maxStepVisited);

        SetCurrentStatusToStep(_value);
    }
}

And also update

private bool DisplayPreviousButton => Value > 0 && _steps[..Value].Any(i => !i.Disabled);

to:

private bool DisplayPreviousButton => Value > 0 && _steps.Count > 0 && _steps[..Value].Any(i => !i.Disabled);

private bool DisplayNextButton => Value < _steps.Count - 1 && _steps.Count > 0 && _steps[(Value + 1)..].Any(i => !i.Disabled);

...then the issue is resolved. However, I’m not sure if this is the most robust or appropriate solution. Let me know what you two think.
@dvoituron

@vnbaaij
Copy link
Collaborator

vnbaaij commented May 8, 2025

Without looking at the code in depth, I can say that having a parameter that isn't a simple get;set property is not a recommended way in Blazor (I saw it is already like that in the existing code, so we need to change that later on)

But going on what you said, we'll fix it for an upcoming release. So no rush!

@MarvinKlein1508
Copy link
Contributor

Yes. I would also do this in an upcoming release. If you want to change the behaviour of the property this might require a significant amount of work. But this is definately a bug within the components :)

@vnbaaij vnbaaij added the status:needs-investigation Needs additional investigation label May 8, 2025
@vnbaaij vnbaaij added this to the v4.12 milestone May 8, 2025
@vnbaaij vnbaaij removed the triage New issue. Needs to be looked at label May 8, 2025
@davhdavh
Copy link
Author

davhdavh commented May 9, 2025

What about do it in a similar way to how the grid does it's start/end column calls. That will give a clear event when to set actual step and do the limit.

<Defer>
@{
FinishCollectingColumns();
}

@vnbaaij
Copy link
Collaborator

vnbaaij commented May 10, 2025

That could work but I think it is a bit of overkill for the Wizard. In a DataGrid there are frequent changes to columns. In a Wizard though, the number of steps will almost never need to change.

@davhdavh
Copy link
Author

True, but it would also eliminate those corner cases where the steps sometimes don't restart the numbering when the page gets re-rendered. I haven't made a bug for it since it happens quite rare.

@davhdavh
Copy link
Author

davhdavh commented May 13, 2025

ok, Defer also works as a workaround...

<FluentWizard @bind-Value="_currentStep" 
...
   </FluentWizardStep>
   <Microsoft.FluentUI.AspNetCore.Components.DataGrid.Infrastructure.Defer>
    @{
     if (_currentStep != _startStep)
     {
        _currentStep = _startStep;
        StateHasChanged();
     }
    }
   </Microsoft.FluentUI.AspNetCore.Components.DataGrid.Infrastructure.Defer>
  </Steps>

@dvoituron
Copy link
Collaborator

As you say, @bind-Value=“Step” will not move the Wizard Step on the second step (Step=1) because of the subcomponent registration. Changing this is not currently planned.

You could use the GoToStepAsync method as follows. Would that work for you?

FluentWizard MyWizard = default!;

protected override async Task OnAfterRenderAsync(bool firstRender)
{
    if (firstRender)
    {
        await MyWizard.GoToStepAsync(1);
    }
}

@dvoituron dvoituron added status:blocked Any issue blocked by another and removed status:needs-investigation Needs additional investigation labels May 13, 2025
@vnbaaij
Copy link
Collaborator

vnbaaij commented May 13, 2025

Closing this as there is a workaound now

@vnbaaij vnbaaij closed this as completed May 13, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status:blocked Any issue blocked by another
Projects
None yet
Development

No branches or pull requests

4 participants