HenryNguyen5 5d4b36d453 Migrate to Typescript (#224)
* Refactor babel/types

* Refactor entry point

* Refactor actions

* Refactor api

* Full project refactor -- Broad type fixing sweep

* - completely fix merge conflicts
- handle various type errors

* Add tslint to package.json

* Dependency cleanup

* Fix module resolution

* Work on type definitions for untyped libs

* progress commit

* Add more definition typing

* various type additions

* Add unit types

* Fix sagaiterator  + unit types

* various types added

* additional type additions

* Fix typing on Sagas

* remove flowfixmes; swap translate for translateRaw

* Get rid of contracts - awaiting Henry's contract PR

* Remove contracts from routing

* Fix most of actions/reducers

* refactor actions directory structure

* fix reducer action type imports

* Fix most of type errors pre-actions refactor

* fix action creator imports in containers

* Refactor more

* Refactor index of actions

* fix action imports; use module level index export

* package-lock.json updated

* Use action types in props

* Type up action creators

* Fix most of connect errors

* Typefixing progress

* More types

* Fix run-time errors

* Caching improvements for webpack

* Remove path resolve from webpack

* Update non-breaking packages to latest version

* Fix token typing

* Remove unused color code

* Fix wallet decrypt dispatch

* Set redux-form related props/functions to ANY, since we're stripping it out later on

* Revert BigNumber.js package changes

* Extend window to custom object for Perf

* Format Navigation

* Typecase keystore errors as any (since we shouldnt touch this)

* Push wallet context fix

* - find/replace value->payload in swap
- properly type swap state properties
- extract inline reducer into reducer function

* - type local storage retrieved items as generic

* - bind all RPCClient methods with fat arrow

* - reformat

* Change to enums for constants

* Change state into any

* Fix swap errors

* ensure that seconds are passed into state as integers

* Fix rest of errors

* use parseInt explicitly instead of type coercion

* Fix derivation-checker, remove flow command, add tslint command, add tslint-react, tell travis to use tslint instead of flow.

* Whoops, remove those tests.

* Remove unsupported (yet) config option.

* Fix precommit to target ts and tsx files.

* Fix some errors, ignore some silly rules.

* Revert jest to v19, use ts-jest and make all tests typescript. Fixes all but one.

* Get rid of saga tests

* Fix tslint errors
2017-09-24 19:06:28 -07:00

114 lines
2.8 KiB
TypeScript

import closeIcon from 'assets/images/icon-x.svg';
import React, { Component } from 'react';
import './Modal.scss';
export interface IButton {
text: string;
type?:
| 'default'
| 'primary'
| 'success'
| 'info'
| 'warning'
| 'danger'
| 'link';
disabled?: boolean;
onClick?(): void;
}
interface Props {
isOpen?: boolean;
title: string;
disableButtons?: boolean;
children: any;
buttons: IButton[];
handleClose(): void;
}
export default class Modal extends Component<Props, {}> {
public componentDidMount() {
this.updateBodyClass();
document.addEventListener('keydown', this.escapeListner);
}
public componentDidUpdate() {
this.updateBodyClass();
}
public updateBodyClass() {
document.body.classList.toggle('no-scroll', !!this.props.isOpen);
}
public componentWillUnmount() {
document.removeEventListener('keydown', this.escapeListner);
document.body.classList.remove('no-scroll');
}
public render() {
const { isOpen, title, children, buttons, handleClose } = this.props;
const hasButtons = buttons && buttons.length;
return (
<div>
<div className={`Modalshade ${isOpen ? 'is-open' : ''}`} />
<div className={`Modal ${isOpen ? 'is-open' : ''}`}>
<div className="Modal-header">
<h2 className="Modal-header-title">
{title}
</h2>
<button className="Modal-header-close" onClick={handleClose}>
<img className="Modal-header-close-icon" src={closeIcon} />
</button>
</div>
<div className="Modal-content">
{isOpen && children}
</div>
{hasButtons &&
<div className="Modal-footer">
{this.renderButtons()}
</div>}
</div>
</div>
);
}
private escapeListner = (ev: KeyboardEvent) => {
// Don't trigger if they hit escape while on an input
if (ev.target) {
if (
(ev.target as HTMLElement).tagName === 'INPUT' ||
(ev.target as HTMLElement).tagName === 'SELECT' ||
(ev.target as HTMLElement).tagName === 'TEXTAREA' ||
(ev.target as HTMLElement).isContentEditable
) {
return;
}
}
if (ev.key === 'Escape' || ev.keyCode === 27) {
this.props.handleClose();
}
};
private renderButtons = () => {
const { disableButtons, buttons } = this.props;
return buttons.map((btn, idx) => {
let btnClass = 'Modal-footer-btn btn';
if (btn.type) {
btnClass += ` btn-${btn.type}`;
}
return (
<button
className={btnClass}
onClick={btn.onClick}
key={idx}
disabled={disableButtons || btn.disabled}
>
{btn.text}
</button>
);
});
};
}