diff --git a/CodeBeam.MudBlazor.Extensions.Docs/CodeBeam.MudBlazor.Extensions.Docs.csproj b/CodeBeam.MudBlazor.Extensions.Docs/CodeBeam.MudBlazor.Extensions.Docs.csproj index 3c0dfd5e..6e9d7a01 100644 --- a/CodeBeam.MudBlazor.Extensions.Docs/CodeBeam.MudBlazor.Extensions.Docs.csproj +++ b/CodeBeam.MudBlazor.Extensions.Docs/CodeBeam.MudBlazor.Extensions.Docs.csproj @@ -14,7 +14,7 @@ - + diff --git a/CodeBeam.MudBlazor.Extensions.Docs/Pages/Index.razor b/CodeBeam.MudBlazor.Extensions.Docs/Pages/Index.razor index b835f3dc..72f54947 100644 --- a/CodeBeam.MudBlazor.Extensions.Docs/Pages/Index.razor +++ b/CodeBeam.MudBlazor.Extensions.Docs/Pages/Index.razor @@ -51,7 +51,7 @@
diff --git a/CodeBeam.MudBlazor.Extensions.Docs/Shared/MainLayout.razor b/CodeBeam.MudBlazor.Extensions.Docs/Shared/MainLayout.razor index 14e7fe2e..20006ef6 100644 --- a/CodeBeam.MudBlazor.Extensions.Docs/Shared/MainLayout.razor +++ b/CodeBeam.MudBlazor.Extensions.Docs/Shared/MainLayout.razor @@ -126,7 +126,7 @@ Typography = new Typography() { - Default = new Default() + Default = new DefaultTypography() { FontFamily = new[] { font, "Roboto", "Poppins", "Helvetica", "sans-serif" } }, diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/MultiSelectWithCustomComparerTest.razor b/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/MultiSelectWithCustomComparerTest.razor index 77ddfd1b..be465a78 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/MultiSelectWithCustomComparerTest.razor +++ b/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/MultiSelectWithCustomComparerTest.razor @@ -46,7 +46,7 @@ class CoffeeComparer : IEqualityComparer { - public bool Equals(Coffee a, Coffee b) => a.Key == b.Key; + public bool Equals(Coffee? a, Coffee? b) => a?.Key == b?.Key; public int GetHashCode(Coffee x) => HashCode.Combine(x.Key); } } diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/ReselectValueTest.razor b/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/ReselectValueTest.razor index dd179995..bba1eb56 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/ReselectValueTest.razor +++ b/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/ReselectValueTest.razor @@ -19,7 +19,7 @@ string fruit = "Apple"; public int ChangeCount { get; private set; } - void FruitChanged(IEnumerable fruits) + void FruitChanged(IEnumerable? fruits) { ChangeCount++; } diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/SelectInitialValueTest.razor b/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/SelectInitialValueTest.razor index 847bd1c7..62cef611 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/SelectInitialValueTest.razor +++ b/CodeBeam.MudBlazor.Extensions.UnitTests.Viewer/TestComponents/SelectExtended/SelectInitialValueTest.razor @@ -12,9 +12,9 @@ public static string __description__ = "Click should open the Menu and selecting a value should update the bindable value."; [Parameter] - public string SelectedValue { get; set; } + public string? SelectedValue { get; set; } [Parameter] - public IEnumerable SelectedValues { get; set; } + public IEnumerable? SelectedValues { get; set; } [Parameter] public bool MultiSelection { get; set; } } diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests/CodeBeam.MudBlazor.Extensions.UnitTests.csproj b/CodeBeam.MudBlazor.Extensions.UnitTests/CodeBeam.MudBlazor.Extensions.UnitTests.csproj index a0544469..8ca3ba16 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests/CodeBeam.MudBlazor.Extensions.UnitTests.csproj +++ b/CodeBeam.MudBlazor.Extensions.UnitTests/CodeBeam.MudBlazor.Extensions.UnitTests.csproj @@ -9,14 +9,14 @@ - + - - - - - - + + + + + + all runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ComboboxTests.cs b/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ComboboxTests.cs index f594f1cb..d0b119b4 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ComboboxTests.cs +++ b/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ComboboxTests.cs @@ -341,91 +341,91 @@ public async Task ComboBoxTest_KeyboardNavigation_SingleSelect() // select elements needed for the test var combobox = comp.FindComponent>().Instance; - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("d-none")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("d-none")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("d-none")); //If we didn't select an item with mouse or arrow keys yet, value should remains null. - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("d-none")); comp.WaitForAssertion(() => combobox.Value.Should().Be(null)); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", AltKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", AltKey = true, Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("d-none")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowUp", AltKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowUp", AltKey = true, Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("d-none")); //If dropdown is closed, arrow key should not set a value. - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("d-none")); comp.WaitForAssertion(() => combobox.Value.Should().Be(null)); // If no item is hiligted, enter should only close popover, not select any item and value - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("d-none")); comp.WaitForAssertion(() => combobox.Value.Should().Be(null)); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("d-none")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().BeNull()); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().Be("3")); //End key should not select the last disabled item - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().Be("3")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("d-none")); comp.WaitForAssertion(() => combobox.Value.Should().Be("1")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().Be("2")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().Be("1")); //Arrow up should select still the first item - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowUp", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowUp", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().Be("3")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().Be("1")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "2", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "2", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().Be("1")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().Be("2")); } @@ -435,19 +435,19 @@ public async Task ComboBoxTest_KeyboardNavigation_ToggleSelect() var comp = Context.RenderComponent(); var combobox = comp.FindComponent>().Instance; combobox.ToggleSelection = true; - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("d-none")); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().BeNull()); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().Be("3")); //End key should not select the last disabled item - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Value.Should().BeNull()); } @@ -458,57 +458,57 @@ public async Task ComboBoxTest_KeyboardNavigation_MultiSelect() var combobox = comp.FindComponent>(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("d-none")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("d-none")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "a", CtrlKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "a", CtrlKey = true, Type = "keydown", })); comp.WaitForAssertion(() => combobox.Instance.GetPresenterText().Should().Be("7 felines have been selected")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); comp.WaitForAssertion(() => combobox.Instance.GetPresenterText().Should().BeNull()); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Instance.GetPresenterText().Should().Be("1 feline has been selected")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); comp.WaitForAssertion(() => combobox.Instance.GetPresenterText().Should().Be("7 felines have been selected")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("d-none")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.Render(); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("d-none")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Instance.SelectedValues.Should().NotContain("Jaguar")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "NumpadEnter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "NumpadEnter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Instance.SelectedValues.Should().Contain("Jaguar")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Instance.SelectedValues.Should().NotContain("Leopard")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Instance.SelectedValues.Should().NotContain("Tiger")); combobox.SetParam("Disabled", true); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => combobox.Instance.SelectedValues.Should().NotContain("Tiger")); combobox.SetParam("Disabled", false); //Test the keyup event - await comp.InvokeAsync(() => combobox.Instance.HandleKeyUp(new KeyboardEventArgs() { Key = "Enter", Type = "keyup", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyUpAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keyup", })); comp.WaitForAssertion(() => combobox.Instance.SelectedValues.Should().NotContain("Tiger")); - await comp.InvokeAsync(() => combobox.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Tab", Type = "keydown", })); + await comp.InvokeAsync(() => combobox.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Tab", Type = "keydown", })); await comp.InvokeAsync(() => combobox.Instance.OnKeyUp.InvokeAsync(new KeyboardEventArgs() { Key = "Tab" })); comp.Render(); // <-- this is necessary for reliable passing of the test comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("d-none")); diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ListExtendedTests.cs b/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ListExtendedTests.cs index 2151d2d2..bd58d064 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ListExtendedTests.cs +++ b/CodeBeam.MudBlazor.Extensions.UnitTests/Components/ListExtendedTests.cs @@ -260,51 +260,51 @@ public async Task List_KeyboardNavigationTest() //Console.WriteLine(comp.Markup); var list = comp.FindComponent>().Instance; - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown" })); comp.WaitForAssertion(() => comp.FindComponents>()[0].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().BeNullOrEmpty()); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter" })); comp.WaitForAssertion(() => comp.FindComponents>()[0].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().ContainSingle()); //Second item is functional, should skip. - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown" })); comp.WaitForAssertion(() => comp.FindComponents>()[0].Instance.IsActive.Should().BeFalse()); comp.WaitForAssertion(() => comp.FindComponents>()[2].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().ContainSingle()); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "NumpadEnter" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "NumpadEnter" })); comp.WaitForAssertion(() => comp.FindComponents>()[2].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().ContainInOrder(new int[] { 1, 3 })); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown" })); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown" })); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter" })); comp.WaitForAssertion(() => comp.FindComponents>()[2].Instance.IsActive.Should().BeFalse()); comp.WaitForAssertion(() => comp.FindComponents>()[5].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().HaveCount(3)); comp.WaitForAssertion(() => list.SelectedValues.Should().Contain(5)); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter" })); comp.WaitForAssertion(() => comp.FindComponents>()[5].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().HaveCount(2)); comp.WaitForAssertion(() => list.SelectedValues.Should().Contain(3)); //Last disabled item should not be active - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "End" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "End" })); comp.WaitForAssertion(() => comp.FindComponents>()[9].Instance.IsActive.Should().BeTrue()); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "Home" })); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Home" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter" })); comp.WaitForAssertion(() => comp.FindComponents>()[0].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().HaveCount(1)); comp.WaitForAssertion(() => list.SelectedValues.Should().NotContain(1)); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "a", CtrlKey = true })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "a", CtrlKey = true })); comp.WaitForAssertion(() => comp.FindComponents>()[0].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().HaveCount(7)); comp.WaitForAssertion(() => list.SelectedValues.Should().NotContain(2)); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "A", CtrlKey = true })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "A", CtrlKey = true })); comp.WaitForAssertion(() => comp.FindComponents>()[0].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().HaveCount(0)); @@ -312,8 +312,8 @@ public async Task List_KeyboardNavigationTest() comp.WaitForAssertion(() => list.SelectedValues.Should().HaveCount(1)); comp.WaitForAssertion(() => list.SelectedValues.Should().Contain(5)); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown" })); - await comp.InvokeAsync(() => list.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown" })); + await comp.InvokeAsync(() => list.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter" })); comp.WaitForAssertion(() => comp.FindComponents>()[6].Instance.IsActive.Should().BeTrue()); comp.WaitForAssertion(() => list.SelectedValues.Should().HaveCount(2)); comp.WaitForAssertion(() => list.SelectedValues.Should().Contain(6)); diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests/Components/SelectExtendedTests.cs b/CodeBeam.MudBlazor.Extensions.UnitTests/Components/SelectExtendedTests.cs index 09fdd326..167a4641 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests/Components/SelectExtendedTests.cs +++ b/CodeBeam.MudBlazor.Extensions.UnitTests/Components/SelectExtendedTests.cs @@ -752,7 +752,7 @@ public async Task MultiSelectTextTest() var comp = Context.RenderComponent(); var select = comp.FindComponent>(); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter" })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter" })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); var selectItems = comp.FindAll("div.mud-list-item-extended"); @@ -1053,85 +1053,85 @@ public async Task SelectTest_KeyboardNavigation_SingleSelect() // select elements needed for the test var select = comp.FindComponent>().Instance; - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); //If we didn't select an item with mouse or arrow keys yet, value should remains null. - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); comp.WaitForAssertion(() => select.Value.Should().Be(null)); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", AltKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", AltKey = true, Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowUp", AltKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowUp", AltKey = true, Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); //If dropdown is closed, arrow key should not set a value. - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); comp.WaitForAssertion(() => select.Value.Should().Be(null)); // If no item is hiligted, enter should only close popover, not select any item and value - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "NumpadEnter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "NumpadEnter", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); comp.WaitForAssertion(() => select.Value.Should().Be(null)); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowUp", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowUp", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); comp.WaitForAssertion(() => select.Value.Should().BeNull()); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Value.Should().Be("2")); //End key should not select the last disabled item - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Value.Should().Be("3")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); comp.WaitForAssertion(() => select.Value.Should().Be("3")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Value.Should().Be("3")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Value.Should().Be("1")); //Arrow up should select still the first item - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowUp", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowUp", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Value.Should().Be("1")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Value.Should().Be("3")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "2", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "2", Type = "keydown", })); comp.WaitForAssertion(() => select.Value.Should().Be("3")); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Value.Should().Be("2")); comp.WaitForAssertion(() => select.SelectedValues.Should().HaveCount(1)); - await comp.InvokeAsync(() => select.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); //comp.Render(); // <-- this is necessary for reliable passing of the test // TODO: Look at this line why working manually and not working on test run. //comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); @@ -1146,54 +1146,54 @@ public async Task SelectTest_KeyboardNavigation_MultiSelect() // select elements needed for the test var select = comp.FindComponent>(); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "a", CtrlKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "a", CtrlKey = true, Type = "keydown", })); comp.WaitForAssertion(() => select.Instance.Text.Should().Be("7 felines have been selected")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); comp.WaitForAssertion(() => select.Instance.Text.Should().Be("0 feline has been selected")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Instance.Text.Should().Be("1 feline has been selected")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "A", CtrlKey = true, Type = "keydown", })); comp.WaitForAssertion(() => select.Instance.Text.Should().Be("7 felines have been selected")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Escape", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().Contain("mud-popover-open")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().NotContain("Tiger")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "NumpadEnter", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "NumpadEnter", Type = "keydown", })); comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().NotContain("Jaguar")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().NotContain("Leopard")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().Contain("Tiger")); select.SetParam("Disabled", true); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().Contain("Tiger")); select.SetParam("Disabled", false); //Test the keyup event - await comp.InvokeAsync(() => select.Instance.HandleKeyUp(new KeyboardEventArgs() { Key = "Enter", Type = "keyup", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyUpAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keyup", })); comp.WaitForAssertion(() => select.Instance.SelectedValues.Should().Contain("Tiger")); - await comp.InvokeAsync(() => select.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Tab", Type = "keydown", })); + await comp.InvokeAsync(() => select.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Tab", Type = "keydown", })); await comp.InvokeAsync(() => select.Instance.OnKeyUp.InvokeAsync(new KeyboardEventArgs() { Key = "Tab" })); comp.Render(); // <-- this is necessary for reliable passing of the test comp.WaitForAssertion(() => comp.Find("div.mud-popover").ClassList.Should().NotContain("mud-popover-open")); @@ -1207,11 +1207,11 @@ public async Task SelectTest_ItemlessSelect() // print the generated html //Console.WriteLine(comp.Markup); - await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); - await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); - await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); - await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); - await comp.InvokeAsync(() => comp.Instance.HandleKeyDown(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); + await comp.InvokeAsync(() => comp.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = " ", Type = "keydown", })); + await comp.InvokeAsync(() => comp.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "ArrowDown", Type = "keydown", })); + await comp.InvokeAsync(() => comp.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Home", Type = "keydown", })); + await comp.InvokeAsync(() => comp.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "End", Type = "keydown", })); + await comp.InvokeAsync(() => comp.Instance.HandleKeyDownAsync(new KeyboardEventArgs() { Key = "Enter", Type = "keydown", })); comp.WaitForAssertion(() => comp.Instance.SelectedValues.Should().HaveCount(0)); comp.WaitForAssertion(() => comp.Instance.Value.Should().Be(null)); } diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockJsEvent.cs b/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockJsEvent.cs index 93d28535..9d4f9010 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockJsEvent.cs +++ b/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockJsEvent.cs @@ -27,24 +27,16 @@ public MockJsEventFactory() public class MockJsEvent : IJsEvent { - public void Dispose() - { - - } - - public Task Connect(string element, JsEventOptions options) - { - return Task.CompletedTask; - } - - public Task Disconnect() - { - return Task.CompletedTask; - } - +#pragma warning disable CS0067 public event Action? CaretPositionChanged; public event Action? Paste; - public event Action? Copy; public event Action? Select; +#pragma warning restore CS0067 + + public Task Connect(string element, JsEventOptions options) => Task.CompletedTask; + + public Task Disconnect() => Task.CompletedTask; + + public ValueTask DisposeAsync() => ValueTask.CompletedTask; } } diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockKeyInterceptor.cs b/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockKeyInterceptorService.cs similarity index 55% rename from CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockKeyInterceptor.cs rename to CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockKeyInterceptorService.cs index 3afdc87a..5a396f29 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockKeyInterceptor.cs +++ b/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockKeyInterceptorService.cs @@ -6,48 +6,8 @@ namespace MudExtensions.UnitTests.Mocks { #pragma warning disable CS1998 #pragma warning disable CS0067 - public class MockKeyInterceptorServiceFactory : IKeyInterceptorFactory + public class MockKeyInterceptorService : IKeyInterceptorService { - private readonly MockKeyInterceptorService? _interceptorService; - - public MockKeyInterceptorServiceFactory(MockKeyInterceptorService interceptorService) - { - _interceptorService = interceptorService; - } - - public MockKeyInterceptorServiceFactory() - { - - } - - public IKeyInterceptor Create() => _interceptorService ?? new MockKeyInterceptorService(); - } - - public class MockKeyInterceptorService : IKeyInterceptor, IKeyInterceptorService - { - public void Dispose() - { - - } - - public Task Connect(string element, KeyInterceptorOptions options) - { - return Task.CompletedTask; - } - - public Task Disconnect() - { - return Task.CompletedTask; - } - - public Task UpdateKey(KeyOptions option) - { - return Task.CompletedTask; - } - - public event KeyboardEvent? KeyDown; - public event KeyboardEvent? KeyUp; - public ValueTask DisposeAsync() => ValueTask.CompletedTask; public Task SubscribeAsync(IKeyInterceptorObserver observer, KeyInterceptorOptions options) => Task.CompletedTask; @@ -66,4 +26,5 @@ public Task UpdateKey(KeyOptions option) public Task UnsubscribeAsync(string elementId) => Task.CompletedTask; } + } diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockPopoverService.cs b/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockPopoverService.cs index 6798d133..e48af844 100644 --- a/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockPopoverService.cs +++ b/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockPopoverService.cs @@ -1,32 +1,41 @@ -using Microsoft.AspNetCore.Components; -using Microsoft.JSInterop; -using Moq; +// Copyright (c) MudBlazor 2021 +// MudBlazor licenses this file to you under the MIT license. +// See the LICENSE file in the project root for more information. + using MudBlazor; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; namespace MudExtensions.UnitTests.Mocks { /// - /// Mock for scroll spy + /// Mock for popover /// - public class MockPopoverService : IMudPopoverService + internal class MockPopoverService : IPopoverService { - private List _handlers = new(); - private static RenderFragment DefaultFragment = (builder) => { }; - public IEnumerable Handlers => _handlers; + public PopoverOptions PopoverOptions { get; } = new(); - public bool ThrowOnDuplicateProvider => false; + public IEnumerable ActivePopovers { get; } = Enumerable.Empty(); - public event EventHandler? FragmentsChanged; + public bool IsInitialized => false; - public Task InitializeIfNeeded() => Task.FromResult(true); + public void Subscribe(IPopoverObserver observer) + { + } - public MudPopoverHandler Register(RenderFragment fragment) => new MudPopoverHandler(fragment ?? DefaultFragment, Mock.Of(), () => + public void Unsubscribe(IPopoverObserver observer) { - FragmentsChanged?.Invoke(this, EventArgs.Empty); - }); + } + + public Task CreatePopoverAsync(IPopover popover) => Task.CompletedTask; + + public Task UpdatePopoverAsync(IPopover popover) => Task.FromResult(true); + + public Task DestroyPopoverAsync(IPopover popover) => Task.FromResult(true); - public Task Unregister(MudPopoverHandler handler) => Task.FromResult(true); + public ValueTask GetProviderCountAsync() => ValueTask.FromResult(0); - public ValueTask CountProviders() => ValueTask.FromResult(0); + public ValueTask DisposeAsync() => ValueTask.CompletedTask; } } diff --git a/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockPopoverServiceV2.cs b/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockPopoverServiceV2.cs deleted file mode 100644 index a41cafad..00000000 --- a/CodeBeam.MudBlazor.Extensions.UnitTests/Mocks/MockPopoverServiceV2.cs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (c) MudBlazor 2021 -// MudBlazor licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using MudBlazor; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; - -namespace MudExtensions.UnitTests.Mocks -{ - /// - /// Mock for popover - /// - internal class MockPopoverServiceV2 : IPopoverService - { - public PopoverOptions PopoverOptions { get; } = new(); - - public IEnumerable ActivePopovers { get; } = Enumerable.Empty(); - - public bool IsInitialized => false; - - public void Subscribe(IPopoverObserver observer) - { - } - - public void Unsubscribe(IPopoverObserver observer) - { - } - - public Task CreatePopoverAsync(IPopover popover) => Task.CompletedTask; - - public Task UpdatePopoverAsync(IPopover popover) => Task.FromResult(true); - - public Task DestroyPopoverAsync(IPopover popover) => Task.FromResult(true); - - public ValueTask GetProviderCountAsync() => ValueTask.FromResult(0); - - public ValueTask DisposeAsync() => ValueTask.CompletedTask; - } -} diff --git a/CodeBeam.MudBlazor.Extensions/CodeBeam.MudBlazor.Extensions.csproj b/CodeBeam.MudBlazor.Extensions/CodeBeam.MudBlazor.Extensions.csproj index 8077fb5a..bd407c74 100644 --- a/CodeBeam.MudBlazor.Extensions/CodeBeam.MudBlazor.Extensions.csproj +++ b/CodeBeam.MudBlazor.Extensions/CodeBeam.MudBlazor.Extensions.csproj @@ -1,11 +1,11 @@  - net7.0;net8.0 + net8.0;net9.0 enable enable MIT - 7.0.2 + 8.0.0-preview.1 CodeBeam.MudBlazor.Extensions CodeBeam CodeBeam @@ -31,14 +31,14 @@ - - + + - - - + + + diff --git a/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor.cs b/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor.cs index 72b0cdd9..56d32fe9 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor.cs +++ b/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBox.razor.cs @@ -35,28 +35,6 @@ protected internal void SetSearchString(T value) } internal string? _searchString { get; set; } - private readonly string? multiSelectionText; - static readonly KeyInterceptorOptions _keyInterceptorOptions = new() - { - //EnableLogging = true, - TargetClass = "mud-input-control", - Keys = - { - new KeyOptions { Key=" ", PreventDown = "key+none" }, //prevent scrolling page, toggle open/close - new KeyOptions { Key="ArrowUp", PreventDown = "key+none" }, // prevent scrolling page, instead hilight previous item - new KeyOptions { Key="ArrowDown", PreventDown = "key+none" }, // prevent scrolling page, instead hilight next item - new KeyOptions { Key="PageUp", PreventDown = "key+none" }, // prevent scrolling page, instead hilight previous item - new KeyOptions { Key="PageDown", PreventDown = "key+none" }, // prevent scrolling page, instead hilight next item - new KeyOptions { Key="Home", PreventDown = "key+none" }, - new KeyOptions { Key="End", PreventDown = "key+none" }, - new KeyOptions { Key="Escape" }, - new KeyOptions { Key="Enter", PreventDown = "key+none" }, - new KeyOptions { Key="NumpadEnter", PreventDown = "key+none" }, - new KeyOptions { Key="a", PreventDown = "key+ctrl" }, // select all items instead of all page text - new KeyOptions { Key="A", PreventDown = "key+ctrl" }, // select all items instead of all page text - new KeyOptions { Key="/./", SubscribeDown = true, SubscribeUp = true }, // for our users - } - }; /// /// Item list of ComboBox. @@ -849,7 +827,30 @@ protected override async Task OnAfterRenderAsync(bool firstRender) if (firstRender) { - await KeyInterceptorService.SubscribeAsync(_elementId, _keyInterceptorOptions, keyDown: HandleKeyDown, keyUp: HandleKeyUp); + var options = new KeyInterceptorOptions( + "mud-input-control", + [ + // prevent scrolling page, toggle open/close + new(" ", preventDown: "key+none"), + // prevent scrolling page, instead highlight previous item + new("ArrowUp", preventDown: "key+none"), + // prevent scrolling page, instead highlight next item + new("ArrowDown", preventDown: "key+none"), + new("Home", preventDown: "key+none"), + new("End", preventDown: "key+none"), + new("Escape"), + new("Enter", preventDown: "key+none"), + new("NumpadEnter", preventDown: "key+none"), + // select all items instead of all page text + new("a", preventDown: "key+ctrl"), + // select all items instead of all page text + new("A", preventDown: "key+ctrl"), + // for our users + new("/./", subscribeDown: true, subscribeUp: true) + ]); + + await KeyInterceptorService.SubscribeAsync(_elementId, options, keyDown: HandleKeyDownAsync, keyUp: HandleKeyUpAsync); + await UpdateDataVisualiserTextAsync(); _firstRendered = true; StateHasChanged(); @@ -861,20 +862,14 @@ protected override async Task OnAfterRenderAsync(bool firstRender) /// /// /// - /// - protected override void Dispose(bool disposing) + /// + protected override async ValueTask DisposeAsyncCore() { - base.Dispose(disposing); + await base.DisposeAsyncCore(); - if (disposing) + if (IsJSRuntimeAvailable) { - if (IsJSRuntimeAvailable) - { - // TODO: Switch to IAsyncDisposable - KeyInterceptorService.UnsubscribeAsync(_elementId).CatchAndLog(); - } - - Items.Clear(); + await KeyInterceptorService.UnsubscribeAsync(_elementId); } } @@ -887,7 +882,7 @@ protected override void Dispose(bool disposing) /// Protected keydown event. /// /// - protected internal async Task HandleKeyDown(KeyboardEventArgs obj) + protected internal async Task HandleKeyDownAsync(KeyboardEventArgs obj) { if (Disabled || ReadOnly) return; @@ -1010,7 +1005,7 @@ protected internal async Task SearchBoxHandleKeyDown(KeyboardEventArgs obj) case "ArrowDown": case "Enter": case "NumpadEnter": - await HandleKeyDown(obj); + await HandleKeyDownAsync(obj); return; case "Tab": @@ -1035,7 +1030,7 @@ protected internal async Task SearchBoxHandleKeyUp(KeyboardEventArgs obj) /// Protected keyup event. /// /// - protected internal async Task HandleKeyUp(KeyboardEventArgs obj) + protected internal async Task HandleKeyUpAsync(KeyboardEventArgs obj) { ForceRenderItems(); await OnKeyUp.InvokeAsync(obj); diff --git a/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor b/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor index 56781cc1..813fb763 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor +++ b/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor @@ -1,5 +1,5 @@ @namespace MudExtensions -@inherits MudBaseSelectItem +@inherits MudComponentBase @typeparam T @if (MudComboBox is not null) diff --git a/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor.cs b/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor.cs index d3755495..b6ee6759 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor.cs +++ b/CodeBeam.MudBlazor.Extensions/Components/ComboBox/MudComboBoxItem.razor.cs @@ -9,7 +9,7 @@ namespace MudExtensions /// /// /// - public partial class MudComboBoxItem : MudBaseSelectItem, IDisposable + public partial class MudComboBoxItem : MudComponentBase, IDisposable { /// /// @@ -45,6 +45,23 @@ public partial class MudComboBoxItem : MudBaseSelectItem, IDisposable [CascadingParameter] MudComboBox MudComboBox { get; set; } + /// + /// Prevents the user from interacting with this item. + /// + [Parameter] + [Category(CategoryTypes.General.Behavior)] + public bool Disabled { get; set; } + + /// + /// Shows a ripple effect when the user clicks the button. + /// + /// + /// Defaults to true. + /// + [Parameter] + [Category(CategoryTypes.General.Appearance)] + public bool Ripple { get; set; } = true; + /// /// The text to display /// @@ -59,6 +76,13 @@ public partial class MudComboBoxItem : MudBaseSelectItem, IDisposable [Category(CategoryTypes.FormComponent.Behavior)] public T? Value { get; set; } + /// + /// The content within this item. + /// + [Parameter] + [Category(CategoryTypes.General.Behavior)] + public RenderFragment? ChildContent { get; set; } + /// /// The color of the text. It supports the theme colors. /// @@ -87,6 +111,13 @@ public partial class MudComboBoxItem : MudBaseSelectItem, IDisposable [Category(CategoryTypes.FormComponent.Appearance)] public Size? CheckBoxSize { get; set; } = null; + /// + /// OnClick event. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public EventCallback OnClick { get; set; } + /// /// /// diff --git a/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudDebouncedInputExtended.cs b/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudDebouncedInputExtended.cs index 02a23a28..515c8b76 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudDebouncedInputExtended.cs +++ b/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudDebouncedInputExtended.cs @@ -47,7 +47,7 @@ public double DebounceInterval /// /// /// - protected Task OnChange() + protected Task OnChanged() { if (DebounceInterval > 0 && _timer != null) { @@ -133,10 +133,9 @@ private void ClearTimer(bool suppressTick = false) /// /// /// - /// - protected override void Dispose(bool disposing) + protected override async ValueTask DisposeAsyncCore() { - base.Dispose(disposing); + await base.DisposeAsyncCore(); ClearTimer(suppressTick: true); } } diff --git a/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudInputExtended.razor.cs b/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudInputExtended.razor.cs index 7dec6868..e52e73f0 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudInputExtended.razor.cs +++ b/CodeBeam.MudBlazor.Extensions/Components/InputExtended/MudInputExtended.razor.cs @@ -306,7 +306,7 @@ public override ValueTask SelectRangeAsync(int pos1, int pos2) private Size GetButtonSize() => Margin == Margin.Dense ? Size.Small : Size.Medium; - private bool _showClearable; + //private bool _showClearable; private void UpdateClearable(object? value) { diff --git a/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor b/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor index 49e09ce7..95791774 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor +++ b/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor @@ -3,7 +3,7 @@ @inherits MudComponentBase @using MudBlazor -
+
@if (MultiSelection && SelectAll && SelectAllPosition == SelectAllPosition.BeforeSearchBox && ParentList == null) { @@ -31,7 +31,7 @@ { } -
diff --git a/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor.cs b/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor.cs index f00541d7..bde0fb18 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor.cs +++ b/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListExtended.razor.cs @@ -744,7 +744,6 @@ protected override void OnParametersSet() ParametersChanged?.Invoke(); } - private IKeyInterceptor? _keyInterceptor; private bool _firstRendered = false; /// /// @@ -758,24 +757,29 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { _firstRendered = false; - await KeyInterceptorService.SubscribeAsync(_elementId, new KeyInterceptorOptions - { - //EnableLogging = true, - TargetClass = "mud-list-item-extended", - Keys = { - //new KeyOptions { Key=" ", PreventDown = "key+none" }, //prevent scrolling page, toggle open/close - new KeyOptions { Key="ArrowUp", PreventDown = "key+none" }, // prevent scrolling page, instead hilight previous item - new KeyOptions { Key="ArrowDown", PreventDown = "key+none" }, // prevent scrolling page, instead hilight next item - new KeyOptions { Key="Home", PreventDown = "key+none" }, - new KeyOptions { Key="End", PreventDown = "key+none" }, - new KeyOptions { Key="Escape" }, - new KeyOptions { Key="Enter", PreventDown = "key+none" }, - new KeyOptions { Key="NumpadEnter", PreventDown = "key+none" }, - new KeyOptions { Key="a", PreventDown = "key+ctrl" }, // select all items instead of all page text - new KeyOptions { Key="A", PreventDown = "key+ctrl" }, // select all items instead of all page text - new KeyOptions { Key="/./", SubscribeDown = true, SubscribeUp = true }, // for our users - }, - }, KeyObserver.KeyDownIgnore(), KeyObserver.KeyUpIgnore()); + var options = new KeyInterceptorOptions( + "mud-list-item-extended", + [ + // prevent scrolling page, toggle open/close + new(" ", preventDown: "key+none"), + // prevent scrolling page, instead highlight previous item + new("ArrowUp", preventDown: "key+none"), + // prevent scrolling page, instead highlight next item + new("ArrowDown", preventDown: "key+none"), + new("Home", preventDown: "key+none"), + new("End", preventDown: "key+none"), + new("Escape"), + new("Enter", preventDown: "key+none"), + new("NumpadEnter", preventDown: "key+none"), + // select all items instead of all page text + new("a", preventDown: "key+ctrl"), + // select all items instead of all page text + new("A", preventDown: "key+ctrl"), + // for our users + new("/./", subscribeDown: true, subscribeUp: true) + ]); + + await KeyInterceptorService.SubscribeAsync(_elementId, options, keyDown: HandleKeyDownAsync); if (MudSelectExtended == null && MudAutocomplete == null) { @@ -901,7 +905,7 @@ protected internal void Unregister(MudListExtended child) /// /// /// - protected internal async Task SearchBoxHandleKeyDown(KeyboardEventArgs obj) + protected internal async Task SearchBoxHandleKeyDownAsync(KeyboardEventArgs obj) { if (Disabled || (!Clickable && !MultiSelection)) return; @@ -924,11 +928,11 @@ protected internal async Task SearchBoxHandleKeyDown(KeyboardEventArgs obj) break; case "ArrowUp": case "ArrowDown": - await HandleKeyDown(obj); + await HandleKeyDownAsync(obj); break; case "Enter": case "NumpadEnter": - await HandleKeyDown(obj); + await HandleKeyDownAsync(obj); if (MudSelectExtended != null && MultiSelection == false) { await MudSelectExtended.CloseMenu(); @@ -956,7 +960,7 @@ protected internal async Task SearchBoxHandleKeyDown(KeyboardEventArgs obj) /// /// /// - protected internal async Task HandleKeyDown(KeyboardEventArgs obj) + protected internal async Task HandleKeyDownAsync(KeyboardEventArgs obj) { if (Disabled || (!Clickable && !MultiSelection)) return; diff --git a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor index dd807da2..cb3d77d6 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor +++ b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectExtended.razor @@ -110,7 +110,7 @@ x.Value != null && Value != null && x.Value.Equals(Value))?.ListItem; @@ -813,18 +819,14 @@ public void ForceUpdateItems() /// /// /// - /// - protected override void Dispose(bool disposing) + /// + protected override async ValueTask DisposeAsyncCore() { - base.Dispose(disposing); + await base.DisposeAsyncCore(); - if (disposing) + if (IsJSRuntimeAvailable) { - if (IsJSRuntimeAvailable) - { - //TODO: Use IAsyncDisposable instead. - KeyInterceptorService.UnsubscribeAsync(_elementId).CatchAndLog(); - } + await KeyInterceptorService.UnsubscribeAsync(_elementId); } } @@ -837,14 +839,14 @@ protected override void Dispose(bool disposing) /// Keydown event. /// /// - protected internal async Task HandleKeyDown(KeyboardEventArgs obj) + protected internal async Task HandleKeyDownAsync(KeyboardEventArgs obj) { if (Disabled || ReadOnly) return; if (_list != null && _isOpen) { - await _list.HandleKeyDown(obj); + await _list.HandleKeyDownAsync(obj); } switch (obj.Key) @@ -914,7 +916,7 @@ protected internal async Task HandleKeyDown(KeyboardEventArgs obj) /// Keyup event. /// /// - protected internal async Task HandleKeyUp(KeyboardEventArgs obj) + protected internal async Task HandleKeyUpAsync(KeyboardEventArgs obj) { await OnKeyUp.InvokeAsync(obj); } diff --git a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor index e6ced25b..31b1ee79 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor +++ b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor @@ -1,10 +1,10 @@ @namespace MudExtensions @typeparam T -@inherits MudBaseSelectItem +@inherits MudComponentBase @if (HideContent == false) { - + @if (ChildContent != null && MudSelectExtended?.ItemCollection == null) { @ChildContent diff --git a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs index 1a05307b..18626005 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs +++ b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemExtended.razor.cs @@ -8,7 +8,7 @@ namespace MudExtensions /// /// Represents an option of a select or multi-select. To be used inside MudSelect. /// - public partial class MudSelectItemExtended : MudBaseSelectItem, IDisposable + public partial class MudSelectItemExtended : MudComponentBase, IDisposable { private String GetCssClasses() => new CssBuilder() .AddClass(Class) @@ -100,6 +100,20 @@ private void OnUpdateSelectionStateFromOutside(IEnumerable? selection) [Category(CategoryTypes.FormComponent.Behavior)] public T? Value { get; set; } + /// + /// The URL to navigate to when this item is clicked. + /// + [Parameter] + [Category(CategoryTypes.General.ClickAction)] + public string? Href { get; set; } + + /// + /// The content within this item. + /// + [Parameter] + [Category(CategoryTypes.General.Behavior)] + public RenderFragment? ChildContent { get; set; } + /// /// Mirrors the MultiSelection status of the parent select /// @@ -113,6 +127,21 @@ protected bool MultiSelection } } + /// + /// OnClick event. + /// + [Parameter] + [Category(CategoryTypes.FormComponent.Behavior)] + public EventCallback OnClick { get; set; } + + /// + /// Prevents the user from interacting with this item. + /// + [Parameter] + [Category(CategoryTypes.General.Behavior)] + public bool Disabled { get; set; } + + private bool _isSelected; internal bool IsSelected { @@ -142,20 +171,20 @@ protected string? DisplayString /// /// /// - protected void HandleOnClick() + protected async Task HandleOnClickAsync() { // Selection works on list. We arrange only popover state and some minor arrangements on click. - MudSelectExtended?.SelectOption(Value).CatchAndLog(); - InvokeAsync(StateHasChanged); + await MudSelectExtended?.SelectOption(Value); + await InvokeAsync(StateHasChanged); if (!MultiSelection) { - MudSelectExtended?.CloseMenu().CatchAndLog(); + await MudSelectExtended?.CloseMenu(); } else { - MudSelectExtended?.FocusAsync().CatchAndLog(); + MudSelectExtended?.FocusAsync(); } - OnClick.InvokeAsync().CatchAndLog(); + await OnClick.InvokeAsync(); } /// diff --git a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor index 8895b9ba..ee13f74c 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor +++ b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor @@ -1,6 +1,6 @@ @namespace MudExtensions @typeparam T -@inherits MudBaseSelectItem +@inherits MudComponentBase @if (HideContent == false) { diff --git a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs index 9cab2d62..c3d974f4 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs +++ b/CodeBeam.MudBlazor.Extensions/Components/SelectExtended/MudSelectItemGroupExtended.razor.cs @@ -6,7 +6,7 @@ namespace MudExtensions /// /// Represents an option of a select or multi-select. To be used inside MudSelect. /// - public partial class MudSelectItemGroupExtended : MudBaseSelectItem + public partial class MudSelectItemGroupExtended : MudComponentBase { //private IMudSelect _parent; @@ -26,6 +26,13 @@ public partial class MudSelectItemGroupExtended : MudBaseSelectItem [Category(CategoryTypes.FormComponent.Behavior)] public string? Text { get; set; } + /// + /// The content within this item. + /// + [Parameter] + [Category(CategoryTypes.General.Behavior)] + public RenderFragment? ChildContent { get; set; } + /// /// A user-defined option that can be selected /// diff --git a/CodeBeam.MudBlazor.Extensions/Components/SwitchM3/MudSwitchM3.razor b/CodeBeam.MudBlazor.Extensions/Components/SwitchM3/MudSwitchM3.razor index 3a801726..b4f6f9ca 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/SwitchM3/MudSwitchM3.razor +++ b/CodeBeam.MudBlazor.Extensions/Components/SwitchM3/MudSwitchM3.razor @@ -2,7 +2,7 @@ @inherits MudBooleanInput @typeparam T - protected string? SwitchClassname => new CssBuilder("mud-button-root mud-icon-button mud-switch-base-m3") - .AddClass($"mud-ripple mud-ripple-switch", Ripple && !ReadOnly && !Disabled) + .AddClass($"mud-ripple mud-ripple-switch", Ripple && !GetReadOnlyState() && !GetDisabledState()) .AddClass($"mud-{Color.ToDescriptionString()}-text hover:mud-{Color.ToDescriptionString()}-hover", BoolValue == true) //.AddClass($"mud-{UnCheckedColor.ToDescriptionString()}-text hover:mud-{UnCheckedColor.ToDescriptionString()}-hover", BoolValue == false) - .AddClass($"mud-switch-disabled", Disabled) - .AddClass($"mud-readonly", ReadOnly) + .AddClass($"mud-switch-disabled", GetDisabledState()) + .AddClass($"mud-readonly", GetReadOnlyState()) .AddClass($"mud-checked", BoolValue) .AddClass("mud-switch-base-dense-m3", !string.IsNullOrEmpty(ThumbOffIcon)) .Build(); @@ -66,27 +67,6 @@ public partial class MudSwitchM3 : MudBooleanInput [Inject] private IKeyInterceptorService KeyInterceptorService { get; set; } = null!; - /// - /// The color of the component. It supports the theme colors. - /// - [Parameter] - [Category(CategoryTypes.FormComponent.Appearance)] - public Color Color { get; set; } = Color.Default; - - /// - /// The text/label will be displayed next to the switch if set. - /// - [Parameter] - [Category(CategoryTypes.FormComponent.Behavior)] - public string? Label { get; set; } - - /// - /// The position of the text/label. - /// - [Parameter] - [Category(CategoryTypes.FormComponent.Behavior)] - public LabelPosition LabelPosition { get; set; } = LabelPosition.End; - /// /// Shows an icon on Switch's thumb. /// @@ -101,18 +81,11 @@ public partial class MudSwitchM3 : MudBooleanInput [Category(CategoryTypes.FormComponent.Appearance)] public string? ThumbOffIcon { get; set; } - /// - /// If true, disables ripple effect. - /// - [Parameter] - [Category(CategoryTypes.FormComponent.Appearance)] - public bool Ripple { get; set; } = true; - /// /// Keydown event. /// /// - protected internal async Task HandleKeyDown(KeyboardEventArgs obj) + protected internal async Task HandleKeyDownAsync(KeyboardEventArgs obj) { if (Disabled || ReadOnly) return; @@ -162,17 +135,17 @@ protected override async Task OnAfterRenderAsync(bool firstRender) { if (firstRender) { - // TODO: Make HandleKeyDown async Task - await KeyInterceptorService.SubscribeAsync(_elementId, new KeyInterceptorOptions() - { - //EnableLogging = true, - TargetClass = "mud-switch-base-m3", - Keys = { - new KeyOptions { Key="ArrowUp", PreventDown = "key+none" }, // prevent scrolling page, instead increment - new KeyOptions { Key="ArrowDown", PreventDown = "key+none" }, // prevent scrolling page, instead decrement - new KeyOptions { Key=" ", PreventDown = "key+none", PreventUp = "key+none" }, - }, - }, keyDown: HandleKeyDown); + var options = new KeyInterceptorOptions( + "mud-switch-base", + [ + // prevent scrolling page, instead increment + new("ArrowUp", preventDown: "key+none"), + // prevent scrolling page, instead decrement + new("ArrowDown", preventDown: "key+none"), + new(" ", preventDown: "key+none", preventUp: "key+none") + ]); + + await KeyInterceptorService.SubscribeAsync(_elementId, options, keyDown: HandleKeyDownAsync); } await base.OnAfterRenderAsync(firstRender); } @@ -180,19 +153,16 @@ protected override async Task OnAfterRenderAsync(bool firstRender) /// /// /// - /// - protected override void Dispose(bool disposing) + /// + protected override async ValueTask DisposeAsyncCore() { - base.Dispose(disposing); + await base.DisposeAsyncCore(); - if (disposing) + if (IsJSRuntimeAvailable) { - if (IsJSRuntimeAvailable) - { - //TODO: Use IAsyncDisposable - KeyInterceptorService.UnsubscribeAsync(_elementId).CatchAndLog(); - } + await KeyInterceptorService.UnsubscribeAsync(_elementId); } } + } } diff --git a/CodeBeam.MudBlazor.Extensions/Components/TextFieldExtended/MudTextFieldExtended.razor b/CodeBeam.MudBlazor.Extensions/Components/TextFieldExtended/MudTextFieldExtended.razor index 12e74795..2e22af0d 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/TextFieldExtended/MudTextFieldExtended.razor +++ b/CodeBeam.MudBlazor.Extensions/Components/TextFieldExtended/MudTextFieldExtended.razor @@ -45,7 +45,7 @@ OnInput="@OnInput" OnBlur="@OnBlurredAsync" OnKeyDown="@InvokeKeyDownAsync" - OnInternalInputChanged="OnChange" + OnInternalInputChanged="OnChanged" OnKeyUp="@InvokeKeyUpAsync" KeyDownPreventDefault="KeyDownPreventDefault" KeyUpPreventDefault="KeyUpPreventDefault" diff --git a/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor.cs b/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor.cs index 732b6f1a..fd90cdb9 100644 --- a/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor.cs +++ b/CodeBeam.MudBlazor.Extensions/Components/Wheel/MudWheel.razor.cs @@ -219,7 +219,7 @@ protected async Task HandleOnSwipe(SwipeEventArgs args) _animateValue = - GetAnimateValue(); } - int changedCount = (Math.Abs((int)args.SwipeDelta) / (Sensitivity == 0 ? 1 : Sensitivity)); + int changedCount = (Math.Abs((int)(args.SwipeDelta ?? 0)) / (Sensitivity == 0 ? 1 : Sensitivity)); for (int i = 0; i < changedCount; i++) { await _animate.Refresh();