diff options
Diffstat (limited to 'packages/website/ts/components')
86 files changed, 1220 insertions, 723 deletions
diff --git a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx index c8e10303f..a0114d898 100644 --- a/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx +++ b/packages/website/ts/components/dialogs/blockchain_err_dialog.tsx @@ -1,4 +1,4 @@ -import { colors, Networks } from '@0xproject/react-shared'; +import { colors, Networks } from '@0x/react-shared'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; @@ -22,7 +22,7 @@ export class BlockchainErrDialog extends React.Component<BlockchainErrDialogProp key="blockchainErrOk" label="Ok" primary={true} - onTouchTap={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)} + onClick={this.props.toggleDialogFn.bind(this.props.toggleDialogFn, false)} />, ]; diff --git a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx index 5f4bf8519..9b9421f1a 100644 --- a/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx +++ b/packages/website/ts/components/dialogs/eth_weth_conversion_dialog.tsx @@ -1,5 +1,5 @@ -import { colors } from '@0xproject/react-shared'; -import { BigNumber } from '@0xproject/utils'; +import { colors } from '@0x/react-shared'; +import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; @@ -54,8 +54,8 @@ export class EthWethConversionDialog extends React.Component< } public render(): React.ReactNode { const convertDialogActions = [ - <FlatButton key="cancel" label="Cancel" onTouchTap={this._onCancel.bind(this)} />, - <FlatButton key="convert" label="Convert" primary={true} onTouchTap={this._onConvertClick.bind(this)} />, + <FlatButton key="cancel" label="Cancel" onClick={this._onCancel.bind(this)} />, + <FlatButton key="convert" label="Convert" primary={true} onClick={this._onConvertClick.bind(this)} />, ]; const title = this.props.direction === Side.Deposit ? 'Wrap ETH' : 'Unwrap WETH'; return !_.isUndefined(this.props.etherBalanceInWei) ? ( diff --git a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx index d2f373d67..a9f591150 100644 --- a/packages/website/ts/components/dialogs/ledger_config_dialog.tsx +++ b/packages/website/ts/components/dialogs/ledger_config_dialog.tsx @@ -1,6 +1,6 @@ -import { colors, constants as sharedConstants } from '@0xproject/react-shared'; -import { BigNumber, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { colors, constants as sharedConstants } from '@0x/react-shared'; +import { BigNumber, logUtils } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; @@ -64,7 +64,7 @@ export class LedgerConfigDialog extends React.Component<LedgerConfigDialogProps, } public render(): React.ReactNode { const dialogActions = [ - <FlatButton key="ledgerConnectCancel" label="Cancel" onTouchTap={this._onClose.bind(this)} />, + <FlatButton key="ledgerConnectCancel" label="Cancel" onClick={this._onClose.bind(this)} />, ]; const dialogTitle = this.state.stepIndex === LedgerSteps.CONNECT ? 'Connect to your Ledger' : 'Select desired address'; diff --git a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx index 41a17fe96..326df2a8c 100644 --- a/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx +++ b/packages/website/ts/components/dialogs/portal_disclaimer_dialog.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; @@ -13,7 +13,7 @@ export const PortalDisclaimerDialog = (props: PortalDisclaimerDialogProps) => { <Dialog title="0x Portal Disclaimer" titleStyle={{ fontWeight: 100 }} - actions={[<FlatButton key="portalAgree" label="I Agree" onTouchTap={props.onToggleDialog} />]} + actions={[<FlatButton key="portalAgree" label="I Agree" onClick={props.onToggleDialog} />]} open={props.isOpen} onRequestClose={props.onToggleDialog} autoScrollBodyContent={true} diff --git a/packages/website/ts/components/dialogs/send_dialog.tsx b/packages/website/ts/components/dialogs/send_dialog.tsx index c1179dbd0..5f6927cef 100644 --- a/packages/website/ts/components/dialogs/send_dialog.tsx +++ b/packages/website/ts/components/dialogs/send_dialog.tsx @@ -1,4 +1,4 @@ -import { BigNumber } from '@0xproject/utils'; +import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; @@ -38,13 +38,13 @@ export class SendDialog extends React.Component<SendDialogProps, SendDialogState } public render(): React.ReactNode { const transferDialogActions = [ - <FlatButton key="cancelTransfer" label="Cancel" onTouchTap={this._onCancel.bind(this)} />, + <FlatButton key="cancelTransfer" label="Cancel" onClick={this._onCancel.bind(this)} />, <FlatButton key="sendTransfer" disabled={this._hasErrors()} label="Send" primary={true} - onTouchTap={this._onSendClick.bind(this)} + onClick={this._onSendClick.bind(this)} />, ]; return ( diff --git a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx index 3751ce06f..c8d5af6b6 100644 --- a/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx +++ b/packages/website/ts/components/dialogs/track_token_confirmation_dialog.tsx @@ -43,12 +43,12 @@ export class TrackTokenConfirmationDialog extends React.Component< <FlatButton key="trackNo" label="No" - onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)} + onClick={this._onTrackConfirmationRespondedAsync.bind(this, false)} />, <FlatButton key="trackYes" label="Yes" - onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)} + onClick={this._onTrackConfirmationRespondedAsync.bind(this, true)} />, ]} open={this.props.isOpen} diff --git a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx index 3ebab03ef..bbec1d649 100644 --- a/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx +++ b/packages/website/ts/components/dialogs/u2f_not_supported_dialog.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; @@ -14,7 +14,7 @@ export const U2fNotSupportedDialog = (props: U2fNotSupportedDialogProps) => { <Dialog title="U2F Not Supported" titleStyle={{ fontWeight: 100 }} - actions={[<FlatButton key="u2fNo" label="Ok" onTouchTap={props.onToggleDialog} />]} + actions={[<FlatButton key="u2fNo" label="Ok" onClick={props.onToggleDialog} />]} open={props.isOpen} onRequestClose={props.onToggleDialog} autoScrollBodyContent={true} diff --git a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx index 78b270c1e..cf2c4dda5 100644 --- a/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx +++ b/packages/website/ts/components/dialogs/wrapped_eth_section_notice_dialog.tsx @@ -14,7 +14,7 @@ export const WrappedEthSectionNoticeDialog = (props: WrappedEthSectionNoticeDial title="Dedicated Wrapped Ether Section" titleStyle={{ fontWeight: 100 }} actions={[ - <FlatButton key="acknowledgeWrapEthSection" label="Sounds good" onTouchTap={props.onToggleDialog} />, + <FlatButton key="acknowledgeWrapEthSection" label="Sounds good" onClick={props.onToggleDialog} />, ]} open={props.isOpen} onRequestClose={props.onToggleDialog} diff --git a/packages/website/ts/components/documentation/docs_logo.tsx b/packages/website/ts/components/documentation/docs_logo.tsx new file mode 100644 index 000000000..2840d5960 --- /dev/null +++ b/packages/website/ts/components/documentation/docs_logo.tsx @@ -0,0 +1,20 @@ +import { Link } from '@0x/react-shared'; +import * as React from 'react'; +import { WebsitePaths } from 'ts/types'; + +export interface DocsLogoProps { + height: number; + containerStyle?: React.CSSProperties; +} + +export const DocsLogo: React.StatelessComponent<DocsLogoProps> = props => { + return ( + <Link to={WebsitePaths.Docs}> + <img src="/images/docs_logo.svg" height={props.height} /> + </Link> + ); +}; + +DocsLogo.defaultProps = { + containerStyle: {}, +}; diff --git a/packages/website/ts/components/documentation/docs_top_bar.tsx b/packages/website/ts/components/documentation/docs_top_bar.tsx new file mode 100644 index 000000000..2054d0860 --- /dev/null +++ b/packages/website/ts/components/documentation/docs_top_bar.tsx @@ -0,0 +1,108 @@ +import { ALink, colors, Link } from '@0x/react-shared'; +import * as _ from 'lodash'; +import Drawer from 'material-ui/Drawer'; +import * as React from 'react'; +import { DocsLogo } from 'ts/components/documentation/docs_logo'; +import { Container } from 'ts/components/ui/container'; +import { Text } from 'ts/components/ui/text'; +import { Deco, Key, ScreenWidths } from 'ts/types'; +import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; + +export interface DocsTopBarProps { + location: Location; + screenWidth: ScreenWidths; + translate: Translate; + sidebar?: React.ReactNode; +} + +interface DocsTopBarState { + isDrawerOpen: boolean; +} + +export class DocsTopBar extends React.Component<DocsTopBarProps, DocsTopBarState> { + constructor(props: DocsTopBarProps) { + super(props); + this.state = { + isDrawerOpen: false, + }; + } + public componentWillReceiveProps(nextProps: DocsTopBarProps): void { + if (nextProps.location.pathname !== this.props.location.pathname) { + this.setState({ + isDrawerOpen: false, + }); + } + } + public render(): React.ReactNode { + return ( + <Container height={80}> + <Container + className="flex items-center lg-pt3 md-pt3 sm-pt1 lg-mt1 md-mt1 sm-mt0 lg-justify-end md-justify-end sm-justify-start" + width="100%" + > + <Container className="sm-hide xs-hide"> + <Container className="flex items-center justify-between right" width="300px"> + {this._renderMenuItems(constants.DEVELOPER_TOPBAR_LINKS)} + </Container> + </Container> + <Container className="lg-hide md-hide"> + <Container paddingTop="6px"> + <DocsLogo height={30} /> + </Container> + </Container> + <Container className="md-hide lg-hide absolute" right="18px" top="12px"> + <i + className="zmdi zmdi-menu" + style={{ + color: colors.grey700, + fontSize: 30, + cursor: 'pointer', + }} + onClick={this._onMenuButtonClick.bind(this)} + /> + </Container> + </Container> + <Container width={'100%'} height={'1px'} backgroundColor={colors.grey300} marginTop={'13px'} /> + {this.props.screenWidth === ScreenWidths.Sm && this._renderDrawer()} + </Container> + ); + } + private _renderMenuItems(menuItemLinks: ALink[]): React.ReactNode { + const menuItems = _.map(menuItemLinks, menuItemInfo => { + return ( + <Link + key={`menu-item-${menuItemInfo.title}`} + to={menuItemInfo.to} + shouldOpenInNewTab={menuItemInfo.shouldOpenInNewTab} + > + <Container className="flex items-center" paddingLeft="4px"> + <Text fontSize="16px" fontColor={colors.lightLinkBlue} fontWeight="bold"> + {this.props.translate.get(menuItemInfo.title as Key, Deco.Cap)} + </Text> + </Container> + </Link> + ); + }); + return menuItems; + } + private _renderDrawer(): React.ReactNode { + return ( + <Drawer + open={this.state.isDrawerOpen} + docked={false} + openSecondary={true} + onRequestChange={this._onMenuButtonClick.bind(this)} + > + <Container className="clearfix pl1 pt2" onClick={this._onMenuButtonClick.bind(this)}> + {this.props.sidebar} + </Container> + </Drawer> + ); + } + private _onMenuButtonClick(): void { + this.setState({ + isDrawerOpen: !this.state.isDrawerOpen, + }); + } +} diff --git a/packages/website/ts/components/documentation/overview_content.tsx b/packages/website/ts/components/documentation/overview_content.tsx new file mode 100644 index 000000000..caabaf874 --- /dev/null +++ b/packages/website/ts/components/documentation/overview_content.tsx @@ -0,0 +1,134 @@ +import { colors, Link, MarkdownLinkBlock, utils as sharedUtils } from '@0x/react-shared'; +import { ObjectMap } from '@0x/types'; +import * as _ from 'lodash'; +import * as React from 'react'; +import * as ReactMarkdown from 'react-markdown'; +import { Element as ScrollElement } from 'react-scroll'; +import { TutorialButton } from 'ts/components/documentation/tutorial_button'; +import { Container } from 'ts/components/ui/container'; +import { Text } from 'ts/components/ui/text'; +import { Deco, Key, Package, TutorialInfo } from 'ts/types'; +import { Translate } from 'ts/utils/translate'; + +export interface OverviewContentProps { + translate: Translate; + tutorials: TutorialInfo[]; + categoryToPackages: ObjectMap<Package[]>; +} + +export interface OverviewContentState {} + +export class OverviewContent extends React.Component<OverviewContentProps, OverviewContentState> { + public render(): React.ReactNode { + return ( + <Container> + {this._renderSectionTitle(this.props.translate.get(Key.StartBuildOn0x, Deco.Cap))} + <Container paddingTop="12px"> + {this._renderSectionDescription(this.props.translate.get(Key.StartBuildOn0xDescription, Deco.Cap))} + <Container marginTop="36px"> + {_.map(this.props.tutorials, tutorialInfo => ( + <ScrollElement + name={sharedUtils.getIdFromName( + this.props.translate.get(tutorialInfo.link.title as Key, Deco.Cap), + )} + key={`tutorial-${tutorialInfo.link.title}`} + > + <TutorialButton translate={this.props.translate} tutorialInfo={tutorialInfo} /> + </ScrollElement> + ))} + </Container> + </Container> + <Container marginTop="32px" paddingBottom="100px"> + {this._renderSectionTitle(this.props.translate.get(Key.LibrariesAndTools, Deco.CapWords))} + <Container paddingTop="12px"> + {this._renderSectionDescription( + this.props.translate.get(Key.LibrariesAndToolsDescription, Deco.Cap), + )} + <Container marginTop="36px"> + {_.map(this.props.categoryToPackages, (pkgs, category) => + this._renderPackageCategory(category, pkgs), + )} + </Container> + </Container> + </Container> + </Container> + ); + } + private _renderPackageCategory(category: string, pkgs: Package[]): React.ReactNode { + return ( + <Container key={`category-${category}`}> + <Text fontSize="18px">{category}</Text> + <Container>{_.map(pkgs, pkg => this._renderPackage(pkg))}</Container> + </Container> + ); + } + private _renderPackage(pkg: Package): React.ReactNode { + const id = sharedUtils.getIdFromName(pkg.link.title); + return ( + <ScrollElement name={id} key={`package-${pkg.link.title}`}> + <Container className="pb2"> + <Container width="100%" height="1px" backgroundColor={colors.grey300} marginTop="11px" /> + <Container className="clearfix mt2 pt1"> + <Container className="md-col lg-col md-col-4 lg-col-4"> + <Link + to={pkg.link.to} + fontColor={colors.lightLinkBlue} + shouldOpenInNewTab={!!pkg.link.shouldOpenInNewTab} + > + <Text Tag="div" fontColor={colors.lightLinkBlue} fontWeight="bold"> + {pkg.link.title} + </Text> + </Link> + </Container> + <Container className="md-col lg-col md-col-6 lg-col-6 sm-py2"> + <Text fontColor={colors.grey700}> + <ReactMarkdown + source={pkg.description} + renderers={{ + link: MarkdownLinkBlock, + paragraph: 'span', + }} + /> + </Text> + </Container> + <Container className="md-col lg-col md-col-2 lg-col-2 sm-pb2 relative"> + <Container position="absolute" right="0px"> + <Link + to={pkg.link.to} + fontColor={colors.lightLinkBlue} + shouldOpenInNewTab={!!pkg.link.shouldOpenInNewTab} + > + <Container className="flex"> + <Container>{this.props.translate.get(Key.More, Deco.Cap)}</Container> + <Container paddingTop="1px" paddingLeft="6px"> + <i + className="zmdi zmdi-chevron-right bold" + style={{ fontSize: 18, color: colors.lightLinkBlue }} + /> + </Container> + </Container> + </Link> + </Container> + </Container> + </Container> + </Container> + </ScrollElement> + ); + } + private _renderSectionTitle(text: string): React.ReactNode { + return ( + <Container paddingTop="30px"> + <Text fontColor={colors.projectsGrey} fontSize="30px" fontWeight="bold"> + {text} + </Text> + </Container> + ); + } + private _renderSectionDescription(text: string): React.ReactNode { + return ( + <Text fontColor={colors.linkSectionGrey} fontSize="16px" fontFamily="Roboto Mono"> + {text} + </Text> + ); + } +} // tslint:disable:max-file-line-count diff --git a/packages/website/ts/components/documentation/sidebar_header.tsx b/packages/website/ts/components/documentation/sidebar_header.tsx new file mode 100644 index 000000000..fece2704b --- /dev/null +++ b/packages/website/ts/components/documentation/sidebar_header.tsx @@ -0,0 +1,57 @@ +import { colors } from '@0x/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; +import { VersionDropDown } from 'ts/components/documentation/version_drop_down'; +import { Container } from 'ts/components/ui/container'; +import { Text } from 'ts/components/ui/text'; +import { ScreenWidths } from 'ts/types'; + +export interface SidebarHeaderProps { + screenWidth: ScreenWidths; + title: string; + docsVersion?: string; + availableDocVersions?: string[]; + onVersionSelected?: () => void; +} + +export const SidebarHeader: React.StatelessComponent<SidebarHeaderProps> = ({ + screenWidth, + title, + docsVersion, + availableDocVersions, + onVersionSelected, +}) => { + return ( + <Container> + <Container className="flex justify-bottom"> + <Container className="left pl1" width="150px"> + <Text + fontColor={colors.lightLinkBlue} + fontSize={screenWidth === ScreenWidths.Sm ? '20px' : '22px'} + fontWeight="bold" + > + {title} + </Text> + </Container> + {!_.isUndefined(docsVersion) && + !_.isUndefined(availableDocVersions) && + !_.isUndefined(onVersionSelected) && ( + <div className="right" style={{ alignSelf: 'flex-end' }}> + <VersionDropDown + selectedVersion={docsVersion} + versions={availableDocVersions} + onVersionSelected={onVersionSelected} + /> + </div> + )} + </Container> + <Container + width={'100%'} + height={'1px'} + backgroundColor={colors.grey300} + marginTop="20px" + marginBottom="27px" + /> + </Container> + ); +}; diff --git a/packages/website/ts/components/documentation/tutorial_button.tsx b/packages/website/ts/components/documentation/tutorial_button.tsx new file mode 100644 index 000000000..b747ef598 --- /dev/null +++ b/packages/website/ts/components/documentation/tutorial_button.tsx @@ -0,0 +1,59 @@ +import { colors, Link } from '@0x/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; +import { Container } from 'ts/components/ui/container'; +import { Text } from 'ts/components/ui/text'; +import { Deco, Key, TutorialInfo } from 'ts/types'; +import { Translate } from 'ts/utils/translate'; + +import { styled } from 'ts/style/theme'; + +export interface TutorialButtonProps { + className?: string; + translate: Translate; + tutorialInfo: TutorialInfo; +} + +const PlainTutorialButton: React.StatelessComponent<TutorialButtonProps> = ({ translate, tutorialInfo, className }) => ( + <Container className={className}> + <Link to={tutorialInfo.link.to} shouldOpenInNewTab={tutorialInfo.link.shouldOpenInNewTab}> + <div className="flex relative"> + <div className="col col-1 flex items-center sm-pr3"> + <img src={tutorialInfo.iconUrl} height={40} /> + </div> + <div className="lg-pl2 md-pl2 sm-pl3 col col-10"> + <Text Tag="div" fontSize="18" fontColor={colors.lightLinkBlue} fontWeight="bold"> + {translate.get(tutorialInfo.link.title as Key, Deco.Cap)} + </Text> + <Text Tag="div" fontColor={colors.grey750} fontSize="16"> + {translate.get(tutorialInfo.description as Key, Deco.Cap)} + </Text> + </div> + <div className="col col-1 flex items-center justify-end"> + <div className="right"> + <i + className="zmdi zmdi-chevron-right bold" + style={{ fontSize: 26, color: colors.lightLinkBlue }} + /> + </div> + </div> + </div> + </Link> + </Container> +); + +export const TutorialButton = styled(PlainTutorialButton)` + border-radius: 4px; + border: 1px solid ${colors.grey325}; + background-color: ${colors.white}; + &:hover { + border: 1px solid ${colors.lightLinkBlue}; + background-color: ${colors.lightestBlue}; + } + padding: 20px; + margin-bottom: 15px; +`; + +TutorialButton.defaultProps = {}; + +TutorialButton.displayName = 'TutorialButton'; diff --git a/packages/website/ts/components/documentation/version_drop_down.tsx b/packages/website/ts/components/documentation/version_drop_down.tsx new file mode 100644 index 000000000..a1c8b0547 --- /dev/null +++ b/packages/website/ts/components/documentation/version_drop_down.tsx @@ -0,0 +1,80 @@ +import { colors } from '@0x/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; +import { Button } from 'ts/components/ui/button'; +import { Container } from 'ts/components/ui/container'; +import { DropDown, DropdownMouseEvent } from 'ts/components/ui/drop_down'; +import { Text } from 'ts/components/ui/text'; +import { styled } from 'ts/style/theme'; + +interface ActiveNodeProps { + className?: string; + selectedVersion: string; +} + +const PlainActiveNode: React.StatelessComponent<ActiveNodeProps> = ({ className, selectedVersion }) => ( + <Container className={className}> + <Container className="flex justify-center"> + <Text fontColor={colors.grey700} fontSize="12px"> + v {selectedVersion} + </Text> + <Container paddingLeft="6px"> + <i className="zmdi zmdi-chevron-down" style={{ fontSize: 17, color: 'rgba(153, 153, 153, 0.8)' }} /> + </Container> + </Container> + </Container> +); + +const ActiveNode = styled(PlainActiveNode)` + cursor: pointer; + border: 2px solid ${colors.beigeWhite}; + border-radius: 4px; + padding: 4px 6px 4px 8px; +`; + +interface VersionDropDownProps { + selectedVersion: string; + versions: string[]; + onVersionSelected: (semver: string) => void; +} + +interface VersionDropDownState {} + +export class VersionDropDown extends React.Component<VersionDropDownProps, VersionDropDownState> { + public render(): React.ReactNode { + const activeNode = <ActiveNode selectedVersion={this.props.selectedVersion} />; + return ( + <DropDown + activateEvent={DropdownMouseEvent.Click} + activeNode={activeNode} + popoverContent={this._renderDropdownMenu()} + anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }} + targetOrigin={{ horizontal: 'middle', vertical: 'top' }} + popoverStyle={{ borderRadius: 4 }} + /> + ); + } + private _renderDropdownMenu(): React.ReactNode { + const items = _.map(this.props.versions, version => { + const isSelected = version === this.props.selectedVersion; + return ( + <Container key={`dropdown-items-${version}`}> + <Button + borderRadius="0px" + padding="0.8em 0em" + width="100%" + isDisabled={isSelected} + onClick={this._onClick.bind(this, version)} + > + v {version} + </Button> + </Container> + ); + }); + const dropdownMenu = <Container width="88px">{items}</Container>; + return dropdownMenu; + } + private _onClick(selectedVersion: string): void { + this.props.onVersionSelected(selectedVersion); + } +} diff --git a/packages/website/ts/components/dropdowns/developers_drop_down.tsx b/packages/website/ts/components/dropdowns/developers_drop_down.tsx new file mode 100644 index 000000000..6e85c1499 --- /dev/null +++ b/packages/website/ts/components/dropdowns/developers_drop_down.tsx @@ -0,0 +1,162 @@ +import { ALink, colors, Link } from '@0x/react-shared'; +import * as _ from 'lodash'; +import * as React from 'react'; +import { Container } from 'ts/components/ui/container'; +import { DropDown } from 'ts/components/ui/drop_down'; +import { Text } from 'ts/components/ui/text'; +import { Deco, Key, WebsitePaths } from 'ts/types'; +import { constants } from 'ts/utils/constants'; +import { Translate } from 'ts/utils/translate'; + +const gettingStartedKeyToLinkInfo1: ALink[] = [ + { + title: Key.BuildARelayer, + to: `${WebsitePaths.Wiki}#Build-A-Relayer`, + }, + { + title: Key.OrderBasics, + to: `${WebsitePaths.Wiki}#Create,-Validate,-Fill-Order`, + }, +]; +const gettingStartedKeyToLinkInfo2: ALink[] = [ + { + title: Key.DevelopOnEthereum, + to: `${WebsitePaths.Wiki}#Ethereum-Development`, + }, + { + title: Key.UseNetworkedLiquidity, + to: `${WebsitePaths.Wiki}#Find,-Submit,-Fill-Order-From-Relayer`, + }, +]; +const popularDocsToLinkInfos: ALink[] = [ + { + title: Key.ZeroExJs, + to: WebsitePaths.ZeroExJs, + }, + { + title: Key.Connect, + to: WebsitePaths.Connect, + }, + { + title: Key.SmartContract, + to: WebsitePaths.SmartContracts, + }, +]; +const usefulLinksToLinkInfo: ALink[] = [ + { + title: Key.Wiki, + to: WebsitePaths.Wiki, + }, + { + title: Key.Github, + to: constants.URL_GITHUB_ORG, + shouldOpenInNewTab: true, + }, + { + title: Key.Whitepaper, + to: WebsitePaths.Whitepaper, + shouldOpenInNewTab: true, + }, +]; + +interface DevelopersDropDownProps { + location: Location; + translate: Translate; + menuItemStyles: React.CSSProperties; + menuIconStyle: React.CSSProperties; +} + +interface DevelopersDropDownState {} + +export class DevelopersDropDown extends React.Component<DevelopersDropDownProps, DevelopersDropDownState> { + public render(): React.ReactNode { + const activeNode = ( + <Container className="flex relative" paddingRight="10"> + <Text fontColor={this.props.menuIconStyle.color}> + {this.props.translate.get(Key.Developers, Deco.Cap)} + </Text> + </Container> + ); + return ( + <DropDown + activeNode={activeNode} + popoverContent={this._renderDropdownMenu()} + anchorOrigin={{ horizontal: 'left', vertical: 'bottom' }} + targetOrigin={{ horizontal: 'left', vertical: 'top' }} + style={this.props.menuItemStyles} + popoverStyle={{ borderRadius: 4, width: 397, height: 373, marginTop: 0 }} + /> + ); + } + private _renderDropdownMenu(): React.ReactNode { + const sectionPadding = '28px'; + const dropdownMenu = ( + <Container> + <Container className="flex" padding={sectionPadding}> + <Container paddingRight="45px"> + {this._renderLinkSection(gettingStartedKeyToLinkInfo1, 'Getting started')} + </Container> + <Container>{this._renderLinkSection(gettingStartedKeyToLinkInfo2)}</Container> + </Container> + <Container width="100%" height="1px" backgroundColor={colors.grey300} /> + <Container className="flex" padding={sectionPadding}> + <Container paddingRight="62px"> + <Container>{this._renderLinkSection(popularDocsToLinkInfos, 'Popular docs')}</Container> + </Container> + <Container> + <Container>{this._renderLinkSection(usefulLinksToLinkInfo, 'Useful links')}</Container> + </Container> + </Container> + <Link to={WebsitePaths.Docs} fontColor={colors.lightBlueA700}> + <Container + padding="0.9rem" + backgroundColor={colors.lightBgGrey} + borderBottomLeftRadius={4} + borderBottomRightRadius={4} + > + <Text fontColor={colors.lightBlueA700} fontWeight="bold" fontSize="14px" textAlign="center"> + {this.props.translate.get(Key.ViewAllDocumentation, Deco.Upper)} + </Text> + </Container> + </Link> + </Container> + ); + return dropdownMenu; + } + private _renderLinkSection(links: ALink[], title: string = ''): React.ReactNode { + const numLinks = links.length; + let i = 0; + const renderLinks = _.map(links, (link: ALink) => { + const isWikiLink = _.startsWith(link.to, WebsitePaths.Wiki) && _.includes(link.to, '#'); + const isOnWiki = this.props.location.pathname === WebsitePaths.Wiki; + let to = link.to; + if (isWikiLink && isOnWiki) { + to = `${link.to.split('#')[1]}`; + } + i++; + const isLast = i === numLinks; + const linkText = this.props.translate.get(link.title as Key, Deco.Cap); + return ( + <Container className={`pr1 pt1 ${!isLast && 'pb1'}`} key={`dev-dropdown-link-${link.title}`}> + <Link to={to} shouldOpenInNewTab={!!link.shouldOpenInNewTab}> + <Text fontFamily="Roboto, Roboto Mono" fontColor={colors.lightBlueA700}> + {linkText} + </Text> + </Link> + </Container> + ); + }); + return ( + <Container> + <Container height="33px"> + {!_.isEmpty(title) && ( + <Text letterSpacing={1} fontColor={colors.linkSectionGrey} fontSize="14px" fontWeight={600}> + {title.toUpperCase()} + </Text> + )} + </Container> + {renderLinks} + </Container> + ); + } +} diff --git a/packages/website/ts/components/dropdowns/network_drop_down.tsx b/packages/website/ts/components/dropdowns/network_drop_down.tsx index 2fd2785d1..df2d72edc 100644 --- a/packages/website/ts/components/dropdowns/network_drop_down.tsx +++ b/packages/website/ts/components/dropdowns/network_drop_down.tsx @@ -1,4 +1,4 @@ -import { constants as sharedConstants } from '@0xproject/react-shared'; +import { constants as sharedConstants } from '@0x/react-shared'; import * as _ from 'lodash'; import DropDownMenu from 'material-ui/DropDownMenu'; import MenuItem from 'material-ui/MenuItem'; diff --git a/packages/website/ts/components/eth_weth_conversion_button.tsx b/packages/website/ts/components/eth_weth_conversion_button.tsx index b0091a1c1..536ba924b 100644 --- a/packages/website/ts/components/eth_weth_conversion_button.tsx +++ b/packages/website/ts/components/eth_weth_conversion_button.tsx @@ -1,5 +1,5 @@ -import { BigNumber, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { BigNumber, logUtils } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; diff --git a/packages/website/ts/components/eth_wrappers.tsx b/packages/website/ts/components/eth_wrappers.tsx index 0b282b2a1..2af4252bd 100644 --- a/packages/website/ts/components/eth_wrappers.tsx +++ b/packages/website/ts/components/eth_wrappers.tsx @@ -1,6 +1,6 @@ -import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0x/react-shared'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import Divider from 'material-ui/Divider'; import { Table, TableBody, TableHeader, TableHeaderColumn, TableRow, TableRowColumn } from 'material-ui/Table'; diff --git a/packages/website/ts/components/fill_order.tsx b/packages/website/ts/components/fill_order.tsx index 7da2e0870..3d0203573 100644 --- a/packages/website/ts/components/fill_order.tsx +++ b/packages/website/ts/components/fill_order.tsx @@ -1,15 +1,13 @@ -import { getOrderHashHex, isValidSignature } from '@0xproject/order-utils'; -import { colors } from '@0xproject/react-shared'; -import { Order as ZeroExOrder } from '@0xproject/types'; -import { BigNumber, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { assetDataUtils, orderHashUtils } from '@0x/order-utils'; +import { colors, Link } from '@0x/react-shared'; +import { BigNumber, logUtils } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as accounting from 'accounting'; import * as _ from 'lodash'; import { Card, CardHeader, CardText } from 'material-ui/Card'; import Divider from 'material-ui/Divider'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; -import { Link } from 'react-router-dom'; import { Blockchain } from 'ts/blockchain'; import { TrackTokenConfirmationDialog } from 'ts/components/dialogs/track_token_confirmation_dialog'; import { FillOrderJSON } from 'ts/components/fill_order_json'; @@ -22,10 +20,10 @@ import { VisualOrder } from 'ts/components/visual_order'; import { Dispatcher } from 'ts/redux/dispatcher'; import { portalOrderSchema } from 'ts/schemas/portal_order_schema'; import { validator } from 'ts/schemas/validator'; -import { AlertTypes, BlockchainErrs, Order, Token, TokenByAddress, WebsitePaths } from 'ts/types'; +import { AlertTypes, BlockchainErrs, PortalOrder, Token, TokenByAddress, WebsitePaths } from 'ts/types'; import { analytics } from 'ts/utils/analytics'; -import { constants } from 'ts/utils/constants'; import { errorReporter } from 'ts/utils/error_reporter'; +import { orderParser } from 'ts/utils/order_parser'; import { utils } from 'ts/utils/utils'; interface FillOrderProps { @@ -36,7 +34,7 @@ interface FillOrderProps { networkId: number; userAddress: string; tokenByAddress: TokenByAddress; - initialOrder: Order; + initialOrder: PortalOrder; dispatcher: Dispatcher; lastForceTokenStateRefetch: number; isFullWidth?: boolean; @@ -49,7 +47,7 @@ interface FillOrderState { globalErrMsg: string; orderJSON: string; orderJSONErrMsg: string; - parsedOrder: Order; + parsedOrder: PortalOrder; didFillOrderSucceed: boolean; didCancelOrderSucceed: boolean; unavailableTakerAmount: BigNumber; @@ -191,26 +189,31 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { ); } private _renderVisualOrder(): React.ReactNode { - const takerTokenAddress = this.state.parsedOrder.signedOrder.takerTokenAddress; + const takerTokenAddress = assetDataUtils.decodeERC20AssetData(this.state.parsedOrder.signedOrder.takerAssetData) + .tokenAddress; const takerToken = this.props.tokenByAddress[takerTokenAddress]; - const orderTakerAmount = new BigNumber(this.state.parsedOrder.signedOrder.takerTokenAmount); - const orderMakerAmount = new BigNumber(this.state.parsedOrder.signedOrder.makerTokenAmount); + const orderTakerAmount = this.state.parsedOrder.signedOrder.takerAssetAmount; + const orderMakerAmount = this.state.parsedOrder.signedOrder.makerAssetAmount; const takerAssetToken = { amount: orderTakerAmount.minus(this.state.unavailableTakerAmount), symbol: takerToken.symbol, }; const fillToken = this.props.tokenByAddress[takerTokenAddress]; - const makerTokenAddress = this.state.parsedOrder.signedOrder.makerTokenAddress; + const makerTokenAddress = assetDataUtils.decodeERC20AssetData(this.state.parsedOrder.signedOrder.makerAssetData) + .tokenAddress; const makerToken = this.props.tokenByAddress[makerTokenAddress]; const makerAssetToken = { - amount: orderMakerAmount.times(takerAssetToken.amount).div(orderTakerAmount), + amount: orderMakerAmount + .times(takerAssetToken.amount) + .div(orderTakerAmount) + .floor(), symbol: makerToken.symbol, }; const fillAssetToken = { amount: this.props.orderFillAmount, symbol: takerToken.symbol, }; - const parsedOrderExpiration = new BigNumber(this.state.parsedOrder.signedOrder.expirationUnixTimestampSec); + const parsedOrderExpiration = this.state.parsedOrder.signedOrder.expirationTimeSeconds; let orderReceiveAmount = 0; if (!_.isUndefined(this.props.orderFillAmount)) { @@ -222,7 +225,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { } const isUserMaker = !_.isUndefined(this.state.parsedOrder) && - this.state.parsedOrder.signedOrder.maker === this.props.userAddress; + this.state.parsedOrder.signedOrder.makerAddress === this.props.userAddress; const expiryDate = utils.convertToReadableDateTimeFromUnixTimestamp(parsedOrderExpiration); return ( <div className="pt3 pb1"> @@ -233,11 +236,11 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { Maker: </div> <div className="col col-2 pr1"> - <Identicon address={this.state.parsedOrder.signedOrder.maker} diameter={23} /> + <Identicon address={this.state.parsedOrder.signedOrder.makerAddress} diameter={23} /> </div> <div className="col col-6"> <EthereumAddress - address={this.state.parsedOrder.signedOrder.maker} + address={this.state.parsedOrder.signedOrder.makerAddress} networkId={this.props.networkId} /> </div> @@ -323,7 +326,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { return ( <div> Order successfully filled. See the trade details in your{' '} - <Link to={`${WebsitePaths.Portal}/trades`} style={{ color: colors.white }}> + <Link to={`${WebsitePaths.Portal}/trades`} fontColor={colors.white}> trade history </Link> </div> @@ -367,17 +370,19 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { if (!_.isEmpty(this.state.orderJSONErrMsg)) { return; } - - const makerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.signedOrder.makerTokenAddress]; - const takerTokenIfExists = this.props.tokenByAddress[this.state.parsedOrder.signedOrder.takerTokenAddress]; - + const makerTokenAddress = assetDataUtils.decodeERC20AssetData(this.state.parsedOrder.signedOrder.makerAssetData) + .tokenAddress; + const takerTokenAddress = assetDataUtils.decodeERC20AssetData(this.state.parsedOrder.signedOrder.takerAssetData) + .tokenAddress; + const makerTokenIfExists = this.props.tokenByAddress[makerTokenAddress]; + const takerTokenIfExists = this.props.tokenByAddress[takerTokenAddress]; const tokensToTrack: Token[] = []; const isUnseenMakerToken = _.isUndefined(makerTokenIfExists); const isMakerTokenTracked = !_.isUndefined(makerTokenIfExists) && utils.isTokenTracked(makerTokenIfExists); if (isUnseenMakerToken) { tokensToTrack.push({ ...this.state.parsedOrder.metadata.makerToken, - address: this.state.parsedOrder.signedOrder.makerTokenAddress, + address: makerTokenAddress, iconUrl: undefined, trackedTimestamp: undefined, isRegistered: false, @@ -390,7 +395,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { if (isUnseenTakerToken) { tokensToTrack.push({ ...this.state.parsedOrder.metadata.takerToken, - address: this.state.parsedOrder.signedOrder.takerTokenAddress, + address: takerTokenAddress, iconUrl: undefined, trackedTimestamp: undefined, isRegistered: false, @@ -411,10 +416,10 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { } private async _validateFillOrderFireAndForgetAsync(orderJSON: string): Promise<void> { let orderJSONErrMsg = ''; - let parsedOrder: Order; + let parsedOrder: PortalOrder; let orderHash: string; try { - const order = JSON.parse(orderJSON); + const order = orderParser.parseJsonString(orderJSON); const validationResult = validator.validate(order, portalOrderSchema); if (validationResult.errors.length > 0) { orderJSONErrMsg = 'Submitted order JSON is not a valid order'; @@ -422,36 +427,16 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { return; } parsedOrder = order; - - const makerAmount = new BigNumber(parsedOrder.signedOrder.makerTokenAmount); - const takerAmount = new BigNumber(parsedOrder.signedOrder.takerTokenAmount); - const expiration = new BigNumber(parsedOrder.signedOrder.expirationUnixTimestampSec); - const salt = new BigNumber(parsedOrder.signedOrder.salt); - const parsedMakerFee = new BigNumber(parsedOrder.signedOrder.makerFee); - const parsedTakerFee = new BigNumber(parsedOrder.signedOrder.takerFee); - - const zeroExOrder: ZeroExOrder = { - exchangeContractAddress: parsedOrder.signedOrder.exchangeContractAddress, - expirationUnixTimestampSec: expiration, - feeRecipient: parsedOrder.signedOrder.feeRecipient, - maker: parsedOrder.signedOrder.maker, - makerFee: parsedMakerFee, - makerTokenAddress: parsedOrder.signedOrder.makerTokenAddress, - makerTokenAmount: makerAmount, - salt, - taker: _.isEmpty(parsedOrder.signedOrder.taker) - ? constants.NULL_ADDRESS - : parsedOrder.signedOrder.taker, - takerFee: parsedTakerFee, - takerTokenAddress: parsedOrder.signedOrder.takerTokenAddress, - takerTokenAmount: takerAmount, - }; - orderHash = getOrderHashHex(zeroExOrder); - + const signedOrder = parsedOrder.signedOrder; + orderHash = orderHashUtils.getOrderHashHex(signedOrder); const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists(); - const signature = parsedOrder.signedOrder.ecSignature; - const isSignatureValid = isValidSignature(orderHash, signature, parsedOrder.signedOrder.maker); - if (exchangeContractAddr !== parsedOrder.signedOrder.exchangeContractAddress) { + const signature = signedOrder.signature; + const isSignatureValid = await this.props.blockchain.isValidSignatureAsync( + orderHash, + signature, + signedOrder.makerAddress, + ); + if (exchangeContractAddr !== signedOrder.exchangeAddress) { orderJSONErrMsg = 'This order was made on another network or using a deprecated Exchange contract'; parsedOrder = undefined; } else if (!isSignatureValid) { @@ -484,11 +469,15 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { this.props.dispatcher.updateUserSuppliedOrderCache(undefined); } else { unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash); + const makerTokenAddress = assetDataUtils.decodeERC20AssetData(parsedOrder.signedOrder.makerAssetData) + .tokenAddress; + const takerTokenAddress = assetDataUtils.decodeERC20AssetData(parsedOrder.signedOrder.takerAssetData) + .tokenAddress; const isMakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync( - parsedOrder.signedOrder.makerTokenAddress, + makerTokenAddress, ); const isTakerTokenAddressInRegistry = await this.props.blockchain.isAddressInTokenRegistryAsync( - parsedOrder.signedOrder.takerTokenAddress, + takerTokenAddress, ); this.setState({ isMakerTokenAddressInRegistry, @@ -537,7 +526,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { globalErrMsg = 'You must specify a fill amount'; } - const signedOrder = this.props.blockchain.portalOrderToZeroExOrder(parsedOrder); + const signedOrder = parsedOrder.signedOrder; if (_.isEmpty(globalErrMsg)) { try { await this.props.blockchain.validateFillOrderThrowIfInvalidAsync( @@ -546,7 +535,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { this.props.userAddress, ); } catch (err) { - globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.signedOrder.taker); + globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.signedOrder.takerAddress); } } if (!_.isEmpty(globalErrMsg)) { @@ -611,18 +600,8 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { return; } let globalErrMsg = ''; - - const takerTokenAmount = new BigNumber(parsedOrder.signedOrder.takerTokenAmount); - - const signedOrder = this.props.blockchain.portalOrderToZeroExOrder(parsedOrder); - const orderHash = getOrderHashHex(signedOrder); - const unavailableTakerAmount = await this.props.blockchain.getUnavailableTakerAmountAsync(orderHash); - const availableTakerTokenAmount = takerTokenAmount.minus(unavailableTakerAmount); - try { - await this.props.blockchain.validateCancelOrderThrowIfInvalidAsync(signedOrder, availableTakerTokenAmount); - } catch (err) { - globalErrMsg = utils.zeroExErrToHumanReadableErrMsg(err.message, parsedOrder.signedOrder.taker); - } + const signedOrder = parsedOrder.signedOrder; + const takerTokenAmount = signedOrder.takerAssetAmount; if (!_.isEmpty(globalErrMsg)) { this.setState({ isCancelling: false, @@ -631,7 +610,7 @@ export class FillOrder extends React.Component<FillOrderProps, FillOrderState> { return; } try { - await this.props.blockchain.cancelOrderAsync(signedOrder, availableTakerTokenAmount); + await this.props.blockchain.cancelOrderAsync(signedOrder); this.setState({ isCancelling: false, didCancelOrderSucceed: true, diff --git a/packages/website/ts/components/fill_order_json.tsx b/packages/website/ts/components/fill_order_json.tsx index 90eedbb18..41413eac2 100644 --- a/packages/website/ts/components/fill_order_json.tsx +++ b/packages/website/ts/components/fill_order_json.tsx @@ -1,5 +1,5 @@ -import { generatePseudoRandomSalt } from '@0xproject/order-utils'; -import { BigNumber } from '@0xproject/utils'; +import { generatePseudoRandomSalt } from '@0x/order-utils'; +import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import Paper from 'material-ui/Paper'; import TextField from 'material-ui/TextField'; @@ -33,11 +33,7 @@ export class FillOrderJSON extends React.Component<FillOrderJSONProps, FillOrder }, }; const hintOrderExpiryTimestamp = utils.initialOrderExpiryUnixTimestampSec(); - const hintECSignature = { - r: '0xf01103f759e2289a28593eaf22e5820032...', - s: '937862111edcba395f8a9e0cc1b2c5e12320...', - v: 27, - }; + const hintECSignature = '0x012761a3ed31b43c8780e905a260a35faefcc527be7516aa11c0256729b5b351bc33'; const hintSalt = generatePseudoRandomSalt(); const feeRecipient = constants.NULL_ADDRESS; const hintOrder = utils.generateOrder( diff --git a/packages/website/ts/components/fill_warning_dialog.tsx b/packages/website/ts/components/fill_warning_dialog.tsx index 45c492221..430abd013 100644 --- a/packages/website/ts/components/fill_warning_dialog.tsx +++ b/packages/website/ts/components/fill_warning_dialog.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import Dialog from 'material-ui/Dialog'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; @@ -18,12 +18,12 @@ export const FillWarningDialog = (props: FillWarningDialogProps) => { <FlatButton key="fillWarningCancel" label="Cancel" - onTouchTap={() => props.onToggleDialog(didCancel)} // tslint:disable-line:jsx-no-lambda + onClick={() => props.onToggleDialog(didCancel)} // tslint:disable-line:jsx-no-lambda />, <FlatButton key="fillWarningContinue" label="Fill Order" - onTouchTap={() => props.onToggleDialog(!didCancel)} // tslint:disable-line:jsx-no-lambda + onClick={() => props.onToggleDialog(!didCancel)} // tslint:disable-line:jsx-no-lambda />, ]} open={props.isOpen} diff --git a/packages/website/ts/components/flash_messages/asset_send_completed.tsx b/packages/website/ts/components/flash_messages/asset_send_completed.tsx index f76e05fe1..b895126dc 100644 --- a/packages/website/ts/components/flash_messages/asset_send_completed.tsx +++ b/packages/website/ts/components/flash_messages/asset_send_completed.tsx @@ -1,6 +1,6 @@ -import { colors } from '@0xproject/react-shared'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { colors } from '@0x/react-shared'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import * as React from 'react'; import { utils } from 'ts/utils/utils'; diff --git a/packages/website/ts/components/flash_messages/transaction_submitted.tsx b/packages/website/ts/components/flash_messages/transaction_submitted.tsx index 2a6d2a64b..b1d909baa 100644 --- a/packages/website/ts/components/flash_messages/transaction_submitted.tsx +++ b/packages/website/ts/components/flash_messages/transaction_submitted.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; diff --git a/packages/website/ts/components/footer.tsx b/packages/website/ts/components/footer.tsx index 6dcb5a0e9..dfedcba55 100644 --- a/packages/website/ts/components/footer.tsx +++ b/packages/website/ts/components/footer.tsx @@ -1,31 +1,17 @@ -import { colors } from '@0xproject/react-shared'; +import { ALink, colors, Link } from '@0x/react-shared'; +import { ObjectMap } from '@0x/types'; import * as _ from 'lodash'; import DropDownMenu from 'material-ui/DropDownMenu'; import MenuItem from 'material-ui/MenuItem'; import * as React from 'react'; -import { Link } from 'react-router-dom'; + import { Dispatcher } from 'ts/redux/dispatcher'; import { Deco, Key, Language, WebsitePaths } from 'ts/types'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; -interface MenuItemsBySection { - [sectionName: string]: FooterMenuItem[]; -} - -interface FooterMenuItem { - title: string; - path?: string; - isExternal?: boolean; -} - const ICON_DIMENSION = 16; -const linkStyle = { - color: colors.white, - cursor: 'pointer', -}; - const languageToMenuTitle = { [Language.English]: 'English', [Language.Russian]: 'Русский', @@ -51,76 +37,74 @@ export class Footer extends React.Component<FooterProps, FooterState> { }; } public render(): React.ReactNode { - const menuItemsBySection: MenuItemsBySection = { + const sectionNameToLinks: ObjectMap<ALink[]> = { [Key.Documentation]: [ { + title: 'Developer Home', + to: WebsitePaths.Docs, + }, + { title: '0x.js', - path: WebsitePaths.ZeroExJs, + to: WebsitePaths.ZeroExJs, }, { title: this.props.translate.get(Key.SmartContracts, Deco.Cap), - path: WebsitePaths.SmartContracts, + to: WebsitePaths.SmartContracts, }, { title: this.props.translate.get(Key.Connect, Deco.Cap), - path: WebsitePaths.Connect, + to: WebsitePaths.Connect, }, { title: this.props.translate.get(Key.Whitepaper, Deco.Cap), - path: WebsitePaths.Whitepaper, - isExternal: true, + to: WebsitePaths.Whitepaper, + shouldOpenInNewTab: true, }, { title: this.props.translate.get(Key.Wiki, Deco.Cap), - path: WebsitePaths.Wiki, - }, - { - title: this.props.translate.get(Key.Faq, Deco.Cap), - path: WebsitePaths.FAQ, + to: WebsitePaths.Wiki, }, ], [Key.Community]: [ { title: this.props.translate.get(Key.RocketChat, Deco.Cap), - isExternal: true, - path: constants.URL_ZEROEX_CHAT, + to: constants.URL_ZEROEX_CHAT, + shouldOpenInNewTab: true, }, { title: this.props.translate.get(Key.Blog, Deco.Cap), - isExternal: true, - path: constants.URL_BLOG, + to: constants.URL_BLOG, + shouldOpenInNewTab: true, }, { title: 'Twitter', - isExternal: true, - path: constants.URL_TWITTER, + to: constants.URL_TWITTER, + shouldOpenInNewTab: true, }, { title: 'Reddit', - isExternal: true, - path: constants.URL_REDDIT, + to: constants.URL_REDDIT, + shouldOpenInNewTab: true, }, { title: this.props.translate.get(Key.Forum, Deco.Cap), - isExternal: true, - path: constants.URL_DISCOURSE_FORUM, + to: constants.URL_DISCOURSE_FORUM, + shouldOpenInNewTab: true, }, ], [Key.Organization]: [ { title: this.props.translate.get(Key.About, Deco.Cap), - isExternal: false, - path: WebsitePaths.About, + to: WebsitePaths.About, }, { title: this.props.translate.get(Key.Careers, Deco.Cap), - isExternal: false, - path: WebsitePaths.Careers, + to: WebsitePaths.Careers, }, { title: this.props.translate.get(Key.Contact, Deco.Cap), - isExternal: true, - path: 'mailto:team@0xproject.com', + to: 'mailto:team@0xproject.com', + shouldOpenInNewTab: true, }, ], }; @@ -160,19 +144,19 @@ export class Footer extends React.Component<FooterProps, FooterState> { <div className="col lg-col-4 md-col-4 col-12"> <div className="lg-right md-right sm-center"> {this._renderHeader(Key.Documentation)} - {_.map(menuItemsBySection[Key.Documentation], this._renderMenuItem.bind(this))} + {_.map(sectionNameToLinks[Key.Documentation], this._renderMenuItem.bind(this))} </div> </div> <div className="col lg-col-4 md-col-4 col-12 lg-pr2 md-pr2"> <div className="lg-right md-right sm-center"> {this._renderHeader(Key.Community)} - {_.map(menuItemsBySection[Key.Community], this._renderMenuItem.bind(this))} + {_.map(sectionNameToLinks[Key.Community], this._renderMenuItem.bind(this))} </div> </div> <div className="col lg-col-4 md-col-4 col-12"> <div className="lg-right md-right sm-center"> {this._renderHeader(Key.Organization)} - {_.map(menuItemsBySection[Key.Organization], this._renderMenuItem.bind(this))} + {_.map(sectionNameToLinks[Key.Organization], this._renderMenuItem.bind(this))} </div> </div> </div> @@ -187,7 +171,7 @@ export class Footer extends React.Component<FooterProps, FooterState> { </div> ); } - private _renderMenuItem(item: FooterMenuItem): React.ReactNode { + private _renderMenuItem(link: ALink): React.ReactNode { const titleToIcon: { [title: string]: string } = { [this.props.translate.get(Key.RocketChat, Deco.Cap)]: 'rocketchat.png', [this.props.translate.get(Key.Blog, Deco.Cap)]: 'medium.png', @@ -195,30 +179,26 @@ export class Footer extends React.Component<FooterProps, FooterState> { Reddit: 'reddit.png', [this.props.translate.get(Key.Forum, Deco.Cap)]: 'discourse.png', }; - const iconIfExists = titleToIcon[item.title]; + const iconIfExists = titleToIcon[link.title]; return ( - <div key={item.title} className="sm-center" style={{ fontSize: 13, paddingTop: 25 }}> - {item.isExternal ? ( - <a className="text-decoration-none" style={linkStyle} target="_blank" href={item.path}> + <div key={link.title} className="sm-center" style={{ fontSize: 13, paddingTop: 25 }}> + <Link + to={link.to} + shouldOpenInNewTab={link.shouldOpenInNewTab} + fontColor={colors.white} + className="text-decoration-none" + > + <div> {!_.isUndefined(iconIfExists) ? ( <div className="inline-block"> <div className="pr1 table-cell">{this._renderIcon(iconIfExists)}</div> - <div className="table-cell">{item.title}</div> + <div className="table-cell">{link.title}</div> </div> ) : ( - item.title + link.title )} - </a> - ) : ( - <Link to={item.path} style={linkStyle} className="text-decoration-none"> - <div> - {!_.isUndefined(iconIfExists) && ( - <div className="pr1">{this._renderIcon(iconIfExists)}</div> - )} - {item.title} - </div> - </Link> - )} + </div> + </Link> </div> ); } diff --git a/packages/website/ts/components/forms/subscribe_form.tsx b/packages/website/ts/components/forms/subscribe_form.tsx index 761db7517..f5560cfa7 100644 --- a/packages/website/ts/components/forms/subscribe_form.tsx +++ b/packages/website/ts/components/forms/subscribe_form.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; diff --git a/packages/website/ts/components/generate_order/asset_picker.tsx b/packages/website/ts/components/generate_order/asset_picker.tsx index 2dca3483f..98aad6c62 100644 --- a/packages/website/ts/components/generate_order/asset_picker.tsx +++ b/packages/website/ts/components/generate_order/asset_picker.tsx @@ -73,12 +73,12 @@ export class AssetPicker extends React.Component<AssetPickerProps, AssetPickerSt <FlatButton key="noTracking" label="No" - onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, false)} + onClick={this._onTrackConfirmationRespondedAsync.bind(this, false)} />, <FlatButton key="yesTrack" label="Yes" - onTouchTap={this._onTrackConfirmationRespondedAsync.bind(this, true)} + onClick={this._onTrackConfirmationRespondedAsync.bind(this, true)} />, ], }, diff --git a/packages/website/ts/components/generate_order/generate_order_form.tsx b/packages/website/ts/components/generate_order/generate_order_form.tsx index 72efab033..8afbee977 100644 --- a/packages/website/ts/components/generate_order/generate_order_form.tsx +++ b/packages/website/ts/components/generate_order/generate_order_form.tsx @@ -1,7 +1,7 @@ -import { generatePseudoRandomSalt, getOrderHashHex } from '@0xproject/order-utils'; -import { colors } from '@0xproject/react-shared'; -import { ECSignature, Order as ZeroExOrder } from '@0xproject/types'; -import { BigNumber, logUtils } from '@0xproject/utils'; +import { assetDataUtils, generatePseudoRandomSalt, orderHashUtils } from '@0x/order-utils'; +import { colors } from '@0x/react-shared'; +import { Order as ZeroExOrder } from '@0x/types'; +import { BigNumber, logUtils } from '@0x/utils'; import * as _ from 'lodash'; import Dialog from 'material-ui/Dialog'; import Divider from 'material-ui/Divider'; @@ -20,7 +20,16 @@ import { SwapIcon } from 'ts/components/ui/swap_icon'; import { Dispatcher } from 'ts/redux/dispatcher'; import { portalOrderSchema } from 'ts/schemas/portal_order_schema'; import { validator } from 'ts/schemas/validator'; -import { AlertTypes, BlockchainErrs, HashData, Order, Side, SideToAssetToken, Token, TokenByAddress } from 'ts/types'; +import { + AlertTypes, + BlockchainErrs, + HashData, + PortalOrder, + Side, + SideToAssetToken, + Token, + TokenByAddress, +} from 'ts/types'; import { analytics } from 'ts/utils/analytics'; import { constants } from 'ts/utils/constants'; import { errorReporter } from 'ts/utils/error_reporter'; @@ -41,7 +50,7 @@ interface GenerateOrderFormProps { orderExpiryTimestamp: BigNumber; networkId: number; userAddress: string; - orderECSignature: ECSignature; + orderSignature: string; orderTakerAddress: string; orderSalt: BigNumber; sideToAssetToken: SideToAssetToken; @@ -212,7 +221,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G <OrderJSON exchangeContractIfExists={exchangeContractIfExists} orderExpiryTimestamp={this.props.orderExpiryTimestamp} - orderECSignature={this.props.orderECSignature} + orderSignature={this.props.orderSignature} orderTakerAddress={this.props.orderTakerAddress} orderMakerAddress={this.props.userAddress} orderSalt={this.props.orderSalt} @@ -294,12 +303,12 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G return false; } } - private async _signTransactionAsync(): Promise<Order | undefined> { + private async _signTransactionAsync(): Promise<PortalOrder | undefined> { this.setState({ signingState: SigningState.SIGNING, }); - const exchangeContractAddr = this.props.blockchain.getExchangeContractAddressIfExists(); - if (_.isUndefined(exchangeContractAddr)) { + const exchangeAddress = this.props.blockchain.getExchangeContractAddressIfExists(); + if (_.isUndefined(exchangeAddress)) { this.props.dispatcher.updateShouldBlockchainErrDialogBeOpen(true); this.setState({ signingState: SigningState.UNSIGNED, @@ -308,28 +317,31 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G } const hashData = this.props.hashData; + const makerAssetData = assetDataUtils.encodeERC20AssetData(hashData.depositTokenContractAddr); + const takerAssetData = assetDataUtils.encodeERC20AssetData(hashData.receiveTokenContractAddr); const zeroExOrder: ZeroExOrder = { - exchangeContractAddress: exchangeContractAddr, - expirationUnixTimestampSec: hashData.orderExpiryTimestamp, - feeRecipient: hashData.feeRecipientAddress, - maker: hashData.orderMakerAddress, + senderAddress: constants.NULL_ADDRESS, + exchangeAddress, + expirationTimeSeconds: hashData.orderExpiryTimestamp, + feeRecipientAddress: hashData.feeRecipientAddress, + makerAddress: hashData.orderMakerAddress, makerFee: hashData.makerFee, - makerTokenAddress: hashData.depositTokenContractAddr, - makerTokenAmount: hashData.depositAmount, + makerAssetData, + makerAssetAmount: hashData.depositAmount, salt: hashData.orderSalt, - taker: hashData.orderTakerAddress, + takerAddress: hashData.orderTakerAddress, takerFee: hashData.takerFee, - takerTokenAddress: hashData.receiveTokenContractAddr, - takerTokenAmount: hashData.receiveAmount, + takerAssetData, + takerAssetAmount: hashData.receiveAmount, }; - const orderHash = getOrderHashHex(zeroExOrder); + const orderHash = orderHashUtils.getOrderHashHex(zeroExOrder); let globalErrMsg = ''; let order; try { - const ecSignature = await this.props.blockchain.signOrderHashAsync(orderHash); + const signature = await this.props.blockchain.signOrderHashAsync(orderHash); order = utils.generateOrder( - exchangeContractAddr, + exchangeAddress, this.props.sideToAssetToken, hashData.orderExpiryTimestamp, this.props.orderTakerAddress, @@ -337,7 +349,7 @@ export class GenerateOrderForm extends React.Component<GenerateOrderFormProps, G hashData.makerFee, hashData.takerFee, hashData.feeRecipientAddress, - ecSignature, + signature, this.props.tokenByAddress, hashData.orderSalt, ); diff --git a/packages/website/ts/components/generate_order/new_token_form.tsx b/packages/website/ts/components/generate_order/new_token_form.tsx index 3d7eda84c..b8cd88b18 100644 --- a/packages/website/ts/components/generate_order/new_token_form.tsx +++ b/packages/website/ts/components/generate_order/new_token_form.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as _ from 'lodash'; import TextField from 'material-ui/TextField'; import * as moment from 'moment'; diff --git a/packages/website/ts/components/inputs/address_input.tsx b/packages/website/ts/components/inputs/address_input.tsx index 39ec72f8a..1a71f8081 100644 --- a/packages/website/ts/components/inputs/address_input.tsx +++ b/packages/website/ts/components/inputs/address_input.tsx @@ -1,5 +1,5 @@ -import { colors } from '@0xproject/react-shared'; -import { addressUtils } from '@0xproject/utils'; +import { colors } from '@0x/react-shared'; +import { addressUtils } from '@0x/utils'; import * as _ from 'lodash'; import TextField from 'material-ui/TextField'; import * as React from 'react'; diff --git a/packages/website/ts/components/inputs/allowance_state_toggle.tsx b/packages/website/ts/components/inputs/allowance_state_toggle.tsx index 39d2e3030..fd7d3b174 100644 --- a/packages/website/ts/components/inputs/allowance_state_toggle.tsx +++ b/packages/website/ts/components/inputs/allowance_state_toggle.tsx @@ -1,5 +1,5 @@ -import { colors } from '@0xproject/react-shared'; -import { BigNumber, logUtils } from '@0xproject/utils'; +import { colors } from '@0x/react-shared'; +import { BigNumber, logUtils } from '@0x/utils'; import * as _ from 'lodash'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); diff --git a/packages/website/ts/components/inputs/balance_bounded_input.tsx b/packages/website/ts/components/inputs/balance_bounded_input.tsx index eb01e3ea6..83f263842 100644 --- a/packages/website/ts/components/inputs/balance_bounded_input.tsx +++ b/packages/website/ts/components/inputs/balance_bounded_input.tsx @@ -1,5 +1,5 @@ -import { colors } from '@0xproject/react-shared'; -import { BigNumber } from '@0xproject/utils'; +import { colors } from '@0x/react-shared'; +import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import TextField from 'material-ui/TextField'; import * as React from 'react'; diff --git a/packages/website/ts/components/inputs/eth_amount_input.tsx b/packages/website/ts/components/inputs/eth_amount_input.tsx index 3a7905442..6799e54bf 100644 --- a/packages/website/ts/components/inputs/eth_amount_input.tsx +++ b/packages/website/ts/components/inputs/eth_amount_input.tsx @@ -1,5 +1,5 @@ -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import * as React from 'react'; import { BalanceBoundedInput } from 'ts/components/inputs/balance_bounded_input'; diff --git a/packages/website/ts/components/inputs/expiration_input.tsx b/packages/website/ts/components/inputs/expiration_input.tsx index 5417ce715..3e43c1c07 100644 --- a/packages/website/ts/components/inputs/expiration_input.tsx +++ b/packages/website/ts/components/inputs/expiration_input.tsx @@ -1,4 +1,4 @@ -import { BigNumber } from '@0xproject/utils'; +import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import DatePicker from 'material-ui/DatePicker'; import TimePicker from 'material-ui/TimePicker'; diff --git a/packages/website/ts/components/inputs/hash_input.tsx b/packages/website/ts/components/inputs/hash_input.tsx index 8d9cdfc0b..73b6615d4 100644 --- a/packages/website/ts/components/inputs/hash_input.tsx +++ b/packages/website/ts/components/inputs/hash_input.tsx @@ -1,9 +1,10 @@ -import { getOrderHashHex } from '@0xproject/order-utils'; -import { Styles } from '@0xproject/react-shared'; -import { Order } from '@0xproject/types'; +import { assetDataUtils, orderHashUtils } from '@0x/order-utils'; +import { Styles } from '@0x/react-shared'; +import { Order } from '@0x/types'; import * as _ from 'lodash'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); + import { Blockchain } from 'ts/blockchain'; import { FakeTextField } from 'ts/components/ui/fake_text_field'; import { HashData } from 'ts/types'; @@ -42,23 +43,26 @@ export class HashInput extends React.Component<HashInputProps, HashInputState> { ); } private _generateMessageHashHex(): string { - const exchangeContractAddress = this.props.blockchain.getExchangeContractAddressIfExists(); + const exchangeAddress = this.props.blockchain.getExchangeContractAddressIfExists(); const hashData = this.props.hashData; + const makerAssetData = assetDataUtils.encodeERC20AssetData(hashData.depositTokenContractAddr); + const takerAssetData = assetDataUtils.encodeERC20AssetData(hashData.receiveTokenContractAddr); const order: Order = { - exchangeContractAddress, - expirationUnixTimestampSec: hashData.orderExpiryTimestamp, - feeRecipient: hashData.feeRecipientAddress, - maker: _.isEmpty(hashData.orderMakerAddress) ? constants.NULL_ADDRESS : hashData.orderMakerAddress, + senderAddress: constants.NULL_ADDRESS, + exchangeAddress, + expirationTimeSeconds: hashData.orderExpiryTimestamp, + feeRecipientAddress: hashData.feeRecipientAddress, + makerAddress: _.isEmpty(hashData.orderMakerAddress) ? constants.NULL_ADDRESS : hashData.orderMakerAddress, makerFee: hashData.makerFee, - makerTokenAddress: hashData.depositTokenContractAddr, - makerTokenAmount: hashData.depositAmount, + makerAssetData, + makerAssetAmount: hashData.depositAmount, salt: hashData.orderSalt, - taker: hashData.orderTakerAddress, + takerAddress: hashData.orderTakerAddress, takerFee: hashData.takerFee, - takerTokenAddress: hashData.receiveTokenContractAddr, - takerTokenAmount: hashData.receiveAmount, + takerAssetData, + takerAssetAmount: hashData.receiveAmount, }; - const orderHash = getOrderHashHex(order); + const orderHash = orderHashUtils.getOrderHashHex(order); return orderHash; } } diff --git a/packages/website/ts/components/inputs/token_amount_input.tsx b/packages/website/ts/components/inputs/token_amount_input.tsx index 93ef516cf..fded3a9dd 100644 --- a/packages/website/ts/components/inputs/token_amount_input.tsx +++ b/packages/website/ts/components/inputs/token_amount_input.tsx @@ -1,9 +1,8 @@ -import { colors } from '@0xproject/react-shared'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { colors, Link } from '@0x/react-shared'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import * as React from 'react'; -import { Link } from 'react-router-dom'; import { Blockchain } from 'ts/blockchain'; import { BalanceBoundedInput } from 'ts/components/inputs/balance_bounded_input'; import { Token, ValidatedBigNumberCallback, WebsitePaths } from 'ts/types'; @@ -111,8 +110,9 @@ export class TokenAmountInput extends React.Component<TokenAmountInputProps, Tok <span> Insufficient allowance.{' '} <Link - to={`${WebsitePaths.Portal}/balances`} - style={{ cursor: 'pointer', color: colors.darkestGrey }} + to={`${WebsitePaths.Portal}/account`} + textDecoration="underline" + fontColor={colors.darkestGrey} > Set allowance </Link> diff --git a/packages/website/ts/components/inputs/token_input.tsx b/packages/website/ts/components/inputs/token_input.tsx index 0bd36781e..c3c2d8b37 100644 --- a/packages/website/ts/components/inputs/token_input.tsx +++ b/packages/website/ts/components/inputs/token_input.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import Paper from 'material-ui/Paper'; import * as React from 'react'; import { Blockchain } from 'ts/blockchain'; 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..db7d55261 --- /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<ALink[]>; + 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 <MenuItem key={`menu-item-${menuItemTitle}`} link={finalLink} />; + }); + // tslint:disable-next-line:no-unused-variable + return ( + <div key={`section-${sectionName}`} className="py1" style={{ color: colors.greyTheme }}> + <Text fontSize="14px" letterSpacing="0.5" className="py1 pl1"> + {finalSectionName.toUpperCase()} + </Text> + {menuItems} + </div> + ); + }); + return ( + <div> + {props.sidebarHeader} + <div>{navigation}</div> + </div> + ); +}; + +export interface MenuItemProps { + link: ALink; +} + +export interface MenuItemState { + isActive: boolean; +} + +export class MenuItem extends React.Component<MenuItemProps, MenuItemState> { + 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 ( + <Link + to={this.props.link.to} + shouldOpenInNewTab={this.props.link.shouldOpenInNewTab} + onActivityChanged={this._onActivityChanged.bind(this)} + > + <Button + borderRadius="4px" + padding="0.4em 0.375em" + width="100%" + backgroundColor={isActive ? colors.lightLinkBlue : colors.grey100} + fontSize="14px" + textAlign="left" + > + <Text + fontWeight={isActive ? 'bold' : 'normal'} + fontColor={isActive ? colors.white : colors.grey800} + > + {this.props.link.title} + </Text> + </Button> + </Link> + ); + } + private _onActivityChanged(isActive: boolean): void { + this.setState({ + isActive, + }); + } +} diff --git a/packages/website/ts/components/onboarding/add_eth_onboarding_step.tsx b/packages/website/ts/components/onboarding/add_eth_onboarding_step.tsx index ca71fcd50..1d21e5a85 100644 --- a/packages/website/ts/components/onboarding/add_eth_onboarding_step.tsx +++ b/packages/website/ts/components/onboarding/add_eth_onboarding_step.tsx @@ -1,4 +1,4 @@ -import { BigNumber } from '@0xproject/utils'; +import { BigNumber } from '@0x/utils'; import * as React from 'react'; import { Balance } from 'ts/components/ui/balance'; import { Container } from 'ts/components/ui/container'; diff --git a/packages/website/ts/components/onboarding/install_wallet_onboarding_step.tsx b/packages/website/ts/components/onboarding/install_wallet_onboarding_step.tsx index d618c8318..173ba9a97 100644 --- a/packages/website/ts/components/onboarding/install_wallet_onboarding_step.tsx +++ b/packages/website/ts/components/onboarding/install_wallet_onboarding_step.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; import { Container } from 'ts/components/ui/container'; import { Image } from 'ts/components/ui/image'; @@ -12,7 +12,7 @@ export const InstallWalletOnboardingStep: React.StatelessComponent<InstallWallet const followupText = isOnMobile ? `Please revisit this site in your mobile dApp browser to continue!` : `Please refresh the page once you've done this to continue!`; - const downloadText = isOnMobile ? 'Get the Toshi Wallet' : 'Get the MetaMask extension'; + const downloadText = isOnMobile ? 'Get Coinbase Wallet' : 'Get the MetaMask extension'; return ( <div className="flex items-center flex-column"> <Text>First, you need to connect to a wallet. This will be used across all 0x relayers and dApps.</Text> @@ -21,7 +21,7 @@ export const InstallWalletOnboardingStep: React.StatelessComponent<InstallWallet height="50px" width="50px" borderRadius="22%" - src={isOnMobile ? '/images/toshi_logo.jpg' : '/images/metamask_icon.png'} + src={isOnMobile ? '/images/coinbase_wallet_logo.png' : '/images/metamask_icon.png'} /> <Container marginLeft="10px"> <a href={downloadLink} target="_blank"> diff --git a/packages/website/ts/components/onboarding/onboarding_card.tsx b/packages/website/ts/components/onboarding/onboarding_card.tsx index e1b0f304b..384bf7154 100644 --- a/packages/website/ts/components/onboarding/onboarding_card.tsx +++ b/packages/website/ts/components/onboarding/onboarding_card.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; import * as _ from 'lodash'; diff --git a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx index 522687758..6adcec0b1 100644 --- a/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx +++ b/packages/website/ts/components/onboarding/portal_onboarding_flow.tsx @@ -2,7 +2,7 @@ import * as _ from 'lodash'; import * as React from 'react'; import { RouteComponentProps, withRouter } from 'react-router'; -import { BigNumber } from '@0xproject/utils'; +import { BigNumber } from '@0x/utils'; import { Blockchain } from 'ts/blockchain'; import { AddEthOnboardingStep } from 'ts/components/onboarding/add_eth_onboarding_step'; import { CongratsOnboardingStep } from 'ts/components/onboarding/congrats_onboarding_step'; diff --git a/packages/website/ts/components/onboarding/wrap_eth_onboarding_step.tsx b/packages/website/ts/components/onboarding/wrap_eth_onboarding_step.tsx index e4332de75..37eef867b 100644 --- a/packages/website/ts/components/onboarding/wrap_eth_onboarding_step.tsx +++ b/packages/website/ts/components/onboarding/wrap_eth_onboarding_step.tsx @@ -1,5 +1,5 @@ -import { colors } from '@0xproject/react-shared'; -import { BigNumber } from '@0xproject/utils'; +import { colors } from '@0x/react-shared'; +import { BigNumber } from '@0x/utils'; import * as React from 'react'; import { Balance } from 'ts/components/ui/balance'; import { Container } from 'ts/components/ui/container'; diff --git a/packages/website/ts/components/order_json.tsx b/packages/website/ts/components/order_json.tsx index cf06f10c8..f33681835 100644 --- a/packages/website/ts/components/order_json.tsx +++ b/packages/website/ts/components/order_json.tsx @@ -1,5 +1,4 @@ -import { ECSignature } from '@0xproject/types'; -import { BigNumber, fetchAsync, logUtils } from '@0xproject/utils'; +import { BigNumber, fetchAsync, logUtils } from '@0x/utils'; import * as _ from 'lodash'; import Paper from 'material-ui/Paper'; import TextField from 'material-ui/TextField'; @@ -14,7 +13,7 @@ import { utils } from 'ts/utils/utils'; interface OrderJSONProps { exchangeContractIfExists: string; orderExpiryTimestamp: BigNumber; - orderECSignature: ECSignature; + orderSignature: string; orderTakerAddress: string; orderMakerAddress: string; orderSalt: BigNumber; @@ -48,7 +47,7 @@ export class OrderJSON extends React.Component<OrderJSONProps, OrderJSONState> { this.props.orderMakerFee, this.props.orderTakerFee, this.props.orderFeeRecipient, - this.props.orderECSignature, + this.props.orderSignature, this.props.tokenByAddress, this.props.orderSalt, ); @@ -169,7 +168,7 @@ You can see and fill it here: ${this.state.shareLink}`); this.props.orderMakerFee, this.props.orderTakerFee, this.props.orderFeeRecipient, - this.props.orderECSignature, + this.props.orderSignature, this.props.tokenByAddress, this.props.orderSalt, ); diff --git a/packages/website/ts/components/portal/back_button.tsx b/packages/website/ts/components/portal/back_button.tsx index ca35abc2b..bea69bb95 100644 --- a/packages/website/ts/components/portal/back_button.tsx +++ b/packages/website/ts/components/portal/back_button.tsx @@ -1,7 +1,5 @@ -import { Styles } from '@0xproject/react-shared'; +import { Link, Styles } from '@0x/react-shared'; import * as React from 'react'; -import { Link } from 'react-router-dom'; - import { Island } from 'ts/components/ui/island'; import { colors } from 'ts/style/colors'; @@ -27,7 +25,7 @@ const styles: Styles = { export const BackButton = (props: BackButtonProps) => { return ( <div style={{ height: 65, paddingTop: 25 }}> - <Link to={props.to} style={{ textDecoration: 'none' }}> + <Link to={props.to}> <Island className="flex right" style={styles.backButton}> <div style={{ marginLeft: 12 }}> <i style={styles.backButtonIcon} className={`zmdi zmdi-arrow-left`} /> diff --git a/packages/website/ts/components/portal/drawer_menu.tsx b/packages/website/ts/components/portal/drawer_menu.tsx index a6707e86c..7280a6102 100644 --- a/packages/website/ts/components/portal/drawer_menu.tsx +++ b/packages/website/ts/components/portal/drawer_menu.tsx @@ -1,4 +1,4 @@ -import { Styles } from '@0xproject/react-shared'; +import { Styles } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; @@ -39,7 +39,7 @@ export interface DrawerMenuProps { } export const DrawerMenu = (props: DrawerMenuProps) => { const relayerItemEntry = { - to: `${WebsitePaths.Portal}`, + to: WebsitePaths.Portal, labelText: 'Relayer ecosystem', iconName: 'zmdi-portable-wifi', }; diff --git a/packages/website/ts/components/portal/menu.tsx b/packages/website/ts/components/portal/menu.tsx index 39dab77f5..d59101686 100644 --- a/packages/website/ts/components/portal/menu.tsx +++ b/packages/website/ts/components/portal/menu.tsx @@ -1,7 +1,7 @@ -import { Styles } from '@0xproject/react-shared'; +import { Styles } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; -import { MenuItem } from 'ts/components/ui/menu_item'; +import { CustomMenuItem } from 'ts/components/ui/custom_menu_item'; import { colors } from 'ts/style/colors'; import { WebsitePaths } from 'ts/types'; @@ -67,14 +67,14 @@ export const Menu: React.StatelessComponent<MenuProps> = (props: MenuProps) => { {_.map(props.menuItemEntries, entry => { const isSelected = entry.to === props.selectedPath; return ( - <MenuItem key={entry.to} to={entry.to}> + <CustomMenuItem key={entry.to} to={entry.to}> <MenuItemLabel title={entry.labelText} iconName={entry.iconName} selected={isSelected} theme={props.theme} /> - </MenuItem> + </CustomMenuItem> ); })} </div> diff --git a/packages/website/ts/components/portal/portal.tsx b/packages/website/ts/components/portal/portal.tsx index ff11880e3..94ab63ac6 100644 --- a/packages/website/ts/components/portal/portal.tsx +++ b/packages/website/ts/components/portal/portal.tsx @@ -1,9 +1,9 @@ -import { colors } from '@0xproject/react-shared'; -import { BigNumber } from '@0xproject/utils'; +import { colors, Link } from '@0x/react-shared'; +import { BigNumber } from '@0x/utils'; import * as _ from 'lodash'; import * as React from 'react'; import * as DocumentTitle from 'react-document-title'; -import { Link, Route, RouteComponentProps, Switch } from 'react-router-dom'; +import { Route, RouteComponentProps, Switch } from 'react-router-dom'; import { Blockchain } from 'ts/blockchain'; import { BlockchainErrDialog } from 'ts/components/dialogs/blockchain_err_dialog'; @@ -18,7 +18,7 @@ import { Loading } from 'ts/components/portal/loading'; import { Menu, MenuTheme } from 'ts/components/portal/menu'; import { Section } from 'ts/components/portal/section'; import { TextHeader } from 'ts/components/portal/text_header'; -import { RelayerIndex } from 'ts/components/relayer_index/relayer_index'; +import { RelayerIndex, RelayerIndexCellStyle } from 'ts/components/relayer_index/relayer_index'; import { TokenBalances } from 'ts/components/token_balances'; import { TopBar, TopBarDisplayType } from 'ts/components/top_bar/top_bar'; import { TradeHistory } from 'ts/components/trade_history/trade_history'; @@ -39,7 +39,7 @@ import { BlockchainErrs, HashData, ItemByAddress, - Order, + PortalOrder, ProviderType, ScreenWidths, Token, @@ -71,7 +71,7 @@ export interface PortalProps { userEtherBalanceInWei?: BigNumber; userAddress: string; shouldBlockchainErrDialogBeOpen: boolean; - userSuppliedOrderCache: Order; + userSuppliedOrderCache: PortalOrder; location: Location; flashMessage?: string | React.ReactNode; lastForceTokenStateRefetch: number; @@ -114,11 +114,11 @@ const DOCUMENT_DESCRIPTION = 'Learn about and trade on 0x Relayers'; export class Portal extends React.Component<PortalProps, PortalState> { private _blockchain: Blockchain; - private readonly _sharedOrderIfExists: Order; + private readonly _sharedOrderIfExists: PortalOrder; private readonly _throttledScreenWidthUpdate: () => void; constructor(props: PortalProps) { super(props); - this._sharedOrderIfExists = orderParser.parse(window.location.search); + this._sharedOrderIfExists = orderParser.parseQueryString(window.location.search); this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT); const didAcceptPortalDisclaimer = localStorage.getItemIfExists(constants.LOCAL_STORAGE_KEY_ACCEPT_DISCLAIMER); const hasAcceptedDisclaimer = @@ -210,12 +210,16 @@ export class Portal extends React.Component<PortalProps, PortalState> { isLoaded: false, }; } - this.setState({ - trackedTokenStateByAddress, - }); - // Fetch the actual balance/allowance. - // tslint:disable-next-line:no-floating-promises - this._fetchBalancesAndAllowancesAsync(newTokenAddresses); + this.setState( + { + trackedTokenStateByAddress, + }, + () => { + // Fetch the actual balance/allowance. + // tslint:disable-next-line:no-floating-promises + this._fetchBalancesAndAllowancesAsync(newTokenAddresses); + }, + ); } } public render(): React.ReactNode { @@ -317,7 +321,7 @@ export class Portal extends React.Component<PortalProps, PortalState> { }; return ( <Section - header={<BackButton to={`${WebsitePaths.Portal}`} labelText="back to Relayers" />} + header={<BackButton to={WebsitePaths.Portal} labelText="back to Relayers" />} body={<Menu selectedPath={routeComponentProps.location.pathname} theme={menuTheme} />} /> ); @@ -389,9 +393,7 @@ export class Portal extends React.Component<PortalProps, PortalState> { </Container> ); return !shouldStartOnboarding ? ( - <Link to={{ pathname: `${WebsitePaths.Portal}/account` }} style={{ textDecoration: 'none' }}> - {startOnboarding} - </Link> + <Link to={`${WebsitePaths.Portal}/account`}>{startOnboarding}</Link> ) : ( startOnboarding ); @@ -541,17 +543,22 @@ export class Portal extends React.Component<PortalProps, PortalState> { } private _renderRelayerIndexSection(): React.ReactNode { const isMobile = utils.isMobileWidth(this.props.screenWidth); + // TODO(bmillman): revert RelayerIndex cellStyle to Expanded once data pipeline is tracking v2 volume return ( <Section header={!isMobile && <TextHeader labelText="0x Relayers" />} body={ - <Container className="flex flex-column items-center"> + <Container className="flex flex-column"> {isMobile && ( <Container marginTop="20px" marginBottom="20px"> {this._renderStartOnboarding()} </Container> )} - <RelayerIndex networkId={this.props.networkId} screenWidth={this.props.screenWidth} /> + <RelayerIndex + networkId={this.props.networkId} + screenWidth={this.props.screenWidth} + cellStyle={RelayerIndexCellStyle.Minimized} + /> </Container> } /> @@ -641,6 +648,9 @@ export class Portal extends React.Component<PortalProps, PortalState> { } private async _fetchBalancesAndAllowancesAsync(tokenAddresses: string[]): Promise<void> { + if (_.isEmpty(tokenAddresses)) { + return; + } const trackedTokenStateByAddress = this.state.trackedTokenStateByAddress; const userAddressIfExists = _.isEmpty(this.props.userAddress) ? undefined : this.props.userAddress; const balancesAndAllowances = await Promise.all( diff --git a/packages/website/ts/components/portal/text_header.tsx b/packages/website/ts/components/portal/text_header.tsx index 853da3a29..b6045b832 100644 --- a/packages/website/ts/components/portal/text_header.tsx +++ b/packages/website/ts/components/portal/text_header.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; import { Text } from 'ts/components/ui/text'; diff --git a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx index 193dd237a..7f1b4ebb4 100644 --- a/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx +++ b/packages/website/ts/components/relayer_index/relayer_grid_tile.tsx @@ -1,4 +1,4 @@ -import { Styles } from '@0xproject/react-shared'; +import { Styles } from '@0x/react-shared'; import * as _ from 'lodash'; import { GridTile as PlainGridTile } from 'material-ui/GridList'; import * as React from 'react'; @@ -14,9 +14,15 @@ import { styled } from 'ts/style/theme'; import { WebsiteBackendRelayerInfo } from 'ts/types'; import { utils } from 'ts/utils/utils'; +export enum RelayerGridTileStyle { + Expanded = 0, + Minimized, +} + export interface RelayerGridTileProps { relayerInfo: WebsiteBackendRelayerInfo; networkId: number; + style: RelayerGridTileStyle; } const styles: Styles = { @@ -30,10 +36,14 @@ const styles: Styles = { height: '100%', boxSizing: 'border-box', }, - header: { + expandedHeader: { height: '50%', width: '100%', }, + minimizedHeader: { + height: '100%', + width: '100%', + }, body: { height: '50%', width: '100%', @@ -75,10 +85,12 @@ export const RelayerGridTile: React.StatelessComponent<RelayerGridTileProps> = ( !_.isUndefined(headerImageUrl) && !_.isUndefined(props.relayerInfo.primaryColor) ? props.relayerInfo.primaryColor : FALLBACK_PRIMARY_COLOR; + const isExpanded = props.style === RelayerGridTileStyle.Expanded; + const headerStyle = isExpanded ? styles.expandedHeader : styles.minimizedHeader; return ( <Island style={styles.root} Component={GridTile}> <div style={styles.innerDiv} onClick={onClick}> - <div className="flex items-center" style={{ ...styles.header, backgroundColor: headerBackgroundColor }}> + <div className="flex items-center" style={{ ...headerStyle, backgroundColor: headerBackgroundColor }}> <Image className="mx-auto" src={props.relayerInfo.logoImgUrl} @@ -86,21 +98,23 @@ export const RelayerGridTile: React.StatelessComponent<RelayerGridTileProps> = ( height={RELAYER_ICON_HEIGHT} /> </div> - <div style={styles.body}> - <div className="pb1" style={styles.relayerNameLabel}> - {props.relayerInfo.name} - </div> - <Section titleText="Weekly Trade Volume"> - {!_.isUndefined(weeklyTxnVolume) && ( - <div style={styles.weeklyTradeVolumeLabel}>{props.relayerInfo.weeklyTxnVolume}</div> - )} - </Section> - <Container marginTop="10px"> - <Section titleText="Top Tokens"> - {!_.isEmpty(topTokens) && <TopTokens tokens={topTokens} networkId={props.networkId} />} + {isExpanded && ( + <div style={styles.body}> + <div className="pb1" style={styles.relayerNameLabel}> + {props.relayerInfo.name} + </div> + <Section titleText="Weekly Trade Volume"> + {!_.isUndefined(weeklyTxnVolume) && ( + <div style={styles.weeklyTradeVolumeLabel}>{props.relayerInfo.weeklyTxnVolume}</div> + )} </Section> - </Container> - </div> + <Container marginTop="10px"> + <Section titleText="Top Tokens"> + {!_.isEmpty(topTokens) && <TopTokens tokens={topTokens} networkId={props.networkId} />} + </Section> + </Container> + </div> + )} </div> </Island> ); diff --git a/packages/website/ts/components/relayer_index/relayer_index.tsx b/packages/website/ts/components/relayer_index/relayer_index.tsx index 4aea1bbbb..e88c20d7e 100644 --- a/packages/website/ts/components/relayer_index/relayer_index.tsx +++ b/packages/website/ts/components/relayer_index/relayer_index.tsx @@ -3,14 +3,20 @@ import CircularProgress from 'material-ui/CircularProgress'; import { GridList } from 'material-ui/GridList'; import * as React from 'react'; -import { RelayerGridTile } from 'ts/components/relayer_index/relayer_grid_tile'; +import { RelayerGridTile, RelayerGridTileStyle } from 'ts/components/relayer_index/relayer_grid_tile'; import { Retry } from 'ts/components/ui/retry'; import { ScreenWidths, WebsiteBackendRelayerInfo } from 'ts/types'; import { backendClient } from 'ts/utils/backend_client'; +export enum RelayerIndexCellStyle { + Expanded = 0, + Minimized, +} + export interface RelayerIndexProps { networkId: number; screenWidth: ScreenWidths; + cellStyle: RelayerIndexCellStyle; } interface RelayerIndexState { @@ -18,7 +24,8 @@ interface RelayerIndexState { error?: Error; } -const CELL_HEIGHT = 290; +const CELL_HEIGHT_EXPANDED = 290; +const CELL_HEIGHT_MINIMIZED = 225; const NUMBER_OF_COLUMNS_LARGE = 3; const NUMBER_OF_COLUMNS_MEDIUM = 2; const NUMBER_OF_COLUMNS_SMALL = 2; @@ -56,16 +63,28 @@ export class RelayerIndex extends React.Component<RelayerIndexProps, RelayerInde </div> ); } else { - const numberOfColumns = this._numberOfColumnsForScreenWidth(this.props.screenWidth); + const numberOfRelayers = this.state.relayerInfos.length; + const numberOfColumns = Math.min( + numberOfRelayers, + this._numberOfColumnsForScreenWidth(this.props.screenWidth), + ); + const isExpanded = this.props.cellStyle === RelayerIndexCellStyle.Expanded; + const cellHeight = isExpanded ? CELL_HEIGHT_EXPANDED : CELL_HEIGHT_MINIMIZED; + const gridTileStyle = isExpanded ? RelayerGridTileStyle.Expanded : RelayerGridTileStyle.Minimized; return ( <GridList - cellHeight={CELL_HEIGHT} + cellHeight={cellHeight} cols={numberOfColumns} padding={GRID_PADDING} style={{ marginTop: -10, marginBottom: 0 }} > {this.state.relayerInfos.map((relayerInfo: WebsiteBackendRelayerInfo, index) => ( - <RelayerGridTile key={index} relayerInfo={relayerInfo} networkId={this.props.networkId} /> + <RelayerGridTile + key={index} + relayerInfo={relayerInfo} + networkId={this.props.networkId} + style={gridTileStyle} + /> ))} </GridList> ); diff --git a/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx b/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx index f3787bd27..558d99855 100644 --- a/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx +++ b/packages/website/ts/components/relayer_index/relayer_top_tokens.tsx @@ -1,4 +1,4 @@ -import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; +import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; diff --git a/packages/website/ts/components/send_button.tsx b/packages/website/ts/components/send_button.tsx index 107983dee..27438e5d5 100644 --- a/packages/website/ts/components/send_button.tsx +++ b/packages/website/ts/components/send_button.tsx @@ -1,4 +1,4 @@ -import { BigNumber, logUtils } from '@0xproject/utils'; +import { BigNumber, logUtils } from '@0x/utils'; import * as _ from 'lodash'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; diff --git a/packages/website/ts/components/sidebar_header.tsx b/packages/website/ts/components/sidebar_header.tsx deleted file mode 100644 index a14ab54f5..000000000 --- a/packages/website/ts/components/sidebar_header.tsx +++ /dev/null @@ -1,35 +0,0 @@ -import { colors } from '@0xproject/react-shared'; -import * as React from 'react'; - -interface SidebarHeaderProps { - title: string; - iconUrl: string; -} - -interface SidebarHeaderState {} - -export class SidebarHeader extends React.Component<SidebarHeaderProps, SidebarHeaderState> { - public render(): React.ReactNode { - return ( - <div className="pt2 md-px1 sm-px2" style={{ color: colors.black, paddingBottom: 18 }}> - <div className="flex" style={{ fontSize: 25 }}> - <div style={{ fontWeight: 'bold', fontFamily: 'Roboto Mono' }}>0x</div> - <div className="pl2" style={{ lineHeight: 1.4, fontWeight: 300 }}> - docs - </div> - </div> - <div className="pl1" style={{ color: colors.grey350, paddingBottom: 9, paddingLeft: 10, height: 17 }}> - | - </div> - <div className="flex"> - <div> - <img src={this.props.iconUrl} width="22" /> - </div> - <div className="pl1" style={{ fontWeight: 600, fontSize: 20, lineHeight: 1.2 }}> - {this.props.title} - </div> - </div> - </div> - ); - } -} diff --git a/packages/website/ts/components/token_balances.tsx b/packages/website/ts/components/token_balances.tsx index 969ef32ff..9ba2bad84 100644 --- a/packages/website/ts/components/token_balances.tsx +++ b/packages/website/ts/components/token_balances.tsx @@ -4,9 +4,9 @@ import { Networks, Styles, utils as sharedUtils, -} from '@0xproject/react-shared'; -import { BigNumber, errorUtils, fetchAsync, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +} from '@0x/react-shared'; +import { BigNumber, errorUtils, fetchAsync, logUtils } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import Dialog from 'material-ui/Dialog'; import Divider from 'material-ui/Divider'; @@ -165,7 +165,7 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala key="errorOkBtn" label="Ok" primary={true} - onTouchTap={this._onErrorDialogToggle.bind(this, false)} + onClick={this._onErrorDialogToggle.bind(this, false)} />, ]; const isTestNetwork = utils.isTestNetwork(this.props.networkId); @@ -337,14 +337,8 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala const isMintable = (_.includes(configs.SYMBOLS_OF_MINTABLE_KOVAN_TOKENS, token.symbol) && this.props.networkId === sharedConstants.NETWORK_ID_BY_NAME[Networks.Kovan]) || - (_.includes(configs.SYMBOLS_OF_MINTABLE_RINKEBY_ROPSTEN_TOKENS, token.symbol) && - _.includes( - [ - sharedConstants.NETWORK_ID_BY_NAME[Networks.Rinkeby], - sharedConstants.NETWORK_ID_BY_NAME[Networks.Ropsten], - ], - this.props.networkId, - )); + (_.includes(configs.SYMBOLS_OF_MINTABLE_ROPSTEN_TOKENS, token.symbol) && + this.props.networkId === sharedConstants.NETWORK_ID_BY_NAME[Networks.Ropsten]); return ( <TableRow key={token.address} style={{ height: TOKEN_TABLE_ROW_HEIGHT }}> <TableRowColumn colSpan={tokenColSpan}> @@ -392,14 +386,6 @@ export class TokenBalances extends React.Component<TokenBalancesProps, TokenBala onClickAsyncFn={this._onMintTestTokensAsync.bind(this, token)} /> )} - {token.symbol === ZRX_TOKEN_SYMBOL && ( - <LifeCycleRaisedButton - labelReady="Request" - labelLoading="Sending..." - labelComplete="Sent!" - onClickAsyncFn={this._faucetRequestAsync.bind(this, false)} - /> - )} </TableRowColumn> )} {this.props.screenWidth !== ScreenWidths.Sm && ( diff --git a/packages/website/ts/components/top_bar/provider_display.tsx b/packages/website/ts/components/top_bar/provider_display.tsx index 806eaeea5..c88c29b8e 100644 --- a/packages/website/ts/components/top_bar/provider_display.tsx +++ b/packages/website/ts/components/top_bar/provider_display.tsx @@ -1,4 +1,4 @@ -import { Styles } from '@0xproject/react-shared'; +import { Styles } from '@0x/react-shared'; import * as _ from 'lodash'; import CircularProgress from 'material-ui/CircularProgress'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; diff --git a/packages/website/ts/components/top_bar/top_bar.tsx b/packages/website/ts/components/top_bar/top_bar.tsx index 646d3fc94..d5967cd1d 100644 --- a/packages/website/ts/components/top_bar/top_bar.tsx +++ b/packages/website/ts/components/top_bar/top_bar.tsx @@ -1,19 +1,18 @@ -import { DocsInfo, DocsMenu } from '@0xproject/react-docs'; -import { colors, MenuSubsectionsBySection, NestedSidebarMenu, Styles } from '@0xproject/react-shared'; +import { DocsInfo } from '@0x/react-docs'; +import { ALink, colors, Link, Styles } from '@0x/react-shared'; +import { ObjectMap } from '@0x/types'; import * as _ from 'lodash'; import Drawer from 'material-ui/Drawer'; -import Menu from 'material-ui/Menu'; import MenuItem from 'material-ui/MenuItem'; import * as React from 'react'; -import { Link } from 'react-router-dom'; import { Blockchain } from 'ts/blockchain'; +import { DevelopersDropDown } from 'ts/components/dropdowns/developers_drop_down'; import { DrawerMenu } from 'ts/components/portal/drawer_menu'; import { ProviderDisplay } from 'ts/components/top_bar/provider_display'; import { TopBarMenuItem } from 'ts/components/top_bar/top_bar_menu_item'; import { Container } from 'ts/components/ui/container'; -import { DropDown } from 'ts/components/ui/drop_down'; import { Dispatcher } from 'ts/redux/dispatcher'; -import { Deco, Key, ProviderType, WebsiteLegacyPaths, WebsitePaths } from 'ts/types'; +import { Deco, Key, ProviderType, WebsitePaths } from 'ts/types'; import { constants } from 'ts/utils/constants'; import { Translate } from 'ts/utils/translate'; @@ -35,8 +34,7 @@ export interface TopBarProps { translate: Translate; docsVersion?: string; availableDocVersions?: string[]; - menu?: DocsMenu; - menuSubsectionsBySection?: MenuSubsectionsBySection; + sectionNameToLinks?: ObjectMap<ALink[]>; displayType?: TopBarDisplayType; docsInfo?: DocsInfo; style?: React.CSSProperties; @@ -109,109 +107,17 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { ? 'flex mx-auto items-center max-width-4' : 'flex mx-auto items-center'; const height = isExpandedDisplayType ? EXPANDED_HEIGHT : DEFAULT_HEIGHT; - const developerSectionMenuItems = [ - <Link key="subMenuItem-zeroEx" to={WebsitePaths.ZeroExJs} className="text-decoration-none"> - <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="0x.js" /> - </Link>, - <Link key="subMenuItem-smartContracts" to={WebsitePaths.SmartContracts} className="text-decoration-none"> - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.SmartContract, Deco.CapWords)} - /> - </Link>, - <Link key="subMenuItem-0xconnect" to={WebsitePaths.Connect} className="text-decoration-none"> - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.Connect, Deco.CapWords)} - /> - </Link>, - <a - key="subMenuItem-standard-relayer-api" - target="_blank" - className="text-decoration-none" - href={constants.URL_STANDARD_RELAYER_API_GITHUB} - > - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.StandardRelayerApi, Deco.CapWords)} - /> - </a>, - <Link key="subMenuItem-jsonSchema" to={WebsitePaths.JSONSchemas} className="text-decoration-none"> - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.JsonSchemas, Deco.CapWords)} - /> - </Link>, - <Link key="subMenuItem-subproviders" to={WebsitePaths.Subproviders} className="text-decoration-none"> - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.Subproviders, Deco.CapWords)} - /> - </Link>, - <Link key="subMenuItem-web3Wrapper" to={WebsitePaths.Web3Wrapper} className="text-decoration-none"> - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.Web3Wrapper, Deco.CapWords)} - /> - </Link>, - <Link key="subMenuItem-sol-compiler" to={WebsitePaths.SolCompiler} className="text-decoration-none"> - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.SolCompiler, Deco.CapWords)} - /> - </Link>, - <Link key="subMenuItem-sol-cov" to={WebsitePaths.SolCov} className="text-decoration-none"> - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.SolCov, Deco.CapWords)} - /> - </Link>, - <Link key="subMenuItem-ethereum-types" to={WebsitePaths.EthereumTypes} className="text-decoration-none"> - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.EthereumTypes, Deco.CapWords)} - /> - </Link>, - <a - key="subMenuItem-whitePaper" - target="_blank" - className="text-decoration-none" - href={`${WebsitePaths.Whitepaper}`} - > - <MenuItem - style={{ fontSize: styles.menuItem.fontSize }} - primaryText={this.props.translate.get(Key.Whitepaper, Deco.CapWords)} - /> - </a>, - <a - key="subMenuItem-github" - target="_blank" - className="text-decoration-none" - href={constants.URL_GITHUB_ORG} - > - <MenuItem style={{ fontSize: styles.menuItem.fontSize }} primaryText="GitHub" /> - </a>, - ]; const bottomBorderStyle = this._shouldDisplayBottomBar() ? styles.bottomBar : {}; const fullWidthClasses = isExpandedDisplayType ? 'pr4' : ''; const logoUrl = isNightVersion ? '/images/protocol_logo_white.png' : '/images/protocol_logo_black.png'; const menuClasses = `col col-${ - isExpandedDisplayType ? '4' : '5' + isExpandedDisplayType ? '4' : '6' } ${fullWidthClasses} lg-pr0 md-pr2 sm-hide xs-hide`; const menuIconStyle = { fontSize: 25, color: isNightVersion ? 'white' : 'black', cursor: 'pointer', }; - const activeNode = ( - <div className="flex relative" style={{ color: menuIconStyle.color }}> - <div style={{ paddingRight: 10 }}>{this.props.translate.get(Key.Developers, Deco.Cap)}</div> - <div className="absolute" style={{ paddingLeft: 3, right: 3, top: -2 }}> - <i className="zmdi zmdi-caret-right" style={{ fontSize: 22 }} /> - </div> - </div> - ); - const popoverContent = <Menu style={{ color: colors.darkGrey }}>{developerSectionMenuItems}</Menu>; return ( <div style={{ ...styles.topBar, ...bottomBorderStyle, ...this.props.style, ...{ height } }} @@ -224,49 +130,45 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { paddingLeft={this.props.paddingLeft} paddingRight={this.props.paddingRight} > - <Link to={`${WebsitePaths.Home}`} className="text-decoration-none"> + <Link to={WebsitePaths.Home}> <img src={logoUrl} height="30" /> </Link> <div className="flex-auto" /> {!this._isViewingPortal() && ( <div className={menuClasses}> <div className="flex items-center justify-between"> - <DropDown - activeNode={activeNode} - popoverContent={popoverContent} - anchorOrigin={{ horizontal: 'middle', vertical: 'bottom' }} - targetOrigin={{ horizontal: 'middle', vertical: 'top' }} - style={styles.menuItem} + <DevelopersDropDown + location={this.props.location} + menuItemStyles={{ ...styles.menuItem, paddingBottom: 12, paddingTop: 12 }} + translate={this.props.translate} + menuIconStyle={menuIconStyle} /> <TopBarMenuItem - title={this.props.translate.get(Key.Wiki, Deco.Cap)} - path={`${WebsitePaths.Wiki}`} + title={this.props.translate.get(Key.Blog, Deco.Cap)} + path={constants.URL_BLOG} style={styles.menuItem} isNightVersion={isNightVersion} - isExternal={false} + shouldOpenInNewTab={true} /> <TopBarMenuItem - title={this.props.translate.get(Key.Blog, Deco.Cap)} - path={constants.URL_BLOG} + title={this.props.translate.get(Key.About, Deco.Cap)} + path={WebsitePaths.About} style={styles.menuItem} isNightVersion={isNightVersion} - isExternal={true} /> <TopBarMenuItem - title={this.props.translate.get(Key.About, Deco.Cap)} - path={`${WebsitePaths.About}`} + title={this.props.translate.get(Key.Careers, Deco.Cap)} + path={WebsitePaths.Careers} style={styles.menuItem} isNightVersion={isNightVersion} - isExternal={false} /> <TopBarMenuItem title={this.props.translate.get(Key.TradeCallToAction, Deco.Cap)} - path={`${WebsitePaths.Portal}`} + path={WebsitePaths.Portal} isPrimary={true} style={styles.menuItem} className={`${isExpandedDisplayType && 'md-hide'}`} isNightVersion={isNightVersion} - isExternal={false} /> </div> </div> @@ -323,104 +225,36 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { onRequestChange={this._onMenuButtonClick.bind(this)} > <div className="clearfix"> - {this._renderDocsMenu()} - {this._renderWiki()} <div className="pl1 py1 mt3" style={{ backgroundColor: colors.lightGrey }}> {this.props.translate.get(Key.Website, Deco.Cap)} </div> - <Link to={WebsitePaths.Home} className="text-decoration-none"> + <Link to={WebsitePaths.Home}> <MenuItem className="py2">{this.props.translate.get(Key.Home, Deco.Cap)}</MenuItem> </Link> - <Link to={`${WebsitePaths.Wiki}`} className="text-decoration-none"> - <MenuItem className="py2">{this.props.translate.get(Key.Wiki, Deco.Cap)}</MenuItem> + <Link to={WebsitePaths.Docs}> + <MenuItem className="py2">{this.props.translate.get(Key.Docs, Deco.Cap)}</MenuItem> </Link> - {!this._isViewing0xjsDocs() && ( - <Link to={WebsitePaths.ZeroExJs} className="text-decoration-none"> - <MenuItem className="py2">0x.js {this.props.translate.get(Key.Docs, Deco.Cap)}</MenuItem> - </Link> - )} - {!this._isViewingConnectDocs() && ( - <Link to={WebsitePaths.Connect} className="text-decoration-none"> - <MenuItem className="py2"> - {this.props.translate.get(Key.Connect, Deco.Cap)}{' '} - {this.props.translate.get(Key.Docs, Deco.Cap)} - </MenuItem> - </Link> - )} - {!this._isViewingSmartContractsDocs() && ( - <Link to={WebsitePaths.SmartContracts} className="text-decoration-none"> - <MenuItem className="py2"> - {this.props.translate.get(Key.SmartContract, Deco.Cap)}{' '} - {this.props.translate.get(Key.Docs, Deco.Cap)} - </MenuItem> - </Link> - )} - {!this._isViewingWeb3WrapperDocs() && ( - <Link to={WebsitePaths.Web3Wrapper} className="text-decoration-none"> - <MenuItem className="py2"> - {this.props.translate.get(Key.Web3Wrapper, Deco.Cap)}{' '} - {this.props.translate.get(Key.Docs, Deco.Cap)} - </MenuItem> - </Link> - )} - {!this._isViewingSolCompilerDocs() && ( - <Link to={WebsitePaths.SolCompiler} className="text-decoration-none"> - <MenuItem className="py2"> - {this.props.translate.get(Key.SolCompiler, Deco.Cap)}{' '} - {this.props.translate.get(Key.Docs, Deco.Cap)} - </MenuItem> - </Link> - )} - {!this._isViewingJsonSchemasDocs() && ( - <Link to={WebsitePaths.JSONSchemas} className="text-decoration-none"> - <MenuItem className="py2"> - {this.props.translate.get(Key.JsonSchemas, Deco.Cap)}{' '} - {this.props.translate.get(Key.Docs, Deco.Cap)} - </MenuItem> - </Link> - )} - {!this._isViewingSolCovDocs() && ( - <Link to={WebsitePaths.SolCov} className="text-decoration-none"> - <MenuItem className="py2"> - {this.props.translate.get(Key.SolCov, Deco.Cap)}{' '} - {this.props.translate.get(Key.Docs, Deco.Cap)} - </MenuItem> - </Link> - )} - {!this._isViewingSubprovidersDocs() && ( - <Link to={WebsitePaths.Subproviders} className="text-decoration-none"> - <MenuItem className="py2"> - {this.props.translate.get(Key.Subproviders, Deco.Cap)}{' '} - {this.props.translate.get(Key.Docs, Deco.Cap)} - </MenuItem> - </Link> - )} - {!this._isViewingEthereumTypesDocs() && ( - <Link to={WebsitePaths.EthereumTypes} className="text-decoration-none"> - <MenuItem className="py2"> - {this.props.translate.get(Key.EthereumTypes, Deco.Cap)}{' '} - {this.props.translate.get(Key.Docs, Deco.Cap)} - </MenuItem> - </Link> - )} {!this._isViewingPortal() && ( - <Link to={`${WebsitePaths.Portal}`} className="text-decoration-none"> + <Link to={WebsitePaths.Portal}> <MenuItem className="py2"> {this.props.translate.get(Key.PortalDApp, Deco.CapWords)} </MenuItem> </Link> )} - <a className="text-decoration-none" target="_blank" href={`${WebsitePaths.Whitepaper}`}> + <Link to={WebsitePaths.Whitepaper} shouldOpenInNewTab={true}> <MenuItem className="py2">{this.props.translate.get(Key.Whitepaper, Deco.Cap)}</MenuItem> - </a> - <Link to={`${WebsitePaths.About}`} className="text-decoration-none"> + </Link> + <Link to={WebsitePaths.About}> <MenuItem className="py2">{this.props.translate.get(Key.About, Deco.Cap)}</MenuItem> </Link> - <a className="text-decoration-none" target="_blank" href={constants.URL_BLOG}> + <Link to={WebsitePaths.Careers}> + <MenuItem className="py2">{this.props.translate.get(Key.Careers, Deco.Cap)}</MenuItem> + </Link> + <Link to={constants.URL_BLOG} shouldOpenInNewTab={true}> <MenuItem className="py2">{this.props.translate.get(Key.Blog, Deco.Cap)}</MenuItem> - </a> - <Link to={`${WebsitePaths.FAQ}`} className="text-decoration-none"> - <MenuItem className="py2" onTouchTap={this._onMenuButtonClick.bind(this)}> + </Link> + <Link to={WebsitePaths.FAQ}> + <MenuItem className="py2" onClick={this._onMenuButtonClick.bind(this)}> {this.props.translate.get(Key.Faq, Deco.Cap)} </MenuItem> </Link> @@ -428,52 +262,6 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { </Drawer> ); } - private _renderDocsMenu(): React.ReactNode { - if ( - (!this._isViewing0xjsDocs() && - !this._isViewingSmartContractsDocs() && - !this._isViewingWeb3WrapperDocs() && - !this._isViewingSolCompilerDocs() && - !this._isViewingJsonSchemasDocs() && - !this._isViewingSolCovDocs() && - !this._isViewingSubprovidersDocs() && - !this._isViewingConnectDocs()) || - _.isUndefined(this.props.menu) - ) { - return undefined; - } - return ( - <div className="lg-hide md-hide"> - <NestedSidebarMenu - topLevelMenu={this.props.menu} - menuSubsectionsBySection={this.props.menuSubsectionsBySection} - sidebarHeader={this.props.sidebarHeader} - shouldDisplaySectionHeaders={false} - onMenuItemClick={this._onMenuButtonClick.bind(this)} - selectedVersion={this.props.docsVersion} - versions={this.props.availableDocVersions} - onVersionSelected={this.props.onVersionSelected} - /> - </div> - ); - } - private _renderWiki(): React.ReactNode { - if (!this._isViewingWiki()) { - return undefined; - } - - return ( - <div className="lg-hide md-hide"> - <NestedSidebarMenu - topLevelMenu={this.props.menuSubsectionsBySection} - menuSubsectionsBySection={this.props.menuSubsectionsBySection} - sidebarHeader={this.props.sidebarHeader} - shouldDisplaySectionHeaders={false} - onMenuItemClick={this._onMenuButtonClick.bind(this)} - /> - </div> - ); - } private _onMenuButtonClick(): void { this.setState({ isDrawerOpen: !this.state.isDrawerOpen, @@ -482,62 +270,10 @@ export class TopBar extends React.Component<TopBarProps, TopBarState> { private _isViewingPortal(): boolean { return _.includes(this.props.location.pathname, WebsitePaths.Portal); } - private _isViewingDocs(): boolean { - return _.includes(this.props.location.pathname, WebsitePaths.Docs); - } private _isViewingFAQ(): boolean { return _.includes(this.props.location.pathname, WebsitePaths.FAQ); } - private _isViewing0xjsDocs(): boolean { - return ( - _.includes(this.props.location.pathname, WebsitePaths.ZeroExJs) || - _.includes(this.props.location.pathname, WebsiteLegacyPaths.ZeroExJs) - ); - } - private _isViewingConnectDocs(): boolean { - return _.includes(this.props.location.pathname, WebsitePaths.Connect); - } - private _isViewingSmartContractsDocs(): boolean { - return _.includes(this.props.location.pathname, WebsitePaths.SmartContracts); - } - private _isViewingWeb3WrapperDocs(): boolean { - return ( - _.includes(this.props.location.pathname, WebsitePaths.Web3Wrapper) || - _.includes(this.props.location.pathname, WebsiteLegacyPaths.Web3Wrapper) - ); - } - private _isViewingSolCompilerDocs(): boolean { - return _.includes(this.props.location.pathname, WebsitePaths.SolCompiler); - } - private _isViewingJsonSchemasDocs(): boolean { - return _.includes(this.props.location.pathname, WebsitePaths.JSONSchemas); - } - private _isViewingSolCovDocs(): boolean { - return _.includes(this.props.location.pathname, WebsitePaths.SolCov); - } - private _isViewingSubprovidersDocs(): boolean { - return _.includes(this.props.location.pathname, WebsitePaths.Subproviders); - } - private _isViewingEthereumTypesDocs(): boolean { - return _.includes(this.props.location.pathname, WebsitePaths.EthereumTypes); - } - private _isViewingWiki(): boolean { - return _.includes(this.props.location.pathname, WebsitePaths.Wiki); - } private _shouldDisplayBottomBar(): boolean { - return ( - this._isViewingWiki() || - this._isViewingFAQ() || - this._isViewingDocs() || - this._isViewing0xjsDocs() || - this._isViewingSmartContractsDocs() || - this._isViewingWeb3WrapperDocs() || - this._isViewingSolCompilerDocs() || - this._isViewingJsonSchemasDocs() || - this._isViewingSolCovDocs() || - this._isViewingSubprovidersDocs() || - this._isViewingConnectDocs() || - this._isViewingPortal() - ); + return this._isViewingFAQ() || this._isViewingPortal(); } } // tslint:disable:max-file-line-count diff --git a/packages/website/ts/components/top_bar/top_bar_menu_item.tsx b/packages/website/ts/components/top_bar/top_bar_menu_item.tsx index 25fab2868..9f15cffbb 100644 --- a/packages/website/ts/components/top_bar/top_bar_menu_item.tsx +++ b/packages/website/ts/components/top_bar/top_bar_menu_item.tsx @@ -1,7 +1,6 @@ -import { colors } from '@0xproject/react-shared'; +import { colors, Link } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; -import { Link } from 'react-router-dom'; import { CallToAction } from 'ts/components/ui/button'; @@ -13,7 +12,7 @@ interface TopBarMenuItemProps { title: string; path?: string; isPrimary?: boolean; - isExternal: boolean; + shouldOpenInNewTab?: boolean; style?: React.CSSProperties; className?: string; isNightVersion?: boolean; @@ -26,6 +25,7 @@ export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarM isPrimary: false, style: DEFAULT_STYLE, className: '', + shouldOpenInNewTab: false, isNightVersion: false, }; public render(): React.ReactNode { @@ -38,20 +38,9 @@ export class TopBarMenuItem extends React.Component<TopBarMenuItemProps, TopBarM ); return ( <div className={`center ${this.props.className}`} style={{ ...this.props.style, color: menuItemColor }}> - {this.props.isExternal ? ( - <a - className="text-decoration-none" - style={{ color: linkColor }} - target="_blank" - href={this.props.path} - > - {itemContent} - </a> - ) : ( - <Link to={this.props.path} className="text-decoration-none" style={{ color: linkColor }}> - {itemContent} - </Link> - )} + <Link to={this.props.path} shouldOpenInNewTab={this.props.shouldOpenInNewTab} fontColor={linkColor}> + {itemContent} + </Link> </div> ); } diff --git a/packages/website/ts/components/track_token_confirmation.tsx b/packages/website/ts/components/track_token_confirmation.tsx index 294fb8590..e701686b0 100644 --- a/packages/website/ts/components/track_token_confirmation.tsx +++ b/packages/website/ts/components/track_token_confirmation.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import { Party } from 'ts/components/ui/party'; diff --git a/packages/website/ts/components/trade_history/trade_history_item.tsx b/packages/website/ts/components/trade_history/trade_history_item.tsx index 321a8b0e1..667027dce 100644 --- a/packages/website/ts/components/trade_history/trade_history_item.tsx +++ b/packages/website/ts/components/trade_history/trade_history_item.tsx @@ -1,6 +1,6 @@ -import { colors, EtherscanLinkSuffixes } from '@0xproject/react-shared'; -import { BigNumber } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { colors, EtherscanLinkSuffixes } from '@0x/react-shared'; +import { BigNumber } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import Paper from 'material-ui/Paper'; import * as moment from 'moment'; diff --git a/packages/website/ts/components/ui/alert.tsx b/packages/website/ts/components/ui/alert.tsx index b571d8c1c..32e0f1be8 100644 --- a/packages/website/ts/components/ui/alert.tsx +++ b/packages/website/ts/components/ui/alert.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; import { AlertTypes } from 'ts/types'; diff --git a/packages/website/ts/components/ui/allowance_state_view.tsx b/packages/website/ts/components/ui/allowance_state_view.tsx index 93d6b0ebb..fc754421a 100644 --- a/packages/website/ts/components/ui/allowance_state_view.tsx +++ b/packages/website/ts/components/ui/allowance_state_view.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; import { Container } from 'ts/components/ui/container'; import { Spinner } from 'ts/components/ui/spinner'; diff --git a/packages/website/ts/components/ui/balance.tsx b/packages/website/ts/components/ui/balance.tsx index 9e5a256b6..a1a8ff89b 100644 --- a/packages/website/ts/components/ui/balance.tsx +++ b/packages/website/ts/components/ui/balance.tsx @@ -1,4 +1,4 @@ -import { BigNumber } from '@0xproject/utils'; +import { BigNumber } from '@0x/utils'; import * as React from 'react'; import { Container } from 'ts/components/ui/container'; import { Text } from 'ts/components/ui/text'; diff --git a/packages/website/ts/components/ui/button.tsx b/packages/website/ts/components/ui/button.tsx index 2952c8859..92f927843 100644 --- a/packages/website/ts/components/ui/button.tsx +++ b/packages/website/ts/components/ui/button.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import { darken, saturate } from 'polished'; import * as React from 'react'; import { styled } from 'ts/style/theme'; @@ -10,11 +10,13 @@ export interface ButtonProps { fontFamily?: string; backgroundColor?: string; borderColor?: string; + borderRadius?: string; width?: string; padding?: string; type?: string; isDisabled?: boolean; onClick?: (event: React.MouseEvent<HTMLElement>) => void; + textAlign?: string; } const PlainButton: React.StatelessComponent<ButtonProps> = ({ children, isDisabled, onClick, type, className }) => ( @@ -29,11 +31,12 @@ export const Button = styled(PlainButton)` color: ${props => props.fontColor}; transition: background-color, opacity 0.5s ease; padding: ${props => props.padding}; - border-radius: 6px; + border-radius: ${props => props.borderRadius}; font-weight: 500; outline: none; font-family: ${props => props.fontFamily}; width: ${props => props.width}; + text-align: ${props => props.textAlign}; background-color: ${props => props.backgroundColor}; border: ${props => (props.borderColor ? `1px solid ${props.borderColor}` : 'none')}; &:hover { @@ -52,11 +55,13 @@ export const Button = styled(PlainButton)` Button.defaultProps = { fontSize: '12px', + borderRadius: '6px', backgroundColor: colors.white, width: 'auto', fontFamily: 'Roboto', isDisabled: false, padding: '0.8em 2.2em', + textAlign: 'center', }; Button.displayName = 'Button'; @@ -96,4 +101,5 @@ export const CallToAction: React.StatelessComponent<CallToActionProps> = ({ CallToAction.defaultProps = { type: 'dark', fontSize: '14px', + padding: '0.9em 1.6em', }; diff --git a/packages/website/ts/components/ui/container.tsx b/packages/website/ts/components/ui/container.tsx index f2ae68b70..ece077563 100644 --- a/packages/website/ts/components/ui/container.tsx +++ b/packages/website/ts/components/ui/container.tsx @@ -15,7 +15,11 @@ export interface ContainerProps { paddingRight?: StringOrNum; paddingLeft?: StringOrNum; backgroundColor?: string; + background?: string; borderRadius?: StringOrNum; + borderBottomLeftRadius?: StringOrNum; + borderBottomRightRadius?: StringOrNum; + borderBottom?: StringOrNum; maxWidth?: StringOrNum; maxHeight?: StringOrNum; width?: StringOrNum; diff --git a/packages/website/ts/components/ui/copy_icon.tsx b/packages/website/ts/components/ui/copy_icon.tsx index 0330d1843..59e398cb6 100644 --- a/packages/website/ts/components/ui/copy_icon.tsx +++ b/packages/website/ts/components/ui/copy_icon.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; import * as CopyToClipboard from 'react-copy-to-clipboard'; import * as ReactDOM from 'react-dom'; diff --git a/packages/website/ts/components/ui/menu_item.tsx b/packages/website/ts/components/ui/custom_menu_item.tsx index 0cb4b387c..87ce32126 100644 --- a/packages/website/ts/components/ui/menu_item.tsx +++ b/packages/website/ts/components/ui/custom_menu_item.tsx @@ -1,24 +1,23 @@ +import { Link } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; -import { Link } from 'react-router-dom'; -interface MenuItemProps { +interface CustomMenuItemProps { to: string; - style?: React.CSSProperties; onClick?: () => void; className?: string; } -interface MenuItemState { +interface CustomMenuItemState { isHovering: boolean; } -export class MenuItem extends React.Component<MenuItemProps, MenuItemState> { - public static defaultProps: Partial<MenuItemProps> = { +export class CustomMenuItem extends React.Component<CustomMenuItemProps, CustomMenuItemState> { + public static defaultProps: Partial<CustomMenuItemProps> = { onClick: _.noop.bind(_), className: '', }; - public constructor(props: MenuItemProps) { + public constructor(props: CustomMenuItemProps) { super(props); this.state = { isHovering: false, @@ -30,7 +29,7 @@ export class MenuItem extends React.Component<MenuItemProps, MenuItemState> { opacity: this.state.isHovering ? 0.5 : 1, }; return ( - <Link to={this.props.to} style={{ textDecoration: 'none', ...this.props.style }}> + <Link to={this.props.to}> <div onClick={this.props.onClick.bind(this)} className={`mx-auto ${this.props.className}`} diff --git a/packages/website/ts/components/ui/drop_down.tsx b/packages/website/ts/components/ui/drop_down.tsx index 4d5caef08..4138b3fe5 100644 --- a/packages/website/ts/components/ui/drop_down.tsx +++ b/packages/website/ts/components/ui/drop_down.tsx @@ -1,3 +1,4 @@ +import * as _ from 'lodash'; import Popover from 'material-ui/Popover'; import * as React from 'react'; import { MaterialUIPosition } from 'ts/types'; @@ -21,6 +22,7 @@ export interface DropDownProps { zDepth?: number; activateEvent?: DropdownMouseEvent; closeEvent?: DropdownMouseEvent; + popoverStyle?: React.CSSProperties; } interface DropDownState { @@ -34,6 +36,7 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> { zDepth: 1, activateEvent: DropdownMouseEvent.Hover, closeEvent: DropdownMouseEvent.Hover, + popoverStyle: {}, }; private _isHovering: boolean; private _popoverCloseCheckIntervalId: number; @@ -73,10 +76,15 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> { anchorEl={this.state.anchorEl} anchorOrigin={this.props.anchorOrigin} targetOrigin={this.props.targetOrigin} - onRequestClose={this._closePopover.bind(this)} + onRequestClose={ + this.props.closeEvent === DropdownMouseEvent.Click + ? this._closePopover.bind(this) + : _.noop.bind(_) + } useLayerForClickAway={this.props.closeEvent === DropdownMouseEvent.Click} animated={false} zDepth={this.props.zDepth} + style={this.props.popoverStyle} > <div onMouseEnter={this._onHover.bind(this)} @@ -92,7 +100,7 @@ export class DropDown extends React.Component<DropDownProps, DropDownState> { private _onActiveNodeClick(event: React.FormEvent<HTMLInputElement>): void { if (this.props.activateEvent === DropdownMouseEvent.Click) { this.setState({ - isDropDownOpen: true, + isDropDownOpen: !this.state.isDropDownOpen, anchorEl: event.currentTarget, }); } diff --git a/packages/website/ts/components/ui/ethereum_address.tsx b/packages/website/ts/components/ui/ethereum_address.tsx index f449a8e75..71d98af56 100644 --- a/packages/website/ts/components/ui/ethereum_address.tsx +++ b/packages/website/ts/components/ui/ethereum_address.tsx @@ -1,4 +1,4 @@ -import { EtherscanLinkSuffixes } from '@0xproject/react-shared'; +import { EtherscanLinkSuffixes } from '@0x/react-shared'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); import { EtherScanIcon } from 'ts/components/ui/etherscan_icon'; diff --git a/packages/website/ts/components/ui/etherscan_icon.tsx b/packages/website/ts/components/ui/etherscan_icon.tsx index 0beb69123..57ab91ba2 100644 --- a/packages/website/ts/components/ui/etherscan_icon.tsx +++ b/packages/website/ts/components/ui/etherscan_icon.tsx @@ -1,4 +1,4 @@ -import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; +import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); diff --git a/packages/website/ts/components/ui/fake_text_field.tsx b/packages/website/ts/components/ui/fake_text_field.tsx index ac3c30fec..7c3a482a4 100644 --- a/packages/website/ts/components/ui/fake_text_field.tsx +++ b/packages/website/ts/components/ui/fake_text_field.tsx @@ -1,4 +1,4 @@ -import { Styles } from '@0xproject/react-shared'; +import { Styles } from '@0x/react-shared'; import * as React from 'react'; import { InputLabel } from 'ts/components/ui/input_label'; diff --git a/packages/website/ts/components/ui/icon_button.tsx b/packages/website/ts/components/ui/icon_button.tsx index 13cd239da..9f469ec69 100644 --- a/packages/website/ts/components/ui/icon_button.tsx +++ b/packages/website/ts/components/ui/icon_button.tsx @@ -1,4 +1,4 @@ -import { colors, Styles } from '@0xproject/react-shared'; +import { colors, Styles } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; diff --git a/packages/website/ts/components/ui/input.tsx b/packages/website/ts/components/ui/input.tsx index e01a71a53..e5f4f6c70 100644 --- a/packages/website/ts/components/ui/input.tsx +++ b/packages/website/ts/components/ui/input.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; import { styled } from 'ts/style/theme'; diff --git a/packages/website/ts/components/ui/input_label.tsx b/packages/website/ts/components/ui/input_label.tsx index 8eda45a5d..e7afb5a17 100644 --- a/packages/website/ts/components/ui/input_label.tsx +++ b/packages/website/ts/components/ui/input_label.tsx @@ -1,4 +1,4 @@ -import { colors, Styles } from '@0xproject/react-shared'; +import { colors, Styles } from '@0x/react-shared'; import * as React from 'react'; export interface InputLabelProps { diff --git a/packages/website/ts/components/ui/lifecycle_raised_button.tsx b/packages/website/ts/components/ui/lifecycle_raised_button.tsx index 380fbc77d..a8daf4102 100644 --- a/packages/website/ts/components/ui/lifecycle_raised_button.tsx +++ b/packages/website/ts/components/ui/lifecycle_raised_button.tsx @@ -1,5 +1,5 @@ -import { colors } from '@0xproject/react-shared'; -import { errorUtils } from '@0xproject/utils'; +import { colors } from '@0x/react-shared'; +import { errorUtils } from '@0x/utils'; import RaisedButton from 'material-ui/RaisedButton'; import * as React from 'react'; @@ -71,7 +71,7 @@ export class LifeCycleRaisedButton extends React.Component<LifeCycleRaisedButton style={{ width: '100%' }} backgroundColor={this.props.backgroundColor} labelColor={this.props.labelColor} - onTouchTap={this.onClickAsync.bind(this)} + onClick={this.onClickAsync.bind(this)} disabled={this.props.isDisabled || this.state.buttonState !== ButtonState.READY} /> ); diff --git a/packages/website/ts/components/ui/party.tsx b/packages/website/ts/components/ui/party.tsx index a25550475..6c0572437 100644 --- a/packages/website/ts/components/ui/party.tsx +++ b/packages/website/ts/components/ui/party.tsx @@ -1,4 +1,4 @@ -import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; +import { colors, EtherscanLinkSuffixes, utils as sharedUtils } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import ReactTooltip = require('react-tooltip'); diff --git a/packages/website/ts/components/ui/pointer.tsx b/packages/website/ts/components/ui/pointer.tsx index db0a4188d..c97b1e700 100644 --- a/packages/website/ts/components/ui/pointer.tsx +++ b/packages/website/ts/components/ui/pointer.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; import { styled } from 'ts/style/theme'; diff --git a/packages/website/ts/components/ui/required_label.tsx b/packages/website/ts/components/ui/required_label.tsx index 0f96586ec..5080462fa 100644 --- a/packages/website/ts/components/ui/required_label.tsx +++ b/packages/website/ts/components/ui/required_label.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; export interface RequiredLabelProps { diff --git a/packages/website/ts/components/ui/simple_menu.tsx b/packages/website/ts/components/ui/simple_menu.tsx index 8a9349c6d..45ee752e3 100644 --- a/packages/website/ts/components/ui/simple_menu.tsx +++ b/packages/website/ts/components/ui/simple_menu.tsx @@ -1,7 +1,7 @@ +import { Link } from '@0x/react-shared'; import * as _ from 'lodash'; import * as React from 'react'; import * as CopyToClipboard from 'react-copy-to-clipboard'; -import { Link } from 'react-router-dom'; import { Container } from 'ts/components/ui/container'; import { Text } from 'ts/components/ui/text'; @@ -72,7 +72,7 @@ export const GoToAccountManagementSimpleMenuItem: React.StatelessComponent< GoToAccountManagementSimpleMenuItemProps > = ({ onClick }) => { return ( - <Link to={`${WebsitePaths.Portal}/account`} style={{ textDecoration: 'none' }}> + <Link to={`${WebsitePaths.Portal}/account`}> <SimpleMenuItem displayText="Manage Account..." onClick={onClick} /> </Link> ); diff --git a/packages/website/ts/components/ui/spinner.tsx b/packages/website/ts/components/ui/spinner.tsx index e8670cc3e..dc73e74e3 100644 --- a/packages/website/ts/components/ui/spinner.tsx +++ b/packages/website/ts/components/ui/spinner.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; import { styled } from 'ts/style/theme'; diff --git a/packages/website/ts/components/ui/swap_icon.tsx b/packages/website/ts/components/ui/swap_icon.tsx index f1d1ae7d4..406da8fe1 100644 --- a/packages/website/ts/components/ui/swap_icon.tsx +++ b/packages/website/ts/components/ui/swap_icon.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import * as React from 'react'; interface SwapIconProps { diff --git a/packages/website/ts/components/ui/text.tsx b/packages/website/ts/components/ui/text.tsx index 734483564..c13e21913 100644 --- a/packages/website/ts/components/ui/text.tsx +++ b/packages/website/ts/components/ui/text.tsx @@ -1,4 +1,4 @@ -import { colors } from '@0xproject/react-shared'; +import { colors } from '@0x/react-shared'; import { darken } from 'polished'; import * as React from 'react'; import { styled } from 'ts/style/theme'; @@ -19,7 +19,10 @@ export interface TextProps { textDecorationLine?: string; onClick?: (event: React.MouseEvent<HTMLElement>) => void; hoverColor?: string; + letterSpacing?: string | number; noWrap?: boolean; + textAlign?: string; + display?: string; } const PlainText: React.StatelessComponent<TextProps> = ({ children, className, onClick, Tag }) => ( @@ -33,6 +36,8 @@ export const Text = styled(PlainText)` font-style: ${props => props.fontStyle}; font-weight: ${props => props.fontWeight}; font-size: ${props => props.fontSize}; + text-align: ${props => props.textAlign}; + letter-spacing: ${props => props.letterSpacing}; text-decoration-line: ${props => props.textDecorationLine}; ${props => (props.lineHeight ? `line-height: ${props.lineHeight}` : '')}; ${props => (props.center ? 'text-align: center' : '')}; @@ -41,6 +46,7 @@ export const Text = styled(PlainText)` ${props => (props.onClick ? 'cursor: pointer' : '')}; transition: color 0.5s ease; ${props => (props.noWrap ? 'white-space: nowrap' : '')}; + ${props => (props.display ? `display: ${props.display}` : '')}; &:hover { ${props => (props.onClick ? `color: ${props.hoverColor || darken(0.3, props.fontColor)}` : '')}; } diff --git a/packages/website/ts/components/ui/typed_text.tsx b/packages/website/ts/components/ui/typed_text.tsx new file mode 100644 index 000000000..6d38580b9 --- /dev/null +++ b/packages/website/ts/components/ui/typed_text.tsx @@ -0,0 +1,75 @@ +import * as _ from 'lodash'; +import * as React from 'react'; +import Typist from 'react-typist'; + +import { Text, TextProps } from 'ts/components/ui/text'; + +import 'react-typist/dist/Typist.css'; + +export interface TypedTextProps extends TextProps { + textList: string[]; + shouldRepeat?: boolean; + wordDelayMs?: number; + avgKeystrokeDelayMs?: number; + stdKeystrokeDelay?: number; +} + +export interface TypedTextState { + cycleCount: number; +} + +export class TypedText extends React.Component<TypedTextProps, TypedTextState> { + public static defaultProps = { + shouldRepeat: false, + avgKeystrokeDelayMs: 90, + wordDelayMs: 1000, + }; + public state = { + cycleCount: 0, + }; + public render(): React.ReactNode { + const { + textList, + shouldRepeat, + wordDelayMs, + avgKeystrokeDelayMs, + stdKeystrokeDelay, + // tslint:disable-next-line + ...textProps + } = this.props; + const { cycleCount } = this.state; + if (_.isEmpty(textList)) { + return null; + } + const typistChildren: React.ReactNode[] = []; + _.forEach(textList, text => { + typistChildren.push( + <Text key={`text-${text}-${cycleCount}`} {...textProps}> + {text} + </Text>, + ); + if (wordDelayMs) { + typistChildren.push(<Typist.Delay key={`delay-${text}-${cycleCount}`} ms={wordDelayMs} />); + } + typistChildren.push(<Typist.Backspace key={`backspace-${text}-${cycleCount}`} count={text.length} />); + }); + return ( + <Typist + avgTypingDelay={avgKeystrokeDelayMs} + stdTypingDelay={stdKeystrokeDelay} + className="inline" + key={`typist-key-${cycleCount}`} + onTypingDone={this._onTypingDone.bind(this)} + > + {typistChildren} + </Typist> + ); + } + private _onTypingDone(): void { + if (this.props.shouldRepeat) { + this.setState({ + cycleCount: this.state.cycleCount + 1, + }); + } + } +} diff --git a/packages/website/ts/components/visual_order.tsx b/packages/website/ts/components/visual_order.tsx index a8d18006e..d723757d2 100644 --- a/packages/website/ts/components/visual_order.tsx +++ b/packages/website/ts/components/visual_order.tsx @@ -1,4 +1,4 @@ -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import * as React from 'react'; import { Party } from 'ts/components/ui/party'; diff --git a/packages/website/ts/components/wallet/body_overlay.tsx b/packages/website/ts/components/wallet/body_overlay.tsx index 26359d0d2..3795f0eaa 100644 --- a/packages/website/ts/components/wallet/body_overlay.tsx +++ b/packages/website/ts/components/wallet/body_overlay.tsx @@ -13,7 +13,7 @@ import { AccountState, ProviderType } from 'ts/types'; import { utils } from 'ts/utils/utils'; const METAMASK_IMG_SRC = '/images/metamask_icon.png'; -const TOSHI_IMG_SRC = '/images/toshi_logo.jpg'; +const COINBASE_WALLET_IMG_SRC = '/images/coinbase_wallet_logo.png'; export interface BodyOverlayProps { dispatcher: Dispatcher; @@ -116,8 +116,8 @@ const UseDifferentWallet = (props: UseDifferentWallet) => { const GetWalletCallToAction = () => { const [downloadLink, isOnMobile] = utils.getBestWalletDownloadLinkAndIsMobile(); - const imageUrl = isOnMobile ? TOSHI_IMG_SRC : METAMASK_IMG_SRC; - const text = isOnMobile ? 'Get Toshi Wallet' : 'Get MetaMask Wallet'; + const imageUrl = isOnMobile ? COINBASE_WALLET_IMG_SRC : METAMASK_IMG_SRC; + const text = isOnMobile ? 'Get Coinbase Wallet' : 'Get MetaMask Wallet'; return ( <a href={downloadLink} target="_blank" style={{ textDecoration: 'none' }}> <Island diff --git a/packages/website/ts/components/wallet/wallet.tsx b/packages/website/ts/components/wallet/wallet.tsx index 6abaa840b..326cd3cfa 100644 --- a/packages/website/ts/components/wallet/wallet.tsx +++ b/packages/website/ts/components/wallet/wallet.tsx @@ -1,5 +1,5 @@ -import { EtherscanLinkSuffixes, utils as sharedUtils } from '@0xproject/react-shared'; -import { BigNumber, errorUtils } from '@0xproject/utils'; +import { EtherscanLinkSuffixes, utils as sharedUtils } from '@0x/react-shared'; +import { BigNumber, errorUtils } from '@0x/utils'; import * as _ from 'lodash'; import ActionAccountBalanceWallet from 'material-ui/svg-icons/action/account-balance-wallet'; diff --git a/packages/website/ts/components/wallet/wrap_ether_item.tsx b/packages/website/ts/components/wallet/wrap_ether_item.tsx index 54ace7ae2..7de3afbf8 100644 --- a/packages/website/ts/components/wallet/wrap_ether_item.tsx +++ b/packages/website/ts/components/wallet/wrap_ether_item.tsx @@ -1,6 +1,6 @@ -import { Styles } from '@0xproject/react-shared'; -import { BigNumber, logUtils } from '@0xproject/utils'; -import { Web3Wrapper } from '@0xproject/web3-wrapper'; +import { Styles } from '@0x/react-shared'; +import { BigNumber, logUtils } from '@0x/utils'; +import { Web3Wrapper } from '@0x/web3-wrapper'; import * as _ from 'lodash'; import FlatButton from 'material-ui/FlatButton'; import * as React from 'react'; |