UNPKG

@commercetools-uikit/pagination

Version:

Components for navigating through pages of items

271 lines (262 loc) • 14.7 kB
import _objectWithoutProperties from '@babel/runtime-corejs3/helpers/esm/objectWithoutProperties'; import '@emotion/react'; import Spacings from '@commercetools-uikit/spacings'; import { jsx, jsxs } from '@emotion/react/jsx-runtime'; import _defineProperty from '@babel/runtime-corejs3/helpers/esm/defineProperty'; import _slicedToArray from '@babel/runtime-corejs3/helpers/esm/slicedToArray'; import _includesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/includes'; import _mapInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/map'; import _Object$keys from '@babel/runtime-corejs3/core-js-stable/object/keys'; import _Object$getOwnPropertySymbols from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-symbols'; import _filterInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/filter'; import _Object$getOwnPropertyDescriptor from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptor'; import _forEachInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/for-each'; import _Object$getOwnPropertyDescriptors from '@babel/runtime-corejs3/core-js-stable/object/get-own-property-descriptors'; import _Object$defineProperties from '@babel/runtime-corejs3/core-js-stable/object/define-properties'; import _Object$defineProperty from '@babel/runtime-corejs3/core-js-stable/object/define-property'; import { useState, useCallback } from 'react'; import uniqueId from 'lodash/uniqueId'; import SelectInput from '@commercetools-uikit/select-input'; import Constraints from '@commercetools-uikit/constraints'; import { warning } from '@commercetools-uikit/utils'; import Label from '@commercetools-uikit/label'; import { defineMessages, useIntl } from 'react-intl'; import _valuesInstanceProperty from '@babel/runtime-corejs3/core-js-stable/instance/values'; import { useFormik } from 'formik'; import { AngleLeftIcon, AngleRightIcon } from '@commercetools-uikit/icons'; import NumberInput from '@commercetools-uikit/number-input'; import SecondaryIconButton from '@commercetools-uikit/secondary-icon-button'; const isValid = (page, totalPages) => { if (page > totalPages) return false; if (page <= 0) return false; return true; }; const normalizePageValue = (value, totalPages) => { if (value < 1) { return 1; } if (value > totalPages) { return totalPages; } return value; }; var messages$2 = defineMessages({ page: { id: 'UIKit.Pagination.PageNavigator.page', description: 'Label for page', defaultMessage: 'Page' }, pageCount: { id: 'UIKit.Pagination.PageNavigator.pageCount', description: 'Label for total pages', defaultMessage: 'of {count}' }, previousPageLabel: { id: 'UIKit.Pagination.PageNavigator.previousPageLabel', description: 'Label for previous page button', defaultMessage: 'Previous page' }, nextPageLabel: { id: 'UIKit.Pagination.PageNavigator.nextPageLabel', description: 'Label for next page button', defaultMessage: 'Next page' } }); function ownKeys$1(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread$1(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys$1(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys$1(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; } const PageNavigator = props => { const intl = useIntl(); const _useState = useState(uniqueId('page-number-')), _useState2 = _slicedToArray(_useState, 1), pageNumberInputId = _useState2[0]; const paginationForm = useFormik({ initialValues: { page: props.page }, enableReinitialize: true, validateOnBlur: true, validateOnChange: true, validateOnMount: true, onSubmit: (values /**, helpers */) => { const nextNormalizedValue = Number(normalizePageValue(values.page, props.totalPages)); props.onPageChange(nextNormalizedValue); }, validate: values => { if (!isValid(values.page, props.totalPages)) { return { page: true }; } return {}; } }); const page = props.page, totalPages = props.totalPages; const isDisabled = totalPages === 0; const isPreviousDisabled = page <= 1; const isNextDisabled = page >= totalPages; const handlePrevPageChange = useCallback(() => { const previousPage = _valuesInstanceProperty(paginationForm).page - 1; if (previousPage >= 1) { paginationForm.setFieldValue('page', previousPage, true); paginationForm.submitForm(); } }, [paginationForm]); const handleNextPageChange = useCallback(() => { const nextPage = _valuesInstanceProperty(paginationForm).page + 1; if (nextPage <= totalPages) { paginationForm.setFieldValue('page', nextPage, true); paginationForm.submitForm(); } }, [paginationForm, totalPages]); return jsx("form", { onSubmit: paginationForm.handleSubmit, children: jsxs(Spacings.Inline, { alignItems: "center", scale: "s", children: [jsx(SecondaryIconButton, { label: intl.formatMessage(messages$2.previousPageLabel), onClick: handlePrevPageChange, isDisabled: isPreviousDisabled || isDisabled, icon: jsx(AngleLeftIcon, {}) }), jsx(Label, { htmlFor: pageNumberInputId, intlMessage: messages$2.page }), jsx("div", { children: jsx(NumberInput, { name: "page", id: pageNumberInputId, value: _valuesInstanceProperty(paginationForm).page, min: 1, max: totalPages, onBlur: paginationForm.handleBlur, onChange: paginationForm.handleChange, isDisabled: isDisabled, hasWarning: Boolean(paginationForm.errors.page), horizontalConstraint: 2 }) }), jsx(Label, { intlMessage: _objectSpread$1(_objectSpread$1({}, messages$2.pageCount), {}, { values: { count: props.totalPages } }) }), jsx(SecondaryIconButton, { label: intl.formatMessage(messages$2.nextPageLabel), onClick: handleNextPageChange, isDisabled: isNextDisabled || isDisabled, icon: jsx(AngleRightIcon, {}) })] }) }); }; PageNavigator.displayName = 'PageNavigator'; var PageNavigator$1 = PageNavigator; const messages = defineMessages({ pageSize: { id: 'UIKit.Pagination.PageSizeSelector.pageSize', description: 'How many items are per page', defaultMessage: 'Items per page ({count} items)' } }); var messages$1 = messages; const _excluded$1 = ["perPage", "perPageRange"]; function ownKeys(e, r) { var t = _Object$keys(e); if (_Object$getOwnPropertySymbols) { var o = _Object$getOwnPropertySymbols(e); r && (o = _filterInstanceProperty(o).call(o, function (r) { return _Object$getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; } function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var _context, _context2; var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? _forEachInstanceProperty(_context = ownKeys(Object(t), !0)).call(_context, function (r) { _defineProperty(e, r, t[r]); }) : _Object$getOwnPropertyDescriptors ? _Object$defineProperties(e, _Object$getOwnPropertyDescriptors(t)) : _forEachInstanceProperty(_context2 = ownKeys(Object(t))).call(_context2, function (r) { _Object$defineProperty(e, r, _Object$getOwnPropertyDescriptor(t, r)); }); } return e; } const mapRangeToListOfOptions = perPageRange => { switch (perPageRange) { case 'xs': return [5, 10, 15, 20]; case 's': return [20, 50]; case 'm': return [20, 50, 100]; case 'l': return [200, 500]; default: throw new Error(`Invalid page range "${perPageRange}", expected one of "xs,s,m,l".`); } }; const PageSizeSelector = _ref => { let _ref$perPage = _ref.perPage, perPage = _ref$perPage === void 0 ? 20 : _ref$perPage, _ref$perPageRange = _ref.perPageRange, perPageRange = _ref$perPageRange === void 0 ? 's' : _ref$perPageRange, props = _objectWithoutProperties(_ref, _excluded$1); const _useState = useState(uniqueId('per-page-selector-')), _useState2 = _slicedToArray(_useState, 1), perPageSelectorId = _useState2[0]; const options = mapRangeToListOfOptions(perPageRange); const hasValidPerPageOption = _includesInstanceProperty(options).call(options, perPage); process.env.NODE_ENV !== "production" ? warning(hasValidPerPageOption, `@commercetools-uikit/pagination: invalid page size ${perPage}. It must be one of the values of the selected range in "${options.toString()}".`) : void 0; const onPerPageChange = props.onPerPageChange; const handleSelectPerPage = useCallback(event => { onPerPageChange(Number(event.target.value)); }, [onPerPageChange]); return jsxs(Spacings.Inline, { alignItems: "center", children: [jsx(Constraints.Horizontal, { max: "auto", children: jsx(SelectInput, { id: perPageSelectorId, isSearchable: false, name: "per-page-selector", value: perPage.toString(), options: _mapInstanceProperty(options).call(options, option => ({ value: option.toString(), label: option.toString() })), onChange: handleSelectPerPage }) }), jsx(Label, { htmlFor: perPageSelectorId, intlMessage: _objectSpread(_objectSpread({}, messages$1.pageSize), {}, { values: { count: props.pageItems } }) })] }); }; PageSizeSelector.displayName = 'PageSizeSelector'; var PageSizeSelector$1 = PageSizeSelector; const _excluded = ["perPage", "perPageRange"]; function _EMOTION_STRINGIFIED_CSS_ERROR__() { return "You have tried to stringify object returned from `css` function. It isn't supposed to be used directly (e.g. as value of the `className` prop), but rather handed to emotion so it can handle it (e.g. as value of `css` prop)."; } var _ref = process.env.NODE_ENV === "production" ? { name: "15sp3y3", styles: "flex-grow:2" } : { name: "mvvfm1-Pagination", styles: "flex-grow:2;label:Pagination;/*# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbInBhZ2luYXRpb24udHN4Il0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQTREZ0IiLCJmaWxlIjoicGFnaW5hdGlvbi50c3giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBjc3MgfSBmcm9tICdAZW1vdGlvbi9yZWFjdCc7XG5pbXBvcnQgU3BhY2luZ3MgZnJvbSAnQGNvbW1lcmNldG9vbHMtdWlraXQvc3BhY2luZ3MnO1xuaW1wb3J0IFBhZ2VOYXZpZ2F0b3IgZnJvbSAnLi9wYWdlLW5hdmlnYXRvcic7XG5pbXBvcnQgUGFnZVNpemVTZWxlY3RvciwgeyB0eXBlIFRQYWdlUmFuZ2VTaXplIH0gZnJvbSAnLi9wYWdlLXNpemUtc2VsZWN0b3InO1xuXG5leHBvcnQgdHlwZSBUUGFnaW5hdGlvblByb3BzID0ge1xuICAvKipcbiAgICogVG90YWwgbnVtYmVyIG9mIGl0ZW1zIGFjcm9zcyBhbGwgcGFnZXNcbiAgICovXG4gIHRvdGFsSXRlbXM6IG51bWJlcjtcblxuICAvKipcbiAgICogVGhlIGN1cnJlbnQgcGFnZVxuICAgKi9cbiAgcGFnZTogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBBIGNhbGxiYWNrIGZ1bmN0aW9uLCBjYWxsZWQgd2hlbiB0aGUgcGFnZSBpcyBjaGFuZ2VkLlxuICAgKi9cbiAgb25QYWdlQ2hhbmdlOiAobmV3UGFnZTogbnVtYmVyKSA9PiB2b2lkO1xuXG4gIC8qKlxuICAgKiBOdW1iZXIgb2YgaXRlbXMgcGVyIHBhZ2UsIGFjY29yZGluZyB0byB0aGUgcHJlLWRlZmluZWQgcmFuZ2UgdmFsdWVzLlxuICAgKi9cbiAgcGVyUGFnZT86IG51bWJlcjtcblxuICAvKipcbiAgICogUmFuZ2Ugb2YgaXRlbXMgcGVyIHBhZ2UuXG4gICAqIDxici8+XG4gICAqIGB4czogNSwxMCwxNSwyMGBcbiAgICogPGJyLz5cbiAgICogYHM6IDIwLDUwYFxuICAgKiA8YnIvPlxuICAgKiBgbTogMjAsNTAsMTAwYFxuICAgKiA8YnIvPlxuICAgKiBgbDogMjAwLDUwMGBcbiAgICovXG4gIHBlclBhZ2VSYW5nZT86IFRQYWdlUmFuZ2VTaXplO1xuXG4gIC8qKlxuICAgKiBBIGNhbGxiYWNrIGZ1bmN0aW9uLCBjYWxsZWQgd2hlbiBgcGVyUGFnZWAgaXMgY2hhbmdlZC5cbiAgICovXG4gIG9uUGVyUGFnZUNoYW5nZTogKG5ld1BlclBhZ2U6IG51bWJlcikgPT4gdm9pZDtcbn07XG5cbmNvbnN0IFBhZ2luYXRpb24gPSAoe1xuICBwZXJQYWdlID0gMjAsXG4gIHBlclBhZ2VSYW5nZSA9ICdzJyxcbiAgLi4ucHJvcHNcbn06IFRQYWdpbmF0aW9uUHJvcHMpID0+IHtcbiAgY29uc3QgdG90YWxQYWdlcyA9IE1hdGguY2VpbChwcm9wcy50b3RhbEl0ZW1zIC8gcGVyUGFnZSk7XG5cbiAgY29uc3QgcGFnZUl0ZW1zID1cbiAgICBwcm9wcy5wYWdlID09PSB0b3RhbFBhZ2VzXG4gICAgICA/IHByb3BzLnRvdGFsSXRlbXMgLSBwZXJQYWdlICogKHByb3BzLnBhZ2UgLSAxKVxuICAgICAgOiBwZXJQYWdlO1xuXG4gIHJldHVybiAoXG4gICAgPFNwYWNpbmdzLklubGluZSBqdXN0aWZ5Q29udGVudD1cInNwYWNlLWJldHdlZW5cIj5cbiAgICAgIDxkaXZcbiAgICAgICAgY3NzPXtjc3NgXG4gICAgICAgICAgZmxleC1ncm93OiAyO1xuICAgICAgICBgfVxuICAgICAgPlxuICAgICAgICA8UGFnZVNpemVTZWxlY3RvclxuICAgICAgICAgIHBhZ2VJdGVtcz17cGFnZUl0ZW1zfVxuICAgICAgICAgIHBlclBhZ2U9e3BlclBhZ2V9XG4gICAgICAgICAgcGVyUGFnZVJhbmdlPXtwZXJQYWdlUmFuZ2V9XG4gICAgICAgICAgb25QZXJQYWdlQ2hhbmdlPXtwcm9wcy5vblBlclBhZ2VDaGFuZ2V9XG4gICAgICAgIC8+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxQYWdlTmF2aWdhdG9yXG4gICAgICAgIHRvdGFsUGFnZXM9e3RvdGFsUGFnZXN9XG4gICAgICAgIHBhZ2U9e3Byb3BzLnBhZ2V9XG4gICAgICAgIG9uUGFnZUNoYW5nZT17cHJvcHMub25QYWdlQ2hhbmdlfVxuICAgICAgLz5cbiAgICA8L1NwYWNpbmdzLklubGluZT5cbiAgKTtcbn07XG5cblBhZ2luYXRpb24uZGlzcGxheU5hbWUgPSAnUGFnaW5hdGlvbic7XG5cbmV4cG9ydCB0eXBlIHsgVFBhZ2VSYW5nZVNpemUgfTtcblxuZXhwb3J0IGRlZmF1bHQgUGFnaW5hdGlvbjtcbiJdfQ== */", toString: _EMOTION_STRINGIFIED_CSS_ERROR__ }; const Pagination = _ref2 => { let _ref2$perPage = _ref2.perPage, perPage = _ref2$perPage === void 0 ? 20 : _ref2$perPage, _ref2$perPageRange = _ref2.perPageRange, perPageRange = _ref2$perPageRange === void 0 ? 's' : _ref2$perPageRange, props = _objectWithoutProperties(_ref2, _excluded); const totalPages = Math.ceil(props.totalItems / perPage); const pageItems = props.page === totalPages ? props.totalItems - perPage * (props.page - 1) : perPage; return jsxs(Spacings.Inline, { justifyContent: "space-between", children: [jsx("div", { css: _ref, children: jsx(PageSizeSelector$1, { pageItems: pageItems, perPage: perPage, perPageRange: perPageRange, onPerPageChange: props.onPerPageChange }) }), jsx(PageNavigator$1, { totalPages: totalPages, page: props.page, onPageChange: props.onPageChange })] }); }; Pagination.displayName = 'Pagination'; var Pagination$1 = Pagination; // NOTE: This string will be replaced on build time with the package version. var version = "20.1.0"; export { PageNavigator$1 as PageNavigator, PageSizeSelector$1 as PageSizeSelector, Pagination$1 as Pagination, version };