Skip to content
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

Dialog enhancements #717

Merged
merged 2 commits into from
Sep 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
74 changes: 73 additions & 1 deletion examples/Demo/Shared/Microsoft.Fast.Components.FluentUI.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

54 changes: 54 additions & 0 deletions examples/Demo/Shared/Pages/Dialog/DialogPage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -118,3 +118,57 @@

<ApiDocumentation Component="typeof(DialogParameters<>)" GenericLabel="TData" />

<h3>Dialog header and footer</h3>
<p>The dialog header and footer can be changed by using the <code>FluentDialog</code>'s <code>HeaderTemplate</code> and <code>FooterTemplate</code> parameters.</p>
<p>
The default implementation uses the <code>FluentDialogHeader</code> and <code>FluentDialogFooter</code> components (see documentation below).
You can use the content of these components as the base for your own implementation:
</p>

<h4>Default dialog header</h4>
<CodeSnippet>
&lt;div class=&quot;fluent-dialog-header&quot;&gt;
&lt;FluentStack Orientation=&quot;Orientation.Horizontal&quot; VerticalAlignment=&quot;VerticalAlignment.Center&quot;&gt;
&lt;FluentLabel Typo=&quot;Typography.PaneHeader&quot; Style=&quot;width: 100%; margin: 0px;&quot;&gt;@@Title&lt;/FluentLabel&gt;
@@if (ShowDismiss)
{
&lt;FluentButton Appearance = &quot; Appearance.Stealth &quot;
@@onclick= &quot;@@(() = &gt; Dialog!.CancelAsync())&quot; &gt;
&lt;FluentIcon Icon = &quot; CoreIcons.Regular.Size24.Dismiss & quot; Width = &quot; 16px & quot; / &gt;
&lt;/FluentButton &gt;
}
&lt;/FluentStack&gt;
&lt;/div&gt;
</CodeSnippet>

<h4>Default dialog footer</h4>
<CodeSnippet>
&lt;div class=&quot;@@(Alignment == HorizontalAlignment.Center ? &quot;fluent-dialog-footer-normal&quot; : &quot;fluent-dialog-footer-bottom&quot;)&quot;&gt;
&lt;FluentStack Orientation=&quot;Orientation.Horizontal&quot;
HorizontalAlignment=&quot;@@(Alignment == HorizontalAlignment.Center ? HorizontalAlignment.Right : HorizontalAlignment.Left)&quot;&gt;
@@if (ShowPrimaryAction)
{
&lt;FluentButton title=&quot;@@PrimaryAction&quot;
@@onclick=&quot;@@OnPrimaryActionButtonClickAsync&quot;
Appearance=&quot;Appearance.Accent&quot;
Disabled=&quot;@@(!PrimaryActionEnabled)&quot;&gt;
@@PrimaryAction
&lt;/FluentButton&gt;
}
@@if (ShowSecondaryAction)
{
&lt;FluentButton title=&quot;@@SecondaryAction&quot;
@@onclick=&quot;@@OnSecondaryActionButtonClickAsync&quot;
Appearance=&quot;Appearance.Neutral&quot;
Disabled=&quot;@@(!SecondaryActionEnabled)&quot;&gt;
@@SecondaryAction
&lt;/FluentButton&gt;
}
&lt;/FluentStack&gt;
&lt;/div&gt;
</CodeSnippet>

<ApiDocumentation Component="typeof(FluentDialogHeader)" />

<ApiDocumentation Component="typeof(FluentDialogFooter)" />

14 changes: 9 additions & 5 deletions examples/Demo/Shared/Pages/Dialog/Examples/DialogDefault.razor
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,22 @@
When 'Trap focus' is checked, only the elements within the dialog will receive focus. When unchecked, focus will also move outside of the
dialog.
</p>
<p>
Hidden is bound to dialog visibility. You can show/hide dialog by changing this property or calling <code>Show()</code> / <code>Hide()</code>
on component reference.
</p>
<FluentCheckbox Name="modal" @bind-Value="_modal">
Modal
</FluentCheckbox>
<FluentCheckbox Name="trap" @bind-Value="_trapFocus">
Trap focus
</FluentCheckbox>
<FluentCheckbox Name="hidden" @bind-Value="Hidden" Readonly="true">
Hidden
</FluentCheckbox>
</div>
<div>
<FluentDialog @ref="_myFluentDialog" Hidden="@_hidden" aria-label="Simple dialog" Modal=@_modal TrapFocus=@_trapFocus @ondialogdismiss=OnDismiss>
<FluentDialog @ref="_myFluentDialog" @bind-Hidden="@Hidden" aria-label="Simple dialog" Modal=@_modal TrapFocus=@_trapFocus @ondialogdismiss=OnDismiss>
<h2>Just a simple dialog</h2>
<p>The 'Close dialog' button is automatically focused.</p>
<p>The 'Another button' doesn't do anything other than showing it can receive focus.</p>
Expand All @@ -35,7 +42,7 @@
private bool _trapFocus = true;
private bool _modal = true;
private string? _status;
private bool _hidden = true;
private bool Hidden { get; set; } = true;

