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

View File

@ -17,9 +17,10 @@
import React, { Component, PropTypes } from 'react'; import React, { Component, PropTypes } from 'react';
import keycode from 'keycode'; import keycode from 'keycode';
import { MenuItem, AutoComplete as MUIAutoComplete } from 'material-ui'; import { MenuItem, AutoComplete as MUIAutoComplete } from 'material-ui';
import Divider from 'material-ui/Divider';
import { PopoverAnimationVertical } from 'material-ui/Popover'; import { PopoverAnimationVertical } from 'material-ui/Popover';
import { isEqual } from 'lodash'; import { isEqual, range } from 'lodash';
export default class AutoComplete extends Component { export default class AutoComplete extends Component {
static propTypes = { static propTypes = {
@ -38,14 +39,17 @@ export default class AutoComplete extends Component {
PropTypes.array, PropTypes.array,
PropTypes.object PropTypes.object
]) ])
} };
state = { state = {
lastChangedValue: undefined, lastChangedValue: undefined,
entry: null, entry: null,
open: false, open: false,
dataSource: [] dataSource: [],
} dividerBreaks: []
};
dividersVisibility = {};
componentWillMount () { componentWillMount () {
const dataSource = this.getDataSource(); const dataSource = this.getDataSource();
@ -63,7 +67,7 @@ export default class AutoComplete extends Component {
} }
render () { 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; const { open, dataSource } = this.state;
return ( return (
@ -79,7 +83,7 @@ export default class AutoComplete extends Component {
onFocus={ this.onFocus } onFocus={ this.onFocus }
onClose={ this.onClose } onClose={ this.onClose }
animation={ PopoverAnimationVertical } animation={ PopoverAnimationVertical }
filter={ filter } filter={ this.handleFilter }
popoverProps={ { open } } popoverProps={ { open } }
openOnFocus openOnFocus
menuCloseDelay={ 0 } menuCloseDelay={ 0 }
@ -99,18 +103,76 @@ export default class AutoComplete extends Component {
? entries ? entries
: Object.values(entries); : Object.values(entries);
if (renderItem && typeof renderItem === 'function') { let currentDivider = 0;
return entriesArray.map(entry => renderItem(entry)); 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 => ({ if (item.first) {
text: entry, this.dividersVisibility = {};
value: ( }
<MenuItem
primaryText={ entry } 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) => { onKeyDown = (event) => {