Fluent UI Blazorに新しく追加されたWizardのボタンカスタマイズについて
始めに
Fluent UI BlazorにWizardのコンポーネントが新たに追加されました。
デフォルトではウィザードを進めるボタンのラベルが英語表記になっています。日本人としては是非とも日本語にして使用していきたいところです。
また、デフォルトではアクセントカラーのボタンが右側に配置されています。これについてもそれなりに理由あってのことですがどうしても統一したいという考えもあるかと思いますのでこの方法についても解説していきます。
ウィザードを表示させる
まず、単純に3ステップのウィザードを作成しすべての工程が完了したところでダイアログを表示するように作っておきます。
@inject IDialogService DialogService
<FluentWizard OnFinish="WizardFinish">
<Steps>
<FluentWizardStep Label="Step1">
何かの処理その1
</FluentWizardStep>
<FluentWizardStep Label="Step2">
何かの処理その2
</FluentWizardStep>
<FluentWizardStep Label="Step3">
何かの処理その3
</FluentWizardStep>
</Steps>
</FluentWizard>
@code {
private async Task WizardFinish()
{
var dialog = await DialogService.ShowMessageBoxAsync(new DialogParameters<MessageBoxContent>()
{
Content = new()
{
Title = "ウィザード完了!"
}
});
}
}
実行結果は以下のようになります。
まあ、ボタンのラベル読めなくはないですがこのまま実環境で使ったら各方面からいろいろ言われることは間違いなさそうです。
ここは、日本であるので日本語でOKと。
ボタンを日本語化する
このボタンのラベルは静的フィールドで宣言されています。
ウィザードが使われるところが1カ所ならそこで初期化してあげれば良さそうですがまあ通常はどこで使われるか分からないのでエントリーポイントのあたりでこのフィールドを書き換えてあげれば良さそうです。
というわけで、Program.csでフィールドを書き換えてあげることにしました。
(public staticなフィールドがいいのかどうかはさておき)
...
builder.Services.AddFluentUIComponents();
FluentWizard.LabelButtonDone = "完了";
FluentWizard.LabelButtonNext = "次へ";
FluentWizard.LabelButtonPrevious = "前へ";
...
まあ、FluentUI関係ということでFluentUIのサービスを汎用ホストにサービス追加したあたりで入れておくのがよいのかと思います。
そうした結果、ボタンのラベルは指定したとおり日本語化されているようです。
めでたしめでたし。
ボタンの配置をカスタマイズする
ボタンの配置をどうしても入れ替えたいという欲求もあると思います。
このようなときは、ButtonTemplateを使用します。
工夫すべき点として、初期状態の時は「前へ」ボタンは本質的に不要ですが単純に取り払ってしまうと次へボタンの位置がずれてしまってユーザービリティが落ちてしまうので無効化しておくなどしておくとよいでしょう。
ButtonTemplateを使用すると以下のようになります。
@inject IDialogService DialogService
<FluentWizard @bind-Value="@Value" @ref="@fluentWizard">
<Steps>
<FluentWizardStep Label="Step1">
何かの処理その1
</FluentWizardStep>
<FluentWizardStep Label="Step2">
何かの処理その2
</FluentWizardStep>
<FluentWizardStep Label="Step3">
何かの処理その3
</FluentWizardStep>
</Steps>
<ButtonTemplate>
@{
var index = context;
var lastStepIndex = 2;
<FluentStack Orientation="Orientation.Horizontal" HorizontalAlignment="HorizontalAlignment.Right" HorizontalGap="10">
@if (index < lastStepIndex)
{
<FluentButton Style="width:80px" OnClick="@(() => Value += 1)" Appearance="Appearance.Accent">次へ</FluentButton>
}
@if (index == lastStepIndex)
{
<FluentButton Style="width:80px" OnClick="@(() => WizardFinish())" Appearance="Appearance.Accent">完了!</FluentButton>
}
@if (index > 0)
{
<FluentButton Style="width:80px" OnClick="@(() => Value -= 1)">前へ</FluentButton>
}
else
{
<FluentButton Style="width:80px" OnClick="@(() => Value -= 1)" Disabled>前へ</FluentButton>
}
</FluentStack>
}
</ButtonTemplate>
</FluentWizard>
@code {
int Value = 0;
FluentWizard fluentWizard = default!;
private async Task WizardFinish()
{
var dialog = await DialogService.ShowMessageBoxAsync(new DialogParameters<MessageBoxContent>()
{
Content = new()
{
Title = "ウィザード完了!"
}
});
}
}
実行結果は以下の通りになります。
良さそうですね。
ボタンの配置はどちらの考え方を優先するかによるかと思いますのでいずれでもよき方で実装するとよいかと思います。
ただし、ButtonTemplateを使うとOnChangeイベントとOnFinishイベントがトリガーされないのでそこは注意が必要です。
今回使用したソース
デモサイト
参考
Discussion