protocol/packages/website/ts/components/ui/lifecycle_raised_button.tsx
Fabio Berger 10478a6b2f Merge branch 'v2-prototype' into refactor/move-spawn-switch-to-utils
* v2-prototype: (66 commits)
  Run prettier
  Remove unused variable
  Fix linting issues
  Change shouldRenderHeader prop to shouldHideHeader
  Get build and tests to pass
  typo
  Apply prettier
  Update contracts tests after rebase
  Apply various fixes based on PR feedback
  Document debug_increaseTime method and fix typo in devnet README
  Use an enum for ProviderType in contracts/src/utils/web3_wrapper
  Update contracts package README
  Update relevant changelogs
  Remove global gas estimate buffer
  Add Async suffix to relevant assertions
  Fix linter errors
  Update package.json and yarn.lock
  Update more things to work with both Geth and Ganache
  Small fixes and cleanup
  Add additional gas to calls to fillOrderNoThrow
  ...

# Conflicts:
#	packages/order-watcher/src/order_watcher/order_watcher.ts
#	packages/react-docs/src/components/type.tsx
#	packages/website/ts/components/ui/lifecycle_raised_button.tsx
#	packages/website/ts/components/wallet/wallet.tsx
2018-06-07 12:21:44 +02:00

104 lines
3.2 KiB
TypeScript

import { colors } from '@0xproject/react-shared';
import { errorUtils } from '@0xproject/utils';
import RaisedButton from 'material-ui/RaisedButton';
import * as React from 'react';
import { utils } from 'ts/utils/utils';
const COMPLETE_STATE_SHOW_LENGTH_MS = 2000;
enum ButtonState {
READY,
LOADING,
COMPLETE,
}
interface LifeCycleRaisedButtonProps {
isHidden?: boolean;
isDisabled?: boolean;
isPrimary?: boolean;
labelReady: React.ReactNode | string;
labelLoading: React.ReactNode | string;
labelComplete: React.ReactNode | string;
onClickAsyncFn: () => Promise<boolean>;
backgroundColor?: string;
labelColor?: string;
}
interface LifeCycleRaisedButtonState {
buttonState: ButtonState;
}
export class LifeCycleRaisedButton extends React.Component<LifeCycleRaisedButtonProps, LifeCycleRaisedButtonState> {
public static defaultProps: Partial<LifeCycleRaisedButtonProps> = {
isDisabled: false,
backgroundColor: colors.white,
labelColor: colors.darkGrey,
};
private _buttonTimeoutId: number;
private _didUnmount: boolean;
constructor(props: LifeCycleRaisedButtonProps) {
super(props);
this.state = {
buttonState: ButtonState.READY,
};
}
public componentWillUnmount(): void {
clearTimeout(this._buttonTimeoutId);
this._didUnmount = true;
}
public render(): React.ReactNode {
if (this.props.isHidden) {
return <span />;
}
let label;
switch (this.state.buttonState) {
case ButtonState.READY:
label = this.props.labelReady;
break;
case ButtonState.LOADING:
label = this.props.labelLoading;
break;
case ButtonState.COMPLETE:
label = this.props.labelComplete;
break;
default:
throw errorUtils.spawnSwitchErr('ButtonState', this.state.buttonState);
}
return (
<RaisedButton
primary={this.props.isPrimary}
label={label}
style={{ width: '100%' }}
backgroundColor={this.props.backgroundColor}
labelColor={this.props.labelColor}
onTouchTap={this.onClickAsync.bind(this)}
disabled={this.props.isDisabled || this.state.buttonState !== ButtonState.READY}
/>
);
}
public async onClickAsync(): Promise<void> {
this.setState({
buttonState: ButtonState.LOADING,
});
const didSucceed = await this.props.onClickAsyncFn();
if (this._didUnmount) {
return; // noop since unmount called before async callback returned.
}
if (didSucceed) {
this.setState({
buttonState: ButtonState.COMPLETE,
});
this._buttonTimeoutId = window.setTimeout(() => {
this.setState({
buttonState: ButtonState.READY,
});
}, COMPLETE_STATE_SHOW_LENGTH_MS);
} else {
this.setState({
buttonState: ButtonState.READY,
});
}
}
}