Skip to content

Commit

Permalink
Convert EuiFieldSearch to TS (#2775)
Browse files Browse the repository at this point in the history
* euifieldsearch to ts

* CL
  • Loading branch information
thompsongl authored Jan 17, 2020
1 parent b5c0d47 commit 09eaef7
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 94 deletions.
7 changes: 4 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
## [`master`](https://github.com/elastic/eui/tree/master)

- Converted `EuiFormRow` to Typescript ([#2712](https://github.com/elastic/eui/pull/2712))
- Converted `EuiFormRow` to TypeScript ([#2712](https://github.com/elastic/eui/pull/2712))
- Updated `logoAPM`, `logoSecurity` and `logoEnterpriseSearch`. Added `logoWorkplaceSearch` and `logoObservability` ([#2769](https://github.com/elastic/eui/pull/2769))
- Convert `EuiFilterButton` to TypeScript ([#2761](https://github.com/elastic/eui/pull/2761))
- Convert `EuiFilterSelectItem` to TypeScript ([#2761](https://github.com/elastic/eui/pull/2761))
- Converted `EuiFilterButton` to TypeScript ([#2761](https://github.com/elastic/eui/pull/2761))
- Converted `EuiFilterSelectItem` to TypeScript ([#2761](https://github.com/elastic/eui/pull/2761))
- Converted `EuiFieldSearch` to TypeScript ([#2775](https://github.com/elastic/eui/pull/2775))

**Bug fixes**

Expand Down
Original file line number Diff line number Diff line change
@@ -1,70 +1,70 @@
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import React, { Component, InputHTMLAttributes } from 'react';
import classNames from 'classnames';
import { Browser } from '../../../services/browser';
import { ENTER } from '../../../services/key_codes';
import { CommonProps } from '../../common';

import { EuiFormControlLayout } from '../form_control_layout';

import { EuiValidatableControl } from '../validatable_control';

const propTypes = {
name: PropTypes.string,
id: PropTypes.string,
placeholder: PropTypes.string,
value: PropTypes.string,
isInvalid: PropTypes.bool,
fullWidth: PropTypes.bool,
isLoading: PropTypes.bool,
inputRef: PropTypes.func,
export interface EuiFieldSearchProps
extends CommonProps,
InputHTMLAttributes<HTMLInputElement> {
name?: string;
id?: string;
placeholder?: string;
value?: string;
isInvalid?: boolean;
fullWidth?: boolean;
isLoading?: boolean;
/**
* Called when the user presses [Enter] OR on change if the incremental prop is `true`.
* If you don't need the on[Enter] functionality, prefer using onChange
*/
onSearch: PropTypes.func,
onSearch?: (value: string) => void;
/**
* When `true` the search will be executed (that is, the `onSearch` will be called) as the
* user types.
*/
incremental: PropTypes.bool,
incremental?: boolean;
/**
* when `true` creates a shorter height input
*/
compressed: PropTypes.bool,
compressed?: boolean;
inputRef?: (node: HTMLInputElement | null) => void;
/**
* Shows a button that quickly clears any input
*/
isClearable: PropTypes.bool,
};

const defaultProps = {
fullWidth: false,
isLoading: false,
incremental: false,
compressed: false,
isClearable: true,
};

export class EuiFieldSearch extends Component {
static propTypes = propTypes;
static defaultProps = defaultProps;

constructor(props) {
super(props);
this.cleanups = [];
}
isClearable?: boolean;
}

export class EuiFieldSearch extends Component<EuiFieldSearchProps> {
static defaultProps = {
fullWidth: false,
isLoading: false,
incremental: false,
compressed: false,
isClearable: true,
};

inputElement: HTMLInputElement | null = null;
cleanups: Array<() => void> = [];

componentDidMount() {
if (!this.inputElement) return;
if (Browser.isEventSupported('search', this.inputElement)) {
const onSearch = event => {
const onSearch = (event?: Event) => {
if (this.props.onSearch) {
this.props.onSearch(event.target.value);
if (!event || !event.target) return;
this.props.onSearch((event.target as HTMLInputElement).value);
}
};
this.inputElement.addEventListener('search', onSearch);
this.cleanups.push(() =>
this.inputElement.removeEventListener('search', onSearch)
);
this.cleanups.push(() => {
if (!this.inputElement) return;
this.inputElement.removeEventListener('search', onSearch);
});
}
}

Expand All @@ -79,50 +79,63 @@ export class EuiFieldSearch extends Component {
// only then will React treat the value as different and fire its `change` event
//
// https://stackoverflow.com/questions/23892547/what-is-the-best-way-to-trigger-onchange-event-in-react-js
const nativeInputValueSetter = Object.getOwnPropertyDescriptor(
window.HTMLInputElement.prototype,
const nativeInputValue = Object.getOwnPropertyDescriptor(
HTMLInputElement.prototype,
'value'
).set;
nativeInputValueSetter.call(this.inputElement, '');
);
const nativeInputValueSetter = nativeInputValue
? nativeInputValue.set
: undefined;
if (nativeInputValueSetter) {
nativeInputValueSetter.call(this.inputElement, '');
}

// dispatch input event, with IE11 support/fallback
let event;
if ('Event' in window && typeof Event === 'function') {
const event = new Event('input', {
event = new Event('input', {
bubbles: true,
cancelable: false,
});
this.inputElement.dispatchEvent(event);
} else {
// IE11
const event = document.createEvent('Event');
event = document.createEvent('Event');
event.initEvent('input', true, false);
this.inputElement.dispatchEvent(event);
}

// set focus on the search field
this.inputElement.focus();
if (this.inputElement) {
if (event) {
this.inputElement.dispatchEvent(event);
}
// set focus on the search field
this.inputElement.focus();
}
};

componentWillUnmount() {
this.cleanups.forEach(cleanup => cleanup());
}

setRef = inputElement => {
setRef = (inputElement: HTMLInputElement | null) => {
this.inputElement = inputElement;
if (this.props.inputRef) {
this.props.inputRef(inputElement);
}
};

onKeyUp = (incremental, onSearch, event) => {
onKeyUp = (
event: React.KeyboardEvent<HTMLInputElement>,
incremental?: boolean,
onSearch?: (value: string) => void
) => {
if (this.props.onKeyUp) {
this.props.onKeyUp(event);
if (event.defaultPrevented) {
return;
}
}
if (onSearch && (incremental || event.keyCode === ENTER)) {
onSearch(event.target.value);
onSearch((event.target as HTMLInputElement).value);
}
};

Expand Down Expand Up @@ -162,7 +175,7 @@ export class EuiFieldSearch extends Component {
clear={
isClearable && value && !rest.readOnly && !rest.disabled
? { onClick: this.onClear }
: null
: undefined
}
compressed={compressed}>
<EuiValidatableControl isInvalid={isInvalid}>
Expand All @@ -173,7 +186,7 @@ export class EuiFieldSearch extends Component {
placeholder={placeholder}
className={classes}
value={value}
onKeyUp={this.onKeyUp.bind(this, incremental, onSearch)}
onKeyUp={e => this.onKeyUp(e, incremental, onSearch)}
ref={this.setRef}
{...rest}
/>
Expand Down
29 changes: 0 additions & 29 deletions src/components/form/field_search/index.d.ts

This file was deleted.

1 change: 0 additions & 1 deletion src/components/form/field_search/index.js

This file was deleted.

1 change: 1 addition & 0 deletions src/components/form/field_search/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { EuiFieldSearch, EuiFieldSearchProps } from './field_search';
3 changes: 0 additions & 3 deletions src/components/form/index.d.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import { CommonProps } from '../common';
/// <reference path="./field_search/index.d.ts" />
/// <reference path="./range/index.d.ts" />
/// <reference path="./select/index.d.ts" />
/// <reference path="./super_select/index.d.ts" />

import { FunctionComponent, FormHTMLAttributes, ReactNode } from 'react';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import React, { Component, InputHTMLAttributes } from 'react';
import classNames from 'classnames';
import { CommonProps } from '../../common';
// @ts-ignore
import { EuiFieldSearch } from '../../form/field_search';
import { EuiFieldSearch, EuiFieldSearchProps } from '../../form/field_search';
import { getMatchingOptions } from '../matching_options';
import { Option } from '../types';

/// <reference path="../../form/field_search/index.d.ts" />
import { EuiFieldSearchProps } from '@elastic/eui'; // eslint-disable-line

export type EuiSelectableSearchProps = Omit<
InputHTMLAttributes<HTMLInputElement> & EuiFieldSearchProps,
'onChange'
Expand Down

0 comments on commit 09eaef7

Please sign in to comment.