Add dividers to AutoComplete
This commit is contained in:
parent
cd6ab07217
commit
2346f29731
@ -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 }
|
||||||
/>
|
/>
|
||||||
|
@ -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) => {
|
||||||
|
Loading…
Reference in New Issue
Block a user