diff --git a/src/connectors/menu/__tests__/connectMenu-test.js b/src/connectors/menu/__tests__/connectMenu-test.js index f3123e7757..94af80e515 100644 --- a/src/connectors/menu/__tests__/connectMenu-test.js +++ b/src/connectors/menu/__tests__/connectMenu-test.js @@ -300,21 +300,30 @@ describe('connectMenu', () => { }); describe('showMore', () => { - it('should throw when `showMoreLimit` is lower than `limit`', () => { - expect(() => - connectMenu(() => {})({ - attribute: 'myFacet', - limit: 10, - showMoreLimit: 1, - }) - ).toThrow(); + it('should set `maxValuesPerFacet` by default', () => { + const widget = makeWidget({ + attribute: 'myFacet', + limit: 10, + showMore: true, + }); + + expect(widget.getConfiguration({})).toEqual({ + hierarchicalFacets: [ + { + name: 'myFacet', + attributes: ['myFacet'], + }, + ], + maxValuesPerFacet: 20, + }); }); it('should provide `showMoreLimit` as `maxValuesPerFacet`', () => { const widget = makeWidget({ attribute: 'myFacet', limit: 10, - showMoreLimit: 20, + showMore: true, + showMoreLimit: 30, }); expect(widget.getConfiguration({})).toEqual({ @@ -324,7 +333,7 @@ describe('connectMenu', () => { attributes: ['myFacet'], }, ], - maxValuesPerFacet: 20, + maxValuesPerFacet: 30, }); }); @@ -333,6 +342,7 @@ describe('connectMenu', () => { const widget = makeWidget({ attribute: 'myFacet', limit: 10, + showMore: true, showMoreLimit: 20, }); @@ -361,6 +371,7 @@ describe('connectMenu', () => { const widget = makeWidget({ attribute: 'category', limit: 1, + showMore: true, showMoreLimit: 2, }); @@ -425,6 +436,7 @@ describe('connectMenu', () => { const widget = makeWidget({ attribute: 'category', limit: 1, + showMore: true, showMoreLimit: 2, }); diff --git a/src/connectors/menu/connectMenu.js b/src/connectors/menu/connectMenu.js index 17c5f764e6..a861d0f719 100644 --- a/src/connectors/menu/connectMenu.js +++ b/src/connectors/menu/connectMenu.js @@ -16,8 +16,9 @@ var customMenu = connectMenu(function render(params, isFirstRendering) { search.addWidget( customMenu({ attribute, - [ limit ], - [ showMoreLimit ], + [ limit = 10 ], + [ showMore = false ], + [ showMoreLimit = 20 ], [ sortBy = ['isRefined', 'name:asc'] ], [ transformItems ] }) @@ -37,7 +38,7 @@ Full documentation available at https://community.algolia.com/instantsearch.js/v * @typedef {Object} CustomMenuWidgetOptions * @property {string} attribute Name of the attribute for faceting (eg. "free_shipping"). * @property {number} [limit = 10] How many facets values to retrieve. - * @property {number} [showMoreLimit = 10] How many facets values to retrieve when `toggleShowMore` is called, this value is meant to be greater than `limit` option. + * @property {number} [showMoreLimit = 20] How many facets values to retrieve when `toggleShowMore` is called, this value is meant to be greater than `limit` option. * @property {string[]|function} [sortBy = ['isRefined', 'name:asc']] How to sort refinements. Possible values: `count|isRefined|name:asc|name:desc`. * * You can also use a sort function that behaves like the standard Javascript [compareFunction](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort#Syntax). @@ -113,15 +114,20 @@ export default function connectMenu(renderFn, unmountFn) { const { attribute, limit = 10, + showMore = false, + showMoreLimit = 20, sortBy = ['isRefined', 'name:asc'], - showMoreLimit = limit, transformItems = items => items, } = widgetParams; - if (!attribute || (!isNaN(showMoreLimit) && showMoreLimit < limit)) { + if (!attribute) { throw new Error(usage); } + if (showMore === true && showMoreLimit <= limit) { + throw new Error('`showMoreLimit` should be greater than `limit`.'); + } + return { isShowingMore: false, @@ -167,7 +173,7 @@ export default function connectMenu(renderFn, unmountFn) { const currentMaxValuesPerFacet = configuration.maxValuesPerFacet || 0; widgetConfiguration.maxValuesPerFacet = Math.max( currentMaxValuesPerFacet, - showMoreLimit || limit + showMore ? showMoreLimit : limit ); return widgetConfiguration; @@ -226,7 +232,8 @@ export default function connectMenu(renderFn, unmountFn) { isShowingMore: this.isShowingMore, toggleShowMore: this.cachedToggleShowMore, canToggleShowMore: - this.isShowingMore || facetItems.length > this.getLimit(), + showMore && + (this.isShowingMore || facetItems.length > this.getLimit()), }, false ); diff --git a/src/widgets/menu/__tests__/__snapshots__/menu-test.js.snap b/src/widgets/menu/__tests__/__snapshots__/menu-test.js.snap index a1b0f0eaad..ca540b0c95 100644 --- a/src/widgets/menu/__tests__/__snapshots__/menu-test.js.snap +++ b/src/widgets/menu/__tests__/__snapshots__/menu-test.js.snap @@ -36,7 +36,6 @@ exports[`menu render renders transformed items 1`] = ` ] } isShowingMore={false} - showMore={false} templateProps={ Object { "templates": Object { @@ -96,7 +95,6 @@ exports[`menu render snapshot 1`] = ` ] } isShowingMore={false} - showMore={false} templateProps={ Object { "templates": Object { diff --git a/src/widgets/menu/__tests__/menu-test.js b/src/widgets/menu/__tests__/menu-test.js index 716df658de..7694e50707 100644 --- a/src/widgets/menu/__tests__/menu-test.js +++ b/src/widgets/menu/__tests__/menu-test.js @@ -1,22 +1,25 @@ import menu from '../menu'; describe('menu', () => { + it('throws usage when no container', () => { + expect(menu.bind(null, { attribute: '' })).toThrow(/^Usage/); + }); + it('throws an exception when no attribute', () => { const container = document.createElement('div'); expect(menu.bind(null, { container })).toThrow(/^Usage/); }); - it('throws an exception when no container', () => { - expect(menu.bind(null, { attribute: '' })).toThrow(/^Usage/); - }); - - it('throws an exception when showMoreLimit without showMore option', () => { - const container = document.createElement('div'); + it('throws an exception when showMoreLimit is equal to limit', () => { expect( - menu.bind(null, { attribute: 'attribute', container, showMoreLimit: 10 }) - ).toThrowErrorMatchingInlineSnapshot( - `"\`showMoreLimit\` must be used with \`showMore\` set to \`true\`."` - ); + menu.bind(null, { + attribute: 'attribute', + container: document.createElement('div'), + limit: 20, + showMore: true, + showMoreLimit: 20, + }) + ).toThrow(/^Usage/); }); it('throws an exception when showMoreLimit is lower than limit', () => { @@ -29,9 +32,7 @@ describe('menu', () => { showMore: true, showMoreLimit: 10, }) - ).toThrowErrorMatchingInlineSnapshot( - `"\`showMoreLimit\` should be greater than \`limit\`."` - ); + ).toThrow(/^Usage/); }); describe('render', () => { diff --git a/src/widgets/menu/menu.js b/src/widgets/menu/menu.js index 5b88547c6b..21a80904de 100644 --- a/src/widgets/menu/menu.js +++ b/src/widgets/menu/menu.js @@ -63,7 +63,7 @@ menu({ [ sortBy = ['isRefined', 'name:asc'] ], [ limit = 10 ], [ showMore = false ], - [ showMoreLimit = 10 ], + [ showMoreLimit = 20 ], [ cssClasses.{root, noRefinementRoot, list, item, selectedItem, link, label, count, showMore, disabledShowMore} ], [ templates.{item, showMoreText} ], [ transformItems ] @@ -99,7 +99,7 @@ menu({ * @property {MenuTemplates} [templates] Customize the output through templating. * @property {number} [limit=10] How many facets values to retrieve. * @property {boolean} [showMore=false] Limit the number of results and display a showMore button. - * @property {number} [showMoreLimit=10] How many facets values to retrieve when showing more. + * @property {number} [showMoreLimit=20] Max number of values to display when showing more. * @property {MenuCSSClasses} [cssClasses] CSS classes to add to the wrapping elements. * @property {function(object[]):object[]} [transformItems] Function to transform the items passed to the templates. */ @@ -130,8 +130,8 @@ export default function menu({ container, attribute, sortBy, - limit = 10, - showMore = false, + limit, + showMore, showMoreLimit, cssClasses: userCssClasses = {}, templates = defaultTemplates, @@ -141,16 +141,6 @@ export default function menu({ throw new Error(usage); } - if (!showMore && showMoreLimit) { - throw new Error( - '`showMoreLimit` must be used with `showMore` set to `true`.' - ); - } - - if (showMore && showMoreLimit < limit) { - throw new Error('`showMoreLimit` should be greater than `limit`.'); - } - const containerNode = getContainerNode(container); const cssClasses = { @@ -190,8 +180,9 @@ export default function menu({ return makeWidget({ attribute, limit, - sortBy, + showMore, showMoreLimit, + sortBy, transformItems, }); } catch (error) { diff --git a/storybook/app/builtin/stories/menu.stories.js b/storybook/app/builtin/stories/menu.stories.js index 955971e79c..fc5c5ca722 100644 --- a/storybook/app/builtin/stories/menu.stories.js +++ b/storybook/app/builtin/stories/menu.stories.js @@ -44,7 +44,20 @@ export default () => { attribute: 'categories', limit: 3, showMore: true, - showMoreLimit: 10, + }) + ); + }) + ) + .add( + 'with show more and showMoreLimit', + wrapWithHits(container => { + window.search.addWidget( + instantsearch.widgets.menu({ + container, + attribute: 'categories', + limit: 3, + showMore: true, + showMoreLimit: 6, }) ); })