Skip to content

Commit

Permalink
Rework component events (#43)
Browse files Browse the repository at this point in the history
* refactor IComponentEvent.cs and add OnFocus & OnBlur event

* e2e test

* code format

* fixes
  • Loading branch information
DavidVollmers authored Dec 14, 2023
1 parent 1782247 commit 6768fa4
Show file tree
Hide file tree
Showing 19 changed files with 85 additions and 35 deletions.
32 changes: 24 additions & 8 deletions packages/Ignis.Components.Web/FocusComponentBase.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ public abstract class FocusComponentBase : IgnisComponentBase, IFocus, IHandleAf

protected virtual bool FocusOnRender => false;

[Parameter] public EventCallback<IComponentEvent> OnFocus { get; set; }

[Parameter] public EventCallback<IComponentEvent> OnBlur { get; set; }

// ReSharper disable once InconsistentNaming
[Inject] public IJSRuntime JSRuntime { get; set; } = null!;

Expand All @@ -32,14 +36,20 @@ public async Task InvokeFocusAsync()
{
if (_isFocused) return;

var @event = new ComponentEvent();

await OnFocus.InvokeAsync(@event);

if (@event.DefaultPrevented) return;

_isFocused = true;

#pragma warning disable MA0042
// ReSharper disable once MethodHasAsyncOverload
OnFocus();
OnTargetFocus();
#pragma warning restore MA0042

await OnFocusAsync();
await OnTargetFocusAsync();
}

/// <summary>
Expand All @@ -50,14 +60,20 @@ public async Task InvokeBlurAsync()
{
if (!_isFocused) return;

var @event = new ComponentEvent();

await OnBlur.InvokeAsync(@event);

if (@event.DefaultPrevented) return;

_isFocused = false;

#pragma warning disable MA0042
// ReSharper disable once MethodHasAsyncOverload
OnBlur();
OnTargetBlur();
#pragma warning restore MA0042

await OnBlurAsync();
await OnTargetBlurAsync();
}

/// <summary>
Expand Down Expand Up @@ -117,20 +133,20 @@ private IEnumerable<ElementReference> GetElementReferences()
}
}

protected virtual void OnFocus()
protected virtual void OnTargetFocus()
{
}

protected virtual Task OnFocusAsync()
protected virtual Task OnTargetFocusAsync()
{
return Task.CompletedTask;
}

protected virtual void OnBlur()
protected virtual void OnTargetBlur()
{
}

