diff --git a/README.md b/README.md
index 120b8b0ef7..bf1fa45d3d 100644
--- a/README.md
+++ b/README.md
@@ -596,15 +596,20 @@ Note that we are not toggling from `true` to `false` here, but from `true` to
* @param {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {String} options.facetName Name of the attribute for faceting (eg. "free_shipping")
* @param {String} options.label Human-readable name of the filter (eg. "Free Shipping")
- * @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
+ * @param {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
* @param {String|String[]} [options.cssClasses.list] CSS class to add to the list element
- * @param {String|String[]} [options.cssClasses.item] CSS class to add to the item element
+ * @param {String|String[]} [options.cssClasses.item] CSS class to add to each item element
+ * @param {String|String[]} [options.cssClasses.active] CSS class to add to each active element
+ * @param {String|String[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
+ * @param {String|String[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
+ * @param {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
* @param {Object} [options.templates] Templates to use for the widget
* @param {String|Function} [options.templates.header=''] Header template
- * @param {String|Function} [options.templates.item='
- {{name}} {{count}}
- '] Item template
+ * @param {String|Function} [options.templates.item] Item template
* @param {String|Function} [options.templates.footer=''] Footer template
* @param {Function} [options.transformData] Function to change the object passed to the item template
* @param {boolean} [hideWhenNoResults=true] Hide the container when there's no results
@@ -631,6 +636,47 @@ search.addWidget(
);
```
+#### Styling
+
+```html
+
+
+
+
+
+
+ Your value
+ 42
+
+
+
+
+
+
+```
+
+```css
+.ais-toggle {
+}
+.ais-toggle--header {
+}
+.ais-toggle--body {
+}
+.ais-toggle--list {
+}
+.ais-toggle--item {
+}
+.ais-toggle--item__active {
+}
+.ais-toggle--label {
+}
+.ais-toggle--checkbox {
+}
+.ais-toggle--count {
+}
+.ais-toggle--footer {
+}
+```
### refinementList
![Example of the refinementList widget][refinementList]
diff --git a/example/app.js b/example/app.js
index e11fe36922..334a00e818 100644
--- a/example/app.js
+++ b/example/app.js
@@ -105,11 +105,12 @@ search.addWidget(
facetName: 'free_shipping',
label: 'Free Shipping',
cssClasses: {
- header: 'panel-heading'
+ header: 'panel-heading',
+ item: 'panel-body',
+ count: 'badge pull-right'
},
templates: {
- header: 'Shipping',
- item: require('./templates/free-shipping.html')
+ header: 'Shipping'
}
})
);
diff --git a/example/style.css b/example/style.css
index 68f25e74c5..31861504bd 100644
--- a/example/style.css
+++ b/example/style.css
@@ -76,6 +76,7 @@ body {
padding-left: 20px;
}
-.ais-refinement-list--label {
+.ais-refinement-list--label,
+.ais-toggle--label {
display: block;
}
diff --git a/themes/default/default.css b/themes/default/default.css
index 7760d012eb..21c1f15075 100644
--- a/themes/default/default.css
+++ b/themes/default/default.css
@@ -83,6 +83,26 @@
/* MENU */
/* TOGGLE */
+.ais-toggle {
+}
+.ais-toggle--header {
+}
+.ais-toggle--body {
+}
+.ais-toggle--list {
+}
+.ais-toggle--item {
+}
+.ais-toggle--item__active {
+}
+.ais-toggle--label {
+}
+.ais-toggle--checkbox {
+}
+.ais-toggle--count {
+}
+.ais-toggle--footer {
+}
/* HIERARCHICAL MENU */
diff --git a/widgets/toggle/__tests__/toggle-test.js b/widgets/toggle/__tests__/toggle-test.js
index b33723f16b..20cda3954d 100644
--- a/widgets/toggle/__tests__/toggle-test.js
+++ b/widgets/toggle/__tests__/toggle-test.js
@@ -12,8 +12,6 @@ describe('toggle()', () => {
jsdom();
context('bad usage', () => {
- var usage = 'Usage: toggle({container, facetName, label[, template, transformData]})';
-
it('throws when no container', () => {
expect(() => {
toggle();
@@ -23,13 +21,13 @@ describe('toggle()', () => {
it('throws when no facetName', () => {
expect(() => {
toggle({container: document.createElement('div')});
- }).toThrow(usage);
+ }).toThrow(/Usage: /);
});
it('throws when no label', () => {
expect(() => {
toggle({container: document.createElement('div'), facetName: 'Hello'});
- }).toThrow(usage);
+ }).toThrow(/Usage: /);
});
});
@@ -88,7 +86,18 @@ describe('toggle()', () => {
search: sinon.spy()
};
props = {
- cssClasses: {},
+ cssClasses: {
+ root: 'ais-toggle',
+ header: 'ais-toggle--header',
+ body: 'ais-toggle--body',
+ footer: 'ais-toggle--footer',
+ list: 'ais-toggle--list',
+ item: 'ais-toggle--item',
+ active: 'ais-toggle--item__active',
+ label: 'ais-toggle--label',
+ checkbox: 'ais-toggle--checkbox',
+ count: 'ais-toggle--count'
+ },
hideWhenNoResults: true,
templateProps,
toggleRefinement: function() {},
diff --git a/widgets/toggle/defaultTemplates.js b/widgets/toggle/defaultTemplates.js
index 6d9395ab2f..2801c7e434 100644
--- a/widgets/toggle/defaultTemplates.js
+++ b/widgets/toggle/defaultTemplates.js
@@ -1,7 +1,8 @@
module.exports = {
header: '',
- item: `
- {{name}} {{count}}
+ item: `
+ {{name}}
+ {{count}}
`,
footer: ''
};
diff --git a/widgets/toggle/toggle.js b/widgets/toggle/toggle.js
index eac645e987..e5b0be50c1 100644
--- a/widgets/toggle/toggle.js
+++ b/widgets/toggle/toggle.js
@@ -3,6 +3,8 @@ var React = require('react');
var ReactDOM = require('react-dom');
var utils = require('../../lib/utils.js');
+var bem = utils.bemHelper('ais-toggle');
+var cx = require('classnames/dedupe');
var autoHide = require('../../decorators/autoHide');
var headerFooter = require('../../decorators/headerFooter');
@@ -16,15 +18,20 @@ var defaultTemplates = require('./defaultTemplates');
* @param {String|DOMElement} options.container CSS Selector or DOMElement to insert the widget
* @param {String} options.facetName Name of the attribute for faceting (eg. "free_shipping")
* @param {String} options.label Human-readable name of the filter (eg. "Free Shipping")
- * @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
+ * @param {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
* @param {String|String[]} [options.cssClasses.list] CSS class to add to the list element
- * @param {String|String[]} [options.cssClasses.item] CSS class to add to the item element
+ * @param {String|String[]} [options.cssClasses.item] CSS class to add to each item element
+ * @param {String|String[]} [options.cssClasses.active] CSS class to add to each active element
+ * @param {String|String[]} [options.cssClasses.label] CSS class to add to each label element (when using the default template)
+ * @param {String|String[]} [options.cssClasses.checkbox] CSS class to add to each checkbox element (when using the default template)
+ * @param {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
* @param {Object} [options.templates] Templates to use for the widget
* @param {String|Function} [options.templates.header=''] Header template
- * @param {String|Function} [options.templates.item='
- {{name}} {{count}}
- '] Item template
+ * @param {String|Function} [options.templates.item] Item template
* @param {String|Function} [options.templates.footer=''] Footer template
* @param {Function} [options.transformData] Function to change the object passed to the item template
* @param {boolean} [hideWhenNoResults=true] Hide the container when there's no results
@@ -41,9 +48,9 @@ function toggle({
} = {}) {
var RefinementList = autoHide(headerFooter(require('../../components/RefinementList')));
var containerNode = utils.getContainerNode(container);
- var usage = 'Usage: toggle({container, facetName, label[, template, transformData]})';
+ var usage = 'Usage: toggle({container, facetName, label[, cssClasses.{root,header,body,footer,list,item,active,label,checkbox,count}, templates.{header,item,footer}, transformData, hideWhenNoResults]})';
- if (container === undefined || facetName === undefined || label === undefined) {
+ if (!container || !facetName || !label) {
throw new Error(usage);
}
@@ -68,6 +75,19 @@ function toggle({
count: values && values.count || null
};
+ cssClasses = {
+ root: cx(bem(null), cssClasses.root),
+ header: cx(bem('header'), cssClasses.header),
+ body: cx(bem('body'), cssClasses.body),
+ footer: cx(bem('footer'), cssClasses.footer),
+ list: cx(bem('list'), cssClasses.list),
+ item: cx(bem('item'), cssClasses.item),
+ active: cx(bem('item', 'active'), cssClasses.active),
+ label: cx(bem('label'), cssClasses.label),
+ checkbox: cx(bem('checkbox'), cssClasses.checkbox),
+ count: cx(bem('count'), cssClasses.count)
+ };
+
ReactDOM.render(
createURL(state.toggleRefinement(facetName, facetValue.isRefined))}