diff --git a/packages/react-instantsearch/src/components/StarRating.js b/packages/react-instantsearch/src/components/StarRating.js
index d4e569005e..af6d2327d9 100644
--- a/packages/react-instantsearch/src/components/StarRating.js
+++ b/packages/react-instantsearch/src/components/StarRating.js
@@ -1,7 +1,7 @@
import React, {PropTypes, Component} from 'react';
import translatable from '../core/translatable';
import classNames from './classNames.js';
-
+import {isEmpty} from 'lodash';
const cx = classNames('StarRating');
class StarRating extends Component {
@@ -44,10 +44,12 @@ class StarRating extends Component {
}
}
- buildItem({max, lowerBound, count, translate, createURL, isLowest}) {
- const selected = lowerBound === this.props.currentRefinement.min &&
- max === this.props.currentRefinement.max;
+ buildItem({max, lowerBound, count, translate, createURL, isLastSelectableItem}) {
const disabled = !count;
+ const isCurrentMinLower = this.props.currentRefinement.min < lowerBound;
+ const selected = isLastSelectableItem && isCurrentMinLower ||
+ !disabled && lowerBound === this.props.currentRefinement.min
+ && max === this.props.currentRefinement.max;
const icons = [];
for (let icon = 0; icon < max; icon++) {
@@ -65,7 +67,7 @@ class StarRating extends Component {
// The last item of the list (the default item), should not
// be clickable if it is selected.
- const isLastAndSelect = isLowest && selected;
+ const isLastAndSelect = isLastSelectableItem && selected;
const StarsWrapper = isLastAndSelect ? 'div' : 'a';
const onClickHandler = isLastAndSelect ? {} : {
href: createURL({min: lowerBound, max}),
@@ -101,13 +103,12 @@ class StarRating extends Component {
render() {
const {translate, refine, min, max, count, createURL, canRefine} = this.props;
-
const items = [];
for (let i = max; i >= min; i--) {
- const itemCount = count.reduce((acc, item) => {
- if (item.value >= i) acc = acc + item.count;
- return acc;
- }, 0);
+ const hasCount = !isEmpty(count.filter(item => Number(item.value) === i));
+ const lastSelectableItem = count.reduce((acc, item) => item.value < acc.value || !acc.value && hasCount
+ ? item : acc, {});
+ const itemCount = count.reduce((acc, item) => item.value >= i && hasCount ? acc + item.count : acc, 0);
items.push(this.buildItem({
lowerBound: i,
max,
@@ -115,7 +116,7 @@ class StarRating extends Component {
count: itemCount,
translate,
createURL,
- isLowest: i === min,
+ isLastSelectableItem: i === Number(lastSelectableItem.value),
}));
}
return (
diff --git a/packages/react-instantsearch/src/components/StarRating.test.js b/packages/react-instantsearch/src/components/StarRating.test.js
index 15e42fc1d5..3a614e2d13 100644
--- a/packages/react-instantsearch/src/components/StarRating.test.js
+++ b/packages/react-instantsearch/src/components/StarRating.test.js
@@ -56,7 +56,7 @@ describe('StarRating', () => {
min={1}
max={5}
currentRefinement={{min: 1, max: 5}}
- count={[{value: '1', count: 1},
+ count={[{value: '1', count: 4},
{value: '2', count: 2},
{value: '3', count: 3},
{value: '4', count: 3},
@@ -139,6 +139,26 @@ describe('StarRating', () => {
expect(refine.mock.calls[0][0]).toEqual({min: 1, max: 5});
wrapper.unmount();
});
+
+ it('the default selected range should be the lowest one with count', () => {
+ const wrapper = mount(starRating);
+ wrapper.setProps({count: [
+ {value: '2', count: 2},
+ {value: '3', count: 3},
+ {value: '4', count: 3},
+ ]});
+
+ const links = wrapper.find('.ais-StarRating__ratingLink');
+ expect(links.first().hasClass('ais-StarRating__ratingLinkSelected')).toBe(false);
+
+ const selected = wrapper.find('.ais-StarRating__ratingLinkSelected');
+ expect(selected.find('.ais-StarRating__ratingIconEmpty').length).toEqual(3);
+ expect(selected.find('.ais-StarRating__ratingIcon').length).toEqual(2);
+ expect(selected.text()).toContain('8');
+
+ wrapper.unmount();
+ });
+
describe('Panel compatibility', () => {
it('Should indicate when no more refinement', () => {
const canRefine = jest.fn();
diff --git a/packages/react-instantsearch/src/connectors/connectRange.js b/packages/react-instantsearch/src/connectors/connectRange.js
index 2f4bb5d3de..6ead3e1999 100644
--- a/packages/react-instantsearch/src/connectors/connectRange.js
+++ b/packages/react-instantsearch/src/connectors/connectRange.js
@@ -71,7 +71,6 @@ export default createConnector({
const stats = searchResults.results.getFacetByName(attributeName) ?
searchResults.results.getFacetStats(attributeName) : null;
-
if (!stats) {
return {
canRefine: false,
diff --git a/stories/StarRating.stories.js b/stories/StarRating.stories.js
index e022049812..572ba46191 100644
--- a/stories/StarRating.stories.js
+++ b/stories/StarRating.stories.js
@@ -1,6 +1,6 @@
import React from 'react';
import {storiesOf} from '@kadira/storybook';
-import {StarRating, Panel, SearchBox} from '../packages/react-instantsearch/dom';
+import {StarRating, Panel, SearchBox, Configure} from '../packages/react-instantsearch/dom';
import {withKnobs, object, number} from '@kadira/storybook-addon-knobs';
import {WrapWithHits} from './util';
@@ -27,6 +27,11 @@ stories.add('default', () =>
+).add('with filter on rating', () =>
+
+
+
+
).add('playground', () =>