Skip to content

Commit fd6bbe0

Browse files
authored
Pagination: fix accessibility with keyboard (#6499)
1 parent dd156bc commit fd6bbe0

4 files changed

Lines changed: 79 additions & 3 deletions

File tree

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
@inherits Blazorise.PaginationLink
22
@if ( ParentPaginationItemState.Disabled )
33
{
4-
<a @ref="@ElementRef" id="@ElementId" class="@ClassNames" style="@StyleNames" aria-current="@AriaCurrent" disabled @onclick="@ClickHandler" @attributes="@Attributes">@ChildContent</a>
4+
<a @ref="@ElementRef" id="@ElementId" class="@ClassNames" style="@StyleNames" aria-current="@AriaCurrent" aria-disabled="@AriaDisabled" tabindex="@GetTabIndex()" @onclick="@ClickHandler" @attributes="@Attributes">@ChildContent</a>
55
}
66
else
77
{
8-
<a @ref="@ElementRef" id="@ElementId" class="@ClassNames" style="@StyleNames" aria-current="@AriaCurrent" @onclick="@ClickHandler" @attributes="@Attributes">@ChildContent</a>
8+
<a @ref="@ElementRef" id="@ElementId" class="@ClassNames" style="@StyleNames" aria-current="@AriaCurrent" aria-disabled="@AriaDisabled" tabindex="@GetTabIndex()" @onclick="@ClickHandler" @attributes="@Attributes">@ChildContent</a>
99
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
@namespace Blazorise
22
@inherits BaseComponent
3-
<a @ref="@ElementRef" id="@ElementId" class="@ClassNames" style="@StyleNames" aria-current="@AriaCurrent" @onclick="@ClickHandler" @attributes="@Attributes">@ChildContent</a>
3+
<a @ref="@ElementRef" id="@ElementId" class="@ClassNames" style="@StyleNames" aria-current="@AriaCurrent" aria-disabled="@AriaDisabled" tabindex="@GetTabIndex()" @onclick="@ClickHandler" @attributes="@Attributes">@ChildContent</a>

Source/Blazorise/Components/Pagination/PaginationLink.razor.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ protected Task ClickHandler( MouseEventArgs eventArgs )
4848
return Clicked.InvokeAsync( Page );
4949
}
5050

51+
/// <summary>
52+
/// Gets the tab index for keyboard accessibility.
53+
/// </summary>
54+
/// <returns>-1 if disabled; otherwise 0.</returns>
55+
protected int GetTabIndex()
56+
=> ParentPaginationItemState.Disabled ? -1 : 0;
57+
5158
#endregion
5259

5360
#region Properties
@@ -62,6 +69,11 @@ protected Task ClickHandler( MouseEventArgs eventArgs )
6269
/// </summary>
6370
protected string AriaCurrent => ParentPaginationItemState.Active ? "page" : null;
6471

72+
/// <summary>
73+
/// Gets the aria-disabled attribute value.
74+
/// </summary>
75+
protected string AriaDisabled => ParentPaginationItemState.Disabled ? "true" : null;
76+
6577
/// <summary>
6678
/// Occurs when the item link is clicked.
6779
/// </summary>
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using Bunit;
2+
using Microsoft.AspNetCore.Components;
3+
using Xunit;
4+
5+
namespace Blazorise.Tests.Components;
6+
7+
public class PaginationComponentTest : TestContext
8+
{
9+
public PaginationComponentTest()
10+
{
11+
Services.AddBlazoriseTests().AddBootstrapProviders().AddEmptyIconProvider().AddTestData();
12+
}
13+
14+
[Fact]
15+
public void EnabledPaginationLink_ShouldBeTabbable()
16+
{
17+
var cut = RenderPaginationLink();
18+
19+
var link = cut.Find( "a" );
20+
21+
Assert.Equal( "0", link.GetAttribute( "tabindex" ) );
22+
Assert.False( link.HasAttribute( "aria-disabled" ) );
23+
}
24+
25+
[Fact]
26+
public void DisabledPaginationLink_ShouldNotBeTabbable()
27+
{
28+
var cut = RenderPaginationLink( disabled: true );
29+
30+
var link = cut.Find( "a" );
31+
32+
Assert.Equal( "-1", link.GetAttribute( "tabindex" ) );
33+
Assert.Equal( "true", link.GetAttribute( "aria-disabled" ) );
34+
}
35+
36+
[Fact]
37+
public void ActivePaginationLink_ShouldSetAriaCurrent()
38+
{
39+
var cut = RenderPaginationLink( active: true );
40+
41+
var link = cut.Find( "a" );
42+
43+
Assert.Equal( "page", link.GetAttribute( "aria-current" ) );
44+
}
45+
46+
private IRenderedComponent<Pagination> RenderPaginationLink( bool disabled = false, bool active = false )
47+
{
48+
return RenderComponent<Pagination>( parameters => parameters
49+
.AddChildContent( builder =>
50+
{
51+
builder.OpenComponent<PaginationItem>( 0 );
52+
builder.AddAttribute( 1, nameof( PaginationItem.Disabled ), disabled );
53+
builder.AddAttribute( 2, nameof( PaginationItem.Active ), active );
54+
builder.AddAttribute( 3, nameof( PaginationItem.ChildContent ), (RenderFragment)( childBuilder =>
55+
{
56+
childBuilder.OpenComponent<PaginationLink>( 0 );
57+
childBuilder.AddAttribute( 1, nameof( PaginationLink.Page ), "1" );
58+
childBuilder.AddAttribute( 2, nameof( PaginationLink.ChildContent ), (RenderFragment)( contentBuilder => contentBuilder.AddContent( 0, "1" ) ) );
59+
childBuilder.CloseComponent();
60+
} ) );
61+
builder.CloseComponent();
62+
} ) );
63+
}
64+
}

0 commit comments

Comments
 (0)