From 4b348e1e603ec45e1e4bf39533b4b204423cafa0 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 11:09:23 -0700 Subject: quoteState -> quoteRequestState --- packages/instant/src/components/instant_heading.tsx | 10 +++++----- packages/instant/src/containers/selected_asset_amount_input.ts | 6 +++--- .../instant/src/containers/selected_asset_instant_heading.ts | 4 ++-- packages/instant/src/redux/actions.ts | 4 ++-- packages/instant/src/redux/reducer.ts | 10 +++++----- 5 files changed, 17 insertions(+), 17 deletions(-) diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index a36d35a93..9dd13299c 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -13,7 +13,7 @@ export interface InstantHeadingProps { selectedAssetAmount?: BigNumber; totalEthBaseAmount?: BigNumber; ethUsdPrice?: BigNumber; - quoteState: AsyncProcessState; + quoteRequestState: AsyncProcessState; } const Placeholder = () => ( @@ -42,8 +42,8 @@ const displayUsdAmount = ({ return format.ethBaseAmountInUsd(totalEthBaseAmount, ethUsdPrice, 2, ); }; -const loadingOrAmount = (quoteState: AsyncProcessState, amount: React.ReactNode): React.ReactNode => { - if (quoteState === AsyncProcessState.PENDING) { +const loadingOrAmount = (quoteRequestState: AsyncProcessState, amount: React.ReactNode): React.ReactNode => { + if (quoteRequestState === AsyncProcessState.PENDING) { return ( …loading @@ -73,11 +73,11 @@ export const InstantHeading: React.StatelessComponent = pro - {loadingOrAmount(props.quoteState, displaytotalEthBaseAmount(props))} + {loadingOrAmount(props.quoteRequestState, displaytotalEthBaseAmount(props))} - {loadingOrAmount(props.quoteState, displayUsdAmount(props))} + {loadingOrAmount(props.quoteRequestState, displayUsdAmount(props))} diff --git a/packages/instant/src/containers/selected_asset_amount_input.ts b/packages/instant/src/containers/selected_asset_amount_input.ts index 0810b093a..aca6a09d4 100644 --- a/packages/instant/src/containers/selected_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_asset_amount_input.ts @@ -44,13 +44,13 @@ const updateBuyQuoteAsync = async ( const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, zrxDecimals); // mark quote as pending - dispatch(actions.updateBuyQuoteStatePending()); + dispatch(actions.updateBuyquoteRequestStatePending()); let newBuyQuote: BuyQuote | undefined; try { newBuyQuote = await assetBuyer.getBuyQuoteAsync(assetData, baseUnitValue); } catch (error) { - dispatch(actions.updateBuyQuoteStateFailure()); + dispatch(actions.updateBuyquoteRequestStateFailure()); errorUtil.errorFlasher.flashNewError(dispatch, error); return; } @@ -76,7 +76,7 @@ const mapDispatchToProps = ( if (!_.isUndefined(value) && !_.isUndefined(assetData)) { // even if it's debounced, give them the illusion it's loading - dispatch(actions.updateBuyQuoteStatePending()); + dispatch(actions.updateBuyquoteRequestStatePending()); // tslint:disable-next-line:no-floating-promises debouncedUpdateBuyQuoteAsync(dispatch, assetData, value); } diff --git a/packages/instant/src/containers/selected_asset_instant_heading.ts b/packages/instant/src/containers/selected_asset_instant_heading.ts index 0509db5da..43127582c 100644 --- a/packages/instant/src/containers/selected_asset_instant_heading.ts +++ b/packages/instant/src/containers/selected_asset_instant_heading.ts @@ -15,14 +15,14 @@ interface ConnectedState { selectedAssetAmount?: BigNumber; totalEthBaseAmount?: BigNumber; ethUsdPrice?: BigNumber; - quoteState: AsyncProcessState; + quoteRequestState: AsyncProcessState; } const mapStateToProps = (state: State, _ownProps: InstantHeadingProps): ConnectedState => ({ selectedAssetAmount: state.selectedAssetAmount, totalEthBaseAmount: oc(state).latestBuyQuote.worstCaseQuoteInfo.totalEthAmount(), ethUsdPrice: state.ethUsdPrice, - quoteState: state.quoteState, + quoteRequestState: state.quoteRequestState, }); export const SelectedAssetInstantHeading: React.ComponentClass = connect(mapStateToProps)( diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts index 9c154c66f..b4aa4f4cb 100644 --- a/packages/instant/src/redux/actions.ts +++ b/packages/instant/src/redux/actions.ts @@ -38,8 +38,8 @@ export const actions = { updatebuyOrderState: (buyState: AsyncProcessState) => createAction(ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, buyState), updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UPDATE_LATEST_BUY_QUOTE, buyQuote), - updateBuyQuoteStatePending: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING), - updateBuyQuoteStateFailure: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_FAILURE), + updateBuyquoteRequestStatePending: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING), + updateBuyquoteRequestStateFailure: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_FAILURE), setError: (error?: any) => createAction(ActionTypes.SET_ERROR, error), hideError: () => createAction(ActionTypes.HIDE_ERROR), clearError: () => createAction(ActionTypes.CLEAR_ERROR), diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index 05aa37420..d2256ef54 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -17,7 +17,7 @@ export interface State { buyOrderState: AsyncProcessState; ethUsdPrice?: BigNumber; latestBuyQuote?: BuyQuote; - quoteState: AsyncProcessState; + quoteRequestState: AsyncProcessState; latestError?: any; latestErrorDisplay: LatestErrorDisplay; } @@ -31,7 +31,7 @@ export const INITIAL_STATE: State = { latestBuyQuote: undefined, latestError: undefined, latestErrorDisplay: LatestErrorDisplay.Hidden, - quoteState: AsyncProcessState.NONE, + quoteRequestState: AsyncProcessState.NONE, }; export const reducer = (state: State = INITIAL_STATE, action: Action): State => { @@ -50,19 +50,19 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State => return { ...state, latestBuyQuote: action.data, - quoteState: AsyncProcessState.SUCCESS, + quoteRequestState: AsyncProcessState.SUCCESS, }; case ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING: return { ...state, latestBuyQuote: undefined, - quoteState: AsyncProcessState.PENDING, + quoteRequestState: AsyncProcessState.PENDING, }; case ActionTypes.UPDATE_BUY_QUOTE_STATE_FAILURE: return { ...state, latestBuyQuote: undefined, - quoteState: AsyncProcessState.FAILURE, + quoteRequestState: AsyncProcessState.FAILURE, }; case ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE: return { -- cgit v1.2.3 From 12b6877aeb0a6bcddab4193b62cd10347b8c328b Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 13:31:11 -0700 Subject: Pulsating holder element showing, even if amount is empty --- .../instant/src/components/amount_placeholder.tsx | 29 ++++++ .../instant/src/components/animations/pulse.tsx | 15 +++ .../instant/src/components/instant_heading.tsx | 112 ++++++++++----------- packages/instant/src/components/ui/container.tsx | 2 + 4 files changed, 101 insertions(+), 57 deletions(-) create mode 100644 packages/instant/src/components/amount_placeholder.tsx create mode 100644 packages/instant/src/components/animations/pulse.tsx diff --git a/packages/instant/src/components/amount_placeholder.tsx b/packages/instant/src/components/amount_placeholder.tsx new file mode 100644 index 000000000..54639effb --- /dev/null +++ b/packages/instant/src/components/amount_placeholder.tsx @@ -0,0 +1,29 @@ +import * as React from 'react'; + +import { ColorOption } from '../style/theme'; + +import { Pulse } from './animations/pulse'; + +import { Text } from './ui'; + +export interface AmountPlaceholderProps { + pulsating: boolean; +} + +const PlainPlaceholder = () => ( + + — + +); + +export const AmountPlaceholder: React.StatelessComponent = props => { + if (props.pulsating) { + return ( + + + + ); + } else { + return ; + } +}; diff --git a/packages/instant/src/components/animations/pulse.tsx b/packages/instant/src/components/animations/pulse.tsx new file mode 100644 index 000000000..01d6ea070 --- /dev/null +++ b/packages/instant/src/components/animations/pulse.tsx @@ -0,0 +1,15 @@ +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/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 9dd13299c..9ca4ce598 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -7,6 +7,7 @@ import { ColorOption } from '../style/theme'; import { AsyncProcessState } from '../types'; import { format } from '../util/format'; +import { AmountPlaceholder } from './amount_placeholder'; import { Container, Flex, Text } from './ui'; export interface InstantHeadingProps { @@ -16,70 +17,67 @@ export interface InstantHeadingProps { quoteRequestState: AsyncProcessState; } -const Placeholder = () => ( - - — - -); -const displaytotalEthBaseAmount = ({ - selectedAssetAmount, - totalEthBaseAmount, -}: InstantHeadingProps): React.ReactNode => { - if (_.isUndefined(selectedAssetAmount)) { - return '0 ETH'; +export class InstantHeading extends React.Component { + public render(): React.ReactNode { + const placeholderAmountToAlwaysShow = this._placeholderAmountToAlwaysShow(); + return ( + + + + I want to buy + + + + + + {placeholderAmountToAlwaysShow || this._ethAmount()} + {placeholderAmountToAlwaysShow || this._dollarAmount()} + + + + ); } - return format.ethBaseAmount(totalEthBaseAmount, 4, ); -}; -const displayUsdAmount = ({ - totalEthBaseAmount, - selectedAssetAmount, - ethUsdPrice, -}: InstantHeadingProps): React.ReactNode => { - if (_.isUndefined(selectedAssetAmount)) { - return '$0.00'; + private _placeholderAmountToAlwaysShow(): React.ReactNode | undefined { + if (this.props.quoteRequestState === AsyncProcessState.PENDING) { + return ; + } + if (_.isUndefined(this.props.selectedAssetAmount)) { + return ; + } + return undefined; } - return format.ethBaseAmountInUsd(totalEthBaseAmount, ethUsdPrice, 2, ); -}; -const loadingOrAmount = (quoteRequestState: AsyncProcessState, amount: React.ReactNode): React.ReactNode => { - if (quoteRequestState === AsyncProcessState.PENDING) { + private _ethAmount(): React.ReactNode { return ( - - …loading + + {format.ethBaseAmount(this.props.totalEthBaseAmount, 4, )} ); - } else { - return amount; } -}; -export const InstantHeading: React.StatelessComponent = props => ( - - - - I want to buy + private _dollarAmount(): React.ReactNode { + return ( + + {format.ethBaseAmountInUsd( + this.props.totalEthBaseAmount, + this.props.ethUsdPrice, + 2, + , + )} - - - - - - - {loadingOrAmount(props.quoteRequestState, displaytotalEthBaseAmount(props))} - - - - {loadingOrAmount(props.quoteRequestState, displayUsdAmount(props))} - - - - -); + ); + } +} diff --git a/packages/instant/src/components/ui/container.tsx b/packages/instant/src/components/ui/container.tsx index 02b16e39f..5e2218c68 100644 --- a/packages/instant/src/components/ui/container.tsx +++ b/packages/instant/src/components/ui/container.tsx @@ -27,6 +27,7 @@ export interface ContainerProps { backgroundColor?: ColorOption; hasBoxShadow?: boolean; zIndex?: number; + opacity?: number; } const PlainContainer: React.StatelessComponent = ({ children, className }) => ( @@ -54,6 +55,7 @@ export const Container = styled(PlainContainer)` ${props => cssRuleIfExists(props, 'border-top')} ${props => cssRuleIfExists(props, 'border-bottom')} ${props => cssRuleIfExists(props, 'z-index')} + ${props => cssRuleIfExists(props, 'opacity')} ${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')}; -- cgit v1.2.3 From 94ace00e0cfd550bccf33f85441ce1dad33f1348 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 13:38:04 -0700 Subject: fix camel casing of updateBuyOrderState --- packages/instant/src/containers/selected_asset_amount_input.ts | 2 +- packages/instant/src/containers/selected_asset_buy_button.ts | 6 +++--- packages/instant/src/redux/actions.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/instant/src/containers/selected_asset_amount_input.ts b/packages/instant/src/containers/selected_asset_amount_input.ts index aca6a09d4..2a1e5e457 100644 --- a/packages/instant/src/containers/selected_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_asset_amount_input.ts @@ -72,7 +72,7 @@ const mapDispatchToProps = ( // invalidate the last buy quote. dispatch(actions.updateLatestBuyQuote(undefined)); // reset our buy state - dispatch(actions.updatebuyOrderState(AsyncProcessState.NONE)); + dispatch(actions.updateBuyOrderState(AsyncProcessState.NONE)); if (!_.isUndefined(value) && !_.isUndefined(assetData)) { // even if it's debounced, give them the illusion it's loading diff --git a/packages/instant/src/containers/selected_asset_buy_button.ts b/packages/instant/src/containers/selected_asset_buy_button.ts index 4a8e31525..4d3315b1a 100644 --- a/packages/instant/src/containers/selected_asset_buy_button.ts +++ b/packages/instant/src/containers/selected_asset_buy_button.ts @@ -44,9 +44,9 @@ const mapStateToProps = (state: State, _ownProps: SelectedAssetBuyButtonProps): }); const mapDispatchToProps = (dispatch: Dispatch, ownProps: SelectedAssetBuyButtonProps): ConnectedDispatch => ({ - onClick: buyQuote => dispatch(actions.updatebuyOrderState(AsyncProcessState.PENDING)), - onBuySuccess: buyQuote => dispatch(actions.updatebuyOrderState(AsyncProcessState.SUCCESS)), - onBuyFailure: buyQuote => dispatch(actions.updatebuyOrderState(AsyncProcessState.FAILURE)), + onClick: buyQuote => dispatch(actions.updateBuyOrderState(AsyncProcessState.PENDING)), + onBuySuccess: buyQuote => dispatch(actions.updateBuyOrderState(AsyncProcessState.SUCCESS)), + onBuyFailure: buyQuote => dispatch(actions.updateBuyOrderState(AsyncProcessState.FAILURE)), }); export const SelectedAssetBuyButton: React.ComponentClass = connect( diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts index b4aa4f4cb..016dc29dc 100644 --- a/packages/instant/src/redux/actions.ts +++ b/packages/instant/src/redux/actions.ts @@ -35,7 +35,7 @@ export enum ActionTypes { export const actions = { updateEthUsdPrice: (price?: BigNumber) => createAction(ActionTypes.UPDATE_ETH_USD_PRICE, price), updateSelectedAssetAmount: (amount?: BigNumber) => createAction(ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, amount), - updatebuyOrderState: (buyState: AsyncProcessState) => + updateBuyOrderState: (buyState: AsyncProcessState) => createAction(ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, buyState), updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UPDATE_LATEST_BUY_QUOTE, buyQuote), updateBuyquoteRequestStatePending: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING), -- cgit v1.2.3 From 9aa67538231cc4ff71fd0f8ebe4dc66b1bcc4937 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 13:42:59 -0700 Subject: Rename update function to set function since it doesnt take a parameter --- packages/instant/src/containers/selected_asset_amount_input.ts | 6 +++--- packages/instant/src/redux/actions.ts | 8 ++++---- packages/instant/src/redux/reducer.ts | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/instant/src/containers/selected_asset_amount_input.ts b/packages/instant/src/containers/selected_asset_amount_input.ts index 2a1e5e457..e55c8b991 100644 --- a/packages/instant/src/containers/selected_asset_amount_input.ts +++ b/packages/instant/src/containers/selected_asset_amount_input.ts @@ -44,13 +44,13 @@ const updateBuyQuoteAsync = async ( const baseUnitValue = Web3Wrapper.toBaseUnitAmount(assetAmount, zrxDecimals); // mark quote as pending - dispatch(actions.updateBuyquoteRequestStatePending()); + dispatch(actions.setQuoteRequestStatePending()); let newBuyQuote: BuyQuote | undefined; try { newBuyQuote = await assetBuyer.getBuyQuoteAsync(assetData, baseUnitValue); } catch (error) { - dispatch(actions.updateBuyquoteRequestStateFailure()); + dispatch(actions.setQuoteRequestStateFailure()); errorUtil.errorFlasher.flashNewError(dispatch, error); return; } @@ -76,7 +76,7 @@ const mapDispatchToProps = ( if (!_.isUndefined(value) && !_.isUndefined(assetData)) { // even if it's debounced, give them the illusion it's loading - dispatch(actions.updateBuyquoteRequestStatePending()); + dispatch(actions.setQuoteRequestStatePending()); // tslint:disable-next-line:no-floating-promises debouncedUpdateBuyQuoteAsync(dispatch, assetData, value); } diff --git a/packages/instant/src/redux/actions.ts b/packages/instant/src/redux/actions.ts index 016dc29dc..e52a79e76 100644 --- a/packages/instant/src/redux/actions.ts +++ b/packages/instant/src/redux/actions.ts @@ -25,8 +25,8 @@ export enum ActionTypes { UPDATE_SELECTED_ASSET_AMOUNT = 'UPDATE_SELECTED_ASSET_AMOUNT', UPDATE_SELECTED_ASSET_BUY_STATE = 'UPDATE_SELECTED_ASSET_BUY_STATE', UPDATE_LATEST_BUY_QUOTE = 'UPDATE_LATEST_BUY_QUOTE', - UPDATE_BUY_QUOTE_STATE_PENDING = 'UPDATE_BUY_QUOTE_STATE_PENDING', - UPDATE_BUY_QUOTE_STATE_FAILURE = 'UPDATE_BUY_QUOTE_STATE_FAILURE', + SET_QUOTE_REQUEST_STATE_PENDING = 'SET_QUOTE_REQUEST_STATE_PENDING', + SET_QUOTE_REQUEST_STATE_FAILURE = 'SET_QUOTE_REQUEST_STATE_FAILURE', SET_ERROR = 'SET_ERROR', HIDE_ERROR = 'HIDE_ERROR', CLEAR_ERROR = 'CLEAR_ERROR', @@ -38,8 +38,8 @@ export const actions = { updateBuyOrderState: (buyState: AsyncProcessState) => createAction(ActionTypes.UPDATE_SELECTED_ASSET_BUY_STATE, buyState), updateLatestBuyQuote: (buyQuote?: BuyQuote) => createAction(ActionTypes.UPDATE_LATEST_BUY_QUOTE, buyQuote), - updateBuyquoteRequestStatePending: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING), - updateBuyquoteRequestStateFailure: () => createAction(ActionTypes.UPDATE_BUY_QUOTE_STATE_FAILURE), + setQuoteRequestStatePending: () => createAction(ActionTypes.SET_QUOTE_REQUEST_STATE_PENDING), + setQuoteRequestStateFailure: () => createAction(ActionTypes.SET_QUOTE_REQUEST_STATE_FAILURE), setError: (error?: any) => createAction(ActionTypes.SET_ERROR, error), hideError: () => createAction(ActionTypes.HIDE_ERROR), clearError: () => createAction(ActionTypes.CLEAR_ERROR), diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index d2256ef54..6c278099f 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -52,13 +52,13 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State => latestBuyQuote: action.data, quoteRequestState: AsyncProcessState.SUCCESS, }; - case ActionTypes.UPDATE_BUY_QUOTE_STATE_PENDING: + case ActionTypes.SET_QUOTE_REQUEST_STATE_PENDING: return { ...state, latestBuyQuote: undefined, quoteRequestState: AsyncProcessState.PENDING, }; - case ActionTypes.UPDATE_BUY_QUOTE_STATE_FAILURE: + case ActionTypes.SET_QUOTE_REQUEST_STATE_FAILURE: return { ...state, latestBuyQuote: undefined, -- cgit v1.2.3 From b4af27dd4462a001904ac6d69e43aac9fd7bb69a Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 13:48:28 -0700 Subject: Moved LatestErrorDisplay to types file and gave generic name --- packages/instant/src/containers/latest_error.tsx | 5 +++-- packages/instant/src/redux/reducer.ts | 16 ++++++---------- packages/instant/src/types.ts | 4 ++++ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/packages/instant/src/containers/latest_error.tsx b/packages/instant/src/containers/latest_error.tsx index 08ea418e7..413cf16ad 100644 --- a/packages/instant/src/containers/latest_error.tsx +++ b/packages/instant/src/containers/latest_error.tsx @@ -3,7 +3,8 @@ import * as React from 'react'; import { connect } from 'react-redux'; import { SlidingError } from '../components/sliding_error'; -import { LatestErrorDisplay, State } from '../redux/reducer'; +import { State } from '../redux/reducer'; +import { DisplayStatus } from '../types'; import { errorUtil } from '../util/error'; export interface LatestErrorComponentProps { @@ -29,7 +30,7 @@ export interface LatestErrorProps {} const mapStateToProps = (state: State, _ownProps: LatestErrorProps): ConnectedState => ({ assetData: state.selectedAssetData, latestError: state.latestError, - slidingDirection: state.latestErrorDisplay === LatestErrorDisplay.Present ? 'up' : 'down', + slidingDirection: state.latestErrorDisplay === DisplayStatus.Present ? 'up' : 'down', }); export const LatestError = connect(mapStateToProps)(LatestErrorComponent); diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts index 6c278099f..2d50dd4b9 100644 --- a/packages/instant/src/redux/reducer.ts +++ b/packages/instant/src/redux/reducer.ts @@ -3,14 +3,10 @@ import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import { zrxAssetData } from '../constants'; -import { AsyncProcessState } from '../types'; +import { AsyncProcessState, DisplayStatus } from '../types'; import { Action, ActionTypes } from './actions'; -export enum LatestErrorDisplay { - Present, - Hidden, -} export interface State { selectedAssetData?: string; selectedAssetAmount?: BigNumber; @@ -19,7 +15,7 @@ export interface State { latestBuyQuote?: BuyQuote; quoteRequestState: AsyncProcessState; latestError?: any; - latestErrorDisplay: LatestErrorDisplay; + latestErrorDisplay: DisplayStatus; } export const INITIAL_STATE: State = { @@ -30,7 +26,7 @@ export const INITIAL_STATE: State = { ethUsdPrice: undefined, latestBuyQuote: undefined, latestError: undefined, - latestErrorDisplay: LatestErrorDisplay.Hidden, + latestErrorDisplay: DisplayStatus.Hidden, quoteRequestState: AsyncProcessState.NONE, }; @@ -73,18 +69,18 @@ export const reducer = (state: State = INITIAL_STATE, action: Action): State => return { ...state, latestError: action.data, - latestErrorDisplay: LatestErrorDisplay.Present, + latestErrorDisplay: DisplayStatus.Present, }; case ActionTypes.HIDE_ERROR: return { ...state, - latestErrorDisplay: LatestErrorDisplay.Hidden, + latestErrorDisplay: DisplayStatus.Hidden, }; case ActionTypes.CLEAR_ERROR: return { ...state, latestError: undefined, - latestErrorDisplay: LatestErrorDisplay.Hidden, + latestErrorDisplay: DisplayStatus.Hidden, }; default: return state; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts index 8e3bb9b37..013ada27b 100644 --- a/packages/instant/src/types.ts +++ b/packages/instant/src/types.ts @@ -7,6 +7,10 @@ export enum AsyncProcessState { SUCCESS = 'Success', FAILURE = 'Failure', } +export enum DisplayStatus { + Present, + Hidden, +} export type FunctionType = (...args: any[]) => any; export type ActionCreatorsMapObject = ObjectMap; -- cgit v1.2.3 From 8a6e0776640a7bec7eab1f91b3b611dc4cadd2f7 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 14:51:45 -0700 Subject: feat(instant): Indicate that order details section is loading by having pulsing placeholder --- .../instant/src/components/amount_placeholder.tsx | 17 +++++++----- .../instant/src/components/instant_heading.tsx | 13 +++++++--- packages/instant/src/components/order_details.tsx | 30 ++++++++++++++++++---- .../containers/latest_buy_quote_order_details.ts | 3 +++ 4 files changed, 47 insertions(+), 16 deletions(-) diff --git a/packages/instant/src/components/amount_placeholder.tsx b/packages/instant/src/components/amount_placeholder.tsx index 54639effb..23a00895a 100644 --- a/packages/instant/src/components/amount_placeholder.tsx +++ b/packages/instant/src/components/amount_placeholder.tsx @@ -6,24 +6,27 @@ import { Pulse } from './animations/pulse'; import { Text } from './ui'; -export interface AmountPlaceholderProps { - pulsating: boolean; +export interface PlainPlaceholder { + color: ColorOption; } - -const PlainPlaceholder = () => ( - +export const PlainPlaceholder: React.StatelessComponent = props => ( + ); +export interface AmountPlaceholderProps { + color: ColorOption; + pulsating: boolean; +} export const AmountPlaceholder: React.StatelessComponent = props => { if (props.pulsating) { return ( - + ); } else { - return ; + return ; } }; diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 9ca4ce598..6a4c850f2 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -17,6 +17,7 @@ export interface InstantHeadingProps { quoteRequestState: AsyncProcessState; } +const placeholderColor = ColorOption.white; export class InstantHeading extends React.Component { public render(): React.ReactNode { const placeholderAmountToAlwaysShow = this._placeholderAmountToAlwaysShow(); @@ -52,10 +53,10 @@ export class InstantHeading extends React.Component { private _placeholderAmountToAlwaysShow(): React.ReactNode | undefined { if (this.props.quoteRequestState === AsyncProcessState.PENDING) { - return ; + return ; } if (_.isUndefined(this.props.selectedAssetAmount)) { - return ; + return ; } return undefined; } @@ -63,7 +64,11 @@ export class InstantHeading extends React.Component { private _ethAmount(): React.ReactNode { return ( - {format.ethBaseAmount(this.props.totalEthBaseAmount, 4, )} + {format.ethBaseAmount( + this.props.totalEthBaseAmount, + 4, + , + )} ); } @@ -75,7 +80,7 @@ export class InstantHeading extends React.Component { this.props.totalEthBaseAmount, this.props.ethUsdPrice, 2, - , + , )} ); diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index ad4a87714..f48f27edb 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -7,11 +7,13 @@ import { oc } from 'ts-optchain'; import { ColorOption } from '../style/theme'; import { format } from '../util/format'; +import { AmountPlaceholder } from './amount_placeholder'; import { Container, Flex, Text } from './ui'; export interface OrderDetailsProps { buyQuoteInfo?: BuyQuoteInfo; ethUsdPrice?: BigNumber; + isLoading: boolean; } export class OrderDetails extends React.Component { @@ -39,13 +41,20 @@ export class OrderDetails extends React.Component { ethAmount={ethAssetPrice} ethUsdPrice={ethUsdPrice} isEthAmountInBaseUnits={false} + isLoading={this.props.isLoading} + /> + - ); @@ -58,6 +67,7 @@ export interface EthAmountRowProps { isEthAmountInBaseUnits?: boolean; ethUsdPrice?: BigNumber; shouldEmphasize?: boolean; + isLoading: boolean; } export const EthAmountRow: React.StatelessComponent = ({ @@ -66,15 +76,19 @@ export const EthAmountRow: React.StatelessComponent = ({ isEthAmountInBaseUnits, ethUsdPrice, shouldEmphasize, + isLoading, }) => { - const fontWeight = shouldEmphasize ? 700 : 400; + // TODO: put in private function const usdFormatter = isEthAmountInBaseUnits ? format.ethBaseAmountInUsd : format.ethUnitAmountInUsd; - const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseAmount : format.ethUnitAmount; - const usdPriceSection = _.isUndefined(ethUsdPrice) ? null : ( + const shouldHideUsdPriceSection = _.isUndefined(ethUsdPrice) || _.isUndefined(ethAmount); + const usdPriceSection = shouldHideUsdPriceSection ? null : ( ({usdFormatter(ethAmount, ethUsdPrice)}) ); + + const fontWeight = shouldEmphasize ? 700 : 400; + const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseAmount : format.ethUnitAmount; return ( @@ -84,7 +98,13 @@ export const EthAmountRow: React.StatelessComponent = ({ {usdPriceSection} - {ethFormatter(ethAmount)} + {ethFormatter( + ethAmount, + 4, + + + , + )} diff --git a/packages/instant/src/containers/latest_buy_quote_order_details.ts b/packages/instant/src/containers/latest_buy_quote_order_details.ts index 597bf3088..092aaaf20 100644 --- a/packages/instant/src/containers/latest_buy_quote_order_details.ts +++ b/packages/instant/src/containers/latest_buy_quote_order_details.ts @@ -8,18 +8,21 @@ import { oc } from 'ts-optchain'; import { State } from '../redux/reducer'; import { OrderDetails } from '../components/order_details'; +import { AsyncProcessState } from '../types'; export interface LatestBuyQuoteOrderDetailsProps {} interface ConnectedState { buyQuoteInfo?: BuyQuoteInfo; ethUsdPrice?: BigNumber; + isLoading: boolean; } const mapStateToProps = (state: State, _ownProps: LatestBuyQuoteOrderDetailsProps): ConnectedState => ({ // use the worst case quote info buyQuoteInfo: oc(state).latestBuyQuote.worstCaseQuoteInfo(), ethUsdPrice: state.ethUsdPrice, + isLoading: state.quoteRequestState === AsyncProcessState.PENDING, }); export const LatestBuyQuoteOrderDetails: React.ComponentClass = connect( -- cgit v1.2.3 From 8ff5e1926993979229783cfb03d38aabd6f2f3d3 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 15:27:34 -0700 Subject: Move USD section into helper function --- packages/instant/src/components/order_details.tsx | 88 +++++++++++------------ 1 file changed, 42 insertions(+), 46 deletions(-) diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index f48f27edb..9a0dbc47a 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -15,7 +15,6 @@ export interface OrderDetailsProps { ethUsdPrice?: BigNumber; isLoading: boolean; } - export class OrderDetails extends React.Component { public render(): React.ReactNode { const { buyQuoteInfo, ethUsdPrice } = this.props; @@ -70,51 +69,48 @@ export interface EthAmountRowProps { isLoading: boolean; } -export const EthAmountRow: React.StatelessComponent = ({ - rowLabel, - ethAmount, - isEthAmountInBaseUnits, - ethUsdPrice, - shouldEmphasize, - isLoading, -}) => { - // TODO: put in private function - const usdFormatter = isEthAmountInBaseUnits ? format.ethBaseAmountInUsd : format.ethUnitAmountInUsd; - const shouldHideUsdPriceSection = _.isUndefined(ethUsdPrice) || _.isUndefined(ethAmount); - const usdPriceSection = shouldHideUsdPriceSection ? null : ( - - ({usdFormatter(ethAmount, ethUsdPrice)}) - - ); +export class EthAmountRow extends React.Component { + public static defaultProps = { + shouldEmphasize: false, + isEthAmountInBaseUnits: true, + }; + public static displayName = 'EthAmountRow'; + public render(): React.ReactNode { + const { rowLabel, ethAmount, isEthAmountInBaseUnits, shouldEmphasize, isLoading } = this.props; - const fontWeight = shouldEmphasize ? 700 : 400; - const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseAmount : format.ethUnitAmount; - return ( - - - - {rowLabel} - - - {usdPriceSection} + const fontWeight = shouldEmphasize ? 700 : 400; + const ethFormatter = isEthAmountInBaseUnits ? format.ethBaseAmount : format.ethUnitAmount; + return ( + + - {ethFormatter( - ethAmount, - 4, - - - , - )} + {rowLabel} - - - - ); -}; - -EthAmountRow.defaultProps = { - shouldEmphasize: false, - isEthAmountInBaseUnits: true, -}; - -EthAmountRow.displayName = 'EthAmountRow'; + + {this._usdSection()} + + {ethFormatter( + ethAmount, + 4, + + + , + )} + + + + + ); + } + private _usdSection(): React.ReactNode { + const usdFormatter = this.props.isEthAmountInBaseUnits ? format.ethBaseAmountInUsd : format.ethUnitAmountInUsd; + const shouldHideUsdPriceSection = _.isUndefined(this.props.ethUsdPrice) || _.isUndefined(this.props.ethAmount); + return shouldHideUsdPriceSection ? null : ( + + + ({usdFormatter(this.props.ethAmount, this.props.ethUsdPrice)}) + + + ); + } +} -- cgit v1.2.3 From a42347a776e2fa14fa898a354190f8b75bbe2fb2 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 15:28:24 -0700 Subject: Allow more than 1 class per file Felt silly that refactoring a component defined as a function to a class with a helper function caused a tslint violation --- packages/instant/tslint.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/instant/tslint.json b/packages/instant/tslint.json index abe874a6d..08b76be97 100644 --- a/packages/instant/tslint.json +++ b/packages/instant/tslint.json @@ -2,6 +2,7 @@ "extends": ["@0x/tslint-config"], "rules": { "custom-no-magic-numbers": false, - "semicolon": [true, "always", "ignore-bound-class-methods"] + "semicolon": [true, "always", "ignore-bound-class-methods"], + "max-classes-per-file": false } } -- cgit v1.2.3 From aa0e07b0581a645c3d2ea035d3acf28a74de0384 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 15:30:14 -0700 Subject: pulsating -> isPulsating --- packages/instant/src/components/amount_placeholder.tsx | 4 ++-- packages/instant/src/components/instant_heading.tsx | 8 ++++---- packages/instant/src/components/order_details.tsx | 2 +- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/packages/instant/src/components/amount_placeholder.tsx b/packages/instant/src/components/amount_placeholder.tsx index 23a00895a..e27d0ba81 100644 --- a/packages/instant/src/components/amount_placeholder.tsx +++ b/packages/instant/src/components/amount_placeholder.tsx @@ -17,10 +17,10 @@ export const PlainPlaceholder: React.StatelessComponent = prop export interface AmountPlaceholderProps { color: ColorOption; - pulsating: boolean; + isPulsating: boolean; } export const AmountPlaceholder: React.StatelessComponent = props => { - if (props.pulsating) { + if (props.isPulsating) { return ( diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 6a4c850f2..e2ef2d668 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -53,10 +53,10 @@ export class InstantHeading extends React.Component { private _placeholderAmountToAlwaysShow(): React.ReactNode | undefined { if (this.props.quoteRequestState === AsyncProcessState.PENDING) { - return ; + return ; } if (_.isUndefined(this.props.selectedAssetAmount)) { - return ; + return ; } return undefined; } @@ -67,7 +67,7 @@ export class InstantHeading extends React.Component { {format.ethBaseAmount( this.props.totalEthBaseAmount, 4, - , + , )} ); @@ -80,7 +80,7 @@ export class InstantHeading extends React.Component { this.props.totalEthBaseAmount, this.props.ethUsdPrice, 2, - , + , )} ); diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index 9a0dbc47a..a7971e1fd 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -93,7 +93,7 @@ export class EthAmountRow extends React.Component { ethAmount, 4, - + , )} -- cgit v1.2.3 From ff1f0a967802529e5ee50a7ff52d67bae1252b51 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Thu, 18 Oct 2018 15:31:18 -0700 Subject: undefined -> null to follow convention --- packages/instant/src/components/instant_heading.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index e2ef2d668..48cda7f88 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -51,14 +51,14 @@ export class InstantHeading extends React.Component { ); } - private _placeholderAmountToAlwaysShow(): React.ReactNode | undefined { + private _placeholderAmountToAlwaysShow(): React.ReactNode | null { if (this.props.quoteRequestState === AsyncProcessState.PENDING) { return ; } if (_.isUndefined(this.props.selectedAssetAmount)) { return ; } - return undefined; + return null; } private _ethAmount(): React.ReactNode { -- cgit v1.2.3 From 977e20edc3d94e2b95cf6e1e82eecdde2311eb7f Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 19 Oct 2018 13:27:16 +0100 Subject: style: make sure sideBar bottom padding is on scrollable content, not container --- packages/website/ts/pages/documentation/developers_page.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/website/ts/pages/documentation/developers_page.tsx b/packages/website/ts/pages/documentation/developers_page.tsx index 30b79552f..401f65df3 100644 --- a/packages/website/ts/pages/documentation/developers_page.tsx +++ b/packages/website/ts/pages/documentation/developers_page.tsx @@ -72,7 +72,6 @@ const SidebarContainer = ` ${scrollableContainerStyles} padding-top: 27px; - padding-bottom: 100px; padding-left: ${SIDEBAR_PADDING}px; padding-right: ${SIDEBAR_PADDING}px; overflow: hidden; @@ -163,7 +162,9 @@ export class DevelopersPage extends React.Component - {this.props.screenWidth !== ScreenWidths.Sm && this.props.sidebar} + + {this.props.screenWidth !== ScreenWidths.Sm && this.props.sidebar} + Date: Fri, 19 Oct 2018 14:04:17 +0100 Subject: style: Switch out homepage image with improved one from Ben --- .../website/public/images/landing/0x_homepage.svg | 57 +++------------------- 1 file changed, 6 insertions(+), 51 deletions(-) diff --git a/packages/website/public/images/landing/0x_homepage.svg b/packages/website/public/images/landing/0x_homepage.svg index 061ac8939..d2ccef8f4 100644 --- a/packages/website/public/images/landing/0x_homepage.svg +++ b/packages/website/public/images/landing/0x_homepage.svg @@ -1,24 +1,18 @@ - - - - - - - - - - + + + + + - @@ -56,7 +50,6 @@ - @@ -89,7 +82,6 @@ - @@ -116,7 +108,6 @@ - @@ -143,11 +134,10 @@ - - + @@ -170,7 +160,6 @@ - @@ -197,7 +186,6 @@ - @@ -224,7 +212,6 @@ - @@ -251,7 +238,6 @@ - @@ -277,109 +263,78 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- cgit v1.2.3 From 16ba01cd2e8b2af7bdeb6779e913ea4b6453dd78 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 19 Oct 2018 14:05:37 +0100 Subject: chore: fix dropdown bug on Firefox and reduced duplicate code --- .../components/dropdowns/developers_drop_down.tsx | 46 +++++++++++----------- 1 file changed, 22 insertions(+), 24 deletions(-) diff --git a/packages/website/ts/components/dropdowns/developers_drop_down.tsx b/packages/website/ts/components/dropdowns/developers_drop_down.tsx index b279566e0..6e85c1499 100644 --- a/packages/website/ts/components/dropdowns/developers_drop_down.tsx +++ b/packages/website/ts/components/dropdowns/developers_drop_down.tsx @@ -89,26 +89,22 @@ export class DevelopersDropDown extends React.Component - - {this._renderTitle('Getting started')} - - - {this._renderLinkSection(gettingStartedKeyToLinkInfo1)} - - {this._renderLinkSection(gettingStartedKeyToLinkInfo2)} + + + {this._renderLinkSection(gettingStartedKeyToLinkInfo1, 'Getting started')} + {this._renderLinkSection(gettingStartedKeyToLinkInfo2)} - - - {this._renderTitle('Popular docs')} - {this._renderLinkSection(popularDocsToLinkInfos)} + + + {this._renderLinkSection(popularDocsToLinkInfos, 'Popular docs')} - {this._renderTitle('Useful links')} - {this._renderLinkSection(usefulLinksToLinkInfo)} + {this._renderLinkSection(usefulLinksToLinkInfo, 'Useful links')} @@ -127,16 +123,7 @@ export class DevelopersDropDown extends React.Component - - {title.toUpperCase()} - - - ); - } - private _renderLinkSection(links: ALink[]): React.ReactNode { + private _renderLinkSection(links: ALink[], title: string = ''): React.ReactNode { const numLinks = links.length; let i = 0; const renderLinks = _.map(links, (link: ALink) => { @@ -159,6 +146,17 @@ export class DevelopersDropDown extends React.Component ); }); - return {renderLinks}; + return ( + + + {!_.isEmpty(title) && ( + + {title.toUpperCase()} + + )} + + {renderLinks} + + ); } } -- cgit v1.2.3 From 90ba8e0e8df2ccd2907adfcb143ed954b9d0b4c5 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 19 Oct 2018 17:09:13 +0100 Subject: Remove unused listeners --- packages/react-docs/src/components/doc_reference.tsx | 10 ---------- packages/website/ts/pages/wiki/wiki.tsx | 8 -------- 2 files changed, 18 deletions(-) diff --git a/packages/react-docs/src/components/doc_reference.tsx b/packages/react-docs/src/components/doc_reference.tsx index 00b1286a4..85547576b 100644 --- a/packages/react-docs/src/components/doc_reference.tsx +++ b/packages/react-docs/src/components/doc_reference.tsx @@ -52,12 +52,6 @@ export interface DocReferenceProps { export interface DocReferenceState {} export class DocReference extends React.Component { - public componentDidMount(): void { - window.addEventListener('hashchange', this._onHashChanged.bind(this), false); - } - public componentWillUnmount(): void { - window.removeEventListener('hashchange', this._onHashChanged.bind(this), false); - } public componentDidUpdate(prevProps: DocReferenceProps, _prevState: DocReferenceState): void { if (!_.isEqual(prevProps.docAgnosticFormat, this.props.docAgnosticFormat)) { const hash = window.location.hash.slice(1); @@ -323,8 +317,4 @@ export class DocReference extends React.Component ); } - private _onHashChanged(_event: any): void { - const hash = window.location.hash.slice(1); - sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID); - } } diff --git a/packages/website/ts/pages/wiki/wiki.tsx b/packages/website/ts/pages/wiki/wiki.tsx index e62300ddf..a35404e33 100644 --- a/packages/website/ts/pages/wiki/wiki.tsx +++ b/packages/website/ts/pages/wiki/wiki.tsx @@ -49,9 +49,6 @@ export class Wiki extends React.Component { isHoveringSidebar: false, }; } - public componentDidMount(): void { - window.addEventListener('hashchange', this._onHashChanged.bind(this), false); - } public componentWillMount(): void { // tslint:disable-next-line:no-floating-promises this._fetchArticlesBySectionAsync(); @@ -59,7 +56,6 @@ export class Wiki extends React.Component { public componentWillUnmount(): void { this._isUnmounted = true; clearTimeout(this._wikiBackoffTimeoutId); - window.removeEventListener('hashchange', this._onHashChanged.bind(this), false); } public render(): React.ReactNode { const sectionNameToLinks = _.isUndefined(this.state.articlesBySection) @@ -198,8 +194,4 @@ export class Wiki extends React.Component { } return sectionNameToLinks; } - private _onHashChanged(_event: any): void { - const hash = window.location.hash.slice(1); - sharedUtils.scrollToHash(hash, sharedConstants.SCROLL_CONTAINER_ID); - } } -- cgit v1.2.3 From d129c922edd8bc0319273488b23a5257d736502d Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 19 Oct 2018 17:22:33 +0100 Subject: Use media module --- packages/website/ts/pages/documentation/developers_page.tsx | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/website/ts/pages/documentation/developers_page.tsx b/packages/website/ts/pages/documentation/developers_page.tsx index 401f65df3..361dbc86e 100644 --- a/packages/website/ts/pages/documentation/developers_page.tsx +++ b/packages/website/ts/pages/documentation/developers_page.tsx @@ -6,6 +6,7 @@ import { DocsLogo } from 'ts/components/documentation/docs_logo'; import { DocsTopBar } from 'ts/components/documentation/docs_top_bar'; import { Container } from 'ts/components/ui/container'; import { Dispatcher } from 'ts/redux/dispatcher'; +import { media } from 'ts/style/media'; import { styled } from 'ts/style/theme'; import { BrowserType, OperatingSystemType, ScreenWidths } from 'ts/types'; import { Translate } from 'ts/utils/translate'; @@ -98,14 +99,14 @@ const MainContentContainer = padding-right: ${50 - SCROLLBAR_WIDTH}px; overflow: auto; } - @media (max-width: 40em) { + ${media.small` padding-left: 20px; padding-right: 20px; &:hover { padding-right: ${20 - SCROLLBAR_WIDTH}px; overflow: auto; } - } + `} `; export class DevelopersPage extends React.Component { -- cgit v1.2.3 From 0de654bbd52f7d4702cec9f1a9a5a2cbb793181b Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 19 Oct 2018 17:40:55 +0100 Subject: fix: scroll lag on doc reference and wiki pages by using react-scroll `spy` and only updating the sidebar menu items whose active state had changed --- packages/react-shared/src/components/link.tsx | 16 ++- .../src/components/nested_sidebar_menu.tsx | 119 --------------------- packages/react-shared/src/index.ts | 1 - .../website/ts/components/nested_sidebar_menu.tsx | 92 ++++++++++++++++ .../website/ts/pages/documentation/doc_page.tsx | 2 +- .../website/ts/pages/documentation/docs_home.tsx | 3 +- packages/website/ts/pages/wiki/wiki.tsx | 2 +- 7 files changed, 111 insertions(+), 124 deletions(-) delete mode 100644 packages/react-shared/src/components/nested_sidebar_menu.tsx create mode 100644 packages/website/ts/components/nested_sidebar_menu.tsx diff --git a/packages/react-shared/src/components/link.tsx b/packages/react-shared/src/components/link.tsx index 5a456109b..089e6e2ba 100644 --- a/packages/react-shared/src/components/link.tsx +++ b/packages/react-shared/src/components/link.tsx @@ -7,7 +7,7 @@ import * as validUrl from 'valid-url'; import { LinkType } from '../types'; import { constants } from '../utils/constants'; -interface LinkProps { +interface BaseLinkProps { to: string; shouldOpenInNewTab?: boolean; className?: string; @@ -18,6 +18,12 @@ interface LinkProps { fontColor?: string; } +interface ScrollLinkProps extends BaseLinkProps { + onActivityChanged?: (isActive: boolean) => void; +} + +type LinkProps = BaseLinkProps & ScrollLinkProps; + export interface LinkState {} /** @@ -103,11 +109,14 @@ export class Link extends React.Component { {this.props.children} @@ -119,6 +128,11 @@ export class Link extends React.Component { throw new Error(`Unrecognized LinkType: ${type}`); } } + private _onActivityChanged(isActive: boolean): void { + if (this.props.onActivityChanged) { + this.props.onActivityChanged(isActive); + } + } // HACK(fabio): For some reason, the react-scroll link decided to stop the propagation of click events. // We do however rely on these events being propagated in certain scenarios (e.g when the link // is within a dropdown we want to close upon being clicked). Because of this, we register the diff --git a/packages/react-shared/src/components/nested_sidebar_menu.tsx b/packages/react-shared/src/components/nested_sidebar_menu.tsx deleted file mode 100644 index 196c91af1..000000000 --- a/packages/react-shared/src/components/nested_sidebar_menu.tsx +++ /dev/null @@ -1,119 +0,0 @@ -import { ObjectMap } from '@0x/types'; -import * as _ from 'lodash'; -import MenuItem from 'material-ui/MenuItem'; -import * as React from 'react'; - -import { ALink, Styles } from '../types'; -import { colors } from '../utils/colors'; -import { utils } from '../utils/utils'; - -import { Link } from './link'; - -export interface NestedSidebarMenuProps { - sectionNameToLinks: ObjectMap; - sidebarHeader?: React.ReactNode; - shouldReformatMenuItemNames?: boolean; -} - -export interface NestedSidebarMenuState { - scrolledToId?: string; -} - -const styles: Styles = { - menuItem: { - minHeight: 0, - paddingLeft: 8, - borderRadius: 6, - }, - menuItemInnerDiv: { - color: colors.grey800, - fontSize: 14, - lineHeight: 2, - padding: 0, - whiteSpace: 'nowrap', - overflow: 'hidden', - textOverflow: 'ellipsis', - }, -}; - -export class NestedSidebarMenu extends React.Component { - public static defaultProps: Partial = { - shouldReformatMenuItemNames: true, - }; - private _urlIntervalCheckId: number | undefined = undefined; - constructor(props: NestedSidebarMenuProps) { - super(props); - this.state = {}; - } - public componentDidMount(): void { - this._urlIntervalCheckId = window.setInterval(() => { - const scrollId = location.hash.slice(1); - if (scrollId !== this.state.scrolledToId) { - this.setState({ - scrolledToId: scrollId, - }); - } - }, 200); - } - public componentWillUnmount(): void { - window.clearInterval(this._urlIntervalCheckId); - } - public render(): React.ReactNode { - const navigation = _.map(this.props.sectionNameToLinks, (links: ALink[], sectionName: string) => { - const finalSectionName = utils.convertCamelCaseToSpaces(sectionName); - // tslint:disable-next-line:no-unused-variable - return ( -
-
- {finalSectionName.toUpperCase()} -
- {this._renderMenuItems(links)} -
- ); - }); - return ( -
- {this.props.sidebarHeader} -
{navigation}
-
- ); - } - private _renderMenuItems(links: ALink[]): React.ReactNode[] { - const scrolledToId = this.state.scrolledToId; - const menuItems = _.map(links, link => { - const finalMenuItemName = this.props.shouldReformatMenuItemNames - ? utils.convertDashesToSpaces(link.title) - : link.title; - let menuItemStyle = styles.menuItem; - let menuItemInnerDivStyle = styles.menuItemInnerDiv; - const isScrolledTo = link.to === scrolledToId; - if (isScrolledTo) { - menuItemStyle = { - ...menuItemStyle, - backgroundColor: colors.lightLinkBlue, - }; - menuItemInnerDivStyle = { - ...menuItemInnerDivStyle, - color: colors.white, - fontWeight: 'bold', - }; - } - return ( -
- - - - {finalMenuItemName} - - - -
- ); - }); - return menuItems; - } -} diff --git a/packages/react-shared/src/index.ts b/packages/react-shared/src/index.ts index e33b09f19..a693f2a36 100644 --- a/packages/react-shared/src/index.ts +++ b/packages/react-shared/src/index.ts @@ -2,7 +2,6 @@ export { AnchorTitle } from './components/anchor_title'; export { MarkdownLinkBlock } from './components/markdown_link_block'; export { MarkdownCodeBlock } from './components/markdown_code_block'; export { MarkdownSection } from './components/markdown_section'; -export { NestedSidebarMenu } from './components/nested_sidebar_menu'; export { SectionHeader } from './components/section_header'; export { Link } from './components/link'; diff --git a/packages/website/ts/components/nested_sidebar_menu.tsx b/packages/website/ts/components/nested_sidebar_menu.tsx new file mode 100644 index 000000000..7de91bf8c --- /dev/null +++ b/packages/website/ts/components/nested_sidebar_menu.tsx @@ -0,0 +1,92 @@ +import { ALink, colors, Link, utils as sharedUtils } from '@0x/react-shared'; +import { ObjectMap } from '@0x/types'; +import * as _ from 'lodash'; +import * as React from 'react'; +import { Button } from 'ts/components/ui/button'; +import { Text } from 'ts/components/ui/text'; + +export interface NestedSidebarMenuProps { + sectionNameToLinks: ObjectMap; + sidebarHeader?: React.ReactNode; + shouldReformatMenuItemNames?: boolean; +} + +export const NestedSidebarMenu = (props: NestedSidebarMenuProps) => { + const navigation = _.map(props.sectionNameToLinks, (links: ALink[], sectionName: string) => { + const finalSectionName = sharedUtils.convertCamelCaseToSpaces(sectionName); + const menuItems = _.map(links, (link, i) => { + const menuItemTitle = props.shouldReformatMenuItemNames + ? _.capitalize(sharedUtils.convertDashesToSpaces(link.title)) + : link.title; + const finalLink = { + ...link, + title: menuItemTitle, + }; + return ; + }); + // tslint:disable-next-line:no-unused-variable + return ( +
+
+ {finalSectionName.toUpperCase()} +
+ {menuItems} +
+ ); + }); + return ( +
+ {props.sidebarHeader} +
{navigation}
+
+ ); +}; + +export interface MenuItemProps { + link: ALink; +} + +export interface MenuItemState { + isActive: boolean; +} + +export class MenuItem extends React.Component { + constructor(props: MenuItemProps) { + super(props); + const isActive = window.location.hash.slice(1) === props.link.to; + this.state = { + isActive, + }; + } + public render(): React.ReactNode { + const isActive = this.state.isActive; + return ( + + + + ); + } + private _onActivityChanged(isActive: boolean): void { + this.setState({ + isActive, + }); + } +} diff --git a/packages/website/ts/pages/documentation/doc_page.tsx b/packages/website/ts/pages/documentation/doc_page.tsx index 7157abfc9..28bf2dba1 100644 --- a/packages/website/ts/pages/documentation/doc_page.tsx +++ b/packages/website/ts/pages/documentation/doc_page.tsx @@ -6,13 +6,13 @@ import { SupportedDocJson, TypeDocUtils, } from '@0x/react-docs'; -import { NestedSidebarMenu } from '@0x/react-shared'; import findVersions = require('find-versions'); import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; import * as React from 'react'; import semverSort = require('semver-sort'); import { SidebarHeader } from 'ts/components/documentation/sidebar_header'; +import { NestedSidebarMenu } from 'ts/components/nested_sidebar_menu'; import { Container } from 'ts/components/ui/container'; import { DevelopersPage } from 'ts/pages/documentation/developers_page'; import { Dispatcher } from 'ts/redux/dispatcher'; diff --git a/packages/website/ts/pages/documentation/docs_home.tsx b/packages/website/ts/pages/documentation/docs_home.tsx index cf229cb3b..298b7ecf3 100644 --- a/packages/website/ts/pages/documentation/docs_home.tsx +++ b/packages/website/ts/pages/documentation/docs_home.tsx @@ -1,8 +1,9 @@ -import { ALink, colors, Link, NestedSidebarMenu } from '@0x/react-shared'; +import { ALink, colors, Link } from '@0x/react-shared'; import { ObjectMap } from '@0x/types'; import * as _ from 'lodash'; import * as React from 'react'; import { OverviewContent } from 'ts/components/documentation/overview_content'; +import { NestedSidebarMenu } from 'ts/components/nested_sidebar_menu'; import { Button } from 'ts/components/ui/button'; import { DevelopersPage } from 'ts/pages/documentation/developers_page'; import { Dispatcher } from 'ts/redux/dispatcher'; diff --git a/packages/website/ts/pages/wiki/wiki.tsx b/packages/website/ts/pages/wiki/wiki.tsx index a35404e33..76df4f06f 100644 --- a/packages/website/ts/pages/wiki/wiki.tsx +++ b/packages/website/ts/pages/wiki/wiki.tsx @@ -5,7 +5,6 @@ import { HeaderSizes, Link, MarkdownSection, - NestedSidebarMenu, utils as sharedUtils, } from '@0x/react-shared'; import { ObjectMap } from '@0x/types'; @@ -13,6 +12,7 @@ import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; import * as React from 'react'; import { SidebarHeader } from 'ts/components/documentation/sidebar_header'; +import { NestedSidebarMenu } from 'ts/components/nested_sidebar_menu'; import { Button } from 'ts/components/ui/button'; import { Container } from 'ts/components/ui/container'; import { DevelopersPage } from 'ts/pages/documentation/developers_page'; -- cgit v1.2.3 From bce90318687b38c35af75cd78bf3ee69271b42ad Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 19 Oct 2018 17:44:49 +0100 Subject: chore: use `colors` module --- packages/website/ts/components/nested_sidebar_menu.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/website/ts/components/nested_sidebar_menu.tsx b/packages/website/ts/components/nested_sidebar_menu.tsx index 7de91bf8c..f83833d69 100644 --- a/packages/website/ts/components/nested_sidebar_menu.tsx +++ b/packages/website/ts/components/nested_sidebar_menu.tsx @@ -70,7 +70,7 @@ export class MenuItem extends React.Component { borderRadius="4px" padding="0.4em 6px" width="100%" - backgroundColor={isActive ? colors.lightLinkBlue : 'rgb(245, 245, 245)'} + backgroundColor={isActive ? colors.lightLinkBlue : colors.grey100} fontSize="14px" textAlign="left" > -- cgit v1.2.3 From 66465816ca049118d58ca34bada241fd146f2656 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 19 Oct 2018 10:19:48 -0700 Subject: Getting rid of displayName, and rename usdSection -> _renderUsdSection --- packages/instant/src/components/order_details.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx index a7971e1fd..704009d89 100644 --- a/packages/instant/src/components/order_details.tsx +++ b/packages/instant/src/components/order_details.tsx @@ -74,7 +74,6 @@ export class EthAmountRow extends React.Component { shouldEmphasize: false, isEthAmountInBaseUnits: true, }; - public static displayName = 'EthAmountRow'; public render(): React.ReactNode { const { rowLabel, ethAmount, isEthAmountInBaseUnits, shouldEmphasize, isLoading } = this.props; @@ -87,7 +86,7 @@ export class EthAmountRow extends React.Component { {rowLabel} - {this._usdSection()} + {this._renderUsdSection()} {ethFormatter( ethAmount, @@ -102,7 +101,7 @@ export class EthAmountRow extends React.Component { ); } - private _usdSection(): React.ReactNode { + private _renderUsdSection(): React.ReactNode { const usdFormatter = this.props.isEthAmountInBaseUnits ? format.ethBaseAmountInUsd : format.ethUnitAmountInUsd; const shouldHideUsdPriceSection = _.isUndefined(this.props.ethUsdPrice) || _.isUndefined(this.props.ethAmount); return shouldHideUsdPriceSection ? null : ( -- cgit v1.2.3 From 2f4e498a099ebbd8078139f90a054941e427de15 Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 19 Oct 2018 10:32:37 -0700 Subject: Refactor to make placeholder logic more straightforward --- packages/instant/src/components/instant_heading.tsx | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx index 48cda7f88..265c3e0a5 100644 --- a/packages/instant/src/components/instant_heading.tsx +++ b/packages/instant/src/components/instant_heading.tsx @@ -20,7 +20,6 @@ export interface InstantHeadingProps { const placeholderColor = ColorOption.white; export class InstantHeading extends React.Component { public render(): React.ReactNode { - const placeholderAmountToAlwaysShow = this._placeholderAmountToAlwaysShow(); return ( { - {placeholderAmountToAlwaysShow || this._ethAmount()} - {placeholderAmountToAlwaysShow || this._dollarAmount()} + + {this._placeholderOrAmount(this._ethAmount.bind(this))} + + {this._placeholderOrAmount(this._dollarAmount.bind(this))} ); } - private _placeholderAmountToAlwaysShow(): React.ReactNode | null { + private _placeholderOrAmount(amountFunction: () => React.ReactNode): React.ReactNode { if (this.props.quoteRequestState === AsyncProcessState.PENDING) { return ; } if (_.isUndefined(this.props.selectedAssetAmount)) { return ; } - return null; + return amountFunction(); } private _ethAmount(): React.ReactNode { -- cgit v1.2.3 From 6588cf919ef70f54754b1428df51e967b817788a Mon Sep 17 00:00:00 2001 From: Steve Klebanoff Date: Fri, 19 Oct 2018 10:34:44 -0700 Subject: dont export PlainPlaceholder --- packages/instant/src/components/amount_placeholder.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/instant/src/components/amount_placeholder.tsx b/packages/instant/src/components/amount_placeholder.tsx index e27d0ba81..6ef8f0ac3 100644 --- a/packages/instant/src/components/amount_placeholder.tsx +++ b/packages/instant/src/components/amount_placeholder.tsx @@ -6,10 +6,10 @@ import { Pulse } from './animations/pulse'; import { Text } from './ui'; -export interface PlainPlaceholder { +interface PlainPlaceholder { color: ColorOption; } -export const PlainPlaceholder: React.StatelessComponent = props => ( +const PlainPlaceholder: React.StatelessComponent = props => ( -- cgit v1.2.3 From ce4da870d79a589913d1660de8cf012b894357c6 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 19 Oct 2018 19:38:12 +0100 Subject: chore: use Text --- packages/website/ts/components/nested_sidebar_menu.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/website/ts/components/nested_sidebar_menu.tsx b/packages/website/ts/components/nested_sidebar_menu.tsx index f83833d69..021e3f0e5 100644 --- a/packages/website/ts/components/nested_sidebar_menu.tsx +++ b/packages/website/ts/components/nested_sidebar_menu.tsx @@ -27,9 +27,9 @@ export const NestedSidebarMenu = (props: NestedSidebarMenuProps) => { // tslint:disable-next-line:no-unused-variable return (
-
+ {finalSectionName.toUpperCase()} -
+ {menuItems}
); -- cgit v1.2.3 From b49e5c76e485beead2554027a3ff8af101bce1d5 Mon Sep 17 00:00:00 2001 From: Fabio Berger Date: Fri, 19 Oct 2018 19:38:20 +0100 Subject: Use em for all --- packages/website/ts/components/nested_sidebar_menu.tsx | 2 +- packages/website/ts/pages/documentation/docs_home.tsx | 2 +- packages/website/ts/pages/wiki/wiki.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/website/ts/components/nested_sidebar_menu.tsx b/packages/website/ts/components/nested_sidebar_menu.tsx index 021e3f0e5..db7d55261 100644 --- a/packages/website/ts/components/nested_sidebar_menu.tsx +++ b/packages/website/ts/components/nested_sidebar_menu.tsx @@ -68,7 +68,7 @@ export class MenuItem extends React.Component { >