Skip to content

Commit e030d56

Browse files
committed
ListBox item is now an object, not string
There are few reasons behind this change, so here they are: * We are about to replace CodeMirror with Ace, and there we have a different set of supported syntaxes. Due to internals, it would be easiery for us to maintain syntaxes mode names on server side instead of syntaxes human names (e.g. c_cpp instead of "C and C++"). Since we want to separate enum value from its representational name, ListBox component is ought to separate these concepts. * ListBox is designed as a replacement for standard HTML <select> tag and the latter separates the value it will send as selected from the value it shows on the page. So why don't we? * The change makes component more general, which is one step closer to make it independent library. The important note here is that it maintains both user interfaces, just like <select> tag and one can pass either an array of strings or an array of objects (with "name" and "value" props).
1 parent 9bfe889 commit e030d56

File tree

2 files changed

+19
-9
lines changed

2 files changed

+19
-9
lines changed

src/components/ListBox.jsx

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,19 +20,21 @@ class ListBox extends React.Component {
2020
// If selected item is not a part of new items, aggressively fallback to
2121
// first item from the list. We're doing it to be protected from cases
2222
// when nothing is selected.
23-
if (!selected || !nextProps.items.contains(selected)) {
23+
if (!selected || !nextProps.items.find(item => item.value === selected)) {
2424
selected = nextProps.items.get(0);
25+
if (!selected) return;
26+
selected = selected.value;
2527
nextProps.onClick(selected);
2628
}
2729

2830
this.setState({ selected });
2931
}
3032

3133
onClick(e) {
32-
const { item } = e.target.dataset;
34+
const { value } = e.target.dataset;
3335

34-
this.setState({ selected: item });
35-
this.props.onClick(item);
36+
this.setState({ selected: value });
37+
this.props.onClick(value);
3638
}
3739

3840
render() {
@@ -48,11 +50,11 @@ class ListBox extends React.Component {
4850
{items.size ? null : <li className="new-snippet-lang-empty">No results found</li>}
4951
{items.map(item => (
5052
<li
51-
className={`new-snippet-lang-item ${item === selected ? 'active' : ''}`}
52-
data-item={item}
53-
key={item}
53+
className={`new-snippet-lang-item ${item.value === selected ? 'active' : ''}`}
54+
data-value={item.value}
55+
key={item.value}
5456
>
55-
{item}
57+
{item.name}
5658
</li>
5759
))}
5860
</ul>

src/components/ListBoxWithSearch.jsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,19 @@ class ListBoxWithSearch extends React.PureComponent {
2020
const { searchQuery } = this.state;
2121
let { items } = this.props;
2222

23+
// Normalize items arrays so each item is always an object.
24+
items = items.map((item) => {
25+
if (item !== Object(item)) {
26+
return { name: item, value: item };
27+
}
28+
return item;
29+
});
30+
2331
// Filter out only those items that match search query. If no query is
2432
// set, do nothing and use the entire set.
2533
if (searchQuery) {
2634
const regExp = new RegExp(regExpEscape(searchQuery), 'gi');
27-
items = items.filter(item => item.match(regExp));
35+
items = items.filter(item => item.name.match(regExp));
2836
}
2937

3038
return (

0 commit comments

Comments
 (0)