react-responsive-pagination
Advanced tools
Comparing version 1.0.3 to 1.1.0-beta.1
# React Responsive Pagination Changelog | ||
# [1.1.0-beta.1](https://github.com/jonelantha/react-responsive-pagination/compare/v1.0.3...v1.1.0-beta.1) (2020-07-13) | ||
### Bug Fixes | ||
* Package Bumps ([b55832f](https://github.com/jonelantha/react-responsive-pagination/commit/b55832f2f1754b038fd6518475a6ed266791fcc6)) | ||
### Features | ||
* Auto calculation of width from parent element ([fe42252](https://github.com/jonelantha/react-responsive-pagination/commit/fe42252806d07f4870bbd281e08f8a6ffa37bc87)) | ||
## [1.0.3](https://github.com/jonelantha/react-responsive-pagination/compare/v1.0.2...v1.0.3) (2020-06-16) | ||
@@ -4,0 +16,0 @@ |
export declare function getElementWidth(element: HTMLElement): number; | ||
export declare function getContentWidth(element: HTMLElement): number; | ||
export declare function getNonContentWidth(element: HTMLElement): number; | ||
export declare function getWidth(element: HTMLElement): number; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.getWidth = exports.getNonContentWidth = exports.getElementWidth = void 0; | ||
exports.getWidth = exports.getNonContentWidth = exports.getContentWidth = exports.getElementWidth = void 0; | ||
function getElementWidth(element) { | ||
@@ -11,2 +11,11 @@ var style = getComputedStyle(element); | ||
exports.getElementWidth = getElementWidth; | ||
function getContentWidth(element) { | ||
var style = getComputedStyle(element); | ||
return (element.getBoundingClientRect().width - | ||
styleMetricToInt(style.borderLeftWidth) - | ||
styleMetricToInt(style.paddingLeft) - | ||
styleMetricToInt(style.paddingRight) - | ||
styleMetricToInt(style.borderRightWidth)); | ||
} | ||
exports.getContentWidth = getContentWidth; | ||
function getNonContentWidth(element) { | ||
@@ -13,0 +22,0 @@ var style = getComputedStyle(element); |
export declare function isNumber(val: any): val is number; | ||
export declare function sum(items: number[]): number; | ||
export declare function sanatizeInteger(maybeInteger: any): number; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.sum = exports.isNumber = void 0; | ||
exports.sanatizeInteger = exports.sum = exports.isNumber = void 0; | ||
function isNumber(val) { | ||
@@ -12,1 +12,7 @@ return typeof val === 'number'; | ||
exports.sum = sum; | ||
function sanatizeInteger(maybeInteger) { | ||
return typeof maybeInteger === 'number' && Number.isInteger(maybeInteger) | ||
? maybeInteger | ||
: 0; | ||
} | ||
exports.sanatizeInteger = sanatizeInteger; |
@@ -41,8 +41,10 @@ "use strict"; | ||
var view_1 = require("./view"); | ||
var AutoWidthRenderer_1 = __importDefault(require("./renderers/AutoWidthRenderer")); | ||
var MaxWidthRenderer_1 = __importDefault(require("./renderers/MaxWidthRenderer")); | ||
var util_1 = require("./helpers/util"); | ||
exports.default = react_1.memo(Pagination); | ||
function Pagination(_a) { | ||
var propsCurrent = _a.current, propsTotal = _a.total, handlePageChange = _a.onPageChange, _b = _a.maxWidth, maxWidth = _b === void 0 ? 0 : _b; | ||
var total = propsTotal !== null && propsTotal !== void 0 ? propsTotal : 0; | ||
var current = Math.max(1, Math.min(propsCurrent !== null && propsCurrent !== void 0 ? propsCurrent : 0, total)); | ||
var propsCurrent = _a.current, propsTotal = _a.total, handlePageChange = _a.onPageChange, maxWidth = _a.maxWidth; | ||
var total = util_1.sanatizeInteger(propsTotal); | ||
var current = Math.max(1, Math.min(util_1.sanatizeInteger(propsCurrent), total)); | ||
var Skin = skins_1.BootstrapSkin; | ||
@@ -53,3 +55,11 @@ var View = view_1.useView(Skin, handlePageChange); | ||
}; | ||
return total > 0 ? (react_1.default.createElement(MaxWidthRenderer_1.default, __assign({}, { maxWidth: maxWidth, narrowToWideCompositionsProvider: narrowToWideCompositionsProvider, View: View }))) : null; | ||
if (total <= 0) { | ||
return null; | ||
} | ||
else if (maxWidth === undefined) { | ||
return react_1.default.createElement(AutoWidthRenderer_1.default, __assign({}, { narrowToWideCompositionsProvider: narrowToWideCompositionsProvider, View: View })); | ||
} | ||
else { | ||
return (react_1.default.createElement(MaxWidthRenderer_1.default, __assign({}, { maxWidth: maxWidth, narrowToWideCompositionsProvider: narrowToWideCompositionsProvider, View: View }))); | ||
} | ||
} | ||
@@ -56,0 +66,0 @@ Pagination.propTypes = { |
@@ -1,4 +0,5 @@ | ||
/// <reference types="react" /> | ||
import React from 'react'; | ||
import { ViewComponent, ViewItem } from '../../view'; | ||
export default function MaxWidthRenderer({ maxWidth, narrowToWideCompositionsProvider, View, }: Props): JSX.Element; | ||
declare const MaxWidthRenderer: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLElement>>; | ||
export default MaxWidthRenderer; | ||
declare type Props = { | ||
@@ -9,2 +10,1 @@ maxWidth: number; | ||
}; | ||
export {}; |
@@ -26,7 +26,11 @@ "use strict"; | ||
var useFoutDetector_1 = require("./useFoutDetector"); | ||
function MaxWidthRenderer(_a) { | ||
var MaxWidthRenderer = react_1.default.forwardRef(function (_a, forwardedViewRef) { | ||
var maxWidth = _a.maxWidth, narrowToWideCompositionsProvider = _a.narrowToWideCompositionsProvider, View = _a.View; | ||
var widthCalculator = useWidthCalculator_1.useWidthCalculator(View); | ||
var viewRef = react_1.useRef(null); | ||
useFoutDetector_1.useFoutDetector(function () { return getItemsDomElements(viewRef.current); }, 'clearCache' in widthCalculator ? widthCalculator.clearCache : function () { }); | ||
var localViewRef = react_1.useRef(null); | ||
function setViewRef(ref) { | ||
typeof forwardedViewRef === 'function' && forwardedViewRef(ref); | ||
localViewRef.current = ref; | ||
} | ||
useFoutDetector_1.useFoutDetector(function () { return getItemsDomElements(localViewRef.current); }, 'clearCache' in widthCalculator ? widthCalculator.clearCache : function () { }); | ||
if ('measuringComponentNeedsRender' in widthCalculator) { | ||
@@ -36,4 +40,4 @@ return widthCalculator.measuringComponentNeedsRender; | ||
var composition = getLargestFittingCompositionWithFallback(narrowToWideCompositionsProvider, widthCalculator.getWidth, maxWidth); | ||
return react_1.default.createElement(View, { items: composition, ref: viewRef }); | ||
} | ||
return react_1.default.createElement(View, { items: composition, ref: setViewRef }); | ||
}); | ||
exports.default = MaxWidthRenderer; | ||
@@ -40,0 +44,0 @@ function getLargestFittingCompositionWithFallback(getNarrowToWideCompositions, getCompositionWidth, maxWidth) { |
@@ -83,5 +83,7 @@ "use strict"; | ||
var getViewMetrics_1 = require("./getViewMetrics"); | ||
var useIsMounted_1 = require("./useIsMounted"); | ||
function useWidthCalculator(view) { | ||
var _this = this; | ||
var _a = __read(react_1.useState({}), 2), _b = _a[0], calculator = _b.calculator, validForView = _b.validForView, setCalculatorWithView = _a[1]; | ||
var isMounted = useIsMounted_1.useIsMounted(); | ||
var resetCalculator = react_1.useCallback(function () { return setCalculatorWithView({}); }, []); | ||
@@ -95,2 +97,4 @@ var setupCalculator = react_1.useCallback(function (viewDomProvider) { return __awaiter(_this, void 0, void 0, function () { | ||
calculatorRootMetrics = _a.sent(); | ||
if (!isMounted()) | ||
return [2 /*return*/]; | ||
calculator = widthCalculator_1.createWidthCalculator(calculatorRootMetrics); | ||
@@ -101,3 +105,3 @@ setCalculatorWithView({ calculator: calculator, validForView: view }); | ||
}); | ||
}); }, [view]); | ||
}); }, [view, isMounted]); | ||
if (!calculator || validForView !== view) { | ||
@@ -104,0 +108,0 @@ return { |
export declare function getElementWidth(element: HTMLElement): number; | ||
export declare function getContentWidth(element: HTMLElement): number; | ||
export declare function getNonContentWidth(element: HTMLElement): number; | ||
export declare function getWidth(element: HTMLElement): number; |
@@ -7,2 +7,10 @@ export function getElementWidth(element) { | ||
} | ||
export function getContentWidth(element) { | ||
var style = getComputedStyle(element); | ||
return (element.getBoundingClientRect().width - | ||
styleMetricToInt(style.borderLeftWidth) - | ||
styleMetricToInt(style.paddingLeft) - | ||
styleMetricToInt(style.paddingRight) - | ||
styleMetricToInt(style.borderRightWidth)); | ||
} | ||
export function getNonContentWidth(element) { | ||
@@ -9,0 +17,0 @@ var style = getComputedStyle(element); |
export declare function isNumber(val: any): val is number; | ||
export declare function sum(items: number[]): number; | ||
export declare function sanatizeInteger(maybeInteger: any): number; |
@@ -7,1 +7,6 @@ export function isNumber(val) { | ||
} | ||
export function sanatizeInteger(maybeInteger) { | ||
return typeof maybeInteger === 'number' && Number.isInteger(maybeInteger) | ||
? maybeInteger | ||
: 0; | ||
} |
@@ -17,8 +17,10 @@ var __assign = (this && this.__assign) || function () { | ||
import { useView } from './view'; | ||
import AutoWidthRenderer from './renderers/AutoWidthRenderer'; | ||
import MaxWidthRenderer from './renderers/MaxWidthRenderer'; | ||
import { sanatizeInteger } from './helpers/util'; | ||
export default memo(Pagination); | ||
function Pagination(_a) { | ||
var propsCurrent = _a.current, propsTotal = _a.total, handlePageChange = _a.onPageChange, _b = _a.maxWidth, maxWidth = _b === void 0 ? 0 : _b; | ||
var total = propsTotal !== null && propsTotal !== void 0 ? propsTotal : 0; | ||
var current = Math.max(1, Math.min(propsCurrent !== null && propsCurrent !== void 0 ? propsCurrent : 0, total)); | ||
var propsCurrent = _a.current, propsTotal = _a.total, handlePageChange = _a.onPageChange, maxWidth = _a.maxWidth; | ||
var total = sanatizeInteger(propsTotal); | ||
var current = Math.max(1, Math.min(sanatizeInteger(propsCurrent), total)); | ||
var Skin = BootstrapSkin; | ||
@@ -29,3 +31,11 @@ var View = useView(Skin, handlePageChange); | ||
}; | ||
return total > 0 ? (React.createElement(MaxWidthRenderer, __assign({}, { maxWidth: maxWidth, narrowToWideCompositionsProvider: narrowToWideCompositionsProvider, View: View }))) : null; | ||
if (total <= 0) { | ||
return null; | ||
} | ||
else if (maxWidth === undefined) { | ||
return React.createElement(AutoWidthRenderer, __assign({}, { narrowToWideCompositionsProvider: narrowToWideCompositionsProvider, View: View })); | ||
} | ||
else { | ||
return (React.createElement(MaxWidthRenderer, __assign({}, { maxWidth: maxWidth, narrowToWideCompositionsProvider: narrowToWideCompositionsProvider, View: View }))); | ||
} | ||
} | ||
@@ -32,0 +42,0 @@ Pagination.propTypes = { |
@@ -1,4 +0,5 @@ | ||
/// <reference types="react" /> | ||
import React from 'react'; | ||
import { ViewComponent, ViewItem } from '../../view'; | ||
export default function MaxWidthRenderer({ maxWidth, narrowToWideCompositionsProvider, View, }: Props): JSX.Element; | ||
declare const MaxWidthRenderer: React.ForwardRefExoticComponent<Props & React.RefAttributes<HTMLElement>>; | ||
export default MaxWidthRenderer; | ||
declare type Props = { | ||
@@ -9,2 +10,1 @@ maxWidth: number; | ||
}; | ||
export {}; |
@@ -5,7 +5,11 @@ import React, { useRef } from 'react'; | ||
import { useFoutDetector } from './useFoutDetector'; | ||
export default function MaxWidthRenderer(_a) { | ||
var MaxWidthRenderer = React.forwardRef(function (_a, forwardedViewRef) { | ||
var maxWidth = _a.maxWidth, narrowToWideCompositionsProvider = _a.narrowToWideCompositionsProvider, View = _a.View; | ||
var widthCalculator = useWidthCalculator(View); | ||
var viewRef = useRef(null); | ||
useFoutDetector(function () { return getItemsDomElements(viewRef.current); }, 'clearCache' in widthCalculator ? widthCalculator.clearCache : function () { }); | ||
var localViewRef = useRef(null); | ||
function setViewRef(ref) { | ||
typeof forwardedViewRef === 'function' && forwardedViewRef(ref); | ||
localViewRef.current = ref; | ||
} | ||
useFoutDetector(function () { return getItemsDomElements(localViewRef.current); }, 'clearCache' in widthCalculator ? widthCalculator.clearCache : function () { }); | ||
if ('measuringComponentNeedsRender' in widthCalculator) { | ||
@@ -15,4 +19,5 @@ return widthCalculator.measuringComponentNeedsRender; | ||
var composition = getLargestFittingCompositionWithFallback(narrowToWideCompositionsProvider, widthCalculator.getWidth, maxWidth); | ||
return React.createElement(View, { items: composition, ref: viewRef }); | ||
} | ||
return React.createElement(View, { items: composition, ref: setViewRef }); | ||
}); | ||
export default MaxWidthRenderer; | ||
function getLargestFittingCompositionWithFallback(getNarrowToWideCompositions, getCompositionWidth, maxWidth) { | ||
@@ -19,0 +24,0 @@ var _a, _b; |
@@ -58,5 +58,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
import { getViewMetrics } from './getViewMetrics'; | ||
import { useIsMounted } from './useIsMounted'; | ||
export function useWidthCalculator(view) { | ||
var _this = this; | ||
var _a = __read(useState({}), 2), _b = _a[0], calculator = _b.calculator, validForView = _b.validForView, setCalculatorWithView = _a[1]; | ||
var isMounted = useIsMounted(); | ||
var resetCalculator = useCallback(function () { return setCalculatorWithView({}); }, []); | ||
@@ -70,2 +72,4 @@ var setupCalculator = useCallback(function (viewDomProvider) { return __awaiter(_this, void 0, void 0, function () { | ||
calculatorRootMetrics = _a.sent(); | ||
if (!isMounted()) | ||
return [2 /*return*/]; | ||
calculator = createWidthCalculator(calculatorRootMetrics); | ||
@@ -76,3 +80,3 @@ setCalculatorWithView({ calculator: calculator, validForView: view }); | ||
}); | ||
}); }, [view]); | ||
}); }, [view, isMounted]); | ||
if (!calculator || validForView !== view) { | ||
@@ -79,0 +83,0 @@ return { |
{ | ||
"name": "react-responsive-pagination", | ||
"version": "1.0.3", | ||
"version": "1.1.0-beta.1", | ||
"description": "React component for responsive pagination", | ||
@@ -48,20 +48,20 @@ "author": "Jon Pollard", | ||
"@semantic-release/git": "^9.0.0", | ||
"@types/react": "^16.9.36", | ||
"@types/react": "^16.9.43", | ||
"@types/react-dom": "^16.9.8", | ||
"@typescript-eslint/eslint-plugin": "^3.3.0", | ||
"@typescript-eslint/parser": "^3.3.0", | ||
"@typescript-eslint/eslint-plugin": "^3.6.1", | ||
"@typescript-eslint/parser": "^3.6.1", | ||
"babel-eslint": "^10.1.0", | ||
"eslint": "^7.2.0", | ||
"eslint": "^7.4.0", | ||
"eslint-config-react-app": "^5.2.1", | ||
"eslint-plugin-flowtype": "^5.1.3", | ||
"eslint-plugin-import": "^2.21.2", | ||
"eslint-plugin-jsx-a11y": "^6.2.3", | ||
"eslint-plugin-react": "^7.20.0", | ||
"eslint-plugin-react-hooks": "^4.0.4", | ||
"eslint-plugin-flowtype": "^5.2.0", | ||
"eslint-plugin-import": "^2.22.0", | ||
"eslint-plugin-jsx-a11y": "^6.3.1", | ||
"eslint-plugin-react": "^7.20.3", | ||
"eslint-plugin-react-hooks": "^4.0.8", | ||
"react": "^16.13.1", | ||
"react-dom": "^16.13.1", | ||
"rimraf": "^3.0.2", | ||
"semantic-release": "^17.0.8", | ||
"typescript": "^3.9.5" | ||
"semantic-release": "^17.1.1", | ||
"typescript": "^3.9.6" | ||
} | ||
} |
@@ -9,3 +9,3 @@ # React Responsive Pagination | ||
A React pagination component which intelligently renders to a given pixel width. Styled for Bootstrap 4 | ||
A React pagination component which intelligently renders to the available width. Styled for Bootstrap 4 | ||
@@ -22,4 +22,6 @@ ![Example pagination](./pagination.png?raw=true 'React Responsive Pagination') | ||
- Use the component with `<Pagination current={currentPage} total={totalPages} onPageChange={pageChangeHandler} maxWidth={maxWidth}/>` (see below for a more detailed example) | ||
- Use the component with `<Pagination current={currentPage} total={totalPages} onPageChange={pageChangeHandler} />` (see [Usage Example](#usage-example) for a more detailed example) | ||
- See the [About Auto Sizing](#about-auto-sizing) section below for info on some limitations of the auto sizing algorithm. | ||
## More details... | ||
@@ -37,13 +39,9 @@ | ||
- The example below includes a simple `useWindowWidth` hook which supplies the pagination component with the browser's window width. | ||
- The [Bootstrap 4 CSS styles](https://getbootstrap.com/docs/4.3/getting-started/download/) needs to be included in the project for this example to work | ||
```jsx | ||
import React, { useLayoutEffect, useState } from 'react'; | ||
import React, { useState } from 'react'; | ||
import Pagination from 'react-responsive-pagination'; | ||
function MyApp() { | ||
const windowWidth = useWindowWidth(); | ||
const [currentPage, setCurrentPage] = useState(4); | ||
@@ -58,24 +56,14 @@ | ||
onPageChange={setCurrentPage} | ||
maxWidth={windowWidth} | ||
/> | ||
); | ||
} | ||
``` | ||
function useWindowWidth() { | ||
const [windowWidth, setWindowWidth] = useState(window.innerWidth); | ||
### About Auto Sizing | ||
useEffect(() => { | ||
const resizeHandler = () => { | ||
setWindowWidth(window.innerWidth); | ||
}; | ||
Auto sizing uses the width of the immediate parent element. For best results make sure the parent element isn't intrinsically sized; that means the width of the parent element shouldn't depend on its contents. If your layout is intrinsic then the pagination component should still fill the space correctly but you may occasionally see inconsistant results or additional renders. | ||
window.addEventListener('resize', resizeHandler); | ||
return () => { | ||
window.removeEventListener('resize', resizeHandler); | ||
}; | ||
}, []); | ||
You can choose to override the auto sizing by specifying the `maxWidth` prop (see [Props](#props) section below). | ||
return windowWidth; | ||
} | ||
``` | ||
The final thing to note is that for very narrow widths the component may exceed the available space - this is to ensure that there's always a usable pagination component. | ||
@@ -89,2 +77,2 @@ ### Props | ||
| onPageChange | (newPage: number) => void | A callback handler which is called when the user clicks a new page, note that the active page will not change unless the `current` prop is updated to reflect the new page (as in the example above). The `newPage` value is indexed from 1 | | ||
| maxWidth | number | The maximum width (in pixels) of the pagination component. Note this width may be exceeded in the case where it's not possible to output a small enough component | | ||
| maxWidth | number | The maximum width (in pixels) of the pagination component. Specify a value if you want to override the automatic sizing. Note this width may be exceeded in the case where it's not possible to output a small enough component | |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
138209
131
2952
2
74