Skip to content

Commit c2524da

Browse files
authored
Stepper Order And Classes (#365)
1 parent a3af83a commit c2524da

File tree

9 files changed

+301
-91
lines changed

9 files changed

+301
-91
lines changed

CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@
1111
</ItemGroup>
1212

1313
<ItemGroup>
14-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.0" />
15-
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.0" PrivateAssets="all" />
16-
<PackageReference Include="System.Net.Http.Json" Version="8.0.0" />
14+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly" Version="8.0.*" />
15+
<PackageReference Include="Microsoft.AspNetCore.Components.WebAssembly.DevServer" Version="8.0.*" PrivateAssets="all" />
16+
<PackageReference Include="System.Net.Http.Json" Version="8.0.*" />
1717
</ItemGroup>
1818

1919
</Project>

CodeBeam.MudBlazor.Extensions/Components/Stepper/MudStep.razor.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,6 @@
22
using MudBlazor;
33
using MudBlazor.Utilities;
44
using MudExtensions.Enums;
5-
using System;
6-
using System.Collections.Generic;
7-
using System.Linq;
8-
using System.Text;
9-
using System.Threading.Tasks;
105
using MudExtensions.Extensions;
116
using Microsoft.AspNetCore.Components.Rendering;
127

@@ -29,6 +24,21 @@ public partial class MudStep : MudComponentBase, IDisposable
2924
[Parameter]
3025
public string Title { get; set; }
3126

27+
private int _order;
28+
/// <summary>
29+
/// The order of the step.
30+
/// </summary>
31+
[Parameter]
32+
public int Order
33+
{
34+
get => _order;
35+
set
36+
{
37+
_order = value;
38+
MudStepper?.ReorderSteps();
39+
}
40+
}
41+
3242

3343
public bool IsActive
3444
{

CodeBeam.MudBlazor.Extensions/Components/Stepper/MudStepper.razor

Lines changed: 75 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -83,97 +83,107 @@
8383
<div class="@ContentClassname" style="@ContentStyle">
8484
@ChildContent
8585
</div>
86+
@if (DisablePreviousButton == false || DisableNextButton == false || DisableSkipButton)
87+
{
88+
<div class="@ActionClassname">
8689

87-
<div class="d-flex gap-4">
88-
89-
@{
90-
bool showResultStep = ShowResultStep();
91-
}
90+
@{
91+
bool showResultStep = ShowResultStep();
92+
}
9293

93-
@if (!DisablePreviousButton && ActiveIndex != 0)
94-
{
95-
if (IconActionButtons || MobileView)
94+
@if (StepperActionsJustify == StepperActionsJustify.End)
9695
{
97-
<MudTooltip Text="@LocalizedStrings.Previous" Delay="300">
98-
<MudIconButton Color="@Color" Variant="@Variant" Icon="@Icons.Material.Filled.ChevronLeft" OnClick="@(() => SetActiveIndex(-1))" />
99-
</MudTooltip>
96+
@if (ActionContent != null)
97+
{
98+
<MudSpacer />
99+
@ActionContent
100+
}
100101
}
101-
else
102+
103+
@if (!DisablePreviousButton && ActiveIndex != 0)
102104
{
103-
<MudButton Color="@Color" Variant="@Variant" OnClick="@(() => SetActiveIndex(-1))">@LocalizedStrings.Previous</MudButton>
105+
if (IconActionButtons || MobileView)
106+
{
107+
<MudTooltip Text="@LocalizedStrings.Previous" Delay="300">
108+
<MudIconButton Color="@Color" Variant="@Variant" Icon="@Icons.Material.Filled.ChevronLeft" OnClick="@(() => SetActiveIndex(-1))" />
109+
</MudTooltip>
110+
}
111+
else
112+
{
113+
<MudButton Color="@Color" Variant="@Variant" OnClick="@(() => SetActiveIndex(-1))">@LocalizedStrings.Previous</MudButton>
114+
}
104115
}
105-
}
106116

107-
@if (ActionContent != null)
108-
{
109-
@* The user will provide their own MudSpacer in this render fragment *@
110-
@ActionContent
111-
}
112-
else
113-
{
114-
<MudSpacer />
115-
}
117+
@if (ActionContent != null && StepperActionsJustify != StepperActionsJustify.End)
118+
{
119+
@* The user will provide their own MudSpacer in this render fragment *@
120+
@ActionContent
121+
}
122+
@if (StepperActionsJustify == StepperActionsJustify.SpaceBetween)
123+
{
124+
<MudSpacer />
125+
}
116126

117-
@if (showResultStep == false)
118-
{
119-
if ((ActiveIndex < Steps.Count && Steps[ActiveIndex].Status != StepStatus.Continued) || (ActiveIndex == Steps.Count - 1 && HasResultStep() == false && IsAllStepsCompleted()))
127+
@if (showResultStep == false)
120128
{
121-
if (!DisableStepResultIndicator && MobileView == false)
129+
if ((ActiveIndex < Steps.Count && Steps[ActiveIndex].Status != StepStatus.Continued) || (ActiveIndex == Steps.Count - 1 && HasResultStep() == false && IsAllStepsCompleted()))
122130
{
123-
<MudButton Color="@Color" Variant="Variant.Text" Disabled="true">@(Steps[ActiveIndex].Status == StepStatus.Completed ? LocalizedStrings.Completed : LocalizedStrings.Skipped)</MudButton>
131+
if (!DisableStepResultIndicator && MobileView == false)
132+
{
133+
<MudButton Color="@Color" Variant="Variant.Text" Disabled="true">@(Steps[ActiveIndex].Status == StepStatus.Completed ? LocalizedStrings.Completed : LocalizedStrings.Skipped)</MudButton>
134+
}
135+
}
136+
else if (ActiveIndex < Steps.Count && Steps[ActiveIndex].Optional == true)
137+
{
138+
if (!DisableSkipButton)
139+
{
140+
if (IconActionButtons || MobileView)
141+
{
142+
<MudTooltip Text="@LocalizedStrings.Skip" Delay="300">
143+
<MudIconButton Color="@Color" Variant="@Variant" Icon="@Icons.Material.Filled.SkipNext" OnClick="@(() => SkipStep(ActiveIndex))" />
144+
</MudTooltip>
145+
}
146+
else
147+
{
148+
<MudButton Color="@Color" Variant="@Variant" OnClick="@(() => SkipStep(ActiveIndex))">@LocalizedStrings.Skip</MudButton>
149+
}
150+
151+
}
124152
}
125153
}
126-
else if (ActiveIndex < Steps.Count && Steps[ActiveIndex].Optional == true)
154+
155+
@if (showResultStep == false && !DisableNextButton && !(ActiveIndex == Steps.Count - 1 && HasResultStep() == false && IsAllStepsCompleted()))
127156
{
128-
if (!DisableSkipButton)
157+
if (ActiveIndex < Steps.Count && Steps[ActiveIndex].Status != StepStatus.Continued)
129158
{
130159
if (IconActionButtons || MobileView)
131160
{
132-
<MudTooltip Text="@LocalizedStrings.Skip" Delay="300">
133-
<MudIconButton Color="@Color" Variant="@Variant" Icon="@Icons.Material.Filled.SkipNext" OnClick="@(() => SkipStep(ActiveIndex))" />
161+
<MudTooltip Text="@GetNextButtonString()" Delay="300">
162+
<MudIconButton Color="@Color" Variant="@Variant" Icon="@Icons.Material.Filled.ChevronRight" OnClick="@(() => SetActiveIndex(1))" />
134163
</MudTooltip>
135164
}
136165
else
137166
{
138-
<MudButton Color="@Color" Variant="@Variant" OnClick="@(() => SkipStep(ActiveIndex))">@LocalizedStrings.Skip</MudButton>
167+
<MudButton Color="@Color" Variant="@Variant" OnClick="@(() => SetActiveIndex(1))">@GetNextButtonString()</MudButton>
139168
}
140-
141-
}
142-
}
143-
}
144-
145-
@if (showResultStep == false && !DisableNextButton && !(ActiveIndex == Steps.Count - 1 && HasResultStep() == false && IsAllStepsCompleted()))
146-
{
147-
if (ActiveIndex < Steps.Count && Steps[ActiveIndex].Status != StepStatus.Continued)
148-
{
149-
if (IconActionButtons || MobileView)
150-
{
151-
<MudTooltip Text="@GetNextButtonString()" Delay="300">
152-
<MudIconButton Color="@Color" Variant="@Variant" Icon="@Icons.Material.Filled.ChevronRight" OnClick="@(() => SetActiveIndex(1))" />
153-
</MudTooltip>
154169
}
155170
else
156171
{
157-
<MudButton Color="@Color" Variant="@Variant" OnClick="@(() => SetActiveIndex(1))">@GetNextButtonString()</MudButton>
158-
}
159-
}
160-
else
161-
{
162-
if (IconActionButtons || MobileView)
163-
{
164-
<MudTooltip Text="@GetNextButtonString()" Delay="300">
165-
<MudIconButton Color="@Color" Variant="@Variant" Icon="@Icons.Material.Filled.ChevronRight" OnClick="@(() => CompleteStep(ActiveIndex))" />
166-
</MudTooltip>
167-
}
168-
else
169-
{
170-
<MudButton Color="@Color" Variant="@Variant" OnClick="@(() => CompleteStep(ActiveIndex))">@GetNextButtonString()</MudButton>
171-
}
172+
if (IconActionButtons || MobileView)
173+
{
174+
<MudTooltip Text="@GetNextButtonString()" Delay="300">
175+
<MudIconButton Color="@Color" Variant="@Variant" Icon="@Icons.Material.Filled.ChevronRight" OnClick="@(() => CompleteStep(ActiveIndex))" />
176+
</MudTooltip>
177+
}
178+
else
179+
{
180+
<MudButton Color="@Color" Variant="@Variant" OnClick="@(() => CompleteStep(ActiveIndex))">@GetNextButtonString()</MudButton>
181+
}
172182

183+
}
173184
}
174-
}
175-
176-
</div>
185+
</div>
186+
}
177187
</MudStack>
178188
</MudStack>
179189
</CascadingValue>

CodeBeam.MudBlazor.Extensions/Components/Stepper/MudStepper.razor.cs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ public partial class MudStepper : MudComponentBase
2323
.AddClass(ContentClass)
2424
.Build();
2525

26+
protected string ActionClassname => new CssBuilder("d-flex gap-4")
27+
.AddClass(ActionClass)
28+
.Build();
29+
2630
protected string AvatarStylename => new StyleBuilder()
2731
.AddStyle("z-index: 20")
2832
.AddStyle("background-color", "var(--mud-palette-background)", Variant == Variant.Outlined)
@@ -127,6 +131,18 @@ internal int ActiveIndex
127131
[Parameter]
128132
public string ContentStyle { get; set; }
129133

134+
/// <summary>
135+
/// Provides CSS classes for the step actions.
136+
/// </summary>
137+
[Parameter]
138+
public string ActionClass { get; set; }
139+
140+
/// <summary>
141+
/// Determines how action buttons justified.
142+
/// </summary>
143+
[Parameter]
144+
public StepperActionsJustify StepperActionsJustify { get; set; }
145+
130146
/// <summary>
131147
/// If true, the header can not be clickable and users can step one by one.
132148
/// </summary>
@@ -289,11 +305,17 @@ internal void AddStep(MudStep step)
289305
if (!step.IsResultStep)
290306
{
291307
Steps.Add(step);
308+
ReorderSteps();
292309
}
293310

294311
StateHasChanged();
295312
}
296313

