Add dividers to AutoComplete

This commit is contained in:
Nicolas Gotchac 2016-12-10 18:35:54 +01:00
parent cd6ab07217
commit 2346f29731
2 changed files with 103 additions and 23 deletions

View File

@ -47,23 +47,41 @@ export default class AddressSelect extends Component {
}
state = {
autocompleteEntries: [],
entries: {},
addresses: [],
value: ''
}
entriesFromProps (props = this.props) {
const { accounts, contacts, contracts, wallets } = props;
const entries = Object.assign({}, accounts || {}, wallets || {}, contacts || {}, contracts || {});
return entries;
const { accounts = {}, contacts = {}, contracts = {}, wallets = {} } = props;
const autocompleteEntries = [].concat(
Object.values(wallets),
'divider',
Object.values(accounts),
'divider',
Object.values(contacts),
'divider',
Object.values(contracts)
);
const entries = {
...wallets,
...accounts,
...contacts,
...contracts
};
return { autocompleteEntries, entries };
}
componentWillMount () {
const { value } = this.props;
const entries = this.entriesFromProps();
const { entries, autocompleteEntries } = this.entriesFromProps();
const addresses = Object.keys(entries).sort();
this.setState({ entries, addresses, value });
this.setState({ autocompleteEntries, entries, addresses, value });
}
componentWillReceiveProps (newProps) {
@ -74,7 +92,7 @@ export default class AddressSelect extends Component {
render () {
const { allowInput, disabled, error, hint, label } = this.props;
const { entries, value } = this.state;
const { autocompleteEntries, value } = this.state;
const searchText = this.getSearchText();
const icon = this.renderIdentityIcon(value);
@ -92,7 +110,7 @@ export default class AddressSelect extends Component {
onUpdateInput={ allowInput && this.onUpdateInput }
value={ searchText }
filter={ this.handleFilter }
entries={ entries }
entries={ autocompleteEntries }
entry={ this.getEntry() || {} }
renderItem={ this.renderItem }
/>

View File

@ -17,9 +17,10 @@
import React, { Component, PropTypes } from 'react';
import keycode from 'keycode';
import { MenuItem, AutoComplete as MUIAutoComplete } from 'material-ui';
import Divider from 'material-ui/Divider';
import { PopoverAnimationVertical } from 'material-ui/Popover';
import { isEqual } from 'lodash';
import { isEqual, range } from 'lodash';
export default class AutoComplete extends Component {
static propTypes = {
@ -38,14 +39,17 @@ export default class AutoComplete extends Component {
PropTypes.array,
PropTypes.object
])
}
};
state = {
lastChangedValue: undefined,
entry: null,
open: false,
dataSource: []
}
dataSource: [],
dividerBreaks: []
};
dividersVisibility = {};
componentWillMount () {
const dataSource = this.getDataSource();
@ -63,7 +67,7 @@ export default class AutoComplete extends Component {
}
render () {
const { disabled, error, hint, label, value, className, filter, onUpdateInput } = this.props;
const { disabled, error, hint, label, value, className, onUpdateInput } = this.props;
const { open, dataSource } = this.state;
return (
@ -79,7 +83,7 @@ export default class AutoComplete extends Component {
onFocus={ this.onFocus }
onClose={ this.onClose }
animation={ PopoverAnimationVertical }
filter={ filter }
filter={ this.handleFilter }
popoverProps={ { open } }
openOnFocus
menuCloseDelay={ 0 }
@ -99,18 +103,76 @@ export default class AutoComplete extends Component {
? entries
: Object.values(entries);
if (renderItem && typeof renderItem === 'function') {
return entriesArray.map(entry => renderItem(entry));
let currentDivider = 0;
let firstSet = false;
const dataSource = entriesArray.map((entry, index) => {
// Render divider
if (typeof entry === 'string' && entry.toLowerCase() === 'divider') {
// Don't add divider if nothing before
if (!firstSet) {
return undefined;
}
const item = {
text: '',
divider: currentDivider,
isDivider: true,
value: (
<Divider />
)
};
currentDivider++;
return item;
}
let item;
if (renderItem && typeof renderItem === 'function') {
item = renderItem(entry);
} else {
item = {
text: entry,
value: (
<MenuItem
primaryText={ entry }
/>
)
};
}
if (!firstSet) {
item.first = true;
firstSet = true;
}
item.divider = currentDivider;
return item;
}).filter((item) => item !== undefined);
return dataSource;
}
handleFilter = (searchText, name, item) => {
if (item.isDivider) {
return this.dividersVisibility[item.divider];
}
return entriesArray.map(entry => ({
text: entry,
value: (
<MenuItem
primaryText={ entry }
/>
)
}));
if (item.first) {
this.dividersVisibility = {};
}
const { filter } = this.props;
const show = filter(searchText, name, item);
// Show the related divider
if (show) {
this.dividersVisibility[item.divider] = true;
}
return show;
}
onKeyDown = (event) => {