aboutsummaryrefslogtreecommitdiffstats
path: root/packages/instant/src/components
diff options
context:
space:
mode:
authorFrancesco Agosti <francesco.agosti93@gmail.com>2018-11-03 07:26:16 +0800
committerGitHub <noreply@github.com>2018-11-03 07:26:16 +0800
commit66261102de57e3bc86714577c021aa5c7e17c150 (patch)
tree2a146790ba3d0a632a23c7335a3dcbd9d5a8c881 /packages/instant/src/components
parentd0f20a4fd5d1ab563d4b1c941b55018da129334e (diff)
parent6748c36b033798de4eb56e5d4e49d1c4b4e7be1e (diff)
downloaddexon-sol-tools-66261102de57e3bc86714577c021aa5c7e17c150.tar
dexon-sol-tools-66261102de57e3bc86714577c021aa5c7e17c150.tar.gz
dexon-sol-tools-66261102de57e3bc86714577c021aa5c7e17c150.tar.bz2
dexon-sol-tools-66261102de57e3bc86714577c021aa5c7e17c150.tar.lz
dexon-sol-tools-66261102de57e3bc86714577c021aa5c7e17c150.tar.xz
dexon-sol-tools-66261102de57e3bc86714577c021aa5c7e17c150.tar.zst
dexon-sol-tools-66261102de57e3bc86714577c021aa5c7e17c150.zip
Merge pull request #1204 from 0xProject/feature/instant/maker-asset-datas-interface
[instant] Add `availableAssetDatas` to render method, fetch from asset-buyer if not specified, implement basic token selection
Diffstat (limited to 'packages/instant/src/components')
-rw-r--r--packages/instant/src/components/erc20_asset_amount_input.tsx46
-rw-r--r--packages/instant/src/components/erc20_token_selector.tsx107
-rw-r--r--packages/instant/src/components/instant_heading.tsx2
-rw-r--r--packages/instant/src/components/search_input.tsx26
-rw-r--r--packages/instant/src/components/sliding_panel.tsx24
-rw-r--r--packages/instant/src/components/ui/circle.tsx22
-rw-r--r--packages/instant/src/components/ui/container.tsx11
-rw-r--r--packages/instant/src/components/ui/icon.tsx23
-rw-r--r--packages/instant/src/components/ui/index.ts1
-rw-r--r--packages/instant/src/components/ui/overlay.tsx4
-rw-r--r--packages/instant/src/components/ui/text.tsx5
-rw-r--r--packages/instant/src/components/zero_ex_instant_container.tsx4
-rw-r--r--packages/instant/src/components/zero_ex_instant_provider.tsx32
13 files changed, 266 insertions, 41 deletions
diff --git a/packages/instant/src/components/erc20_asset_amount_input.tsx b/packages/instant/src/components/erc20_asset_amount_input.tsx
index 6fb8f60f0..6ad0e92e7 100644
--- a/packages/instant/src/components/erc20_asset_amount_input.tsx
+++ b/packages/instant/src/components/erc20_asset_amount_input.tsx
@@ -3,7 +3,7 @@ import * as _ from 'lodash';
import * as React from 'react';
import { ColorOption, transparentWhite } from '../style/theme';
-import { ERC20Asset } from '../types';
+import { ERC20Asset, SimpleHandler } from '../types';
import { assetUtils } from '../util/asset';
import { util } from '../util/util';
@@ -19,6 +19,7 @@ export interface ERC20AssetAmountInputProps {
startingFontSizePx: number;
fontColor?: ColorOption;
isDisabled: boolean;
+ numberOfAssetsAvailable?: number;
}
export interface ERC20AssetAmountInputState {
@@ -40,13 +41,14 @@ export class ERC20AssetAmountInput extends React.Component<ERC20AssetAmountInput
const { asset } = this.props;
return (
<Container whiteSpace="nowrap">
- {_.isUndefined(asset) ? this._renderBackupContent() : this._renderContentForAsset(asset)}
+ {_.isUndefined(asset) ? this._renderTokenSelectionContent() : this._renderContentForAsset(asset)}
</Container>
);
}
private readonly _renderContentForAsset = (asset: ERC20Asset): React.ReactNode => {
const { onChange, ...rest } = this.props;
const amountBorderBottom = this.props.isDisabled ? '' : `1px solid ${transparentWhite}`;
+ const onSymbolClick = this._generateSelectAssetClickHandler();
return (
<React.Fragment>
<Container borderBottom={amountBorderBottom} display="inline-block">
@@ -59,7 +61,6 @@ export class ERC20AssetAmountInput extends React.Component<ERC20AssetAmountInput
/>
</Container>
<Container
- cursor="pointer"
display="inline-block"
marginLeft="8px"
title={assetUtils.bestNameForAsset(asset, undefined)}
@@ -69,7 +70,7 @@ export class ERC20AssetAmountInput extends React.Component<ERC20AssetAmountInput
fontSize={`${this.state.currentFontSizePx}px`}
fontColor={ColorOption.white}
textTransform="uppercase"
- onClick={this._handleSymbolClick}
+ onClick={onSymbolClick}
>
{assetUtils.formattedSymbolForAsset(asset)}
</Text>
@@ -79,7 +80,14 @@ export class ERC20AssetAmountInput extends React.Component<ERC20AssetAmountInput
</React.Fragment>
);
};
- private readonly _renderBackupContent = (): React.ReactNode => {
+ 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
@@ -87,18 +95,21 @@ export class ERC20AssetAmountInput extends React.Component<ERC20AssetAmountInput
fontColor={ColorOption.white}
opacity={0.7}
fontWeight="500"
- onClick={this._handleSymbolClick}
+ onClick={this._generateSelectAssetClickHandler()}
>
- Select Token
+ {text}
</Text>
{this._renderChevronIcon()}
</Flex>
);
};
private readonly _renderChevronIcon = (): React.ReactNode => {
+ if (!this._areMultipleAssetsAvailable()) {
+ return null;
+ }
return (
- <Container marginLeft="5px" onClick={this._handleSymbolClick}>
- <Icon icon="chevron" width={12} />
+ <Container marginLeft="5px">
+ <Icon icon="chevron" width={12} onClick={this._handleSelectAssetClick} />
</Container>
);
};
@@ -110,9 +121,22 @@ export class ERC20AssetAmountInput extends React.Component<ERC20AssetAmountInput
currentFontSizePx: fontSizePx,
});
};
- private readonly _handleSymbolClick = () => {
+ 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._areMultipleAssetsAvailable() || _.isUndefined(this.props.onSelectAssetClick)) {
+ return undefined;
+ }
+ return this._handleSelectAssetClick;
+ };
+ private readonly _areMultipleAssetsAvailable = (): boolean => {
+ const { numberOfAssetsAvailable } = this.props;
+ return !_.isUndefined(numberOfAssetsAvailable) && numberOfAssetsAvailable > 1;
+ };
+ private readonly _handleSelectAssetClick = (): void => {
if (this.props.onSelectAssetClick) {
- this.props.onSelectAssetClick(this.props.asset);
+ this.props.onSelectAssetClick();
}
};
// For assets with symbols of different length,
diff --git a/packages/instant/src/components/erc20_token_selector.tsx b/packages/instant/src/components/erc20_token_selector.tsx
new file mode 100644
index 000000000..481778495
--- /dev/null
+++ b/packages/instant/src/components/erc20_token_selector.tsx
@@ -0,0 +1,107 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { ColorOption } from '../style/theme';
+import { ERC20Asset } from '../types';
+import { assetUtils } from '../util/asset';
+
+import { SearchInput } from './search_input';
+import { Circle, Container, Flex, Text } from './ui';
+
+export interface ERC20TokenSelectorProps {
+ tokens: ERC20Asset[];
+ onTokenSelect: (token: ERC20Asset) => void;
+}
+
+export interface ERC20TokenSelectorState {
+ searchQuery?: string;
+}
+
+export class ERC20TokenSelector extends React.Component<ERC20TokenSelectorProps> {
+ public state: ERC20TokenSelectorState = {
+ searchQuery: undefined,
+ };
+ public render(): React.ReactNode {
+ const { tokens, onTokenSelect } = this.props;
+ return (
+ <Container>
+ <SearchInput
+ placeholder="Search tokens..."
+ width="100%"
+ value={this.state.searchQuery}
+ onChange={this._handleSearchInputChange}
+ />
+ <Container overflow="scroll" height="275px" marginTop="10px">
+ {_.map(tokens, token => {
+ if (!this._isTokenQueryMatch(token)) {
+ return null;
+ }
+ return <TokenSelectorRow key={token.assetData} token={token} onClick={onTokenSelect} />;
+ })}
+ </Container>
+ </Container>
+ );
+ }
+ private readonly _handleSearchInputChange = (event: React.ChangeEvent<HTMLInputElement>): void => {
+ const searchQuery = event.target.value;
+ this.setState({
+ searchQuery,
+ });
+ };
+ private readonly _isTokenQueryMatch = (token: ERC20Asset): boolean => {
+ const { searchQuery } = this.state;
+ if (_.isUndefined(searchQuery)) {
+ return true;
+ }
+ const stringToSearch = `${token.metaData.name} ${token.metaData.symbol}`;
+ return _.includes(stringToSearch.toLowerCase(), searchQuery.toLowerCase());
+ };
+}
+
+interface TokenSelectorRowProps {
+ token: ERC20Asset;
+ onClick: (token: ERC20Asset) => void;
+}
+
+class TokenSelectorRow extends React.Component<TokenSelectorRowProps> {
+ public render(): React.ReactNode {
+ const { token } = this.props;
+ 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={30} fillColor={token.metaData.primaryColor}>
+ <Flex height="100%">
+ <Text fontColor={ColorOption.white} fontSize="8px">
+ {displaySymbol}
+ </Text>
+ </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);
+ };
+}
diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx
index 19c08db70..80d7a3ee2 100644
--- a/packages/instant/src/components/instant_heading.tsx
+++ b/packages/instant/src/components/instant_heading.tsx
@@ -22,7 +22,7 @@ export interface InstantHeadingProps {
const PLACEHOLDER_COLOR = ColorOption.white;
const ICON_WIDTH = 34;
const ICON_HEIGHT = 34;
-const ICON_COLOR = 'white';
+const ICON_COLOR = ColorOption.white;
export class InstantHeading extends React.Component<InstantHeadingProps, {}> {
public render(): React.ReactNode {
diff --git a/packages/instant/src/components/search_input.tsx b/packages/instant/src/components/search_input.tsx
new file mode 100644
index 000000000..f082eaa16
--- /dev/null
+++ b/packages/instant/src/components/search_input.tsx
@@ -0,0 +1,26 @@
+import * as _ from 'lodash';
+import * as React from 'react';
+
+import { ColorOption } from '../style/theme';
+
+import { Container, Flex, Icon, Input, InputProps } from './ui';
+
+export interface SearchInputProps extends InputProps {
+ backgroundColor?: ColorOption;
+}
+
+export const SearchInput: React.StatelessComponent<SearchInputProps> = props => (
+ <Container backgroundColor={props.backgroundColor} borderRadius="3px" padding=".5em .3em">
+ <Flex justify="flex-start" align="flex-end">
+ <Icon width={14} height={14} icon="search" color={ColorOption.lightGrey} padding="0px 12px" />
+ <Input {...props} fontSize="14px" fontColor={props.fontColor} />
+ </Flex>
+ </Container>
+);
+
+SearchInput.displayName = 'SearchInput';
+
+SearchInput.defaultProps = {
+ backgroundColor: ColorOption.lightestGrey,
+ fontColor: ColorOption.grey,
+};
diff --git a/packages/instant/src/components/sliding_panel.tsx b/packages/instant/src/components/sliding_panel.tsx
index 9219ad1f1..ea1d6b9a1 100644
--- a/packages/instant/src/components/sliding_panel.tsx
+++ b/packages/instant/src/components/sliding_panel.tsx
@@ -5,18 +5,28 @@ import { zIndex } from '../style/z_index';
import { PositionAnimationSettings } from './animations/position_animation';
import { SlideAnimation, SlideAnimationState } from './animations/slide_animation';
-import { Button, Container, Text } from './ui';
+import { Container, Flex, Icon, Text } from './ui';
export interface PanelProps {
+ title?: string;
onClose?: () => void;
}
-export const Panel: React.StatelessComponent<PanelProps> = ({ children, onClose }) => (
- <Container backgroundColor={ColorOption.white} width="100%" height="100%" zIndex={zIndex.panel}>
- <Button onClick={onClose}>
- <Text fontColor={ColorOption.white}>Close </Text>
- </Button>
- {children}
+export const Panel: React.StatelessComponent<PanelProps> = ({ title, children, onClose }) => (
+ <Container backgroundColor={ColorOption.white} width="100%" height="100%" zIndex={zIndex.panel} padding="20px">
+ <Flex justify="space-between">
+ {title && (
+ <Container marginTop="3px">
+ <Text fontColor={ColorOption.darkGrey} fontSize="18px" fontWeight="600" lineHeight="22px">
+ {title}
+ </Text>
+ </Container>
+ )}
+ <Container position="relative" bottom="7px">
+ <Icon width={12} color={ColorOption.lightGrey} icon="closeX" onClick={onClose} />
+ </Container>
+ </Flex>
+ <Container marginTop="10px">{children}</Container>
</Container>
);
diff --git a/packages/instant/src/components/ui/circle.tsx b/packages/instant/src/components/ui/circle.tsx
new file mode 100644
index 000000000..eec2777d2
--- /dev/null
+++ b/packages/instant/src/components/ui/circle.tsx
@@ -0,0 +1,22 @@
+import { styled } from '../../style/theme';
+
+export interface CircleProps {
+ diameter: number;
+ fillColor?: string;
+}
+
+export const Circle =
+ styled.div <
+ CircleProps >
+ `
+ width: ${props => props.diameter}px;
+ height: ${props => props.diameter}px;
+ background-color: ${props => props.fillColor};
+ border-radius: 50%;
+`;
+
+Circle.displayName = 'Circle';
+
+Circle.defaultProps = {
+ fillColor: 'white',
+};
diff --git a/packages/instant/src/components/ui/container.tsx b/packages/instant/src/components/ui/container.tsx
index 7b8642761..a0a187e5f 100644
--- a/packages/instant/src/components/ui/container.tsx
+++ b/packages/instant/src/components/ui/container.tsx
@@ -1,3 +1,5 @@
+import { darken } from 'polished';
+
import { ColorOption, styled } from '../../style/theme';
import { cssRuleIfExists } from '../../style/util';
@@ -30,6 +32,7 @@ export interface ContainerProps {
opacity?: number;
cursor?: string;
overflow?: string;
+ darkenOnHover?: boolean;
}
export const Container =
@@ -64,6 +67,14 @@ export const Container =
${props => (props.hasBoxShadow ? `box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1)` : '')};
background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')};
border-color: ${props => (props.borderColor ? props.theme[props.borderColor] : 'none')};
+ &:hover {
+ ${props =>
+ props.darkenOnHover
+ ? `background-color: ${
+ props.backgroundColor ? darken(0.05, props.theme[props.backgroundColor]) : 'none'
+ }`
+ : ''};
+ }
`;
Container.defaultProps = {
diff --git a/packages/instant/src/components/ui/icon.tsx b/packages/instant/src/components/ui/icon.tsx
index f12059cff..94ea26900 100644
--- a/packages/instant/src/components/ui/icon.tsx
+++ b/packages/instant/src/components/ui/icon.tsx
@@ -1,7 +1,7 @@
import * as _ from 'lodash';
import * as React from 'react';
-import { styled } from '../../style/theme';
+import { ColorOption, styled, Theme, withTheme } from '../../style/theme';
type svgRule = 'evenodd' | 'nonzero' | 'inherit';
interface IconInfo {
@@ -20,6 +20,7 @@ interface IconInfoMapping {
failed: IconInfo;
success: IconInfo;
chevron: IconInfo;
+ search: IconInfo;
}
const ICONS: IconInfoMapping = {
closeX: {
@@ -52,19 +53,28 @@ const ICONS: IconInfoMapping = {
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',
+ },
};
export interface IconProps {
className?: string;
width: number;
height?: number;
- color?: string;
+ color?: ColorOption;
icon: keyof IconInfoMapping;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
padding?: string;
+ theme: Theme;
}
-const PlainIcon: React.SFC<IconProps> = props => {
+const PlainIcon: React.StatelessComponent<IconProps> = props => {
const iconInfo = ICONS[props.icon];
+ const colorValue = _.isUndefined(props.color) ? undefined : props.theme[props.color];
return (
<div onClick={props.onClick} className={props.className}>
<svg
@@ -76,7 +86,7 @@ const PlainIcon: React.SFC<IconProps> = props => {
>
<path
d={iconInfo.path}
- fill={props.color}
+ fill={colorValue}
fillRule={iconInfo.fillRule || 'nonzero'}
clipRule={iconInfo.clipRule || 'nonzero'}
stroke={iconInfo.stroke}
@@ -90,7 +100,7 @@ const PlainIcon: React.SFC<IconProps> = props => {
);
};
-export const Icon = styled(PlainIcon)`
+export const Icon = withTheme(styled(PlainIcon)`
cursor: ${props => (!_.isUndefined(props.onClick) ? 'pointer' : 'default')};
transition: opacity 0.5s ease;
padding: ${props => props.padding};
@@ -101,10 +111,9 @@ export const Icon = styled(PlainIcon)`
&:active {
opacity: 1;
}
-`;
+`);
Icon.defaultProps = {
- color: 'white',
padding: '0em 0em',
};
diff --git a/packages/instant/src/components/ui/index.ts b/packages/instant/src/components/ui/index.ts
index 0efabdb85..87f5c11a1 100644
--- a/packages/instant/src/components/ui/index.ts
+++ b/packages/instant/src/components/ui/index.ts
@@ -1,4 +1,5 @@
export { Text, TextProps, Title } from './text';
+export { Circle, CircleProps } from './circle';
export { Button, ButtonProps } from './button';
export { Flex, FlexProps } from './flex';
export { Container, ContainerProps } from './container';
diff --git a/packages/instant/src/components/ui/overlay.tsx b/packages/instant/src/components/ui/overlay.tsx
index c5258b031..f1706c874 100644
--- a/packages/instant/src/components/ui/overlay.tsx
+++ b/packages/instant/src/components/ui/overlay.tsx
@@ -1,7 +1,7 @@
import * as _ from 'lodash';
import * as React from 'react';
-import { overlayBlack, styled } from '../../style/theme';
+import { ColorOption, overlayBlack, styled } from '../../style/theme';
import { Container } from './container';
import { Flex } from './flex';
@@ -16,7 +16,7 @@ export interface OverlayProps {
const PlainOverlay: React.StatelessComponent<OverlayProps> = ({ children, className, onClose }) => (
<Flex height="100vh" className={className}>
<Container position="absolute" top="0px" right="0px">
- <Icon height={18} width={18} color="white" icon="closeX" onClick={onClose} padding="2em 2em" />
+ <Icon height={18} width={18} color={ColorOption.white} icon="closeX" onClick={onClose} padding="2em 2em" />
</Container>
<div>{children}</div>
</Flex>
diff --git a/packages/instant/src/components/ui/text.tsx b/packages/instant/src/components/ui/text.tsx
index fd72f6cc8..cba6e7b20 100644
--- a/packages/instant/src/components/ui/text.tsx
+++ b/packages/instant/src/components/ui/text.tsx
@@ -18,7 +18,6 @@ export interface TextProps {
fontWeight?: number | string;
textDecorationLine?: string;
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
- hoverColor?: string;
noWrap?: boolean;
display?: string;
}
@@ -46,9 +45,7 @@ export const Text =
${props => (props.textTransform ? `text-transform: ${props.textTransform}` : '')};
&:hover {
${props =>
- props.onClick
- ? `color: ${props.hoverColor || darken(darkenOnHoverAmount, props.theme[props.fontColor || 'white'])}`
- : ''};
+ props.onClick ? `color: ${darken(darkenOnHoverAmount, props.theme[props.fontColor || 'white'])}` : ''};
}
`;
diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx
index f8e3935fb..c1bd17502 100644
--- a/packages/instant/src/components/zero_ex_instant_container.tsx
+++ b/packages/instant/src/components/zero_ex_instant_container.tsx
@@ -1,5 +1,6 @@
import * as React from 'react';
+import { AvailableERC20TokenSelector } from '../containers/available_erc20_token_selector';
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';
@@ -45,10 +46,11 @@ export class ZeroExInstantContainer extends React.Component<ZeroExInstantContain
</Container>
</Flex>
<SlidingPanel
+ title="Select Token"
animationState={this.state.tokenSelectionPanelAnimationState}
onClose={this._handlePanelClose}
>
- Select Your Token
+ <AvailableERC20TokenSelector onTokenSelect={this._handlePanelClose} />
</SlidingPanel>
</Container>
</Container>
diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx
index fe4d37331..0b9408329 100644
--- a/packages/instant/src/components/zero_ex_instant_provider.tsx
+++ b/packages/instant/src/components/zero_ex_instant_provider.tsx
@@ -25,14 +25,14 @@ export type ZeroExInstantProviderProps = ZeroExInstantProviderRequiredProps &
Partial<ZeroExInstantProviderOptionalProps>;
export interface ZeroExInstantProviderRequiredProps {
- // TODO: Change API when we allow the selection of different assetDatas
- assetData: string;
- liquiditySource: string | SignedOrder[];
+ orderSource: string | SignedOrder[];
}
export interface ZeroExInstantProviderOptionalProps {
provider: Provider;
+ availableAssetDatas: string[];
defaultAssetBuyAmount: number;
+ defaultSelectedAssetData: string;
additionalAssetMetaDataMap: ObjectMap<AssetMetaData>;
networkId: Network;
affiliateInfo: AffiliateInfo;
@@ -40,6 +40,7 @@ export interface ZeroExInstantProviderOptionalProps {
export class ZeroExInstantProvider extends React.Component<ZeroExInstantProviderProps> {
private readonly _store: Store;
+ // TODO(fragosti): Write tests for this beast once we inject a provider.
private static _mergeInitialStateWithProps(props: ZeroExInstantProviderProps, state: State = INITIAL_STATE): State {
const networkId = props.networkId || state.network;
// TODO: Proper wallet connect flow
@@ -48,14 +49,14 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
networkId,
};
let assetBuyer;
- if (_.isString(props.liquiditySource)) {
+ if (_.isString(props.orderSource)) {
assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl(
provider,
- props.liquiditySource,
+ props.orderSource,
assetBuyerOptions,
);
} else {
- assetBuyer = AssetBuyer.getAssetBuyerForProvidedOrders(provider, props.liquiditySource, assetBuyerOptions);
+ assetBuyer = AssetBuyer.getAssetBuyerForProvidedOrders(provider, props.orderSource, assetBuyerOptions);
}
const completeAssetMetaDataMap = {
...props.additionalAssetMetaDataMap,
@@ -65,10 +66,19 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
...state,
assetBuyer,
network: networkId,
- selectedAsset: assetUtils.createAssetFromAssetData(props.assetData, completeAssetMetaDataMap, networkId),
+ selectedAsset: _.isUndefined(props.defaultSelectedAssetData)
+ ? undefined
+ : assetUtils.createAssetFromAssetDataOrThrow(
+ props.defaultSelectedAssetData,
+ completeAssetMetaDataMap,
+ networkId,
+ ),
selectedAssetAmount: _.isUndefined(props.defaultAssetBuyAmount)
? state.selectedAssetAmount
: new BigNumber(props.defaultAssetBuyAmount),
+ availableAssets: _.isUndefined(props.availableAssetDatas)
+ ? undefined
+ : assetUtils.createAssetsFromAssetDatas(props.availableAssetDatas, completeAssetMetaDataMap, networkId),
assetMetaDataMap: completeAssetMetaDataMap,
affiliateInfo: props.affiliateInfo,
};
@@ -81,8 +91,14 @@ export class ZeroExInstantProvider extends React.Component<ZeroExInstantProvider
}
public componentDidMount(): void {
+ const state = this._store.getState();
// tslint:disable-next-line:no-floating-promises
- asyncData.fetchAndDispatchToStore(this._store);
+ asyncData.fetchEthPriceAndDispatchToStore(this._store);
+ // fetch available assets if none are specified
+ if (_.isUndefined(state.availableAssets)) {
+ // tslint:disable-next-line:no-floating-promises
+ asyncData.fetchAvailableAssetDatasAndDispatchToStore(this._store);
+ }
// warm up the gas price estimator cache just in case we can't
// grab the gas price estimate when submitting the transaction