314+
public void ReorderSteps()
315+
{
316+
Steps = Steps.OrderBy(x => x.Order).ToList();
317+
}
318+
297319
internal void RemoveStep(MudStep step)
298320
{
299321
Steps.Remove(step);
@@ -512,5 +534,15 @@ public void Reset()
512534
ActiveIndex = 0;
513535
}
514536

537+
public void SetStepStatus(int index, StepStatus status)
538+
{
539+
Steps[index].SetStatus(status);
540+
}
541+
542+
public void ForceRender()
543+
{
544+
StateHasChanged();
545+
}
546+
515547
}
516548
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.ComponentModel;
2+
3+
namespace MudExtensions.Enums
4+
{
5+
public enum StepperActionsJustify
6+
{
7+
[Description("space-between")]
8+
SpaceBetween,
9+
[Description("end")]
10+
End,
11+
[Description("start")]
12+
Start,
13+
}
14+
}

ComponentViewer.Docs/Pages/Components/StepperPage.razor

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,8 @@
55
<ExampleCard ExampleName="StepperExample1" Title="Playground" Description="Place MudSteps in the MudStepper.">
66
<StepperExample1 />
77
</ExampleCard>
8+
9+
<ExampleCard ExampleName="StepperExample2" Title="Order" Description="You can set each step's order dynamically.">
10+
<StepperExample2 />
11+
</ExampleCard>
812
</ExamplePage>

