UNPKG

@douyinfe/semi-ui

Version:

A modern, comprehensive, flexible design system and UI library. Connect DesignOps & DevOps. Quickly build beautiful React apps. Maintained by Douyin-fe team.

480 lines (478 loc) 17.6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = void 0; var _noop2 = _interopRequireDefault(require("lodash/noop")); var _react = _interopRequireDefault(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _propTypes = _interopRequireDefault(require("prop-types")); var _reactWindow = require("react-window"); var _foundation = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/pagination/foundation")); var _constants = require("@douyinfe/semi-foundation/lib/cjs/pagination/constants"); require("@douyinfe/semi-foundation/lib/cjs/pagination/pagination.css"); var _constants2 = require("@douyinfe/semi-foundation/lib/cjs/popover/constants"); var _semiIcons = require("@douyinfe/semi-icons"); var _warning = _interopRequireDefault(require("@douyinfe/semi-foundation/lib/cjs/utils/warning")); var _context = _interopRequireDefault(require("../configProvider/context")); var _localeConsumer = _interopRequireDefault(require("../locale/localeConsumer")); var _index = _interopRequireDefault(require("../select/index")); var _index2 = _interopRequireDefault(require("../inputNumber/index")); var _baseComponent = _interopRequireDefault(require("../_base/baseComponent")); var _index3 = _interopRequireDefault(require("../popover/index")); function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; } var __rest = void 0 && (void 0).__rest || function (s, e) { var t = {}; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p]; if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]]; } return t; }; /* eslint-disable jsx-a11y/no-noninteractive-element-to-interactive-role */ const prefixCls = _constants.cssClasses.PREFIX; const { Option } = _index.default; class Pagination extends _baseComponent.default { constructor(props) { super(props); const total = props.total; const pageSize = props.pageSize || props.pageSizeOpts[0] || _constants.numbers.DEFAULT_PAGE_SIZE; // Use pageSize first, use the first of pageSizeOpts when not, use the default value when none const shouldFillAllNumber = props.size === 'small' && props.hoverShowPageSelect && !props.disabled; this.state = { total, showTotal: props.showTotal, currentPage: props.currentPage || props.defaultCurrentPage, pageSize, pageList: [], prevDisabled: false, nextDisabled: false, restLeftPageList: [], restRightPageList: [], quickJumpPage: '', allPageNumbers: shouldFillAllNumber ? Array.from({ length: Math.ceil(total / pageSize) }, (v, i) => i + 1) : [] // only need to count in smallPage mode, when props.size = small }; this.foundation = new _foundation.default(this.adapter); this.renderDefaultPage = this.renderDefaultPage.bind(this); this.renderSmallPage = this.renderSmallPage.bind(this); (0, _warning.default)(Boolean(props.showSizeChanger && props.hideOnSinglePage), '[Semi Pagination] You should not use showSizeChanger and hideOnSinglePage in ths same time. At this time, hideOnSinglePage no longer takes effect, otherwise there may be a problem that the switch entry disappears'); } get adapter() { return Object.assign(Object.assign({}, super.adapter), { setPageList: pageListState => { const { pageList, restLeftPageList, restRightPageList } = pageListState; this.setState({ pageList, restLeftPageList, restRightPageList }); }, setDisabled: (prevIsDisabled, nextIsDisabled) => { this.setState({ prevDisabled: prevIsDisabled, nextDisabled: nextIsDisabled }); }, updateTotal: total => this.setState({ total }), updatePageSize: pageSize => this.setState({ pageSize }), updateQuickJumpPage: quickJumpPage => this.setState({ quickJumpPage }), updateAllPageNumbers: allPageNumbers => this.setState({ allPageNumbers }), setCurrentPage: pageIndex => { this.setState({ currentPage: pageIndex }); }, registerKeyDownHandler: handler => { document.addEventListener('keydown', handler); }, unregisterKeyDownHandler: handler => { document.removeEventListener('keydown', handler); }, notifyPageChange: pageIndex => { this.props.onPageChange(pageIndex); }, notifyPageSizeChange: pageSize => { this.props.onPageSizeChange(pageSize); }, notifyChange: (pageIndex, pageSize) => { this.props.onChange(pageIndex, pageSize); } }); } componentDidMount() { this.foundation.init(); } componentWillUnmount() { this.foundation.destroy(); } componentDidUpdate(prevProps) { const pagerProps = { currentPage: this.props.currentPage, total: this.props.total, pageSize: this.props.pageSize }; let pagerHasChanged = false; let allPageNumberNeedUpdate = false; if (prevProps.currentPage !== this.props.currentPage) { pagerHasChanged = true; // this.foundation.updatePage(this.props.currentPage); } if (prevProps.total !== this.props.total) { pagerHasChanged = true; allPageNumberNeedUpdate = true; } if (prevProps.pageSize !== this.props.pageSize) { pagerHasChanged = true; allPageNumberNeedUpdate = true; } if (pagerHasChanged) { this.foundation.updatePage(pagerProps.currentPage, pagerProps.total, pagerProps.pageSize); } if (allPageNumberNeedUpdate) { this.foundation.updateAllPageNumbers(pagerProps.total, pagerProps.pageSize); } } renderPrevBtn() { const { prevText, disabled } = this.props; const { prevDisabled } = this.state; const isDisabled = prevDisabled || disabled; const preClassName = (0, _classnames.default)({ [`${prefixCls}-item`]: true, [`${prefixCls}-prev`]: true, [`${prefixCls}-item-disabled`]: isDisabled }); return /*#__PURE__*/_react.default.createElement("li", { role: "button", "aria-disabled": isDisabled ? true : false, "aria-label": "Previous", onClick: e => !isDisabled && this.foundation.goPrev(e), className: preClassName, "x-semi-prop": "prevText" }, prevText || /*#__PURE__*/_react.default.createElement(_semiIcons.IconChevronLeft, { size: "large" })); } renderNextBtn() { const { nextText, disabled } = this.props; const { nextDisabled } = this.state; const isDisabled = nextDisabled || disabled; const nextClassName = (0, _classnames.default)({ [`${prefixCls}-item`]: true, [`${prefixCls}-item-disabled`]: isDisabled, [`${prefixCls}-next`]: true }); return /*#__PURE__*/_react.default.createElement("li", { role: "button", "aria-disabled": isDisabled ? true : false, "aria-label": "Next", onClick: e => !isDisabled && this.foundation.goNext(e), className: nextClassName, "x-semi-prop": "nextText" }, nextText || /*#__PURE__*/_react.default.createElement(_semiIcons.IconChevronRight, { size: "large" })); } renderPageSizeSwitch(locale) { // rtl modify the default position const { direction } = this.context; const defaultPopoverPosition = direction === 'rtl' ? 'bottomRight' : 'bottomLeft'; const { showSizeChanger, popoverPosition = defaultPopoverPosition, disabled, popoverZIndex } = this.props; const { pageSize } = this.state; const switchCls = (0, _classnames.default)(`${prefixCls}-switch`); if (!showSizeChanger) { return null; } const newPageSizeOpts = this.foundation.pageSizeInOpts(); const pageSizeToken = locale.pageSize; // Display pageSize in a specific language format order const options = newPageSizeOpts.map(size => (/*#__PURE__*/_react.default.createElement(Option, { value: size, key: size }, /*#__PURE__*/_react.default.createElement("span", null, pageSizeToken.replace('${pageSize}', size.toString()))))); return /*#__PURE__*/_react.default.createElement("div", { className: switchCls }, /*#__PURE__*/_react.default.createElement(_index.default, { "aria-label": "Page size selector", disabled: disabled, onChange: newPageSize => this.foundation.changePageSize(newPageSize), value: pageSize, key: pageSize + pageSizeToken, position: popoverPosition || 'bottomRight', clickToHide: true, zIndex: popoverZIndex, dropdownClassName: `${prefixCls}-select-dropdown` }, options)); } renderQuickJump(locale) { const { showQuickJumper, disabled } = this.props; const { quickJumpPage, total, pageSize } = this.state; if (!showQuickJumper) { return null; } const totalPageNum = this.foundation._getTotalPageNumber(total, pageSize); const isDisabled = totalPageNum === 1 || disabled; const quickJumpCls = (0, _classnames.default)({ [`${prefixCls}-quickjump`]: true, [`${prefixCls}-quickjump-disabled`]: isDisabled }); return /*#__PURE__*/_react.default.createElement("div", { className: quickJumpCls }, /*#__PURE__*/_react.default.createElement("span", null, locale.jumpTo), /*#__PURE__*/_react.default.createElement(_index2.default, { value: quickJumpPage, className: `${prefixCls}-quickjump-input-number`, hideButtons: true, disabled: isDisabled, onBlur: e => this.foundation.handleQuickJumpBlur(), onEnterPress: e => this.foundation.handleQuickJumpEnterPress(e.target.value), onChange: v => this.foundation.handleQuickJumpNumberChange(v) }), /*#__PURE__*/_react.default.createElement("span", null, locale.page)); } renderPageList() { const { pageList, currentPage, restLeftPageList, restRightPageList } = this.state; const { popoverPosition, popoverZIndex, disabled } = this.props; return pageList.map((page, i) => { const pageListClassName = (0, _classnames.default)(`${prefixCls}-item`, { [`${prefixCls}-item-active`]: currentPage === page, [`${prefixCls}-item-all-disabled`]: disabled, [`${prefixCls}-item-all-disabled-active`]: currentPage === page && disabled // [`${prefixCls}-item-rest-opening`]: (i < 3 && isLeftRestHover && page ==='...') || (i > 3 && isRightRestHover && page === '...') }); const pageEl = /*#__PURE__*/_react.default.createElement("li", { key: `${page}${i}`, onClick: () => !disabled && this.foundation.goPage(page, i), className: pageListClassName, "aria-label": page === '...' ? 'More' : `Page ${page}`, "aria-current": currentPage === page ? "page" : false }, page); if (page === '...' && !disabled) { let content; i < 3 ? content = restLeftPageList : content = restRightPageList; return /*#__PURE__*/_react.default.createElement(_index3.default, { rePosKey: this.props.currentPage, trigger: "hover", // onVisibleChange={visible=>this.handleRestHover(visible, i < 3 ? 'left' : 'right')} content: this.renderRestPageList(content), key: `${page}${i}`, position: popoverPosition, zIndex: popoverZIndex }, pageEl); } return pageEl; }); } renderRestPageList(restList) { // The number of pages may be tens of thousands, here is virtualized with the help of react-window const { direction } = this.context; const className = (0, _classnames.default)(`${prefixCls}-rest-item`); const count = restList.length; const row = item => { const { index, style } = item; const page = restList[index]; return /*#__PURE__*/_react.default.createElement("div", { role: "listitem", key: `${page}${index}`, className: className, onClick: () => this.foundation.goPage(page, index), style: style, "aria-label": `${page}` }, page); }; const itemHeight = 32; const listHeight = count >= 5 ? itemHeight * 5 : itemHeight * count; return ( /*#__PURE__*/ // @ts-ignore skip type check cause react-window not update with @types/react 18 _react.default.createElement(_reactWindow.FixedSizeList, { className: `${prefixCls}-rest-list`, itemData: restList, itemSize: itemHeight, width: 78, itemCount: count, height: listHeight, style: { direction } }, row) ); } renderSmallPageSelect(content) { const allPageNumbers = this.state.allPageNumbers; const pageList = this.renderRestPageList(allPageNumbers); return /*#__PURE__*/_react.default.createElement(_index3.default, { content: pageList }, content); } renderSmallPage(locale) { const _a = this.props, { className, style, hideOnSinglePage, hoverShowPageSelect, showSizeChanger, disabled } = _a, rest = __rest(_a, ["className", "style", "hideOnSinglePage", "hoverShowPageSelect", "showSizeChanger", "disabled"]); const paginationCls = (0, _classnames.default)(`${prefixCls}-small`, prefixCls, className, { [`${prefixCls}-disabled`]: disabled }); const { currentPage, total, pageSize } = this.state; const totalPageNum = Math.ceil(total / pageSize); if (totalPageNum < 2 && hideOnSinglePage && !showSizeChanger) { return null; } const pageCls = (0, _classnames.default)({ [`${prefixCls}-item`]: true, [`${prefixCls}-item-small`]: true, [`${prefixCls}-item-all-disabled`]: disabled }); const content = /*#__PURE__*/_react.default.createElement("div", { className: pageCls }, currentPage, "/", totalPageNum, " "); return /*#__PURE__*/_react.default.createElement("div", Object.assign({ className: paginationCls, style: style }, this.getDataAttr(rest)), this.renderPrevBtn(), hoverShowPageSelect && !disabled ? this.renderSmallPageSelect(content) : content, this.renderNextBtn(), this.renderQuickJump(locale)); } renderDefaultPage(locale) { const { total, pageSize } = this.state; const _a = this.props, { showTotal, className, style, hideOnSinglePage, showSizeChanger, disabled } = _a, rest = __rest(_a, ["showTotal", "className", "style", "hideOnSinglePage", "showSizeChanger", "disabled"]); const paginationCls = (0, _classnames.default)(className, `${prefixCls}`, { [`${prefixCls}-disabled`]: disabled }); const showTotalCls = `${prefixCls}-total`; const totalPageNum = Math.ceil(total / pageSize); if (totalPageNum < 2 && hideOnSinglePage && !showSizeChanger) { return null; } const totalNum = Math.ceil(total / pageSize); const totalToken = locale.total.replace('${total}', totalNum.toString()); return /*#__PURE__*/_react.default.createElement("ul", Object.assign({ className: paginationCls, style: style }, this.getDataAttr(rest)), showTotal ? (/*#__PURE__*/_react.default.createElement("span", { className: showTotalCls }, totalToken)) : null, this.renderPrevBtn(), this.renderPageList(), this.renderNextBtn(), this.renderPageSizeSwitch(locale), this.renderQuickJump(locale)); } render() { const { size } = this.props; return /*#__PURE__*/_react.default.createElement(_localeConsumer.default, { componentName: "Pagination" }, locale => size === 'small' ? this.renderSmallPage(locale) : this.renderDefaultPage(locale)); } } exports.default = Pagination; Pagination.contextType = _context.default; Pagination.propTypes = { total: _propTypes.default.number, showTotal: _propTypes.default.bool, pageSize: _propTypes.default.number, pageSizeOpts: _propTypes.default.array, size: _propTypes.default.string, currentPage: _propTypes.default.number, defaultCurrentPage: _propTypes.default.number, onPageChange: _propTypes.default.func, onPageSizeChange: _propTypes.default.func, onChange: _propTypes.default.func, prevText: _propTypes.default.node, nextText: _propTypes.default.node, showSizeChanger: _propTypes.default.bool, popoverZIndex: _propTypes.default.number, popoverPosition: _propTypes.default.string, style: _propTypes.default.object, className: _propTypes.default.string, hideOnSinglePage: _propTypes.default.bool, hoverShowPageSelect: _propTypes.default.bool, showQuickJumper: _propTypes.default.bool, disabled: _propTypes.default.bool }; Pagination.defaultProps = { total: 1, popoverZIndex: _constants2.numbers.DEFAULT_Z_INDEX, showTotal: false, pageSize: null, pageSizeOpts: _constants.numbers.PAGE_SIZE_OPTION, defaultCurrentPage: 1, size: 'default', onPageChange: _noop2.default, onPageSizeChange: _noop2.default, onChange: _noop2.default, showSizeChanger: false, className: '', hideOnSinglePage: false, showQuickJumper: false, disabled: false };