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

Fixed clear button not showing when external input value is passed. #3497

Merged
merged 10 commits into from
Jun 4, 2020
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)

- Replaced usage of `displayName` with `inputValue` prop in `EuiFieldSearch` ([#3497](https://github.com/elastic/eui/pull/3497))
- Added exports for `EuiSteps` and related components types ([#3471](https://github.com/elastic/eui/pull/3471))
- Added `displayName` to components using `React.forwardRef` ([#3451](https://github.com/elastic/eui/pull/3451))
- Added event target checker for `EuiOverlayMask`'s `onClick` prop ([#3462](https://github.com/elastic/eui/pull/3462))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@

exports[`EuiFieldSearch is rendered 1`] = `
<eui-form-control-layout
clear="[object Object]"
compressed="false"
fullwidth="false"
icon="search"
Expand Down Expand Up @@ -35,6 +34,7 @@ exports[`EuiFieldSearch props append is rendered 1`] = `
<input
class="euiFieldSearch euiFieldText--inGroup"
type="search"
value=""
/>
</eui-validatable-control>
</eui-form-control-layout>
Expand All @@ -51,6 +51,7 @@ exports[`EuiFieldSearch props fullWidth is rendered 1`] = `
<input
class="euiFieldSearch euiFieldSearch--fullWidth"
type="search"
value=""
/>
</eui-validatable-control>
</eui-form-control-layout>
Expand All @@ -69,6 +70,7 @@ exports[`EuiFieldSearch props isInvalid is rendered 1`] = `
<input
class="euiFieldSearch"
type="search"
value=""
/>
</eui-validatable-control>
</eui-form-control-layout>
Expand All @@ -85,6 +87,7 @@ exports[`EuiFieldSearch props isLoading is rendered 1`] = `
<input
class="euiFieldSearch euiFieldSearch-isLoading"
type="search"
value=""
/>
</eui-validatable-control>
</eui-form-control-layout>
Expand All @@ -102,6 +105,7 @@ exports[`EuiFieldSearch props prepend is rendered 1`] = `
<input
class="euiFieldSearch euiFieldText--inGroup"
type="search"
value=""
/>
</eui-validatable-control>
</eui-form-control-layout>
Expand Down
28 changes: 23 additions & 5 deletions src/components/form/field_search/field_search.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@ export interface EuiFieldSearchProps
* `string` | `ReactElement` or an array of these
*/
append?: EuiFormControlLayoutProps['append'];

/**
* Input value to be set externally
*/
inputValue?: string;
}

interface EuiFieldSearchState {
Expand All @@ -91,7 +96,7 @@ export class EuiFieldSearch extends Component<
};

state = {
value: this.props.value || '',
value: '',
};

inputElement: HTMLInputElement | null = null;
Expand All @@ -115,6 +120,17 @@ export class EuiFieldSearch extends Component<
}
}

componentDidUpdate(prevProps: EuiFieldSearchProps) {
if (prevProps.inputValue !== this.props.inputValue) {
this.changeValue();
}
}

changeValue = () => {
const { inputValue } = this.props;
this.setState({ value: inputValue || '' });
};

onClear = () => {
// clear the field's value

Expand Down Expand Up @@ -182,8 +198,6 @@ export class EuiFieldSearch extends Component<
incremental?: boolean,
onSearch?: (value: string) => void
) => {
this.setState({ value: (event.target as HTMLInputElement).value });

if (this.props.onKeyUp) {
this.props.onKeyUp(event);
if (event.defaultPrevented) {
Expand Down Expand Up @@ -216,11 +230,11 @@ export class EuiFieldSearch extends Component<
isClearable,
append,
prepend,
inputValue,
...rest
} = this.props;

let value = this.props.value;
if (typeof this.props.value !== 'string') value = this.state.value;
const { value } = this.state;

const classes = classNames(
'euiFieldSearch',
Expand Down Expand Up @@ -251,6 +265,10 @@ export class EuiFieldSearch extends Component<
type="search"
id={id}
name={name}
value={this.state.value}
onChange={e => {
this.setState({ value: e.target.value });
}}
placeholder={placeholder}
className={classes}
onKeyUp={e => this.onKeyUp(e, incremental, onSearch)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ exports[`SearchBar render - no config, no query 1`] = `
grow={true}
>
<EuiSearchBox
incremental={false}
isInvalid={false}
onSearch={[Function]}
placeholder="Search..."
query=""
/>
</EuiFlexItem>
Expand All @@ -56,10 +54,8 @@ exports[`SearchBar render - provided query, filters 1`] = `
grow={true}
>
<EuiSearchBox
incremental={false}
isInvalid={false}
onSearch={[Function]}
placeholder="Search..."
query="this is a query"
/>
</EuiFlexItem>
Expand Down Expand Up @@ -168,10 +164,8 @@ exports[`SearchBar render - tools 1`] = `
grow={true}
>
<EuiSearchBox
incremental={false}
isInvalid={false}
onSearch={[Function]}
placeholder="Search..."
query=""
/>
</EuiFlexItem>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,9 @@ exports[`EuiSearchBox render - custom placeholder and incremental 1`] = `
className="testClass1 testClass2"
compressed={false}
data-test-subj="test subject string"
defaultValue=""
fullWidth={true}
incremental={true}
inputRef={[Function]}
inputValue=""
isClearable={true}
isLoading={false}
onSearch={[Function]}
Expand All @@ -23,10 +22,9 @@ exports[`EuiSearchBox render - no config 1`] = `
className="testClass1 testClass2"
compressed={false}
data-test-subj="test subject string"
defaultValue=""
fullWidth={true}
incremental={false}
inputRef={[Function]}
inputValue=""
isClearable={true}
isLoading={false}
onSearch={[Function]}
Expand Down
63 changes: 22 additions & 41 deletions src/components/search_bar/search_box.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
* under the License.
*/

import React, { Component } from 'react';
import React from 'react';
import { EuiFieldSearch, EuiFieldSearchProps } from '../form';

export interface SchemaType {
Expand All @@ -32,43 +32,24 @@ export interface EuiSearchBoxProps extends EuiFieldSearchProps {
onSearch: (queryText: string) => void;
}

type DefaultProps = Pick<EuiSearchBoxProps, 'placeholder' | 'incremental'>;

export class EuiSearchBox extends Component<EuiSearchBoxProps> {
static defaultProps: DefaultProps = {
placeholder: 'Search...',
incremental: false,
};

private inputElement: HTMLInputElement | null = null;

componentDidUpdate(oldProps: EuiSearchBoxProps) {
if (oldProps.query !== this.props.query && this.inputElement != null) {
this.inputElement.value = this.props.query;
}
}

render() {
const { query, incremental, ...rest } = this.props;

let ariaLabel;
if (incremental) {
ariaLabel =
'This is a search bar. As you type, the results lower in the page will automatically filter.';
} else {
ariaLabel =
'This is a search bar. After typing your query, hit enter to filter the results lower in the page.';
}

return (
<EuiFieldSearch
inputRef={input => (this.inputElement = input)}
fullWidth
defaultValue={query}
incremental={incremental}
aria-label={ariaLabel}
{...rest}
/>
);
}
}
export const EuiSearchBox = ({
placeholder = 'Search...',
query,
incremental = false,
...rest
}: EuiSearchBoxProps) => {
const ariaLabel = incremental
? 'This is a search bar. As you type, the results lower in the page will automatically filter.'
: 'This is a search bar. After typing your query, hit enter to filter the results lower in the page.';

return (
<EuiFieldSearch
fullWidth
incremental={incremental}
aria-label={ariaLabel}
inputValue={query}
placeholder={placeholder}
{...rest}
/>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ exports[`EuiSelectableSearch is rendered 1`] = `
</div>
`;

exports[`EuiSelectableSearch props defaultValue 1`] = `
exports[`EuiSelectableSearch props inputValue 1`] = `
<div
class="euiFormControlLayout euiFormControlLayout--fullWidth"
>
Expand All @@ -43,7 +43,7 @@ exports[`EuiSelectableSearch props defaultValue 1`] = `
class="euiFieldSearch euiFieldSearch--fullWidth euiSelectableSearch"
placeholder="Filter options"
type="search"
value="Mi"
value=""
/>
<div
class="euiFormControlLayoutIcons"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,9 @@ describe('EuiSelectableSearch', () => {
});

describe('props', () => {
test('defaultValue', () => {
test('inputValue', () => {
const component = render(
<EuiSelectableSearch options={[]} defaultValue="Mi" />
<EuiSelectableSearch options={[]} inputValue="Mi" />
);

expect(component).toMatchSnapshot();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ export class EuiSelectableSearch extends Component<
placeholder="Filter options"
onSearch={this.onSearchChange}
incremental
defaultValue={defaultValue}
inputValue={defaultValue}
fullWidth
{...rest}
/>
Expand Down