-
Notifications
You must be signed in to change notification settings - Fork 182
/
nav.js
107 lines (94 loc) · 2.34 KB
/
nav.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {Input, List, Markdown, fuzzyHighlight} from '@jetbrains/ring-ui';
import {currentPath} from './utils';
import styles from './index.css';
import Item from './item';
function makeFilter(filter) {
const needle = filter.trim();
if (needle === '') {
return null;
}
return haystack => fuzzyHighlight(needle, haystack);
}
const filterItems = (items, filterFn) =>
items.
map(({title, ...rest}) => ({
filtered: filterFn(title),
...rest
})).
filter(({filtered}) => filtered.matched).
map(({filtered, ...rest}) => ({
title: (
<Markdown
inline={true}
source={filtered.highlight}
/>
),
...rest
}));
const groupListItem = name => ({
rgItemType: List.ListProps.Type.TITLE,
label: name,
key: name
});
const linkListItem = ({url, title}) => ({
rgItemType: List.ListProps.Type.LINK,
href: url,
active: url === currentPath(),
label: title,
key: url
});
class Nav extends PureComponent {
state = {
filter: ''
}
setFilter = e => this.setState({
filter: e.target.value
});
render() {
const {categories} = this.props;
const {filter} = this.state;
const filterFn = makeFilter(filter);
const filteredCategories = filterFn
? categories.
map(({items, ...rest}) => ({
items: filterItems(items, filterFn),
...rest
})).
filter(({items}) => items.length > 0)
: categories;
// [].concat(...arrs) === arrs.flatten()
const data = [].concat(
...filteredCategories.map(({name, items}) => [
groupListItem(name),
...items.map(linkListItem)
])
);
return (
<div className={styles.nav}>
<Input
className="ring-js-shortcuts"
autoFocus={true}
placeholder="Search components"
value={filter}
onChange={this.setFilter}
/>
<List
renderOptimization={false}
className={styles.list}
shortcuts={true}
activeIndex={filterFn && 1}
{...{data}}
/>
</div>
);
}
}
Nav.propTypes = {
categories: PropTypes.arrayOf(PropTypes.shape({
name: PropTypes.string,
items: PropTypes.arrayOf(PropTypes.shape(Item.propTypes))
}))
};
export default Nav;