@shopify/polaris
Version:
Shopify’s product component library
75 lines (74 loc) • 3.95 kB
JavaScript
import React from 'react';
import { ArrowLeftMinor, ArrowRightMinor } from '@shopify/polaris-icons';
import { TextStyle } from '../TextStyle';
import { classNames } from '../../utilities/css';
import { useI18n } from '../../utilities/i18n';
import { isInputFocused } from '../../utilities/is-input-focused';
import { Icon } from '../Icon';
import { UnstyledLink } from '../UnstyledLink';
import { Tooltip } from '../Tooltip';
import { KeypressListener } from '../KeypressListener';
import { handleMouseUpByBlurring } from '../../utilities/focus';
import styles from './Pagination.scss';
export function Pagination({ hasNext, hasPrevious, nextURL, previousURL, onNext, onPrevious, nextTooltip, previousTooltip, nextKeys, previousKeys, plain, accessibilityLabel, label, }) {
const i18n = useI18n();
const node = React.createRef();
const navLabel = accessibilityLabel || i18n.translate('Polaris.Pagination.pagination');
const className = classNames(styles.Pagination, plain && styles.plain);
const previousClassName = classNames(styles.Button, !label && styles.PreviousButton);
const nextClassName = classNames(styles.Button, !label && styles.NextButton);
const previousButton = previousURL ? (<UnstyledLink className={previousClassName} url={previousURL} onMouseUp={handleMouseUpByBlurring} aria-label={i18n.translate('Polaris.Pagination.previous')} id="previousURL">
<Icon source={ArrowLeftMinor}/>
</UnstyledLink>) : (<button onClick={onPrevious} type="button" onMouseUp={handleMouseUpByBlurring} className={previousClassName} aria-label={i18n.translate('Polaris.Pagination.previous')} disabled={!hasPrevious}>
<Icon source={ArrowLeftMinor}/>
</button>);
const nextButton = nextURL ? (<UnstyledLink className={nextClassName} url={nextURL} onMouseUp={handleMouseUpByBlurring} aria-label={i18n.translate('Polaris.Pagination.next')} id="nextURL">
<Icon source={ArrowRightMinor}/>
</UnstyledLink>) : (<button onClick={onNext} type="button" onMouseUp={handleMouseUpByBlurring} className={nextClassName} aria-label={i18n.translate('Polaris.Pagination.next')} disabled={!hasNext}>
<Icon source={ArrowRightMinor}/>
</button>);
const constructedPrevious = previousTooltip && hasPrevious ? (<Tooltip content={previousTooltip}>{previousButton}</Tooltip>) : (previousButton);
const constructedNext = nextTooltip && hasNext ? (<Tooltip content={nextTooltip}>{nextButton}</Tooltip>) : (nextButton);
const previousButtonEvents = previousKeys &&
(previousURL || onPrevious) &&
hasPrevious &&
previousKeys.map((key) => (<KeypressListener key={key} keyCode={key} handler={previousURL
? handleCallback(clickPaginationLink('previousURL', node))
: handleCallback(onPrevious)}/>));
const nextButtonEvents = nextKeys &&
(nextURL || onNext) &&
hasNext &&
nextKeys.map((key) => (<KeypressListener key={key} keyCode={key} handler={nextURL
? handleCallback(clickPaginationLink('nextURL', node))
: handleCallback(onNext)}/>));
const labelTextMarkup = hasNext && hasPrevious ? (<TextStyle>{label}</TextStyle>) : (<TextStyle variation="subdued">{label}</TextStyle>);
const labelMarkup = label ? (<div className={styles.Label} aria-live="polite">
{labelTextMarkup}
</div>) : null;
return (<nav className={className} aria-label={navLabel} ref={node}>
{previousButtonEvents}
{constructedPrevious}
{labelMarkup}
{nextButtonEvents}
{constructedNext}
</nav>);
}
function clickPaginationLink(id, node) {
return () => {
if (node.current == null) {
return;
}
const link = node.current.querySelector(`#${id}`);
if (link) {
link.click();
}
};
}
function handleCallback(fn) {
return () => {
if (isInputFocused()) {
return;
}
fn();
};
}