Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

react-responsive-pagination

Package Overview
Dependencies
Maintainers
1
Versions
129
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

react-responsive-pagination - npm Package Compare versions

Comparing version 2.2.4 to 2.3.0-beta.1

8

CHANGELOG.md
# React Responsive Pagination Changelog
# [2.3.0-beta.1](https://github.com/jonelantha/react-responsive-pagination/compare/v2.2.4...v2.3.0-beta.1) (2023-12-11)
### Features
* NarrowBehaviour combine helper, for using multiple NarrowBehaviours ([3c040ec](https://github.com/jonelantha/react-responsive-pagination/commit/3c040ec0060fcb9aeaa284b66f1d35376ed748f2))
* new dropFirstAndLast NarrowBehaviour ([f0b0a54](https://github.com/jonelantha/react-responsive-pagination/commit/f0b0a54d1886fded1a1aa8d25921a4f8f3a622ed))
## [2.2.4](https://github.com/jonelantha/react-responsive-pagination/compare/v2.2.3...v2.2.4) (2023-11-24)

@@ -4,0 +12,0 @@

6

dist/compositionItem.d.ts

@@ -29,3 +29,7 @@ type CompositionPage = {

export declare function isEllipsis(item: CompositionItem): item is CompositionEllipsis;
export declare function containsEllipsis(composition: CompositionItem[]): boolean;
export declare function containsEllipsis(composition: ReadonlyArray<CompositionItem>): boolean;
export declare function isPageWithNumber(item: CompositionItem, page: number): item is CompositionPage;
export declare function getLastPage(composition: ReadonlyArray<CompositionItem>): number;
export declare function compositionMatches(composition: ReadonlyArray<CompositionItem>, startIndex: number, pattern: (number | '#' | '…' | '*')[]): boolean | undefined;
export declare function compositionMatchesEnd(composition: ReadonlyArray<CompositionItem>, endIndex: number, pattern: (number | '#' | '…' | '*')[]): boolean | undefined;
export {};

@@ -0,1 +1,2 @@

import { UnsupportedValueError } from './helpers/util.js';
export function createActivePage(page) {

@@ -25,1 +26,36 @@ return { type: 'active', page };

}
export function isPageWithNumber(item, page) {
return item.type === 'page' && item.page === page;
}
export function getLastPage(composition) {
return Math.max(...composition
.filter((item) => item.type === 'active' || item.type === 'page')
.map(item => item.page));
}
export function compositionMatches(composition, startIndex, pattern) {
if (startIndex < 0)
return;
return pattern.every((matchItem, patternIndex) => {
if (!composition[startIndex + patternIndex])
return false;
const { type, page } = composition[startIndex + patternIndex];
if (typeof matchItem === 'number') {
return type === 'page' && page === matchItem;
}
else if (matchItem === '#') {
return type === 'page';
}
else if (matchItem === '…') {
return type === '…L' || type === '…R';
}
else if (matchItem === '*') {
return type === 'active';
}
else {
throw new UnsupportedValueError(matchItem);
}
});
}
export function compositionMatchesEnd(composition, endIndex, pattern) {
return compositionMatches(composition, endIndex - pattern.length + 1, pattern);
}

1

dist/compositions/index.d.ts
import { CompositionItem } from '../compositionItem.js';
import { NarrowBehaviour } from '../narrowBehaviour.js';
export type NarrowStrategy = 'dropEllipsis' | 'dropNav';
export declare function narrowToWideCompositions({ current, total, narrowBehaviour, renderNav, }: {

@@ -5,0 +4,0 @@ current: number;

@@ -5,1 +5,5 @@ export declare function isNumber(val: any): val is number;

export declare function sanatizeBoolean(maybeBoolean: unknown): boolean | undefined;
export declare function findLastIndex<T>(array: ReadonlyArray<T>, predicate: (item: T) => boolean): number;
export declare class UnsupportedValueError extends Error {
constructor(value: never);
}

@@ -15,1 +15,14 @@ export function isNumber(val) {

}
// TODO: use native findLastIndex in next major release
export function findLastIndex(array, predicate) {
for (let k = array.length - 1; k >= 0; k--) {
if (predicate(array[k]))
return k;
}
return -1;
}
export class UnsupportedValueError extends Error {
constructor(value) {
super('Unsupported value: ' + value);
}
}
import { CompositionItem } from './compositionItem.js';
export type NarrowBehaviour = (composition: CompositionItem[]) => Generator<CompositionItem[]>;
export declare function dropEllipsis(initialComposition: CompositionItem[]): Generator<CompositionItem[], void, unknown>;
export declare function dropNav(initialComposition: CompositionItem[]): Generator<CompositionItem[], void, unknown>;
export declare function dropEllipsisThenNav(initialComposition: CompositionItem[]): Generator<CompositionItem[], void, unknown>;
export declare function dropNavThenEllipsis(initialComposition: CompositionItem[]): Generator<CompositionItem[], void, unknown>;
/**
* NarrowBehaviours will yield their narrowest composition first and then
* yield a less narrow composition
* They should not yield the initialComposition
*/
export type NarrowBehaviour = (composition: ReadonlyArray<CompositionItem>, metaData?: NarrowBehaviourMetaData) => Generator<CompositionItem[]>;
type NarrowBehaviourMetaData = {
appliedBehaviours?: NarrowBehaviour[];
};
export declare function dropEllipsis(initialComposition: ReadonlyArray<CompositionItem>, metaData?: NarrowBehaviourMetaData): Generator<CompositionItem[], void, unknown>;
export declare function dropNav(initialComposition: ReadonlyArray<CompositionItem>): Generator<CompositionItem[], void, unknown>;
export declare function dropFirstAndLast(initialComposition: ReadonlyArray<CompositionItem>, metaData?: NarrowBehaviourMetaData): Generator<CompositionItem[], void, unknown>;
export declare function dropEllipsisThenNav(initialComposition: ReadonlyArray<CompositionItem>): Generator<CompositionItem[], void, unknown>;
export declare function dropNavThenEllipsis(initialComposition: ReadonlyArray<CompositionItem>): Generator<CompositionItem[], void, unknown>;
/**
* When combining NarrowBehaviours the behaviours will be applied in order:
* the first behaviour will be used before subsequent behaviours
* Compositions yielded from combineBehaviours will initially have
* all behaviours applied in their narrowest form and then work through
* each behaviour in turn (from last to first)
*/
/**
* Combine two or more narrowBehaviours
*/
export declare const combine: (...behaviours: ReadonlyArray<NarrowBehaviour>) => NarrowBehaviour;
export {};

@@ -1,6 +0,22 @@

import { containsEllipsis, isEllipsis, isNav, } from './compositionItem.js';
export function* dropEllipsis(initialComposition) {
if (containsEllipsis(initialComposition)) {
yield initialComposition.filter(item => !isEllipsis(item));
import { containsEllipsis, createEllipsis, getLastPage, isEllipsis, isNav, isPageWithNumber, compositionMatches, compositionMatchesEnd, } from './compositionItem.js';
import { findLastIndex } from './helpers/util.js';
export function* dropEllipsis(initialComposition, metaData) {
const indicesToDrop = [];
if (metaData?.appliedBehaviours?.includes(dropFirstAndLast)) {
// 1, 2 => …, 2 => 2
const firstPageIndex = initialComposition.findIndex(item => isPageWithNumber(item, 1));
if (compositionMatches(initialComposition, firstPageIndex, [1, 2])) {
indicesToDrop.push(firstPageIndex);
}
// n-1, n => n-1, … => n-1
/** last page */
const n = getLastPage(initialComposition);
const lastPageIndex = findLastIndex(initialComposition, item => isPageWithNumber(item, n));
if (compositionMatchesEnd(initialComposition, lastPageIndex, [n - 1, n])) {
indicesToDrop.push(lastPageIndex);
}
}
if (containsEllipsis(initialComposition) || indicesToDrop.length > 0) {
yield initialComposition.filter((item, index) => !isEllipsis(item) && !indicesToDrop.includes(index));
}
}

@@ -10,2 +26,60 @@ export function* dropNav(initialComposition) {

}
export function* dropFirstAndLast(initialComposition, metaData) {
const ellipsisDropped = metaData?.appliedBehaviours?.includes(dropEllipsis);
let composition = initialComposition.slice();
/**
* normal
* 1* 1*
* 1, 2* 1, 2*
* 1, 2, 3* 1, 2, 3*
* 1, 2, 3, 4* …, 3, 4*
* 1, …, p, p+1* …, p, p+1* (p>=4)
*
* after dropEllipsis
* 1* 1*
* 1, 2* 1, 2*
* 1, 2, 3* 2, 3*
* 1, 2, 3, 4* 3, 4*
* 1, p, p+1* p, p+1 (p>=4)
*/
const firstPageIndex = composition.findIndex(item => isPageWithNumber(item, 1));
if (ellipsisDropped) {
if (compositionMatches(composition, firstPageIndex, [1, 2, 3, '*'])) {
composition.splice(firstPageIndex, 2);
}
else if (compositionMatches(composition, firstPageIndex, [1, '#', '*'])) {
composition.splice(firstPageIndex, 1);
}
}
else {
if (compositionMatches(composition, firstPageIndex, [1, 2, 3, '*'])) {
composition.splice(firstPageIndex, 2, createEllipsis('L'));
}
else if (compositionMatches(composition, firstPageIndex, [1, '…', '#'])) {
composition.splice(firstPageIndex, 1);
}
}
/** last page */
const n = getLastPage(composition);
const lastPageIndex = findLastIndex(composition, item => isPageWithNumber(item, n));
if (ellipsisDropped) {
if (compositionMatchesEnd(composition, lastPageIndex, ['*', n - 2, n - 1, n])) {
composition.splice(lastPageIndex - 1, 2);
}
else if (compositionMatchesEnd(composition, lastPageIndex, ['*', '#', n])) {
composition.splice(lastPageIndex, 1);
}
}
else {
if (compositionMatchesEnd(composition, lastPageIndex, ['*', n - 2, n - 1, n])) {
composition.splice(lastPageIndex - 1, 2, createEllipsis('R'));
}
else if (compositionMatchesEnd(composition, lastPageIndex, ['#', '…', n])) {
composition.splice(lastPageIndex, 1);
}
}
if (initialComposition.length !== composition.length) {
yield composition;
}
}
export function* dropEllipsisThenNav(initialComposition) {

@@ -26,1 +100,37 @@ if (containsEllipsis(initialComposition)) {

}
/**
* When combining NarrowBehaviours the behaviours will be applied in order:
* the first behaviour will be used before subsequent behaviours
* Compositions yielded from combineBehaviours will initially have
* all behaviours applied in their narrowest form and then work through
* each behaviour in turn (from last to first)
*/
/**
* Combine two or more narrowBehaviours
*/
export const combine = (...behaviours) => initialComposition => combineRecursive(behaviours, [], initialComposition);
function* combineRecursive(behaviours, previousBehaviours, initialComposition) {
// if no behaviours then we are done
if (behaviours.length === 0)
return;
const [firstBehaviour, ...remainingBehaviours] = behaviours;
const firstBehaviourCompositions = firstBehaviour(initialComposition, {
appliedBehaviours: previousBehaviours,
});
const firstResult = firstBehaviourCompositions.next();
if (firstResult.done) {
// if this behaviour did not yield anything then just move on to the next behaviour
yield* combineRecursive(remainingBehaviours, [...previousBehaviours, firstBehaviour], initialComposition);
}
else {
const firstComposition = firstResult.value;
// the first composition will be the most reduced
// this will be the composition for lower priority behaviours to
// be applied on top of
yield* combineRecursive(remainingBehaviours, [...previousBehaviours, firstBehaviour], firstComposition);
// then yield this composition without any other behaviours applied
yield firstComposition;
// then yield the remaining compositions from this behaviour
yield* firstBehaviourCompositions;
}
}
{
"name": "react-responsive-pagination",
"version": "2.2.4",
"version": "2.3.0-beta.1",
"description": "React component for responsive pagination",

@@ -5,0 +5,0 @@ "author": "jonelantha",

@@ -122,6 +122,6 @@ # React Responsive Pagination

| Prop | Description |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| **renderNav**<br />`boolean`<br />(optional) | When set to `false` the nav buttons (**«**/**»**) will not be rendered. Defaults to `true` |
| **narrowBehaviour**<br />`NarrowBehaviour`<br />(optional) | Specify that nav buttons (**«**/**»**) and/or the ellipsis (**…**) can be dropped for very narrow widths (useful if the component is used in narrow widths with high page numbers)<br />Valid behaviours should be imported from `react-responsive-pagination/narrowBehaviour`, [see example](https://react-responsive-pagination.elantha.com/props/#misc-props)<br /><br />`dropEllipsis` - drop the ellipsis (**…**) for narrow widths<br />`dropNav` - drop the nav (**«**/**»**) for narrow widths<br />`dropNavThenEllipsis` - drop the nav initially and then further drop the ellipsis if required<br />`dropEllipsisThenNav` - drop the ellipsis initially and then further drop the nav if required |
| Prop | Description |
| ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **renderNav**<br />`boolean`<br />(optional) | When set to `false` the nav buttons (**«**/**»**) will not be rendered. Defaults to `true` |
| **narrowBehaviour**<br />`NarrowBehaviour`<br />(optional) | Specify that nav buttons (**«**/**»**) and/or the ellipsis (**…**) can be dropped for very narrow widths (useful if the component is used in narrow widths with high page numbers)<br />Valid behaviours should be imported from `react-responsive-pagination/narrowBehaviour`, [see example](https://react-responsive-pagination.elantha.com/props/#misc-props)<br /><br />`dropEllipsis` - drop the ellipsis (**…**) for narrow widths<br />`dropNav` - drop the nav (**«**/**»**) for narrow widths<br />`dropFirstAndLast` - drop the first and last pages for narrow widths<br /><br />Use the `combine` helper to combine narrowBehaviours, example:<br />`narrowBehaviour={combine(dropNav, dropEllipsis)}` - drop the nav initially and then further drop the ellipsis if required<br />`combine` should also be imported from `react-responsive-pagination/narrowBehaviour` [see examples](https://react-responsive-pagination.elantha.com/props/#misc-props) |

@@ -128,0 +128,0 @@ See [Props Reference](https://react-responsive-pagination.elantha.com/props) for the full list

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc