Skip to content

Commit 75243b0

Browse files
author
Alexandre Stanislawski
committed
feat(connectors): jsDoc connectHitsPerPageSelector
1 parent c924043 commit 75243b0

File tree

2 files changed

+99
-69
lines changed

2 files changed

+99
-69
lines changed
Lines changed: 98 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,117 @@
11
import some from 'lodash/some';
22

3+
import {checkRendering} from '../../lib/utils.js';
4+
5+
const usage = `Usage:
6+
var customHitsPerPage = connectHitsPerPageSelector(function render(params, isFirstRendering) {
7+
// params = {
8+
// options,
9+
// currentValue,
10+
// setValue,
11+
// hasNoResults,
12+
// instantSearchInstance,
13+
// widgetParams,
14+
// }
15+
});
16+
search.addWidget(
17+
options: [
18+
{value: 10, label: '10 results per page'},
19+
{value: 42, label: '42 results per page'},
20+
],
21+
);
22+
Full documentation available at https://community.algolia.com/instantsearch.js/connectors/connectHitsPerPageSelector.html
23+
`;
24+
325
/**
4-
* Instantiate a dropdown element to choose the number of hits to display per page
5-
* @function connectHitsPerPageSelector
6-
* @param {string|DOMElement} options.container CSS Selector or DOMElement to insert the widget
7-
* @param {Array} options.options Array of objects defining the different values and labels
8-
* @param {number} options.options[0].value number of hits to display per page
9-
* @param {string} options.options[0].label Label to display in the option
10-
* @param {boolean} [options.autoHideContainer=false] Hide the container when no results match
11-
* @param {Object} [options.cssClasses] CSS classes to be added
12-
* @param {string|string[]} [options.cssClasses.root] CSS classes added to the parent `<select>`
13-
* @param {string|string[]} [options.cssClasses.item] CSS classes added to each `<option>`
14-
* @return {Object}
26+
* @typedef HitsPerPageRenderingOptions
27+
* @property {Object[]} options Array of objects defining the different values and labels
28+
* @property {number} options[0].value number of hits to display per page
29+
* @property {string} options[0].label Label to display in the option
30+
* @property {number} currentValue the currently selected value of hitsPerPage
31+
* @property {function(number)} setValue sets the number of hits per page and trigger a search
32+
* @property {boolean} hasNoResults true if there were no results in the last search
33+
* @property {InstantSearch} instantSearchInstance the instance of instantsearch on which the widget is attached
34+
* @property {Object} widgetParams all original options forwarded to rendering
1535
*/
1636

17-
const usage = `Usage:
18-
hitsPerPageSelector({
19-
container,
20-
options,
21-
})`;
37+
/**
38+
* @typedef HitsPerPageWidgetOptions
39+
* @property {Object[]} options Array of objects defining the different values and labels
40+
* @property {number} options[0].value number of hits to display per page
41+
* @property {string} options[0].label Label to display in the option
42+
*/
2243

23-
const connectHitsPerPageSelector = renderHitsPerPageSelector => (widgetParams = {}) => {
24-
const {options: userOptions} = widgetParams;
25-
let options = userOptions;
44+
/**
45+
* Creates a custom HitsPerPage widget factory.
46+
* @param {function(HitsPerPageRenderingOptions, boolean)} renderFn function that renders the hits widget
47+
* @return {function(HitsPerPageWidgetOptions)} a custom HitsPerPage widget factory
48+
*/
49+
export default function connectHitsPerPageSelector(renderFn) {
50+
checkRendering(renderFn, usage);
51+
52+
return (widgetParams = {}) => {
53+
const {options: userOptions} = widgetParams;
54+
let options = userOptions;
2655

27-
if (!options) {
28-
throw new Error(usage);
29-
}
56+
if (!options) {
57+
throw new Error(usage);
58+
}
3059

31-
return {
32-
init({helper, state}) {
33-
const isCurrentInOptions = some(
34-
options,
35-
option => Number(state.hitsPerPage) === Number(option.value)
36-
);
60+
return {
61+
init({helper, state, instantSearchInstance}) {
62+
const isCurrentInOptions = some(
63+
options,
64+
option => Number(state.hitsPerPage) === Number(option.value)
65+
);
3766

38-
if (!isCurrentInOptions) {
39-
if (state.hitsPerPage === undefined) {
40-
if (window.console) {
67+
if (!isCurrentInOptions) {
68+
if (state.hitsPerPage === undefined) {
69+
if (window.console) {
70+
window.console.log(
71+
`[Warning][hitsPerPageSelector] hitsPerPage not defined.
72+
You should probably use a \`hits\` widget or set the value \`hitsPerPage\`
73+
using the searchParameters attribute of the instantsearch constructor.`
74+
);
75+
}
76+
} else if (window.console) {
4177
window.console.log(
42-
`[Warning][hitsPerPageSelector] hitsPerPage not defined.
43-
You should probably use a \`hits\` widget or set the value \`hitsPerPage\`
44-
using the searchParameters attribute of the instantsearch constructor.`
78+
`[Warning][hitsPerPageSelector] No option in \`options\`
79+
with \`value: hitsPerPage\` (hitsPerPage: ${state.hitsPerPage})`
4580
);
4681
}
47-
} else if (window.console) {
48-
window.console.log(
49-
`[Warning][hitsPerPageSelector] No option in \`options\`
50-
with \`value: hitsPerPage\` (hitsPerPage: ${state.hitsPerPage})`
51-
);
52-
}
5382

54-
options = [{value: undefined, label: ''}].concat(options);
55-
}
83+
options = [{value: undefined, label: ''}].concat(options);
84+
}
5685

57-
const currentValue = state.hitsPerPage;
86+
const currentValue = state.hitsPerPage;
5887

59-
this.setHitsPerPage = value => helper
60-
.setQueryParameter('hitsPerPage', value)
61-
.search();
88+
this.setHitsPerPage = value => helper
89+
.setQueryParameter('hitsPerPage', value)
90+
.search();
6291

63-
renderHitsPerPageSelector({
64-
currentValue,
65-
options,
66-
setValue: this.setHitsPerPage,
67-
hasNoResults: true,
68-
widgetParams,
69-
}, true);
70-
},
92+
renderFn({
93+
currentValue,
94+
options,
95+
setValue: this.setHitsPerPage,
96+
hasNoResults: true,
97+
widgetParams,
98+
instantSearchInstance,
99+
}, true);
100+
},
71101

72-
render({state, results}) {
73-
const currentValue = state.hitsPerPage;
74-
const hasNoResults = results.nbHits === 0;
102+
render({state, results, instantSearchInstance}) {
103+
const currentValue = state.hitsPerPage;
104+
const hasNoResults = results.nbHits === 0;
75105

76-
renderHitsPerPageSelector({
77-
currentValue,
78-
options,
79-
setValue: this.setHitsPerPage,
80-
hasNoResults,
81-
widgetParams,
82-
}, false);
83-
},
106+
renderFn({
107+
currentValue,
108+
options,
109+
setValue: this.setHitsPerPage,
110+
hasNoResults,
111+
widgetParams,
112+
instantSearchInstance,
113+
}, false);
114+
},
115+
};
84116
};
85-
};
86-
87-
export default connectHitsPerPageSelector;
117+
}

src/widgets/hits-per-page-selector/hits-per-page-selector.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ hitsPerPageSelector({
4949
* Instantiate a dropdown element to choose the number of hits to display per page
5050
* @function hitsPerPageSelector
5151
* @param {string|DOMElement} $0.container CSS Selector or DOMElement to insert the widget
52-
* @param {Array} $0.options Array of objects defining the different values and labels
52+
* @param {Object[]} $0.options Array of objects defining the different values and labels
5353
* @param {number} $0.options[0].value number of hits to display per page
5454
* @param {string} $0.options[0].label Label to display in the option
5555
* @param {boolean} [$0.autoHideContainer=false] Hide the container when no results match

0 commit comments

Comments
 (0)