Skip to content

Commit

Permalink
fix(show-more): should hide button when show more is not available
Browse files Browse the repository at this point in the history
As noticed by @timkelty in #2160, showMore button should not be rendered
if there are not enough items to display based on the limits. With the
new connector API, this means that we should add a new parameter to
the renderer to give the information that this button should be
displayed.

fixes #2160
  • Loading branch information
Alexandre Stanislawski committed May 22, 2017
1 parent 5001a63 commit 7947b22
Show file tree
Hide file tree
Showing 9 changed files with 159 additions and 2 deletions.
3 changes: 2 additions & 1 deletion src/components/RefinementList/RefinementList.js
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,7 @@ export class RawRefinementList extends React.Component {
cssClassList.push(`${this.props.cssClasses.depth}${this.props.depth}`);
}

const showMoreBtn = this.props.showMore === true ?
const showMoreBtn = this.props.showMore === true && this.props.canToggleShowMore ?
<Template
rootProps={{onClick: this.props.toggleShowMore}}
templateKey={`show-more-${this.props.isShowingMore ? 'active' : 'inactive'}`}
Expand Down Expand Up @@ -193,6 +193,7 @@ RawRefinementList.propTypes = {
toggleShowMore: PropTypes.func,
isShowingMore: PropTypes.bool,
hasExhaustiveItems: PropTypes.bool,
canToggleShowMore: PropTypes.bool,
};

RawRefinementList.defaultProps = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,7 @@ describe('RefinementList', () => {
],
showMore: true,
isShowingMore: false,
canToggleShowMore: true,
};

// When
Expand Down Expand Up @@ -201,6 +202,7 @@ describe('RefinementList', () => {
],
showMore: true,
isShowingMore: true,
canToggleShowMore: true,
};

// When
Expand Down
49 changes: 49 additions & 0 deletions src/connectors/menu/__tests__/connectMenu-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ describe('connectMenu', () => {
const firstRenderingOptions = rendering.lastCall.args[0];
expect(firstRenderingOptions.isShowingMore).toBe(false);
expect(firstRenderingOptions.items.length).toBe(1);
expect(firstRenderingOptions.canToggleShowMore).toBe(true);

// When
firstRenderingOptions.toggleShowMore();
Expand All @@ -338,6 +339,54 @@ describe('connectMenu', () => {
const secondRenderingOptions = rendering.lastCall.args[0];
expect(secondRenderingOptions.isShowingMore).toBe(true);
expect(secondRenderingOptions.items.length).toBe(2);
expect(firstRenderingOptions.canToggleShowMore).toBe(true);
});

it('should set canToggleShowMore to false when there are not enough items', () => {
// Given
const widget = makeWidget({
attributeName: 'category',
limit: 1,
showMoreLimit: 2,
});

// When
const config = widget.getConfiguration({});
const helper = algoliasearchHelper(fakeClient, '', config);

helper.search = jest.fn();
helper.toggleRefinement('category', 'Decoration');

widget.init({
helper,
state: helper.state,
createURL: () => '#',
onHistoryChange: () => {},
});

widget.render({
results: new SearchResults(helper.state, [{
hits: [],
facets: {
category: {
Decoration: 880,
},
},
}, {
facets: {
category: {
Decoration: 880,
},
},
}]),
state: helper.state,
helper,
createURL: () => '#',
});

const firstRenderingOptions = rendering.lastCall.args[0];
expect(firstRenderingOptions.items.length).toBe(1);
expect(firstRenderingOptions.canToggleShowMore).toBe(false);
});
});
});
7 changes: 6 additions & 1 deletion src/connectors/menu/connectMenu.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ Full documentation available at https://community.algolia.com/instantsearch.js/c
* @property {Object} widgetParams All original `CustomMenuWidgetOptions` forwarded to the `renderFn`.
* @property {boolean} isShowingMore True if the menu is displaying all the menu items.
* @property {function} toggleShowMore Toggles the number of values displayed between `limit` and `showMore.limit`.
* @property {boolean} canToggleShowMore `true` if the toggleShowMore button can be activated (enough items to display more or
* already displaying more than limit items)
*/

