Skip to content

Commit 9846a70

Browse files
author
Vincent Voyer
committed
Merge pull request #304 from algolia/feat/bem-hierarchical-menu
feat(hierarchical-menu): Add BEM classes
2 parents 586e3c2 + 58ec191 commit 9846a70

File tree

5 files changed

+126
-24
lines changed

5 files changed

+126
-24
lines changed

README.md

Lines changed: 70 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -957,12 +957,18 @@ search.addWidget(
957957
* @param {String[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
958958
* @param {Number} [options.limit=100] How much facet values to get
959959
* @param {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, list, item
960-
* @param {String|String[]} [options.cssClasses.root] CSS class added to the root element
961-
* @param {String|String[]} [options.cssClasses.list] CSS class added to each list element
962-
* @param {String|String[]} [options.cssClasses.item] CSS class added to each item element
960+
* @param {String|String[]} [options.cssClasses.root] CSS class to add to the root element
961+
* @param {String|String[]} [options.cssClasses.header] CSS class to add to the header element
962+
* @param {String|String[]} [options.cssClasses.body] CSS class to add to the body element
963+
* @param {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
964+
* @param {String|String[]} [options.cssClasses.list] CSS class to add to the list element
965+
* @param {String|String[]} [options.cssClasses.item] CSS class to add to each item element
966+
* @param {String|String[]} [options.cssClasses.active] CSS class to add to each active element
967+
* @param {String|String[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
968+
* @param {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
963969
* @param {Object} [options.templates] Templates to use for the widget
964970
* @param {String|Function} [options.templates.header=''] Header template (root level only)
965-
* @param {String|Function} [options.templates.item='<a href="{{href}}">{{name}}</a> {{count}}'] Item template, provided with `name`, `count`, `isRefined`, `path`
971+
* @param {String|Function} [options.templates.item] Item template
966972
* @param {String|Function} [options.templates.footer=''] Footer template (root level only)
967973
* @param {Function} [options.transformData] Method to change the object passed to the item template
968974
* @param {boolean} [hideWhenNoResults=true] Hide the container when there's no results
@@ -998,6 +1004,66 @@ search.addWidget(
9981004
);
9991005
```
10001006

1007+
#### Styling
1008+
1009+
```html
1010+
<div class="ais-hierarchical-menu">
1011+
<div class="ais-hierarchical-menu--header ais-header">[custom header template]</div>
1012+
<div class="ais-hierarchical-menu--body">
1013+
<div class="ais-hierarchical-menu--list">
1014+
<div class="ais-hierarchical-menu--item">
1015+
<a class="ais-hierarchical-menu--link" href="/url">
1016+
Your value
1017+
<span class="ais-hierarchical-menu--count">42</span>
1018+
</a>
1019+
</div>
1020+
<div class="ais-hierarchical-menu--item ais-hierarchical-menu--item__active">
1021+
<a class="ais-hierarchical-menu--link" href="/url">
1022+
Your active value
1023+
<span class="ais-hierarchical-menu--count">42</span>
1024+
</a>
1025+
<div class="ais-hierarchical-menu--list">
1026+
<div class="ais-hierarchical-menu--item">
1027+
<a class="ais-hierarchical-menu--link" href="/url">
1028+
Your subvalue 1
1029+
<span class="ais-hierarchical-menu--count">10</span>
1030+
</a>
1031+
</div>
1032+
<div class="ais-hierarchical-menu--item">
1033+
<a class="ais-hierarchical-menu--link" href="/url">
1034+
Your subvalue 2
1035+
<span class="ais-hierarchical-menu--count">32</span>
1036+
</a>
1037+
</div>
1038+
</div>
1039+
</div>
1040+
</div>
1041+
</div>
1042+
<div class="ais-hierarchical-menu--footer ais-footer">[custom footer template]</div>
1043+
</div>
1044+
```
1045+
1046+
```css
1047+
.ais-hierarchical-menu {
1048+
}
1049+
.ais-hierarchical-menu--header {
1050+
}
1051+
.ais-hierarchical-menu--body {
1052+
}
1053+
.ais-hierarchical-menu--list {
1054+
}
1055+
.ais-hierarchical-menu--item {
1056+
}
1057+
.ais-hierarchical-menu--item__active {
1058+
}
1059+
.ais-hierarchical-menu--link {
1060+
}
1061+
.ais-hierarchical-menu--count {
1062+
}
1063+
.ais-hierarchical-menu--footer {
1064+
}
1065+
```
1066+
10011067
## Browser support
10021068

10031069
We natively support IE10+ and all other modern browsers without any dependency need

index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var InstantSearch = require('./lib/InstantSearch');
88
var instantsearch = toFactory(InstantSearch);
99

1010
instantsearch.widgets = {
11-
hierarchicalMenu: require('./widgets/hierarchicalMenu'),
11+
hierarchicalMenu: require('./widgets/hierarchical-menu/hierarchical-menu.js'),
1212
hits: require('./widgets/hits/hits'),
1313
indexSelector: require('./widgets/index-selector/index-selector'),
1414
menu: require('./widgets/menu/menu.js'),

themes/default/default.css

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,24 @@
137137
}
138138

139139
/* HIERARCHICAL MENU */
140+
.ais-hierarchical-menu {
141+
}
142+
.ais-hierarchical-menu--header {
143+
}
144+
.ais-hierarchical-menu--body {
145+
}
146+
.ais-hierarchical-menu--list {
147+
}
148+
.ais-hierarchical-menu--item {
149+
}
150+
.ais-hierarchical-menu--item__active {
151+
}
152+
.ais-hierarchical-menu--link {
153+
}
154+
.ais-hierarchical-menu--count {
155+
}
156+
.ais-hierarchical-menu--footer {
157+
}
140158

141159
/* RANGE SLIDER */
142160
.ais-range-slider--target,
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
module.exports = {
2+
header: '',
3+
item: `<a class="{{cssClasses.link}}" href="{{url}}">{{name}} <span class="{{cssClasses.count}}">{{count}}</span></a>`,
4+
footer: ''
5+
};
6+

widgets/hierarchicalMenu.js renamed to widgets/hierarchical-menu/hierarchical-menu.js

Lines changed: 31 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,14 @@
11
var React = require('react');
22
var ReactDOM = require('react-dom');
33

4-
var utils = require('../lib/utils.js');
5-
var autoHide = require('../decorators/autoHide');
6-
var headerFooter = require('../decorators/headerFooter');
7-
var RefinementList = autoHide(headerFooter(require('../components/RefinementList')));
4+
var utils = require('../../lib/utils.js');
5+
var bem = utils.bemHelper('ais-hierarchical-menu');
6+
var cx = require('classnames/dedupe');
7+
var autoHide = require('../../decorators/autoHide');
8+
var headerFooter = require('../../decorators/headerFooter');
9+
var RefinementList = autoHide(headerFooter(require('../../components/RefinementList')));
810

9-
var defaultTemplates = {
10-
header: '',
11-
item: '<a href="{{url}}">{{name}}</a> {{count}}',
12-
footer: ''
13-
};
11+
var defaultTemplates = require('./defaultTemplates.js');
1412

1513
/**
1614
* Create a hierarchical menu using multiple attributes
@@ -20,28 +18,30 @@ var defaultTemplates = {
2018
* @param {String[]} [options.sortBy=['count:desc']] How to sort refinements. Possible values: `count|isRefined|name:asc|desc`
2119
* @param {Number} [options.limit=100] How much facet values to get
2220
* @param {Object} [options.cssClasses] CSS classes to add to the wrapping elements: root, list, item
23-
* @param {String|String[]} [options.cssClasses.root] CSS class added to the root element
24-
* @param {String|String[]} [options.cssClasses.list] CSS class added to each list element
25-
* @param {String|String[]} [options.cssClasses.item] CSS class added to each item element
21+
* @param {String|String[]} [options.cssClasses.root] CSS class to add to the root element
22+
* @param {String|String[]} [options.cssClasses.header] CSS class to add to the header element
23+
* @param {String|String[]} [options.cssClasses.body] CSS class to add to the body element
24+
* @param {String|String[]} [options.cssClasses.footer] CSS class to add to the footer element
25+
* @param {String|String[]} [options.cssClasses.list] CSS class to add to the list element
26+
* @param {String|String[]} [options.cssClasses.item] CSS class to add to each item element
27+
* @param {String|String[]} [options.cssClasses.active] CSS class to add to each active element
28+
* @param {String|String[]} [options.cssClasses.link] CSS class to add to each link (when using the default template)
29+
* @param {String|String[]} [options.cssClasses.count] CSS class to add to each count element (when using the default template)
2630
* @param {Object} [options.templates] Templates to use for the widget
2731
* @param {String|Function} [options.templates.header=''] Header template (root level only)
28-
* @param {String|Function} [options.templates.item='<a href="{{href}}">{{name}}</a> {{count}}'] Item template, provided with `name`, `count`, `isRefined`, `path`
32+
* @param {String|Function} [options.templates.item] Item template
2933
* @param {String|Function} [options.templates.footer=''] Footer template (root level only)
3034
* @param {Function} [options.transformData] Method to change the object passed to the item template
3135
* @param {boolean} [hideWhenNoResults=true] Hide the container when there's no results
3236
* @return {Object}
3337
*/
3438
function hierarchicalMenu({
35-
container = null,
39+
container,
3640
attributes = [],
3741
separator,
3842
limit = 100,
3943
sortBy = ['name:asc'],
40-
cssClasses = {
41-
root: null,
42-
list: null,
43-
item: null
44-
},
44+
cssClasses = {},
4545
hideWhenNoResults = true,
4646
templates = defaultTemplates,
4747
transformData
@@ -76,6 +76,18 @@ function hierarchicalMenu({
7676
templates
7777
});
7878

79+
cssClasses = {
80+
root: cx(bem(null), cssClasses.root),
81+
header: cx(bem('header'), cssClasses.header),
82+
body: cx(bem('body'), cssClasses.body),
83+
footer: cx(bem('footer'), cssClasses.footer),
84+
list: cx(bem('list'), cssClasses.list),
85+
item: cx(bem('item'), cssClasses.item),
86+
active: cx(bem('item', 'active'), cssClasses.active),
87+
link: cx(bem('link'), cssClasses.link),
88+
count: cx(bem('count'), cssClasses.count)
89+
};
90+
7991
ReactDOM.render(
8092
<RefinementList
8193
createURL={(facetValue) => createURL(state.toggleRefinement(hierarchicalFacetName, facetValue))}

0 commit comments

Comments
 (0)