Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions src/Options.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { KeyCode } from '@rc-component/util';
import React from 'react';
import isEnterOrSpaceKey from './isEnterOrSpaceKey';
import type { PaginationLocale } from './interface';

export type SizeChangerRender = (info: {
Expand Down Expand Up @@ -91,6 +92,17 @@ const Options: React.FC<OptionsProps> = (props) => {
}
};

const preventInnerKeyDown = (e: React.KeyboardEvent<HTMLSpanElement>) => {
if (disabled && isEnterOrSpaceKey(e)) {
e.preventDefault();
}
};

const unfocusableWhenDisabled = (node: React.ReactNode) =>
disabled && React.isValidElement<React.HTMLAttributes<HTMLElement>>(node)
? React.cloneElement(node, { tabIndex: -1 })
: node;

const getPageSizeOptions = () => {
if (
pageSizeOptions.some(
Expand Down Expand Up @@ -150,8 +162,8 @@ const Options: React.FC<OptionsProps> = (props) => {
{locale.jump_to_confirm}
</button>
) : (
<span onClick={go} onKeyUp={go}>
{goButton}
<span onClick={go} onKeyUp={go} onKeyDown={preventInnerKeyDown}>
{unfocusableWhenDisabled(goButton)}
</span>
);
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
Expand Down
13 changes: 10 additions & 3 deletions src/Pager.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ export interface PagerProps extends Pick<PaginationProps, 'itemRender'> {
className?: string;
style?: React.CSSProperties;
showTitle: boolean;
disabled?: boolean;
onClick?: (page: number) => void;
onKeyPress?: (
e: React.KeyboardEvent<HTMLLIElement>,
Expand All @@ -28,6 +29,7 @@ const Pager: React.FC<PagerProps> = (props) => {
className,
style,
showTitle,
disabled,
onClick,
onKeyPress,
itemRender,
Expand Down Expand Up @@ -59,21 +61,26 @@ const Pager: React.FC<PagerProps> = (props) => {
{page}
</a>,
);
const pagerContent =
disabled && React.isValidElement<React.HTMLAttributes<HTMLElement>>(pager)
? React.cloneElement(pager, { tabIndex: -1 })
: pager;
const pagerLabel = `${pageLabel} ${page}`.trim();

return pager ? (
return pagerContent ? (
<li
title={showTitle ? String(page) : null}
className={cls}
style={style}
onClick={handleClick}
onKeyDown={handleKeyPress}
tabIndex={0}
tabIndex={disabled ? null : 0}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
role="button"
aria-label={pagerLabel}
aria-current={active ? 'page' : undefined}
aria-disabled={disabled || undefined}
>
{pager}
{pagerContent}
</li>
) : null;
};
Expand Down
72 changes: 50 additions & 22 deletions src/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ const Pagination: React.FC<PaginationProps> = (props) => {
),
);
return React.isValidElement<HTMLButtonElement>(prevButton)
? React.cloneElement(prevButton, { disabled: !hasPrev })
? React.cloneElement(prevButton, { disabled: !hasPrev || disabled })
: prevButton;
}

Expand All @@ -312,7 +312,7 @@ const Pagination: React.FC<PaginationProps> = (props) => {
),
);
return React.isValidElement<HTMLButtonElement>(nextButton)
? React.cloneElement(nextButton, { disabled: !hasNext })
? React.cloneElement(nextButton, { disabled: !hasNext || disabled })
: nextButton;
}

Expand All @@ -322,6 +322,28 @@ const Pagination: React.FC<PaginationProps> = (props) => {
}
}

function preventInnerDefault(event: React.MouseEvent<HTMLUListElement>) {
if (disabled) {
event.preventDefault();
}
}

function preventInnerKeyDown(event: React.KeyboardEvent<HTMLElement>) {
if (disabled && isEnterOrSpaceKey(event)) {
event.preventDefault();
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}

function withUnfocusable(node: React.ReactNode) {
if (
disabled &&
React.isValidElement<React.HTMLAttributes<HTMLElement>>(node)
) {
return React.cloneElement(node, { tabIndex: -1 });
}
return node;
}

let jumpPrev: React.ReactElement<PagerProps> = null;

const dataOrAriaAttributeProps = pickAttrs(props, {
Expand Down Expand Up @@ -360,6 +382,7 @@ const Pagination: React.FC<PaginationProps> = (props) => {
page: -1,
className: paginationClassNames?.item,
style: styles?.item,
disabled,
};

const prevPage = current - 1 > 0 ? current - 1 : 0;
Expand All @@ -377,14 +400,23 @@ const Pagination: React.FC<PaginationProps> = (props) => {
if (goButton) {
if (typeof goButton === 'boolean') {
gotoButton = (
<button type="button" onClick={handleGoTO} onKeyUp={handleGoTO}>
<button
type="button"
onClick={handleGoTO}
onKeyUp={handleGoTO}
disabled={disabled}
>
{locale.jump_to_confirm}
</button>
);
} else {
gotoButton = (
<span onClick={handleGoTO} onKeyUp={handleGoTO}>
{goButton}
<span
onClick={handleGoTO}
onKeyUp={handleGoTO}
onKeyDown={preventInnerKeyDown}
>
{withUnfocusable(goButton)}
</span>
);
}
Expand Down Expand Up @@ -476,33 +508,35 @@ const Pagination: React.FC<PaginationProps> = (props) => {
<li
key="prev"
onClick={jumpPrevHandle}
tabIndex={0}
tabIndex={disabled ? null : 0}
onKeyDown={runIfEnterJumpPrev}
className={clsx(`${prefixCls}-jump-prev`, {
[`${prefixCls}-jump-prev-custom-icon`]:
isReactRenderable(jumpPrevIcon),
})}
role="button"
aria-label={prevItemTitle}
aria-disabled={disabled || undefined}
>
{jumpPrevContent}
{withUnfocusable(jumpPrevContent)}
</li>
) : null;

jumpNext = isReactRenderable(jumpNextContent) ? (
<li
key="next"
onClick={jumpNextHandle}
tabIndex={0}
tabIndex={disabled ? null : 0}
onKeyDown={runIfEnterJumpNext}
className={clsx(`${prefixCls}-jump-next`, {
[`${prefixCls}-jump-next-custom-icon`]:
isReactRenderable(jumpNextIcon),
})}
role="button"
aria-label={nextItemTitle}
aria-disabled={disabled || undefined}
>
{jumpNextContent}
{withUnfocusable(jumpNextContent)}
</li>
) : null;
}
Expand Down Expand Up @@ -570,7 +604,7 @@ const Pagination: React.FC<PaginationProps> = (props) => {

let prev = renderPrev(prevPage);
if (isReactRenderable(prev)) {
const prevDisabled = !hasPrev || !allPages;
const prevDisabled = !hasPrev || !allPages || !!disabled;
prev = (
<li
onClick={prevHandle}
Expand All @@ -584,27 +618,19 @@ const Pagination: React.FC<PaginationProps> = (props) => {
role="button"
aria-label={locale.prev_page}
>
{prev}
{withUnfocusable(prev)}
</li>
);
}

let next = renderNext(nextPage);
if (isReactRenderable(next)) {
let nextDisabled: boolean, nextTabIndex: number | null;

if (simple) {
nextDisabled = !hasNext;
nextTabIndex = hasPrev ? 0 : null;
} else {
nextDisabled = !hasNext || !allPages;
nextTabIndex = nextDisabled ? null : 0;
}
const nextDisabled = !hasNext || !allPages || !!disabled;

next = (
<li
onClick={nextHandle}
tabIndex={nextTabIndex}
tabIndex={nextDisabled ? null : 0}
onKeyDown={runIfEnterNext}
className={clsx(`${prefixCls}-next`, paginationClassNames?.item, {
[`${prefixCls}-disabled`]: nextDisabled,
Expand All @@ -614,7 +640,7 @@ const Pagination: React.FC<PaginationProps> = (props) => {
role="button"
aria-label={locale.next_page}
>
{next}
{withUnfocusable(next)}
</li>
);
}
Expand All @@ -632,7 +658,9 @@ const Pagination: React.FC<PaginationProps> = (props) => {
className={cls}
style={style}
ref={paginationRef}
onClick={preventInnerDefault}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
{...dataOrAriaAttributeProps}
aria-disabled={disabled || undefined}
>
{totalText}
{prev}
Expand Down
Loading