diff --git a/CHANGELOG.md b/CHANGELOG.md index 003e11429f1..c7dd11a1dbd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Made boolean matching in `EuiSearchBar` more exact so it doesn't match words starting with booleans, like "truest" or "offer" ([#776](https://github.com/elastic/eui/pull/776)) - `EuiComboBox` do not setState or call refs once component is unmounted ([807](https://github.com/elastic/eui/pull/807) and [#813](https://github.com/elastic/eui/pull/813)) - Added better accessibility labeling to `EuiPagination`, `EuiSideNav`, `EuiPopover`, `EuiBottomBar` and `EuiBasicTable`. ([#821](https://github.com/elastic/eui/pull/821)) +- Added `isDisabled` to `EuiComboBox` ([#829](https://github.com/elastic/eui/pull/829)) ## [`0.0.46`](https://github.com/elastic/eui/tree/v0.0.46) diff --git a/src-docs/src/views/combo_box/combo_box_example.js b/src-docs/src/views/combo_box/combo_box_example.js index e3d69e48c60..055b577d8b2 100644 --- a/src-docs/src/views/combo_box/combo_box_example.js +++ b/src-docs/src/views/combo_box/combo_box_example.js @@ -58,6 +58,10 @@ import Virtualized from './virtualized'; const virtualizedSource = require('!!raw-loader!./virtualized'); const virtualizedHtml = renderToHtml(Virtualized); +import Disabled from './disabled'; +const disabledSource = require('!!raw-loader!./disabled'); +const disabledHtml = renderToHtml(Disabled); + export const ComboBoxExample = { title: 'Combo Box', intro: ( @@ -98,6 +102,22 @@ export const ComboBoxExample = { }], props: { EuiComboBox }, demo: , + }, { + title: 'Disabled', + source: [{ + type: GuideSectionTypes.JS, + code: disabledSource, + }, { + type: GuideSectionTypes.HTML, + code: disabledHtml, + }], + text: ( +

+ Set the prop isDisabled to make the combo box disabled. +

+ ), + props: { EuiComboBox }, + demo: , }, { title: 'Virtualized', source: [{ diff --git a/src-docs/src/views/combo_box/disabled.js b/src-docs/src/views/combo_box/disabled.js new file mode 100644 index 00000000000..499ee32c47b --- /dev/null +++ b/src-docs/src/views/combo_box/disabled.js @@ -0,0 +1,84 @@ +import React, { Component } from 'react'; + +import { + EuiComboBox, +} from '../../../../src/components'; + +export default class extends Component { + constructor(props) { + super(props); + + this.options = [{ + label: 'Titan', + 'data-test-subj': 'titanOption', + }, { + label: 'Enceladus is disabled', + disabled: true, + }, { + label: 'Mimas', + }, { + label: 'Dione', + }, { + label: 'Iapetus', + }, { + label: 'Phoebe', + }, { + label: 'Rhea', + }, { + label: 'Pandora is one of Saturn\'s moons, named for a Titaness of Greek mythology', + }, { + label: 'Tethys', + }, { + label: 'Hyperion', + }]; + + this.state = { + selectedOptions: [this.options[2], this.options[4]], + }; + } + + onChange = (selectedOptions) => { + this.setState({ + selectedOptions, + }); + }; + + onCreateOption = (searchValue, flattenedOptions) => { + const normalizedSearchValue = searchValue.trim().toLowerCase(); + + if (!normalizedSearchValue) { + return; + } + + const newOption = { + label: searchValue, + }; + + // Create the option if it doesn't exist. + if (flattenedOptions.findIndex(option => + option.label.trim().toLowerCase() === normalizedSearchValue + ) === -1) { + this.options.push(newOption); + } + + // Select the option. + this.setState(prevState => ({ + selectedOptions: prevState.selectedOptions.concat(newOption), + })); + }; + + render() { + const { selectedOptions } = this.state; + return ( + + ); + } +} diff --git a/src/components/combo_box/_combo_box.scss b/src/components/combo_box/_combo_box.scss index c40ccdd6e50..abe866d0b39 100644 --- a/src/components/combo_box/_combo_box.scss +++ b/src/components/combo_box/_combo_box.scss @@ -64,4 +64,10 @@ @include euiFormControlInvalidStyle; } } + + &.euiComboBox-isDisabled { + .euiComboBox__inputWrap { + @include euiFormControlDisabledStyle; + } + } } diff --git a/src/components/combo_box/combo_box.js b/src/components/combo_box/combo_box.js index dd92923ec95..3e1faa2d24c 100644 --- a/src/components/combo_box/combo_box.js +++ b/src/components/combo_box/combo_box.js @@ -26,6 +26,7 @@ import { export class EuiComboBox extends Component { static propTypes = { id: PropTypes.string, + isDisabled: PropTypes.bool, className: PropTypes.string, placeholder: PropTypes.string, isLoading: PropTypes.bool, @@ -433,6 +434,14 @@ export class EuiComboBox extends Component { } }; + onClear = () => { + if (this.props.isClearable && this.clearSelectedOptions && !this.props.isDisabled) { + return this.clearSelectedOptions(); + } else { + return undefined; + } + } + autoSizeInputRef = node => { this.autoSizeInput = node; }; @@ -500,6 +509,7 @@ export class EuiComboBox extends Component { render() { const { id, + isDisabled, className, isLoading, options, @@ -514,7 +524,7 @@ export class EuiComboBox extends Component { async, // eslint-disable-line no-unused-vars isInvalid, rowHeight, - isClearable, + isClearable, // eslint-disable-line no-unused-vars ...rest } = this.props; @@ -523,6 +533,7 @@ export class EuiComboBox extends Component { const classes = classNames('euiComboBox', className, { 'euiComboBox-isOpen': isListOpen, 'euiComboBox-isInvalid': isInvalid, + 'euiComboBox-isDisabled': isDisabled, }); const value = selectedOptions.map(selectedOption => selectedOption.label).join(', '); @@ -552,6 +563,7 @@ export class EuiComboBox extends Component { scrollToIndex={activeOptionIndex} onScroll={this.focusActiveOption} rowHeight={rowHeight} + isDisabled={isDisabled} /> ); @@ -578,12 +590,13 @@ export class EuiComboBox extends Component { autoSizeInputRef={this.autoSizeInputRef} inputRef={this.searchInputRef} updatePosition={this.updateListPosition} - onClear={isClearable && this.clearSelectedOptions ? this.clearSelectedOptions : undefined} + onClear={this.onClear} hasSelectedOptions={selectedOptions.length > 0} isListOpen={isListOpen} onOpen={this.openList} onClose={this.closeList} singleSelection={singleSelection} + isDisabled={isDisabled} /> {optionsList} diff --git a/src/components/combo_box/combo_box_input/combo_box_input.js b/src/components/combo_box/combo_box_input/combo_box_input.js index d8ce6f6d249..ac35ac3c9f2 100644 --- a/src/components/combo_box/combo_box_input/combo_box_input.js +++ b/src/components/combo_box/combo_box_input/combo_box_input.js @@ -29,6 +29,7 @@ export class EuiComboBoxInput extends Component { onOpen: PropTypes.func.isRequired, onClose: PropTypes.func.isRequired, singleSelection: PropTypes.bool, + isDisabled: PropTypes.bool, } constructor(props) { @@ -87,6 +88,7 @@ export class EuiComboBoxInput extends Component { onOpen, onClose, singleSelection, + isDisabled, } = this.props; const pills = selectedOptions.map((option) => { @@ -99,7 +101,7 @@ export class EuiComboBoxInput extends Component { return (
{removeOptionMessage}