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

Added delimiter prop to EuiComboBox #3104

Merged
merged 25 commits into from
Mar 25, 2020
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
4111a91
added delimenator prop
anishagg17 Mar 17, 2020
ac1f76d
Entering delimeator hits enter functionality added
anishagg17 Mar 17, 2020
fb452c2
added docs example, CL
anishagg17 Mar 19, 2020
406ec71
Merge branch 'master' into deim
anishagg17 Mar 19, 2020
386acbb
prettified
anishagg17 Mar 19, 2020
a133ba6
removed console.log()
anishagg17 Mar 19, 2020
c3142a4
added copy functionality
anishagg17 Mar 19, 2020
5d2cb23
added test,snap
anishagg17 Mar 19, 2020
e0a58bf
removed copy button
anishagg17 Mar 20, 2020
e89727a
removed copy button
anishagg17 Mar 20, 2020
ae3ae85
Update src-docs/src/views/combo_box/combo_box_example.js
anishagg17 Mar 20, 2020
864f5a9
Update src/components/combo_box/combo_box.tsx
anishagg17 Mar 20, 2020
ff3131a
fixed only first gets entered
anishagg17 Mar 21, 2020
4879bda
Merge branch 'deim' of https://github.com/anishagg17/eui into deim
anishagg17 Mar 21, 2020
b002be1
Merge branch 'master' into deim
anishagg17 Mar 23, 2020
fe9b420
Merge branch 'master' into deim
anishagg17 Mar 24, 2020
0c08b72
updated text
anishagg17 Mar 25, 2020
14f6499
Merge branch 'deim' of https://github.com/anishagg17/eui into deim
anishagg17 Mar 25, 2020
033499a
indent fix
anishagg17 Mar 25, 2020
e983a61
Update combo_box_options_list.tsx
anishagg17 Mar 25, 2020
5eeff79
Update src/components/combo_box/combo_box_options_list/combo_box_opti…
anishagg17 Mar 25, 2020
368c92c
Merge branch 'master' of https://github.com/elastic/eui into deim
anishagg17 Mar 25, 2020
bcd13cd
removed empty string
anishagg17 Mar 25, 2020
14ad843
removed redundant code
anishagg17 Mar 25, 2020
26ee787
Merge branch 'master' into deim
anishagg17 Mar 25, 2020
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
@@ -1,5 +1,6 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Added `delimiter` prop to `EuiComboBox` ([#3104](https://github.com/elastic/eui/pull/3104))
- Added `sortMatchesBy` prop for `EuiComboBox` ([#3089](https://github.com/elastic/eui/pull/3089))
- Added `prepend` and `append` ability to `EuiFieldPassword` ([#3122](https://github.com/elastic/eui/pull/3122))
- Added `Enter` key press functionality to `EuiSuperDatePicker` ([#3048](https://github.com/elastic/eui/pull/3048))
Expand Down
98 changes: 98 additions & 0 deletions src-docs/src/views/combo_box/combo_box_delimiter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
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}
delimiter=","
noSuggestions
anishagg17 marked this conversation as resolved.
Show resolved Hide resolved
selectedOptions={selectedOptions}
onChange={this.onChange}
onCreateOption={this.onCreateOption}
isClearable={true}
data-test-subj="demoComboBox"
/>
);
}
}
25 changes: 25 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 @@ -59,6 +59,10 @@ import Disabled from './disabled';
const disabledSource = require('!!raw-loader!./disabled');
const disabledHtml = renderToHtml(Disabled);

import Delimiter from './combo_box_delimiter';
const delimiterSource = require('!!raw-loader!./combo_box_delimiter');
const delimiterHtml = renderToHtml(Delimiter);

import StartingWith from './startingWith';
const startingWithSource = require('!!raw-loader!./startingWith');
const startingWithHtml = renderToHtml(StartingWith);
Expand Down Expand Up @@ -351,6 +355,27 @@ export const ComboBoxExample = {
props: { EuiComboBox },
demo: <Async />,
},
{
title: 'With delimiter',
source: [
{
type: GuideSectionTypes.JS,
code: delimiterSource,
},
{
type: GuideSectionTypes.HTML,
code: delimiterHtml,
},
],
text: (
<p>
Use the <EuiCode>delimiter</EuiCode> prop to trigger an entry creation
in <EuiCode>EuiComboBox</EuiCode> .
</p>
anishagg17 marked this conversation as resolved.
Show resolved Hide resolved
),
props: { EuiComboBox },
demo: <Delimiter />,
},
{
title: 'Sorting matches',
source: [
Expand Down
43 changes: 43 additions & 0 deletions src/components/combo_box/__snapshots__/combo_box.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,49 @@ exports[`EuiComboBox is rendered 1`] = `
</div>
`;

exports[`props delimiter is rendered 1`] = `
<div
aria-expanded={false}
aria-haspopup="listbox"
className="euiComboBox"
onKeyDown={[Function]}
role="combobox"
>
<EuiComboBoxInput
autoSizeInputRef={[Function]}
compressed={false}
fullWidth={false}
hasSelectedOptions={true}
inputRef={[Function]}
isListOpen={false}
noIcon={false}
onChange={[Function]}
onClear={[Function]}
onClick={[Function]}
onCloseListClick={[Function]}
onFocus={[Function]}
onOpenListClick={[Function]}
onRemoveOption={[Function]}
rootId={[Function]}
searchValue=""
selectedOptions={
Array [
Object {
"label": "Mimas",
},
Object {
"label": "Dione",
},
]
}
singleSelection={false}
toggleButtonRef={[Function]}
updatePosition={[Function]}
value="Mimas, Dione"
/>
</div>
`;

exports[`props full width is rendered 1`] = `
<div
aria-expanded={false}
Expand Down
12 changes: 12 additions & 0 deletions src/components/combo_box/combo_box.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,18 @@ describe('props', () => {

expect(component).toMatchSnapshot();
});

test('delimiter is rendered', () => {
const component = shallow(
<EuiComboBox
options={options}
selectedOptions={[options[2], options[3]]}
delimiter=","
/>
);

expect(component).toMatchSnapshot();
});
});

describe('behavior', () => {
Expand Down
34 changes: 28 additions & 6 deletions src/components/combo_box/combo_box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,7 @@ interface _EuiComboBoxProps<T>
* `string` | `ReactElement` or an array of these
*/
append?: EuiFormControlLayoutProps['append'];
delimiter?: string;
anishagg17 marked this conversation as resolved.
Show resolved Hide resolved
}

/**
Expand Down Expand Up @@ -400,15 +401,15 @@ export class EuiComboBox<T> extends Component<
}
};

addCustomOption = (isContainerBlur: boolean) => {
addCustomOption = (isContainerBlur: boolean, searchValue: string) => {
const {
onCreateOption,
options,
selectedOptions,
singleSelection,
} = this.props;

const { searchValue, matchingOptions } = this.state;
const { matchingOptions } = this.state;

if (this.doesSearchMatchOnlyOption()) {
this.onAddOption(matchingOptions[0], isContainerBlur);
Expand Down Expand Up @@ -531,7 +532,15 @@ export class EuiComboBox<T> extends Component<
// If the user tabs away or changes focus to another element, take whatever input they've
// typed and convert it into a pill, to prevent the combo box from looking like a text input.
if (!this.hasActiveOption()) {
this.addCustomOption(true);
const { searchValue } = this.state;
const { delimiter } = this.props;
if (delimiter) {
searchValue
.split(delimiter)
.forEach((option: string) => this.addCustomOption(true, option));
} else {
this.addCustomOption(true, searchValue);
}
}
}
};
Expand Down Expand Up @@ -576,7 +585,15 @@ export class EuiComboBox<T> extends Component<
this.state.matchingOptions[this.state.activeOptionIndex]
);
} else {
this.addCustomOption(false);
const { searchValue } = this.state;
const { delimiter } = this.props;
if (delimiter) {
searchValue
.split(delimiter)
.forEach((option: string) => this.addCustomOption(false, option));
} else {
this.addCustomOption(false, searchValue);
}
anishagg17 marked this conversation as resolved.
Show resolved Hide resolved
}
break;

Expand Down Expand Up @@ -708,7 +725,8 @@ export class EuiComboBox<T> extends Component<
onSearchChange: NonNullable<
EuiComboBoxInputProps<T>['onChange']
> = searchValue => {
const { onSearchChange } = this.props;
const { onSearchChange, delimiter } = this.props;

if (onSearchChange) {
const hasMatchingOptions = this.state.matchingOptions.length > 0;
onSearchChange(searchValue, hasMatchingOptions);
Expand All @@ -717,6 +735,9 @@ export class EuiComboBox<T> extends Component<
this.setState({ searchValue }, () => {
if (searchValue && this.state.isListOpen === false) this.openList();
});
if (delimiter && searchValue.endsWith(delimiter)) {
this.addCustomOption(false, searchValue.split(delimiter)[0]);
}
};

componentDidMount() {
Expand Down Expand Up @@ -848,8 +869,9 @@ export class EuiComboBox<T> extends Component<
selectedOptions,
singleSelection,
prepend,
append,
sortMatchesBy,
delimiter,
append,
...rest
} = this.props;
const {
Expand Down