From 6801460912bfa7007242dfcacbb88a98161ec11d Mon Sep 17 00:00:00 2001 From: Labhansh Agrawal Date: Fri, 13 Mar 2020 20:49:23 +0530 Subject: [PATCH] port notification and split-pane component to ts --- .../{notification.js => notification.tsx} | 14 +++--- .../{split-pane.js => split-pane.tsx} | 45 +++++++++++-------- lib/hyper.d.ts | 17 +++++++ package.json | 1 + yarn.lock | 5 +++ 5 files changed, 57 insertions(+), 25 deletions(-) rename lib/components/{notification.js => notification.tsx} (88%) rename lib/components/{split-pane.js => split-pane.tsx} (82%) diff --git a/lib/components/notification.js b/lib/components/notification.tsx similarity index 88% rename from lib/components/notification.js rename to lib/components/notification.tsx index 88badb7b..0240cbdd 100644 --- a/lib/components/notification.js +++ b/lib/components/notification.tsx @@ -1,8 +1,10 @@ import React from 'react'; +import {NotificationProps} from '../hyper'; -export default class Notification extends React.PureComponent { - constructor() { - super(); +export default class Notification extends React.PureComponent { + dismissTimer!: NodeJS.Timeout; + constructor(props: NotificationProps) { + super(props); this.state = { dismissing: false }; @@ -14,7 +16,7 @@ export default class Notification extends React.PureComponent { } } //TODO: Remove usage of legacy and soon deprecated lifecycle methods - UNSAFE_componentWillReceiveProps(next) { + UNSAFE_componentWillReceiveProps(next: NotificationProps) { // if we have a timer going and the notification text // changed we reset the timer if (next.text !== this.props.text) { @@ -31,7 +33,7 @@ export default class Notification extends React.PureComponent { this.setState({dismissing: true}); }; - onElement = el => { + onElement = (el: HTMLDivElement | null) => { if (el) { el.addEventListener('webkitTransitionEnd', () => { if (this.state.dismissing) { @@ -48,7 +50,7 @@ export default class Notification extends React.PureComponent { setDismissTimer() { this.dismissTimer = setTimeout(() => { this.handleDismiss(); - }, this.props.dismissAfter); + }, this.props.dismissAfter!); } resetDismissTimer() { diff --git a/lib/components/split-pane.js b/lib/components/split-pane.tsx similarity index 82% rename from lib/components/split-pane.js rename to lib/components/split-pane.tsx index aaa5928b..4824c45b 100644 --- a/lib/components/split-pane.js +++ b/lib/components/split-pane.tsx @@ -1,26 +1,36 @@ import React from 'react'; import _ from 'lodash'; +import {SplitPaneProps} from '../hyper'; -export default class SplitPane extends React.PureComponent { - constructor(props) { +export default class SplitPane extends React.PureComponent { + dragPanePosition!: number; + dragTarget!: Element; + panes!: Element[]; + paneIndex!: number; + d1!: 'height' | 'width'; + d2!: 'top' | 'left'; + d3!: 'clientX' | 'clientY'; + panesSize!: number; + dragging!: boolean; + constructor(props: SplitPaneProps) { super(props); this.state = {dragging: false}; } - componentDidUpdate(prevProps) { + componentDidUpdate(prevProps: SplitPaneProps) { if (this.state.dragging && prevProps.sizes !== this.props.sizes) { // recompute positions for ongoing dragging this.dragPanePosition = this.dragTarget.getBoundingClientRect()[this.d2]; } } - setupPanes(ev) { + setupPanes(ev: any) { this.panes = Array.from(ev.target.parentNode.childNodes); this.paneIndex = this.panes.indexOf(ev.target); this.paneIndex -= Math.ceil(this.paneIndex / 2); } - handleAutoResize = ev => { + handleAutoResize = (ev: React.MouseEvent) => { ev.preventDefault(); this.setupPanes(ev); @@ -36,7 +46,7 @@ export default class SplitPane extends React.PureComponent { this.props.onResize(sizes_); }; - handleDragStart = ev => { + handleDragStart = (ev: any) => { ev.preventDefault(); this.setState({dragging: true}); window.addEventListener('mousemove', this.onDrag); @@ -61,20 +71,20 @@ export default class SplitPane extends React.PureComponent { getSizes() { const {sizes} = this.props; - let sizes_; + let sizes_: number[]; if (sizes) { - sizes_ = [].concat(sizes); + sizes_ = [...sizes.asMutable()]; } else { - const total = this.props.children.length; - const count = new Array(total).fill(1 / total); + const total = (this.props.children as React.ReactNodeArray).length; + const count = new Array(total).fill(1 / total); sizes_ = count; } return sizes_; } - onDrag = ev => { + onDrag = (ev: MouseEvent) => { const sizes_ = this.getSizes(); const i = this.paneIndex; @@ -99,16 +109,13 @@ export default class SplitPane extends React.PureComponent { }; render() { - const children = this.props.children; + const children = this.props.children as React.ReactNodeArray; const {direction, borderColor} = this.props; const sizeProperty = direction === 'horizontal' ? 'height' : 'width'; - let {sizes} = this.props; - if (!sizes) { - // workaround for the fact that if we don't specify - // sizes, sometimes flex fails to calculate the - // right height for the horizontal panes - sizes = new Array(children.length).fill(1 / children.length); - } + // workaround for the fact that if we don't specify + // sizes, sometimes flex fails to calculate the + // right height for the horizontal panes + const sizes = this.props.sizes || new Array(children.length).fill(1 / children.length); return (
{React.Children.map(children, (child, i) => { diff --git a/lib/hyper.d.ts b/lib/hyper.d.ts index 22b3c271..6606a859 100644 --- a/lib/hyper.d.ts +++ b/lib/hyper.d.ts @@ -241,3 +241,20 @@ export type TabsProps = { onClose: () => void; fullScreen: boolean; } & extensionProps; + +export type NotificationProps = { + backgroundColor: string; + color?: string; + dismissAfter?: number; + onDismiss: Function; + text?: string | null; + userDismissable?: boolean | null; + userDismissColor?: string; +} & extensionProps; + +export type SplitPaneProps = { + borderColor: string; + direction: 'horizontal' | 'vertical'; + onResize: Function; + sizes?: Immutable | null; +}; diff --git a/package.json b/package.json index 017e963f..f4df8547 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "@types/copy-webpack-plugin": "5.0.0", "@types/electron-devtools-installer": "2.2.0", "@types/fs-extra": "8.1.0", + "@types/lodash": "^4.14.149", "@types/mkdirp": "1.0.0", "@types/mousetrap": "^1.6.3", "@types/ms": "0.7.31", diff --git a/yarn.lock b/yarn.lock index 8eb9a48b..bafa56d9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -649,6 +649,11 @@ dependencies: "@types/node" "*" +"@types/lodash@^4.14.149": + version "4.14.149" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" + integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== + "@types/minimatch@*": version "3.0.3" resolved "https://registry.yarnpkg.com/@types/minimatch/-/minimatch-3.0.3.tgz#3dca0e3f33b200fc7d1139c0cd96c1268cadfd9d"