main
Peace 9 months ago
parent 744ce10816
commit 0404959bf1
  1. 1
      BlazorFluentUI/Components/Layout/NavMenu.razor
  2. 156
      BlazorFluentUI/Components/Pages/Components/CompoDialog.razor
  3. 41
      BlazorFluentUI/Components/Pages/Components/Dialogs/SimpleCustimizedDialog.razor
  4. 43
      BlazorFluentUI/Components/Pages/Components/Dialogs/SimpleDiaolg.razor
  5. 58
      BlazorFluentUI/Components/Pages/Components/Dialogs/SimpleEditDialog.razor

@ -58,6 +58,7 @@
</FluentNavGroup>
<FluentNavLink Href="compocard" Icon="@(new Icons.Regular.Size20.CardUi())" IconColor="Color.Accent">Card</FluentNavLink>
<FluentNavLink Href="compodatagrid" Icon="@(new Icons.Regular.Size20.Grid())" IconColor="Color.Accent">DataGrid</FluentNavLink>
<FluentNavLink Href="compodialog" Icon="@(new Icons.Regular.Size20.AppTitle())" IconColor="Color.Accent">Dialog</FluentNavLink>
</FluentNavGroup>
</FluentNavMenu>

@ -0,0 +1,156 @@
@page "/compodialog"
@using BlazorFluentUI.Components.Pages.Components.Dialogs
@using System.ComponentModel.DataAnnotations
@inject EmployeeService EmployeeService;
@inject IDialogService DialogService;
@rendermode RenderMode.InteractiveServer
<h3>Dialog</h3>
<FluentDivider class="mt-1 mb-3" Role="DividerRole.Separator" />
<div>
The <code>FluentDialog</code> wraps a web component <code>dialog</code>.
</div>
<h4 class="mt-3">DialogService</h4>
<div>
The <code>DialogService</code> is a service which is used to show different type of dialogs.
It is registered as a scpoed service, so it can be injected into pages/components that use it.
</div>
<h4 class="mt-4">DialogService with IDialogReference</h4>
<FluentCard Class="mt-3" Width="auto" Height="auto" AreaRestricted="false">
<div>
<p>
When <FluentBadge Appearance="Appearance.Accent">Modal</FluentBadge> is checked, the dialog can be dissmissed by clicking outside of the dialog.
When unchecked, the dialog can be dissmissed only by the <span class="fluent-border-s1-r5 px-1">Esc</span> key.
The dialog can always be closed by using the <FluentBadge Appearance="Appearance.Accent">Close dialog (X)</FluentBadge> button.
</p>
<p>
When <FluentBadge Appearance="Appearance.Accent">Trap focus</FluentBadge> is checked, only the elements within the dialog will receive focus (by using <span class="fluent-border-s1-r5 px-1">tab</span> key).
When unchecked, focus will also move outside of the dialog.
</p>
</div>
<div>
<FluentCheckbox @bind-Value="modal">Modal</FluentCheckbox>
<FluentCheckbox @bind-Value="trapFocus">Trap Focus</FluentCheckbox>
</div>
<div class="mt-2">
<FluentButton Appearance="@Appearance.Accent" OnClick="@OpenDialogAsync">Open Dialog</FluentButton>
</div>
<p><b>Message</b>: @message</p>
</FluentCard>
<h4 class ="mt-4">Customized Dialog</h4>
<FluentCard Class="mt-3" Width="auto" Height="auto" AreaRestricted="false">
<FluentButton Appearance="Appearance.Accent" OnClick="@OpenCustomizedDialogAsync">Open Dialog</FluentButton>
<p><b>Message</b>: @customizedMessage</p>
</FluentCard>
<h4 class ="mt-4">Editable Dialog</h4>
<FluentCard Class="mt-3" Width="auto" Height="auto" AreaRestricted="false">
<FluentButton Appearance="Appearance.Accent" OnClick="@OpenEditDialogAsync">Open Dialog</FluentButton>
<p><b>Message</b>: @editMessage</p>
</FluentCard>
@code {
readonly int SIZE = 10;
bool modal = true;
bool trapFocus = true;
List<Employee>? employees;
protected override async Task OnInitializedAsync()
{
employees = await EmployeeService.GetEmployeeDataAsync(SIZE);
}
string message;
private async Task OpenDialogAsync()
{
int index = Random.Shared.Next(0, SIZE);
Employee employee = employees[index];
DialogParameters parameters = new DialogParameters
{
Title = $"Hello {employee.FirstName}",
PrimaryAction = "Yes",
PrimaryActionEnabled = false,
SecondaryAction = "No",
Width = "500px",
TrapFocus = trapFocus,
Modal = modal,
PreventScroll = true
};
IDialogReference dialog = await DialogService.ShowDialogAsync<SimpleDiaolg>(employee, parameters);
DialogResult? result = await dialog.Result;
if (result.Data is not null)
{
Employee? tmp = result.Data as Employee;
if (tmp is not null)
message = $"[Dialog closed] FirstName: {tmp.FirstName}, LastName: {tmp.LastName}, BirthDate: {tmp.BirthDate}";
}
else
{
message = $"[Dialog closed] Canceled: {result.Cancelled}";
}
}
public record NameAndAge
{
public int Id { get; set; }
[MinLength(3)]
[MaxLength(20)]
public string? Name { get; set; }
[Range(1, 150)]
public int Age { get; set; }
}
NameAndAge customizedData = new NameAndAge { Id = 1, Name = "Taylor", Age = 25 };
string? customizedMessage;
async Task OpenCustomizedDialogAsync()
{
var data = customizedData with { Id = 1 };
var dialog = await DialogService.ShowDialogAsync<SimpleCustimizedDialog>(data, new DialogParameters
{
Height = "240px",
Title = $"Updating the {data.Name}'s data",
PreventDismissOnOverlayClick = true,
PreventScroll = true
});
var result = await dialog.Result;
if (!result.Cancelled && result.Data != null)
{
customizedData = result.Data as NameAndAge;
customizedMessage = $"Name: {customizedData.Name}, Age: {customizedData.Age}";
}
}
NameAndAge editData = new NameAndAge { Id = 1, Name = "Taylor", Age = 25 };
string? editMessage;
async Task OpenEditDialogAsync()
{
var data = editData with { Id = 0 };
var dialog = await DialogService.ShowDialogAsync<SimpleEditDialog>(data, new DialogParameters
{
Height = "400px",
Title = $"Updating the {data.Name}'s data",
PreventDismissOnOverlayClick = true,
PreventScroll = true
});
var result = await dialog.Result;
if (!result.Cancelled && result.Data != null)
{
editData = result.Data as NameAndAge;
editMessage = $"Name: {editData.Name}, Age: {editData.Age}";
}
}
}