protected override void OnAfterRender(bool firstRender)
{
Expand All @@ -46,7 +53,6 @@
private void OnOpen()
{
_status = "Dialog opened with button click";
_hidden = false;
_myFluentDialog!.Show();
DemoLogger.WriteLine(_status);
}
Expand All @@ -55,7 +61,6 @@
{
_status = $"Dialog dismissed with reason: Close button clicked";
_myFluentDialog!.Hide();
_hidden = true;
DemoLogger.WriteLine(_status);
}

Expand All @@ -64,7 +69,6 @@
if (args is not null && args.Reason is not null && args.Reason == "dismiss")
{
_status = $"Dialog dismissed with reason: Dismissed";
_hidden = true;
_myFluentDialog!.Hide();
DemoLogger.WriteLine(_status);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,9 @@
DialogParameters<SimplePerson> parameters = new()
{
Title = $"Hello {simplePerson.Firstname}",
PrimaryAction = "Yes",
PrimaryAction = "",
PrimaryActionEnabled = false,
SecondaryAction = "No",
SecondaryAction = "",
Width = "500px",
Height = "500px",
Content = simplePerson,
Expand Down
2 changes: 1 addition & 1 deletion examples/Demo/Shared/Pages/DialogServicePage.razor
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@


<p>
See the following pages for examples on how to use the DialogService with thedifferent types of dialogs.
See the following pages for examples on how to use the DialogService with the different types of dialogs.
<ul>
<li><a href="/Dialog">Regular dialogs</a></li>
<li><a href="/MessageBox">Message boxes</a></li>
Expand Down
58 changes: 19 additions & 39 deletions src/Core/Components/Dialog/FluentDialog.razor
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
@inherits FluentComponentBase

<CascadingValue Value="this" IsFixed="true">
<fluent-dialog @ref=Element
<fluent-dialog @ref="Element"
id="@Id"
class="@ClassValue"
style="@StyleValue"
Expand All @@ -14,22 +14,16 @@
aria-label=@(_parameters.AriaLabel ?? AriaLabel)
@attributes=@AdditionalAttributes>
<FluentStack Orientation="Orientation.Vertical" Class="fluent-dialog-content" Style="height:100%;">
@if (_parameters.ShowTitle && (_parameters.Title != null || _parameters.ShowDismiss))
@if (HeaderTemplate is not null)
{
<div class="fluent-dialog-header">
<FluentStack Orientation="Orientation.Horizontal" VerticalAlignment="VerticalAlignment.Center">
<FluentLabel Typo="Typography.PaneHeader" Style="width: 100%; margin: 0px;">@_parameters.Title</FluentLabel>
@if (_parameters.ShowDismiss)
{
<FluentButton Appearance="Appearance.Stealth" @onclick="@(() => CancelAsync())">
<FluentIcon Icon="CoreIcons.Regular.Size24.Dismiss" Width="16px" />
</FluentButton>
}
</FluentStack>
</div>
@HeaderTemplate
}
else if (_parameters.ShowTitle && (_parameters.Title != null || _parameters.ShowDismiss))
{
<FluentDialogHeader Title="@_parameters.Title" ShowDismiss="@_parameters.ShowDismiss" />
}

<div class="fluent-dialog-body" nofooter=@(!HasButtons) style="@(_parameters.DialogBodyStyle ?? null)">
<div class="fluent-dialog-body" nofooter="@(!HasButtons)" style="@(_parameters.DialogBodyStyle ?? null)">
@if (Instance is null)
{
@ChildContent
Expand All @@ -39,32 +33,18 @@
<DynamicComponent Type="@Instance.ContentType" Parameters="Instance.GetParameterDictionary()" />
}
</div>

@if (HasButtons)
@if (FooterTemplate is not null)
{
@FooterTemplate
}
else if (HasButtons)
{
<div class="@(_parameters.Alignment == HorizontalAlignment.Center ? "fluent-dialog-footer-normal" : "fluent-dialog-footer-bottom")">
<FluentStack Orientation="Orientation.Horizontal"
HorizontalAlignment="@(_parameters.Alignment == HorizontalAlignment.Center ? HorizontalAlignment.Right : HorizontalAlignment.Left)">
@if (_parameters.ShowPrimaryAction)
{
<FluentButton title="@_parameters.PrimaryAction"
@onclick="@(() => CloseAsync<object?>(Instance!.Content ??= true))"
Appearance="Appearance.Accent"
Disabled="@(!_parameters.PrimaryActionEnabled)">
@_parameters.PrimaryAction
</FluentButton>
}
@if (_parameters.ShowSecondaryAction)
{
<FluentButton title="@_parameters.SecondaryAction"
@onclick="@(() => CancelAsync<object?>(Instance!.Content ??= false))"
Appearance="Appearance.Neutral"
Disabled="@(!_parameters.SecondaryActionEnabled)">
@_parameters.SecondaryAction
</FluentButton>
}
</FluentStack>
</div>
<FluentDialogFooter Alignment="@_parameters.Alignment"
PrimaryAction="@_parameters.PrimaryAction"
PrimaryActionEnabled="@_parameters.PrimaryActionEnabled"
SecondaryAction="@_parameters.SecondaryAction"
SecondaryActionEnabled="@_parameters.SecondaryActionEnabled"/>

}
</FluentStack>
</fluent-dialog>
Expand Down
45 changes: 40 additions & 5 deletions src/Core/Components/Dialog/FluentDialog.razor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ public partial class FluentDialog : FluentComponentBase //, IDisposable
private const string DEFAULT_WIDTH = "500px";
private const string DEFAULT_HEIGHT = "unset";
private DialogParameters _parameters = default!;
private bool _hidden;

[CascadingParameter]
private InternalDialogContext? DialogContext { get; set; } = default!;
Expand All @@ -24,7 +25,23 @@ public partial class FluentDialog : FluentComponentBase //, IDisposable
/// Gets or sets if the dialog is hidden
/// </summary>
[Parameter]
public bool Hidden { get; set; }
public bool Hidden
{
get => _hidden;
set
{
if (value == _hidden)
return;
_hidden = value;
HiddenChanged.InvokeAsync(value);
}
}

/// <summary>
/// The event callback invoked when <see cref="Hidden"/> change.
/// </summary>
[Parameter]
public EventCallback<bool> HiddenChanged { get; set; }

/// <summary>
/// Indicates that the dialog should trap focus.
Expand Down Expand Up @@ -58,11 +75,23 @@ public partial class FluentDialog : FluentComponentBase //, IDisposable


/// <summary>
/// Used when not calling the <see cref="DialogService" /> to show a dialog
/// Used when not calling the <see cref="DialogService" /> to show a dialog.
/// </summary>
[Parameter]
public RenderFragment? ChildContent { get; set; }

/// <summary>
/// Content to render in header.
/// </summary>
[Parameter]
public RenderFragment? HeaderTemplate { get; set; }

/// <summary>
/// Content to render in footer.
/// </summary>
[Parameter]
public RenderFragment? FooterTemplate { get; set; }

/// <summary>
/// The event callback invoked to return the dialog result.
/// </summary>
Expand All @@ -85,7 +114,6 @@ public partial class FluentDialog : FluentComponentBase //, IDisposable
.Build();

[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(DialogEventArgs))]

public FluentDialog()
{

Expand Down Expand Up @@ -159,9 +187,16 @@ public void ToggleSecondaryActionButton(bool isEnabled)
public async Task CloseAsync(DialogResult dialogResult)
{
DialogContext?.DialogContainer.DismissInstance(Id!, dialogResult);
if (Instance.Parameters.OnDialogResult.HasDelegate)
if (Instance is not null)
{
if (Instance.Parameters.OnDialogResult.HasDelegate)
{
await Instance.Parameters.OnDialogResult.InvokeAsync(dialogResult);
}
}
else
{
await Instance.Parameters.OnDialogResult.InvokeAsync(dialogResult);
Hide();
}
}
}