Skip to content

Commit 445ca60

Browse files
committed
fix: allow tab navigation after disabling focused pagination items
1 parent 5d0e76b commit 445ca60

2 files changed

Lines changed: 53 additions & 2 deletions

File tree

‎src/PaginationItem.tsx‎

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import React from 'react';
2+
import isEnterOrSpaceKey from './isEnterOrSpaceKey';
23

34
interface PaginationItemProps extends React.LiHTMLAttributes<HTMLLIElement> {
45
disabled?: boolean;
@@ -59,7 +60,9 @@ const PaginationItem: React.FC<PaginationItemProps> = ({
5960
}}
6061
onKeyDown={(event) => {
6162
if (controlDisabled) {
62-
event.preventDefault();
63+
if (isEnterOrSpaceKey(event)) {
64+
event.preventDefault();
65+
}
6366
return;
6467
}
6568
if (
@@ -103,7 +106,9 @@ const PaginationItem: React.FC<PaginationItemProps> = ({
103106
},
104107
onKeyDown: (event: React.KeyboardEvent<HTMLElement>) => {
105108
if (controlDisabled) {
106-
event.preventDefault();
109+
if (isEnterOrSpaceKey(event)) {
110+
event.preventDefault();
111+
}
107112
return;
108113
}
109114
controlProps.onKeyDown?.(event);

‎tests/itemRender-compat.test.tsx‎

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,52 @@ describe('itemRender interaction compatibility', () => {
5050
expect(onChange).not.toHaveBeenCalled();
5151
});
5252

53+
it.each([
54+
['default', false],
55+
['default', true],
56+
['opaque', false],
57+
['opaque', true],
58+
] as const)(
59+
'allows Tab navigation after disabling a focused %s item (shift=%s)',
60+
async (kind, shift) => {
61+
const Label = () => <span>page</span>;
62+
const onChange = jest.fn();
63+
const renderPagination = (disabled: boolean) => (
64+
<div>
65+
<button data-testid="before">Before pagination</button>
66+
<Pagination
67+
total={100}
68+
disabled={disabled}
69+
onChange={onChange}
70+
itemRender={kind === 'opaque' ? () => <Label /> : undefined}
71+
/>
72+
<button data-testid="after">After pagination</button>
73+
</div>
74+
);
75+
const { container, rerender, getByTestId } = render(
76+
renderPagination(false),
77+
);
78+
const item = container.querySelector<HTMLElement>(
79+
'.rc-pagination-item-2',
80+
);
81+
const control = kind === 'opaque' ? item : item.querySelector('a');
82+
control.focus();
83+
expect(control).toHaveFocus();
84+
85+
rerender(renderPagination(true));
86+
expect(control).toHaveFocus();
87+
expect(control).toHaveAttribute('tabindex', '-1');
88+
// Disabling activation must still allow the focused item to be left.
89+
expect(fireEvent.keyDown(control, { key: 'Enter' })).toBe(false);
90+
expect(fireEvent.keyDown(control, { key: ' ' })).toBe(false);
91+
expect(onChange).not.toHaveBeenCalled();
92+
93+
await userEvent.tab({ shift });
94+
expect(getByTestId(shift ? 'before' : 'after')).toHaveFocus();
95+
expect(onChange).not.toHaveBeenCalled();
96+
},
97+
);
98+
5399
it.each([
54100
['prev', 49],
55101
['next', 51],

0 commit comments

Comments
 (0)