aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/components/ui/lifecycle_raised_button.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website/ts/components/ui/lifecycle_raised_button.tsx')
-rw-r--r--packages/website/ts/components/ui/lifecycle_raised_button.tsx105
1 files changed, 105 insertions, 0 deletions
diff --git a/packages/website/ts/components/ui/lifecycle_raised_button.tsx b/packages/website/ts/components/ui/lifecycle_raised_button.tsx
new file mode 100644
index 000000000..e93c80ba4
--- /dev/null
+++ b/packages/website/ts/components/ui/lifecycle_raised_button.tsx
@@ -0,0 +1,105 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+import {utils} from 'ts/utils/utils';
+import {Token} from 'ts/types';
+import {Blockchain} from 'ts/blockchain';
+import RaisedButton from 'material-ui/RaisedButton';
+
+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: () => 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: 'white',
+ labelColor: 'rgb(97, 97, 97)',
+ };
+ private buttonTimeoutId: number;
+ private didUnmount: boolean;
+ constructor(props: LifeCycleRaisedButtonProps) {
+ super(props);
+ this.state = {
+ buttonState: ButtonState.READY,
+ };
+ }
+ public componentWillUnmount() {
+ clearTimeout(this.buttonTimeoutId);
+ this.didUnmount = true;
+ }
+ public render() {
+ if (this.props.isHidden === true) {
+ 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 utils.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() {
+ 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,
+ });
+ }
+ }
+}