feat: refactor progress bar code to expose static progress bar

This commit is contained in:
fragosti
2018-11-09 13:19:59 -08:00
parent daa011f7cb
commit fa7bd072d0
5 changed files with 73 additions and 26 deletions

View File

@@ -1,6 +1,7 @@
import * as _ from 'lodash';
import * as React from 'react'; import * as React from 'react';
import { TimedProgressBar } from '../components/timed_progress_bar'; import { ProgressBar, TimedProgressBar } from '../components/timed_progress_bar';
import { TimeCounter } from '../components/time_counter'; import { TimeCounter } from '../components/time_counter';
import { Container } from '../components/ui/container'; import { Container } from '../components/ui/container';
@@ -12,7 +13,7 @@ export interface BuyOrderProgressProps {
export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> = props => { export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> = props => {
const { buyOrderState } = props; const { buyOrderState } = props;
let content: React.ReactNode = null;
if ( if (
buyOrderState.processState === OrderProcessState.Processing || buyOrderState.processState === OrderProcessState.Processing ||
buyOrderState.processState === OrderProcessState.Success || buyOrderState.processState === OrderProcessState.Success ||
@@ -21,15 +22,25 @@ export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> =
const progress = buyOrderState.progress; const progress = buyOrderState.progress;
const hasEnded = buyOrderState.processState !== OrderProcessState.Processing; const hasEnded = buyOrderState.processState !== OrderProcessState.Processing;
const expectedTimeMs = progress.expectedEndTimeUnix - progress.startTimeUnix; const expectedTimeMs = progress.expectedEndTimeUnix - progress.startTimeUnix;
return ( content = (
<Container padding="20px 20px 0px 20px" width="100%"> <React.Fragment>
<Container marginBottom="5px"> <Container marginBottom="5px">
<TimeCounter estimatedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} /> <TimeCounter estimatedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} />
</Container> </Container>
<TimedProgressBar expectedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} /> <TimedProgressBar expectedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} />
</React.Fragment>
);
} else {
// Just show a static progress bar if we aren't processing or in an end state
content = (
<Container marginTop="10px">
<ProgressBar width="0px" />
</Container> </Container>
); );
} }
return (
return null; <Container padding="20px 20px 0px 20px" width="100%">
{content}
</Container>
);
}; };

View File