ComponentViewer.Docs/Pages/Examples/StepperExample1.razor

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@
99
DisableAnimation="_disableAnimation" DisablePreviousButton="_disablePreviousButton" DisableNextButton="_disableNextButton"
1010
DisableSkipButton="_disableSkipButton" DisableStepResultIndicator="_disableStepResultIndicator" HeaderBadgeView="_headerBadgeView"
1111
HeaderTextView="_headerTextView" PreventStepChangeAsync="new Func<StepChangeDirection, int, Task<bool>>(CheckChange)" LocalizedStrings="GetLocalizedStrings()"
12-
MobileView="_mobileView" IconActionButtons="_iconActionButtons" Loading="_loading" HeaderSize="_headerSize" HeaderIcon="false">
12+
MobileView="_mobileView" IconActionButtons="_iconActionButtons" Loading="_loading" HeaderSize="_headerSize" HeaderIcon="false"
13+
StepperActionsJustify="_stepperActionsJustify">
1314
<StaticContent>
1415
@if (_showStaticContent)
1516
{
@@ -69,28 +70,28 @@
6970
{
7071
<MudButton Color="Color.Secondary" Variant="_variant" OnClick="@(() => Snackbar.Add("Custom cancel button clicked.", Severity.Info))">Cancel</MudButton>
7172
}
72-
<MudSpacer />
73+
@* <MudSpacer /> *@
7374
</ActionContent>
7475
</MudStepper>
7576
</MudItem>
7677

7778
<MudItem xs="12" sm="4" Style="box-shadow: rgba(240, 46, 170, 0.4) -3px 3px;">
7879
<MudStack Spacing="4">
7980
<MudNumericField @bind-Value="_activeIndex" Label="Change ActiveIndex" @bind-Value:after="(() => _stepper.SetActiveStepByIndex(_activeIndex))" Variant="Variant.Outlined" Margin="Margin.Dense" />
80-
<MudCheckBox @bind-Checked="_vertical" Color="Color.Secondary" Label="Vertical" Dense="true" />
81-
<MudCheckBox @bind-Checked="_linear" Color="Color.Secondary" Label="Linear" Dense="true" />
82-
<MudCheckBox @bind-Checked="_disableAnimation" Color="Color.Secondary" Label="Disable Animation" Dense="true" />
83-
<MudCheckBox @bind-Checked="_disablePreviousButton" Color="Color.Secondary" Label="Disable Previous Step Action Button" Dense="true" />
84-
<MudCheckBox @bind-Checked="_disableNextButton" Color="Color.Secondary" Label="Disable Next Step Action Button" Dense="true" />
85-
<MudCheckBox @bind-Checked="_disableSkipButton" Color="Color.Secondary" Label="Disable Skip Step Action Button" Dense="true" />
86-
<MudCheckBox @bind-Checked="_disableStepResultIndicator" Color="Color.Secondary" Label="Disable Step Result Indicator" Dense="true" />
87-
<MudSwitchM3 @bind-Checked="_mobileView" Color="Color.Secondary" Label="Mobile View" />
88-
<MudSwitchM3 @bind-Checked="_iconActionButtons" Color="Color.Secondary" Label="IconActionButtons" />
89-
<MudSwitchM3 @bind-Checked="_addResultStep" Color="Color.Secondary" Label="Has Result Step" />
90-
<MudSwitchM3 @bind-Checked="_checkValidationBeforeComplete" Color="Color.Secondary" Label="Check Validation Before Complete Step" />
91-
<MudSwitchM3 @bind-Checked="_customLocalization" Color="Color.Secondary" Label="Custom Localization (German)" />
92-
<MudSwitchM3 @bind-Checked="_showStaticContent" Color="Color.Secondary" Label="Show Some Static Content" />
93-
<MudSwitchM3 @bind-Checked="_showCustomButton" Color="Color.Secondary" Label="Show Custom Button" />
81+
<MudCheckBox @bind-Value="_vertical" Color="Color.Secondary" Label="Vertical" Dense="true" />
82+
<MudCheckBox @bind-Value="_linear" Color="Color.Secondary" Label="Linear" Dense="true" />
83+
<MudCheckBox @bind-Value="_disableAnimation" Color="Color.Secondary" Label="Disable Animation" Dense="true" />
84+
<MudCheckBox @bind-Value="_disablePreviousButton" Color="Color.Secondary" Label="Disable Previous Step Action Button" Dense="true" />
85+
<MudCheckBox @bind-Value="_disableNextButton" Color="Color.Secondary" Label="Disable Next Step Action Button" Dense="true" />
86+
<MudCheckBox @bind-Value="_disableSkipButton" Color="Color.Secondary" Label="Disable Skip Step Action Button" Dense="true" />
87+
<MudCheckBox @bind-Value="_disableStepResultIndicator" Color="Color.Secondary" Label="Disable Step Result Indicator" Dense="true" />
88+
<MudSwitchM3 @bind-Value="_mobileView" Color="Color.Secondary" Label="Mobile View" />
89+
<MudSwitchM3 @bind-Value="_iconActionButtons" Color="Color.Secondary" Label="IconActionButtons" />
90+
<MudSwitchM3 @bind-Value="_addResultStep" Color="Color.Secondary" Label="Has Result Step" />
91+
<MudSwitchM3 @bind-Value="_checkValidationBeforeComplete" Color="Color.Secondary" Label="Check Validation Before Complete Step" />
92+
<MudSwitchM3 @bind-Value="_customLocalization" Color="Color.Secondary" Label="Custom Localization (German)" />
93+
<MudSwitchM3 @bind-Value="_showStaticContent" Color="Color.Secondary" Label="Show Some Static Content" />
94+
<MudSwitchM3 @bind-Value="_showCustomButton" Color="Color.Secondary" Label="Show Custom Button" />
9495
<MudSelect @bind-Value="_variant" Variant="Variant.Outlined" Label="Variant" Margin="Margin.Dense" Dense="true">
9596
@foreach (Variant item in Enum.GetValues<Variant>())
9697
{
@@ -115,6 +116,12 @@
115116
<MudSelectItem Value="item">@item.ToDescriptionString()</MudSelectItem>
116117
}
117118
</MudSelect>
119+
<MudSelect @bind-Value="_stepperActionsJustify" Variant="Variant.Outlined" Label="Action Buttons Justify" Margin="Margin.Dense" Dense="true">
120+
@foreach (StepperActionsJustify item in Enum.GetValues<StepperActionsJustify>())
121+
{
122+
<MudSelectItem Value="item">@item.ToDescriptionString()</MudSelectItem>
123+
}
124+
</MudSelect>
118125
<MudSelectExtended @bind-Value="_headerSize" ItemCollection="@(Enum.GetValues<Size>())" Variant="Variant.Outlined" Label="Header Size" Margin="Margin.Dense" Dense="true" />
119126
<MudButton Variant="Variant.Filled" Color="Color.Primary" OnClick="(() => _stepper.Reset())">Reset</MudButton>
120127
</MudStack>
@@ -146,6 +153,7 @@
146153
bool _showCustomButton = false;
147154
bool _vertical = false;
148155
Size _headerSize = Size.Medium;
156+
StepperActionsJustify _stepperActionsJustify = StepperActionsJustify.SpaceBetween;
149157

150158
private async Task<bool> CheckChange(StepChangeDirection direction, int targetIndex)
151159
{

0 commit comments

Comments
 (0)