diff --git a/src/connectors/pagination/__tests__/connectPagination-test.js b/src/connectors/pagination/__tests__/connectPagination-test.js
index a41c9bb168..5a8f11a07c 100644
--- a/src/connectors/pagination/__tests__/connectPagination-test.js
+++ b/src/connectors/pagination/__tests__/connectPagination-test.js
@@ -1,5 +1,3 @@
-
-
import sinon from 'sinon';
import jsHelper from 'algoliasearch-helper';
@@ -43,8 +41,6 @@ describe('connectPagination', () => {
expect(firstRenderingOptions.currentPage).toBe(0);
expect(firstRenderingOptions.nbHits).toBe(0);
expect(firstRenderingOptions.nbPages).toBe(0);
- expect(firstRenderingOptions.shouldAutoHideContainer).toBe(true);
- expect(firstRenderingOptions.showFirstLast).toBe(true);
}
widget.render({
@@ -69,22 +65,17 @@ describe('connectPagination', () => {
expect(secondRenderingOptions.currentPage).toBe(0);
expect(secondRenderingOptions.nbHits).toBe(1);
expect(secondRenderingOptions.nbPages).toBe(1);
- expect(secondRenderingOptions.shouldAutoHideContainer).toBe(false);
- expect(secondRenderingOptions.showFirstLast).toBe(true);
}
});
it('Provides a function to update the refinements at each step', () => {
const container = document.createElement('div');
- const scrollTo = document.createElement('div');
- scrollTo.scrollIntoView = sinon.stub();
const rendering = sinon.stub();
const makeWidget = connectPagination(rendering);
const widget = makeWidget({
container,
- scrollTo,
});
const helper = jsHelper(fakeClient);
@@ -103,7 +94,6 @@ describe('connectPagination', () => {
setPage(2);
expect(helper.getPage()).toBe(2);
expect(helper.search.callCount).toBe(1);
- expect(scrollTo.scrollIntoView.callCount).toBe(1);
}
widget.render({
@@ -119,7 +109,6 @@ describe('connectPagination', () => {
setPage(7);
expect(helper.getPage()).toBe(7);
expect(helper.search.callCount).toBe(2);
- expect(scrollTo.scrollIntoView.callCount).toBe(2);
}
});
});
diff --git a/src/connectors/pagination/connectPagination.js b/src/connectors/pagination/connectPagination.js
index 29cc163b0a..ad98845327 100644
--- a/src/connectors/pagination/connectPagination.js
+++ b/src/connectors/pagination/connectPagination.js
@@ -1,17 +1,22 @@
-import defaults from 'lodash/defaults';
-import cx from 'classnames';
-import {
- bemHelper,
- getContainerNode,
-} from '../../lib/utils.js';
+import {checkRendering} from '../../lib/utils.js';
-const defaultLabels = {
- previous: '‹',
- next: '›',
- first: '«',
- last: '»',
-};
-const bem = bemHelper('ais-pagination');
+const usage = `Usage:
+var customPagination = connectPagination(function render(params, isFirstRendering) {
+ // params = {
+ // createURL,
+ // currentPage,
+ // nbHits,
+ // nbPages,
+ // setPage,
+ // }
+});
+search.addWidget(
+ customPagination({
+ [maxPages]
+ })
+);
+Full documentation available at https://community.algolia.com/instantsearch.js/connectors/connectPagination.html
+`;
/**
* Add a pagination menu to navigate through the results
@@ -38,107 +43,44 @@ const bem = bemHelper('ais-pagination');
* @param {string|string[]} [options.cssClasses.last] CSS classes added to the last `
`
* @param {string|string[]} [options.cssClasses.active] CSS classes added to the active ``
* @param {string|string[]} [options.cssClasses.disabled] CSS classes added to the disabled ``
- * @return {Object}
+ * @return {Object} widget
*/
-const usage = `Usage:
-pagination({
- container,
- [ cssClasses.{root,item,page,previous,next,first,last,active,disabled}={} ],
- [ labels.{previous,next,first,last} ],
- [ maxPages ],
- [ padding=3 ],
- [ showFirstLast=true ],
- [ autoHideContainer=true ],
- [ scrollTo='body' ]
-})`;
-const connectPagination = paginationRendering => ({
- container,
- cssClasses: userCssClasses = {},
- labels: userLabels = {},
- maxPages,
- padding = 3,
- showFirstLast = true,
- autoHideContainer = true,
- scrollTo: userScrollTo = 'body',
- } = {}) => {
- let scrollTo = userScrollTo;
-
- if (!container) {
- throw new Error(usage);
- }
-
- if (scrollTo === true) {
- scrollTo = 'body';
- }
-
- const containerNode = getContainerNode(container);
- const scrollToNode = scrollTo !== false ? getContainerNode(scrollTo) : false;
- const cssClasses = {
- root: cx(bem(null), userCssClasses.root),
- item: cx(bem('item'), userCssClasses.item),
- link: cx(bem('link'), userCssClasses.link),
- page: cx(bem('item', 'page'), userCssClasses.page),
- previous: cx(bem('item', 'previous'), userCssClasses.previous),
- next: cx(bem('item', 'next'), userCssClasses.next),
- first: cx(bem('item', 'first'), userCssClasses.first),
- last: cx(bem('item', 'last'), userCssClasses.last),
- active: cx(bem('item', 'active'), userCssClasses.active),
- disabled: cx(bem('item', 'disabled'), userCssClasses.disabled),
- };
+export default function connectPagination(renderFn) {
+ checkRendering(renderFn, usage);
- const labels = defaults(userLabels, defaultLabels);
-
- return {
+ return ({maxPages}) => ({
init({helper, createURL}) {
this.setPage = page => {
helper.setPage(page);
- if (scrollToNode !== false) {
- scrollToNode.scrollIntoView();
- }
helper.search();
};
this.createURL = state => page => createURL(state.setPage(page));
- paginationRendering({
+ renderFn({
createURL: this.createURL(helper.state),
- cssClasses,
currentPage: helper.getPage() || 0,
- labels,
nbHits: 0,
nbPages: 0,
- padding,
setPage: this.setPage,
- shouldAutoHideContainer: autoHideContainer,
- showFirstLast,
- containerNode,
}, true);
},
- getMaxPage(results) {
- if (maxPages !== undefined) {
- return Math.min(maxPages, results.nbPages);
- }
- return results.nbPages;
+ getMaxPage({nbPages}) {
+ return maxPages !== undefined
+ ? Math.min(maxPages, nbPages)
+ : nbPages;
},
render({results, state}) {
- paginationRendering({
+ renderFn({
createURL: this.createURL(state),
- cssClasses,
currentPage: state.page,
- labels,
+ setPage: this.setPage,
nbHits: results.nbHits,
nbPages: this.getMaxPage(results),
- padding,
- setPage: this.setPage,
- shouldAutoHideContainer: autoHideContainer && results.nbHits === 0,
- showFirstLast,
- containerNode,
}, false);
},
- };
-};
-
-export default connectPagination;
+ });
+}
diff --git a/src/widgets/pagination/__tests__/pagination-test.js b/src/widgets/pagination/__tests__/pagination-test.js
index 153fdf133d..b5bce0f41a 100644
--- a/src/widgets/pagination/__tests__/pagination-test.js
+++ b/src/widgets/pagination/__tests__/pagination-test.js
@@ -76,7 +76,7 @@ describe('pagination()', () => {
const getContainerNode = sinon.stub().returns({
scrollIntoView,
});
- connectPagination.__Rewire__('getContainerNode', getContainerNode);
+ pagination.__Rewire__('getContainerNode', getContainerNode);
});
it('should not scroll', () => {
@@ -89,7 +89,9 @@ describe('pagination()', () => {
it('should scroll to body', () => {
widget = pagination({container});
widget.init({helper});
- widget.setPage(helper, 2);
+ widget.render({results, helper, state: {page: 0}});
+ const {props: {setCurrentPage}} = ReactDOM.render.firstCall.args[0];
+ setCurrentPage(2);
expect(scrollIntoView.calledOnce).toBe(true, 'scrollIntoView called once');
});
diff --git a/src/widgets/pagination/pagination.js b/src/widgets/pagination/pagination.js
index 26212813c2..2e77910fe1 100644
--- a/src/widgets/pagination/pagination.js
+++ b/src/widgets/pagination/pagination.js
@@ -1,8 +1,79 @@
+import defaults from 'lodash/defaults';
+
import React from 'react';
import ReactDOM from 'react-dom';
+import cx from 'classnames';
+
import Pagination from '../../components/Pagination/Pagination.js';
import connectPagination from '../../connectors/pagination/connectPagination.js';
+import {bemHelper, getContainerNode} from '../../lib/utils.js';
+
+const defaultLabels = {
+ previous: '‹',
+ next: '›',
+ first: '«',
+ last: '»',
+};
+
+const bem = bemHelper('ais-pagination');
+
+const renderer = ({
+ containerNode,
+ cssClasses,
+ labels,
+ showFirstLast,
+ padding,
+ autoHideContainer,
+ scrollToNode,
+}) => ({
+ createURL,
+ currentPage,
+ nbHits,
+ nbPages,
+ setPage,
+}, isFirstRendering) => {
+ if (isFirstRendering) return;
+
+ const setCurrentPage = () => {
+ setPage();
+
+ if (scrollToNode !== false) {
+ scrollToNode.scrollIntoView();
+ }
+ };
+
+ const shouldAutoHideContainer = autoHideContainer && nbHits === 0;
+
+ ReactDOM.render(
+ ,
+ containerNode
+ );
+};
+
+const usage = `Usage:
+pagination({
+ container,
+ [ cssClasses.{root,item,page,previous,next,first,last,active,disabled}={} ],
+ [ labels.{previous,next,first,last} ],
+ [ maxPages ],
+ [ padding=3 ],
+ [ showFirstLast=true ],
+ [ autoHideContainer=true ],
+ [ scrollTo='body' ]
+})`;
+
/**
* Add a pagination menu to navigate through the results
* @function pagination
@@ -28,37 +99,56 @@ import connectPagination from '../../connectors/pagination/connectPagination.js'
* @param {string|string[]} [options.cssClasses.last] CSS classes added to the last ``
* @param {string|string[]} [options.cssClasses.active] CSS classes added to the active ``
* @param {string|string[]} [options.cssClasses.disabled] CSS classes added to the disabled ``
- * @return {Object}
+ * @return {Object} widget
*/
-export default connectPagination(defaultRendering);
+export default function pagination({
+ container,
+ labels: userLabels = defaultLabels,
+ cssClasses: userCssClasses = {},
+ maxPages,
+ padding = 3,
+ showFirstLast = true,
+ autoHideContainer = true,
+ scrollTo: userScrollTo = 'body',
+} = {}) {
+ if (!container) {
+ throw new Error(usage);
+ }
-function defaultRendering({
- createURL,
- cssClasses,
- currentPage,
- labels,
- nbHits,
- nbPages,
- padding,
- setPage,
- shouldAutoHideContainer,
- showFirstLast,
- containerNode,
-}, isFirstRendering) {
- if (isFirstRendering) return;
- ReactDOM.render(
- ,
- containerNode
- );
+ const containerNode = getContainerNode(container);
+
+ const scrollTo = userScrollTo === true ? 'body' : userScrollTo;
+ const scrollToNode = scrollTo !== false ? getContainerNode(scrollTo) : false;
+
+ const cssClasses = {
+ root: cx(bem(null), userCssClasses.root),
+ item: cx(bem('item'), userCssClasses.item),
+ link: cx(bem('link'), userCssClasses.link),
+ page: cx(bem('item', 'page'), userCssClasses.page),
+ previous: cx(bem('item', 'previous'), userCssClasses.previous),
+ next: cx(bem('item', 'next'), userCssClasses.next),
+ first: cx(bem('item', 'first'), userCssClasses.first),
+ last: cx(bem('item', 'last'), userCssClasses.last),
+ active: cx(bem('item', 'active'), userCssClasses.active),
+ disabled: cx(bem('item', 'disabled'), userCssClasses.disabled),
+ };
+
+ const labels = defaults(userLabels, defaultLabels);
+
+ const specializedRenderer = renderer({
+ containerNode,
+ cssClasses,
+ labels,
+ showFirstLast,
+ padding,
+ autoHideContainer,
+ scrollToNode,
+ });
+
+ try {
+ const makeWidget = connectPagination(specializedRenderer);
+ return makeWidget({maxPages});
+ } catch (e) {
+ throw new Error(usage);
+ }
}