@@ -2,7 +2,7 @@ import * as _ from 'lodash';
import * as React from 'react'; import * as React from 'react';
import { PROGRESS_FINISH_ANIMATION_TIME_MS, PROGRESS_STALL_AT_WIDTH } from '../constants'; import { PROGRESS_FINISH_ANIMATION_TIME_MS, PROGRESS_STALL_AT_WIDTH } from '../constants';
import { ColorOption, keyframes, styled } from '../style/theme'; import { ColorOption, css, keyframes, styled } from '../style/theme';
import { Container } from './ui/container'; import { Container } from './ui/container';
@@ -20,15 +20,11 @@ export class TimedProgressBar extends React.Component<TimedProgressBarProps, {}>
private readonly _barRef = React.createRef<HTMLDivElement>(); private readonly _barRef = React.createRef<HTMLDivElement>();
public render(): React.ReactNode { public render(): React.ReactNode {
const timedProgressProps = this._calculateTimedProgressProps(); const widthAnimationSettings = this._calculateWidthAnimationSettings();
return ( return <ProgressBar animationSettings={widthAnimationSettings} ref={this._barRef} />;
<Container width="100%" backgroundColor={ColorOption.lightGrey} borderRadius="6px">
<TimedProgress {...timedProgressProps} ref={this._barRef as any} />
</Container>
);
} }
private _calculateTimedProgressProps(): TimedProgressProps { private _calculateWidthAnimationSettings(): WidthAnimationSettings {
if (this.props.hasEnded) { if (this.props.hasEnded) {
if (!this._barRef.current) { if (!this._barRef.current) {
throw new Error('ended but no reference'); throw new Error('ended but no reference');
@@ -60,21 +56,45 @@ const expandingWidthKeyframes = (fromWidth: string, toWidth: string) => {
`; `;
}; };
interface TimedProgressProps { export interface WidthAnimationSettings {
timeMs: number; timeMs: number;
fromWidth: string; fromWidth: string;
toWidth: string; toWidth: string;
} }
export const TimedProgress = interface ProgressProps {
width?: string;
animationSettings?: WidthAnimationSettings;
}
export const Progress =
styled.div < styled.div <
TimedProgressProps > ProgressProps >
` `
&& { && {
background-color: ${props => props.theme[ColorOption.primaryColor]}; background-color: ${props => props.theme[ColorOption.primaryColor]};
border-radius: 6px; border-radius: 6px;
height: 6px; height: 6px;
animation: ${props => expandingWidthKeyframes(props.fromWidth, props.toWidth)} ${props => (props.width ? `width: ${props.width};` : '')}
${props => props.timeMs}ms linear 1 forwards; ${props =>
props.animationSettings
? css`
animation: ${expandingWidthKeyframes(
props.animationSettings.fromWidth,
props.animationSettings.toWidth,
)}
${props.animationSettings.timeMs}ms linear 1 forwards;
`
: ''}
} }
`; `;
export interface ProgressBarProps extends ProgressProps {}
export const ProgressBar: React.ComponentType<ProgressBarProps & React.ClassAttributes<{}>> = React.forwardRef(
(props, ref) => (
<Container width="100%" backgroundColor={ColorOption.lightGrey} borderRadius="6px">
<Progress {...props} ref={ref as any} />
</Container>
),
);

View File

@@ -1,8 +1,8 @@
import * as React from 'react'; import * as React from 'react';
import { INJECTED_DIV_CLASS } from '../constants'; import { INJECTED_DIV_CLASS } from '../constants';
import { ConnectedZeroExInstantContainer } from '../containers/connected_zero_ex_instant_container';
import { ZeroExInstantContainer } from './zero_ex_instant_container';
import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider'; import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider';
export type ZeroExInstantProps = ZeroExInstantProviderProps; export type ZeroExInstantProps = ZeroExInstantProviderProps;
@@ -11,7 +11,7 @@ export const ZeroExInstant: React.StatelessComponent<ZeroExInstantProps> = props
return ( return (
<div className={INJECTED_DIV_CLASS}> <div className={INJECTED_DIV_CLASS}>
<ZeroExInstantProvider {...props}> <ZeroExInstantProvider {...props}>
<ZeroExInstantContainer /> <ConnectedZeroExInstantContainer />
</ZeroExInstantProvider> </ZeroExInstantProvider>
</div> </div>
); );

View File

@@ -9,14 +9,16 @@ import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_
import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading'; import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading';
import { ColorOption } from '../style/theme'; import { ColorOption } from '../style/theme';
import { zIndex } from '../style/z_index'; import { zIndex } from '../style/z_index';
import { SlideAnimationState } from '../types'; import { OrderProcessState, SlideAnimationState } from '../types';
import { CSSReset } from './css_reset'; import { CSSReset } from './css_reset';
import { SlidingPanel } from './sliding_panel'; import { SlidingPanel } from './sliding_panel';
import { Container } from './ui/container'; import { Container } from './ui/container';
import { Flex } from './ui/flex'; import { Flex } from './ui/flex';
export interface ZeroExInstantContainerProps {} export interface ZeroExInstantContainerProps {
orderProcessState: OrderProcessState;
}
export interface ZeroExInstantContainerState { export interface ZeroExInstantContainerState {
tokenSelectionPanelAnimationState: SlideAnimationState; tokenSelectionPanelAnimationState: SlideAnimationState;
} }
@@ -48,7 +50,7 @@ export class ZeroExInstantContainer extends React.Component<ZeroExInstantContain
> >
<Flex direction="column" justify="flex-start" height="100%"> <Flex direction="column" justify="flex-start" height="100%">
<SelectedAssetInstantHeading onSelectAssetClick={this._handleSymbolClick} /> <SelectedAssetInstantHeading onSelectAssetClick={this._handleSymbolClick} />
<SelectedAssetBuyOrderProgress /> {this._renderPaymentMethodOrBuyOrderProgress()}
<LatestBuyQuoteOrderDetails /> <LatestBuyQuoteOrderDetails />
<Container padding="20px" width="100%"> <Container padding="20px" width="100%">
<SelectedAssetBuyOrderStateButtons /> <SelectedAssetBuyOrderStateButtons />
@@ -76,4 +78,18 @@ export class ZeroExInstantContainer extends React.Component<ZeroExInstantContain
tokenSelectionPanelAnimationState: 'slidOut', tokenSelectionPanelAnimationState: 'slidOut',
}); });
}; };
private readonly _renderPaymentMethodOrBuyOrderProgress = (): React.ReactNode => {
const { orderProcessState } = this.props;
if (
orderProcessState === OrderProcessState.Processing ||
orderProcessState === OrderProcessState.Success ||
orderProcessState === OrderProcessState.Failure
) {
return <SelectedAssetBuyOrderProgress />;
}
if (orderProcessState === OrderProcessState.None) {
return <SelectedAssetBuyOrderProgress />;
}
return null;
};
} }

View File

@@ -1,12 +1,12 @@
import * as React from 'react'; import * as React from 'react';
import { ConnectedZeroExInstantContainer } from '../containers/connected_zero_ex_instant_container';
import { ColorOption } from '../style/theme'; import { ColorOption } from '../style/theme';
import { Container } from './ui/container'; import { Container } from './ui/container';
import { Flex } from './ui/flex'; import { Flex } from './ui/flex';
import { Icon } from './ui/icon'; import { Icon } from './ui/icon';
import { Overlay } from './ui/overlay'; import { Overlay } from './ui/overlay';
import { ZeroExInstantContainer } from './zero_ex_instant_container';
import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider'; import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider';
export interface ZeroExInstantOverlayProps extends ZeroExInstantProviderProps { export interface ZeroExInstantOverlayProps extends ZeroExInstantProviderProps {
@@ -31,7 +31,7 @@ export const ZeroExInstantOverlay: React.StatelessComponent<ZeroExInstantOverlay
/> />
</Container> </Container>
<Container width={{ default: 'auto', sm: '100%' }} height={{ default: 'auto', sm: '100%' }}> <Container width={{ default: 'auto', sm: '100%' }} height={{ default: 'auto', sm: '100%' }}>
<ZeroExInstantContainer /> <ConnectedZeroExInstantContainer />
</Container> </Container>
</Flex> </Flex>
</Overlay> </Overlay>