@ -0,0 +1,41 @@
@implements IDialogContentComponent<CompoDialog.NameAndAge>
@* Header *@
<FluentDialogHeader ShowDismiss="true">
<FluentStack VerticalAlignment="VerticalAlignment.Center">
<FluentIcon Value="@(new Icons.Regular.Size24.PersonNote())"/>
<FluentLabel Typo="Typography.PaneHeader">
@Dialog.Instance.Parameters.Title
</FluentLabel>
</FluentStack>
</FluentDialogHeader>
@* Body *@
<FluentDialogBody>
<FluentTextField @bind-Value="Content.Name">Name:</FluentTextField>
<FluentNumberField @bind-Value="Content.Age">Age:</FluentNumberField>
</FluentDialogBody>
@* Footer *@
<FluentDialogFooter>
<FluentButton Appearance="Appearance.Accent" OnClick="@SaveAsync">Save</FluentButton>
<FluentButton Appearance="Appearance.Neutral" OnClick="@CancelAsync">Cancel</FluentButton>
</FluentDialogFooter>
@code {
[Parameter]
public CompoDialog.NameAndAge Content { get; set; } = default!;
[CascadingParameter]
public FluentDialog Dialog { get; set; } = default!;
private async Task SaveAsync()
{
await Dialog.CloseAsync(Content);
}
private async Task CancelAsync()
{
await Dialog.CancelAsync();
}
}

@ -0,0 +1,43 @@
@implements IDialogContentComponent<Employee>
<FluentMessageBarProvider Section="This is Section" MaxMessageCount="1"/>
<p>@($"{Content.FirstName}, {Content.LastName}") is @(Content.Job).</p>
<FluentTextField @bind-Value="Content.FirstName">First name: </FluentTextField>
<FluentTextField @bind-Value="Content.LastName">Last name: </FluentTextField>
<FluentDatePicker @bind-Value="BirthDate">Birth date: </FluentDatePicker>
@if (Dialog != null)
{
<FluentStack Class="fluent-border-d1 p-2" Orientation="Orientation.Vertical">
<span>This section is visible only when component is hosted inside a Dialog.</span>
<FluentButton OnClick="@(() => ToggleDialogPrimaryActionButton(true))">Enable Dialog Primary Action.</FluentButton>
<FluentButton OnClick="@(() => ToggleDialogPrimaryActionButton(false))">Disable Dialog Primary Action.</FluentButton>
</FluentStack>
}
@code {
[Parameter]
public Employee Content { get; set; } = default!;
DateTime? BirthDate
{
get
{
return Content.BirthDate as DateTime?;
}
set
{
Content.BirthDate = value == null ? DateTime.Now : value.Value;
}
}
[CascadingParameter]
public FluentDialog? Dialog { get; set; }
void ToggleDialogPrimaryActionButton(bool enable)
{
Dialog!.TogglePrimaryActionButton(enable);
}
}

@ -0,0 +1,58 @@
@implements IDialogContentComponent<CompoDialog.NameAndAge>
@* Header *@
<FluentDialogHeader ShowDismiss="true">
<FluentStack VerticalAlignment="VerticalAlignment.Center">
<FluentIcon Value="@(new Icons.Regular.Size24.PersonNote())"/>
<FluentLabel Typo="Typography.PaneHeader">
@Dialog.Instance.Parameters.Title
</FluentLabel>
</FluentStack>
</FluentDialogHeader>
@* Body *@
<FluentDialogBody>
<EditForm EditContext="@editContext">
<DataAnnotationsValidator/>
<FluentLabel Class="mb-3">
Name must be between 3 and 20 characters long,
and your age between 1 and 150.
</FluentLabel>
<FluentTextField @bind-Value="Content.Name" Label="Name" Required/>
<FluentNumberField @bind-Value="Content.Age" Label="Age" Required/>
<div style="color: var(--error)">
<FluentValidationSummary/>
</div>
</EditForm>
</FluentDialogBody>
@* Footer *@
<FluentDialogFooter>
<FluentButton Appearance="Appearance.Accent" OnClick="@SaveAsync" Disabled="@(!editContext.Validate())">Save</FluentButton>
<FluentButton Appearance="Appearance.Neutral" OnClick="@CancelAsync">Cancel</FluentButton>
</FluentDialogFooter>
@code {
EditContext editContext = default!;
[Parameter]
public CompoDialog.NameAndAge Content { get; set; } = default!;
[CascadingParameter]
public FluentDialog Dialog { get; set; } = default!;
protected override void OnInitialized()
{
editContext = new EditContext(Content);
}
private async Task SaveAsync()
{
await Dialog.CloseAsync(Content);
}
private async Task CancelAsync()
{
await Dialog.CancelAsync();
}
}
Loading…
Cancel
Save