/**
Expand Down Expand Up @@ -171,11 +173,13 @@ export default function connectMenu(renderFn) {
widgetParams,
isShowingMore: this.isShowingMore,
toggleShowMore: this.cachedToggleShowMore,
canToggleShowMore: false,
}, true);
},

render({results, instantSearchInstance}) {
const items = (results.getFacetValues(attributeName, {sortBy}).data || [])
const facetItems = results.getFacetValues(attributeName, {sortBy}).data || [];
const items = facetItems
.slice(0, this.getLimit())
.map(({name: label, path: value, ...item}) => ({...item, label, value}));

Expand All @@ -190,6 +194,7 @@ export default function connectMenu(renderFn) {
widgetParams,
isShowingMore: this.isShowingMore,
toggleShowMore: this.cachedToggleShowMore,
canToggleShowMore: this.isShowingMore || facetItems.length > this.getLimit(),
}, false);
},
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -185,6 +185,99 @@ describe('connectRefinementList', () => {
expect(helper.hasRefinements('category')).toBe(true);
});

it('If there are too few items then canToggleShowMore is false', () => {
const widget = makeWidget({
attributeName: 'category',
limit: 3,
showMoreLimit: 10,
});

const helper = algoliasearchHelper(fakeClient, '', widget.getConfiguration({}));
helper.search = sinon.stub();

widget.init({
helper,
state: helper.state,
createURL: () => '#',
onHistoryChange: () => {},
});

widget.render({
results: new SearchResults(helper.state, [{
hits: [],
facets: {
category: {
c1: 880,
c2: 47,
},
},
}, {
facets: {
category: {
c1: 880,
c2: 47,
},
},
}]),
state: helper.state,
helper,
createURL: () => '#',
});

const secondRenderingOptions = rendering.lastCall.args[0];
expect(secondRenderingOptions.canToggleShowMore).toBe(false);
});

it('If there are too few items then canToggleShowMore is false', () => {
const widget = makeWidget({
attributeName: 'category',
limit: 1,
showMoreLimit: 10,
});

const helper = algoliasearchHelper(fakeClient, '', widget.getConfiguration({}));
helper.search = sinon.stub();

widget.init({
helper,
state: helper.state,
createURL: () => '#',
onHistoryChange: () => {},
});

widget.render({
results: new SearchResults(helper.state, [{
hits: [],
facets: {
category: {
c1: 880,
c2: 47,
},
},
}, {
facets: {
category: {
c1: 880,
c2: 47,
},
},
}]),
state: helper.state,
helper,
createURL: () => '#',
});

const secondRenderingOptions = rendering.lastCall.args[0];
expect(secondRenderingOptions.canToggleShowMore).toBe(true);

// toggleShowMore will set the state of the show more to true
// therefore it's always possible to go back and show less items
secondRenderingOptions.toggleShowMore();

const thirdRenderingOptions = rendering.lastCall.args[0];
expect(thirdRenderingOptions.canToggleShowMore).toBe(true);
});

it('Show more should toggle between two limits', () => {
const widget = makeWidget({
attributeName: 'category',
Expand Down
2 changes: 2 additions & 0 deletions src/connectors/refinement-list/connectRefinementList.js
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ export const checkUsage = ({attributeName, operator, usageMessage, showMoreLimit
* @property {function} searchForItems Searches for values inside the list.
* @property {boolean} isFromSearch `true` if the values are from an index search.
* @property {boolean} canRefine `true` if a refinement can be applied.
* @property {boolean} canToggleShowMore `true` if the show more feature is available and there are enough items to show more
* @property {Object} widgetParams All original `CustomRefinementListWidgetOptions` forwarded to the `renderFn`.
* @property {boolean} isShowingMore True if the menu is displaying all the menu items.
* @property {function} toggleShowMore Toggles the number of values displayed between `limit` and `showMoreLimit`.
Expand Down Expand Up @@ -177,6 +178,7 @@ export default function connectRefinementList(renderFn) {
canRefine: isFromSearch || items.length > 0,
widgetParams,
isShowingMore,
canToggleShowMore: isShowingMore || !hasExhaustiveItems,
toggleShowMore,
hasExhaustiveItems,
}, isFirstSearch);
Expand Down
1 change: 1 addition & 0 deletions src/widgets/menu/__tests__/__snapshots__/menu-test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

exports[`menu snapshot 1`] = `
<HeaderFooter-AutoHide
canToggleShowMore={false}
collapsible={false}
createURL={[Function]}
cssClasses={
Expand Down
2 changes: 2 additions & 0 deletions src/widgets/menu/menu.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ const renderer = ({
instantSearchInstance,
isShowingMore,
toggleShowMore,
canToggleShowMore,
}, isFirstRendering) => {
if (isFirstRendering) {
renderState.templateProps = prepareTemplateProps({
Expand All @@ -59,6 +60,7 @@ const renderer = ({
toggleRefinement={ refine }
toggleShowMore={ toggleShowMore }
isShowingMore={ isShowingMore }
canToggleShowMore={ canToggleShowMore }
/>,
containerNode
);
Expand Down
2 changes: 2 additions & 0 deletions src/widgets/refinement-list/refinement-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const renderer = ({
toggleShowMore,
isShowingMore,
hasExhaustiveItems,
canToggleShowMore,
}, isFirstRendering) => {
if (isFirstRendering) {
renderState.templateProps = prepareTemplateProps({
Expand Down Expand Up @@ -71,6 +72,7 @@ const renderer = ({
toggleShowMore={toggleShowMore}
isShowingMore={isShowingMore}
hasExhaustiveItems={hasExhaustiveItems}
canToggleShowMore={canToggleShowMore}
/>,
containerNode
);
Expand Down

0 comments on commit 7947b22

Please sign in to comment.