Merge pull request #838 from 0xProject/feature/website/portal-final-touches
Some final polish touches for portal!
This commit is contained in:
commit
269b56b907
BIN
packages/website/public/images/unlock-mm.png
Normal file
BIN
packages/website/public/images/unlock-mm.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
@ -1,10 +1,10 @@
|
|||||||
import { BigNumber } from '@0xproject/utils';
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { Balance } from 'ts/components/ui/balance';
|
||||||
import { Container } from 'ts/components/ui/container';
|
import { Container } from 'ts/components/ui/container';
|
||||||
import { Image } from 'ts/components/ui/image';
|
import { Image } from 'ts/components/ui/image';
|
||||||
import { Text } from 'ts/components/ui/text';
|
import { Text } from 'ts/components/ui/text';
|
||||||
import { constants } from 'ts/utils/constants';
|
import { constants } from 'ts/utils/constants';
|
||||||
import { utils } from 'ts/utils/utils';
|
|
||||||
|
|
||||||
export interface AddEthOnboardingStepProps {
|
export interface AddEthOnboardingStepProps {
|
||||||
userEthBalanceInWei: BigNumber;
|
userEthBalanceInWei: BigNumber;
|
||||||
@ -15,13 +15,11 @@ export const AddEthOnboardingStep: React.StatelessComponent<AddEthOnboardingStep
|
|||||||
<div className="flex items-center flex-column">
|
<div className="flex items-center flex-column">
|
||||||
<Text>
|
<Text>
|
||||||
Great! Looks like you already have{' '}
|
Great! Looks like you already have{' '}
|
||||||
<b>
|
<Balance
|
||||||
{utils.getFormattedAmount(
|
amount={props.userEthBalanceInWei}
|
||||||
props.userEthBalanceInWei,
|
decimals={constants.DECIMAL_PLACES_ETH}
|
||||||
constants.DECIMAL_PLACES_ETH,
|
symbol={constants.ETHER_SYMBOL}
|
||||||
constants.ETHER_SYMBOL,
|
/>{' '}
|
||||||
)}{' '}
|
|
||||||
</b>
|
|
||||||
in your wallet.
|
in your wallet.
|
||||||
</Text>
|
</Text>
|
||||||
<Container marginTop="15px" marginBottom="15px">
|
<Container marginTop="15px" marginBottom="15px">
|
||||||
|
@ -12,6 +12,7 @@ export type ContinueButtonDisplay = 'enabled' | 'disabled';
|
|||||||
|
|
||||||
export interface OnboardingCardProps {
|
export interface OnboardingCardProps {
|
||||||
title?: string;
|
title?: string;
|
||||||
|
shouldCenterTitle?: boolean;
|
||||||
content: React.ReactNode;
|
content: React.ReactNode;
|
||||||
isLastStep: boolean;
|
isLastStep: boolean;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
@ -23,10 +24,13 @@ export interface OnboardingCardProps {
|
|||||||
shouldHideNextButton?: boolean;
|
shouldHideNextButton?: boolean;
|
||||||
continueButtonText?: string;
|
continueButtonText?: string;
|
||||||
borderRadius?: string;
|
borderRadius?: string;
|
||||||
|
// Used for super-custom content.
|
||||||
|
shouldRemoveExtraSpacing?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OnboardingCard: React.StatelessComponent<OnboardingCardProps> = ({
|
export const OnboardingCard: React.StatelessComponent<OnboardingCardProps> = ({
|
||||||
title,
|
title,
|
||||||
|
shouldCenterTitle,
|
||||||
content,
|
content,
|
||||||
continueButtonDisplay,
|
continueButtonDisplay,
|
||||||
continueButtonText,
|
continueButtonText,
|
||||||
@ -37,19 +41,34 @@ export const OnboardingCard: React.StatelessComponent<OnboardingCardProps> = ({
|
|||||||
shouldHideBackButton,
|
shouldHideBackButton,
|
||||||
shouldHideNextButton,
|
shouldHideNextButton,
|
||||||
borderRadius,
|
borderRadius,
|
||||||
}) => (
|
shouldRemoveExtraSpacing,
|
||||||
|
}) => {
|
||||||
|
const padding = shouldRemoveExtraSpacing
|
||||||
|
? {}
|
||||||
|
: {
|
||||||
|
paddingRight: '30px',
|
||||||
|
paddingLeft: '30px',
|
||||||
|
paddingTop: '15px',
|
||||||
|
paddingBottom: '15px',
|
||||||
|
};
|
||||||
|
const closeIconPositioning = shouldRemoveExtraSpacing
|
||||||
|
? { right: '15px', bottom: '3px' }
|
||||||
|
: { bottom: '20px', left: '15px' };
|
||||||
|
return (
|
||||||
<Island borderRadius={borderRadius}>
|
<Island borderRadius={borderRadius}>
|
||||||
<Container paddingRight="30px" paddingLeft="30px" paddingTop="15px" paddingBottom="15px">
|
<Container {...padding}>
|
||||||
<div className="flex flex-column">
|
<div className="flex flex-column">
|
||||||
<div className="flex justify-between">
|
<Container className="flex justify-between">
|
||||||
<Title>{title}</Title>
|
<Container width="100%">
|
||||||
<Container position="relative" bottom="20px" left="15px">
|
<Title center={shouldCenterTitle}>{title}</Title>
|
||||||
|
</Container>
|
||||||
|
<Container position="relative" {...closeIconPositioning}>
|
||||||
<IconButton color={colors.grey} iconName="zmdi-close" onClick={onClose}>
|
<IconButton color={colors.grey} iconName="zmdi-close" onClick={onClose}>
|
||||||
Close
|
Close
|
||||||
</IconButton>
|
</IconButton>
|
||||||
</Container>
|
</Container>
|
||||||
</div>
|
</Container>
|
||||||
<Container marginBottom="15px">
|
<Container marginBottom={shouldRemoveExtraSpacing ? undefined : '15px'}>
|
||||||
<Text>{content}</Text>
|
<Text>{content}</Text>
|
||||||
</Container>
|
</Container>
|
||||||
{continueButtonDisplay && (
|
{continueButtonDisplay && (
|
||||||
@ -63,6 +82,7 @@ export const OnboardingCard: React.StatelessComponent<OnboardingCardProps> = ({
|
|||||||
{continueButtonText}
|
{continueButtonText}
|
||||||
</Button>
|
</Button>
|
||||||
)}
|
)}
|
||||||
|
{!(shouldHideBackButton && shouldHideNextButton) && (
|
||||||
<Container className="clearfix" marginTop="15px">
|
<Container className="clearfix" marginTop="15px">
|
||||||
<div className="left">
|
<div className="left">
|
||||||
{!shouldHideBackButton && (
|
{!shouldHideBackButton && (
|
||||||
@ -79,13 +99,17 @@ export const OnboardingCard: React.StatelessComponent<OnboardingCardProps> = ({
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</Container>
|
</Container>
|
||||||
</Island>
|
</Island>
|
||||||
);
|
);
|
||||||
|
};
|
||||||
|
|
||||||
OnboardingCard.defaultProps = {
|
OnboardingCard.defaultProps = {
|
||||||
continueButtonText: 'Continue',
|
continueButtonText: 'Continue',
|
||||||
|
shouldCenterTitle: false,
|
||||||
|
shouldRemoveExtraSpacing: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
OnboardingCard.displayName = 'OnboardingCard';
|
OnboardingCard.displayName = 'OnboardingCard';
|
||||||
|
@ -2,11 +2,14 @@ import * as React from 'react';
|
|||||||
import { Placement, Popper, PopperChildrenProps } from 'react-popper';
|
import { Placement, Popper, PopperChildrenProps } from 'react-popper';
|
||||||
|
|
||||||
import { OnboardingCard } from 'ts/components/onboarding/onboarding_card';
|
import { OnboardingCard } from 'ts/components/onboarding/onboarding_card';
|
||||||
import { ContinueButtonDisplay, OnboardingTooltip } from 'ts/components/onboarding/onboarding_tooltip';
|
import {
|
||||||
|
ContinueButtonDisplay,
|
||||||
|
OnboardingTooltip,
|
||||||
|
TooltipPointerDisplay,
|
||||||
|
} from 'ts/components/onboarding/onboarding_tooltip';
|
||||||
import { Animation } from 'ts/components/ui/animation';
|
import { Animation } from 'ts/components/ui/animation';
|
||||||
import { Container } from 'ts/components/ui/container';
|
import { Container } from 'ts/components/ui/container';
|
||||||
import { Overlay } from 'ts/components/ui/overlay';
|
import { Overlay } from 'ts/components/ui/overlay';
|
||||||
import { PointerDirection } from 'ts/components/ui/pointer';
|
|
||||||
import { zIndex } from 'ts/style/z_index';
|
import { zIndex } from 'ts/style/z_index';
|
||||||
|
|
||||||
export interface FixedPositionSettings {
|
export interface FixedPositionSettings {
|
||||||
@ -15,7 +18,7 @@ export interface FixedPositionSettings {
|
|||||||
bottom?: string;
|
bottom?: string;
|
||||||
left?: string;
|
left?: string;
|
||||||
right?: string;
|
right?: string;
|
||||||
pointerDirection?: PointerDirection;
|
tooltipPointerDisplay?: TooltipPointerDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface TargetPositionSettings {
|
export interface TargetPositionSettings {
|
||||||
@ -28,12 +31,15 @@ export interface Step {
|
|||||||
// Provide either a CSS selector, or fixed position settings. Only applies to desktop.
|
// Provide either a CSS selector, or fixed position settings. Only applies to desktop.
|
||||||
position: TargetPositionSettings | FixedPositionSettings;
|
position: TargetPositionSettings | FixedPositionSettings;
|
||||||
title?: string;
|
title?: string;
|
||||||
|
shouldCenterTitle?: boolean;
|
||||||
content: React.ReactNode;
|
content: React.ReactNode;
|
||||||
shouldHideBackButton?: boolean;
|
shouldHideBackButton?: boolean;
|
||||||
shouldHideNextButton?: boolean;
|
shouldHideNextButton?: boolean;
|
||||||
continueButtonDisplay?: ContinueButtonDisplay;
|
continueButtonDisplay?: ContinueButtonDisplay;
|
||||||
continueButtonText?: string;
|
continueButtonText?: string;
|
||||||
onContinueButtonClick?: () => void;
|
onContinueButtonClick?: () => void;
|
||||||
|
// Only used for very custom steps.
|
||||||
|
shouldRemoveExtraSpacing?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface OnboardingFlowProps {
|
export interface OnboardingFlowProps {
|
||||||
@ -69,7 +75,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
</Popper>
|
</Popper>
|
||||||
);
|
);
|
||||||
} else if (currentStep.position.type === 'fixed') {
|
} else if (currentStep.position.type === 'fixed') {
|
||||||
const { top, right, bottom, left, pointerDirection } = currentStep.position;
|
const { top, right, bottom, left, tooltipPointerDisplay } = currentStep.position;
|
||||||
onboardingElement = (
|
onboardingElement = (
|
||||||
<Container
|
<Container
|
||||||
position="fixed"
|
position="fixed"
|
||||||
@ -79,7 +85,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
bottom={bottom}
|
bottom={bottom}
|
||||||
left={left}
|
left={left}
|
||||||
>
|
>
|
||||||
{this._renderToolTip(pointerDirection)}
|
{this._renderToolTip(tooltipPointerDisplay)}
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -103,7 +109,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
private _renderToolTip(pointerDirection?: PointerDirection): React.ReactNode {
|
private _renderToolTip(tooltipPointerDisplay?: TooltipPointerDisplay): React.ReactNode {
|
||||||
const { steps, stepIndex } = this.props;
|
const { steps, stepIndex } = this.props;
|
||||||
const step = steps[stepIndex];
|
const step = steps[stepIndex];
|
||||||
const isLastStep = steps.length - 1 === stepIndex;
|
const isLastStep = steps.length - 1 === stepIndex;
|
||||||
@ -111,6 +117,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
<Container marginLeft="30px" width="400px">
|
<Container marginLeft="30px" width="400px">
|
||||||
<OnboardingTooltip
|
<OnboardingTooltip
|
||||||
title={step.title}
|
title={step.title}
|
||||||
|
shouldCenterTitle={step.shouldCenterTitle}
|
||||||
content={step.content}
|
content={step.content}
|
||||||
isLastStep={isLastStep}
|
isLastStep={isLastStep}
|
||||||
shouldHideBackButton={step.shouldHideBackButton}
|
shouldHideBackButton={step.shouldHideBackButton}
|
||||||
@ -121,7 +128,8 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
continueButtonDisplay={step.continueButtonDisplay}
|
continueButtonDisplay={step.continueButtonDisplay}
|
||||||
continueButtonText={step.continueButtonText}
|
continueButtonText={step.continueButtonText}
|
||||||
onContinueButtonClick={step.onContinueButtonClick}
|
onContinueButtonClick={step.onContinueButtonClick}
|
||||||
pointerDirection={pointerDirection}
|
pointerDisplay={tooltipPointerDisplay}
|
||||||
|
shouldRemoveExtraSpacing={step.shouldRemoveExtraSpacing}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
@ -135,6 +143,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
<Container position="relative" zIndex={1}>
|
<Container position="relative" zIndex={1}>
|
||||||
<OnboardingCard
|
<OnboardingCard
|
||||||
title={step.title}
|
title={step.title}
|
||||||
|
shouldCenterTitle={step.shouldCenterTitle}
|
||||||
content={step.content}
|
content={step.content}
|
||||||
isLastStep={isLastStep}
|
isLastStep={isLastStep}
|
||||||
shouldHideBackButton={step.shouldHideBackButton}
|
shouldHideBackButton={step.shouldHideBackButton}
|
||||||
@ -146,6 +155,7 @@ export class OnboardingFlow extends React.Component<OnboardingFlowProps> {
|
|||||||
continueButtonText={step.continueButtonText}
|
continueButtonText={step.continueButtonText}
|
||||||
onContinueButtonClick={step.onContinueButtonClick}
|
onContinueButtonClick={step.onContinueButtonClick}
|
||||||
borderRadius="10px 10px 0px 0px"
|
borderRadius="10px 10px 0px 0px"
|
||||||
|
shouldRemoveExtraSpacing={step.shouldRemoveExtraSpacing}
|
||||||
/>
|
/>
|
||||||
</Container>
|
</Container>
|
||||||
);
|
);
|
||||||
|
@ -4,22 +4,27 @@ import { OnboardingCard, OnboardingCardProps } from 'ts/components/onboarding/on
|
|||||||
import { Pointer, PointerDirection } from 'ts/components/ui/pointer';
|
import { Pointer, PointerDirection } from 'ts/components/ui/pointer';
|
||||||
|
|
||||||
export type ContinueButtonDisplay = 'enabled' | 'disabled';
|
export type ContinueButtonDisplay = 'enabled' | 'disabled';
|
||||||
|
export type TooltipPointerDisplay = PointerDirection | 'none';
|
||||||
|
|
||||||
export interface OnboardingTooltipProps extends OnboardingCardProps {
|
export interface OnboardingTooltipProps extends OnboardingCardProps {
|
||||||
className?: string;
|
className?: string;
|
||||||
pointerDirection?: PointerDirection;
|
pointerDisplay?: TooltipPointerDisplay;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const OnboardingTooltip: React.StatelessComponent<OnboardingTooltipProps> = props => {
|
export const OnboardingTooltip: React.StatelessComponent<OnboardingTooltipProps> = props => {
|
||||||
const { pointerDirection, className, ...cardProps } = props;
|
const { pointerDisplay, className, ...cardProps } = props;
|
||||||
|
const card = <OnboardingCard {...cardProps} />;
|
||||||
|
if (pointerDisplay === 'none') {
|
||||||
|
return card;
|
||||||
|
}
|
||||||
return (
|
return (
|
||||||
<Pointer className={className} direction={pointerDirection}>
|
<Pointer className={className} direction={pointerDisplay}>
|
||||||
<OnboardingCard {...cardProps} />
|
<OnboardingCard {...cardProps} />
|
||||||
</Pointer>
|
</Pointer>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
OnboardingTooltip.defaultProps = {
|
OnboardingTooltip.defaultProps = {
|
||||||
pointerDirection: 'left',
|
pointerDisplay: 'left',
|
||||||
};
|
};
|
||||||
|
|
||||||
OnboardingTooltip.displayName = 'OnboardingTooltip';
|
OnboardingTooltip.displayName = 'OnboardingTooltip';
|
||||||
|
@ -91,9 +91,9 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
};
|
};
|
||||||
const underMetamaskExtension: FixedPositionSettings = {
|
const underMetamaskExtension: FixedPositionSettings = {
|
||||||
type: 'fixed',
|
type: 'fixed',
|
||||||
top: '30px',
|
top: '10px',
|
||||||
right: '10px',
|
right: '10px',
|
||||||
pointerDirection: 'top',
|
tooltipPointerDisplay: 'none',
|
||||||
};
|
};
|
||||||
const steps: Step[] = [
|
const steps: Step[] = [
|
||||||
{
|
{
|
||||||
@ -105,10 +105,12 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
position: underMetamaskExtension,
|
position: underMetamaskExtension,
|
||||||
title: '0x Ecosystem Setup',
|
title: 'Please Unlock Metamask...',
|
||||||
content: <UnlockWalletOnboardingStep />,
|
content: <UnlockWalletOnboardingStep />,
|
||||||
shouldHideBackButton: true,
|
shouldHideBackButton: true,
|
||||||
shouldHideNextButton: true,
|
shouldHideNextButton: true,
|
||||||
|
shouldCenterTitle: true,
|
||||||
|
shouldRemoveExtraSpacing: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
position: nextToWalletPosition,
|
position: nextToWalletPosition,
|
||||||
@ -140,13 +142,7 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
{
|
{
|
||||||
position: nextToWalletPosition,
|
position: nextToWalletPosition,
|
||||||
title: 'Step 2: Wrap ETH',
|
title: 'Step 2: Wrap ETH',
|
||||||
content: (
|
content: <WrapEthOnboardingStep3 wethAmount={this._getWethBalance()} />,
|
||||||
<WrapEthOnboardingStep3
|
|
||||||
formattedWethBalanceIfExists={
|
|
||||||
this._userHasVisibleWeth() ? this._getFormattedWethBalance() : undefined
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled',
|
continueButtonDisplay: this._userHasVisibleWeth() ? 'enabled' : 'disabled',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -187,11 +183,6 @@ class PlainPortalOnboardingFlow extends React.Component<PortalOnboardingFlowProp
|
|||||||
const ethTokenState = this.props.trackedTokenStateByAddress[ethToken.address];
|
const ethTokenState = this.props.trackedTokenStateByAddress[ethToken.address];
|
||||||
return ethTokenState.balance;
|
return ethTokenState.balance;
|
||||||
}
|
}
|
||||||
private _getFormattedWethBalance(): string {
|
|
||||||
const ethToken = utils.getEthToken(this.props.tokenByAddress);
|
|
||||||
const ethTokenState = this.props.trackedTokenStateByAddress[ethToken.address];
|
|
||||||
return utils.getFormattedAmountFromToken(ethToken, ethTokenState);
|
|
||||||
}
|
|
||||||
private _userHasVisibleWeth(): boolean {
|
private _userHasVisibleWeth(): boolean {
|
||||||
return this._getWethBalance() > new BigNumber(0);
|
return this._getWethBalance() > new BigNumber(0);
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,8 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import { Container } from 'ts/components/ui/container';
|
import { Image } from 'ts/components/ui/image';
|
||||||
import { Text } from 'ts/components/ui/text';
|
|
||||||
|
|
||||||
export interface UnlockWalletOnboardingStepProps {}
|
export interface UnlockWalletOnboardingStepProps {}
|
||||||
|
|
||||||
export const UnlockWalletOnboardingStep: React.StatelessComponent<UnlockWalletOnboardingStepProps> = () => (
|
export const UnlockWalletOnboardingStep: React.StatelessComponent<UnlockWalletOnboardingStepProps> = () => (
|
||||||
<div className="flex items-center flex-column">
|
<Image src="/images/unlock-mm.png" />
|
||||||
<div className="flex items-center flex-column">
|
|
||||||
<Container marginTop="15px" marginBottom="15px">
|
|
||||||
<img src="/images/metamask_icon.png" height="50px" width="50px" />
|
|
||||||
</Container>
|
|
||||||
<Text center={true}>Unlock your MetaMask extension to get started.</Text>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
);
|
||||||
|
@ -1,8 +1,11 @@
|
|||||||
import { colors } from '@0xproject/react-shared';
|
import { colors } from '@0xproject/react-shared';
|
||||||
|
import { BigNumber } from '@0xproject/utils';
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import { Balance } from 'ts/components/ui/balance';
|
||||||
import { Container } from 'ts/components/ui/container';
|
import { Container } from 'ts/components/ui/container';
|
||||||
import { IconButton } from 'ts/components/ui/icon_button';
|
import { IconButton } from 'ts/components/ui/icon_button';
|
||||||
import { Text } from 'ts/components/ui/text';
|
import { Text } from 'ts/components/ui/text';
|
||||||
|
import { constants } from 'ts/utils/constants';
|
||||||
|
|
||||||
export interface WrapEthOnboardingStep1Props {}
|
export interface WrapEthOnboardingStep1Props {}
|
||||||
|
|
||||||
@ -51,16 +54,20 @@ export const WrapEthOnboardingStep2: React.StatelessComponent<WrapEthOnboardingS
|
|||||||
);
|
);
|
||||||
|
|
||||||
export interface WrapEthOnboardingStep3Props {
|
export interface WrapEthOnboardingStep3Props {
|
||||||
formattedWethBalanceIfExists?: string;
|
wethAmount: BigNumber;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const WrapEthOnboardingStep3: React.StatelessComponent<WrapEthOnboardingStep3Props> = ({
|
export const WrapEthOnboardingStep3: React.StatelessComponent<WrapEthOnboardingStep3Props> = ({ wethAmount }) => (
|
||||||
formattedWethBalanceIfExists,
|
|
||||||
}) => (
|
|
||||||
<div className="flex items-center flex-column">
|
<div className="flex items-center flex-column">
|
||||||
<Text>
|
<Text>
|
||||||
You have <b>{formattedWethBalanceIfExists || '0 WETH'}</b> in your wallet.
|
You have{' '}
|
||||||
{formattedWethBalanceIfExists && ' Great!'}
|
<Balance
|
||||||
|
amount={wethAmount}
|
||||||
|
decimals={constants.DECIMAL_PLACES_ETH}
|
||||||
|
symbol={constants.ETHER_TOKEN_SYMBOL}
|
||||||
|
/>{' '}
|
||||||
|
in your wallet.
|
||||||
|
{wethAmount.gt(0) && ' Great!'}
|
||||||
</Text>
|
</Text>
|
||||||
<Container width="100%" marginTop="25px" marginBottom="15px" className="flex justify-center">
|
<Container width="100%" marginTop="25px" marginBottom="15px" className="flex justify-center">
|
||||||
<div className="flex flex-column items-center">
|
<div className="flex flex-column items-center">
|
||||||
|
27
packages/website/ts/components/ui/balance.tsx
Normal file
27
packages/website/ts/components/ui/balance.tsx
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
import { BigNumber } from '@0xproject/utils';
|
||||||
|
import * as React from 'react';
|
||||||
|
import { Container } from 'ts/components/ui/container';
|
||||||
|
import { Text } from 'ts/components/ui/text';
|
||||||
|
import { utils } from 'ts/utils/utils';
|
||||||
|
|
||||||
|
export interface BalanceProps {
|
||||||
|
amount: BigNumber;
|
||||||
|
decimals: number;
|
||||||
|
symbol: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const Balance: React.StatelessComponent<BalanceProps> = ({ amount, decimals, symbol }) => {
|
||||||
|
const formattedAmout = utils.getFormattedAmount(amount, decimals);
|
||||||
|
return (
|
||||||
|
<span>
|
||||||
|
<Text Tag="span" fontSize="16px" fontWeight="700" lineHeight="1em">
|
||||||
|
{formattedAmout}
|
||||||
|
</Text>
|
||||||
|
<Container marginLeft="0.3em" Tag="span">
|
||||||
|
<Text Tag="span" fontSize="12px" fontWeight="700" lineHeight="1em">
|
||||||
|
{symbol}
|
||||||
|
</Text>
|
||||||
|
</Container>
|
||||||
|
</span>
|
||||||
|
);
|
||||||
|
};
|
@ -2,6 +2,8 @@ import * as React from 'react';
|
|||||||
|
|
||||||
type StringOrNum = string | number;
|
type StringOrNum = string | number;
|
||||||
|
|
||||||
|
export type ContainerTag = 'div' | 'span';
|
||||||
|
|
||||||
export interface ContainerProps {
|
export interface ContainerProps {
|
||||||
marginTop?: StringOrNum;
|
marginTop?: StringOrNum;
|
||||||
marginBottom?: StringOrNum;
|
marginBottom?: StringOrNum;
|
||||||
@ -28,15 +30,21 @@ export interface ContainerProps {
|
|||||||
right?: string;
|
right?: string;
|
||||||
bottom?: string;
|
bottom?: string;
|
||||||
zIndex?: number;
|
zIndex?: number;
|
||||||
|
Tag?: ContainerTag;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const Container: React.StatelessComponent<ContainerProps> = ({ children, className, isHidden, ...style }) => {
|
export const Container: React.StatelessComponent<ContainerProps> = props => {
|
||||||
|
const { children, className, Tag, isHidden, ...style } = props;
|
||||||
const visibility = isHidden ? 'hidden' : undefined;
|
const visibility = isHidden ? 'hidden' : undefined;
|
||||||
return (
|
return (
|
||||||
<div style={{ ...style, visibility }} className={className}>
|
<Tag style={{ ...style, visibility }} className={className}>
|
||||||
{children}
|
{children}
|
||||||
</div>
|
</Tag>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Container.defaultProps = {
|
||||||
|
Tag: 'div',
|
||||||
|
};
|
||||||
|
|
||||||
Container.displayName = 'Container';
|
Container.displayName = 'Container';
|
||||||
|
@ -8,6 +8,7 @@ import firstBy = require('thenby');
|
|||||||
|
|
||||||
import { Blockchain } from 'ts/blockchain';
|
import { Blockchain } from 'ts/blockchain';
|
||||||
import { AccountConnection } from 'ts/components/ui/account_connection';
|
import { AccountConnection } from 'ts/components/ui/account_connection';
|
||||||
|
import { Balance } from 'ts/components/ui/balance';
|
||||||
import { Container } from 'ts/components/ui/container';
|
import { Container } from 'ts/components/ui/container';
|
||||||
import { DropDown, DropdownMouseEvent } from 'ts/components/ui/drop_down';
|
import { DropDown, DropdownMouseEvent } from 'ts/components/ui/drop_down';
|
||||||
import { IconButton } from 'ts/components/ui/icon_button';
|
import { IconButton } from 'ts/components/ui/icon_button';
|
||||||
@ -269,7 +270,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
|
|||||||
position: 'relative',
|
position: 'relative',
|
||||||
overflowY: this.state.isHoveringSidebar ? 'scroll' : 'hidden',
|
overflowY: this.state.isHoveringSidebar ? 'scroll' : 'hidden',
|
||||||
marginRight: this.state.isHoveringSidebar ? 0 : 4,
|
marginRight: this.state.isHoveringSidebar ? 0 : 4,
|
||||||
// TODO: make this completely responsive
|
minHeight: '250px',
|
||||||
maxHeight: !utils.isMobileWidth(this.props.screenWidth) ? 'calc(90vh - 300px)' : undefined,
|
maxHeight: !utils.isMobileWidth(this.props.screenWidth) ? 'calc(90vh - 300px)' : undefined,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -436,12 +437,7 @@ export class Wallet extends React.Component<WalletProps, WalletState> {
|
|||||||
</PlaceHolder>
|
</PlaceHolder>
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
const result = utils.getFormattedAmount(amount, decimals, symbol);
|
return <Balance amount={amount} decimals={decimals} symbol={symbol} />;
|
||||||
return (
|
|
||||||
<Text fontSize="16px" fontWeight="bold" lineHeight="1em">
|
|
||||||
{result}
|
|
||||||
</Text>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
private _renderValue(
|
private _renderValue(
|
||||||
|
@ -381,9 +381,9 @@ export const utils = {
|
|||||||
return trackedTokens;
|
return trackedTokens;
|
||||||
},
|
},
|
||||||
getFormattedAmountFromToken(token: Token, tokenState: TokenState): string {
|
getFormattedAmountFromToken(token: Token, tokenState: TokenState): string {
|
||||||
return utils.getFormattedAmount(tokenState.balance, token.decimals, token.symbol);
|
return utils.getFormattedAmount(tokenState.balance, token.decimals);
|
||||||
},
|
},
|
||||||
getFormattedAmount(amount: BigNumber, decimals: number, symbol: string): string {
|
getFormattedAmount(amount: BigNumber, decimals: number): string {
|
||||||
const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals);
|
const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals);
|
||||||
// if the unit amount is less than 1, show the natural number of decimal places with a max of 4
|
// if the unit amount is less than 1, show the natural number of decimal places with a max of 4
|
||||||
// if the unit amount is greater than or equal to 1, show only 2 decimal places
|
// if the unit amount is greater than or equal to 1, show only 2 decimal places
|
||||||
@ -392,7 +392,7 @@ export const utils = {
|
|||||||
: 2;
|
: 2;
|
||||||
const format = `0,0.${_.repeat('0', precision)}`;
|
const format = `0,0.${_.repeat('0', precision)}`;
|
||||||
const formattedAmount = numeral(unitAmount).format(format);
|
const formattedAmount = numeral(unitAmount).format(format);
|
||||||
return `${formattedAmount} ${symbol}`;
|
return formattedAmount;
|
||||||
},
|
},
|
||||||
getUsdValueFormattedAmount(amount: BigNumber, decimals: number, price: BigNumber): string {
|
getUsdValueFormattedAmount(amount: BigNumber, decimals: number, price: BigNumber): string {
|
||||||
const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals);
|
const unitAmount = Web3Wrapper.toUnitAmount(amount, decimals);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user