Skip to content

Commit

Permalink
feat(refinement-list): Add BEM naming
Browse files Browse the repository at this point in the history
  • Loading branch information
pixelastic committed Oct 16, 2015
1 parent 40a359b commit b09b830
Show file tree
Hide file tree
Showing 8 changed files with 111 additions and 27 deletions.
49 changes: 44 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -556,14 +556,19 @@ search.addWidget(
* @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 {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 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=`<label>
<input type="checkbox" value="{{name}}" {{#isRefined}}checked{{/isRefined}} />{{name}} <span>{{count}}</span>
</label>`] Item template, provided with `name`, `count`, `isRefined`
* @param {String|Function} [options.templates.footer=''] Footer template
* @param {String|Function} [options.templates.header] Header template
* @param {String|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
* @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
* @return {Object}
Expand All @@ -585,6 +590,40 @@ search.addWidget(
);
```

#### Styling

```html
<div class="ais-refinement-list--list">
<div class="ais-refinement-list--item">
<label class="ais-refinement-list--label">
<input type="checkbox" class="ais-refinement-list--checkbox" value="your_value"> Your value
<span class="ais-refinement-list--count">42</span>
</label>
</div>
<div class="ais-refinement-list--item ais-refinement-list--item__active">
<label class="ais-refinement-list--label">
<input type="checkbox" class="ais-refinement-list--checkbox" value="your_selected_value" checked="checked"> Your selected value
<span class="ais-refinement-list--count">42</span>
</label>
</div>
</div>
```

```css
.ais-refinement-list--list {
}
.ais-refinement-list--item {
}
.ais-refinement-list--item__active {
}
.ais-refinement-list--label {
}
.ais-refinement-list--checkbox {
}
.ais-refinement-list--count {
}
```

### menu

![Example of the menu widget][menu]
Expand Down
15 changes: 9 additions & 6 deletions components/RefinementList.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,19 @@ class RefinementList extends React.Component {
<RefinementList {...this.props} facetValues={facetValue.data} /> :
null;

var templateData = {...facetValue, cssClasses: this.props.cssClasses};

var cssClassItem = cx(this.props.cssClasses.item, {
[this.props.cssClasses.active]: facetValue.isRefined
});

return (
<div
className={cx(this.props.cssClasses.item)}
className={cssClassItem}
key={facetValue[this.props.facetNameKey]}
onClick={this.handleClick.bind(this, facetValue[this.props.facetNameKey])}
>
<Template data={facetValue} templateKey="item" {...this.props.templateProps} />
<Template data={templateData} templateKey="item" {...this.props.templateProps} />
{subList}
</div>
);
Expand Down Expand Up @@ -96,10 +102,7 @@ RefinementList.propTypes = {
};

RefinementList.defaultProps = {
cssClasses: {
item: null,
list: null
},
cssClasses: {},
facetNameKey: 'name'
};

Expand Down
7 changes: 4 additions & 3 deletions example/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,12 @@ search.addWidget(
operator: 'or',
limit: 10,
cssClasses: {
list: 'nav nav-stacked panel-body'
list: 'nav nav-stacked panel-body',
item: 'checkbox',
count: 'badge pull-right'
},
templates: {
header: '<div class="panel-heading">Brands</div>',
item: require('./templates/or.html')
header: '<div class="panel-heading">Brands</div>'
}
})
);
Expand Down
4 changes: 4 additions & 0 deletions example/style.css
Original file line number Diff line number Diff line change
Expand Up @@ -75,3 +75,7 @@ body {
.hierarchical-categories-list .hierarchical-categories-list {
padding-left: 20px;
}

.ais-refinement-list--label {
display: block;
}
13 changes: 11 additions & 2 deletions themes/debug.css
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@
position:relative;
}
[class^=ais-]:hover:after {
background:red;
background: grey;
background: red;
color: black;
content:attr(class);
font-size:1rem;
Expand All @@ -20,6 +19,7 @@
top:0;
white-space: nowrap;
z-index:10;
font-weight: normal;
}
[class^=ais-] [class^=ais-] {
outline: 1px solid orange !important;
Expand All @@ -39,3 +39,12 @@
top:40px;
z-index:1000;
}
[class^=ais-] [class^=ais-] [class^=ais-] [class^=ais-] {
outline: 1px solid cyan !important;
position:relative;
}
[class^=ais-] [class^=ais-] [class^=ais-] [class^=ais-]:hover:after {
background: cyan;
top:40px;
z-index:1100;
}
6 changes: 3 additions & 3 deletions widgets/refinement-list/defaultTemplates.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module.exports = {
header: '',
item: `<label>
<input type="checkbox" value="{{name}}" {{#isRefined}}checked{{/isRefined}} />{{name}}
<span>{{count}}</span>
item: `<label class="{{cssClasses.label}}">
<input type="checkbox" class="{{cssClasses.checkbox}}" value="{{name}}" {{#isRefined}}checked{{/isRefined}} />{{name}}
<span class="{{cssClasses.count}}">{{count}}</span>
</label>`,
footer: ''
};
12 changes: 12 additions & 0 deletions widgets/refinement-list/refinement-list.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
.ais-refinement-list--list {
}
.ais-refinement-list--item {
}
.ais-refinement-list--item__active {
}
.ais-refinement-list--label {
}
.ais-refinement-list--checkbox {
}
.ais-refinement-list--count {
}
32 changes: 24 additions & 8 deletions widgets/refinement-list/refinement-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ var React = require('react');
var ReactDOM = require('react-dom');

var utils = require('../../lib/utils.js');
var bem = utils.bemHelper('ais-refinement-list');
var cx = require('classnames/dedupe');

var autoHide = require('../../decorators/autoHide');
var headerFooter = require('../../decorators/headerFooter');
Expand All @@ -18,14 +20,19 @@ var defaultTemplates = require('./defaultTemplates');
* @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 {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 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=`<label>
<input type="checkbox" value="{{name}}" {{#isRefined}}checked{{/isRefined}} />{{name}} <span>{{count}}</span>
</label>`] Item template, provided with `name`, `count`, `isRefined`
* @param {String|Function} [options.templates.footer=''] Footer template
* @param {String|Function} [options.templates.header] Header template
* @param {String|Function} [options.templates.item] Item template, provided with `name`, `count`, `isRefined`
* @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
* @return {Object}
Expand All @@ -37,12 +44,12 @@ function refinementList({
sortBy = ['count:desc'],
limit = 1000,
cssClasses = {},
hideWhenNoResults = true,
templates = defaultTemplates,
transformData
transformData,
hideWhenNoResults = true
}) {
var containerNode = utils.getContainerNode(container);
var usage = 'Usage: refinementList({container, facetName, [operator, sortBy, limit, cssClasses.{root,list,item}, templates.{header,item,footer}, transformData, hideIfNoResults]})';
var usage = 'Usage: refinementList({container, facetName, [operator, sortBy, limit, cssClasses.{root,header,body,footer,list,item,active,label,checkbox,count}, templates.{header,item,footer}, transformData, hideIfNoResults]})';

if (!container || !facetName) {
throw new Error(usage);
Expand Down Expand Up @@ -79,6 +86,15 @@ function refinementList({

var facetValues = results.getFacetValues(facetName, {sortBy: sortBy}).slice(0, limit);

cssClasses = {
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(
<RefinementList
cssClasses={cssClasses}
Expand Down

0 comments on commit b09b830

Please sign in to comment.