protected virtual Task OnBlurAsync()
protected virtual Task OnTargetBlurAsync()
{
return Task.CompletedTask;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/Ignis.Components/ComponentEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ public class ComponentEvent : IComponentEvent, IDisposable
{
private readonly CancellationTokenSource _cancellationTokenSource = new();

public CancellationToken CancellationToken => this._cancellationTokenSource.Token;
public bool DefaultPrevented => this._cancellationTokenSource.IsCancellationRequested;

public void PreventDefault()
{
Expand Down
2 changes: 2 additions & 0 deletions packages/Ignis.Components/IComponentEvent.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,7 @@

public interface IComponentEvent
{
bool DefaultPrevented { get; }

void PreventDefault();
}
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
}

/// <inheritdoc />
protected override void OnBlur()
protected override void OnTargetBlur()
{
Dialog.Close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ private void Click()

var __ = OnClick.InvokeAsync(@event);

if (@event.CancellationToken.IsCancellationRequested) return;
if (@event.DefaultPrevented) return;

Toggle();
}
Expand Down
2 changes: 1 addition & 1 deletion packages/Tailwind/Ignis.Components.HeadlessUI/Listbox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -219,7 +219,7 @@ protected override IEnumerable<object> Targets
new[] { "Escape", "Space", "Enter", "ArrowUp", "ArrowDown" };

/// <inheritdoc />
protected override void OnBlur()
protected override void OnTargetBlur()
{
Close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private void Click()

var __ = OnClick.InvokeAsync(@event);

if (@event.CancellationToken.IsCancellationRequested) return;
if (@event.DefaultPrevented) return;

if (Listbox.IsOpen) Listbox.Close();
else Listbox.Open();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public void Click()

var __ = OnClick.InvokeAsync(@event);

if (@event.CancellationToken.IsCancellationRequested) return;
if (@event.DefaultPrevented) return;

Listbox.SelectValue(Value);

Expand Down
2 changes: 1 addition & 1 deletion packages/Tailwind/Ignis.Components.HeadlessUI/Menu.cs
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,7 @@ protected override IEnumerable<object> Targets
new[] { "Escape", "Space", "Enter", "ArrowUp", "ArrowDown" };

/// <inheritdoc />
protected override void OnBlur()
protected override void OnTargetBlur()
{
Close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void Click()

var __ = OnClick.InvokeAsync(@event);

if (@event.CancellationToken.IsCancellationRequested) return;
if (@event.DefaultPrevented) return;

if (Menu.IsOpen) Menu.Close();
else Menu.Open();
Expand Down
2 changes: 1 addition & 1 deletion packages/Tailwind/Ignis.Components.HeadlessUI/MenuItem.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ public void Click()

var __ = OnClick.InvokeAsync(@event);

if (@event.CancellationToken.IsCancellationRequested) return;
if (@event.DefaultPrevented) return;

Menu.Close();
}
Expand Down
2 changes: 1 addition & 1 deletion packages/Tailwind/Ignis.Components.HeadlessUI/Popover.cs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ protected override void BuildRenderTree(RenderTreeBuilder builder)
}

/// <inheritdoc />
protected override void OnBlur()
protected override void OnTargetBlur()
{
Close();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ private void Click()

var __ = OnClick.InvokeAsync(@event);

if (@event.CancellationToken.IsCancellationRequested) return;
if (@event.DefaultPrevented) return;

if (Popover.IsOpen) Popover.Close();
else Popover.Open();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -193,19 +193,19 @@ private void Click()

var __ = OnClick.InvokeAsync(@event);

if (@event.CancellationToken.IsCancellationRequested) return;
if (@event.DefaultPrevented) return;

Check();
}

/// <inheritdoc />
protected override void OnFocus()
protected override void OnTargetFocus()
{
RadioGroup.ActiveOption = this;
}

/// <inheritdoc />
protected override void OnBlur()
protected override void OnTargetBlur()
{
if (RadioGroup.ActiveOption == this) RadioGroup.ActiveOption = null;
}
Expand Down
2 changes: 1 addition & 1 deletion packages/Tailwind/Ignis.Components.HeadlessUI/Switch.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private void Click()

var __ = OnClick.InvokeAsync(@event);

if (@event.CancellationToken.IsCancellationRequested) return;
if (@event.DefaultPrevented) return;

Toggle();
}
Expand Down
2 changes: 1 addition & 1 deletion packages/Tailwind/Ignis.Components.HeadlessUI/Tab.cs
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public void Click()

var __ = OnClick.InvokeAsync(@event);

if (@event.CancellationToken.IsCancellationRequested) return;
if (@event.DefaultPrevented) return;

TabGroup.SelectTab(this);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
@page "/tests/dialog/preventOnBlur"
@inherits IgnisComponentBase

<PageTitle>Test: Prevent OnBlur</PageTitle>

<CustomDialog data-testid="dialog" Open="true" OnBlur="e => e.PreventDefault()">
<p data-testid="content">This dialog cannot be closed.</p>
</CustomDialog>

<DialogOutlet/>
21 changes: 10 additions & 11 deletions tests/e2e/Ignis.Tests.E2E.Website/Shared/CustomDialog.razor
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
@inherits IgnisComponentBase

<Transition AsComponent="typeof(Fragment)" Show="Open" Context="_">
<Transition AsComponent="typeof(Fragment)" Show="Open" Context="_" Appear>
<Dialog Context="dialog" IsOpenChanged="OpenChanged"
class="relative z-20" @attributes="AdditionalAttributes">
<TransitionChild AsComponent="typeof(Fragment)"
Expand All @@ -23,7 +23,8 @@
LeaveFrom="opacity-100 translate-y-0 sm:scale-100"
LeaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
Context="transition">
<DialogPanel class="@Css.Class("relative text-left shadow-xl sm:my-8 sm:w-full sm:max-w-2xl pointer-events-auto rounded-lg transform transition-all", transition)">
<DialogPanel OnBlur="OnBlur"
class="@Css.Class("relative text-left shadow-xl sm:my-8 sm:w-full sm:max-w-2xl pointer-events-auto rounded-lg transform transition-all", transition)">
<div class="bg-white px-4 pb-4 pt-5 sm:p-6 sm:pb-4 rounded-t-lg">
@ChildContent
</div>
Expand All @@ -39,18 +40,16 @@

@code
{
[Parameter]
public RenderFragment? ChildContent { get; set; }
[Parameter] public RenderFragment? ChildContent { get; set; }

[Parameter]
public RenderFragment? FooterContent { get; set; }
[Parameter] public RenderFragment? FooterContent { get; set; }

[Parameter]
public bool Open { get; set; }
[Parameter] public bool Open { get; set; }

[Parameter]
public EventCallback<bool> OpenChanged { get; set; }
[Parameter] public EventCallback<bool> OpenChanged { get; set; }

[Parameter] public EventCallback<IComponentEvent> OnBlur { get; set; }

[Parameter(CaptureUnmatchedValues = true)]
public IEnumerable<KeyValuePair<string, object?>>? AdditionalAttributes { get; set; }
}
}
23 changes: 23 additions & 0 deletions tests/e2e/Ignis.Tests.E2E/DialogTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,27 @@ await Page.ClickAsync(".fixed.inset-0.bg-gray-500",
await Expect(dialog).ToBeHiddenAsync();
}
}

[Test]
public async Task Test_Dialog_PreventOnBlur()
{
await Page.GotoAsync("https://e2e.ignis.dvolper.dev/tests/dialog/preventOnBlur");

var dialog = Page.GetByTestId("dialog");

await Expect(dialog).ToBeInViewportAsync();

var content = Page.GetByTestId("content");

await Expect(content).ToBeInViewportAsync();

await Expect(content).ToContainTextAsync("This dialog cannot be closed.");

await Page.ClickAsync(".fixed.inset-0.bg-gray-500",
new PageClickOptions { Position = new Position { X = 0, Y = 0 } });

await Task.Delay(300);

await Expect(dialog).ToBeInViewportAsync();
}
}

0 comments on commit 6768fa4

Please sign in to comment.