diff --git a/PickerMenu.js b/PickerMenu.js index 33ea508..5ed4bf0 100644 --- a/PickerMenu.js +++ b/PickerMenu.js @@ -1,5 +1,5 @@ // Menu-like Picker variant with keyboard control -// Version 2021-08-20 +// Version 2021-08-30 // License: LGPLv3.0+ // (c) Vitaliy Filippov 2020+ @@ -25,6 +25,8 @@ export default class PickerMenu extends Picker keepOnClick: PropTypes.bool, // menuitem name key - default empty (render the item itself) labelKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + // menuitem "disabled" key - default none + disabledKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), // change theme (CSS module) for this input theme: PropTypes.object, } @@ -34,11 +36,24 @@ export default class PickerMenu extends Picker if ((ev.which == 40 || ev.which == 38) && this.props.items.length) { // up / down - this.setState({ - active: this.state.active == null ? 0 : ( - (this.state.active + (event.which === 40 ? 1 : this.props.items.length-1)) % this.props.items.length - ), - }); + const dir = (event.which === 40 ? 1 : -1); + let prev = this.state.active, active; + if (prev == null) + active = dir == 1 ? 0 : this.props.items.length-1; + else + active = (prev + this.props.items.length - dir) % this.props.items.length; + if (this.props.disabledKey) + { + while (this.props.items[active][this.props.disabledKey] && active != prev) + { + active = (active + this.props.items.length - dir) % this.props.items.length; + } + if (this.props.items[active][this.props.disabledKey]) + { + active = null; + } + } + this.setState({ active }); if (!this.state.focused) { this.focus(); @@ -87,13 +102,14 @@ export default class PickerMenu extends Picker onMouseOver = (ev) => { let e = ev.target; - while (e && e != ev.currentTarget && !e.id) + while (e && e != ev.currentTarget && !e.getAttribute('data-idx')) { e = e.parentNode; } - if (e && e.id) + if (e && e.getAttribute('data-idx') && + (!this.props.disabledKey || !this.props.items[e.getAttribute('data-idx')][this.props.disabledKey])) { - this.setState({ active: e.id }); + this.setState({ active: e.getAttribute('data-idx') }); } } @@ -140,8 +156,10 @@ export default class PickerMenu extends Picker onKeyDown={this.onKeyDown} onMouseOver={this.onMouseOver}> {this.props.beforeItems} - {this.props.items.map((e, i) => (
+ {this.props.items.map((e, i) => (
{!this.props.labelKey ? e : e[this.props.labelKey]}
))} {this.props.afterItems} diff --git a/Selectbox.js b/Selectbox.js index e1cfa18..66c034e 100644 --- a/Selectbox.js +++ b/Selectbox.js @@ -1,5 +1,5 @@ // Simple Dropdown/Autocomplete with single/multiple selection and easy customisation via CSS modules -// Version 2021-08-25 +// Version 2021-08-30 // License: LGPLv3.0+ // (c) Vitaliy Filippov 2019+ @@ -32,6 +32,8 @@ export default class Selectbox extends React.PureComponent textKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), // item id key - default "id" valueKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), + // item "disabled" key - default none + disabledKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]), // automatically filter autocomplete options based on user input if `true` suggestionMatch: PropTypes.oneOfType([PropTypes.bool, PropTypes.oneOf(['disabled'])]), // additional message to display below autocomplete options (arbitrary HTML, for example "...") @@ -105,6 +107,11 @@ export default class Selectbox extends React.PureComponent this.picker.blur(); } const sel = item[this.props.valueKey||'id']; + if (this.props.disabledKey && item[this.props.disabledKey]) + { + // item is disabled + return; + } let value = sel; if (this.props.multiple) { @@ -279,6 +286,7 @@ export default class Selectbox extends React.PureComponent renderInput={this.renderInput} items={this.filtered_items} labelKey={this.props.labelKey||'name'} + disabledKey={this.props.disabledKey} afterItems={this.props.suggestionMsg} onSelectItem={this.onSelectItem} />); diff --git a/autocomplete.css b/autocomplete.css index 556c0fd..a266829 100644 --- a/autocomplete.css +++ b/autocomplete.css @@ -75,6 +75,12 @@ cursor: pointer; } +.suggestion.disabled +{ + color: #aaa; + background: #f4f6f8; +} + .suggestion.active { background: #d6e8f6;