From d7e7533388d9c5f3e4ba09c1d0c6949dc81bd72f Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Wed, 11 Sep 2019 16:31:05 +0100 Subject: [PATCH 1/7] Migrate EuiBottomBar to TS --- ...bottom_bar.test.js => bottom_bar.test.tsx} | 1 + .../{bottom_bar.js => bottom_bar.tsx} | 51 +++++++++---------- .../bottom_bar/{index.js => index.ts} | 0 3 files changed, 25 insertions(+), 27 deletions(-) rename src/components/bottom_bar/{bottom_bar.test.js => bottom_bar.test.tsx} (98%) rename src/components/bottom_bar/{bottom_bar.js => bottom_bar.tsx} (73%) rename src/components/bottom_bar/{index.js => index.ts} (100%) diff --git a/src/components/bottom_bar/bottom_bar.test.js b/src/components/bottom_bar/bottom_bar.test.tsx similarity index 98% rename from src/components/bottom_bar/bottom_bar.test.js rename to src/components/bottom_bar/bottom_bar.test.tsx index 06ad975abd8..b5878df4f43 100644 --- a/src/components/bottom_bar/bottom_bar.test.js +++ b/src/components/bottom_bar/bottom_bar.test.tsx @@ -7,6 +7,7 @@ import { EuiBottomBar, PADDING_SIZES } from './bottom_bar'; // TODO: Temporary hack which we can remove once react-test-renderer supports portals. // More info at https://github.com/facebook/react/issues/11565. +// @ts-ignore ReactDOM.createPortal = node => node; describe('EuiBottomBar', () => { diff --git a/src/components/bottom_bar/bottom_bar.js b/src/components/bottom_bar/bottom_bar.tsx similarity index 73% rename from src/components/bottom_bar/bottom_bar.js rename to src/components/bottom_bar/bottom_bar.tsx index 9ac5c915a59..d40f401ad6e 100644 --- a/src/components/bottom_bar/bottom_bar.js +++ b/src/components/bottom_bar/bottom_bar.tsx @@ -1,23 +1,41 @@ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import classNames from 'classnames'; +import { CommonProps, keysOf } from '../common'; import { EuiPortal } from '../portal'; import { EuiScreenReaderOnly } from '../accessibility'; import { EuiI18n } from '../i18n'; -const paddingSizeToClassNameMap = { +type BottomBarPaddingSize = 'none' | 's' | 'm' | 'l'; + +const paddingSizeToClassNameMap: { + [value in BottomBarPaddingSize]: string | null +} = { none: null, s: 'euiBottomBar--paddingSmall', m: 'euiBottomBar--paddingMedium', l: 'euiBottomBar--paddingLarge', }; -export const PADDING_SIZES = Object.keys(paddingSizeToClassNameMap); +export const PADDING_SIZES = keysOf(paddingSizeToClassNameMap); + +interface Props extends CommonProps { + /** + * Optional class applied to the body class + */ + bodyClassName?: string; + + /** + * Padding applied to the bar + */ + paddingSize?: BottomBarPaddingSize; +} + +export class EuiBottomBar extends Component { + private bar: HTMLDivElement | null = null; -export class EuiBottomBar extends Component { componentDidMount() { - const height = this.bar.clientHeight; + const height = this.bar ? this.bar.clientHeight : -1; document.body.style.paddingBottom = `${height}px`; if (this.props.bodyClassName) { document.body.classList.add(this.props.bodyClassName); @@ -35,8 +53,7 @@ export class EuiBottomBar extends Component { const { children, className, - paddingSize, - // eslint-disable-next-line no-unused-vars + paddingSize = 'm', bodyClassName, ...rest } = this.props; @@ -69,23 +86,3 @@ export class EuiBottomBar extends Component { ); } } - -EuiBottomBar.propTypes = { - children: PropTypes.node, - /** - * Optional class applied to the bar itself - */ - className: PropTypes.string, - /** - * Optional class applied to the body class - */ - bodyClassName: PropTypes.string, - /** - * Padding applied to the bar - */ - paddingSize: PropTypes.oneOf(PADDING_SIZES), -}; - -EuiBottomBar.defaultProps = { - paddingSize: 'm', -}; diff --git a/src/components/bottom_bar/index.js b/src/components/bottom_bar/index.ts similarity index 100% rename from src/components/bottom_bar/index.js rename to src/components/bottom_bar/index.ts From 3d38327535d9f429f20b22438c2b9e26c7fb310f Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Wed, 11 Sep 2019 16:35:30 +0100 Subject: [PATCH 2/7] Migrate EuiHealth to TS --- .../{health.test.js => health.test.tsx} | 0 .../health/{health.js => health.tsx} | 23 +++++++++++-------- src/components/health/index.d.ts | 19 --------------- src/components/health/{index.js => index.ts} | 0 src/components/index.d.ts | 1 - 5 files changed, 14 insertions(+), 29 deletions(-) rename src/components/health/{health.test.js => health.test.tsx} (100%) rename src/components/health/{health.js => health.tsx} (57%) delete mode 100644 src/components/health/index.d.ts rename src/components/health/{index.js => index.ts} (100%) diff --git a/src/components/health/health.test.js b/src/components/health/health.test.tsx similarity index 100% rename from src/components/health/health.test.js rename to src/components/health/health.test.tsx diff --git a/src/components/health/health.js b/src/components/health/health.tsx similarity index 57% rename from src/components/health/health.js rename to src/components/health/health.tsx index 9c59cd43eaf..17ea359c50c 100644 --- a/src/components/health/health.js +++ b/src/components/health/health.tsx @@ -1,12 +1,22 @@ -import React from 'react'; -import PropTypes from 'prop-types'; +import React, { FunctionComponent, HTMLAttributes } from 'react'; import classNames from 'classnames'; +import { CommonProps } from '../common'; -import { EuiIcon } from '../icon'; +import { EuiIcon, IconColor } from '../icon'; import { EuiFlexGroup, EuiFlexItem } from '../flex'; -export const EuiHealth = ({ children, className, color, ...rest }) => { +type EuiHealthProps = CommonProps & + HTMLAttributes & { + color?: IconColor; + }; + +export const EuiHealth: FunctionComponent = ({ + children, + className, + color, + ...rest +}) => { const classes = classNames('euiHealth', className); return ( @@ -20,8 +30,3 @@ export const EuiHealth = ({ children, className, color, ...rest }) => { ); }; - -EuiHealth.propTypes = { - children: PropTypes.node, - className: PropTypes.string, -}; diff --git a/src/components/health/index.d.ts b/src/components/health/index.d.ts deleted file mode 100644 index 5f57a7bb137..00000000000 --- a/src/components/health/index.d.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { IconColor } from '../icon'; - -import { FunctionComponent, HTMLAttributes } from 'react'; -import { CommonProps } from '../common'; - -declare module '@elastic/eui' { - /** - * health type defs - * - * @see './health.js' - */ - - type EuiHealthProps = CommonProps & - HTMLAttributes & { - color: IconColor; - }; - - export const EuiHealth: FunctionComponent; -} diff --git a/src/components/health/index.js b/src/components/health/index.ts similarity index 100% rename from src/components/health/index.js rename to src/components/health/index.ts diff --git a/src/components/index.d.ts b/src/components/index.d.ts index 50edc2d4bb3..e9ed157e185 100644 --- a/src/components/index.d.ts +++ b/src/components/index.d.ts @@ -10,7 +10,6 @@ /// /// /// -/// /// /// /// From e0446e37f59504b0412ec0d6560e22daebe2fb22 Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Wed, 11 Sep 2019 16:48:40 +0100 Subject: [PATCH 3/7] Migrate EuiImage to TS --- ....test.js.snap => bottom_bar.test.tsx.snap} | 0 ...alth.test.js.snap => health.test.tsx.snap} | 0 ...image.test.js.snap => image.test.tsx.snap} | 1 + .../image/{image.test.js => image.test.tsx} | 2 +- src/components/image/{image.js => image.tsx} | 59 ++++++++++--------- src/components/image/{index.js => index.ts} | 0 6 files changed, 33 insertions(+), 29 deletions(-) rename src/components/bottom_bar/__snapshots__/{bottom_bar.test.js.snap => bottom_bar.test.tsx.snap} (100%) rename src/components/health/__snapshots__/{health.test.js.snap => health.test.tsx.snap} (100%) rename src/components/image/__snapshots__/{image.test.js.snap => image.test.tsx.snap} (94%) rename src/components/image/{image.test.js => image.test.tsx} (80%) rename src/components/image/{image.js => image.tsx} (74%) rename src/components/image/{index.js => index.ts} (100%) diff --git a/src/components/bottom_bar/__snapshots__/bottom_bar.test.js.snap b/src/components/bottom_bar/__snapshots__/bottom_bar.test.tsx.snap similarity index 100% rename from src/components/bottom_bar/__snapshots__/bottom_bar.test.js.snap rename to src/components/bottom_bar/__snapshots__/bottom_bar.test.tsx.snap diff --git a/src/components/health/__snapshots__/health.test.js.snap b/src/components/health/__snapshots__/health.test.tsx.snap similarity index 100% rename from src/components/health/__snapshots__/health.test.js.snap rename to src/components/health/__snapshots__/health.test.tsx.snap diff --git a/src/components/image/__snapshots__/image.test.js.snap b/src/components/image/__snapshots__/image.test.tsx.snap similarity index 94% rename from src/components/image/__snapshots__/image.test.js.snap rename to src/components/image/__snapshots__/image.test.tsx.snap index 10a6524c3f6..3154b1c1983 100644 --- a/src/components/image/__snapshots__/image.test.js.snap +++ b/src/components/image/__snapshots__/image.test.tsx.snap @@ -12,6 +12,7 @@ exports[`EuiImage is rendered 1`] = ` alt diff --git a/src/components/image/image.test.js b/src/components/image/image.test.tsx similarity index 80% rename from src/components/image/image.test.js rename to src/components/image/image.test.tsx index e235f0ce345..7c1630a7494 100644 --- a/src/components/image/image.test.js +++ b/src/components/image/image.test.tsx @@ -7,7 +7,7 @@ import { EuiImage } from './image'; describe('EuiImage', () => { test('is rendered', () => { const component = render( - + ); expect(component).toMatchSnapshot(); diff --git a/src/components/image/image.js b/src/components/image/image.tsx similarity index 74% rename from src/components/image/image.js rename to src/components/image/image.tsx index c31d158e84b..b7e372511ac 100644 --- a/src/components/image/image.js +++ b/src/components/image/image.tsx @@ -1,7 +1,7 @@ import React, { Component } from 'react'; -import PropTypes from 'prop-types'; import classNames from 'classnames'; +import { CommonProps } from '../common'; import { EuiOverlayMask } from '../overlay_mask'; import { EuiIcon } from '../icon'; @@ -10,7 +10,9 @@ import { EuiFocusTrap } from '../focus_trap'; import { keyCodes } from '../../services'; -const sizeToClassNameMap = { +type ImageSize = 's' | 'm' | 'l' | 'xl' | 'fullWidth' | 'original'; + +const sizeToClassNameMap: { [size in ImageSize]: string } = { s: 'euiImage--small', m: 'euiImage--medium', l: 'euiImage--large', @@ -21,21 +23,33 @@ const sizeToClassNameMap = { export const SIZES = Object.keys(sizeToClassNameMap); -const fullScreenIconColorMap = { +type FullScreenIconColor = 'light' | 'dark'; + +const fullScreenIconColorMap: { [color in FullScreenIconColor]: string } = { light: 'ghost', dark: 'default', }; -export class EuiImage extends Component { - constructor(props) { - super(props); +interface EuiImageProps extends CommonProps { + alt: string; + size: ImageSize; + fullScreenIconColor?: FullScreenIconColor; + url: string; + caption?: string; + hasShadow?: boolean; + allowFullScreen?: boolean; +} - this.state = { - isFullScreen: false, - }; - } +interface State { + isFullScreen: boolean; +} - onKeyDown = event => { +export class EuiImage extends Component { + state: State = { + isFullScreen: false, + }; + + onKeyDown = (event: React.KeyboardEvent) => { if (event.keyCode === keyCodes.ESCAPE) { event.preventDefault(); event.stopPropagation(); @@ -91,7 +105,11 @@ export class EuiImage extends Component { optionalIcon = ( ); @@ -107,11 +125,7 @@ export class EuiImage extends Component { type="button" onClick={this.closeFullScreen} onKeyDown={this.onKeyDown}> -
{ - this.figure = node; - }} - className="euiImageFullScreen"> +
{alt} {optionalCaption}
@@ -140,14 +154,3 @@ export class EuiImage extends Component { ); } } - -EuiImage.propTypes = { - alt: PropTypes.string.isRequired, - size: PropTypes.string.isRequired, - fullScreenIconColor: PropTypes.string, -}; - -EuiImage.defaultProps = { - size: 'original', - fullScreenIconColor: 'light', -}; diff --git a/src/components/image/index.js b/src/components/image/index.ts similarity index 100% rename from src/components/image/index.js rename to src/components/image/index.ts From 997d70c3a1d38cc3e33a4421de647930621cfe6c Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Wed, 11 Sep 2019 16:50:54 +0100 Subject: [PATCH 4/7] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index afc59bc8836..6918478e298 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## [`master`](https://github.com/elastic/eui/tree/master) - Added missing `compressed` styling to `EuiSwitch` ([#2327](https://github.com/elastic/eui/pull/2327)) +- Migrate `EuiBottomBar`, `EuiHealth` and `EuiImage` to TS ([#2328](https://github.com/elastic/eui/pull/2328)) ## [`14.0.0`](https://github.com/elastic/eui/tree/v14.0.0) From c17ff1184dfefe7f9edf5afea005ffe7a3b79654 Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Thu, 12 Sep 2019 10:08:40 +0100 Subject: [PATCH 5/7] Work around a TypeScript build problem The `yarn build` command was failing due to wierdness around the `PADDING_SIZES` export from `bottom_bar.tsx`. Remove it, and essentially move it to the test file, which is the only usage I could find (I checked Kibana too). --- src-docs/src/i18ntokens.json | 6 +++--- src/components/bottom_bar/bottom_bar.test.tsx | 5 +++-- src/components/bottom_bar/bottom_bar.tsx | 7 +++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src-docs/src/i18ntokens.json b/src-docs/src/i18ntokens.json index c388889539e..9373dc86839 100644 --- a/src-docs/src/i18ntokens.json +++ b/src-docs/src/i18ntokens.json @@ -85,15 +85,15 @@ "highlighting": "string", "loc": { "start": { - "line": 54, + "line": 70, "column": 12 }, "end": { - "line": 57, + "line": 73, "column": 14 } }, - "filepath": "src/components/bottom_bar/bottom_bar.js" + "filepath": "src/components/bottom_bar/bottom_bar.tsx" }, { "token": "euiCardSelect.selected", diff --git a/src/components/bottom_bar/bottom_bar.test.tsx b/src/components/bottom_bar/bottom_bar.test.tsx index b5878df4f43..97fca8f042a 100644 --- a/src/components/bottom_bar/bottom_bar.test.tsx +++ b/src/components/bottom_bar/bottom_bar.test.tsx @@ -2,8 +2,9 @@ import React from 'react'; import ReactDOM from 'react-dom'; import { render } from 'enzyme'; import { requiredProps } from '../../test/required_props'; +import { keysOf } from '../common'; -import { EuiBottomBar, PADDING_SIZES } from './bottom_bar'; +import { EuiBottomBar, paddingSizeToClassNameMap } from './bottom_bar'; // TODO: Temporary hack which we can remove once react-test-renderer supports portals. // More info at https://github.com/facebook/react/issues/11565. @@ -21,7 +22,7 @@ describe('EuiBottomBar', () => { describe('props', () => { describe('paddingSize', () => { - PADDING_SIZES.forEach(paddingSize => { + keysOf(paddingSizeToClassNameMap).forEach(paddingSize => { test(`${paddingSize} is rendered`, () => { const component = render(); diff --git a/src/components/bottom_bar/bottom_bar.tsx b/src/components/bottom_bar/bottom_bar.tsx index d40f401ad6e..67d633ac67b 100644 --- a/src/components/bottom_bar/bottom_bar.tsx +++ b/src/components/bottom_bar/bottom_bar.tsx @@ -1,14 +1,15 @@ import React, { Component } from 'react'; import classNames from 'classnames'; -import { CommonProps, keysOf } from '../common'; +import { CommonProps } from '../common'; import { EuiPortal } from '../portal'; import { EuiScreenReaderOnly } from '../accessibility'; import { EuiI18n } from '../i18n'; type BottomBarPaddingSize = 'none' | 's' | 'm' | 'l'; -const paddingSizeToClassNameMap: { +// Exported for testing +export const paddingSizeToClassNameMap: { [value in BottomBarPaddingSize]: string | null } = { none: null, @@ -17,8 +18,6 @@ const paddingSizeToClassNameMap: { l: 'euiBottomBar--paddingLarge', }; -export const PADDING_SIZES = keysOf(paddingSizeToClassNameMap); - interface Props extends CommonProps { /** * Optional class applied to the body class From aa8cda1ed60de76bc81b37255fa886757945aea3 Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Fri, 13 Sep 2019 20:32:47 +0100 Subject: [PATCH 6/7] Fixes from review --- src/components/health/health.tsx | 4 ++-- src/components/image/image.tsx | 12 ++++-------- 2 files changed, 6 insertions(+), 10 deletions(-) diff --git a/src/components/health/health.tsx b/src/components/health/health.tsx index 17ea359c50c..1c01f05eb6f 100644 --- a/src/components/health/health.tsx +++ b/src/components/health/health.tsx @@ -1,13 +1,13 @@ import React, { FunctionComponent, HTMLAttributes } from 'react'; import classNames from 'classnames'; -import { CommonProps } from '../common'; +import { CommonProps, Omit } from '../common'; import { EuiIcon, IconColor } from '../icon'; import { EuiFlexGroup, EuiFlexItem } from '../flex'; type EuiHealthProps = CommonProps & - HTMLAttributes & { + Omit, 'color'> & { color?: IconColor; }; diff --git a/src/components/image/image.tsx b/src/components/image/image.tsx index b7e372511ac..640daa67e4b 100644 --- a/src/components/image/image.tsx +++ b/src/components/image/image.tsx @@ -32,7 +32,7 @@ const fullScreenIconColorMap: { [color in FullScreenIconColor]: string } = { interface EuiImageProps extends CommonProps { alt: string; - size: ImageSize; + size?: ImageSize; fullScreenIconColor?: FullScreenIconColor; url: string; caption?: string; @@ -73,11 +73,11 @@ export class EuiImage extends Component { const { className, url, - size, + size = 'original', caption, hasShadow, allowFullScreen, - fullScreenIconColor, + fullScreenIconColor = 'light', alt, ...rest } = this.props; @@ -105,11 +105,7 @@ export class EuiImage extends Component { optionalIcon = ( ); From de4a5fa874f20c788cfda992353bfbf7df39dac4 Mon Sep 17 00:00:00 2001 From: Rory Hunter Date: Fri, 13 Sep 2019 21:08:30 +0100 Subject: [PATCH 7/7] More review feedback --- src/components/image/image.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/image/image.tsx b/src/components/image/image.tsx index 640daa67e4b..6bd97d271e3 100644 --- a/src/components/image/image.tsx +++ b/src/components/image/image.tsx @@ -1,4 +1,4 @@ -import React, { Component } from 'react'; +import React, { Component, HTMLAttributes } from 'react'; import classNames from 'classnames'; import { CommonProps } from '../common'; @@ -30,7 +30,7 @@ const fullScreenIconColorMap: { [color in FullScreenIconColor]: string } = { dark: 'default', }; -interface EuiImageProps extends CommonProps { +interface EuiImageProps extends CommonProps, HTMLAttributes { alt: string; size?: ImageSize; fullScreenIconColor?: FullScreenIconColor;