aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'packages/instant/src/components')
-rw-r--r--packages/instant/src/components/amount_placeholder.tsx34
-rw-r--r--packages/instant/src/components/animations/full_rotation.tsx21
-rw-r--r--packages/instant/src/components/animations/position_animation.tsx107
-rw-r--r--packages/instant/src/components/animations/pulse.tsx15
-rw-r--r--packages/instant/src/components/animations/slide_animation.tsx34
-rw-r--r--packages/instant/src/components/buy_button.tsx120
-rw-r--r--packages/instant/src/components/buy_order_progress.tsx35
-rw-r--r--packages/instant/src/components/buy_order_state_buttons.tsx75
-rw-r--r--packages/instant/src/components/coinbase_wallet_logo.tsx23
-rw-r--r--packages/instant/src/components/css_reset.tsx32
-rw-r--r--packages/instant/src/components/erc20_asset_amount_input.tsx166
-rw-r--r--packages/instant/src/components/erc20_token_selector.tsx176
-rw-r--r--packages/instant/src/components/install_wallet_panel_content.tsx75
-rw-r--r--packages/instant/src/components/instant_heading.tsx149
-rw-r--r--packages/instant/src/components/meta_mask_logo.tsx80
-rw-r--r--packages/instant/src/components/order_details.tsx230
-rw-r--r--packages/instant/src/components/payment_method.tsx110
-rw-r--r--packages/instant/src/components/payment_method_dropdown.tsx60
-rw-r--r--packages/instant/src/components/placing_order_button.tsx18
-rw-r--r--packages/instant/src/components/scaling_amount_input.tsx92
-rw-r--r--packages/instant/src/components/scaling_input.tsx165
-rw-r--r--packages/instant/src/components/search_input.tsx29
-rw-r--r--packages/instant/src/components/secondary_button.tsx27
-rw-r--r--packages/instant/src/components/section_header.tsx21
-rw-r--r--packages/instant/src/components/sliding_error.tsx100
-rw-r--r--packages/instant/src/components/sliding_panel.tsx73
-rw-r--r--packages/instant/src/components/standard_panel_content.tsx75
-rw-r--r--packages/instant/src/components/standard_sliding_panel.tsx29
-rw-r--r--packages/instant/src/components/time_counter.tsx78
-rw-r--r--packages/instant/src/components/timed_progress_bar.tsx106
-rw-r--r--packages/instant/src/components/ui/button.tsx87
-rw-r--r--packages/instant/src/components/ui/circle.tsx26
-rw-r--r--packages/instant/src/components/ui/container.tsx104
-rw-r--r--packages/instant/src/components/ui/dropdown.tsx147
-rw-r--r--packages/instant/src/components/ui/flex.tsx38
-rw-r--r--packages/instant/src/components/ui/icon.tsx129
-rw-r--r--packages/instant/src/components/ui/input.tsx46
-rw-r--r--packages/instant/src/components/ui/overlay.tsx36
-rw-r--r--packages/instant/src/components/ui/spinner.tsx30
-rw-r--r--packages/instant/src/components/ui/text.tsx71
-rw-r--r--packages/instant/src/components/wallet_prompt.tsx49
-rw-r--r--packages/instant/src/components/zero_ex_instant.tsx21
-rw-r--r--packages/instant/src/components/zero_ex_instant_container.tsx112
-rw-r--r--packages/instant/src/components/zero_ex_instant_overlay.tsx53
-rw-r--r--packages/instant/src/components/zero_ex_instant_provider.tsx156
45 files changed, 0 insertions, 3460 deletions
diff --git a/packages/instant/src/components/amount_placeholder.tsx b/packages/instant/src/components/amount_placeholder.tsx
deleted file mode 100644
index 290e34a07..000000000
--- a/packages/instant/src/components/amount_placeholder.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-
-import { Pulse } from './animations/pulse';
-
-import { Text } from './ui/text';
-
-interface PlainPlaceholder {
- color: ColorOption;
-}
-const PlainPlaceholder: React.StatelessComponent<PlainPlaceholder> = props => (
- <Text fontWeight="bold" fontColor={props.color}>
- &mdash;
- </Text>
-);
-
-export interface AmountPlaceholderProps {
- color: ColorOption;
- isPulsating: boolean;
-}
-export const AmountPlaceholder: React.StatelessComponent<AmountPlaceholderProps> = props => {
- if (props.isPulsating) {
- return (
- <Pulse>
- <PlainPlaceholder color={props.color} />
- </Pulse>
- );
- } else {
- return <PlainPlaceholder color={props.color} />;
- }
-};
-
-AmountPlaceholder.displayName = 'AmountPlaceholder';
diff --git a/packages/instant/src/components/animations/full_rotation.tsx b/packages/instant/src/components/animations/full_rotation.tsx
deleted file mode 100644
index 1dff1b1fc..000000000
--- a/packages/instant/src/components/animations/full_rotation.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { keyframes, styled } from '../../style/theme';
-
-interface FullRotationProps {
- height: string;
- width: string;
-}
-const rotatingKeyframes = keyframes`
-from {
- transform: rotate(0deg);
-}
-
-to {
- transform: rotate(360deg);
-}
-`;
-
-export const FullRotation = styled.div<FullRotationProps>`
- animation: ${rotatingKeyframes} 2s linear infinite;
- height: ${props => props.height};
- width: ${props => props.width};
-`;
diff --git a/packages/instant/src/components/animations/position_animation.tsx b/packages/instant/src/components/animations/position_animation.tsx
deleted file mode 100644
index 4f8f25679..000000000
--- a/packages/instant/src/components/animations/position_animation.tsx
+++ /dev/null
@@ -1,107 +0,0 @@
-import { InterpolationValue } from 'styled-components';
-
-import { media, OptionallyScreenSpecific, stylesForMedia } from '../../style/media';
-import { css, keyframes, styled } from '../../style/theme';
-
-export interface TransitionInfo {
- from: string;
- to: string;
-}
-
-const generateTransitionInfoCss = (
- key: keyof TransitionInfo,
- top?: TransitionInfo,
- bottom?: TransitionInfo,
- left?: TransitionInfo,
- right?: TransitionInfo,
-): string => {
- const topStringIfExists = top ? `top: ${top[key]};` : '';
- const bottomStringIfExists = bottom ? `bottom: ${bottom[key]};` : '';
- const leftStringIfExists = left ? `left: ${left[key]};` : '';
- const rightStringIfExists = right ? `right: ${right[key]};` : '';
- return `
- ${topStringIfExists}
- ${bottomStringIfExists}
- ${leftStringIfExists}
- ${rightStringIfExists}
- `;
-};
-
-const slideKeyframeGenerator = (
- position: string,
- top?: TransitionInfo,
- bottom?: TransitionInfo,
- left?: TransitionInfo,
- right?: TransitionInfo,
-) => keyframes`
- from {
- position: ${position};
- ${generateTransitionInfoCss('from', top, bottom, left, right)}
- }
-
- to {
- position: ${position};
- ${generateTransitionInfoCss('to', top, bottom, left, right)}
- }
-`;
-
-export interface PositionAnimationSettings {
- top?: TransitionInfo;
- bottom?: TransitionInfo;
- left?: TransitionInfo;
- right?: TransitionInfo;
- timingFunction: string;
- duration?: string;
- position?: string;
-}
-
-const generatePositionAnimationCss = (positionSettings: PositionAnimationSettings) => {
- return css`
- animation-name: ${slideKeyframeGenerator(
- positionSettings.position || 'relative',
- positionSettings.top,
- positionSettings.bottom,
- positionSettings.left,
- positionSettings.right,
- )};
- animation-duration: ${positionSettings.duration || '0.3s'};
- animation-timing-function: ${positionSettings.timingFunction};
- animation-delay: 0s;
- animation-iteration-count: 1;
- animation-fill-mode: forwards;
- position: ${positionSettings.position || 'relative'};
- width: 100%;
- `;
-};
-
-export interface PositionAnimationProps {
- positionSettings: OptionallyScreenSpecific<PositionAnimationSettings>;
- zIndex?: OptionallyScreenSpecific<number>;
- height?: string;
-}
-
-const defaultAnimation = (positionSettings: OptionallyScreenSpecific<PositionAnimationSettings>) => {
- const bestDefault = 'default' in positionSettings ? positionSettings.default : positionSettings;
- return generatePositionAnimationCss(bestDefault);
-};
-const animationForSize = (
- positionSettings: OptionallyScreenSpecific<PositionAnimationSettings>,
- sizeKey: 'sm' | 'md' | 'lg',
- mediaFn: (...args: any[]) => InterpolationValue[],
-) => {
- // checking default makes sure we have a PositionAnimationSettings object
- // and then we check to see if we have a setting for the specific `sizeKey`
- const animationSettingsForSize = 'default' in positionSettings && positionSettings[sizeKey];
- return animationSettingsForSize && mediaFn`${generatePositionAnimationCss(animationSettingsForSize)}`;
-};
-
-export const PositionAnimation = styled.div<PositionAnimationProps>`
- && {
- ${props => props.zIndex && stylesForMedia<number>('z-index', props.zIndex)}
- ${props => defaultAnimation(props.positionSettings)}
- ${props => animationForSize(props.positionSettings, 'sm', media.small)}
- ${props => animationForSize(props.positionSettings, 'md', media.medium)}
- ${props => animationForSize(props.positionSettings, 'lg', media.large)}
- ${props => (props.height ? `height: ${props.height};` : '')}
- }
-`;
diff --git a/packages/instant/src/components/animations/pulse.tsx b/packages/instant/src/components/animations/pulse.tsx
deleted file mode 100644
index 01d6ea070..000000000
--- a/packages/instant/src/components/animations/pulse.tsx
+++ /dev/null
@@ -1,15 +0,0 @@
-import { keyframes, styled } from '../../style/theme';
-
-const pulsingKeyframes = keyframes`
- 0%, 100% {
- opacity: 0.2;
- }
- 50% {
- opacity: 100;
- }
-`;
-export const Pulse = styled.div`
- animation-name: ${pulsingKeyframes}
- animation-duration: 2s;
- animation-iteration-count: infinite;
-`;
diff --git a/packages/instant/src/components/animations/slide_animation.tsx b/packages/instant/src/components/animations/slide_animation.tsx
deleted file mode 100644
index 6ac47e9a6..000000000
--- a/packages/instant/src/components/animations/slide_animation.tsx
+++ /dev/null
@@ -1,34 +0,0 @@
-import * as React from 'react';
-
-import { OptionallyScreenSpecific } from '../../style/media';
-import { SlideAnimationState } from '../../types';
-
-import { PositionAnimation, PositionAnimationSettings } from './position_animation';
-
-export interface SlideAnimationProps {
- animationState: SlideAnimationState;
- slideInSettings: OptionallyScreenSpecific<PositionAnimationSettings>;
- slideOutSettings: OptionallyScreenSpecific<PositionAnimationSettings>;
- zIndex?: OptionallyScreenSpecific<number>;
- height?: string;
- onAnimationEnd?: () => void;
-}
-
-export const SlideAnimation: React.StatelessComponent<SlideAnimationProps> = props => {
- if (props.animationState === 'none') {
- return <React.Fragment>{props.children}</React.Fragment>;
- }
- const positionSettings = props.animationState === 'slidIn' ? props.slideInSettings : props.slideOutSettings;
- return (
- <PositionAnimation
- onAnimationEnd={props.onAnimationEnd}
- height={props.height}
- positionSettings={positionSettings}
- zIndex={props.zIndex}
- >
- {props.children}
- </PositionAnimation>
- );
-};
-
-SlideAnimation.displayName = 'SlideAnimation';
diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx
deleted file mode 100644
index 551e857a5..000000000
--- a/packages/instant/src/components/buy_button.tsx
+++ /dev/null
@@ -1,120 +0,0 @@
-import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer';
-import { AssetProxyId } from '@0x/types';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import * as _ from 'lodash';
-import * as React from 'react';
-import { oc } from 'ts-optchain';
-
-import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants';
-import { ColorOption } from '../style/theme';
-import { AffiliateInfo, Asset, ZeroExInstantError } from '../types';
-import { analytics } from '../util/analytics';
-import { errorReporter } from '../util/error_reporter';
-import { gasPriceEstimator } from '../util/gas_price_estimator';
-import { util } from '../util/util';
-
-import { Button } from './ui/button';
-
-export interface BuyButtonProps {
- accountAddress?: string;
- accountEthBalanceInWei?: BigNumber;
- buyQuote?: BuyQuote;
- assetBuyer: AssetBuyer;
- web3Wrapper: Web3Wrapper;
- affiliateInfo?: AffiliateInfo;
- selectedAsset?: Asset;
- onValidationPending: (buyQuote: BuyQuote) => void;
- onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void;
- onSignatureDenied: (buyQuote: BuyQuote) => void;
- onBuyProcessing: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void;
- onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void;
- onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void;
-}
-
-export class BuyButton extends React.PureComponent<BuyButtonProps> {
- public static defaultProps = {
- onClick: util.boundNoop,
- onBuySuccess: util.boundNoop,
- onBuyFailure: util.boundNoop,
- };
- public render(): React.ReactNode {
- const { buyQuote, accountAddress, selectedAsset } = this.props;
- const shouldDisableButton = _.isUndefined(buyQuote) || _.isUndefined(accountAddress);
- const buttonText =
- !_.isUndefined(selectedAsset) && selectedAsset.metaData.assetProxyId === AssetProxyId.ERC20
- ? `Buy ${selectedAsset.metaData.symbol.toUpperCase()}`
- : 'Buy Now';
- return (
- <Button
- width="100%"
- onClick={this._handleClick}
- isDisabled={shouldDisableButton}
- fontColor={ColorOption.white}
- >
- {buttonText}
- </Button>
- );
- }
- private readonly _handleClick = async () => {
- // The button is disabled when there is no buy quote anyway.
- const { buyQuote, assetBuyer, affiliateInfo, accountAddress, accountEthBalanceInWei, web3Wrapper } = this.props;
- if (_.isUndefined(buyQuote) || _.isUndefined(accountAddress)) {
- return;
- }
- this.props.onValidationPending(buyQuote);
- const ethNeededForBuy = buyQuote.worstCaseQuoteInfo.totalEthAmount;
- // if we don't have a balance for the user, let the transaction through, it will be handled by the wallet
- const hasSufficientEth = _.isUndefined(accountEthBalanceInWei) || accountEthBalanceInWei.gte(ethNeededForBuy);
- if (!hasSufficientEth) {
- analytics.trackBuyNotEnoughEth(buyQuote);
- this.props.onValidationFail(buyQuote, ZeroExInstantError.InsufficientETH);
- return;
- }
- let txHash: string | undefined;
- const gasInfo = await gasPriceEstimator.getGasInfoAsync();
- const feeRecipient = oc(affiliateInfo).feeRecipient();
- try {
- analytics.trackBuyStarted(buyQuote);
- txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, {
- feeRecipient,
- takerAddress: accountAddress,
- gasPrice: gasInfo.gasPriceInWei,
- });
- } catch (e) {
- if (e instanceof Error) {
- if (e.message === AssetBuyerError.TransactionValueTooLow) {
- analytics.trackBuySimulationFailed(buyQuote);
- this.props.onValidationFail(buyQuote, AssetBuyerError.TransactionValueTooLow);
- return;
- } else if (e.message === AssetBuyerError.SignatureRequestDenied) {
- analytics.trackBuySignatureDenied(buyQuote);
- this.props.onSignatureDenied(buyQuote);
- return;
- } else {
- errorReporter.report(e);
- analytics.trackBuyUnknownError(buyQuote, e.message);
- this.props.onValidationFail(buyQuote, ZeroExInstantError.CouldNotSubmitTransaction);
- return;
- }
- }
- throw e;
- }
- const startTimeUnix = new Date().getTime();
- const expectedEndTimeUnix = startTimeUnix + gasInfo.estimatedTimeMs;
- this.props.onBuyProcessing(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix);
- try {
- analytics.trackBuyTxSubmitted(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix);
- await web3Wrapper.awaitTransactionSuccessAsync(txHash);
- } catch (e) {
- if (e instanceof Error && e.message.startsWith(WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX)) {
- analytics.trackBuyTxFailed(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix);
- this.props.onBuyFailure(buyQuote, txHash);
- return;
- }
- throw e;
- }
- analytics.trackBuyTxSucceeded(buyQuote, txHash, startTimeUnix, expectedEndTimeUnix);
- this.props.onBuySuccess(buyQuote, txHash);
- };
-}
diff --git a/packages/instant/src/components/buy_order_progress.tsx b/packages/instant/src/components/buy_order_progress.tsx
deleted file mode 100644
index 11ac5d5e0..000000000
--- a/packages/instant/src/components/buy_order_progress.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import * as React from 'react';
-
-import { TimedProgressBar } from '../components/timed_progress_bar';
-
-import { TimeCounter } from '../components/time_counter';
-import { Container } from '../components/ui/container';
-import { OrderProcessState, OrderState } from '../types';
-
-export interface BuyOrderProgressProps {
- buyOrderState: OrderState;
-}
-
-export const BuyOrderProgress: React.StatelessComponent<BuyOrderProgressProps> = props => {
- const { buyOrderState } = props;
- if (
- buyOrderState.processState === OrderProcessState.Processing ||
- buyOrderState.processState === OrderProcessState.Success ||
- buyOrderState.processState === OrderProcessState.Failure
- ) {
- const progress = buyOrderState.progress;
- const hasEnded = buyOrderState.processState !== OrderProcessState.Processing;
- const expectedTimeMs = progress.expectedEndTimeUnix - progress.startTimeUnix;
- return (
- <Container width="100%" padding="20px 20px 0px 20px">
- <Container marginBottom="5px">
- <TimeCounter estimatedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} />
- </Container>
- <TimedProgressBar expectedTimeMs={expectedTimeMs} hasEnded={hasEnded} key={progress.startTimeUnix} />
- </Container>
- );
- }
- return null;
-};
-
-BuyOrderProgress.displayName = 'BuyOrderProgress';
diff --git a/packages/instant/src/components/buy_order_state_buttons.tsx b/packages/instant/src/components/buy_order_state_buttons.tsx
deleted file mode 100644
index 1214559d1..000000000
--- a/packages/instant/src/components/buy_order_state_buttons.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer';
-import { BigNumber } from '@0x/utils';
-import { Web3Wrapper } from '@0x/web3-wrapper';
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-import { AffiliateInfo, Asset, OrderProcessState, ZeroExInstantError } from '../types';
-
-import { BuyButton } from './buy_button';
-import { PlacingOrderButton } from './placing_order_button';
-import { SecondaryButton } from './secondary_button';
-
-import { Button } from './ui/button';
-import { Flex } from './ui/flex';
-
-export interface BuyOrderStateButtonProps {
- accountAddress?: string;
- accountEthBalanceInWei?: BigNumber;
- buyQuote?: BuyQuote;
- buyOrderProcessingState: OrderProcessState;
- assetBuyer: AssetBuyer;
- web3Wrapper: Web3Wrapper;
- affiliateInfo?: AffiliateInfo;
- selectedAsset?: Asset;
- onViewTransaction: () => void;
- onValidationPending: (buyQuote: BuyQuote) => void;
- onValidationFail: (buyQuote: BuyQuote, errorMessage: AssetBuyerError | ZeroExInstantError) => void;
- onSignatureDenied: (buyQuote: BuyQuote) => void;
- onBuyProcessing: (buyQuote: BuyQuote, txHash: string, startTimeUnix: number, expectedEndTimeUnix: number) => void;
- onBuySuccess: (buyQuote: BuyQuote, txHash: string) => void;
- onBuyFailure: (buyQuote: BuyQuote, txHash: string) => void;
- onRetry: () => void;
-}
-
-export const BuyOrderStateButtons: React.StatelessComponent<BuyOrderStateButtonProps> = props => {
- if (props.buyOrderProcessingState === OrderProcessState.Failure) {
- return (
- <Flex justify="space-between">
- <Button width="48%" onClick={props.onRetry} fontColor={ColorOption.white}>
- Back
- </Button>
- <SecondaryButton width="48%" onClick={props.onViewTransaction}>
- Details
- </SecondaryButton>
- </Flex>
- );
- } else if (
- props.buyOrderProcessingState === OrderProcessState.Success ||
- props.buyOrderProcessingState === OrderProcessState.Processing
- ) {
- return <SecondaryButton onClick={props.onViewTransaction}>View Transaction</SecondaryButton>;
- } else if (props.buyOrderProcessingState === OrderProcessState.Validating) {
- return <PlacingOrderButton />;
- }
-
- return (
- <BuyButton
- accountAddress={props.accountAddress}
- accountEthBalanceInWei={props.accountEthBalanceInWei}
- buyQuote={props.buyQuote}
- assetBuyer={props.assetBuyer}
- web3Wrapper={props.web3Wrapper}
- affiliateInfo={props.affiliateInfo}
- selectedAsset={props.selectedAsset}
- onValidationPending={props.onValidationPending}
- onValidationFail={props.onValidationFail}
- onSignatureDenied={props.onSignatureDenied}
- onBuyProcessing={props.onBuyProcessing}
- onBuySuccess={props.onBuySuccess}
- onBuyFailure={props.onBuyFailure}
- />
- );
-};
-
-BuyOrderStateButtons.displayName = 'BuyOrderStateButtons';
diff --git a/packages/instant/src/components/coinbase_wallet_logo.tsx b/packages/instant/src/components/coinbase_wallet_logo.tsx
deleted file mode 100644
index 845b96d73..000000000
--- a/packages/instant/src/components/coinbase_wallet_logo.tsx
+++ /dev/null
@@ -1,23 +0,0 @@
-import * as React from 'react';
-
-export interface CoinbaseWalletLogoProps {
- width?: number;
-}
-
-export const CoinbaseWalletLogo: React.StatelessComponent<CoinbaseWalletLogoProps> = ({ width }) => (
- <svg width={width} viewBox="0 0 51 51" fill="none" xmlns="http://www.w3.org/2000/svg">
- <circle cx="25.5" cy="25.5" r="25.5" fill="#3263E9" />
- <path
- fillRule="evenodd"
- clipRule="evenodd"
- d="M25.5 41C34.0604 41 41 34.0604 41 25.5C41 16.9396 34.0604 10 25.5 10C16.9396 10 10 16.9396 10 25.5C10 34.0604 16.9396 41 25.5 41ZM21.5108 20.5107C20.9586 20.5107 20.5108 20.9584 20.5108 21.5107V29.6223C20.5108 30.1746 20.9586 30.6223 21.5108 30.6223H29.6224C30.1747 30.6223 30.6224 30.1746 30.6224 29.6223V21.5107C30.6224 20.9584 30.1747 20.5107 29.6224 20.5107H21.5108Z"
- fill="white"
- />
- </svg>
-);
-
-CoinbaseWalletLogo.displayName = 'CoinbaseWalletLogo';
-
-CoinbaseWalletLogo.defaultProps = {
- width: 164,
-};
diff --git a/packages/instant/src/components/css_reset.tsx b/packages/instant/src/components/css_reset.tsx
deleted file mode 100644
index d1b20f4c9..000000000
--- a/packages/instant/src/components/css_reset.tsx
+++ /dev/null
@@ -1,32 +0,0 @@
-import { INJECTED_DIV_CLASS } from '../constants';
-import { createGlobalStyle } from '../style/theme';
-
-export interface CSSResetProps {}
-
-/*
- * Derived from
- * https://github.com/jtrost/Complete-CSS-Reset
- */
-export const CSSReset = createGlobalStyle`
- .${INJECTED_DIV_CLASS} {
- a, abbr, area, article, aside, audio, b, bdo, blockquote, body, button,
- canvas, caption, cite, code, col, colgroup, command, datalist, dd, del,
- details, dialog, dfn, div, dl, dt, em, embed, fieldset, figure, form,
- h1, h2, h3, h4, h5, h6, head, header, hgroup, hr, html, i, iframe, img,
- input, ins, keygen, kbd, label, legend, li, map, mark, menu, meter, nav,
- noscript, object, ol, optgroup, option, output, p, param, pre, progress,
- q, rp, rt, ruby, samp, section, select, small, span, strong, sub, sup,
- table, tbody, td, textarea, tfoot, th, thead, time, tr, ul, var, video {
- background: transparent;
- border: 0;
- font-size: 100%;
- font: inherit;
- margin: 0;
- outline: none;
- padding: 0;
- text-align: left;
- text-decoration: none;
- vertical-align: baseline;
- }
- }
-`;
diff --git a/packages/instant/src/components/erc20_asset_amount_input.tsx b/packages/instant/src/components/erc20_asset_amount_input.tsx
deleted file mode 100644
index 0418f9165..000000000
--- a/packages/instant/src/components/erc20_asset_amount_input.tsx
+++ /dev/null
@@ -1,166 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { ColorOption, transparentWhite } from '../style/theme';
-import { ERC20Asset, SimpleHandler } from '../types';
-import { assetUtils } from '../util/asset';
-import { util } from '../util/util';
-
-import { ScalingAmountInput } from './scaling_amount_input';
-
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Icon } from './ui/icon';
-import { Text } from './ui/text';
-
-// Asset amounts only apply to ERC20 assets
-export interface ERC20AssetAmountInputProps {
- asset?: ERC20Asset;
- value?: BigNumber;
- onChange: (value?: BigNumber, asset?: ERC20Asset) => void;
- onSelectAssetClick?: (asset?: ERC20Asset) => void;
- startingFontSizePx: number;
- fontColor?: ColorOption;
- isInputDisabled: boolean;
- canSelectOtherAsset: boolean;
- numberOfAssetsAvailable?: number;
-}
-
-export interface ERC20AssetAmountInputState {
- currentFontSizePx: number;
-}
-
-export class ERC20AssetAmountInput extends React.PureComponent<ERC20AssetAmountInputProps, ERC20AssetAmountInputState> {
- public static defaultProps = {
- onChange: util.boundNoop,
- isDisabled: false,
- };
- constructor(props: ERC20AssetAmountInputProps) {
- super(props);
- this.state = {
- currentFontSizePx: props.startingFontSizePx,
- };
- }
- public render(): React.ReactNode {
- const { asset } = this.props;
- return (
- <Container whiteSpace="nowrap">
- {_.isUndefined(asset) ? this._renderTokenSelectionContent() : this._renderContentForAsset(asset)}
- </Container>
- );
- }
- private readonly _renderContentForAsset = (asset: ERC20Asset): React.ReactNode => {
- const { onChange, isInputDisabled, ...rest } = this.props;
- const amountBorderBottom = isInputDisabled ? '' : `1px solid ${transparentWhite}`;
- const onSymbolClick = this._generateSelectAssetClickHandler();
- return (
- <React.Fragment>
- <Container borderBottom={amountBorderBottom} display="inline-block">
- <ScalingAmountInput
- {...rest}
- isDisabled={isInputDisabled}
- textLengthThreshold={this._textLengthThresholdForAsset(asset)}
- maxFontSizePx={this.props.startingFontSizePx}
- onAmountChange={this._handleChange}
- onFontSizeChange={this._handleFontSizeChange}
- hasAutofocus={true}
- /* We send in a key of asset data to force a rerender of this component when the user selects a new asset. We do this so the autofocus attribute will bring focus onto this input */
- key={asset.assetData}
- />
- </Container>
- <Container
- display="inline-block"
- marginLeft="8px"
- title={assetUtils.bestNameForAsset(asset, undefined)}
- >
- <Flex inline={true}>
- <Text
- fontSize={`${this.state.currentFontSizePx}px`}
- fontColor={ColorOption.white}
- textTransform="uppercase"
- onClick={this.props.canSelectOtherAsset ? onSymbolClick : undefined}
- >
- {assetUtils.formattedSymbolForAsset(asset)}
- </Text>
- {this.props.canSelectOtherAsset && this._renderChevronIcon()}
- </Flex>
- </Container>
- </React.Fragment>
- );
- };
- private readonly _renderTokenSelectionContent = (): React.ReactNode => {
- const { numberOfAssetsAvailable } = this.props;
- let text = 'Select Token';
- if (_.isUndefined(numberOfAssetsAvailable)) {
- text = 'Loading...';
- } else if (numberOfAssetsAvailable === 0) {
- text = 'Assets Unavailable';
- }
- return (
- <Flex>
- <Text
- fontSize="30px"
- fontColor={ColorOption.white}
- opacity={0.7}
- fontWeight="500"
- onClick={this._generateSelectAssetClickHandler()}
- >
- {text}
- </Text>
- {this._renderChevronIcon()}
- </Flex>
- );
- };
- private readonly _renderChevronIcon = (): React.ReactNode => {
- if (!this._areAnyAssetsAvailable()) {
- return null;
- }
- return (
- <Container marginLeft="5px">
- <Icon icon="chevron" width={12} stroke={ColorOption.white} onClick={this._handleSelectAssetClick} />
- </Container>
- );
- };
- private readonly _handleChange = (value?: BigNumber): void => {
- this.props.onChange(value, this.props.asset);
- };
- private readonly _handleFontSizeChange = (fontSizePx: number): void => {
- this.setState({
- currentFontSizePx: fontSizePx,
- });
- };
- private readonly _generateSelectAssetClickHandler = (): SimpleHandler | undefined => {
- // We don't want to allow opening the token selection panel if there are no assets.
- // Since styles are inferred from the presence of a click handler, we want to return undefined
- // instead of providing a noop.
- if (!this._areAnyAssetsAvailable() || _.isUndefined(this.props.onSelectAssetClick)) {
- return undefined;
- }
- return this._handleSelectAssetClick;
- };
- private readonly _areAnyAssetsAvailable = (): boolean => {
- const { numberOfAssetsAvailable } = this.props;
- return !_.isUndefined(numberOfAssetsAvailable) && numberOfAssetsAvailable > 0;
- };
- private readonly _handleSelectAssetClick = (): void => {
- if (this.props.onSelectAssetClick) {
- this.props.onSelectAssetClick();
- }
- };
- // For assets with symbols of different length,
- // start scaling the input at different character lengths
- private readonly _textLengthThresholdForAsset = (asset?: ERC20Asset): number => {
- if (_.isUndefined(asset)) {
- return 3;
- }
- const symbol = asset.metaData.symbol;
- if (symbol.length <= 3) {
- return 5;
- }
- if (symbol.length === 5) {
- return 3;
- }
- return 4;
- };
-}
diff --git a/packages/instant/src/components/erc20_token_selector.tsx b/packages/instant/src/components/erc20_token_selector.tsx
deleted file mode 100644
index a26fb5cf5..000000000
--- a/packages/instant/src/components/erc20_token_selector.tsx
+++ /dev/null
@@ -1,176 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-import { ERC20Asset } from '../types';
-import { analytics } from '../util/analytics';
-import { assetUtils } from '../util/asset';
-
-import { SearchInput } from './search_input';
-import { Circle } from './ui/circle';
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Text } from './ui/text';
-
-export interface ERC20TokenSelectorProps {
- tokens: ERC20Asset[];
- onTokenSelect: (token: ERC20Asset) => void;
-}
-
-export interface ERC20TokenSelectorState {
- searchQuery: string;
-}
-
-export class ERC20TokenSelector extends React.PureComponent<ERC20TokenSelectorProps> {
- public state: ERC20TokenSelectorState = {
- searchQuery: '',
- };
- public render(): React.ReactNode {
- const { tokens } = this.props;
- return (
- <Container height="100%">
- <Container marginBottom="10px">
- <Text fontColor={ColorOption.darkGrey} fontSize="18px" fontWeight="600" lineHeight="22px">
- Select Token
- </Text>
- </Container>
- <SearchInput
- placeholder="Search tokens..."
- width="100%"
- value={this.state.searchQuery}
- onChange={this._handleSearchInputChange}
- tabIndex={-1}
- />
- <Container overflow="scroll" height="calc(100% - 90px)" marginTop="10px">
- <TokenRowFilter
- tokens={tokens}
- onClick={this._handleTokenClick}
- searchQuery={this.state.searchQuery}
- />
- </Container>
- </Container>
- );
- }
- private readonly _handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
- const searchQuery = event.target.value;
- this.setState({
- searchQuery,
- });
- analytics.trackTokenSelectorSearched(searchQuery);
- };
- private readonly _handleTokenClick = (token: ERC20Asset): void => {
- this.props.onTokenSelect(token);
- };
-}
-
-interface TokenRowFilterProps {
- tokens: ERC20Asset[];
- onClick: (token: ERC20Asset) => void;
- searchQuery: string;
-}
-
-class TokenRowFilter extends React.Component<TokenRowFilterProps> {
- public render(): React.ReactNode {
- return _.map(this.props.tokens, token => {
- if (!this._isTokenQueryMatch(token)) {
- return null;
- }
- return <TokenSelectorRow key={token.assetData} token={token} onClick={this.props.onClick} />;
- });
- }
- public shouldComponentUpdate(nextProps: TokenRowFilterProps): boolean {
- const arePropsDeeplyEqual = _.isEqual(nextProps, this.props);
- return !arePropsDeeplyEqual;
- }
- private readonly _isTokenQueryMatch = (token: ERC20Asset): boolean => {
- const { searchQuery } = this.props;
- const searchQueryLowerCase = searchQuery.toLowerCase().trim();
- if (searchQueryLowerCase === '') {
- return true;
- }
- const tokenName = token.metaData.name.toLowerCase();
- const tokenSymbol = token.metaData.symbol.toLowerCase();
- return _.startsWith(tokenSymbol, searchQueryLowerCase) || _.startsWith(tokenName, searchQueryLowerCase);
- };
-}
-
-interface TokenSelectorRowProps {
- token: ERC20Asset;
- onClick: (token: ERC20Asset) => void;
-}
-
-class TokenSelectorRow extends React.PureComponent<TokenSelectorRowProps> {
- public render(): React.ReactNode {
- const { token } = this.props;
- const circleColor = token.metaData.primaryColor || 'black';
- const displaySymbol = assetUtils.bestNameForAsset(token);
- return (
- <Container
- padding="12px 0px"
- borderBottom="1px solid"
- borderColor={ColorOption.feintGrey}
- backgroundColor={ColorOption.white}
- width="100%"
- onClick={this._handleClick}
- darkenOnHover={true}
- cursor="pointer"
- >
- <Container marginLeft="5px">
- <Flex justify="flex-start">
- <Container marginRight="10px">
- <Circle diameter={26} rawColor={circleColor}>
- <Flex height="100%" width="100%">
- <TokenSelectorRowIcon token={token} />
- </Flex>
- </Circle>
- </Container>
- <Text fontSize="14px" fontWeight={700} fontColor={ColorOption.black}>
- {displaySymbol}
- </Text>
- <Container margin="0px 5px">
- <Text fontSize="14px"> - </Text>
- </Container>
- <Text fontSize="14px">{token.metaData.name}</Text>
- </Flex>
- </Container>
- </Container>
- );
- }
- private readonly _handleClick = (): void => {
- this.props.onClick(this.props.token);
- };
-}
-
-interface TokenSelectorRowIconProps {
- token: ERC20Asset;
-}
-
-const getTokenIcon = (symbol: string): React.StatelessComponent | undefined => {
- try {
- return require(`../assets/icons/${symbol}.svg`) as React.StatelessComponent;
- } catch (e) {
- // Can't find icon
- return undefined;
- }
-};
-
-class TokenSelectorRowIcon extends React.PureComponent<TokenSelectorRowIconProps> {
- public render(): React.ReactNode {
- const { token } = this.props;
- const iconUrlIfExists = token.metaData.iconUrl;
-
- const TokenIcon = getTokenIcon(token.metaData.symbol);
- const displaySymbol = assetUtils.bestNameForAsset(token);
- if (!_.isUndefined(iconUrlIfExists)) {
- return <img src={iconUrlIfExists} />;
- } else if (!_.isUndefined(TokenIcon)) {
- return <TokenIcon />;
- } else {
- return (
- <Text fontColor={ColorOption.white} fontSize="8px">
- {displaySymbol}
- </Text>
- );
- }
- }
-}
diff --git a/packages/instant/src/components/install_wallet_panel_content.tsx b/packages/instant/src/components/install_wallet_panel_content.tsx
deleted file mode 100644
index 1af3dafbb..000000000
--- a/packages/instant/src/components/install_wallet_panel_content.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import * as React from 'react';
-
-import {
- META_MASK_CHROME_STORE_URL,
- META_MASK_FIREFOX_STORE_URL,
- META_MASK_OPERA_STORE_URL,
- META_MASK_SITE_URL,
-} from '../constants';
-import { ColorOption } from '../style/theme';
-import { Browser } from '../types';
-import { analytics } from '../util/analytics';
-import { envUtil } from '../util/env';
-import { util } from '../util/util';
-
-import { MetaMaskLogo } from './meta_mask_logo';
-import { StandardPanelContent, StandardPanelContentProps } from './standard_panel_content';
-import { Button } from './ui/button';
-
-export interface InstallWalletPanelContentProps {}
-
-export class InstallWalletPanelContent extends React.PureComponent<InstallWalletPanelContentProps> {
- public render(): React.ReactNode {
- const panelProps = this._getStandardPanelContentProps();
- return <StandardPanelContent {...panelProps} />;
- }
- private readonly _getStandardPanelContentProps = (): StandardPanelContentProps => {
- const browser = envUtil.getBrowser();
- let description = 'Please install the MetaMask wallet browser extension.';
- let actionText = 'Learn More';
- let actionUrl = META_MASK_SITE_URL;
- switch (browser) {
- case Browser.Chrome:
- description = 'Please install the MetaMask wallet browser extension from the Chrome Store.';
- actionText = 'Get Chrome Extension';
- actionUrl = META_MASK_CHROME_STORE_URL;
- break;
- case Browser.Firefox:
- description = 'Please install the MetaMask wallet browser extension from the Firefox Store.';
- actionText = 'Get Firefox Extension';
- actionUrl = META_MASK_FIREFOX_STORE_URL;
- break;
- case Browser.Opera:
- description = 'Please install the MetaMask wallet browser extension from the Opera Store.';
- actionText = 'Get Opera Add-on';
- actionUrl = META_MASK_OPERA_STORE_URL;
- break;
- default:
- break;
- }
- const onActionClick = () => {
- analytics.trackInstallWalletModalClickedGet();
- util.createOpenUrlInNewWindow(actionUrl)();
- };
- return {
- image: <MetaMaskLogo width={85} height={80} />,
- title: 'Install MetaMask',
- description,
- moreInfoSettings: {
- href: META_MASK_SITE_URL,
- text: 'What is MetaMask?',
- onClick: analytics.trackInstallWalletModalClickedExplanation,
- },
- action: (
- <Button
- onClick={onActionClick}
- width="100%"
- fontColor={ColorOption.white}
- backgroundColor={ColorOption.darkOrange}
- >
- {actionText}
- </Button>
- ),
- };
- };
-}
diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx
deleted file mode 100644
index e943f68d7..000000000
--- a/packages/instant/src/components/instant_heading.tsx
+++ /dev/null
@@ -1,149 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { SelectedERC20AssetAmountInput } from '../containers/selected_erc20_asset_amount_input';
-import { ColorOption } from '../style/theme';
-import { AsyncProcessState, ERC20Asset, OrderProcessState, OrderState } from '../types';
-import { format } from '../util/format';
-
-import { AmountPlaceholder } from './amount_placeholder';
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Icon } from './ui/icon';
-import { Spinner } from './ui/spinner';
-import { Text } from './ui/text';
-
-export interface InstantHeadingProps {
- selectedAssetUnitAmount?: BigNumber;
- totalEthBaseUnitAmount?: BigNumber;
- ethUsdPrice?: BigNumber;
- quoteRequestState: AsyncProcessState;
- buyOrderState: OrderState;
- onSelectAssetClick?: (asset?: ERC20Asset) => void;
-}
-
-const PLACEHOLDER_COLOR = ColorOption.white;
-const ICON_WIDTH = 34;
-const ICON_HEIGHT = 34;
-const ICON_COLOR = ColorOption.white;
-
-export class InstantHeading extends React.PureComponent<InstantHeadingProps, {}> {
- public render(): React.ReactNode {
- const iconOrAmounts = this._renderIcon() || this._renderAmountsSection();
- return (
- <Container backgroundColor={ColorOption.primaryColor} width="100%" padding="20px">
- <Container marginBottom="5px">
- <Text
- letterSpacing="1px"
- fontColor={ColorOption.white}
- opacity={0.7}
- fontWeight={500}
- textTransform="uppercase"
- fontSize="12px"
- >
- {this._renderTopText()}
- </Text>
- </Container>
- <Flex direction="row" justify="space-between">
- <Flex height="60px">
- <SelectedERC20AssetAmountInput
- startingFontSizePx={38}
- onSelectAssetClick={this.props.onSelectAssetClick}
- />
- </Flex>
- <Flex direction="column" justify="space-between">
- {iconOrAmounts}
- </Flex>
- </Flex>
- </Container>
- );
- }
-
- private _renderAmountsSection(): React.ReactNode {
- if (
- _.isUndefined(this.props.totalEthBaseUnitAmount) &&
- this.props.quoteRequestState !== AsyncProcessState.Pending
- ) {
- return null;
- } else {
- return (
- <Container>
- <Container marginBottom="5px">{this._renderPlaceholderOrAmount(this._renderEthAmount)}</Container>
- <Container opacity={0.7}>{this._renderPlaceholderOrAmount(this._renderDollarAmount)}</Container>
- </Container>
- );
- }
- }
-
- private _renderIcon(): React.ReactNode {
- const processState = this.props.buyOrderState.processState;
-
- if (processState === OrderProcessState.Failure) {
- return <Icon icon="failed" width={ICON_WIDTH} height={ICON_HEIGHT} color={ICON_COLOR} />;
- } else if (processState === OrderProcessState.Processing) {
- return <Spinner widthPx={ICON_HEIGHT} heightPx={ICON_HEIGHT} />;
- } else if (processState === OrderProcessState.Success) {
- return <Icon icon="success" width={ICON_WIDTH} height={ICON_HEIGHT} color={ICON_COLOR} />;
- }
- return undefined;
- }
-
- private _renderTopText(): React.ReactNode {
- const processState = this.props.buyOrderState.processState;
- if (processState === OrderProcessState.Failure) {
- return 'Order failed';
- } else if (processState === OrderProcessState.Processing) {
- return 'Processing Order...';
- } else if (processState === OrderProcessState.Success) {
- return 'Tokens received!';
- }
-
- return 'I want to buy';
- }
-
- private _renderPlaceholderOrAmount(amountFunction: () => React.ReactNode): React.ReactNode {
- if (this.props.quoteRequestState === AsyncProcessState.Pending) {
- return <AmountPlaceholder isPulsating={true} color={PLACEHOLDER_COLOR} />;
- }
- if (_.isUndefined(this.props.selectedAssetUnitAmount)) {
- return <AmountPlaceholder isPulsating={false} color={PLACEHOLDER_COLOR} />;
- }
- return amountFunction();
- }
-
- private readonly _renderEthAmount = (): React.ReactNode => {
- const ethAmount = format.ethBaseUnitAmount(
- this.props.totalEthBaseUnitAmount,
- 4,
- <AmountPlaceholder isPulsating={false} color={PLACEHOLDER_COLOR} />,
- );
-
- const fontSize = _.isString(ethAmount) && ethAmount.length >= 13 ? '14px' : '16px';
- return (
- <Text
- fontSize={fontSize}
- textAlign="right"
- width="100%"
- fontColor={ColorOption.white}
- fontWeight={500}
- noWrap={true}
- >
- {ethAmount}
- </Text>
- );
- };
-
- private readonly _renderDollarAmount = (): React.ReactNode => {
- return (
- <Text fontSize="16px" textAlign="right" width="100%" fontColor={ColorOption.white} noWrap={true}>
- {format.ethBaseUnitAmountInUsd(
- this.props.totalEthBaseUnitAmount,
- this.props.ethUsdPrice,
- 2,
- <AmountPlaceholder isPulsating={false} color={ColorOption.white} />,
- )}
- </Text>
- );
- };
-}
diff --git a/packages/instant/src/components/meta_mask_logo.tsx b/packages/instant/src/components/meta_mask_logo.tsx
deleted file mode 100644
index bfbc67270..000000000
--- a/packages/instant/src/components/meta_mask_logo.tsx
+++ /dev/null
@@ -1,80 +0,0 @@
-import * as React from 'react';
-
-export interface MetaMaskLogoProps {
- width?: number;
- height?: number;
-}
-
-export const MetaMaskLogo: React.StatelessComponent<MetaMaskLogoProps> = ({ width, height }) => (
- <svg width={width} height={height} viewBox="0 0 85 80" fill="none" xmlns="http://www.w3.org/2000/svg">
- <path d="M80.578 0L47.7107 24.8648L53.542 10.2702L80.578 0Z" fill="#E2761B" />
- <path d="M4.24075 0L37.1081 25.4053L31.2768 10.2702L4.24075 0Z" fill="#E4761B" />
- <path d="M68.9152 57.8379L59.9032 71.8919L78.9874 77.2973L84.2886 58.3785L68.9152 57.8379Z" fill="#E4761B" />
- <path d="M0.53006 58.3785L5.83124 77.2973L24.9155 71.8919L15.9035 57.8379L0.53006 58.3785Z" fill="#E4761B" />
- <path d="M23.8552 34.5941L18.554 42.7022L37.1082 43.7833L36.5781 23.2428L23.8552 34.5941Z" fill="#E4761B" />
- <path d="M60.9635 34.5941L47.7106 23.2428V43.7833L66.2647 42.7022L60.9635 34.5941Z" fill="#E4761B" />
- <path d="M24.9156 71.8914L36.0481 66.4861L26.5059 58.378L24.9156 71.8914Z" fill="#E4761B" />
- <path d="M48.7709 66.4861L59.9034 71.8914L58.313 58.378L48.7709 66.4861Z" fill="#E4761B" />
- <path d="M59.9034 71.8919L48.7709 66.4865L49.301 73.5135V76.7567L59.9034 71.8919Z" fill="#D7C1B3" />
- <path d="M24.9157 71.892L35.518 76.7568V73.5136L36.0482 66.4866L24.9157 71.892Z" fill="#D7C1B3" />
- <path d="M35.5179 53.5138L25.9758 50.8111L32.8673 47.5678L35.5179 53.5138Z" fill="#233447" />
- <path d="M49.3009 53.5138L51.9515 47.5678L58.843 50.8111L49.3009 53.5138Z" fill="#233447" />
- <path d="M24.9155 71.892L26.5059 57.838L15.9035 58.3785L24.9155 71.892Z" fill="#CD6116" />
- <path d="M58.313 57.838L59.9034 71.892L68.9154 58.3785L58.313 57.838Z" fill="#CD6116" />
- <path
- d="M66.2648 42.7025L47.7106 43.7836L49.301 53.5132L51.9516 47.5673L58.8431 50.8106L66.2648 42.7025Z"
- fill="#CD6116"
- />
- <path
- d="M25.9758 50.8106L32.8673 47.5673L35.5179 53.5132L37.1083 43.7836L18.5541 42.7025L25.9758 50.8106Z"
- fill="#CD6116"
- />
- <path d="M18.5541 42.7024L26.5059 58.378L25.9758 50.8105L18.5541 42.7024Z" fill="#E4751F" />
- <path d="M58.8431 50.8106L58.313 58.3781L66.2647 42.7025L58.8431 50.8106Z" fill="#E4751F" />
- <path d="M37.1083 43.7838L35.518 53.5135L37.6384 65.4053L38.1686 49.7297L37.1083 43.7838Z" fill="#E4751F" />
- <path d="M47.7105 43.7838L46.6503 49.7297L47.1804 65.4053L49.3009 53.5135L47.7105 43.7838Z" fill="#E4751F" />
- <path
- d="M49.301 53.5134L47.1805 65.4052L48.7709 66.4863L58.313 58.3782L58.8431 50.8107L49.301 53.5134Z"
- fill="#F6851B"
- />
- <path
- d="M25.9758 50.8107L26.5059 58.3782L36.048 66.4863L37.6384 65.4052L35.5179 53.5134L25.9758 50.8107Z"
- fill="#F6851B"
- />
- <path
- d="M49.3011 76.7568V73.5135L48.771 72.973H36.0482L35.518 73.5135V76.7568L24.9157 71.8919L28.6265 75.1351L36.0482 80H48.771L56.1927 75.1351L59.9035 71.8919L49.3011 76.7568Z"
- fill="#C0AD9E"
- />
- <path
- d="M48.771 66.486L47.1806 65.405H37.6385L36.0482 66.486L35.518 73.513L36.0482 72.9725H48.771L49.3011 73.513L48.771 66.486Z"
- fill="#161616"
- />
- <path
- d="M82.1685 26.4864L84.8191 12.9729L80.5781 0L48.771 24.3242L60.9637 34.5945L78.4576 39.9998L82.1685 35.6755L80.5781 34.0539L83.2287 31.8918L81.1082 30.2702L83.7588 28.108L82.1685 26.4864Z"
- fill="#763D16"
- />
- <path
- d="M0 12.9729L2.65059 26.4864L1.06024 28.108L3.71083 30.2702L1.59036 31.8918L4.24095 34.0539L2.65059 35.6755L6.36142 39.9998L23.8553 34.5945L36.0481 24.3242L4.24095 0L0 12.9729Z"
- fill="#763D16"
- />
- <path
- d="M78.4575 39.9993L60.9636 34.5939L66.2648 42.702L58.313 58.3776H68.9154H84.2888L78.4575 39.9993Z"
- fill="#F6851B"
- />
- <path
- d="M23.8554 34.5939L6.36147 39.9993L0.530167 58.3776H15.9036H26.506L18.5542 42.702L23.8554 34.5939Z"
- fill="#F6851B"
- />
- <path
- d="M47.7106 43.7833L48.7709 24.3239L53.5419 10.2699H31.2769L36.048 24.3239L37.1083 43.7833L37.6384 49.7292V65.4048H47.1805V49.7292L47.7106 43.7833Z"
- fill="#F6851B"
- />
- </svg>
-);
-
-MetaMaskLogo.displayName = 'MetaMaskLogo';
-
-MetaMaskLogo.defaultProps = {
- width: 85,
- height: 80,
-};
diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx
deleted file mode 100644
index 3ded50652..000000000
--- a/packages/instant/src/components/order_details.tsx
+++ /dev/null
@@ -1,230 +0,0 @@
-import { BuyQuoteInfo } from '@0x/asset-buyer';
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-import * as React from 'react';
-import { oc } from 'ts-optchain';
-
-import { BIG_NUMBER_ZERO, DEFAULT_UNKOWN_ASSET_NAME } from '../constants';
-import { ColorOption } from '../style/theme';
-import { BaseCurrency } from '../types';
-import { format } from '../util/format';
-
-import { AmountPlaceholder } from './amount_placeholder';
-import { SectionHeader } from './section_header';
-
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Text, TextProps } from './ui/text';
-
-export interface OrderDetailsProps {
- buyQuoteInfo?: BuyQuoteInfo;
- selectedAssetUnitAmount?: BigNumber;
- ethUsdPrice?: BigNumber;
- isLoading: boolean;
- assetName?: string;
- baseCurrency: BaseCurrency;
- onBaseCurrencySwitchEth: () => void;
- onBaseCurrencySwitchUsd: () => void;
-}
-export class OrderDetails extends React.PureComponent<OrderDetailsProps> {
- public render(): React.ReactNode {
- const shouldShowUsdError = this.props.baseCurrency === BaseCurrency.USD && this._hadErrorFetchingUsdPrice();
- return (
- <Container width="100%" flexGrow={1} padding="20px 20px 0px 20px">
- <Container marginBottom="10px">{this._renderHeader()}</Container>
- {shouldShowUsdError ? this._renderErrorFetchingUsdPrice() : this._renderRows()}
- </Container>
- );
- }
-
- private _renderRows(): React.ReactNode {
- const { buyQuoteInfo } = this.props;
- return (
- <React.Fragment>
- <OrderDetailsRow
- labelText={this._assetAmountLabel()}
- primaryValue={this._displayAmountOrPlaceholder(buyQuoteInfo && buyQuoteInfo.assetEthAmount)}
- />
- <OrderDetailsRow
- labelText="Fee"
- primaryValue={this._displayAmountOrPlaceholder(buyQuoteInfo && buyQuoteInfo.feeEthAmount)}
- />
- <OrderDetailsRow
- labelText="Total Cost"
- isLabelBold={true}
- primaryValue={this._displayAmountOrPlaceholder(buyQuoteInfo && buyQuoteInfo.totalEthAmount)}
- isPrimaryValueBold={true}
- secondaryValue={this._totalCostSecondaryValue()}
- />
- </React.Fragment>
- );
- }
-
- private _renderErrorFetchingUsdPrice(): React.ReactNode {
- return (
- <Text>
- There was an error fetching the USD price.
- <Text
- onClick={this.props.onBaseCurrencySwitchEth}
- fontWeight={700}
- fontColor={ColorOption.primaryColor}
- >
- Click here
- </Text>
- {' to view ETH prices'}
- </Text>
- );
- }
-
- private _hadErrorFetchingUsdPrice(): boolean {
- return this.props.ethUsdPrice ? this.props.ethUsdPrice.isEqualTo(BIG_NUMBER_ZERO) : false;
- }
-
- private _totalCostSecondaryValue(): React.ReactNode {
- const secondaryCurrency = this.props.baseCurrency === BaseCurrency.USD ? BaseCurrency.ETH : BaseCurrency.USD;
-
- const canDisplayCurrency =
- secondaryCurrency === BaseCurrency.ETH ||
- (secondaryCurrency === BaseCurrency.USD && this.props.ethUsdPrice && !this._hadErrorFetchingUsdPrice());
-
- if (this.props.buyQuoteInfo && canDisplayCurrency) {
- return this._displayAmount(secondaryCurrency, this.props.buyQuoteInfo.totalEthAmount);
- } else {
- return undefined;
- }
- }
-
- private _displayAmountOrPlaceholder(weiAmount?: BigNumber): React.ReactNode {
- const { baseCurrency, isLoading } = this.props;
-
- if (_.isUndefined(weiAmount)) {
- return (
- <Container opacity={0.5}>
- <AmountPlaceholder color={ColorOption.lightGrey} isPulsating={isLoading} />
- </Container>
- );
- }
-
- return this._displayAmount(baseCurrency, weiAmount);
- }
-
- private _displayAmount(currency: BaseCurrency, weiAmount: BigNumber): React.ReactNode {
- switch (currency) {
- case BaseCurrency.USD:
- return format.ethBaseUnitAmountInUsd(weiAmount, this.props.ethUsdPrice, 2, '');
- case BaseCurrency.ETH:
- return format.ethBaseUnitAmount(weiAmount, 4, '');
- }
- }
-
- private _assetAmountLabel(): React.ReactNode {
- const { assetName, baseCurrency } = this.props;
- const numTokens = this.props.selectedAssetUnitAmount;
-
- // Display as 0 if we have a selected asset
- const displayNumTokens =
- assetName && assetName !== DEFAULT_UNKOWN_ASSET_NAME && _.isUndefined(numTokens)
- ? new BigNumber(0)
- : numTokens;
- if (!_.isUndefined(displayNumTokens)) {
- let numTokensWithSymbol: React.ReactNode = displayNumTokens.toString();
- if (assetName) {
- numTokensWithSymbol += ` ${assetName}`;
- }
- const pricePerTokenWei = this._pricePerTokenWei();
- if (pricePerTokenWei) {
- const atPriceDisplay = (
- <Text fontColor={ColorOption.lightGrey}>
- @ {this._displayAmount(baseCurrency, pricePerTokenWei)}
- </Text>
- );
- numTokensWithSymbol = (
- <React.Fragment>
- {numTokensWithSymbol} {atPriceDisplay}
- </React.Fragment>
- );
- }
- return numTokensWithSymbol;
- }
- return 'Token Amount';
- }
-
- private _pricePerTokenWei(): BigNumber | undefined {
- const buyQuoteAccessor = oc(this.props.buyQuoteInfo);
- const assetTotalInWei = buyQuoteAccessor.assetEthAmount();
- const selectedAssetUnitAmount = this.props.selectedAssetUnitAmount;
- return !_.isUndefined(assetTotalInWei) &&
- !_.isUndefined(selectedAssetUnitAmount) &&
- !selectedAssetUnitAmount.eq(BIG_NUMBER_ZERO)
- ? assetTotalInWei.div(selectedAssetUnitAmount).integerValue(BigNumber.ROUND_CEIL)
- : undefined;
- }
-
- private _baseCurrencyChoice(choice: BaseCurrency): React.ReactNode {
- const onClick =
- choice === BaseCurrency.ETH ? this.props.onBaseCurrencySwitchEth : this.props.onBaseCurrencySwitchUsd;
- const isSelected = this.props.baseCurrency === choice;
-
- const textStyle: TextProps = { onClick, fontSize: '12px' };
- if (isSelected) {
- textStyle.fontColor = ColorOption.primaryColor;
- textStyle.fontWeight = 700;
- } else {
- textStyle.fontColor = ColorOption.lightGrey;
- }
- return <Text {...textStyle}>{choice}</Text>;
- }
-
- private _renderHeader(): React.ReactNode {
- return (
- <Flex justify="space-between">
- <SectionHeader>Order Details</SectionHeader>
- <Container>
- {this._baseCurrencyChoice(BaseCurrency.ETH)}
- <Container marginLeft="5px" marginRight="5px" display="inline">
- <Text fontSize="12px" fontColor={ColorOption.feintGrey}>
- /
- </Text>
- </Container>
- {this._baseCurrencyChoice(BaseCurrency.USD)}
- </Container>
- </Flex>
- );
- }
-}
-
-export interface OrderDetailsRowProps {
- labelText: React.ReactNode;
- isLabelBold?: boolean;
- isPrimaryValueBold?: boolean;
- primaryValue: React.ReactNode;
- secondaryValue?: React.ReactNode;
-}
-export class OrderDetailsRow extends React.PureComponent<OrderDetailsRowProps, {}> {
- public render(): React.ReactNode {
- return (
- <Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}>
- <Flex justify="space-between">
- <Text fontWeight={this.props.isLabelBold ? 700 : 400} fontColor={ColorOption.grey}>
- {this.props.labelText}
- </Text>
- <Container>{this._renderValues()}</Container>
- </Flex>
- </Container>
- );
- }
-
- private _renderValues(): React.ReactNode {
- const secondaryValueNode: React.ReactNode = this.props.secondaryValue && (
- <Container marginRight="3px" display="inline-block">
- <Text fontColor={ColorOption.lightGrey}>({this.props.secondaryValue})</Text>
- </Container>
- );
- return (
- <React.Fragment>
- {secondaryValueNode}
- <Text fontWeight={this.props.isPrimaryValueBold ? 700 : 400}>{this.props.primaryValue}</Text>
- </React.Fragment>
- );
- }
-}
diff --git a/packages/instant/src/components/payment_method.tsx b/packages/instant/src/components/payment_method.tsx
deleted file mode 100644
index ada9f7bab..000000000
--- a/packages/instant/src/components/payment_method.tsx
+++ /dev/null
@@ -1,110 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-import { Account, AccountState, Network } from '../types';
-import { envUtil } from '../util/env';
-
-import { CoinbaseWalletLogo } from './coinbase_wallet_logo';
-import { MetaMaskLogo } from './meta_mask_logo';
-import { PaymentMethodDropdown } from './payment_method_dropdown';
-import { SectionHeader } from './section_header';
-import { Circle } from './ui/circle';
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Icon } from './ui/icon';
-import { Text } from './ui/text';
-import { WalletPrompt } from './wallet_prompt';
-
-export interface PaymentMethodProps {
- account: Account;
- network: Network;
- walletDisplayName: string;
- onInstallWalletClick: () => void;
- onUnlockWalletClick: () => void;
-}
-
-export class PaymentMethod extends React.PureComponent<PaymentMethodProps> {
- public render(): React.ReactNode {
- return (
- <Container width="100%" height="120px" padding="20px 20px 0px 20px">
- <Container marginBottom="12px">
- <Flex justify="space-between">
- <SectionHeader>{this._renderTitleText()}</SectionHeader>
- {this._renderTitleLabel()}
- </Flex>
- </Container>
- {this._renderMainContent()}
- </Container>
- );
- }
- private readonly _renderTitleText = (): string => {
- const { account } = this.props;
- switch (account.state) {
- case AccountState.Loading:
- return 'loading...';
- case AccountState.Locked:
- case AccountState.None:
- return 'connect your wallet';
- case AccountState.Ready:
- return 'payment method';
- }
- };
- private readonly _renderTitleLabel = (): React.ReactNode => {
- const { account } = this.props;
- if (account.state === AccountState.Ready || account.state === AccountState.Locked) {
- const circleColor: ColorOption = account.state === AccountState.Ready ? ColorOption.green : ColorOption.red;
- return (
- <Flex align="center">
- <Circle diameter={8} color={circleColor} />
- <Container marginLeft="5px">
- <Text fontColor={ColorOption.darkGrey} fontSize="12px" lineHeight="30px">
- {this.props.walletDisplayName}
- </Text>
- </Container>
- </Flex>
- );
- }
- return null;
- };
- private readonly _renderMainContent = (): React.ReactNode => {
- const { account, network } = this.props;
- const isMobile = envUtil.isMobileOperatingSystem();
- const logo = isMobile ? <CoinbaseWalletLogo width={22} /> : <MetaMaskLogo width={19} height={18} />;
- const primaryColor = isMobile ? ColorOption.darkBlue : ColorOption.darkOrange;
- const secondaryColor = isMobile ? ColorOption.lightBlue : ColorOption.lightOrange;
- const colors = { primaryColor, secondaryColor };
- switch (account.state) {
- case AccountState.Loading:
- return null;
- case AccountState.Locked:
- return (
- <WalletPrompt
- onClick={this.props.onUnlockWalletClick}
- image={
- <Container position="relative" top="2px">
- <Icon width={13} icon="lock" color={ColorOption.black} />
- </Container>
- }
- {...colors}
- >
- Click to Connect {this.props.walletDisplayName}
- </WalletPrompt>
- );
- case AccountState.None:
- return (
- <WalletPrompt onClick={this.props.onInstallWalletClick} image={logo} {...colors}>
- {isMobile ? 'Install Coinbase Wallet' : 'Install MetaMask'}
- </WalletPrompt>
- );
- case AccountState.Ready:
- return (
- <PaymentMethodDropdown
- accountAddress={account.address}
- accountEthBalanceInWei={account.ethBalanceInWei}
- network={network}
- />
- );
- }
- };
-}
diff --git a/packages/instant/src/components/payment_method_dropdown.tsx b/packages/instant/src/components/payment_method_dropdown.tsx
deleted file mode 100644
index e463e3eae..000000000
--- a/packages/instant/src/components/payment_method_dropdown.tsx
+++ /dev/null
@@ -1,60 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as copy from 'copy-to-clipboard';
-import * as React from 'react';
-
-import { Network } from '../types';
-import { analytics } from '../util/analytics';
-import { envUtil } from '../util/env';
-import { etherscanUtil } from '../util/etherscan';
-import { format } from '../util/format';
-
-import { Dropdown, DropdownItemConfig } from './ui/dropdown';
-
-export interface PaymentMethodDropdownProps {
- accountAddress: string;
- accountEthBalanceInWei?: BigNumber;
- network: Network;
-}
-
-export class PaymentMethodDropdown extends React.PureComponent<PaymentMethodDropdownProps> {
- public render(): React.ReactNode {
- const { accountAddress, accountEthBalanceInWei } = this.props;
- const value = format.ethAddress(accountAddress);
- const label = format.ethBaseUnitAmount(accountEthBalanceInWei, 4, '') as string;
- return (
- <Dropdown
- value={value}
- label={label}
- items={this._getDropdownItemConfigs()}
- onOpen={analytics.trackPaymentMethodDropdownOpened}
- />
- );
- }
- private readonly _getDropdownItemConfigs = (): DropdownItemConfig[] => {
- if (envUtil.isMobileOperatingSystem()) {
- return [];
- }
- const viewOnEtherscan = {
- text: 'View on Etherscan',
- onClick: this._handleEtherscanClick,
- };
- const copyAddressToClipboard = {
- text: 'Copy address to clipboard',
- onClick: this._handleCopyToClipboardClick,
- };
- return [viewOnEtherscan, copyAddressToClipboard];
- };
- private readonly _handleEtherscanClick = (): void => {
- analytics.trackPaymentMethodOpenedEtherscan();
-
- const { accountAddress, network } = this.props;
- const etherscanUrl = etherscanUtil.getEtherScanEthAddressIfExists(accountAddress, network);
- window.open(etherscanUrl, '_blank');
- };
- private readonly _handleCopyToClipboardClick = (): void => {
- analytics.trackPaymentMethodCopiedAddress();
-
- const { accountAddress } = this.props;
- copy(accountAddress);
- };
-}
diff --git a/packages/instant/src/components/placing_order_button.tsx b/packages/instant/src/components/placing_order_button.tsx
deleted file mode 100644
index 528a305dc..000000000
--- a/packages/instant/src/components/placing_order_button.tsx
+++ /dev/null
@@ -1,18 +0,0 @@
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-
-import { Button } from './ui/button';
-import { Container } from './ui/container';
-import { Spinner } from './ui/spinner';
-
-export const PlacingOrderButton: React.StatelessComponent<{}> = props => (
- <Button isDisabled={true} width="100%" fontColor={ColorOption.white}>
- <Container display="inline-block" position="relative" top="3px" marginRight="8px">
- <Spinner widthPx={16} heightPx={16} />
- </Container>
- Placing Order&hellip;
- </Button>
-);
-
-PlacingOrderButton.displayName = 'PlacingOrderButton';
diff --git a/packages/instant/src/components/scaling_amount_input.tsx b/packages/instant/src/components/scaling_amount_input.tsx
deleted file mode 100644
index 7dc1fdc0c..000000000
--- a/packages/instant/src/components/scaling_amount_input.tsx
+++ /dev/null
@@ -1,92 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { Maybe } from '../types';
-
-import { GIT_SHA, MAGIC_TRIGGER_ERROR_INPUT, MAGIC_TRIGGER_ERROR_MESSAGE, NPM_PACKAGE_VERSION } from '../constants';
-import { ColorOption } from '../style/theme';
-import { maybeBigNumberUtil } from '../util/maybe_big_number';
-import { util } from '../util/util';
-
-import { ScalingInput } from './scaling_input';
-
-export interface ScalingAmountInputProps {
- isDisabled: boolean;
- maxFontSizePx: number;
- textLengthThreshold: number;
- fontColor?: ColorOption;
- value?: BigNumber;
- onAmountChange: (value?: BigNumber) => void;
- onFontSizeChange: (fontSizePx: number) => void;
- hasAutofocus: boolean;
-}
-interface ScalingAmountInputState {
- stringValue: string;
-}
-
-const { stringToMaybeBigNumber, areMaybeBigNumbersEqual } = maybeBigNumberUtil;
-export class ScalingAmountInput extends React.PureComponent<ScalingAmountInputProps, ScalingAmountInputState> {
- public static defaultProps = {
- onAmountChange: util.boundNoop,
- onFontSizeChange: util.boundNoop,
- isDisabled: false,
- hasAutofocus: false,
- };
- public constructor(props: ScalingAmountInputProps) {
- super(props);
- this.state = {
- stringValue: _.isUndefined(props.value) ? '' : props.value.toString(),
- };
- }
- public componentDidUpdate(): void {
- const parsedStateValue = stringToMaybeBigNumber(this.state.stringValue);
- const currentValue = this.props.value;
-
- if (!areMaybeBigNumbersEqual(parsedStateValue, currentValue)) {
- // we somehow got into the state in which the value passed in and the string value
- // in state have differed, reset state
- // we dont expect to ever get into this state, but let's make sure
- // we reset if we do since we're dealing with important numbers
- this.setState({
- stringValue: _.isUndefined(currentValue) ? '' : currentValue.toString(),
- });
- }
- }
-
- public render(): React.ReactNode {
- const { textLengthThreshold, fontColor, maxFontSizePx, onFontSizeChange } = this.props;
- return (
- <ScalingInput
- type="number"
- maxFontSizePx={maxFontSizePx}
- textLengthThreshold={textLengthThreshold}
- onFontSizeChange={onFontSizeChange}
- fontColor={fontColor}
- onChange={this._handleChange}
- value={this.state.stringValue}
- placeholder="0.00"
- emptyInputWidthCh={3.5}
- isDisabled={this.props.isDisabled}
- hasAutofocus={this.props.hasAutofocus}
- />
- );
- }
- private readonly _handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
- if (event.target.value === MAGIC_TRIGGER_ERROR_INPUT) {
- throw new Error(`${MAGIC_TRIGGER_ERROR_MESSAGE} git: ${GIT_SHA}, npm: ${NPM_PACKAGE_VERSION}`);
- }
-
- const sanitizedValue = event.target.value.replace(/[^0-9.]/g, ''); // only allow numbers and "."
- this.setState({
- stringValue: sanitizedValue,
- });
-
- // Trigger onAmountChange with a valid BigNumber, or undefined if the sanitizedValue is invalid or empty
- const bigNumberValue: Maybe<BigNumber> = _.isEmpty(sanitizedValue)
- ? undefined
- : stringToMaybeBigNumber(sanitizedValue);
-
- this.props.onAmountChange(bigNumberValue);
- };
-}
diff --git a/packages/instant/src/components/scaling_input.tsx b/packages/instant/src/components/scaling_input.tsx
deleted file mode 100644
index c31de1fb5..000000000
--- a/packages/instant/src/components/scaling_input.tsx
+++ /dev/null
@@ -1,165 +0,0 @@
-import { ObjectMap } from '@0x/types';
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-import { util } from '../util/util';
-
-import { Input } from './ui/input';
-
-export enum ScalingInputPhase {
- FixedFontSize,
- ScalingFontSize,
-}
-
-export interface ScalingSettings {
- percentageToReduceFontSizePerCharacter: number;
- // 1ch = the width of the 0 chararacter.
- // Allow to customize 'char' length for different characters.
- characterWidthOverrides: ObjectMap<number>;
- // How much room to leave to the right of the scaling input.
- additionalInputSpaceInCh: number;
-}
-
-export interface ScalingInputProps {
- type?: string;
- textLengthThreshold: number;
- maxFontSizePx: number;
- value: string;
- emptyInputWidthCh: number;
- onChange: (event: React.ChangeEvent<HTMLInputElement>) => void;
- onFontSizeChange: (fontSizePx: number) => void;
- fontColor?: ColorOption;
- placeholder?: string;
- maxLength?: number;
- scalingSettings: ScalingSettings;
- isDisabled: boolean;
- hasAutofocus: boolean;
-}
-
-export interface ScalingInputSnapshot {
- inputWidthPx: number;
-}
-
-// These are magic numbers that were determined experimentally.
-const defaultScalingSettings: ScalingSettings = {
- percentageToReduceFontSizePerCharacter: 0.1,
- characterWidthOverrides: {
- '1': 0.7,
- '.': 0.4,
- },
- additionalInputSpaceInCh: 0.4,
-};
-
-export class ScalingInput extends React.PureComponent<ScalingInputProps> {
- public static defaultProps = {
- onChange: util.boundNoop,
- onFontSizeChange: util.boundNoop,
- maxLength: 9,
- scalingSettings: defaultScalingSettings,
- isDisabled: false,
- hasAutofocus: false,
- };
- private readonly _inputRef = React.createRef<HTMLInputElement>();
- public static getPhase(textLengthThreshold: number, value: string): ScalingInputPhase {
- if (value.length <= textLengthThreshold) {
- return ScalingInputPhase.FixedFontSize;
- }
- return ScalingInputPhase.ScalingFontSize;
- }
- public static getPhaseFromProps(props: ScalingInputProps): ScalingInputPhase {
- const { value, textLengthThreshold } = props;
- return ScalingInput.getPhase(textLengthThreshold, value);
- }
- public static calculateFontSize(
- textLengthThreshold: number,
- maxFontSizePx: number,
- phase: ScalingInputPhase,
- value: string,
- percentageToReduceFontSizePerCharacter: number,
- ): number {
- if (phase !== ScalingInputPhase.ScalingFontSize) {
- return maxFontSizePx;
- }
- const charactersOverMax = value.length - textLengthThreshold;
- const scalingFactor = (1 - percentageToReduceFontSizePerCharacter) ** charactersOverMax;
- const fontSize = scalingFactor * maxFontSizePx;
- return fontSize;
- }
- public static calculateFontSizeFromProps(props: ScalingInputProps, phase: ScalingInputPhase): number {
- const { textLengthThreshold, value, maxFontSizePx, scalingSettings } = props;
- return ScalingInput.calculateFontSize(
- textLengthThreshold,
- maxFontSizePx,
- phase,
- value,
- scalingSettings.percentageToReduceFontSizePerCharacter,
- );
- }
- public componentDidMount(): void {
- // Trigger an initial notification of the calculated fontSize.
- const currentPhase = ScalingInput.getPhaseFromProps(this.props);
- const currentFontSize = ScalingInput.calculateFontSizeFromProps(this.props, currentPhase);
- this.props.onFontSizeChange(currentFontSize);
- }
- public componentDidUpdate(prevProps: ScalingInputProps): void {
- const prevPhase = ScalingInput.getPhaseFromProps(prevProps);
- const curPhase = ScalingInput.getPhaseFromProps(this.props);
- const prevFontSize = ScalingInput.calculateFontSizeFromProps(prevProps, prevPhase);
- const curFontSize = ScalingInput.calculateFontSizeFromProps(this.props, curPhase);
- // If font size has changed, notify.
- if (prevFontSize !== curFontSize) {
- this.props.onFontSizeChange(curFontSize);
- }
- }
- public render(): React.ReactNode {
- const { type, hasAutofocus, isDisabled, fontColor, placeholder, value, maxLength } = this.props;
- const phase = ScalingInput.getPhaseFromProps(this.props);
- return (
- <Input
- type={type}
- ref={this._inputRef as any}
- fontColor={fontColor}
- onChange={this._handleChange}
- value={value}
- placeholder={placeholder}
- fontSize={`${this._calculateFontSize(phase)}px`}
- width={this._calculateWidth(phase)}
- maxLength={maxLength}
- disabled={isDisabled}
- autoFocus={hasAutofocus}
- />
- );
- }
- private readonly _calculateWidth = (phase: ScalingInputPhase): string => {
- const { value, scalingSettings } = this.props;
- if (_.isEmpty(value)) {
- return `${this.props.emptyInputWidthCh}ch`;
- }
- const lengthInCh = _.reduce(
- value.split(''),
- (sum, char) => {
- const widthOverride = scalingSettings.characterWidthOverrides[char];
- if (!_.isUndefined(widthOverride)) {
- // tslint is confused
- // tslint:disable-next-line:restrict-plus-operands
- return sum + widthOverride;
- }
- return sum + 1;
- },
- scalingSettings.additionalInputSpaceInCh,
- );
- return `${lengthInCh}ch`;
- };
- private readonly _calculateFontSize = (phase: ScalingInputPhase): number => {
- return ScalingInput.calculateFontSizeFromProps(this.props, phase);
- };
- private readonly _handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
- const value = event.target.value;
- const { maxLength } = this.props;
- if (!_.isUndefined(value) && !_.isUndefined(maxLength) && value.length > maxLength) {
- return;
- }
- this.props.onChange(event);
- };
-}
diff --git a/packages/instant/src/components/search_input.tsx b/packages/instant/src/components/search_input.tsx
deleted file mode 100644
index 71bc18915..000000000
--- a/packages/instant/src/components/search_input.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Icon } from './ui/icon';
-import { Input, InputProps } from './ui/input';
-
-export interface SearchInputProps extends InputProps {
- backgroundColor?: ColorOption;
-}
-
-export const SearchInput: React.StatelessComponent<SearchInputProps> = props => (
- <Container backgroundColor={props.backgroundColor} borderRadius="3px" padding=".5em .5em">
- <Flex justify="flex-start" align="center">
- <Icon width={14} height={14} icon="search" color={ColorOption.lightGrey} padding="2px 12px" />
- <Input {...props} type="search" fontSize="16px" fontColor={props.fontColor} />
- </Flex>
- </Container>
-);
-
-SearchInput.displayName = 'SearchInput';
-
-SearchInput.defaultProps = {
- backgroundColor: ColorOption.lightestGrey,
- fontColor: ColorOption.grey,
-};
diff --git a/packages/instant/src/components/secondary_button.tsx b/packages/instant/src/components/secondary_button.tsx
deleted file mode 100644
index 0714ce287..000000000
--- a/packages/instant/src/components/secondary_button.tsx
+++ /dev/null
@@ -1,27 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-
-import { Button, ButtonProps } from './ui/button';
-
-export interface SecondaryButtonProps extends ButtonProps {}
-
-export const SecondaryButton: React.StatelessComponent<SecondaryButtonProps> = props => {
- const buttonProps = _.omit(props, 'text');
- return (
- <Button
- backgroundColor={ColorOption.white}
- borderColor={ColorOption.lightGrey}
- width={props.width}
- onClick={props.onClick}
- {...buttonProps}
- >
- {props.children}
- </Button>
- );
-};
-SecondaryButton.defaultProps = {
- width: '100%',
-};
-SecondaryButton.displayName = 'SecondaryButton';
diff --git a/packages/instant/src/components/section_header.tsx b/packages/instant/src/components/section_header.tsx
deleted file mode 100644
index 2185b67ba..000000000
--- a/packages/instant/src/components/section_header.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-
-import { Text } from './ui/text';
-
-export interface SectionHeaderProps {}
-export const SectionHeader: React.StatelessComponent<SectionHeaderProps> = props => {
- return (
- <Text
- letterSpacing="1px"
- fontColor={ColorOption.primaryColor}
- fontWeight={600}
- textTransform="uppercase"
- fontSize="12px"
- >
- {props.children}
- </Text>
- );
-};
-SectionHeader.displayName = 'SectionHeader';
diff --git a/packages/instant/src/components/sliding_error.tsx b/packages/instant/src/components/sliding_error.tsx
deleted file mode 100644
index c7c6732cf..000000000
--- a/packages/instant/src/components/sliding_error.tsx
+++ /dev/null
@@ -1,100 +0,0 @@
-import * as React from 'react';
-
-import { ScreenSpecification } from '../style/media';
-import { ColorOption } from '../style/theme';
-import { zIndex } from '../style/z_index';
-import { SlideAnimationState } from '../types';
-
-import { PositionAnimationSettings } from './animations/position_animation';
-import { SlideAnimation } from './animations/slide_animation';
-
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Text } from './ui/text';
-
-export interface ErrorProps {
- icon: string;
- message: string;
-}
-
-export const Error: React.StatelessComponent<ErrorProps> = props => (
- <Container
- padding="10px"
- border={`1px solid ${ColorOption.darkOrange}`}
- backgroundColor={ColorOption.lightOrange}
- width="100%"
- borderRadius="6px"
- marginTop="10px"
- marginBottom="10px"
- >
- <Flex justify="flex-start">
- <Container marginRight="5px" display="inline" top="3px" position="relative">
- <Text fontSize="20px">{props.icon}</Text>
- </Container>
- <Text fontWeight="500" fontColor={ColorOption.darkOrange}>
- {props.message}
- </Text>
- </Flex>
- </Container>
-);
-
-Error.displayName = 'Error';
-
-export interface SlidingErrorProps extends ErrorProps {
- animationState: SlideAnimationState;
-}
-export const SlidingError: React.StatelessComponent<SlidingErrorProps> = props => {
- const slideAmount = '120px';
-
- const desktopSlideIn: PositionAnimationSettings = {
- timingFunction: 'ease-in',
- top: {
- from: slideAmount,
- to: '0px',
- },
- position: 'relative',
- };
- const desktopSlideOut: PositionAnimationSettings = {
- timingFunction: 'cubic-bezier(0.25, 0.1, 0.25, 1)',
- top: {
- from: '0px',
- to: slideAmount,
- },
- position: 'relative',
- };
-
- const mobileSlideIn: PositionAnimationSettings = {
- duration: '0.5s',
- timingFunction: 'ease-in',
- top: { from: '-120px', to: '0px' },
- position: 'fixed',
- };
- const moblieSlideOut: PositionAnimationSettings = {
- duration: '0.5s',
- timingFunction: 'ease-in',
- top: { from: '0px', to: '-120px' },
- position: 'fixed',
- };
-
- const slideUpSettings: ScreenSpecification<PositionAnimationSettings> = {
- default: desktopSlideIn,
- sm: mobileSlideIn,
- };
- const slideOutSettings: ScreenSpecification<PositionAnimationSettings> = {
- default: desktopSlideOut,
- sm: moblieSlideOut,
- };
-
- return (
- <SlideAnimation
- slideInSettings={slideUpSettings}
- slideOutSettings={slideOutSettings}
- zIndex={{ sm: zIndex.errorPopup, default: zIndex.errorPopBehind }}
- animationState={props.animationState}
- >
- <Error icon={props.icon} message={props.message} />
- </SlideAnimation>
- );
-};
-
-SlidingError.displayName = 'SlidingError';
diff --git a/packages/instant/src/components/sliding_panel.tsx b/packages/instant/src/components/sliding_panel.tsx
deleted file mode 100644
index 9b09a0d80..000000000
--- a/packages/instant/src/components/sliding_panel.tsx
+++ /dev/null
@@ -1,73 +0,0 @@
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-import { zIndex } from '../style/z_index';
-import { SlideAnimationState } from '../types';
-
-import { PositionAnimationSettings } from './animations/position_animation';
-import { SlideAnimation } from './animations/slide_animation';
-
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Icon } from './ui/icon';
-
-export interface PanelProps {
- onClose?: () => void;
-}
-
-export const Panel: React.StatelessComponent<PanelProps> = ({ children, onClose }) => (
- <Container backgroundColor={ColorOption.white} width="100%" height="100%" zIndex={zIndex.panel} padding="20px">
- <Flex justify="flex-end">
- <Icon padding="5px" width={12} color={ColorOption.lightGrey} icon="closeX" onClick={onClose} />
- </Flex>
- <Container position="relative" top="-10px" height="100%">
- {children}
- </Container>
- </Container>
-);
-
-Panel.displayName = 'Panel';
-
-export interface SlidingPanelProps extends PanelProps {
- animationState: SlideAnimationState;
- onAnimationEnd?: () => void;
-}
-
-export class SlidingPanel extends React.PureComponent<SlidingPanelProps> {
- public render(): React.ReactNode {
- if (this.props.animationState === 'none') {
- return null;
- }
- const { animationState, onAnimationEnd, ...rest } = this.props;
- const slideAmount = '100%';
- const slideUpSettings: PositionAnimationSettings = {
- duration: '0.3s',
- timingFunction: 'ease-in-out',
- top: {
- from: slideAmount,
- to: '0px',
- },
- position: 'absolute',
- };
- const slideDownSettings: PositionAnimationSettings = {
- duration: '0.3s',
- timingFunction: 'ease-out',
- top: {
- from: '0px',
- to: slideAmount,
- },
- position: 'absolute',
- };
- return (
- <SlideAnimation
- slideInSettings={slideUpSettings}
- slideOutSettings={slideDownSettings}
- animationState={animationState}
- height="100%"
- onAnimationEnd={onAnimationEnd}
- >
- <Panel {...rest} />
- </SlideAnimation>
- );
- }
-}
diff --git a/packages/instant/src/components/standard_panel_content.tsx b/packages/instant/src/components/standard_panel_content.tsx
deleted file mode 100644
index f2987df82..000000000
--- a/packages/instant/src/components/standard_panel_content.tsx
+++ /dev/null
@@ -1,75 +0,0 @@
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-import { util } from '../util/util';
-
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Text } from './ui/text';
-
-export interface MoreInfoSettings {
- text: string;
- href: string;
- onClick?: () => void;
-}
-
-export interface StandardPanelContentProps {
- image: React.ReactNode;
- title?: string;
- description: string;
- moreInfoSettings?: MoreInfoSettings;
- action: React.ReactNode;
-}
-
-const SPACING_BETWEEN_PX = '20px';
-
-const onMoreInfoClick = (href: string, onClick?: () => void) => {
- return () => {
- if (onClick) {
- onClick();
- }
- util.createOpenUrlInNewWindow(href)();
- };
-};
-
-export const StandardPanelContent: React.StatelessComponent<StandardPanelContentProps> = ({
- image,
- title,
- description,
- moreInfoSettings,
- action,
-}) => (
- <Container height="100%">
- <Flex direction="column" height="calc(100% - 58px)">
- <Container marginBottom={SPACING_BETWEEN_PX}>{image}</Container>
- {title && (
- <Container marginBottom={SPACING_BETWEEN_PX}>
- <Text fontSize="20px" fontWeight={700} fontColor={ColorOption.black}>
- {title}
- </Text>
- </Container>
- )}
- <Container marginBottom={SPACING_BETWEEN_PX}>
- <Text fontSize="14px" fontColor={ColorOption.grey} center={true}>
- {description}
- </Text>
- </Container>
- <Container marginBottom={SPACING_BETWEEN_PX}>
- {moreInfoSettings && (
- <Text
- center={true}
- fontSize="13px"
- textDecorationLine="underline"
- fontColor={ColorOption.lightGrey}
- onClick={onMoreInfoClick(moreInfoSettings.href, moreInfoSettings.onClick)}
- >
- {moreInfoSettings.text}
- </Text>
- )}
- </Container>
- </Flex>
- <Container>{action}</Container>
- </Container>
-);
-
-StandardPanelContent.displayName = 'StandardPanelContent';
diff --git a/packages/instant/src/components/standard_sliding_panel.tsx b/packages/instant/src/components/standard_sliding_panel.tsx
deleted file mode 100644
index bcc9d3dce..000000000
--- a/packages/instant/src/components/standard_sliding_panel.tsx
+++ /dev/null
@@ -1,29 +0,0 @@
-import * as React from 'react';
-
-import { StandardSlidingPanelContent, StandardSlidingPanelSettings } from '../types';
-
-import { InstallWalletPanelContent } from './install_wallet_panel_content';
-import { SlidingPanel } from './sliding_panel';
-
-export interface StandardSlidingPanelProps extends StandardSlidingPanelSettings {
- onClose: () => void;
-}
-
-export class StandardSlidingPanel extends React.PureComponent<StandardSlidingPanelProps> {
- public render(): React.ReactNode {
- const { animationState, content, onClose } = this.props;
- return (
- <SlidingPanel animationState={animationState} onClose={onClose}>
- {this._getNodeForContent(content)}
- </SlidingPanel>
- );
- }
- private readonly _getNodeForContent = (content: StandardSlidingPanelContent): React.ReactNode => {
- switch (content) {
- case StandardSlidingPanelContent.InstallWallet:
- return <InstallWalletPanelContent />;
- case StandardSlidingPanelContent.None:
- return null;
- }
- };
-}
diff --git a/packages/instant/src/components/time_counter.tsx b/packages/instant/src/components/time_counter.tsx
deleted file mode 100644
index 93dc497d5..000000000
--- a/packages/instant/src/components/time_counter.tsx
+++ /dev/null
@@ -1,78 +0,0 @@
-import * as React from 'react';
-
-import { ONE_SECOND_MS } from '../constants';
-import { ColorOption } from '../style/theme';
-import { timeUtil } from '../util/time';
-
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Text } from './ui/text';
-
-export interface TimeCounterProps {
- estimatedTimeMs: number;
- hasEnded: boolean;
-}
-interface TimeCounterState {
- elapsedSeconds: number;
-}
-
-export class TimeCounter extends React.PureComponent<TimeCounterProps, TimeCounterState> {
- public state = {
- elapsedSeconds: 0,
- };
- private _timerId?: number;
-
- public componentDidMount(): void {
- this._setupTimerBasedOnProps();
- }
-
- public componentWillUnmount(): void {
- this._clearTimer();
- }
-
- public componentDidUpdate(prevProps: TimeCounterProps): void {
- if (prevProps.hasEnded !== this.props.hasEnded) {
- this._setupTimerBasedOnProps();
- }
- }
-
- public render(): React.ReactNode {
- const estimatedTimeSeconds = this.props.estimatedTimeMs / ONE_SECOND_MS;
- return (
- <Flex justify="space-between">
- <Container>
- <Container marginRight="5px" display="inline">
- <Text fontWeight={600} fontColor={ColorOption.grey}>
- Est. Time
- </Text>
- </Container>
- <Text fontColor={ColorOption.grey}>
- ({timeUtil.secondsToHumanDescription(estimatedTimeSeconds)})
- </Text>
- </Container>
- <Text fontColor={ColorOption.grey}>
- Time: {timeUtil.secondsToStopwatchTime(this.state.elapsedSeconds)}
- </Text>
- </Flex>
- );
- }
-
- private _setupTimerBasedOnProps(): void {
- this.props.hasEnded ? this._clearTimer() : this._newTimer();
- }
-
- private _newTimer(): void {
- this._clearTimer();
- this._timerId = window.setInterval(() => {
- this.setState({
- elapsedSeconds: this.state.elapsedSeconds + 1,
- });
- }, ONE_SECOND_MS);
- }
-
- private _clearTimer(): void {
- if (this._timerId) {
- window.clearInterval(this._timerId);
- }
- }
-}
diff --git a/packages/instant/src/components/timed_progress_bar.tsx b/packages/instant/src/components/timed_progress_bar.tsx
deleted file mode 100644
index 287269af7..000000000
--- a/packages/instant/src/components/timed_progress_bar.tsx
+++ /dev/null
@@ -1,106 +0,0 @@
-import * as _ from 'lodash';
-import { transparentize } from 'polished';
-import * as React from 'react';
-
-import { PROGRESS_FINISH_ANIMATION_TIME_MS, PROGRESS_STALL_AT_WIDTH } from '../constants';
-import { ColorOption, css, keyframes, styled, ThemeConsumer } from '../style/theme';
-
-import { Container } from './ui/container';
-
-export interface TimedProgressBarProps {
- expectedTimeMs: number;
- hasEnded: boolean;
-}
-
-/**
- * Timed Progress Bar
- * Goes from 0% -> PROGRESS_STALL_AT_WIDTH over time of expectedTimeMs
- * When hasEnded set to true, goes to 100% through animation of PROGRESS_FINISH_ANIMATION_TIME_MS length of time
- */
-export class TimedProgressBar extends React.PureComponent<TimedProgressBarProps, {}> {
- private readonly _barRef = React.createRef<HTMLDivElement>();
-
- public render(): React.ReactNode {
- const widthAnimationSettings = this._calculateWidthAnimationSettings();
- return <ProgressBar animationSettings={widthAnimationSettings} ref={this._barRef} />;
- }
-
- private _calculateWidthAnimationSettings(): WidthAnimationSettings {
- if (this.props.hasEnded) {
- if (!this._barRef.current) {
- throw new Error('ended but no reference');
- }
- const fromWidth = `${this._barRef.current.offsetWidth}px`;
- return {
- timeMs: PROGRESS_FINISH_ANIMATION_TIME_MS,
- fromWidth,
- toWidth: '100%',
- };
- }
-
- return {
- timeMs: this.props.expectedTimeMs,
- fromWidth: '0px',
- toWidth: PROGRESS_STALL_AT_WIDTH,
- };
- }
-}
-
-const expandingWidthKeyframes = (fromWidth: string, toWidth: string) => {
- return keyframes`
- from {
- width: ${fromWidth};
- }
- to {
- width: ${toWidth};
- }
- `;
-};
-
-export interface WidthAnimationSettings {
- timeMs: number;
- fromWidth: string;
- toWidth: string;
-}
-
-interface ProgressProps {
- width?: string;
- animationSettings?: WidthAnimationSettings;
-}
-
-export const Progress = styled.div<ProgressProps>`
- && {
- background-color: ${props => props.theme[ColorOption.primaryColor]};
- border-radius: 6px;
- height: 6px;
- ${props => (props.width ? `width: ${props.width};` : '')}
- ${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) => (
- <ThemeConsumer>
- {theme => (
- <Container
- width="100%"
- borderRadius="6px"
- rawBackgroundColor={transparentize(0.5, theme[ColorOption.primaryColor])}
- >
- <Progress {...props} ref={ref as any} />
- </Container>
- )}
- </ThemeConsumer>
- ),
-);
diff --git a/packages/instant/src/components/ui/button.tsx b/packages/instant/src/components/ui/button.tsx
deleted file mode 100644
index e77b1b5d1..000000000
--- a/packages/instant/src/components/ui/button.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import { darken, saturate } from 'polished';
-import * as React from 'react';
-
-import { ColorOption, styled } from '../../style/theme';
-import { util } from '../../util/util';
-
-export type ButtonOnClickHandler = (event: React.MouseEvent<HTMLElement>) => void;
-
-export interface ButtonProps {
- backgroundColor?: ColorOption;
- borderColor?: ColorOption;
- fontColor?: ColorOption;
- fontSize?: string;
- width?: string;
- padding?: string;
- type?: string;
- isDisabled?: boolean;
- href?: string;
- onClick?: ButtonOnClickHandler;
- className?: string;
-}
-
-const PlainButton: React.StatelessComponent<ButtonProps> = ({
- children,
- isDisabled,
- onClick,
- href,
- type,
- className,
-}) => {
- const computedOnClick = isDisabled ? undefined : href ? util.createOpenUrlInNewWindow(href) : onClick;
- return (
- <button type={type} className={className} onClick={computedOnClick} disabled={isDisabled}>
- {children}
- </button>
- );
-};
-
-const darkenOnHoverAmount = 0.1;
-const darkenOnActiveAmount = 0.2;
-const saturateOnFocusAmount = 0.2;
-export const Button = styled(PlainButton)`
- && {
- all: initial;
- box-sizing: border-box;
- font-size: ${props => props.fontSize};
- font-family: 'Inter UI', sans-serif;
- font-weight: 500;
- color: ${props => props.fontColor && props.theme[props.fontColor]};
- cursor: ${props => (props.isDisabled ? 'default' : 'pointer')};
- transition: background-color, opacity 0.5s ease;
- padding: ${props => props.padding};
- border-radius: 3px;
- text-align: center;
- outline: none;
- width: ${props => props.width};
- background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')};
- border: ${props => (props.borderColor ? `1px solid ${props.theme[props.borderColor]}` : 'none')};
- &:hover {
- background-color: ${props =>
- !props.isDisabled
- ? darken(darkenOnHoverAmount, props.theme[props.backgroundColor || 'white'])
- : ''} !important;
- }
- &:active {
- background-color: ${props =>
- !props.isDisabled ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''};
- }
- &:disabled {
- opacity: 0.5;
- }
- &:focus {
- background-color: ${props =>
- saturate(saturateOnFocusAmount, props.theme[props.backgroundColor || 'white'])};
- }
- }
-`;
-
-Button.defaultProps = {
- backgroundColor: ColorOption.primaryColor,
- width: 'auto',
- isDisabled: false,
- padding: '.82em 1.2em',
- fontSize: '16px',
-};
-
-Button.displayName = 'Button';
diff --git a/packages/instant/src/components/ui/circle.tsx b/packages/instant/src/components/ui/circle.tsx
deleted file mode 100644
index e4f2c5260..000000000
--- a/packages/instant/src/components/ui/circle.tsx
+++ /dev/null
@@ -1,26 +0,0 @@
-import { ColorOption, styled, Theme, withTheme } from '../../style/theme';
-
-export interface CircleProps {
- diameter: number;
- rawColor?: string;
- color?: ColorOption;
- theme: Theme;
-}
-
-export const Circle = withTheme(
- styled.div<CircleProps>`
- && {
- width: ${props => props.diameter}px;
- height: ${props => props.diameter}px;
- background-color: ${props =>
- props.rawColor ? props.rawColor : props.theme[props.color || ColorOption.white]};
- border-radius: 50%;
- }
- `,
-);
-
-Circle.displayName = 'Circle';
-
-Circle.defaultProps = {
- color: ColorOption.white,
-};
diff --git a/packages/instant/src/components/ui/container.tsx b/packages/instant/src/components/ui/container.tsx
deleted file mode 100644
index 59b733f3e..000000000
--- a/packages/instant/src/components/ui/container.tsx
+++ /dev/null
@@ -1,104 +0,0 @@
-import { darken } from 'polished';
-
-import { MediaChoice, stylesForMedia } from '../../style/media';
-import { ColorOption, styled } from '../../style/theme';
-import { cssRuleIfExists } from '../../style/util';
-
-export interface ContainerProps {
- display?: MediaChoice;
- position?: string;
- top?: string;
- right?: string;
- bottom?: string;
- left?: string;
- width?: MediaChoice;
- height?: MediaChoice;
- maxWidth?: string;
- margin?: string;
- marginTop?: string;
- marginRight?: string;
- marginBottom?: string;
- marginLeft?: string;
- padding?: string;
- borderRadius?: MediaChoice;
- border?: string;
- borderColor?: ColorOption;
- borderTop?: string;
- borderBottom?: string;
- className?: string;
- backgroundColor?: ColorOption;
- rawBackgroundColor?: string;
- hasBoxShadow?: boolean;
- isHidden?: boolean;
- zIndex?: number;
- whiteSpace?: string;
- opacity?: number;
- cursor?: string;
- overflow?: string;
- darkenOnHover?: boolean;
- rawHoverColor?: string;
- boxShadowOnHover?: boolean;
- flexGrow?: string | number;
-}
-
-const getBackgroundColor = (theme: any, backgroundColor?: ColorOption, rawBackgroundColor?: string): string => {
- if (backgroundColor) {
- return theme[backgroundColor] as string;
- }
- if (rawBackgroundColor) {
- return rawBackgroundColor;
- }
- return 'none';
-};
-
-export const Container = styled.div<ContainerProps>`
- && {
- box-sizing: border-box;
- ${props => cssRuleIfExists(props, 'flex-grow')}
- ${props => cssRuleIfExists(props, 'position')}
- ${props => cssRuleIfExists(props, 'top')}
- ${props => cssRuleIfExists(props, 'right')}
- ${props => cssRuleIfExists(props, 'bottom')}
- ${props => cssRuleIfExists(props, 'left')}
- ${props => cssRuleIfExists(props, 'max-width')}
- ${props => cssRuleIfExists(props, 'margin')}
- ${props => cssRuleIfExists(props, 'margin-top')}
- ${props => cssRuleIfExists(props, 'margin-right')}
- ${props => cssRuleIfExists(props, 'margin-bottom')}
- ${props => cssRuleIfExists(props, 'margin-left')}
- ${props => cssRuleIfExists(props, 'padding')}
- ${props => cssRuleIfExists(props, 'border')}
- ${props => cssRuleIfExists(props, 'border-top')}
- ${props => cssRuleIfExists(props, 'border-bottom')}
- ${props => cssRuleIfExists(props, 'z-index')}
- ${props => cssRuleIfExists(props, 'white-space')}
- ${props => cssRuleIfExists(props, 'opacity')}
- ${props => cssRuleIfExists(props, 'cursor')}
- ${props => cssRuleIfExists(props, 'overflow')}
- ${props => (props.overflow === 'scroll' ? `-webkit-overflow-scrolling: touch` : '')};
- ${props => (props.hasBoxShadow ? `box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1)` : '')};
- ${props => props.display && stylesForMedia<string>('display', props.display)}
- ${props => props.width && stylesForMedia<string>('width', props.width)}
- ${props => props.height && stylesForMedia<string>('height', props.height)}
- ${props => props.borderRadius && stylesForMedia<string>('border-radius', props.borderRadius)}
- ${props => (props.isHidden ? 'visibility: hidden;' : '')}
- background-color: ${props => getBackgroundColor(props.theme, props.backgroundColor, props.rawBackgroundColor)};
- border-color: ${props => (props.borderColor ? props.theme[props.borderColor] : 'none')};
- &:hover {
- ${props => (props.rawHoverColor ? `background-color: ${props.rawHoverColor}` : '')}
- ${props =>
- props.darkenOnHover
- ? `background-color: ${
- props.backgroundColor ? darken(0.05, props.theme[props.backgroundColor]) : 'none'
- }`
- : ''};
- ${props => (props.boxShadowOnHover ? 'box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1)' : '')};
- }
- }
-`;
-
-Container.defaultProps = {
- display: 'block',
-};
-
-Container.displayName = 'Container';
diff --git a/packages/instant/src/components/ui/dropdown.tsx b/packages/instant/src/components/ui/dropdown.tsx
deleted file mode 100644
index 8788d3d59..000000000
--- a/packages/instant/src/components/ui/dropdown.tsx
+++ /dev/null
@@ -1,147 +0,0 @@
-import * as _ from 'lodash';
-import { transparentize } from 'polished';
-import * as React from 'react';
-
-import { ColorOption, completelyTransparent, ThemeConsumer } from '../../style/theme';
-import { zIndex } from '../../style/z_index';
-
-import { Container } from './container';
-import { Flex } from './flex';
-import { Icon } from './icon';
-import { Overlay } from './overlay';
-import { Text } from './text';
-
-export interface DropdownItemConfig {
- text: string;
- onClick?: () => void;
-}
-
-export interface DropdownProps {
- value: string;
- label?: string;
- items: DropdownItemConfig[];
- onOpen?: () => void;
-}
-
-export interface DropdownState {
- isOpen: boolean;
-}
-
-export class Dropdown extends React.PureComponent<DropdownProps, DropdownState> {
- public static defaultProps = {
- items: [],
- };
- public state: DropdownState = {
- isOpen: false,
- };
- public render(): React.ReactNode {
- const { value, label, items } = this.props;
- const { isOpen } = this.state;
- const hasItems = !_.isEmpty(items);
- const borderRadius = isOpen ? '4px 4px 0px 0px' : '4px';
- return (
- <React.Fragment>
- {isOpen && (
- <Overlay
- zIndex={zIndex.dropdownItems - 1}
- backgroundColor={completelyTransparent}
- onClick={this._closeDropdown}
- />
- )}
- <Container position="relative">
- <Container
- cursor={hasItems ? 'pointer' : undefined}
- onClick={this._handleDropdownClick}
- hasBoxShadow={isOpen}
- boxShadowOnHover={true}
- borderRadius={borderRadius}
- border="1px solid"
- borderColor={ColorOption.feintGrey}
- padding="0.8em"
- >
- <Flex justify="space-between">
- <Text fontSize="16px" fontColor={ColorOption.darkGrey}>
- {value}
- </Text>
- <Container>
- {label && (
- <Text fontSize="16px" fontColor={ColorOption.lightGrey}>
- {label}
- </Text>
- )}
- {hasItems && (
- <Container marginLeft="5px" display="inline-block" position="relative" bottom="2px">
- <Icon padding="3px" icon="chevron" width={12} stroke={ColorOption.grey} />
- </Container>
- )}
- </Container>
- </Flex>
- </Container>
- {isOpen && (
- <Container
- width="100%"
- position="absolute"
- onClick={this._closeDropdown}
- backgroundColor={ColorOption.white}
- hasBoxShadow={true}
- zIndex={zIndex.dropdownItems}
- >
- {_.map(items, (item, index) => (
- <DropdownItem key={item.text} {...item} isLast={index === items.length - 1} />
- ))}
- </Container>
- )}
- </Container>
- </React.Fragment>
- );
- }
- private readonly _handleDropdownClick = (): void => {
- if (_.isEmpty(this.props.items)) {
- return;
- }
- const isOpen = !this.state.isOpen;
- this.setState({
- isOpen,
- });
-
- if (isOpen && this.props.onOpen) {
- this.props.onOpen();
- }
- };
- private readonly _closeDropdown = (): void => {
- this.setState({
- isOpen: false,
- });
- };
-}
-
-export interface DropdownItemProps extends DropdownItemConfig {
- text: string;
- onClick?: () => void;
- isLast: boolean;
-}
-
-export const DropdownItem: React.StatelessComponent<DropdownItemProps> = ({ text, onClick, isLast }) => (
- <ThemeConsumer>
- {theme => (
- <Container
- onClick={onClick}
- cursor="pointer"
- rawHoverColor={transparentize(0.9, theme[ColorOption.primaryColor])}
- backgroundColor={ColorOption.white}
- padding="0.8em"
- borderTop="0"
- border="1px solid"
- borderRadius={isLast ? '0px 0px 4px 4px' : undefined}
- width="100%"
- borderColor={ColorOption.feintGrey}
- >
- <Text fontSize="14px" fontColor={ColorOption.darkGrey}>
- {text}
- </Text>
- </Container>
- )}
- </ThemeConsumer>
-);
-
-DropdownItem.displayName = 'DropdownItem';
diff --git a/packages/instant/src/components/ui/flex.tsx b/packages/instant/src/components/ui/flex.tsx
deleted file mode 100644
index 145e654f1..000000000
--- a/packages/instant/src/components/ui/flex.tsx
+++ /dev/null
@@ -1,38 +0,0 @@
-import { MediaChoice, stylesForMedia } from '../../style/media';
-import { ColorOption, styled } from '../../style/theme';
-import { cssRuleIfExists } from '../../style/util';
-
-export interface FlexProps {
- direction?: 'row' | 'column';
- flexWrap?: 'wrap' | 'nowrap';
- justify?: 'flex-start' | 'center' | 'space-around' | 'space-between' | 'space-evenly' | 'flex-end';
- align?: 'flex-start' | 'center' | 'space-around' | 'space-between' | 'space-evenly' | 'flex-end';
- width?: MediaChoice;
- height?: MediaChoice;
- backgroundColor?: ColorOption;
- inline?: boolean;
- flexGrow?: number | string;
-}
-
-export const Flex = styled.div<FlexProps>`
- && {
- display: ${props => (props.inline ? 'inline-flex' : 'flex')};
- flex-direction: ${props => props.direction};
- flex-wrap: ${props => props.flexWrap};
- ${props => cssRuleIfExists(props, 'flexGrow')}
- justify-content: ${props => props.justify};
- align-items: ${props => props.align};
- background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')};
- ${props => (props.width ? stylesForMedia('width', props.width) : '')}
- ${props => (props.height ? stylesForMedia('height', props.height) : '')}
- }
-`;
-
-Flex.defaultProps = {
- direction: 'row',
- flexWrap: 'nowrap',
- justify: 'center',
- align: 'center',
-};
-
-Flex.displayName = 'Flex';
diff --git a/packages/instant/src/components/ui/icon.tsx b/packages/instant/src/components/ui/icon.tsx
deleted file mode 100644
index 811142b5b..000000000
--- a/packages/instant/src/components/ui/icon.tsx
+++ /dev/null
@@ -1,129 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { ColorOption, styled, Theme, withTheme } from '../../style/theme';
-
-type svgRule = 'evenodd' | 'nonzero' | 'inherit';
-interface IconInfo {
- viewBox: string;
- path: string;
- fillRule?: svgRule;
- clipRule?: svgRule;
- strokeOpacity?: number;
- strokeWidth?: number;
- strokeLinecap?: 'butt' | 'round' | 'square' | 'inherit';
- strokeLinejoin?: 'miter' | 'round' | 'bevel' | 'inherit';
-}
-interface IconInfoMapping {
- closeX: IconInfo;
- failed: IconInfo;
- success: IconInfo;
- chevron: IconInfo;
- search: IconInfo;
- lock: IconInfo;
-}
-const ICONS: IconInfoMapping = {
- closeX: {
- viewBox: '0 0 11 11',
- fillRule: 'evenodd',
- clipRule: 'evenodd',
- path:
- 'M10.45 10.449C10.7539 10.1453 10.7539 9.65282 10.45 9.34909L6.60068 5.49999L10.45 1.65093C10.7538 1.3472 10.7538 0.854765 10.45 0.551038C10.1462 0.24731 9.65378 0.24731 9.34995 0.551038L5.50058 4.40006L1.65024 0.549939C1.34641 0.246212 0.853973 0.246212 0.550262 0.549939C0.246429 0.853667 0.246429 1.34611 0.550262 1.64983L4.40073 5.49995L0.55014 9.35019C0.246307 9.65392 0.246307 10.1464 0.55014 10.4501C0.853851 10.7538 1.34628 10.7538 1.65012 10.4501L5.5007 6.59987L9.35007 10.449C9.6539 10.7527 10.1463 10.7527 10.45 10.449Z',
- },
- failed: {
- viewBox: '0 0 34 34',
- fillRule: 'evenodd',
- clipRule: 'evenodd',
- path:
- 'M6.65771 26.4362C9.21777 29.2406 12.9033 31 17 31C24.7319 31 31 24.7319 31 17C31 14.4468 30.3164 12.0531 29.1226 9.99219L6.65771 26.4362ZM4.88281 24.0173C3.68555 21.9542 3 19.5571 3 17C3 9.26807 9.26807 3 17 3C21.1006 3 24.7891 4.76294 27.3496 7.57214L4.88281 24.0173ZM0 17C0 26.3888 7.61133 34 17 34C26.3887 34 34 26.3888 34 17C34 7.61121 26.3887 0 17 0C7.61133 0 0 7.61121 0 17Z',
- },
- success: {
- viewBox: '0 0 34 34',
- fillRule: 'evenodd',
- clipRule: 'evenodd',
- path:
- 'M17 34C26.3887 34 34 26.3888 34 17C34 7.61121 26.3887 0 17 0C7.61133 0 0 7.61121 0 17C0 26.3888 7.61133 34 17 34ZM25.7539 13.0977C26.2969 12.4718 26.2295 11.5244 25.6035 10.9817C24.9775 10.439 24.0303 10.5063 23.4878 11.1323L15.731 20.0771L12.3936 16.7438C11.8071 16.1583 10.8574 16.1589 10.272 16.7451C9.68652 17.3313 9.6875 18.281 10.2734 18.8665L14.75 23.3373L15.8887 24.4746L16.9434 23.2587L25.7539 13.0977Z',
- },
- chevron: {
- viewBox: '0 0 12 7',
- path: 'M11 1L6 6L1 1',
- strokeOpacity: 0.5,
- strokeWidth: 1.5,
- strokeLinecap: 'round',
- strokeLinejoin: 'round',
- },
- search: {
- viewBox: '0 0 14 14',
- fillRule: 'evenodd',
- clipRule: 'evenodd',
- path:
- 'M8.39404 5.19727C8.39404 6.96289 6.96265 8.39453 5.19702 8.39453C3.4314 8.39453 2 6.96289 2 5.19727C2 3.43164 3.4314 2 5.19702 2C6.96265 2 8.39404 3.43164 8.39404 5.19727ZM8.09668 9.51074C7.26855 10.0684 6.27075 10.3945 5.19702 10.3945C2.3269 10.3945 0 8.06738 0 5.19727C0 2.32715 2.3269 0 5.19702 0C8.06738 0 10.394 2.32715 10.394 5.19727C10.394 6.27051 10.0686 7.26855 9.51074 8.09668L13.6997 12.2861L12.2854 13.7002L8.09668 9.51074Z',
- },
- lock: {
- viewBox: '0 0 13 16',
- path:
- 'M6.47619 0C3.79509 0 1.60489 2.21216 1.60489 4.92014V6.33135C0.717479 6.33135 0 7.05602 0 7.95232V14.379C0 15.2753 0.717479 16 1.60489 16H11.3475C12.2349 16 12.9524 15.2753 12.9524 14.379V7.95232C12.9524 7.05602 12.2349 6.33135 11.3475 6.33135V4.92014C11.3475 2.21216 9.1573 0 6.47619 0ZM9.6482 6.33135H3.30418V4.92014C3.30418 3.16567 4.72026 1.71633 6.47619 1.71633C8.23213 1.71633 9.6482 3.16567 9.6482 4.92014V6.33135Z',
- },
-};
-
-export interface IconProps {
- className?: string;
- width: number;
- height?: number;
- color?: ColorOption;
- stroke?: ColorOption;
- icon: keyof IconInfoMapping;
- onClick?: (event: React.MouseEvent<HTMLElement>) => void;
- padding?: string;
- theme: Theme;
-}
-const PlainIcon: React.StatelessComponent<IconProps> = props => {
- const iconInfo = ICONS[props.icon];
- const colorValue = _.isUndefined(props.color) ? undefined : props.theme[props.color];
- const strokeValue = _.isUndefined(props.stroke) ? undefined : props.theme[props.stroke];
- return (
- <div onClick={props.onClick} className={props.className}>
- <svg
- width={props.width}
- height={props.height}
- viewBox={iconInfo.viewBox}
- fill="none"
- xmlns="http://www.w3.org/2000/svg"
- >
- <path
- d={iconInfo.path}
- fill={colorValue}
- fillRule={iconInfo.fillRule || 'nonzero'}
- clipRule={iconInfo.clipRule || 'nonzero'}
- stroke={strokeValue}
- strokeOpacity={iconInfo.strokeOpacity}
- strokeWidth={iconInfo.strokeWidth}
- strokeLinecap={iconInfo.strokeLinecap}
- strokeLinejoin={iconInfo.strokeLinejoin}
- />
- </svg>
- </div>
- );
-};
-
-export const Icon = withTheme(styled(PlainIcon)`
- && {
- display: inline-block;
- ${props => (!_.isUndefined(props.onClick) ? 'cursor: pointer' : '')};
- transition: opacity 0.5s ease;
- padding: ${props => props.padding};
- opacity: ${props => (!_.isUndefined(props.onClick) ? 0.7 : 1)};
- &:hover {
- opacity: 1;
- }
- &:active {
- opacity: 1;
- }
- }
-`);
-
-Icon.defaultProps = {
- padding: '0em 0em',
-};
-
-Icon.displayName = 'Icon';
diff --git a/packages/instant/src/components/ui/input.tsx b/packages/instant/src/components/ui/input.tsx
deleted file mode 100644
index 024e81b15..000000000
--- a/packages/instant/src/components/ui/input.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as React from 'react';
-
-import { ColorOption, styled } from '../../style/theme';
-
-export interface InputProps extends React.HTMLAttributes<HTMLInputElement> {
- tabIndex?: number;
- className?: string;
- value?: string;
- width?: string;
- fontSize?: string;
- fontColor?: ColorOption;
- placeholder?: string;
- type?: string;
- onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
-}
-
-export const Input = styled.input<InputProps>`
- && {
- all: initial;
- font-size: ${props => props.fontSize};
- width: ${props => props.width};
- padding: 0.1em 0em;
- font-family: 'Inter UI';
- color: ${props => props.theme[props.fontColor || 'white']};
- background: transparent;
- outline: none;
- border: none;
- &::placeholder {
- color: ${props => props.theme[props.fontColor || 'white']} !important;
- opacity: 0.5 !important;
- }
- &::-webkit-outer-spin-button,
- &::-webkit-inner-spin-button {
- -webkit-appearance: none;
- margin: 0;
- }
- }
-`;
-
-Input.defaultProps = {
- width: 'auto',
- fontColor: ColorOption.white,
- fontSize: '12px',
-};
-
-Input.displayName = 'Input';
diff --git a/packages/instant/src/components/ui/overlay.tsx b/packages/instant/src/components/ui/overlay.tsx
deleted file mode 100644
index 0b1be6a65..000000000
--- a/packages/instant/src/components/ui/overlay.tsx
+++ /dev/null
@@ -1,36 +0,0 @@
-import * as _ from 'lodash';
-
-import { generateMediaWrapper, ScreenWidths } from '../../style/media';
-import { generateOverlayBlack, styled } from '../../style/theme';
-import { zIndex } from '../../style/z_index';
-
-export interface OverlayProps {
- zIndex?: number;
- backgroundColor?: string;
- width?: string;
- height?: string;
- showMaxWidth?: ScreenWidths;
-}
-
-export const Overlay = styled.div<OverlayProps>`
- && {
- position: fixed;
- top: 0;
- right: 0;
- bottom: 0;
- left: 0;
- z-index: ${props => props.zIndex}
- background-color: ${props => props.backgroundColor};
- ${props => props.width && `width: ${props.width};`}
- ${props => props.height && `height: ${props.height};`}
- display: ${props => (props.showMaxWidth ? 'none' : 'block')};
- ${props => props.showMaxWidth && generateMediaWrapper(props.showMaxWidth)`display: block;`}
- }
-`;
-
-Overlay.defaultProps = {
- zIndex: zIndex.overlayDefault,
- backgroundColor: generateOverlayBlack(0.7),
-};
-
-Overlay.displayName = 'Overlay';
diff --git a/packages/instant/src/components/ui/spinner.tsx b/packages/instant/src/components/ui/spinner.tsx
deleted file mode 100644
index 28ebc2598..000000000
--- a/packages/instant/src/components/ui/spinner.tsx
+++ /dev/null
@@ -1,30 +0,0 @@
-import * as React from 'react';
-
-import { FullRotation } from '../animations/full_rotation';
-
-export interface SpinnerProps {
- widthPx: number;
- heightPx: number;
-}
-export const Spinner: React.StatelessComponent<SpinnerProps> = props => {
- return (
- <FullRotation width={`${props.widthPx}px`} height={`${props.heightPx}px`}>
- <svg
- width={props.widthPx}
- height={props.heightPx}
- viewBox="0 0 34 34"
- fill="none"
- xmlns="http://www.w3.org/2000/svg"
- >
- <circle cx="17" cy="17" r="15" stroke="white" strokeOpacity="0.2" strokeWidth="4" />
- <path
- d="M17 32C25.2843 32 32 25.2843 32 17C32 8.71573 25.2843 2 17 2"
- stroke="white"
- strokeWidth="4"
- strokeLinecap="round"
- strokeLinejoin="round"
- />
- </svg>
- </FullRotation>
- );
-};
diff --git a/packages/instant/src/components/ui/text.tsx b/packages/instant/src/components/ui/text.tsx
deleted file mode 100644
index ca120f3bd..000000000
--- a/packages/instant/src/components/ui/text.tsx
+++ /dev/null
@@ -1,71 +0,0 @@
-import * as React from 'react';
-
-import { ColorOption, styled } from '../../style/theme';
-import { util } from '../../util/util';
-
-export interface TextProps {
- fontColor?: ColorOption;
- fontFamily?: string;
- fontStyle?: string;
- fontSize?: string;
- opacity?: number;
- letterSpacing?: string;
- textAlign?: string;
- textTransform?: string;
- lineHeight?: string;
- className?: string;
- minHeight?: string;
- center?: boolean;
- fontWeight?: number | string;
- textDecorationLine?: string;
- onClick?: (event: React.MouseEvent<HTMLElement>) => void;
- noWrap?: boolean;
- display?: string;
- href?: string;
- width?: string;
-}
-
-export const Text: React.StatelessComponent<TextProps> = ({ href, onClick, ...rest }) => {
- const computedOnClick = href ? util.createOpenUrlInNewWindow(href) : onClick;
- return <StyledText {...rest} onClick={computedOnClick} />;
-};
-
-const opacityOnHoverAmount = 0.5;
-export const StyledText = styled.div<TextProps>`
- && {
- font-family: 'Inter UI', sans-serif;
- font-style: ${props => props.fontStyle};
- font-weight: ${props => props.fontWeight};
- font-size: ${props => props.fontSize};
- opacity: ${props => props.opacity};
- text-decoration-line: ${props => props.textDecorationLine};
- ${props => (props.lineHeight ? `line-height: ${props.lineHeight}` : '')};
- ${props => (props.center ? 'text-align: center' : '')};
- color: ${props => props.fontColor && props.theme[props.fontColor]};
- ${props => (props.minHeight ? `min-height: ${props.minHeight}` : '')};
- ${props => (props.onClick ? 'cursor: pointer' : '')};
- transition: color 0.5s ease;
- ${props => (props.noWrap ? 'white-space: nowrap' : '')};
- ${props => (props.display ? `display: ${props.display}` : '')};
- ${props => (props.letterSpacing ? `letter-spacing: ${props.letterSpacing}` : '')};
- ${props => (props.textTransform ? `text-transform: ${props.textTransform}` : '')};
- ${props => (props.textAlign ? `text-align: ${props.textAlign}` : '')};
- ${props => (props.width ? `width: ${props.width}` : '')};
- &:hover {
- ${props => (props.onClick ? `opacity: ${opacityOnHoverAmount};` : '')};
- }
- }
-`;
-
-Text.defaultProps = {
- fontFamily: 'Inter UI',
- fontStyle: 'normal',
- fontWeight: 400,
- fontColor: ColorOption.black,
- fontSize: '15px',
- textDecorationLine: 'none',
- noWrap: false,
- display: 'inline-block',
-};
-
-Text.displayName = 'Text';
diff --git a/packages/instant/src/components/wallet_prompt.tsx b/packages/instant/src/components/wallet_prompt.tsx
deleted file mode 100644
index 10433767f..000000000
--- a/packages/instant/src/components/wallet_prompt.tsx
+++ /dev/null
@@ -1,49 +0,0 @@
-import * as React from 'react';
-
-import { ColorOption } from '../style/theme';
-
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Text } from './ui/text';
-
-export interface WalletPromptProps {
- image: React.ReactNode;
- onClick?: () => void;
- primaryColor: ColorOption;
- secondaryColor: ColorOption;
-}
-
-export const WalletPrompt: React.StatelessComponent<WalletPromptProps> = ({
- onClick,
- image,
- children,
- secondaryColor,
- primaryColor,
-}) => (
- <Container
- padding="10px"
- border={`1px solid ${primaryColor}`}
- backgroundColor={secondaryColor}
- width="100%"
- borderRadius="4px"
- onClick={onClick}
- cursor={onClick ? 'pointer' : undefined}
- boxShadowOnHover={!!onClick}
- >
- <Flex>
- {image}
- <Container marginLeft="10px">
- <Text fontSize="16px" fontColor={primaryColor} fontWeight="500">
- {children}
- </Text>
- </Container>
- </Flex>
- </Container>
-);
-
-WalletPrompt.defaultProps = {
- primaryColor: ColorOption.darkOrange,
- secondaryColor: ColorOption.lightOrange,
-};
-
-WalletPrompt.displayName = 'WalletPrompt';
diff --git a/packages/instant/src/components/zero_ex_instant.tsx b/packages/instant/src/components/zero_ex_instant.tsx
deleted file mode 100644
index e9cb48e61..000000000
--- a/packages/instant/src/components/zero_ex_instant.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import * as React from 'react';
-
-import { ZeroExInstantContainer } from '../components/zero_ex_instant_container';
-
-import { INJECTED_DIV_CLASS } from '../constants';
-
-import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider';
-
-export type ZeroExInstantProps = ZeroExInstantProviderProps;
-
-export const ZeroExInstant: React.StatelessComponent<ZeroExInstantProps> = props => {
- return (
- <div className={INJECTED_DIV_CLASS}>
- <ZeroExInstantProvider {...props}>
- <ZeroExInstantContainer />
- </ZeroExInstantProvider>
- </div>
- );
-};
-
-ZeroExInstant.displayName = 'ZeroExInstant';
diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx
deleted file mode 100644
index e8c64d5d1..000000000
--- a/packages/instant/src/components/zero_ex_instant_container.tsx
+++ /dev/null
@@ -1,112 +0,0 @@
-import * as React from 'react';
-
-import PoweredByLogo from '../assets/powered_by_0x.svg';
-import { ZERO_EX_SITE_URL } from '../constants';
-import { AvailableERC20TokenSelector } from '../containers/available_erc20_token_selector';
-import { ConnectedBuyOrderProgressOrPaymentMethod } from '../containers/connected_buy_order_progress_or_payment_method';
-import { CurrentStandardSlidingPanel } from '../containers/current_standard_sliding_panel';
-import { LatestBuyQuoteOrderDetails } from '../containers/latest_buy_quote_order_details';
-import { LatestError } from '../containers/latest_error';
-import { SelectedAssetBuyOrderStateButtons } from '../containers/selected_asset_buy_order_state_buttons';
-import { SelectedAssetInstantHeading } from '../containers/selected_asset_instant_heading';
-import { ColorOption } from '../style/theme';
-import { zIndex } from '../style/z_index';
-import { SlideAnimationState } from '../types';
-import { analytics, TokenSelectorClosedVia } from '../util/analytics';
-
-import { CSSReset } from './css_reset';
-import { SlidingPanel } from './sliding_panel';
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-
-export interface ZeroExInstantContainerProps {}
-export interface ZeroExInstantContainerState {
- tokenSelectionPanelAnimationState: SlideAnimationState;
-}
-
-export class ZeroExInstantContainer extends React.PureComponent<
- ZeroExInstantContainerProps,
- ZeroExInstantContainerState
-> {
- public state = {
- tokenSelectionPanelAnimationState: 'none' as SlideAnimationState,
- };
- public render(): React.ReactNode {
- return (
- <React.Fragment>
- <CSSReset />
- <Container
- width={{ default: '350px', sm: '100%' }}
- height={{ default: 'auto', sm: '100%' }}
- position="relative"
- >
- <Container position="relative">
- <LatestError />
- </Container>
- <Container
- zIndex={zIndex.mainContainer}
- position="relative"
- backgroundColor={ColorOption.white}
- borderRadius={{ default: '3px', sm: '0px' }}
- hasBoxShadow={true}
- overflow="hidden"
- height="100%"
- >
- <Flex direction="column" justify="flex-start" height="100%">
- <SelectedAssetInstantHeading onSelectAssetClick={this._handleSymbolClick} />
- <ConnectedBuyOrderProgressOrPaymentMethod />
- <LatestBuyQuoteOrderDetails />
- <Container padding="20px" width="100%">
- <SelectedAssetBuyOrderStateButtons />
- </Container>
- </Flex>
- <SlidingPanel
- animationState={this.state.tokenSelectionPanelAnimationState}
- onClose={this._handlePanelCloseClickedX}
- onAnimationEnd={this._handleSlidingPanelAnimationEnd}
- >
- <AvailableERC20TokenSelector onTokenSelect={this._handlePanelCloseAfterChose} />
- </SlidingPanel>
- <CurrentStandardSlidingPanel />
- </Container>
- <Container
- display={{ sm: 'none', default: 'block' }}
- marginTop="10px"
- marginLeft="auto"
- marginRight="auto"
- width="108px"
- >
- <a href={ZERO_EX_SITE_URL} target="_blank">
- <PoweredByLogo />
- </a>
- </Container>
- </Container>
- </React.Fragment>
- );
- }
- private readonly _handleSymbolClick = (): void => {
- analytics.trackTokenSelectorOpened();
- this.setState({
- tokenSelectionPanelAnimationState: 'slidIn',
- });
- };
- private readonly _handlePanelCloseClickedX = (): void => {
- this._handlePanelClose(TokenSelectorClosedVia.ClickedX);
- };
- private readonly _handlePanelCloseAfterChose = (): void => {
- this._handlePanelClose(TokenSelectorClosedVia.TokenChose);
- };
- private readonly _handlePanelClose = (closedVia: TokenSelectorClosedVia): void => {
- analytics.trackTokenSelectorClosed(closedVia);
- this.setState({
- tokenSelectionPanelAnimationState: 'slidOut',
- });
- };
- private readonly _handleSlidingPanelAnimationEnd = (): void => {
- if (this.state.tokenSelectionPanelAnimationState === 'slidOut') {
- // When the slidOut animation completes, don't keep the panel mounted.
- // Performance optimization
- this.setState({ tokenSelectionPanelAnimationState: 'none' });
- }
- };
-}
diff --git a/packages/instant/src/components/zero_ex_instant_overlay.tsx b/packages/instant/src/components/zero_ex_instant_overlay.tsx
deleted file mode 100644
index 38a716091..000000000
--- a/packages/instant/src/components/zero_ex_instant_overlay.tsx
+++ /dev/null
@@ -1,53 +0,0 @@
-import * as React from 'react';
-
-import { ZeroExInstantContainer } from '../components/zero_ex_instant_container';
-import { MAIN_CONTAINER_DIV_CLASS, OVERLAY_CLOSE_BUTTON_DIV_CLASS, OVERLAY_DIV_CLASS } from '../constants';
-import { ColorOption } from '../style/theme';
-
-import { Container } from './ui/container';
-import { Flex } from './ui/flex';
-import { Icon } from './ui/icon';
-import { Overlay } from './ui/overlay';
-import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider';
-
-export interface ZeroExInstantOverlayProps extends ZeroExInstantProviderProps {
- onClose?: () => void;
- zIndex?: number;
-}
-
-export const ZeroExInstantOverlay: React.StatelessComponent<ZeroExInstantOverlayProps> = props => {
- const { onClose, zIndex, ...rest } = props;
- return (
- <ZeroExInstantProvider {...rest}>
- <Overlay zIndex={zIndex} className={OVERLAY_DIV_CLASS}>
- <Flex height="100vh">
- <Container
- className={OVERLAY_CLOSE_BUTTON_DIV_CLASS}
- position="absolute"
- top="0px"
- right="0px"
- display={{ default: 'initial', sm: 'none' }}
- >
- <Icon
- height={18}
- width={18}
- color={ColorOption.white}
- icon="closeX"
- onClick={onClose}
- padding="2em 2em"
- />
- </Container>
- <Container
- width={{ default: 'auto', sm: '100%' }}
- height={{ default: 'auto', sm: '100%' }}
- className={MAIN_CONTAINER_DIV_CLASS}
- >
- <ZeroExInstantContainer />
- </Container>
- </Flex>
- </Overlay>
- </ZeroExInstantProvider>
- );
-};
-
-ZeroExInstantOverlay.displayName = 'ZeroExInstantOverlay';
diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx
deleted file mode 100644
index ec8e82ee3..000000000
--- a/packages/instant/src/components/zero_ex_instant_provider.tsx
+++ /dev/null
@@ -1,156 +0,0 @@
-import { BigNumber } from '@0x/utils';
-import * as _ from 'lodash';
-import * as React from 'react';
-import { Provider as ReduxProvider } from 'react-redux';
-
-import { ACCOUNT_UPDATE_INTERVAL_TIME_MS, BUY_QUOTE_UPDATE_INTERVAL_TIME_MS } from '../constants';
-import { SelectedAssetThemeProvider } from '../containers/selected_asset_theme_provider';
-import { asyncData } from '../redux/async_data';
-import { DEFAULT_STATE, DefaultState, State } from '../redux/reducer';
-import { store, Store } from '../redux/store';
-import { fonts } from '../style/fonts';
-import { AccountState, Network, QuoteFetchOrigin, ZeroExInstantBaseConfig } from '../types';
-import { analytics, disableAnalytics } from '../util/analytics';
-import { assetUtils } from '../util/asset';
-import { errorFlasher } from '../util/error_flasher';
-import { setupRollbar } from '../util/error_reporter';
-import { gasPriceEstimator } from '../util/gas_price_estimator';
-import { Heartbeater } from '../util/heartbeater';
-import { generateAccountHeartbeater, generateBuyQuoteHeartbeater } from '../util/heartbeater_factory';
-import { providerStateFactory } from '../util/provider_state_factory';
-
-export type ZeroExInstantProviderProps = ZeroExInstantBaseConfig;
-
-export class ZeroExInstantProvider extends React.PureComponent<ZeroExInstantProviderProps> {
- private readonly _store: Store;
- private _accountUpdateHeartbeat?: Heartbeater;
- private _buyQuoteHeartbeat?: Heartbeater;
-
- // TODO(fragosti): Write tests for this beast once we inject a provider.
- private static _mergeDefaultStateWithProps(
- props: ZeroExInstantProviderProps,
- defaultState: DefaultState = DEFAULT_STATE,
- ): State {
- // use the networkId passed in with the props, otherwise default to that of the default state (1, mainnet)
- const networkId = props.networkId || defaultState.network;
- // construct the ProviderState
- const providerState = providerStateFactory.getInitialProviderState(
- props.orderSource,
- networkId,
- props.provider,
- props.walletDisplayName,
- );
- // merge the additional additionalAssetMetaDataMap with our default map
- const completeAssetMetaDataMap = {
- // Make sure the passed in assetDatas are lower case
- ..._.mapKeys(props.additionalAssetMetaDataMap || {}, (value, key) => key.toLowerCase()),
- ...defaultState.assetMetaDataMap,
- };
- // construct the final state
- const storeStateFromProps: State = {
- ...defaultState,
- providerState,
- network: networkId,
- walletDisplayName: props.walletDisplayName,
- selectedAsset: _.isUndefined(props.defaultSelectedAssetData)
- ? undefined
- : assetUtils.createAssetFromAssetDataOrThrow(
- props.defaultSelectedAssetData,
- completeAssetMetaDataMap,
- networkId,
- ),
- selectedAssetUnitAmount: _.isUndefined(props.defaultAssetBuyAmount)
- ? undefined
- : new BigNumber(props.defaultAssetBuyAmount),
- availableAssets: _.isUndefined(props.availableAssetDatas)
- ? undefined
- : assetUtils.createAssetsFromAssetDatas(props.availableAssetDatas, completeAssetMetaDataMap, networkId),
- assetMetaDataMap: completeAssetMetaDataMap,
- affiliateInfo: props.affiliateInfo,
- };
- return storeStateFromProps;
- }
- constructor(props: ZeroExInstantProviderProps) {
- super(props);
- setupRollbar();
- fonts.include();
- const initialAppState = ZeroExInstantProvider._mergeDefaultStateWithProps(this.props);
- this._store = store.create(initialAppState);
- }
- public componentDidMount(): void {
- const state = this._store.getState();
- const dispatch = this._store.dispatch;
- // tslint:disable-next-line:no-floating-promises
- asyncData.fetchEthPriceAndDispatchToStore(dispatch);
- // fetch available assets if none are specified
- if (_.isUndefined(state.availableAssets)) {
- // tslint:disable-next-line:no-floating-promises
- asyncData.fetchAvailableAssetDatasAndDispatchToStore(state, dispatch);
- }
- if (state.providerState.account.state !== AccountState.None) {
- this._accountUpdateHeartbeat = generateAccountHeartbeater({
- store: this._store,
- shouldPerformImmediatelyOnStart: true,
- });
- this._accountUpdateHeartbeat.start(ACCOUNT_UPDATE_INTERVAL_TIME_MS);
- }
-
- this._buyQuoteHeartbeat = generateBuyQuoteHeartbeater({
- store: this._store,
- shouldPerformImmediatelyOnStart: false,
- });
- this._buyQuoteHeartbeat.start(BUY_QUOTE_UPDATE_INTERVAL_TIME_MS);
- // Trigger first buyquote fetch
- // tslint:disable-next-line:no-floating-promises
- asyncData.fetchCurrentBuyQuoteAndDispatchToStore(state, dispatch, QuoteFetchOrigin.Manual, {
- updateSilently: false,
- });
- // warm up the gas price estimator cache just in case we can't
- // grab the gas price estimate when submitting the transaction
- // tslint:disable-next-line:no-floating-promises
- gasPriceEstimator.getGasInfoAsync();
- // tslint:disable-next-line:no-floating-promises
- this._flashErrorIfWrongNetwork();
-
- // Analytics
- disableAnalytics(this.props.shouldDisableAnalyticsTracking || false);
- analytics.addEventProperties(
- analytics.generateEventProperties(
- state.network,
- this.props.orderSource,
- state.providerState,
- window,
- state.selectedAsset,
- this.props.affiliateInfo,
- state.baseCurrency,
- ),
- );
- analytics.trackInstantOpened();
- }
- public componentWillUnmount(): void {
- if (this._accountUpdateHeartbeat) {
- this._accountUpdateHeartbeat.stop();
- }
- if (this._buyQuoteHeartbeat) {
- this._buyQuoteHeartbeat.stop();
- }
- }
- public render(): React.ReactNode {
- return (
- <ReduxProvider store={this._store}>
- <SelectedAssetThemeProvider>{this.props.children}</SelectedAssetThemeProvider>
- </ReduxProvider>
- );
- }
- private readonly _flashErrorIfWrongNetwork = async (): Promise<void> => {
- const msToShowError = 30000; // 30 seconds
- const state = this._store.getState();
- const network = state.network;
- const web3Wrapper = state.providerState.web3Wrapper;
- const networkOfProvider = await web3Wrapper.getNetworkIdAsync();
- if (network !== networkOfProvider) {
- const errorMessage = `Wrong network detected. Try switching to ${Network[network]}.`;
- errorFlasher.flashNewErrorMessage(this._store.dispatch, errorMessage, msToShowError);
- }
- };
-}