Skip to content

Commit

Permalink
feat(headerFooter): Add BEM classes to header and footer
Browse files Browse the repository at this point in the history
All headers and footers will now receive a `ais-header` and
`ais-footer` class. Additional classes can also be added through
`cssClasses.{root,header,body,footer}`.

It means that it is no longer necessary to pass a full HTML div in the
`templates.header`. One can simply pass the header text content and
pass a `cssClasses.header` custom class.

So far only the `refinementList` widgets correctly add the
`ais-widgetname-header`/`ais-widgetname-footer` classes. I'll update
the other widgets once this gets merged.

Fixes #259
Relies on #264 being
merged first
  • Loading branch information
pixelastic committed Oct 16, 2015
1 parent 85b573d commit 9e9d438
Show file tree
Hide file tree
Showing 4 changed files with 59 additions and 30 deletions.
30 changes: 18 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -593,19 +593,25 @@ 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 class="ais-refinement-list">
<div class="ais-refinement-list--header ais-header">[custom header template]</div>
<div class="ais-refinement-list--body">
<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>
</div>
<div class="ais-refinement-list--footer ais-footer">[custom footer template]</div>
</div>
```

Expand Down
35 changes: 23 additions & 12 deletions decorators/headerFooter.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
var React = require('react');

var cx = require('classnames');
var cx = require('classnames/dedupe');

var Template = require('../components/Template');

Expand All @@ -10,30 +10,41 @@ function headerFooter(ComposedComponent) {
// override potential widget's defined transformData,
// header and footer currently do not have it
var transformData = null;
var templateProps = this.props.templateProps;
var classNames = {
root: this.props.cssClasses.root,
header: cx(this.props.cssClasses.header, 'ais-header'),
body: this.props.cssClasses.body,
footer: cx(this.props.cssClasses.footer, 'ais-footer')
};

return (
<div className={cx(this.props.cssClasses.root)}>
<Template templateKey="header" {...this.props.templateProps} transformData={transformData} />
<ComposedComponent {...this.props} />
<Template templateKey="footer" {...this.props.templateProps} transformData={transformData} />
<div className={classNames.root}>
<div className={classNames.header}>
<Template templateKey="header" {...templateProps} transformData={transformData} />
</div>
<div className={classNames.body}>
<ComposedComponent {...this.props} />
</div>
<div className={classNames.footer}>
<Template templateKey="footer" {...templateProps} transformData={transformData} />
</div>
</div>
);
}
}

HeaderFooter.propTypes = {
cssClasses: React.PropTypes.shape({
root: React.PropTypes.oneOfType([
React.PropTypes.string,
React.PropTypes.arrayOf(React.PropTypes.string)
])
root: React.PropTypes.string,
header: React.PropTypes.string,
body: React.PropTypes.string,
footer: React.PropTypes.string
})
};

HeaderFooter.defaultProps = {
cssClasses: {
root: null
}
cssClasses: {}
};

// precise displayName for ease of debugging (react dev tool, react warnings)
Expand Down
20 changes: 14 additions & 6 deletions example/app.js
Original file line number Diff line number Diff line change
Expand Up @@ -70,12 +70,13 @@ search.addWidget(
operator: 'or',
limit: 10,
cssClasses: {
header: 'panel-heading',
list: 'nav nav-stacked panel-body',
item: 'checkbox',
count: 'badge pull-right'
},
templates: {
header: '<div class="panel-heading">Brands</div>'
header: 'Brands'
}
})
);
Expand All @@ -87,10 +88,11 @@ search.addWidget(
operator: 'and',
limit: 10,
cssClasses: {
header: 'panel-heading',
root: 'list-group'
},
templates: {
header: '<div class="panel-heading">Price ranges</div>',
header: 'Price ranges',
item: require('./templates/and.html')
},
transformData: function(data) {
Expand All @@ -105,8 +107,11 @@ search.addWidget(
container: '#free-shipping',
facetName: 'free_shipping',
label: 'Free Shipping',
cssClasses: {
header: 'panel-heading'
},
templates: {
header: '<div class="panel-heading">Shipping</div>',
header: 'Shipping',
body: require('./templates/free-shipping.html')
}
})
Expand All @@ -118,10 +123,11 @@ search.addWidget(
facetName: 'categories',
limit: 10,
cssClasses: {
header: 'panel-heading',
root: 'list-group'
},
templates: {
header: '<div class="panel-heading">Categories</div>',
header: 'Categories',
item: require('./templates/category.html')
}
})
Expand All @@ -132,10 +138,11 @@ search.addWidget(
container: '#price',
facetName: 'price',
cssClasses: {
header: 'panel-heading',
body: 'panel-body'
},
templates: {
header: '<div class="panel-heading">Price</div>'
header: 'Price'
},
tooltips: {
format: function(formattedValue) {
Expand All @@ -151,10 +158,11 @@ search.addWidget(
attributes: ['hierarchicalCategories.lvl0', 'hierarchicalCategories.lvl1', 'hierarchicalCategories.lvl2'],
cssClasses: {
root: 'list-group',
header: 'panel-heading',
list: 'hierarchical-categories-list'
},
templates: {
header: '<div class="panel-heading">Hierarchical categories</div>',
header: 'Hierarchical categories',
item: require('./templates/category.html')
}
})
Expand Down
4 changes: 4 additions & 0 deletions widgets/refinement-list/refinement-list.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ function refinementList({
var facetValues = results.getFacetValues(facetName, {sortBy: sortBy}).slice(0, limit);

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),
Expand Down

0 comments on commit 9e9d438

Please sign in to comment.