diff --git a/docs/CodeBeam.MudBlazor.Extensions.Docs.Wasm/wwwroot/CodeBeam.MudBlazor.Extensions.xml b/docs/CodeBeam.MudBlazor.Extensions.Docs.Wasm/wwwroot/CodeBeam.MudBlazor.Extensions.xml index 13869c4d..d00d32ec 100644 --- a/docs/CodeBeam.MudBlazor.Extensions.Docs.Wasm/wwwroot/CodeBeam.MudBlazor.Extensions.xml +++ b/docs/CodeBeam.MudBlazor.Extensions.Docs.Wasm/wwwroot/CodeBeam.MudBlazor.Extensions.xml @@ -2699,6 +2699,12 @@ + + + The accessible name used for the item. Prefer Text, then SecondaryText, then Value.ToString(). + If the parent list has a ToStringFunc use that for Value formatting. + + Functional items does not hold values. If a value set on Functional item, it ignores by the MudList. They can not count on Items list (they count on AllItems), cannot be subject of keyboard navigation and selection. diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListItemExtended.razor b/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListItemExtended.razor index 903f5fe4..351123a1 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListItemExtended.razor +++ b/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListItemExtended.razor @@ -5,10 +5,14 @@ @if (IsVisible) { -
+
@if (MudListExtended?.ItemDisabledTemplate != null && GetDisabledStatus() == true) - { + { @MudListExtended.ItemDisabledTemplate(this) } else if (MudListExtended?.ItemSelectedTemplate != null && IsSelected == true) @@ -27,15 +31,18 @@
@if (OverrideMultiSelectionComponent == null ? MudListExtended?.MultiSelectionComponent == MultiSelectionComponent.CheckBox : OverrideMultiSelectionComponent.Value == MultiSelectionComponent.CheckBox) { - + } else if (OverrideMultiSelectionComponent == null ? MudListExtended?.MultiSelectionComponent == MultiSelectionComponent.Switch : OverrideMultiSelectionComponent.Value == MultiSelectionComponent.Switch) { - + } else if (OverrideMultiSelectionComponent == null ? MudListExtended?.MultiSelectionComponent == MultiSelectionComponent.SwitchM3 : OverrideMultiSelectionComponent.Value == MultiSelectionComponent.SwitchM3) { - + }
} @@ -75,15 +82,18 @@
@if (OverrideMultiSelectionComponent == null ? MudListExtended?.MultiSelectionComponent == MultiSelectionComponent.CheckBox : OverrideMultiSelectionComponent.Value == MultiSelectionComponent.CheckBox) { - + } else if (OverrideMultiSelectionComponent == null ? MudListExtended?.MultiSelectionComponent == MultiSelectionComponent.Switch : OverrideMultiSelectionComponent.Value == MultiSelectionComponent.Switch) { - + } else if (OverrideMultiSelectionComponent == null ? MudListExtended?.MultiSelectionComponent == MultiSelectionComponent.SwitchM3 : OverrideMultiSelectionComponent.Value == MultiSelectionComponent.SwitchM3) { - + }
} diff --git a/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListItemExtended.razor.cs b/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListItemExtended.razor.cs index c973383d..e623db80 100644 --- a/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListItemExtended.razor.cs +++ b/src/CodeBeam.MudBlazor.Extensions/Components/ListExtended/MudListItemExtended.razor.cs @@ -1,7 +1,5 @@ -using System.Windows.Input; -using Microsoft.AspNetCore.Components; +using Microsoft.AspNetCore.Components; using Microsoft.AspNetCore.Components.Web; -using MudBlazor.Extensions; using MudBlazor.Utilities; using MudBlazor; @@ -59,7 +57,29 @@ public partial class MudListItemExtended : MudComponentBase, IDisposable /// /// /// - protected internal string? ItemId { get; } = "listitem_" + Guid.NewGuid().ToString().Substring(0, 8); + protected internal string? ItemId { get; } = string.Concat("listitem_", Guid.NewGuid().ToString().AsSpan(0, 8)); + + /// + /// The accessible name used for the item. Prefer Text, then SecondaryText, then Value.ToString(). + /// If the parent list has a ToStringFunc use that for Value formatting. + /// + protected string AccessibleName + { + get + { + if (!string.IsNullOrWhiteSpace(Text)) + return Text!; + if (!string.IsNullOrWhiteSpace(SecondaryText)) + return SecondaryText!; + if (Value != null) + { + if (MudListExtended?.ToStringFunc != null) + return MudListExtended.ToStringFunc(Value) ?? Value.ToString() ?? string.Empty; + return Value.ToString() ?? string.Empty; + } + return string.Empty; + } + } /// /// Functional items does not hold values. If a value set on Functional item, it ignores by the MudList. They can not count on Items list (they count on AllItems), cannot be subject of keyboard navigation and selection. diff --git a/tests/CodeBeam.MudBlazor.Extensions.UnitTests/Components/SelectExtendedTests.cs b/tests/CodeBeam.MudBlazor.Extensions.UnitTests/Components/SelectExtendedTests.cs index 23ef428e..41f900f3 100644 --- a/tests/CodeBeam.MudBlazor.Extensions.UnitTests/Components/SelectExtendedTests.cs +++ b/tests/CodeBeam.MudBlazor.Extensions.UnitTests/Components/SelectExtendedTests.cs @@ -29,6 +29,41 @@ public void SelectLabelFor() label[0].Attributes.GetNamedItem("for")?.Value.Should().Be("selectLabelTest"); } + [Test] + public void Select_Items_Should_Expose_Accessible_Role_And_Label() + { + var comp = Context.Render(); + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + var item = items[1]; + item.GetAttribute("role").Should().Be("option"); + item.GetAttribute("aria-selected").Should().Be("false"); + var ariaLabel = item.GetAttribute("aria-label"); + ariaLabel.Should().NotBeNullOrEmpty(); + ariaLabel.Trim().Should().Be("2"); + } + + [Test] + public void MultiSelect_Items_Should_Expose_Checkbox_AriaLabel_And_TestId() + { + var comp = Context.Render(); + comp.Find("div.mud-input-control").Click(); + comp.WaitForAssertion(() => comp.FindAll("div.mud-list-item-extended").Count.Should().BeGreaterThan(0)); + + var items = comp.FindAll("div.mud-list-item-extended").ToArray(); + var item = items[1]; + item.GetAttribute("role").Should().Be("option"); + var checkbox = item.QuerySelector("input[type=checkbox]"); + checkbox.Should().NotBeNull(); + var optionAria = item.GetAttribute("aria-label"); + optionAria.Should().NotBeNullOrEmpty(); + var checkboxAria = checkbox.GetAttribute("aria-label"); + checkboxAria.Should().NotBeNullOrEmpty(); + checkboxAria.Trim().Should().Be($"Select {optionAria.Trim()}"); + } + // Note: MudSelect doesn't guaranteed the consequences of changing Value if MultiSelection is true for now. // When this feature will add, just uncomment the testcase to test it. No need to write new test. [Test]