mirror of
https://github.com/radzenhq/radzen-blazor.git
synced 2026-07-08 18:16:08 +00:00
DataGrid rows cannot be accessed using arrow keys with enabled screen reader
Fix #2530
This commit is contained in:
@@ -3273,5 +3273,43 @@ namespace Radzen.Blazor.Tests
|
||||
Assert.Equal("0", wrapper.GetAttribute("tabindex"));
|
||||
Assert.False(string.IsNullOrEmpty(wrapper.GetAttribute("aria-activedescendant")));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void DataGrid_AppliesAriaGridRolesToTableDescendants()
|
||||
{
|
||||
using var ctx = new TestContext();
|
||||
ctx.JSInterop.Mode = JSRuntimeMode.Loose;
|
||||
ctx.JSInterop.SetupModule("_content/Radzen.Blazor/Radzen.Blazor.js");
|
||||
|
||||
var component = ctx.RenderComponent<RadzenDataGrid<dynamic>>(parameterBuilder =>
|
||||
{
|
||||
parameterBuilder.Add<IEnumerable<dynamic>>(p => p.Data, new[] { new { Id = 1 }, new { Id = 2 } });
|
||||
parameterBuilder.Add<RenderFragment>(p => p.Columns, builder =>
|
||||
{
|
||||
builder.OpenComponent(0, typeof(RadzenDataGridColumn<dynamic>));
|
||||
builder.AddAttribute(1, "Property", "Id");
|
||||
builder.CloseComponent();
|
||||
});
|
||||
});
|
||||
|
||||
Assert.Equal("presentation", component.Find("table.rz-grid-table").GetAttribute("role"));
|
||||
Assert.Equal("rowgroup", component.Find("thead").GetAttribute("role"));
|
||||
Assert.Equal("rowgroup", component.Find("tbody").GetAttribute("role"));
|
||||
|
||||
var headerCell = component.Find("thead tr th");
|
||||
Assert.Equal("row", headerCell.ParentElement!.GetAttribute("role"));
|
||||
Assert.Equal("columnheader", headerCell.GetAttribute("role"));
|
||||
|
||||
var dataRows = component.FindAll("tbody tr");
|
||||
Assert.NotEmpty(dataRows);
|
||||
foreach (var row in dataRows)
|
||||
{
|
||||
Assert.Equal("row", row.GetAttribute("role"));
|
||||
foreach (var cell in row.QuerySelectorAll("td"))
|
||||
{
|
||||
Assert.Equal("gridcell", cell.GetAttribute("role"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -83,7 +83,7 @@
|
||||
}
|
||||
|
||||
<div class="rz-data-grid-data" tabindex="-1">
|
||||
<table class="rz-grid-table rz-grid-table-fixed @(AllowAlternatingRows ? "rz-grid-table-striped" : "") @(allColumns.Any(c => c.Parent != null) ? "rz-grid-table-composite" : "") @(getGridLinesCSSClass())">
|
||||
<table role="presentation" class="rz-grid-table rz-grid-table-fixed @(AllowAlternatingRows ? "rz-grid-table-striped" : "") @(allColumns.Any(c => c.Parent != null) ? "rz-grid-table-composite" : "") @(getGridLinesCSSClass())">
|
||||
@if(allColumns.All(c => c.Parent == null))
|
||||
{
|
||||
<colgroup>
|
||||
@@ -104,26 +104,26 @@
|
||||
}
|
||||
</colgroup>
|
||||
}
|
||||
<thead>
|
||||
<thead role="rowgroup">
|
||||
@if (ShowHeader)
|
||||
{
|
||||
@for (var i = 0; i < deepestChildColumnLevel + 1; i++)
|
||||
{
|
||||
<tr>
|
||||
<tr role="row">
|
||||
@if (i == 0) // Only add the th elements for the first row
|
||||
{
|
||||
@if (ShowGroupExpandColumn)
|
||||
{
|
||||
@foreach (var g in Groups)
|
||||
{
|
||||
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<th role="columnheader" class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<span class="rz-column-title"><span style="visibility:hidden">GEC</span></span>
|
||||
</th>
|
||||
}
|
||||
}
|
||||
@if (Template != null && ShowExpandColumn && i == 0)
|
||||
{
|
||||
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<th role="columnheader" class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<span class="rz-column-title">
|
||||
@if(ShowExpandAll && ExpandMode == DataGridExpandMode.Multiple)
|
||||
{
|
||||
@@ -166,26 +166,26 @@
|
||||
}
|
||||
@if (FilterRowActive)
|
||||
{
|
||||
<tr @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<tr role="row" @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
@if (ShowGroupExpandColumn)
|
||||
{
|
||||
@foreach (var g in Groups)
|
||||
{
|
||||
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<th role="columnheader" class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<span class="rz-column-title"></span>
|
||||
</th>
|
||||
}
|
||||
}
|
||||
@if (Template != null && ShowExpandColumn )
|
||||
{
|
||||
<th class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<th role="columnheader" class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<span class="rz-column-title"></span>
|
||||
</th>
|
||||
}
|
||||
@foreach (var column in visibleColumns)
|
||||
{
|
||||
var filterMode = column.FilterMode ?? FilterMode;
|
||||
<th colspan="@column.GetColSpan()" class="@($"rz-unselectable-text {getFrozenColumnClass(column, visibleColumns)} {column.HeaderCssClass}")" scope="col" style="@column.GetStyle(true, true)">
|
||||
<th role="columnheader" colspan="@column.GetColSpan()" class="@($"rz-unselectable-text {getFrozenColumnClass(column, visibleColumns)} {column.HeaderCssClass}")" scope="col" style="@column.GetStyle(true, true)">
|
||||
@if (allColumns.All(c => c.Parent == null) && AllowFiltering && column.Filterable && column.Columns == null && (!string.IsNullOrEmpty(column.GetFilterProperty()) || column.FilterTemplate != null))
|
||||
{
|
||||
if(filterMode == FilterMode.Simple || filterMode == FilterMode.SimpleWithMenu)
|
||||
@@ -198,7 +198,7 @@
|
||||
</tr>
|
||||
}
|
||||
</thead>
|
||||
<tbody>
|
||||
<tbody role="rowgroup">
|
||||
@if (Data != null)
|
||||
{
|
||||
@if (!ShowEmptyMessage || Count > 0 && (IsVirtualizationAllowed() ? Count > 0 && Data.Count() > 0 : true) || LoadData.HasDelegate && Data.Count() > 0 || itemsToInsert.Count > 0)
|
||||
@@ -209,8 +209,8 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<tr class=" rz-datatable-emptymessage-row" @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<td class="rz-datatable-emptymessage" colspan="@(visibleColumns.Sum(c => c.GetColSpan()) + (Template != null && ShowExpandColumn ? 1 : 0))">
|
||||
<tr role="row" class=" rz-datatable-emptymessage-row" @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<td role="gridcell" class="rz-datatable-emptymessage" colspan="@(visibleColumns.Sum(c => c.GetColSpan()) + (Template != null && ShowExpandColumn ? 1 : 0))">
|
||||
@if (EmptyTemplate != null)
|
||||
{
|
||||
@EmptyTemplate
|
||||
@@ -225,8 +225,8 @@
|
||||
}
|
||||
else
|
||||
{
|
||||
<tr class=" rz-datatable-emptymessage-row" @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<td class="rz-datatable-emptymessage" colspan="@(visibleColumns.Sum(c => c.GetColSpan()) + (Template != null && ShowExpandColumn ? 1 : 0) + Groups.Count)">
|
||||
<tr role="row" class=" rz-datatable-emptymessage-row" @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<td role="gridcell" class="rz-datatable-emptymessage" colspan="@(visibleColumns.Sum(c => c.GetColSpan()) + (Template != null && ShowExpandColumn ? 1 : 0) + Groups.Count)">
|
||||
@if (EmptyTemplate != null)
|
||||
{
|
||||
@EmptyTemplate
|
||||
@@ -242,24 +242,24 @@
|
||||
</tbody>
|
||||
@if (allColumns.Where(c => c.Visible && c.FooterTemplate != null).Any())
|
||||
{
|
||||
<tfoot class="rz-datatable-tfoot" @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<tfoot role="rowgroup" class="rz-datatable-tfoot" @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
@for (var i = 0; i < deepestChildColumnLevel + 1; i++)
|
||||
{
|
||||
<tr>
|
||||
<tr role="row">
|
||||
@if (i == 0) // Only add the th elements for the first row
|
||||
{
|
||||
@if (ShowGroupExpandColumn)
|
||||
{
|
||||
@foreach (var g in Groups)
|
||||
{
|
||||
<td class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<td role="gridcell" class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<span class="rz-column-title"></span>
|
||||
</td>
|
||||
}
|
||||
}
|
||||
@if (Template != null && ShowExpandColumn && i == 0)
|
||||
{
|
||||
<td class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<td role="gridcell" class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(deepestChildColumnLevel + 1)>
|
||||
<span class="rz-column-title"></span>
|
||||
</td>
|
||||
}
|
||||
@@ -621,7 +621,7 @@
|
||||
<text>
|
||||
@if (this.AllowCompositeDataCells ? RowIndex == column.GetLevel() : (column.Parent != null && RowIndex == column.GetLevel() || column.Columns == null))
|
||||
{
|
||||
<td @attributes="@CellAttributes" @oncontextmenu:preventDefault="@this.CellContextMenu.HasDelegate" @oncontextmenu:stopPropagation="@this.CellContextMenu.HasDelegate" @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<td role="gridcell" @attributes="@CellAttributes" @oncontextmenu:preventDefault="@this.CellContextMenu.HasDelegate" @oncontextmenu:stopPropagation="@this.CellContextMenu.HasDelegate" @onkeydown:stopPropagation="stopGuardKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
@if (this.Responsive)
|
||||
{
|
||||
<span class="rz-column-title">
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@typeparam TItem
|
||||
@if (RowIndex == Column.GetLevel())
|
||||
{
|
||||
<td rowspan="@(Column.GetRowSpan())" colspan="@(Column.GetColSpan())" @attributes="@Attributes" class="@CssClass" scope="col" style="@GetStyle()">
|
||||
<td role="gridcell" rowspan="@(Column.GetRowSpan())" colspan="@(Column.GetColSpan())" @attributes="@Attributes" class="@CssClass" scope="col" style="@GetStyle()">
|
||||
<span class="rz-column-footer">
|
||||
@if (Column.FooterTemplate != null)
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@typeparam TItem
|
||||
@if (RowIndex == Column.GetLevel())
|
||||
{
|
||||
<td rowspan="@(Column.GetRowSpan())" colspan="@(Column.GetColSpan())" @attributes="@Attributes" class="@CssClass" scope="col" style="@GetStyle()">
|
||||
<td role="gridcell" rowspan="@(Column.GetRowSpan())" colspan="@(Column.GetColSpan())" @attributes="@Attributes" class="@CssClass" scope="col" style="@GetStyle()">
|
||||
<span class="rz-column-footer">
|
||||
@if (Column.GroupFooterTemplate != null)
|
||||
{
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
@typeparam TItem
|
||||
@for (var i = 0; i < Grid.deepestChildColumnLevel + 1; i++)
|
||||
{
|
||||
<tr>
|
||||
<tr role="row">
|
||||
@if (i == 0) // Only add the th elements for the first row
|
||||
{
|
||||
@if (Grid.Template != null && Grid.ShowExpandColumn)
|
||||
{
|
||||
<td class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(Grid.deepestChildColumnLevel + 1)>
|
||||
<td role="gridcell" class="rz-col-icon rz-unselectable-text" scope="col" rowspan=@(Grid.deepestChildColumnLevel + 1)>
|
||||
<span class="rz-column-title"></span>
|
||||
</td>
|
||||
}
|
||||
}
|
||||
@for (var j = 0; j < GetLevel() + (Grid.ShowGroupExpandColumn ? 0 : -1) + Grid.Groups.Count - GetLevel(); j++)
|
||||
{
|
||||
<td class="rz-col-icon">
|
||||
<td role="gridcell" class="rz-col-icon">
|
||||
<span class="rz-column-title"></span>
|
||||
</td>
|
||||
}
|
||||
|
||||
@@ -11,20 +11,20 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
<tr class="rz-group-row" @attributes="@(rowArgs?.Item2)">
|
||||
<tr role="row" class="rz-group-row" @attributes="@(rowArgs?.Item2)">
|
||||
@if (Grid != null && Grid.ShowGroupExpandColumn)
|
||||
{
|
||||
@if (Group.GroupDescriptor != null)
|
||||
{
|
||||
@for (var i = 0; i < GetLevel(); i++)
|
||||
{
|
||||
<td class="rz-col-icon">
|
||||
<td role="gridcell" class="rz-col-icon">
|
||||
<span class="rz-column-title"></span>
|
||||
</td>
|
||||
}
|
||||
|
||||
}
|
||||
<td class="rz-col-icon">
|
||||
<td role="gridcell" class="rz-col-icon">
|
||||
<span class="rz-column-title"></span>
|
||||
@if (rowArgs?.Item1.Expandable == true)
|
||||
{
|
||||
@@ -37,7 +37,7 @@
|
||||
}
|
||||
</td>
|
||||
}
|
||||
<td colspan="@(TotalColumnCount + (Grid?.Groups.Count ?? 0) - 1 - Group.Level + ((Grid?.Template != null && Grid?.ShowExpandColumn == true) ? 1 : 0))">
|
||||
<td role="gridcell" colspan="@(TotalColumnCount + (Grid?.Groups.Count ?? 0) - 1 - Group.Level + ((Grid?.Template != null && Grid?.ShowExpandColumn == true) ? 1 : 0))">
|
||||
<span class="rz-cell-data">
|
||||
@if (Grid?.GroupHeaderTemplate != null)
|
||||
{
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
@if (RowIndex == Column.GetLevel())
|
||||
{
|
||||
<th rowspan="@(Column.GetRowSpan())" colspan="@(Column.GetColSpan())" @attributes="@Attributes" class="@CssClass"
|
||||
<th role="columnheader" rowspan="@(Column.GetRowSpan())" colspan="@(Column.GetColSpan())" @attributes="@Attributes" class="@CssClass"
|
||||
scope="col" style="@GetStyle()" data-column-index="@ColumnIndex" @onmouseup=@(args => Grid.EndColumnReorder(args, ColumnIndex))
|
||||
aria-sort="@(Grid.AllowSorting && Column.Sortable ? (Column.GetSortOrder() == SortOrder.Ascending ? "ascending" : Column.GetSortOrder() == SortOrder.Descending ? "descending" : "none") : null)">
|
||||
<div @onclick='@((args) => Grid.OnSort(args, Column))'>
|
||||
|
||||
@@ -7,23 +7,23 @@
|
||||
@{var firstLevel = Grid?.AllowCompositeDataCells == true ? 0 : (Grid?.deepestChildColumnLevel ?? 0); }
|
||||
@for(var i = firstLevel; (Grid?.AllowCompositeDataCells == true ? i <= (Grid?.deepestChildColumnLevel ?? 0) + 1 : i < (Grid?.deepestChildColumnLevel ?? 0) + 1); i++)
|
||||
{
|
||||
<tr class="@(Grid?.RowStyle(Item, Index) ?? "")" @attributes="@(rowArgs?.Item2)">
|
||||
<tr role="row" class="@(Grid?.RowStyle(Item, Index) ?? "")" @attributes="@(rowArgs?.Item2)">
|
||||
@if (Grid?.ShowGroupExpandColumn == true)
|
||||
{
|
||||
@foreach(var g in Grid.Groups)
|
||||
{
|
||||
@if (i == firstLevel)
|
||||
{
|
||||
<td class="rz-col-icon" rowspan="@((Grid?.AllowCompositeDataCells == true ? ((Grid?.deepestChildColumnLevel ?? 0) + 1) : 1))">
|
||||
<td role="gridcell" class="rz-col-icon" rowspan="@((Grid?.AllowCompositeDataCells == true ? ((Grid?.deepestChildColumnLevel ?? 0) + 1) : 1))">
|
||||
<span class="rz-column-title"></span>
|
||||
</td>
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@if (Grid?.Template != null && Grid?.ShowExpandColumn == true && i == firstLevel)
|
||||
{
|
||||
<td class="rz-col-icon" rowspan="@((Grid?.AllowCompositeDataCells == true ? ((Grid?.deepestChildColumnLevel ?? 0) + 1) : 1))">
|
||||
<td role="gridcell" class="rz-col-icon" rowspan="@((Grid?.AllowCompositeDataCells == true ? ((Grid?.deepestChildColumnLevel ?? 0) + 1) : 1))">
|
||||
<span class="rz-column-title"></span>
|
||||
@if (rowArgs?.Item1.Expandable == true && !(Grid?.LoadChildData.HasDelegate ?? false))
|
||||
{
|
||||
@@ -90,8 +90,8 @@
|
||||
{
|
||||
@if (Grid.IsRowInEditMode(Item) && Grid.EditTemplate != null)
|
||||
{
|
||||
<tr class="rz-expanded-row-content" @onkeydown:stopPropagation="stopKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<td colspan="@(Columns.Sum(c => c.GetColSpan()) + (Grid.ShowExpandColumn ? 1 : 0) + Grid.Groups.Count)">
|
||||
<tr role="row" class="rz-expanded-row-content" @onkeydown:stopPropagation="stopKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<td role="gridcell" colspan="@(Columns.Sum(c => c.GetColSpan()) + (Grid.ShowExpandColumn ? 1 : 0) + Grid.Groups.Count)">
|
||||
<div class="rz-expanded-row-template" style="position:sticky">
|
||||
<CascadingValue Value=@EditContext>
|
||||
<CascadingValue Value=this>
|
||||
@@ -104,8 +104,8 @@
|
||||
}
|
||||
else if (Grid.Template != null)
|
||||
{
|
||||
<tr class="rz-expanded-row-content" @onkeydown:stopPropagation="stopKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<td colspan="@(Columns.Sum(c => c.GetColSpan()) + (Grid.ShowExpandColumn ? 1 : 0) + Grid.Groups.Count)">
|
||||
<tr role="row" class="rz-expanded-row-content" @onkeydown:stopPropagation="stopKeydownPropagation" @onkeydown="OnGuardKeyDown">
|
||||
<td role="gridcell" colspan="@(Columns.Sum(c => c.GetColSpan()) + (Grid.ShowExpandColumn ? 1 : 0) + Grid.Groups.Count)">
|
||||
<div class="rz-expanded-row-template" style="position:sticky">
|
||||
@Grid.Template(Item)
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user