From 02a975dde45ba879627975ac836956b679a1a0ac Mon Sep 17 00:00:00 2001 From: fragosti Date: Mon, 29 Oct 2018 13:17:16 -0700 Subject: feat: add augur provided order --- .../instant/src/containers/selected_erc20_asset_amount_input.ts | 1 + packages/instant/src/data/asset_data_network_mapping.ts | 4 ++++ packages/instant/src/data/asset_meta_data_map.ts | 6 ++++++ 3 files changed, 11 insertions(+) (limited to 'packages/instant/src') diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index 4767b15d4..ad3aa9582 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -78,6 +78,7 @@ const updateBuyQuoteAsync = async ( try { newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue); } catch (error) { + console.log(error); dispatch(actions.setQuoteRequestStateFailure()); let errorMessage; if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { diff --git a/packages/instant/src/data/asset_data_network_mapping.ts b/packages/instant/src/data/asset_data_network_mapping.ts index e8ccbf011..28a04eb8a 100644 --- a/packages/instant/src/data/asset_data_network_mapping.ts +++ b/packages/instant/src/data/asset_data_network_mapping.ts @@ -12,4 +12,8 @@ export const assetDataNetworkMapping: AssetDataByNetwork[] = [ [Network.Mainnet]: '0xf47261b0000000000000000000000000e41d2489571d322189246dafa5ebde1f4699f498', [Network.Kovan]: '0xf47261b00000000000000000000000002002d3812f58e35f0ea1ffbf80a75a38c32175fa', }, + { + [Network.Kovan]: '0xf47261b00000000000000000000000008cb3971b8eb709c14616bd556ff6683019e90d9c', + [Network.Mainnet]: '0xf47261b0000000000000000000000000e94327d07fc17907b4db788e5adf2ed424addff6', + }, ]; diff --git a/packages/instant/src/data/asset_meta_data_map.ts b/packages/instant/src/data/asset_meta_data_map.ts index 3a820a0c4..4e6e15d38 100644 --- a/packages/instant/src/data/asset_meta_data_map.ts +++ b/packages/instant/src/data/asset_meta_data_map.ts @@ -11,4 +11,10 @@ export const assetMetaDataMap: ObjectMap = { primaryColor: 'rgb(54, 50, 60)', symbol: 'zrx', }, + '0xf47261b0000000000000000000000000e94327d07fc17907b4db788e5adf2ed424addff6': { + assetProxyId: AssetProxyId.ERC20, + decimals: 18, + primaryColor: '#512D80', + symbol: 'rep', + }, }; -- cgit From 25ca3d4c29ad98b75e256424246a38a72e5a26da Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Mon, 29 Oct 2018 12:51:38 -0700 Subject: feat(instant): add default gasPrice of 6 gwei to transactions --- packages/instant/src/components/buy_button.tsx | 5 +++-- packages/instant/src/constants.ts | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 129aedaf3..e65e62e47 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -2,7 +2,7 @@ import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; import * as _ from 'lodash'; import * as React from 'react'; -import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants'; +import { DEFAULT_GAS_PRICE, WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants'; import { ColorOption } from '../style/theme'; import { ZeroExInstantError } from '../types'; import { getBestAddress } from '../util/address'; @@ -57,7 +57,8 @@ export class BuyButton extends React.Component { let txHash: string | undefined; try { - txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { takerAddress }); + const gasPrice = DEFAULT_GAS_PRICE; + txHash = await assetBuyer.executeBuyQuoteAsync(buyQuote, { gasPrice, takerAddress }); } catch (e) { if (e instanceof Error) { if (e.message === AssetBuyerError.SignatureRequestDenied) { diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index e4281d54a..47cb2eaeb 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -3,3 +3,5 @@ export const BIG_NUMBER_ZERO = new BigNumber(0); export const ETH_DECIMALS = 18; export const DEFAULT_ZERO_EX_CONTAINER_SELECTOR = '#zeroExInstantContainer'; export const WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX = 'Transaction failed'; +export const GWEI_IN_WEI = new BigNumber(1000000000); +export const DEFAULT_GAS_PRICE = GWEI_IN_WEI.mul(6); -- cgit From ac72df41883af261b8661cb5f52c01567a6aad62 Mon Sep 17 00:00:00 2001 From: fragosti Date: Mon, 29 Oct 2018 15:30:25 -0700 Subject: chore: remove console log --- packages/instant/src/containers/selected_erc20_asset_amount_input.ts | 1 - 1 file changed, 1 deletion(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts index ad3aa9582..4767b15d4 100644 --- a/packages/instant/src/containers/selected_erc20_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_erc20_asset_amount_input.ts @@ -78,7 +78,6 @@ const updateBuyQuoteAsync = async ( try { newBuyQuote = await assetBuyer.getBuyQuoteAsync(asset.assetData, baseUnitValue); } catch (error) { - console.log(error); dispatch(actions.setQuoteRequestStateFailure()); let errorMessage; if (error.message === AssetBuyerError.InsufficientAssetLiquidity) { -- cgit From c1ad1d203dcb9041e15bfb4f0d5fa9ab60ed9486 Mon Sep 17 00:00:00 2001 From: fragosti Date: Wed, 31 Oct 2018 14:15:03 -0700 Subject: chore: remove unused import --- packages/instant/src/components/buy_button.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx index 58575b1b3..93bd8e635 100644 --- a/packages/instant/src/components/buy_button.tsx +++ b/packages/instant/src/components/buy_button.tsx @@ -2,7 +2,7 @@ import { AssetBuyer, AssetBuyerError, BuyQuote } from '@0x/asset-buyer'; import * as _ from 'lodash'; import * as React from 'react'; -import { DEFAULT_GAS_PRICE, WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants'; +import { WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX } from '../constants'; import { ColorOption } from '../style/theme'; import { ZeroExInstantError } from '../types'; import { getBestAddress } from '../util/address'; -- cgit From c2645b26b457c66b3adcb98a5c089eba3e72f458 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Wed, 31 Oct 2018 15:09:12 -0700 Subject: feat(instant): add interactive overlay presentation to umd bundle --- packages/instant/src/components/ui/button.tsx | 20 +++- packages/instant/src/components/ui/icon.tsx | 8 ++ packages/instant/src/components/ui/index.ts | 5 +- packages/instant/src/components/ui/overlay.tsx | 49 +++++++++ .../instant/src/components/zero_ex_instant.tsx | 115 ++------------------- .../src/components/zero_ex_instant_overlay.tsx | 21 ++++ .../src/components/zero_ex_instant_provider.tsx | 108 +++++++++++++++++++ packages/instant/src/constants.ts | 1 + packages/instant/src/index.ts | 1 + packages/instant/src/index.umd.ts | 39 +++++-- packages/instant/src/style/theme.ts | 3 + 11 files changed, 250 insertions(+), 120 deletions(-) create mode 100644 packages/instant/src/components/ui/overlay.tsx create mode 100644 packages/instant/src/components/zero_ex_instant_overlay.tsx create mode 100644 packages/instant/src/components/zero_ex_instant_provider.tsx (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/ui/button.tsx b/packages/instant/src/components/ui/button.tsx index 5274d835b..0051482e7 100644 --- a/packages/instant/src/components/ui/button.tsx +++ b/packages/instant/src/components/ui/button.tsx @@ -3,6 +3,11 @@ import * as React from 'react'; import { ColorOption, styled } from '../../style/theme'; +export enum ButtonHoverStyle { + Darken = 0, + Opacity, +} + export interface ButtonProps { backgroundColor?: ColorOption; borderColor?: ColorOption; @@ -12,6 +17,7 @@ export interface ButtonProps { isDisabled?: boolean; onClick?: (event: React.MouseEvent) => void; className?: string; + hoverStyle?: ButtonHoverStyle; } const PlainButton: React.StatelessComponent = ({ children, isDisabled, onClick, type, className }) => ( @@ -32,30 +38,38 @@ export const Button = styled(PlainButton)` 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')}; + opacity: ${props => (props.hoverStyle === ButtonHoverStyle.Opacity ? 0.7 : 1)}; &:hover { background-color: ${props => - !props.isDisabled + shouldDarken(props) ? darken(darkenOnHoverAmount, props.theme[props.backgroundColor || 'white']) : ''} !important; + opacity: 1; } &:active { background-color: ${props => - !props.isDisabled ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; + shouldDarken(props) ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; + opacity: 1; } &:disabled { - opacity: 0.5; + opacity: ${props => (props.hoverStyle === ButtonHoverStyle.Darken ? 0.5 : 0.2)}; } &:focus { background-color: ${props => saturate(saturateOnFocusAmount, props.theme[props.backgroundColor || 'white'])}; } `; +const shouldDarken = (props: ButtonProps) => { + return !props.isDisabled && props.hoverStyle === ButtonHoverStyle.Darken; +}; + Button.defaultProps = { backgroundColor: ColorOption.primaryColor, borderColor: ColorOption.primaryColor, width: 'auto', isDisabled: false, padding: '1em 2.2em', + hoverStyle: ButtonHoverStyle.Darken, }; Button.displayName = 'Button'; diff --git a/packages/instant/src/components/ui/icon.tsx b/packages/instant/src/components/ui/icon.tsx index 61b382760..a05017ba1 100644 --- a/packages/instant/src/components/ui/icon.tsx +++ b/packages/instant/src/components/ui/icon.tsx @@ -13,11 +13,19 @@ interface IconInfo { strokeLinejoin?: 'miter' | 'round' | 'bevel' | 'inherit'; } interface IconInfoMapping { + closeX: IconInfo; failed: IconInfo; success: IconInfo; chevron: 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', diff --git a/packages/instant/src/components/ui/index.ts b/packages/instant/src/components/ui/index.ts index 28f76c262..c60b9640e 100644 --- a/packages/instant/src/components/ui/index.ts +++ b/packages/instant/src/components/ui/index.ts @@ -1,7 +1,8 @@ -export { Text, Title } from './text'; -export { Button, ButtonProps } from './button'; +export { Text, TextProps, Title } from './text'; +export { Button, ButtonProps, ButtonHoverStyle } from './button'; export { Flex, FlexProps } from './flex'; export { Container, ContainerProps } from './container'; export { Input, InputProps } from './input'; export { Icon, IconProps } from './icon'; export { Spinner, SpinnerProps } from './spinner'; +export { Overlay, OverlayProps } from './overlay'; diff --git a/packages/instant/src/components/ui/overlay.tsx b/packages/instant/src/components/ui/overlay.tsx new file mode 100644 index 000000000..94fa10fc5 --- /dev/null +++ b/packages/instant/src/components/ui/overlay.tsx @@ -0,0 +1,49 @@ +import * as _ from 'lodash'; +import * as React from 'react'; + +import { ColorOption, overlayBlack, styled } from '../../style/theme'; +import { util } from '../../util/util'; + +import { Button, ButtonHoverStyle } from './button'; +import { Container } from './container'; +import { Flex } from './flex'; +import { Icon } from './icon'; + +export interface OverlayProps { + className?: string; + onClose?: () => void; + zIndex?: number; +} + +const PlainOverlay: React.StatelessComponent = ({ children, className, onClose }) => ( + + + + +
{children}
+
+); +export const Overlay = styled(PlainOverlay)` + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + z-index: ${props => props.zIndex} + background-color: ${overlayBlack}; +`; + +Overlay.defaultProps = { + onClose: util.boundNoop, + zIndex: 100, +}; + +Overlay.displayName = 'Overlay'; diff --git a/packages/instant/src/components/zero_ex_instant.tsx b/packages/instant/src/components/zero_ex_instant.tsx index d54dfc153..907c42e7a 100644 --- a/packages/instant/src/components/zero_ex_instant.tsx +++ b/packages/instant/src/components/zero_ex_instant.tsx @@ -1,111 +1,14 @@ -import { AssetBuyer } from '@0x/asset-buyer'; -import { ObjectMap, SignedOrder } from '@0x/types'; -import * as _ from 'lodash'; import * as React from 'react'; -import { Provider } from 'react-redux'; - -import { SelectedAssetThemeProvider } from '../containers/selected_asset_theme_provider'; -import { asyncData } from '../redux/async_data'; -import { INITIAL_STATE, State } from '../redux/reducer'; -import { store, Store } from '../redux/store'; -import { fonts } from '../style/fonts'; -import { AssetMetaData, Network } from '../types'; -import { assetUtils } from '../util/asset'; -import { BigNumberInput } from '../util/big_number_input'; -import { errorFlasher } from '../util/error_flasher'; -import { gasPriceEstimator } from '../util/gas_price_estimator'; -import { getProvider } from '../util/provider'; -import { web3Wrapper } from '../util/web3_wrapper'; import { ZeroExInstantContainer } from './zero_ex_instant_container'; +import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider'; -fonts.include(); - -export type ZeroExInstantProps = ZeroExInstantRequiredProps & Partial; - -export interface ZeroExInstantRequiredProps { - // TODO: Change API when we allow the selection of different assetDatas - assetData: string; - liquiditySource: string | SignedOrder[]; -} - -export interface ZeroExInstantOptionalProps { - defaultAssetBuyAmount?: number; - additionalAssetMetaDataMap: ObjectMap; - networkId: Network; -} - -export class ZeroExInstant extends React.Component { - private readonly _store: Store; - private static _mergeInitialStateWithProps(props: ZeroExInstantProps, state: State = INITIAL_STATE): State { - const networkId = props.networkId || state.network; - // TODO: Provider needs to not be hard-coded to injected web3. - const provider = getProvider(); - const assetBuyerOptions = { - networkId, - }; - let assetBuyer; - if (_.isString(props.liquiditySource)) { - assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl( - provider, - props.liquiditySource, - assetBuyerOptions, - ); - } else { - assetBuyer = AssetBuyer.getAssetBuyerForProvidedOrders(provider, props.liquiditySource, assetBuyerOptions); - } - const completeAssetMetaDataMap = { - ...props.additionalAssetMetaDataMap, - ...state.assetMetaDataMap, - }; - const storeStateFromProps: State = { - ...state, - assetBuyer, - network: networkId, - selectedAsset: assetUtils.createAssetFromAssetData(props.assetData, completeAssetMetaDataMap, networkId), - selectedAssetAmount: _.isUndefined(props.defaultAssetBuyAmount) - ? state.selectedAssetAmount - : new BigNumberInput(props.defaultAssetBuyAmount), - assetMetaDataMap: completeAssetMetaDataMap, - }; - return storeStateFromProps; - } - constructor(props: ZeroExInstantProps) { - super(props); - const initialAppState = ZeroExInstant._mergeInitialStateWithProps(this.props, INITIAL_STATE); - this._store = store.create(initialAppState); - } - - public componentDidMount(): void { - // tslint:disable-next-line:no-floating-promises - asyncData.fetchAndDispatchToStore(this._store); - - // 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.getFastAmountInWeiAsync(); - - // tslint:disable-next-line:no-floating-promises - this._flashErrorIfWrongNetwork(); - } - - public render(): React.ReactNode { - return ( - - - - - - ); - } +export type ZeroExInstantProps = ZeroExInstantProviderProps; - private readonly _flashErrorIfWrongNetwork = async (): Promise => { - const msToShowError = 30000; // 30 seconds - const network = this._store.getState().network; - 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); - } - }; -} +export const ZeroExInstant: React.StatelessComponent = props => { + return ( + + + + ); +}; diff --git a/packages/instant/src/components/zero_ex_instant_overlay.tsx b/packages/instant/src/components/zero_ex_instant_overlay.tsx new file mode 100644 index 000000000..8f872f896 --- /dev/null +++ b/packages/instant/src/components/zero_ex_instant_overlay.tsx @@ -0,0 +1,21 @@ +import * as React from 'react'; + +import { Overlay } from './ui'; +import { ZeroExInstantContainer } from './zero_ex_instant_container'; +import { ZeroExInstantProvider, ZeroExInstantProviderProps } from './zero_ex_instant_provider'; + +export interface ZeroExInstantOverlayProps extends ZeroExInstantProviderProps { + onClose?: () => void; + zIndex?: number; +} + +export const ZeroExInstantOverlay: React.StatelessComponent = props => { + const { onClose, zIndex, ...rest } = props; + return ( + + + + + + ); +}; diff --git a/packages/instant/src/components/zero_ex_instant_provider.tsx b/packages/instant/src/components/zero_ex_instant_provider.tsx new file mode 100644 index 000000000..8c1025723 --- /dev/null +++ b/packages/instant/src/components/zero_ex_instant_provider.tsx @@ -0,0 +1,108 @@ +import { AssetBuyer } from '@0x/asset-buyer'; +import { ObjectMap, SignedOrder } from '@0x/types'; +import * as _ from 'lodash'; +import * as React from 'react'; +import { Provider } from 'react-redux'; + +import { SelectedAssetThemeProvider } from '../containers/selected_asset_theme_provider'; +import { asyncData } from '../redux/async_data'; +import { INITIAL_STATE, State } from '../redux/reducer'; +import { store, Store } from '../redux/store'; +import { fonts } from '../style/fonts'; +import { AssetMetaData, Network } from '../types'; +import { assetUtils } from '../util/asset'; +import { BigNumberInput } from '../util/big_number_input'; +import { errorFlasher } from '../util/error_flasher'; +import { gasPriceEstimator } from '../util/gas_price_estimator'; +import { getProvider } from '../util/provider'; +import { web3Wrapper } from '../util/web3_wrapper'; + +fonts.include(); + +export type ZeroExInstantProviderProps = ZeroExInstantProviderRequiredProps & + Partial; + +export interface ZeroExInstantProviderRequiredProps { + // TODO: Change API when we allow the selection of different assetDatas + assetData: string; + liquiditySource: string | SignedOrder[]; +} + +export interface ZeroExInstantProviderOptionalProps { + defaultAssetBuyAmount?: number; + additionalAssetMetaDataMap: ObjectMap; + networkId: Network; +} + +export class ZeroExInstantProvider extends React.Component { + private readonly _store: Store; + private static _mergeInitialStateWithProps(props: ZeroExInstantProviderProps, state: State = INITIAL_STATE): State { + const networkId = props.networkId || state.network; + // TODO: Provider needs to not be hard-coded to injected web3. + const provider = getProvider(); + const assetBuyerOptions = { + networkId, + }; + let assetBuyer; + if (_.isString(props.liquiditySource)) { + assetBuyer = AssetBuyer.getAssetBuyerForStandardRelayerAPIUrl( + provider, + props.liquiditySource, + assetBuyerOptions, + ); + } else { + assetBuyer = AssetBuyer.getAssetBuyerForProvidedOrders(provider, props.liquiditySource, assetBuyerOptions); + } + const completeAssetMetaDataMap = { + ...props.additionalAssetMetaDataMap, + ...state.assetMetaDataMap, + }; + const storeStateFromProps: State = { + ...state, + assetBuyer, + network: networkId, + selectedAsset: assetUtils.createAssetFromAssetData(props.assetData, completeAssetMetaDataMap, networkId), + selectedAssetAmount: _.isUndefined(props.defaultAssetBuyAmount) + ? state.selectedAssetAmount + : new BigNumberInput(props.defaultAssetBuyAmount), + assetMetaDataMap: completeAssetMetaDataMap, + }; + return storeStateFromProps; + } + constructor(props: ZeroExInstantProviderProps) { + super(props); + const initialAppState = ZeroExInstantProvider._mergeInitialStateWithProps(this.props, INITIAL_STATE); + this._store = store.create(initialAppState); + } + + public componentDidMount(): void { + // tslint:disable-next-line:no-floating-promises + asyncData.fetchAndDispatchToStore(this._store); + + // 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.getFastAmountInWeiAsync(); + + // tslint:disable-next-line:no-floating-promises + this._flashErrorIfWrongNetwork(); + } + + public render(): React.ReactNode { + return ( + + {this.props.children} + + ); + } + + private readonly _flashErrorIfWrongNetwork = async (): Promise => { + const msToShowError = 30000; // 30 seconds + const network = this._store.getState().network; + 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); + } + }; +} diff --git a/packages/instant/src/constants.ts b/packages/instant/src/constants.ts index 424f35ecb..3e830ba00 100644 --- a/packages/instant/src/constants.ts +++ b/packages/instant/src/constants.ts @@ -2,6 +2,7 @@ import { BigNumber } from '@0x/utils'; export const BIG_NUMBER_ZERO = new BigNumber(0); export const ETH_DECIMALS = 18; export const DEFAULT_ZERO_EX_CONTAINER_SELECTOR = '#zeroExInstantContainer'; +export const INJECTED_DIV_ID = 'zeroExInstant'; export const WEB_3_WRAPPER_TRANSACTION_FAILED_ERROR_MSG_PREFIX = 'Transaction failed'; export const GWEI_IN_WEI = new BigNumber(1000000000); export const DEFAULT_GAS_PRICE = GWEI_IN_WEI.mul(6); diff --git a/packages/instant/src/index.ts b/packages/instant/src/index.ts index 54059cdad..6e611dae8 100644 --- a/packages/instant/src/index.ts +++ b/packages/instant/src/index.ts @@ -1 +1,2 @@ export { ZeroExInstant, ZeroExInstantProps } from './components/zero_ex_instant'; +export { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './components/zero_ex_instant_overlay'; diff --git a/packages/instant/src/index.umd.ts b/packages/instant/src/index.umd.ts index dabd45cae..b12e65485 100644 --- a/packages/instant/src/index.umd.ts +++ b/packages/instant/src/index.umd.ts @@ -2,21 +2,42 @@ import * as _ from 'lodash'; import * as React from 'react'; import * as ReactDOM from 'react-dom'; -import { DEFAULT_ZERO_EX_CONTAINER_SELECTOR } from './constants'; -import { ZeroExInstant, ZeroExInstantProps } from './index'; +import { DEFAULT_ZERO_EX_CONTAINER_SELECTOR, INJECTED_DIV_ID } from './constants'; +import { ZeroExInstantOverlay, ZeroExInstantOverlayProps } from './index'; import { assert } from './util/assert'; -export const render = (props: ZeroExInstantProps, selector: string = DEFAULT_ZERO_EX_CONTAINER_SELECTOR) => { - assert.isHexString('assetData', props.assetData); - assert.isValidLiquiditySource('liquiditySource', props.liquiditySource); +export const render = (props: ZeroExInstantOverlayProps, selector: string = DEFAULT_ZERO_EX_CONTAINER_SELECTOR) => { + assert.isHexString('props.assetData', props.assetData); + assert.isValidLiquiditySource('props.liquiditySource', props.liquiditySource); if (!_.isUndefined(props.additionalAssetMetaDataMap)) { - assert.isValidAssetMetaDataMap('additionalAssetMetaDataMap', props.additionalAssetMetaDataMap); + assert.isValidAssetMetaDataMap('props.additionalAssetMetaDataMap', props.additionalAssetMetaDataMap); } if (!_.isUndefined(props.defaultAssetBuyAmount)) { - assert.isNumber('defaultAssetBuyAmount', props.defaultAssetBuyAmount); + assert.isNumber('props.defaultAssetBuyAmount', props.defaultAssetBuyAmount); } if (!_.isUndefined(props.networkId)) { - assert.isNumber('networkId', props.networkId); + assert.isNumber('props.networkId', props.networkId); } - ReactDOM.render(React.createElement(ZeroExInstant, props), document.querySelector(selector)); + if (!_.isUndefined(props.onClose)) { + assert.isFunction('props.onClose', props.onClose); + } + if (!_.isUndefined(props.zIndex)) { + assert.isNumber('props.zIndex', props.zIndex); + } + const appendToIfExists = document.querySelector(selector); + assert.assert(!_.isNull(appendToIfExists), `Could not find div with selector: ${selector}`); + const appendTo = appendToIfExists as Element; + const injectedDiv = document.createElement('div'); + injectedDiv.setAttribute('id', INJECTED_DIV_ID); + appendTo.appendChild(injectedDiv); + const instantOverlayProps = { + ...props, + onClose: () => { + appendTo.removeChild(injectedDiv); + if (!_.isUndefined(props.onClose)) { + props.onClose(); + } + }, + }; + ReactDOM.render(React.createElement(ZeroExInstantOverlay, instantOverlayProps), injectedDiv); }; diff --git a/packages/instant/src/style/theme.ts b/packages/instant/src/style/theme.ts index 6575ff9f4..c7cb0bebe 100644 --- a/packages/instant/src/style/theme.ts +++ b/packages/instant/src/style/theme.ts @@ -14,6 +14,7 @@ export enum ColorOption { white = 'white', lightOrange = 'lightOrange', darkOrange = 'darkOrange', + clear = 'clear', } export const theme: Theme = { @@ -26,8 +27,10 @@ export const theme: Theme = { white: 'white', lightOrange: '#F9F2ED', darkOrange: '#F2994C', + clear: 'rgba(0, 0, 0, 0.0)', }; export const transparentWhite = 'rgba(255,255,255,0.3)'; +export const overlayBlack = 'rgba(0, 0, 0, 0.6)'; export { styled, css, keyframes, ThemeProvider }; -- cgit From d16499da4e0611438df7bfe226bce940beca6918 Mon Sep 17 00:00:00 2001 From: Brandon Millman Date: Thu, 1 Nov 2018 15:23:42 -0700 Subject: Remove alternate hover styling from button and move into icon component --- packages/instant/src/components/ui/button.tsx | 20 ++------ packages/instant/src/components/ui/icon.tsx | 69 ++++++++++++++++++-------- packages/instant/src/components/ui/index.ts | 2 +- packages/instant/src/components/ui/overlay.tsx | 15 +----- packages/instant/src/style/theme.ts | 2 - 5 files changed, 54 insertions(+), 54 deletions(-) (limited to 'packages/instant/src') diff --git a/packages/instant/src/components/ui/button.tsx b/packages/instant/src/components/ui/button.tsx index 0051482e7..5274d835b 100644 --- a/packages/instant/src/components/ui/button.tsx +++ b/packages/instant/src/components/ui/button.tsx @@ -3,11 +3,6 @@ import * as React from 'react'; import { ColorOption, styled } from '../../style/theme'; -export enum ButtonHoverStyle { - Darken = 0, - Opacity, -} - export interface ButtonProps { backgroundColor?: ColorOption; borderColor?: ColorOption; @@ -17,7 +12,6 @@ export interface ButtonProps { isDisabled?: boolean; onClick?: (event: React.MouseEvent) => void; className?: string; - hoverStyle?: ButtonHoverStyle; } const PlainButton: React.StatelessComponent = ({ children, isDisabled, onClick, type, className }) => ( @@ -38,38 +32,30 @@ export const Button = styled(PlainButton)` 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')}; - opacity: ${props => (props.hoverStyle === ButtonHoverStyle.Opacity ? 0.7 : 1)}; &:hover { background-color: ${props => - shouldDarken(props) + !props.isDisabled ? darken(darkenOnHoverAmount, props.theme[props.backgroundColor || 'white']) : ''} !important; - opacity: 1; } &:active { background-color: ${props => - shouldDarken(props) ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; - opacity: 1; + !props.isDisabled ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; } &:disabled { - opacity: ${props => (props.hoverStyle === ButtonHoverStyle.Darken ? 0.5 : 0.2)}; + opacity: 0.5; } &:focus { background-color: ${props => saturate(saturateOnFocusAmount, props.theme[props.backgroundColor || 'white'])}; } `; -const shouldDarken = (props: ButtonProps) => { - return !props.isDisabled && props.hoverStyle === ButtonHoverStyle.Darken; -}; - Button.defaultProps = { backgroundColor: ColorOption.primaryColor, borderColor: ColorOption.primaryColor, width: 'auto', isDisabled: false, padding: '1em 2.2em', - hoverStyle: ButtonHoverStyle.Darken, }; Button.displayName = 'Button'; diff --git a/packages/instant/src/components/ui/icon.tsx b/packages/instant/src/components/ui/icon.tsx index a05017ba1..f12059cff 100644 --- a/packages/instant/src/components/ui/icon.tsx +++ b/packages/instant/src/components/ui/icon.tsx @@ -1,5 +1,8 @@ +import * as _ from 'lodash'; import * as React from 'react'; +import { styled } from '../../style/theme'; + type svgRule = 'evenodd' | 'nonzero' | 'inherit'; interface IconInfo { viewBox: string; @@ -52,33 +55,57 @@ const ICONS: IconInfoMapping = { }; export interface IconProps { + className?: string; width: number; height?: number; color?: string; icon: keyof IconInfoMapping; + onClick?: (event: React.MouseEvent) => void; + padding?: string; } -export const Icon: React.SFC = props => { +const PlainIcon: React.SFC = props => { const iconInfo = ICONS[props.icon]; - return ( - - - +
+ + + +
); }; + +export const Icon = styled(PlainIcon)` + cursor: ${props => (!_.isUndefined(props.onClick) ? 'pointer' : 'default')}; + 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 = { + color: 'white', + padding: '0em 0em', +}; + +Icon.displayName = 'Icon'; diff --git a/packages/instant/src/components/ui/index.ts b/packages/instant/src/components/ui/index.ts index c60b9640e..0efabdb85 100644 --- a/packages/instant/src/components/ui/index.ts +++ b/packages/instant/src/components/ui/index.ts @@ -1,5 +1,5 @@ export { Text, TextProps, Title } from './text'; -export { Button, ButtonProps, ButtonHoverStyle } from './button'; +export { Button, ButtonProps } from './button'; export { Flex, FlexProps } from './flex'; export { Container, ContainerProps } from './container'; export { Input, InputProps } from './input'; diff --git a/packages/instant/src/components/ui/overlay.tsx b/packages/instant/src/components/ui/overlay.tsx index 94fa10fc5..c5258b031 100644 --- a/packages/instant/src/components/ui/overlay.tsx +++ b/packages/instant/src/components/ui/overlay.tsx @@ -1,10 +1,8 @@ import * as _ from 'lodash'; import * as React from 'react'; -import { ColorOption, overlayBlack, styled } from '../../style/theme'; -import { util } from '../../util/util'; +import { overlayBlack, styled } from '../../style/theme'; -import { Button, ButtonHoverStyle } from './button'; import { Container } from './container'; import { Flex } from './flex'; import { Icon } from './icon'; @@ -18,15 +16,7 @@ export interface OverlayProps { const PlainOverlay: React.StatelessComponent = ({ children, className, onClose }) => ( - +
{children}
@@ -42,7 +32,6 @@ export const Overlay = styled(PlainOverlay)` `; Overlay.defaultProps = { - onClose: util.boundNoop, zIndex: 100, }; diff --git a/packages/instant/src/style/theme.ts b/packages/instant/src/style/theme.ts index c7cb0bebe..e81694620 100644 --- a/packages/instant/src/style/theme.ts +++ b/packages/instant/src/style/theme.ts @@ -14,7 +14,6 @@ export enum ColorOption { white = 'white', lightOrange = 'lightOrange', darkOrange = 'darkOrange', - clear = 'clear', } export const theme: Theme = { @@ -27,7 +26,6 @@ export const theme: Theme = { white: 'white', lightOrange: '#F9F2ED', darkOrange: '#F2994C', - clear: 'rgba(0, 0, 0, 0.0)', }; export const transparentWhite = 'rgba(255,255,255,0.3)'; -- cgit