UNPKG

wix-style-react

Version:
191 lines • 9.83 kB
import * as React from 'react'; import { st, classes } from './PaginationCore.st.css'; import { DataHooks } from './constants'; import { calculateWidth, getId, measureAndSetRootMinWidth } from './utils'; import { PageStrip } from './PageStrip'; import { filterDataProps } from '../../utils/propsUtils'; const upperCaseFirst = (str) => str[0].toUpperCase() + str.slice(1); class PaginationCore extends React.Component { constructor() { super(...arguments); this.getMaxPagesToShow = () => { if (this.props.maxPagesToShow) { return this.props.maxPagesToShow; } if (this.props.responsive) { return 20; } return 7; }; this.state = { pageInputValue: String(this.props.currentPage), pageInputHasError: false, }; this.handlePageInputChange = (e) => { this.setState({ pageInputValue: e.target.value, pageInputHasError: false, }); }; this.handlePageInputKeyDown = (event) => { // Enter if (event.key === 'Enter') { const page = Number(this.state.pageInputValue); if (page !== this.props.currentPage) { if (1 <= page && page <= this.props.totalPages) { this.props.onChange && this.props.onChange({ event, page }); } else { this.setState({ pageInputHasError: true }); } } } }; this.handlePageInputBlur = () => { this.setState({ pageInputValue: String(this.props.currentPage), pageInputHasError: false, }); }; this.handlePageClick = (event, page) => { this.props.onChange && this.props.onChange({ event, page }); }; this.handlePageKeyDown = (event, page) => { // Enter or Space if (event.key === 'Enter' || event.key === 'Space') { this.props.onChange && this.props.onChange({ event, page }); } }; } updateRootMinWidth() { this.rootNode && this.props.paginationMode && measureAndSetRootMinWidth(this.rootNode, this.props.paginationMode, this.props.id); } componentDidMount() { this.props.updateResponsiveLayout && this.updateRootMinWidth(); } componentDidUpdate() { this.props.updateResponsiveLayout && this.updateRootMinWidth(); } getId(elementName = '') { return getId(this.props.id, elementName); } renderPageStrip() { return (React.createElement(PageStrip, { id: this.props.id, totalPages: this.props.totalPages || 0, currentPage: this.props.currentPage || 0, maxPagesToShow: this.getMaxPagesToShow() || 0, showFirstPage: !!this.props.showFirstPage, showLastPage: !!this.props.showLastPage, responsive: !!this.props.responsive, pageUrl: this.props.pageUrl, gapLabel: this.props.gapLabel || '', onPageClick: this.handlePageClick, onPageKeyDown: this.handlePageKeyDown, updateResponsiveLayout: this.props.updateResponsiveLayout, disabled: !!this.props.disabled })); } renderPages() { switch (this.props.paginationMode) { case "input" /* PaginationCoreMode.Input */: return this.renderPageForm(); case "compact" /* PaginationCoreMode.Compact */: return this.renderPageCompact(); case "pages" /* PaginationCoreMode.Pages */: default: return this.renderPageStrip(); } } renderPageCompact() { return (React.createElement("div", { "data-hook": DataHooks.pageCompact, id: this.getId('pageCompact'), className: classes.compact }, React.createElement("span", { id: this.getId('currentPage'), "data-hook": DataHooks.currentPage }, this.props.currentPage), React.createElement("span", { id: this.getId('slash'), className: classes.slash, "data-hook": DataHooks.slashLabel }, this.props.slashLabel), React.createElement("span", { id: this.getId('totalPages'), "data-hook": DataHooks.totalPages }, this.props.totalPages))); } renderPageForm() { return (React.createElement("div", { "data-hook": DataHooks.pageForm, id: this.getId('pageForm'), className: classes.pageForm, dir: "ltr" }, React.createElement("input", { id: this.getId('pageInput'), "data-hook": DataHooks.pageInput, type: "number", className: classes.pageInput, min: 1, max: this.props.totalPages, value: this.state.pageInputValue, disabled: this.props.disabled, onChange: this.handlePageInputChange, onKeyDown: this.handlePageInputKeyDown, "aria-label": 'Page number, select a number between 1 and ' + this.props.totalPages, onBlur: this.handlePageInputBlur, style: { width: calculateWidth(this.props.totalPages) } }), this.props.showInputModeTotalPages && [ React.createElement("span", { key: "slash", id: this.getId('slash'), className: classes.slash }, this.props.slashLabel), React.createElement("span", { key: "total-pages", id: this.getId('totalPages'), "data-hook": DataHooks.totalPages, className: classes.totalPages }, this.props.totalPages), ])); } renderEmptyButton(type) { let btnClass = ''; switch (type) { case "previous" /* ButtonType.Prev */: { btnClass = classes.emptyButtonPrevious; break; } case "next" /* ButtonType.Next */: { btnClass = classes.emptyButtonNext; break; } default: } return (React.createElement("div", { "data-hook": DataHooks[type], className: st(classes.emptyButton, btnClass) })); } renderNavButton(type) { const { currentPage, totalPages, pageUrl } = this.props; const disabled = this.props.disabled || ((type === "first" /* ButtonType.First */ || type === "previous" /* ButtonType.Prev */) && (currentPage || 0) <= 1) || ((type === "last" /* ButtonType.Last */ || type === "next" /* ButtonType.Next */) && (currentPage || 0) >= totalPages); const [btnClass, label, page] = { ["previous" /* ButtonType.Prev */]: [ classes.navButtonPrevious, this.props.previousLabel, (currentPage || 0) - 1, ], ["next" /* ButtonType.Next */]: [ classes.navButtonNext, this.props.nextLabel, (currentPage || 0) + 1, ], ["first" /* ButtonType.First */]: [classes.navButtonFirst, this.props.firstLabel, 1], ["last" /* ButtonType.Last */]: [ classes.navButtonLast, this.props.lastLabel, totalPages, ], }[type]; return (React.createElement("a", { "data-hook": DataHooks[type], id: this.getId('navButton' + upperCaseFirst(type)), className: st(classes.navButton, { disabled }, btnClass), "aria-label": upperCaseFirst(type) + ' Page', "aria-disabled": disabled, tabIndex: disabled || pageUrl ? undefined : 0, onClick: disabled ? undefined : event => this.handlePageClick(event, page), onKeyDown: disabled ? undefined : event => this.handlePageKeyDown(event, page), href: !disabled && pageUrl ? pageUrl(page) : undefined }, label)); } UNSAFE_componentWillReceiveProps(nextProps) { this.setState({ pageInputValue: String(nextProps.currentPage), pageInputHasError: false, }); } render() { const { disabled, showFirstLastNavButtons, showNextLabel, showPreviousLabel, width, style: inlineStyle, } = this.props; const styleStates = { disabled, error: this.state.pageInputHasError, }; return (React.createElement("nav", { ref: el => (this.rootNode = el), id: this.getId(''), "aria-label": "PaginationCore Navigation", "aria-disabled": disabled, dir: this.props.rtl ? 'rtl' : undefined, onClick: this.props.onClick, onDoubleClick: this.props.onDoubleClick, onMouseEnter: this.props.onMouseEnter, onMouseLeave: this.props.onMouseLeave, style: inlineStyle || { width }, className: st(classes.root, styleStates, this.props.className), ...filterDataProps(this.props) }, showFirstLastNavButtons && this.renderNavButton("first" /* ButtonType.First */), showPreviousLabel ? this.renderNavButton("previous" /* ButtonType.Prev */) : this.renderEmptyButton("previous" /* ButtonType.Prev */), this.renderPages(), showNextLabel ? this.renderNavButton("next" /* ButtonType.Next */) : this.renderEmptyButton("next" /* ButtonType.Next */), showFirstLastNavButtons && this.renderNavButton("last" /* ButtonType.Last */))); } } PaginationCore.displayName = 'PaginationCore'; PaginationCore.defaultProps = { currentPage: 1, showFirstLastNavButtons: false, showFirstPage: false, showLastPage: false, showNextLabel: true, showPreviousLabel: true, responsive: false, paginationMode: 'pages', showInputModeTotalPages: false, disabled: false, // dir="rtl" automatically flips the direction of less-than and more-than signs. // If we decide to use different labels we need to add conditional logic. firstLabel: '<<', lastLabel: '>>', previousLabel: '<', nextLabel: '>', gapLabel: '...', slashLabel: '\u00A0/\u00A0', }; export default PaginationCore; //# sourceMappingURL=PaginationCore.js.map