various accessibility fixes

This commit is contained in:
Vladimir Enchev
2026-07-08 16:41:38 +03:00
parent 08f9299390
commit 6066feb203
2 changed files with 58 additions and 4 deletions

View File

@@ -435,6 +435,60 @@ namespace Radzen.Blazor.Tests
Assert.Equal(2, component.FindAll("span.rz-calendar-month-title").Count);
}
[Fact]
public void DateRangePicker_Follows_Aria_Authoring_Practices()
{
using var ctx = new TestContext();
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
var component = ctx.RenderComponent<RadzenDateRangePicker>(parameters =>
{
parameters.Add(p => p.InitialViewDate, new DateTime(2024, 1, 1));
parameters.Add(p => p.Value, new DateRange(new DateTime(2024, 1, 10), new DateTime(2024, 2, 5)));
});
var dialog = component.Find("[role=dialog]");
Assert.False(string.IsNullOrEmpty(dialog.GetAttribute("aria-label")));
var trigger = component.Find(".rz-datepicker-trigger");
Assert.Equal("dialog", trigger.GetAttribute("aria-haspopup"));
Assert.Equal(dialog.Id, trigger.GetAttribute("aria-controls"));
var grids = component.FindAll("table[role=grid]");
Assert.All(grids, g => Assert.False(string.IsNullOrEmpty(g.GetAttribute("aria-label"))));
Assert.Single(component.FindAll("td[tabindex='0']"));
var dayCells = component.FindAll("td[id]");
Assert.All(dayCells, c => Assert.False(string.IsNullOrEmpty(c.GetAttribute("aria-label"))));
Assert.All(dayCells, c => Assert.Contains(c.GetAttribute("aria-selected"), new[] { "true", "false" }));
Assert.All(component.FindAll("[aria-hidden='true']"), e => Assert.Null(e.GetAttribute("tabindex")));
Assert.Empty(component.FindAll("[aria-pressed]"));
Assert.Empty(component.FindAll("button:not([aria-label])").Where(b => string.IsNullOrWhiteSpace(b.TextContent)));
component.InvokeAsync(() => component.FindAll(".rz-calendar-title-button")[0].Click());
var monthsGroup = component.Find(".rz-calendar-months");
Assert.Equal("group", monthsGroup.GetAttribute("role"));
Assert.False(string.IsNullOrEmpty(monthsGroup.GetAttribute("aria-label")));
var focusedMonth = component.FindAll(".rz-calendar-month-cell").Single(c => c.GetAttribute("tabindex") == "0");
Assert.Equal("true", focusedMonth.GetAttribute("aria-current"));
Assert.Contains("2024", focusedMonth.GetAttribute("aria-label"));
component.InvokeAsync(() => component.Find(".rz-calendar-title-button").Click());
var yearsGroup = component.Find(".rz-calendar-years");
Assert.Equal("group", yearsGroup.GetAttribute("role"));
Assert.False(string.IsNullOrEmpty(yearsGroup.GetAttribute("aria-label")));
var focusedYear = component.FindAll(".rz-calendar-year-cell").Single(c => c.GetAttribute("tabindex") == "0");
Assert.Equal("true", focusedYear.GetAttribute("aria-current"));
Assert.Empty(component.FindAll("[aria-pressed]"));
}
[Fact]
public void DateRangePicker_Does_Not_Render_TimePicker()
{

View File

@@ -75,12 +75,12 @@
@if (currentView == CalendarViewKind.Months)
{
<div class="rz-calendar-view-container">
<div class="rz-calendar-months">
<div class="rz-calendar-months" role="group" aria-label="@GetViewTitle()">
@foreach (var month in MonthsInView)
{
var isActiveMonth = month.Value == GetCalendarMonth(CurrentDate);
var monthDisabled = Disabled || IsMonthDisabled(month.Value);
<button type="button" id="@($"{GetId()}-month-{month.Value}")" class="@($"rz-calendar-month-cell{(isActiveMonth ? " rz-state-active" : "")}")" disabled="@monthDisabled" aria-disabled="@(monthDisabled ? "true" : "false")" aria-pressed="@(isActiveMonth ? "true" : "false")" tabindex="@(isActiveMonth && !monthDisabled ? TabIndex : -1)"
<button type="button" id="@($"{GetId()}-month-{month.Value}")" class="@($"rz-calendar-month-cell{(isActiveMonth ? " rz-state-active" : "")}")" disabled="@monthDisabled" aria-disabled="@(monthDisabled ? "true" : "false")" aria-label="@($"{month.Name} {GetViewTitle()}")" aria-current="@(isActiveMonth ? "true" : null)" tabindex="@(isActiveMonth && !monthDisabled ? TabIndex : -1)"
@onclick="@(() => SelectViewMonth(month.Value))" @onkeydown="@OnMonthCellKeyDown" @onkeydown:preventDefault="preventKeyPress" @onkeydown:stopPropagation="stopKeydownPropagation">@month.Name</button>
}
</div>
@@ -89,11 +89,11 @@
else if (currentView == CalendarViewKind.Years)
{
<div class="rz-calendar-view-container">
<div class="rz-calendar-years">
<div class="rz-calendar-years" role="group" aria-label="@GetViewTitle()">
@foreach (var year in YearsInView)
{
var isActiveYear = year.Value == GetCalendarYear(CurrentDate);
<button type="button" id="@($"{GetId()}-year-{year.Value}")" class="@($"rz-calendar-year-cell{(isActiveYear ? " rz-state-active" : "")}")" disabled="@Disabled" aria-disabled="@(Disabled ? "true" : "false")" aria-pressed="@(isActiveYear ? "true" : "false")" tabindex="@(isActiveYear ? TabIndex : -1)"
<button type="button" id="@($"{GetId()}-year-{year.Value}")" class="@($"rz-calendar-year-cell{(isActiveYear ? " rz-state-active" : "")}")" disabled="@Disabled" aria-disabled="@(Disabled ? "true" : "false")" aria-current="@(isActiveYear ? "true" : null)" tabindex="@(isActiveYear ? TabIndex : -1)"
@onclick="@(() => SelectViewYear(year.Value))" @onkeydown="@OnYearCellKeyDown" @onkeydown:preventDefault="preventKeyPress" @onkeydown:stopPropagation="stopKeydownPropagation">@year.Name</button>
}
</div>