diff --git a/README.md b/README.md
index c3bd37cfcc..120b8b0ef7 100644
--- a/README.md
+++ b/README.md
@@ -352,17 +352,15 @@ search.addWidget(
/**
* Display various stats about the current search state
* @param {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
- * @param {Object} [options.cssClasses] CSS classes to add to the default template
+ * @param {Object} [options.cssClasses] CSS classes to add
* @param {String} [options.cssClasses.root] CSS class to add to the root element
+ * @param {String} [options.cssClasses.header] CSS class to add to the header element
+ * @param {String} [options.cssClasses.body] CSS class to add to the body element
+ * @param {String} [options.cssClasses.footer] CSS class to add to the footer element
* @param {String} [options.cssClasses.time] CSS class to add to the element wrapping the time processingTimeMs
* @param {Object} [options.templates] Templates to use for the widget
* @param {String|Function} [options.templates.header=''] Header template
- * @param {String|Function} [options.templates.body='
- {{#hasNoResults}}No results{{/hasNoResults}}
- {{#hasOneResult}}1 result{{/hasOneResult}}
- {{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}}
- found in {{processingTimeMS}}ms
-
'] Body template
+ * @param {String|Function} [options.templates.body] Body template
* @param {String|Function} [options.templates.footer=''] Footer template
* @param {Function} [options.transformData] Function to change the object passed to the `body` template
* @param {boolean} [hideWhenNoResults=true] Hide the container when there's no results
@@ -370,8 +368,6 @@ search.addWidget(
*/
```
-
-
#### Usage
```html
@@ -389,6 +385,32 @@ search.addWidget(
);
```
+### Styling
+
+```html
+
+
+
+ 42 results found in 42ms
+
+
+
+```
+
+```css
+.ais-stats {
+}
+.ais-stats--header {
+}
+.ais-stats--body {
+}
+.ais-stats--time {
+ font-size: small;
+}
+.ais-stats--footer {
+}
+```
+
### indexSelector
![Example of the indexSelector widget][indexSelector]
@@ -623,7 +645,7 @@ search.addWidget(
* @param {String} [options.operator='or'] How to apply refinements. Possible values: `or`, `and`
* @param {String[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
* @param {String} [options.limit=1000] How much facet values to get
- * @param {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, list, item
+ * @param {Object} [options.cssClasses] CSS classes to add
* @param {String|String[]} [options.cssClasses.root] CSS class to add to the root element
* @param {String|String[]} [options.cssClasses.header] CSS class to add to the header element
* @param {String|String[]} [options.cssClasses.body] CSS class to add to the body element
diff --git a/components/Stats/Stats.js b/components/Stats/Stats.js
index 747df1c4dd..5882b9c8d3 100644
--- a/components/Stats/Stats.js
+++ b/components/Stats/Stats.js
@@ -1,8 +1,6 @@
var React = require('react');
var Template = require('../Template');
-var bem = require('../../lib/utils').bemHelper('ais-stats');
-var cx = require('classnames');
class Stats extends React.Component {
render() {
@@ -16,10 +14,7 @@ class Stats extends React.Component {
page: this.props.page,
processingTimeMS: this.props.processingTimeMS,
query: this.props.query,
- cssClasses: {
- root: cx(bem(null), this.props.cssClasses.root),
- time: cx(bem('time'), this.props.cssClasses.time)
- }
+ cssClasses: this.props.cssClasses
};
return (
@@ -29,6 +24,12 @@ class Stats extends React.Component {
}
Stats.propTypes = {
+ cssClasses: React.PropTypes.shape({
+ time: React.PropTypes.oneOfType([
+ React.PropTypes.string,
+ React.PropTypes.arrayOf(React.PropTypes.string)
+ ])
+ }),
hitsPerPage: React.PropTypes.number,
nbHits: React.PropTypes.number,
nbPages: React.PropTypes.number,
diff --git a/components/Stats/__tests__/Stats-test.js b/components/Stats/__tests__/Stats-test.js
index 88964c6020..ed32db1f47 100644
--- a/components/Stats/__tests__/Stats-test.js
+++ b/components/Stats/__tests__/Stats-test.js
@@ -6,9 +6,6 @@ import TestUtils from 'react-addons-test-utils';
import Stats from '../Stats';
import Template from '../../Template';
-var bem = require('../../../lib/utils').bemHelper('ais-stats');
-var cx = require('classnames');
-
describe('Stats', () => {
var renderer;
@@ -21,10 +18,7 @@ describe('Stats', () => {
it('should render ', () => {
var out = render();
var defaultProps = {
- cssClasses: {
- root: cx(bem(null)),
- time: cx(bem('time'))
- },
+ cssClasses: {},
hasManyResults: true,
hasNoResults: false,
hasOneResult: false
diff --git a/themes/default/default.css b/themes/default/default.css
index 59b16ec2b7..7760d012eb 100644
--- a/themes/default/default.css
+++ b/themes/default/default.css
@@ -27,9 +27,15 @@
/* STATS */
.ais-stats {
}
+.ais-stats--header {
+}
+.ais-stats--body {
+}
.ais-stats--time {
font-size: small;
}
+.ais-stats--footer {
+}
/* INDEX SELECTOR */
.ais-index-selector {
@@ -51,7 +57,7 @@
}
.ais-pagination--item-previous {
}
-.ais-pagination--item-page {
+.ais-pagination--item-page {
}
.ais-pagination--item-page__active {
}
diff --git a/widgets/stats/__tests__/stats-test.js b/widgets/stats/__tests__/stats-test.js
index fdb172a0ed..75f1ccc83e 100644
--- a/widgets/stats/__tests__/stats-test.js
+++ b/widgets/stats/__tests__/stats-test.js
@@ -51,7 +51,13 @@ describe('stats()', () => {
expect(headerFooter.calledOnce).toBe(true, 'headerFooter called once');
expect(ReactDOM.render.firstCall.args[0]).toEqualJSX(
- {{#hasNoResults}}No results{{/hasNoResults}}
+ body: `{{#hasNoResults}}No results{{/hasNoResults}}
{{#hasOneResult}}1 result{{/hasOneResult}}
{{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}}
- found in {{processingTimeMS}}ms
-`,
+ found in {{processingTimeMS}}ms`,
footer: ''
};
diff --git a/widgets/stats/stats.js b/widgets/stats/stats.js
index 0630336a02..20f75f5fbe 100644
--- a/widgets/stats/stats.js
+++ b/widgets/stats/stats.js
@@ -4,23 +4,23 @@ var ReactDOM = require('react-dom');
var utils = require('../../lib/utils.js');
var autoHide = require('../../decorators/autoHide');
var headerFooter = require('../../decorators/headerFooter');
+var bem = require('../../lib/utils').bemHelper('ais-stats');
+var cx = require('classnames/dedupe');
var defaultTemplates = require('./defaultTemplates.js');
/**
* Display various stats about the current search state
* @param {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
- * @param {Object} [options.cssClasses] CSS classes to add to the default template
+ * @param {Object} [options.cssClasses] CSS classes to add
* @param {String} [options.cssClasses.root] CSS class to add to the root element
+ * @param {String} [options.cssClasses.header] CSS class to add to the header element
+ * @param {String} [options.cssClasses.body] CSS class to add to the body element
+ * @param {String} [options.cssClasses.footer] CSS class to add to the footer element
* @param {String} [options.cssClasses.time] CSS class to add to the element wrapping the time processingTimeMs
* @param {Object} [options.templates] Templates to use for the widget
* @param {String|Function} [options.templates.header=''] Header template
- * @param {String|Function} [options.templates.body='
- {{#hasNoResults}}No results{{/hasNoResults}}
- {{#hasOneResult}}1 result{{/hasOneResult}}
- {{#hasManyResults}}{{#helpers.formatNumber}}{{nbHits}}{{/helpers.formatNumber}} results{{/hasManyResults}}
- found in {{processingTimeMS}}ms
-
'] Body template
+ * @param {String|Function} [options.templates.body] Body template
* @param {String|Function} [options.templates.footer=''] Footer template
* @param {Function} [options.transformData] Function to change the object passed to the `body` template
* @param {boolean} [hideWhenNoResults=true] Hide the container when there's no results
@@ -49,6 +49,15 @@ function stats({
});
var Stats = autoHide(headerFooter(require('../../components/Stats/Stats.js')));
+
+ cssClasses = {
+ body: cx(bem('body'), cssClasses.body),
+ footer: cx(bem('footer'), cssClasses.footer),
+ header: cx(bem('header'), cssClasses.header),
+ root: cx(bem(null), cssClasses.root),
+ time: cx(bem('time'), cssClasses.time)
+ };
+
ReactDOM.render(