Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds isDisabled prop to EuiComboBox #829

Merged
merged 5 commits into from
May 15, 2018
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
20 changes: 20 additions & 0 deletions src-docs/src/views/combo_box/combo_box_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -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: (
Expand Down Expand Up @@ -98,6 +102,22 @@ export const ComboBoxExample = {
}],
props: { EuiComboBox },
demo: <ComboBox />,
}, {
title: 'Disabled',
source: [{
type: GuideSectionTypes.JS,
code: disabledSource,
}, {
type: GuideSectionTypes.HTML,
code: disabledHtml,
}],
text: (
<p>
Set the prop <EuiCode>isDisabled</EuiCode> to make the combo box disabled.
</p>
),
props: { EuiComboBox },
demo: <Disabled />,
}, {
title: 'Virtualized',
source: [{
Expand Down
84 changes: 84 additions & 0 deletions src-docs/src/views/combo_box/disabled.js
Original file line number Diff line number Diff line change
@@ -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 (
<EuiComboBox
placeholder="Select or create options"
options={this.options}
selectedOptions={selectedOptions}
onChange={this.onChange}
onCreateOption={this.onCreateOption}
isClearable={true}
isDisabled
/>
);
}
}
6 changes: 6 additions & 0 deletions src/components/combo_box/_combo_box.scss
Original file line number Diff line number Diff line change
Expand Up @@ -64,4 +64,10 @@
@include euiFormControlInvalidStyle;
}
}

&.euiComboBox-isDisabled {
.euiComboBox__inputWrap {
@include euiFormControlDisabledStyle;
}
}
}
7 changes: 6 additions & 1 deletion src/components/combo_box/combo_box.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -500,6 +501,7 @@ export class EuiComboBox extends Component {
render() {
const {
id,
isDisabled,
className,
isLoading,
options,
Expand All @@ -523,6 +525,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(', ');
Expand Down Expand Up @@ -552,6 +555,7 @@ export class EuiComboBox extends Component {
scrollToIndex={activeOptionIndex}
onScroll={this.focusActiveOption}
rowHeight={rowHeight}
isDisabled={isDisabled}
/>
</EuiPortal>
);
Expand All @@ -578,12 +582,13 @@ export class EuiComboBox extends Component {
autoSizeInputRef={this.autoSizeInputRef}
inputRef={this.searchInputRef}
updatePosition={this.updateListPosition}
onClear={isClearable && this.clearSelectedOptions ? this.clearSelectedOptions : undefined}
onClear={(isClearable && this.clearSelectedOptions && !isDisabled) ? this.clearSelectedOptions : undefined}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are your thoughts on pulling this out into a function? I feel like it might improve the readability now that there are three conditions being checked here.

hasSelectedOptions={selectedOptions.length > 0}
isListOpen={isListOpen}
onOpen={this.openList}
onClose={this.closeList}
singleSelection={singleSelection}
isDisabled={isDisabled}
/>

{optionsList}
Expand Down
15 changes: 12 additions & 3 deletions src/components/combo_box/combo_box_input/combo_box_input.js
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -87,6 +88,7 @@ export class EuiComboBoxInput extends Component {
onOpen,
onClose,
singleSelection,
isDisabled,
} = this.props;

const pills = selectedOptions.map((option) => {
Expand All @@ -99,7 +101,7 @@ export class EuiComboBoxInput extends Component {
return (
<EuiComboBoxPill
option={option}
onClose={singleSelection ? null : onRemoveOption}
onClose={(isDisabled || singleSelection) ? null : onRemoveOption}
key={label.toLowerCase()}
color={color}
{...rest}
Expand Down Expand Up @@ -143,12 +145,18 @@ export class EuiComboBoxInput extends Component {
);
}

const clickProps = {};

if (!isDisabled) {
clickProps.onClear = hasSelectedOptions ? onClear : undefined;
clickProps.onIconClick = isListOpen ? onClose : onOpen;
}

return (
<EuiFormControlLayout
icon="arrowDown"
iconSide="right"
onIconClick={isListOpen ? onClose : onOpen}
onClear={hasSelectedOptions ? onClear : undefined}
{...clickProps}
>
<div
className="euiComboBox__inputWrap"
Expand All @@ -168,6 +176,7 @@ export class EuiComboBoxInput extends Component {
value={searchValue}
ref={autoSizeInputRef}
inputRef={inputRef}
disabled={isDisabled}
/>
{removeOptionMessage}
</div>
Expand Down