aboutsummaryrefslogtreecommitdiffstats
path: root/packages/website/ts/pages/instant
diff options
context:
space:
mode:
Diffstat (limited to 'packages/website/ts/pages/instant')
-rw-r--r--packages/website/ts/pages/instant/action_link.tsx46
-rw-r--r--packages/website/ts/pages/instant/code_demo.tsx30
-rw-r--r--packages/website/ts/pages/instant/config_generator.tsx79
-rw-r--r--packages/website/ts/pages/instant/config_generator_address_input.tsx55
-rw-r--r--packages/website/ts/pages/instant/configurator.tsx72
-rw-r--r--packages/website/ts/pages/instant/features.tsx115
-rw-r--r--packages/website/ts/pages/instant/fee_percentage_slider.tsx77
-rw-r--r--packages/website/ts/pages/instant/instant.tsx87
-rw-r--r--packages/website/ts/pages/instant/introducing_0x_instant.tsx57
-rw-r--r--packages/website/ts/pages/instant/need_more.tsx62
-rw-r--r--packages/website/ts/pages/instant/rc-slider.css295
-rw-r--r--packages/website/ts/pages/instant/screenshots.tsx35
-rw-r--r--packages/website/ts/pages/instant/select.tsx74
13 files changed, 550 insertions, 534 deletions
diff --git a/packages/website/ts/pages/instant/action_link.tsx b/packages/website/ts/pages/instant/action_link.tsx
deleted file mode 100644
index c196f03ef..000000000
--- a/packages/website/ts/pages/instant/action_link.tsx
+++ /dev/null
@@ -1,46 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { Container } from 'ts/components/ui/container';
-import { Text } from 'ts/components/ui/text';
-import { colors } from 'ts/style/colors';
-import { utils } from 'ts/utils/utils';
-
-export interface ActionLinkProps {
- displayText: string;
- linkSrc?: string;
- onClick?: () => void;
- fontSize?: number;
- color?: string;
- className?: string;
-}
-
-export class ActionLink extends React.Component<ActionLinkProps> {
- public static defaultProps = {
- fontSize: 16,
- color: colors.white,
- };
- public render(): React.ReactNode {
- const { displayText, fontSize, color, className } = this.props;
- return (
- <Container className={`flex items-center ${className}`} onClick={this._handleClick} cursor="pointer">
- <Container>
- <Text fontSize="16px" fontColor={color}>
- {displayText}
- </Text>
- </Container>
- <Container paddingTop="1px" paddingLeft="6px">
- <i className="zmdi zmdi-chevron-right bold" style={{ fontSize, color }} />
- </Container>
- </Container>
- );
- }
-
- private readonly _handleClick = (event: React.MouseEvent<HTMLElement>) => {
- if (!_.isUndefined(this.props.onClick)) {
- this.props.onClick();
- } else if (!_.isUndefined(this.props.linkSrc)) {
- utils.openUrl(this.props.linkSrc);
- }
- };
-}
diff --git a/packages/website/ts/pages/instant/code_demo.tsx b/packages/website/ts/pages/instant/code_demo.tsx
index a3b5fe847..c59f148b8 100644
--- a/packages/website/ts/pages/instant/code_demo.tsx
+++ b/packages/website/ts/pages/instant/code_demo.tsx
@@ -2,9 +2,8 @@ import * as React from 'react';
import * as CopyToClipboard from 'react-copy-to-clipboard';
import SyntaxHighlighter from 'react-syntax-highlighter';
-import { Button } from 'ts/components/ui/button';
+import { Button } from 'ts/components/button';
import { Container } from 'ts/components/ui/container';
-import { colors } from 'ts/style/colors';
import { styled } from 'ts/style/theme';
import { zIndex } from 'ts/style/z_index';
@@ -12,7 +11,7 @@ const CustomPre = styled.pre`
margin: 0px;
line-height: 24px;
overflow: scroll;
- width: 600px;
+ width: 100%;
height: 100%;
max-height: 800px;
border-radius: 4px;
@@ -23,19 +22,21 @@ const CustomPre = styled.pre`
border: none;
}
code:first-of-type {
- background-color: #2a2a2a !important;
+ background-color: #060d0d !important;
color: #999;
- min-height: 98%;
+ min-height: 100%;
text-align: center;
- padding-right: 5px !important;
- padding-left: 5px;
margin-right: 15px;
line-height: 25px;
- padding-top: 10px;
+ padding: 10px 7px !important;
}
code:last-of-type {
position: relative;
top: 10px;
+ top: 0;
+ padding-top: 11px;
+ display: inline-block;
+ line-height: 25px;
}
`;
@@ -130,7 +131,7 @@ const customStyle = {
hljs: {
display: 'block',
overflowX: 'hidden',
- background: colors.instantSecondaryBackground,
+ background: '#1B2625',
color: 'white',
fontSize: '12px',
},
@@ -160,9 +161,7 @@ export class CodeDemo extends React.Component<CodeDemoProps, CodeDemoState> {
<Container position="relative" height="100%">
<Container position="absolute" top="10px" right="10px" zIndex={zIndex.overlay - 1}>
<CopyToClipboard text={this.props.children} onCopy={this._handleCopyClick}>
- <Button fontSize="14px">
- <b>{copyButtonText}</b>
- </Button>
+ <StyledButton>{copyButtonText}</StyledButton>
</CopyToClipboard>
</Container>
<SyntaxHighlighter language="html" style={customStyle} showLineNumbers={true} PreTag={CustomPre}>
@@ -175,3 +174,10 @@ export class CodeDemo extends React.Component<CodeDemoProps, CodeDemoState> {
this.setState({ didCopyCode: true });
};
}
+
+const StyledButton = styled(Button)`
+ border-radius: 4px;
+ font-size: 15px;
+ font-weight: 400;
+ padding: 9px 21px 7px;
+`;
diff --git a/packages/website/ts/pages/instant/config_generator.tsx b/packages/website/ts/pages/instant/config_generator.tsx
index fbeeeaeaf..e43d47119 100644
--- a/packages/website/ts/pages/instant/config_generator.tsx
+++ b/packages/website/ts/pages/instant/config_generator.tsx
@@ -4,11 +4,11 @@ import { assetDataUtils } from '@0x/order-utils';
import { ObjectMap } from '@0x/types';
import * as _ from 'lodash';
import * as React from 'react';
+import styled from 'styled-components';
import { CheckMark } from 'ts/components/ui/check_mark';
import { Container } from 'ts/components/ui/container';
import { MultiSelect } from 'ts/components/ui/multi_select';
-import { Select, SelectItemConfig } from 'ts/components/ui/select';
import { Spinner } from 'ts/components/ui/spinner';
import { Text } from 'ts/components/ui/text';
import { ConfigGeneratorAddressInput } from 'ts/pages/instant/config_generator_address_input';
@@ -17,6 +17,10 @@ import { colors } from 'ts/style/colors';
import { WebsitePaths } from 'ts/types';
import { constants } from 'ts/utils/constants';
+// New components
+import { Heading } from 'ts/components/text';
+import { Select, SelectItemConfig } from 'ts/pages/instant/select';
+
import { assetMetaDataMap } from '../../../../instant/src/data/asset_meta_data_map';
import { ERC20AssetMetaData, ZeroExInstantBaseConfig } from '../../../../instant/src/types';
@@ -59,8 +63,14 @@ export class ConfigGenerator extends React.Component<ConfigGeneratorProps, Confi
}
return (
<Container minWidth="350px">
- <ConfigGeneratorSection title="Standard relayer API endpoint">
- <Select value={value.orderSource} items={this._generateItems()} />
+ <ConfigGeneratorSection title="Liquidity Source">
+ <Select
+ shouldIncludeEmpty={false}
+ id=""
+ value={value.orderSource}
+ items={this._generateItems()}
+ onChange={this._handleSRASelection.bind(this)}
+ />
</ConfigGeneratorSection>
<ConfigGeneratorSection {...this._getTokenSelectorProps()}>
{this._renderTokenMultiSelectOrSpinner()}
@@ -110,14 +120,16 @@ export class ConfigGenerator extends React.Component<ConfigGeneratorProps, Confi
};
private readonly _generateItems = (): SelectItemConfig[] => {
return _.map(SRA_ENDPOINTS, endpoint => ({
- text: endpoint,
+ label: endpoint,
+ value: endpoint,
onClick: this._handleSRASelection.bind(this, endpoint),
}));
};
private readonly _handleAffiliatePercentageLearnMoreClick = (): void => {
window.open(`${WebsitePaths.Wiki}#Learn-About-Affiliate-Fees`, '_blank');
};
- private readonly _handleSRASelection = (sraEndpoint: string) => {
+ private readonly _handleSRASelection = (event: React.ChangeEvent<HTMLSelectElement>) => {
+ const sraEndpoint = event.target.value;
const newConfig: ZeroExInstantBaseConfig = {
...this.props.value,
orderSource: sraEndpoint,
@@ -249,15 +261,11 @@ export class ConfigGenerator extends React.Component<ConfigGeneratorProps, Confi
renderItemContent: (isSelected: boolean) => (
<Container className="flex items-center">
<Container marginRight="10px">
- <CheckMark isChecked={isSelected} />
+ <CheckMark isChecked={isSelected} color={colors.brandLight} />
</Container>
- <Text
- fontSize="16px"
- fontColor={isSelected ? colors.mediumBlue : colors.darkerGrey}
- fontWeight={300}
- >
- <b>{metaData.symbol.toUpperCase()}</b> — {metaData.name}
- </Text>
+ <CheckboxText isSelected={isSelected}>
+ {metaData.symbol.toUpperCase()} — {metaData.name}
+ </CheckboxText>
</Container>
),
onClick: this._handleTokenClick.bind(this, assetData),
@@ -285,22 +293,11 @@ export const ConfigGeneratorSection: React.StatelessComponent<ConfigGeneratorSec
}) => (
<Container marginBottom={marginBottom}>
<Container marginBottom="10px" className="flex justify-between items-center">
- <Container>
- <Text fontColor={colors.white} fontSize="16px" lineHeight="18px" display="inline">
- {title}
- </Text>
- {isOptional && (
- <Text fontColor={colors.grey} fontSize="16px" lineHeight="18px" display="inline">
- {' '}
- (optional)
- </Text>
- )}
- </Container>
- {actionText && (
- <Text fontSize="12px" fontColor={colors.grey} onClick={onActionTextClick}>
- {actionText}
- </Text>
- )}
+ <Heading size="small" marginBottom="0" isFlex={true}>
+ <span>{title}</span>
+ {isOptional && <OptionalText> Optional</OptionalText>}
+ </Heading>
+ {actionText && <OptionalAction onClick={onActionTextClick}>{actionText}</OptionalAction>}
</Container>
{children}
</Container>
@@ -309,3 +306,27 @@ export const ConfigGeneratorSection: React.StatelessComponent<ConfigGeneratorSec
ConfigGeneratorSection.defaultProps = {
marginBottom: '30px',
};
+
+const OptionalText = styled.span`
+ display: inline;
+ font-size: 14px;
+ color: #999999;
+ flex-shrink: 0;
+`;
+
+interface CheckboxTextProps {
+ isSelected?: boolean;
+}
+
+const CheckboxText =
+ styled.span <
+ CheckboxTextProps >
+ `
+ font-size: 14px;
+ line-height: 18px;
+ color: ${props => (props.isSelected ? colors.brandDark : '#666666')}
+`;
+
+const OptionalAction = styled(OptionalText)`
+ cursor: pointer;
+`;
diff --git a/packages/website/ts/pages/instant/config_generator_address_input.tsx b/packages/website/ts/pages/instant/config_generator_address_input.tsx
index ccbaf4482..890e39da6 100644
--- a/packages/website/ts/pages/instant/config_generator_address_input.tsx
+++ b/packages/website/ts/pages/instant/config_generator_address_input.tsx
@@ -1,11 +1,13 @@
-import { colors } from '@0x/react-shared';
import { addressUtils } from '@0x/utils';
import * as _ from 'lodash';
import * as React from 'react';
+import styled from 'styled-components';
+
+import { colors } from 'ts/style/colors';
import { Container } from 'ts/components/ui/container';
-import { Input } from 'ts/components/ui/input';
-import { Text } from 'ts/components/ui/text';
+
+import { Paragraph } from 'ts/components/text';
export interface ConfigGeneratorAddressInputProps {
value?: string;
@@ -16,6 +18,19 @@ export interface ConfigGeneratorAddressInputState {
errMsg: string;
}
+export interface InputProps {
+ className?: string;
+ value?: string;
+ width?: string;
+ fontSize?: string;
+ fontColor?: string;
+ padding?: string;
+ placeholderColor?: string;
+ placeholder?: string;
+ backgroundColor?: string;
+ onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
+}
+
export class ConfigGeneratorAddressInput extends React.Component<
ConfigGeneratorAddressInputProps,
ConfigGeneratorAddressInputState
@@ -26,22 +41,13 @@ export class ConfigGeneratorAddressInput extends React.Component<
public render(): React.ReactNode {
const { errMsg } = this.state;
const hasError = !_.isEmpty(errMsg);
- const border = hasError ? '1px solid red' : undefined;
return (
<Container height="80px">
- <Input
- width="100%"
- fontSize="16px"
- padding="0.7em 1em"
- value={this.props.value}
- onChange={this._handleChange}
- placeholder="0xe99...aa8da4"
- border={border}
- />
+ <Input value={this.props.value} onChange={this._handleChange} placeholder="0xe99...aa8da4" />
<Container marginTop="5px" isHidden={!hasError} height="25px">
- <Text fontSize="14px" fontColor={colors.grey} fontStyle="italic">
+ <Paragraph size="small" isNoMargin={true}>
{errMsg}
- </Text>
+ </Paragraph>
</Container>
</Container>
);
@@ -57,3 +63,22 @@ export class ConfigGeneratorAddressInput extends React.Component<
this.props.onChange(address, isValidAddress);
};
}
+
+const PlainInput: React.StatelessComponent<InputProps> = ({ value, className, placeholder, onChange }) => (
+ <input className={className} value={value} onChange={onChange} placeholder={placeholder} />
+);
+
+export const Input = styled(PlainInput)`
+ background-color: ${colors.white};
+ color: ${colors.textDarkSecondary};
+ font-size: 1rem;
+ width: 100%;
+ padding: 16px 20px 18px;
+ border-radius: 4px;
+ border: 1px solid transparent;
+ outline: none;
+ &::placeholder {
+ color: #333333;
+ opacity: 0.5;
+ }
+`;
diff --git a/packages/website/ts/pages/instant/configurator.tsx b/packages/website/ts/pages/instant/configurator.tsx
index 2cb1a1c1c..a63e1752e 100644
--- a/packages/website/ts/pages/instant/configurator.tsx
+++ b/packages/website/ts/pages/instant/configurator.tsx
@@ -1,25 +1,22 @@
import * as _ from 'lodash';
import * as React from 'react';
+import styled from 'styled-components';
-import { Container } from 'ts/components/ui/container';
-import { Text } from 'ts/components/ui/text';
-import { ActionLink } from 'ts/pages/instant/action_link';
import { CodeDemo } from 'ts/pages/instant/code_demo';
import { ConfigGenerator } from 'ts/pages/instant/config_generator';
-import { colors } from 'ts/style/colors';
+
+import { Link } from 'ts/components/link';
+import { Column, FlexWrap } from 'ts/components/newLayout';
+import { Heading } from 'ts/components/text';
import { WebsitePaths } from 'ts/types';
import { ZeroExInstantBaseConfig } from '../../../../instant/src/types';
-export interface ConfiguratorProps {
- hash: string;
-}
-
export interface ConfiguratorState {
instantConfig: ZeroExInstantBaseConfig;
}
-export class Configurator extends React.Component<ConfiguratorProps> {
+export class Configurator extends React.Component {
public state: ConfiguratorState = {
instantConfig: {
orderSource: 'https://api.radarrelay.com/0x/v2/',
@@ -31,36 +28,24 @@ export class Configurator extends React.Component<ConfiguratorProps> {
},
};
public render(): React.ReactNode {
- const { hash } = this.props;
const codeToDisplay = this._generateCodeDemoCode();
return (
- <Container
- className="flex justify-center py4 px3"
- id={hash}
- backgroundColor={colors.instantTertiaryBackground}
- >
- <Container className="mx3">
- <Container className="mb3">
- <Text fontSize="20px" lineHeight="28px" fontColor={colors.white} fontWeight={500}>
- 0x Instant Configurator
- </Text>
- </Container>
+ <FlexWrap isFlex={true}>
+ <Column width="442px" padding="0 70px 0 0">
<ConfigGenerator value={this.state.instantConfig} onConfigChange={this._handleConfigChange} />
- </Container>
- <Container className="mx3" height="550px">
- <Container className="mb3 flex justify-between">
- <Text fontSize="20px" lineHeight="28px" fontColor={colors.white} fontWeight={500}>
+ </Column>
+ <Column width="100%">
+ <HeadingWrapper>
+ <Heading size="small" marginBottom="15px">
Code Snippet
- </Text>
- <ActionLink
- displayText="Explore the Docs"
- linkSrc={`${WebsitePaths.Wiki}#Get-Started-With-Instant`}
- color={colors.grey}
- />
- </Container>
+ </Heading>
+ <Link href={`${WebsitePaths.Wiki}#Get-Started-With-Instant`} isBlock={true} target="_blank">
+ Explore the Docs
+ </Link>
+ </HeadingWrapper>
<CodeDemo key={codeToDisplay}>{codeToDisplay}</CodeDemo>
- </Container>
- </Container>
+ </Column>
+ </FlexWrap>
);
}
private readonly _handleConfigChange = (config: ZeroExInstantBaseConfig) => {
@@ -74,7 +59,7 @@ export class Configurator extends React.Component<ConfiguratorProps> {
<html>
<head>
<meta charset="utf-8" />
- <script src="https://instant.0xproject.com/instant.js"></script>
+ <script src="https://instant.0x.org/instant.js"></script>
</head>
<body>
<script>
@@ -93,10 +78,10 @@ export class Configurator extends React.Component<ConfiguratorProps> {
)}`
: ''
}
- }, 'body');
- </script>
- </body>
-</html>`;
+ }, 'body');
+ </script>
+ </body>
+ </html>`;
};
private readonly _renderAvailableAssetDatasString = (availableAssetDatas: string[]): string => {
const stringAvailableAssetDatas = availableAssetDatas.map(assetData => `'${assetData}'`);
@@ -108,3 +93,12 @@ export class Configurator extends React.Component<ConfiguratorProps> {
)}\n ]`;
};
}
+
+const HeadingWrapper = styled.div`
+ display: flex;
+ justify-content: space-between;
+
+ a {
+ transform: translateY(-8px);
+ }
+`;
diff --git a/packages/website/ts/pages/instant/features.tsx b/packages/website/ts/pages/instant/features.tsx
deleted file mode 100644
index ed98ceb53..000000000
--- a/packages/website/ts/pages/instant/features.tsx
+++ /dev/null
@@ -1,115 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { Container } from 'ts/components/ui/container';
-import { Image } from 'ts/components/ui/image';
-import { Text } from 'ts/components/ui/text';
-import { ActionLink, ActionLinkProps } from 'ts/pages/instant/action_link';
-import { colors } from 'ts/style/colors';
-import { ScreenWidths, WebsitePaths } from 'ts/types';
-
-export interface FeatureProps {
- screenWidth: ScreenWidths;
- onGetStartedClick: () => void;
-}
-
-export const Features = (props: FeatureProps) => {
- const isSmallScreen = props.screenWidth === ScreenWidths.Sm;
- const getStartedLinkInfo = {
- displayText: 'Get started',
- onClick: props.onGetStartedClick,
- };
- const exploreTheDocsLinkInfo = {
- displayText: 'Explore the docs',
- linkSrc: `${WebsitePaths.Wiki}#Get-Started-With-Instant`,
- };
- const tokenLinkInfos = isSmallScreen ? [getStartedLinkInfo] : [getStartedLinkInfo, exploreTheDocsLinkInfo];
- return (
- <Container backgroundColor={colors.instantSecondaryBackground} className="py3 flex flex-column px3">
- <FeatureItem
- imgSrc="images/instant/feature_1.svg"
- title="Support ERC-20 and ERC-721 tokens"
- description="Seamlessly integrate token purchasing into your product experience by offering digital assets ranging from in-game items to stablecoins."
- linkInfos={tokenLinkInfos}
- screenWidth={props.screenWidth}
- />
- <FeatureItem
- imgSrc="images/instant/feature_2.svg"
- title="Generate revenue for your business"
- description="With just a few lines of code, you can earn up to 5% in affiliate fees on every transaction from your crypto wallet or dApp."
- linkInfos={[
- {
- displayText: 'Learn about affiliate fees',
- linkSrc: `${WebsitePaths.Wiki}#Learn-About-Affiliate-Fees`,
- },
- ]}
- screenWidth={props.screenWidth}
- />
- <FeatureItem
- imgSrc="images/instant/feature_3.svg"
- title="Easy and Flexible Integration"
- description="Use our out-of-the-box design or customize the user interface by integrating the AssetBuyer engine. You can also tap into 0x networked liquidity or choose your own liquidity pool."
- linkInfos={[
- {
- displayText: 'Explore AssetBuyer',
- linkSrc: `${WebsitePaths.Docs}/asset-buyer`,
- },
- ]}
- screenWidth={props.screenWidth}
- />
- </Container>
- );
-};
-
-interface FeatureItemProps {
- imgSrc: string;
- title: string;
- description: string;
- linkInfos: ActionLinkProps[];
- screenWidth: ScreenWidths;
-}
-
-const FeatureItem = (props: FeatureItemProps) => {
- const { imgSrc, title, description, linkInfos, screenWidth } = props;
- const isLargeScreen = screenWidth === ScreenWidths.Lg;
- const maxWidth = isLargeScreen ? '500px' : undefined;
- const image = (
- <Container className="center" minWidth="435px" maxHeight="225px">
- <Image src={imgSrc} additionalStyle={{ filter: 'drop-shadow(0px 4px 4px rgba(0,0,0,.25))' }} />
- </Container>
- );
- const info = (
- <Container maxWidth={maxWidth}>
- <Text fontSize="24px" lineHeight="34px" fontColor={colors.white} fontWeight={500}>
- {title}
- </Text>
- <Container marginTop="28px">
- <Text fontFamily="Roboto Mono" fontSize="14px" lineHeight="2em" fontColor={colors.grey500}>
- {description}
- </Text>
- </Container>
- <Container className="flex" marginTop="28px">
- {_.map(linkInfos, linkInfo => (
- <Container key={linkInfo.displayText} marginRight="32px">
- <ActionLink {...linkInfo} />
- </Container>
- ))}
- </Container>
- </Container>
- );
- return (
- <Container className="flex flex-column items-center py4 px3">
- {isLargeScreen ? (
- <Container className="flex">
- {image}
- <Container marginLeft="115px">{info}</Container>
- </Container>
- ) : (
- <Container className="flex flex-column items-center" width="100%">
- {image}
- <Container marginTop="48px">{info}</Container>
- </Container>
- )}
- </Container>
- );
-};
diff --git a/packages/website/ts/pages/instant/fee_percentage_slider.tsx b/packages/website/ts/pages/instant/fee_percentage_slider.tsx
index d76cee58f..c4d9f908f 100644
--- a/packages/website/ts/pages/instant/fee_percentage_slider.tsx
+++ b/packages/website/ts/pages/instant/fee_percentage_slider.tsx
@@ -1,64 +1,36 @@
import Slider from 'rc-slider';
-import 'rc-slider/assets/index.css';
import * as React from 'react';
+import styled from 'styled-components';
+import 'ts/pages/instant/rc-slider.css';
-import { Text } from 'ts/components/ui/text';
import { colors } from 'ts/style/colors';
-import { injectGlobal } from 'ts/style/theme';
const SliderWithTooltip = (Slider as any).createSliderWithTooltip(Slider);
// tslint:disable-next-line:no-unused-expression
-injectGlobal`
- .rc-slider-tooltip-inner {
- box-shadow: none !important;
- background-color: ${colors.white} !important;
- border-radius: 4px !important;
- padding: 3px 12px !important;
- height: auto !important;
- position: relative;
- top: 7px;
- &: after {
- border: solid transparent;
- content: " ";
- height: 0;
- width: 0;
- position: absolute;
- pointer-events: none;
- border-width: 6px;
- bottom: 100%;
- left: 100%;
- border-bottom-color: ${colors.white};
- margin-left: -60%;
- }
- }
- .rc-slider-disabled {
- background-color: inherit !important;
- }
-`;
export interface FeePercentageSliderProps {
value: number;
- isDisabled: boolean;
+ isDisabled?: boolean;
onChange: (value: number) => void;
}
export class FeePercentageSlider extends React.Component<FeePercentageSliderProps> {
public render(): React.ReactNode {
return (
- <SliderWithTooltip
- disabled={this.props.isDisabled}
+ <StyledSlider
min={0}
max={0.05}
step={0.0025}
value={this.props.value}
+ disabled={this.props.isDisabled}
onChange={this.props.onChange}
tipFormatter={this._feePercentageSliderFormatter}
- tipProps={{ placement: 'bottom' }}
+ tipProps={{ placement: 'bottom', overlayStyle: { backgroundColor: '#fff', borderRadius: '4px' } }}
trackStyle={{
- backgroundColor: '#b4b4b4',
+ backgroundColor: colors.brandLight,
}}
railStyle={{
- backgroundColor: '#696969',
+ backgroundColor: 'rgba(255, 255, 255, 0.2)',
}}
handleStyle={{
border: 'none',
@@ -72,6 +44,37 @@ export class FeePercentageSlider extends React.Component<FeePercentageSliderProp
);
}
private readonly _feePercentageSliderFormatter = (value: number): React.ReactNode => {
- return <Text fontColor={colors.black} fontSize="14px" fontWeight={700}>{`${(value * 100).toFixed(2)}%`}</Text>;
+ return <Text>{`${(value * 100).toFixed(2)}%`}</Text>;
};
}
+
+const StyledSlider = styled(SliderWithTooltip)`
+ .rc-slider-tooltip__inner {
+ box-shadow: none !important;
+ background-color: ${colors.white} !important;
+ border-radius: 4px !important;
+ padding: 3px 12px !important;
+ height: auto !important;
+ position: relative;
+ top: 7px;
+ &:after {
+ border: solid transparent;
+ content: ' ';
+ height: 0;
+ width: 0;
+ position: absolute;
+ pointer-events: none;
+ border-width: 6px;
+ bottom: 100%;
+ left: 100%;
+ border-bottom-color: ${colors.white};
+ margin-left: -60%;
+ }
+ }
+`;
+
+const Text = styled.span`
+ color: #000000;
+ font-size: 12px;
+ line-height: 18px;
+`;
diff --git a/packages/website/ts/pages/instant/instant.tsx b/packages/website/ts/pages/instant/instant.tsx
deleted file mode 100644
index d72585bfa..000000000
--- a/packages/website/ts/pages/instant/instant.tsx
+++ /dev/null
@@ -1,87 +0,0 @@
-import { utils as sharedUtils } from '@0x/react-shared';
-import * as _ from 'lodash';
-import * as React from 'react';
-import * as DocumentTitle from 'react-document-title';
-
-import { Footer } from 'ts/components/footer';
-import { MetaTags } from 'ts/components/meta_tags';
-import { TopBar } from 'ts/components/top_bar/top_bar';
-import { Container } from 'ts/components/ui/container';
-import { Configurator } from 'ts/pages/instant/configurator';
-import { Features } from 'ts/pages/instant/features';
-import { Introducing0xInstant } from 'ts/pages/instant/introducing_0x_instant';
-import { NeedMore } from 'ts/pages/instant/need_more';
-import { Screenshots } from 'ts/pages/instant/screenshots';
-import { Dispatcher } from 'ts/redux/dispatcher';
-import { colors } from 'ts/style/colors';
-import { ScreenWidths, WebsitePaths } from 'ts/types';
-import { Translate } from 'ts/utils/translate';
-import { utils } from 'ts/utils/utils';
-
-export interface InstantProps {
- location: Location;
- translate: Translate;
- dispatcher: Dispatcher;
- screenWidth: ScreenWidths;
-}
-
-export interface InstantState {}
-
-const CONFIGURATOR_HASH = 'configure';
-const THROTTLE_TIMEOUT = 100;
-const DOCUMENT_TITLE = '0x Instant';
-const DOCUMENT_DESCRIPTION = '0x Instant';
-
-export class Instant extends React.Component<InstantProps, InstantState> {
- // TODO: consolidate this small screen scaffolding into one place (its being used in portal and docs as well)
- private readonly _throttledScreenWidthUpdate: () => void;
- public constructor(props: InstantProps) {
- super(props);
- this._throttledScreenWidthUpdate = _.throttle(this._updateScreenWidth.bind(this), THROTTLE_TIMEOUT);
- }
- public componentDidMount(): void {
- window.addEventListener('resize', this._throttledScreenWidthUpdate);
- window.scrollTo(0, 0);
- }
- public render(): React.ReactNode {
- return (
- <Container overflowX="hidden">
- <MetaTags title={DOCUMENT_TITLE} description={DOCUMENT_DESCRIPTION} />
- <DocumentTitle title={DOCUMENT_TITLE} />
- <TopBar
- blockchainIsLoaded={false}
- location={this.props.location}
- style={{ backgroundColor: colors.instantPrimaryBackground, position: 'relative' }}
- translate={this.props.translate}
- isNightVersion={true}
- />
- <Container backgroundColor={colors.instantPrimaryBackground} />
- <Introducing0xInstant screenWidth={this.props.screenWidth} onCTAClick={this._onGetStartedClick} />
- <Screenshots screenWidth={this.props.screenWidth} />
- <Features screenWidth={this.props.screenWidth} onGetStartedClick={this._onGetStartedClick} />
- {!this._isSmallScreen() && <Configurator hash={CONFIGURATOR_HASH} />}
- <NeedMore screenWidth={this.props.screenWidth} />
- <Footer translate={this.props.translate} dispatcher={this.props.dispatcher} />
- </Container>
- );
- }
- private readonly _onGetStartedClick = () => {
- if (this._isSmallScreen()) {
- utils.openUrl(`${WebsitePaths.Wiki}#Get-Started-With-Instant`);
- } else {
- this._scrollToConfigurator();
- }
- };
- private _isSmallScreen(): boolean {
- const isSmallScreen = this.props.screenWidth === ScreenWidths.Sm;
- return isSmallScreen;
- }
- private _scrollToConfigurator(): void {
- sharedUtils.setUrlHash(CONFIGURATOR_HASH);
- sharedUtils.scrollToHash(CONFIGURATOR_HASH, '');
- }
- private _updateScreenWidth(): void {
- const newScreenWidth = utils.getScreenWidth();
- this.props.dispatcher.updateScreenWidth(newScreenWidth);
- }
-}
diff --git a/packages/website/ts/pages/instant/introducing_0x_instant.tsx b/packages/website/ts/pages/instant/introducing_0x_instant.tsx
deleted file mode 100644
index da3f09faa..000000000
--- a/packages/website/ts/pages/instant/introducing_0x_instant.tsx
+++ /dev/null
@@ -1,57 +0,0 @@
-import * as React from 'react';
-
-import { Button } from 'ts/components/ui/button';
-import { Container } from 'ts/components/ui/container';
-import { Text } from 'ts/components/ui/text';
-import { colors } from 'ts/style/colors';
-import { ScreenWidths } from 'ts/types';
-
-export interface Introducing0xInstantProps {
- screenWidth: ScreenWidths;
- onCTAClick: () => void;
-}
-
-export const Introducing0xInstant = (props: Introducing0xInstantProps) => {
- const isSmallScreen = props.screenWidth === ScreenWidths.Sm;
- const zero = (
- <Text fontColor={colors.white} fontSize="42px" fontWeight="600" fontFamily="Roboto Mono" Tag="span">
- 0
- </Text>
- );
- const title = isSmallScreen ? (
- <div>
- Introducing<br />
- {zero}x Instant
- </div>
- ) : (
- <div>Introducing {zero}x Instant</div>
- );
- return (
- <div className="clearfix center lg-pt4 md-pt4" style={{ backgroundColor: colors.instantPrimaryBackground }}>
- <div className="mx-auto inline-block align-middle py4" style={{ lineHeight: '44px', textAlign: 'center' }}>
- <Container className="sm-center sm-pt3">
- <Text fontColor={colors.white} fontSize="42px" lineHeight="52px" fontWeight="600">
- {title}
- </Text>
- </Container>
- <Container className="pb2 lg-pt2 md-pt2 sm-pt3 sm-px3 sm-center" maxWidth="600px">
- <Text fontColor={colors.grey500} fontSize="20px" lineHeight="32px" fontFamily="Roboto Mono">
- A free and flexible way to offer simple crypto
- <br /> purchasing in any app or website.
- </Text>
- </Container>
- <div className="py3">
- <Button
- type="button"
- backgroundColor={colors.mediumBlue}
- fontColor={colors.white}
- fontSize="18px"
- onClick={props.onCTAClick}
- >
- Get Started
- </Button>
- </div>
- </div>
- </div>
- );
-};
diff --git a/packages/website/ts/pages/instant/need_more.tsx b/packages/website/ts/pages/instant/need_more.tsx
deleted file mode 100644
index 70aea7363..000000000
--- a/packages/website/ts/pages/instant/need_more.tsx
+++ /dev/null
@@ -1,62 +0,0 @@
-import * as React from 'react';
-
-import { Button } from 'ts/components/ui/button';
-import { Container } from 'ts/components/ui/container';
-import { Text } from 'ts/components/ui/text';
-import { colors } from 'ts/style/colors';
-import { ScreenWidths, WebsitePaths } from 'ts/types';
-import { constants } from 'ts/utils/constants';
-import { utils } from 'ts/utils/utils';
-
-export interface NeedMoreProps {
- screenWidth: ScreenWidths;
-}
-export const NeedMore = (props: NeedMoreProps) => {
- const isSmallScreen = props.screenWidth === ScreenWidths.Sm;
- const backgroundColor = isSmallScreen ? colors.instantTertiaryBackground : colors.instantSecondaryBackground;
- const className = isSmallScreen ? 'flex flex-column items-center' : 'flex';
- const marginRight = isSmallScreen ? undefined : '200px';
- return (
- <Container className="flex flex-column items-center py4 px3" backgroundColor={backgroundColor}>
- <Container className={className}>
- <Container className="sm-center" marginRight={marginRight}>
- <Text fontColor={colors.white} fontSize="32px" lineHeight="45px">
- Need more flexibility?
- </Text>
- <Text fontColor={colors.grey500} fontSize="18px" lineHeight="27px">
- View our full documentation or reach out if you have any questions.
- </Text>
- </Container>
- <Container className="py3 flex">
- <Container marginRight="20px">
- <Button
- type="button"
- backgroundColor={colors.white}
- fontColor={backgroundColor}
- fontSize="18px"
- onClick={onGetInTouchClick}
- >
- Get in Touch
- </Button>
- </Container>
- <Button
- type="button"
- backgroundColor={colors.mediumBlue}
- fontColor={colors.white}
- fontSize="18px"
- onClick={onDocsClick}
- >
- Explore the Docs
- </Button>
- </Container>
- </Container>
- </Container>
- );
-};
-
-const onGetInTouchClick = () => {
- utils.openUrl(constants.URL_ZEROEX_CHAT);
-};
-const onDocsClick = () => {
- utils.openUrl(`${WebsitePaths.Wiki}#Get-Started-With-Instant`);
-};
diff --git a/packages/website/ts/pages/instant/rc-slider.css b/packages/website/ts/pages/instant/rc-slider.css
new file mode 100644
index 000000000..63038324e
--- /dev/null
+++ b/packages/website/ts/pages/instant/rc-slider.css
@@ -0,0 +1,295 @@
+.rc-slider {
+ position: relative;
+ height: 14px;
+ padding: 5px 0;
+ width: 100%;
+ border-radius: 6px;
+ -ms-touch-action: none;
+ touch-action: none;
+ box-sizing: border-box;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+.rc-slider * {
+ box-sizing: border-box;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+.rc-slider-rail {
+ position: absolute;
+ width: 100%;
+ background-color: #e9e9e9;
+ height: 4px;
+ border-radius: 6px;
+}
+
+.rc-slider-track {
+ position: absolute;
+ left: 0;
+ height: 4px;
+ border-radius: 6px;
+ background-color: #abe2fb;
+}
+
+.rc-slider-handle {
+ position: absolute;
+ margin-left: -7px;
+ margin-top: -5px;
+ width: 14px;
+ height: 14px;
+ cursor: pointer;
+ cursor: -webkit-grab;
+ cursor: grab;
+ border-radius: 50%;
+ border: solid 2px #96dbfa;
+ background-color: #fff;
+ -ms-touch-action: pan-x;
+ touch-action: pan-x;
+}
+
+.rc-slider-handle:focus {
+ border-color: #57c5f7;
+ box-shadow: 0 0 0 5px #96dbfa;
+ outline: none;
+}
+
+.rc-slider-handle-click-focused:focus {
+ border-color: #96dbfa;
+ box-shadow: unset;
+}
+
+.rc-slider-handle:hover {
+ border-color: #57c5f7;
+}
+
+.rc-slider-handle:active {
+ border-color: #57c5f7;
+ box-shadow: 0 0 5px #57c5f7;
+ cursor: -webkit-grabbing;
+ cursor: grabbing;
+}
+
+.rc-slider-mark {
+ position: absolute;
+ top: 18px;
+ left: 0;
+ width: 100%;
+ font-size: 12px;
+}
+
+.rc-slider-mark-text {
+ position: absolute;
+ display: inline-block;
+ vertical-align: middle;
+ text-align: center;
+ cursor: pointer;
+ color: #999;
+}
+
+.rc-slider-mark-text-active {
+ color: #666;
+}
+
+.rc-slider-step {
+ position: absolute;
+ width: 100%;
+ height: 4px;
+ background: transparent;
+}
+
+.rc-slider-dot {
+ position: absolute;
+ bottom: -2px;
+ margin-left: -4px;
+ width: 8px;
+ height: 8px;
+ border: 2px solid #e9e9e9;
+ background-color: #fff;
+ cursor: pointer;
+ border-radius: 50%;
+ vertical-align: middle;
+}
+
+.rc-slider-dot-active {
+ border-color: #96dbfa;
+}
+
+.rc-slider-disabled {
+ opacity: 0.2;
+}
+
+.rc-slider-disabled .rc-slider-track {
+ background-color: #ccc;
+}
+
+.rc-slider-disabled .rc-slider-handle,
+.rc-slider-disabled .rc-slider-dot {
+ border-color: #ccc;
+ box-shadow: none;
+ background-color: #fff;
+ cursor: not-allowed;
+}
+
+.rc-slider-disabled .rc-slider-mark-text,
+.rc-slider-disabled .rc-slider-dot {
+ cursor: not-allowed !important;
+}
+
+.rc-slider-vertical {
+ width: 14px;
+ height: 100%;
+ padding: 0 5px;
+}
+
+.rc-slider-vertical .rc-slider-rail {
+ height: 100%;
+ width: 4px;
+}
+
+.rc-slider-vertical .rc-slider-track {
+ left: 5px;
+ bottom: 0;
+ width: 4px;
+}
+
+.rc-slider-vertical .rc-slider-handle {
+ margin-left: -5px;
+ margin-bottom: -7px;
+ -ms-touch-action: pan-y;
+ touch-action: pan-y;
+}
+
+.rc-slider-vertical .rc-slider-mark {
+ top: 0;
+ left: 18px;
+ height: 100%;
+}
+
+.rc-slider-vertical .rc-slider-step {
+ height: 100%;
+ width: 4px;
+}
+
+.rc-slider-vertical .rc-slider-dot {
+ left: 2px;
+ margin-bottom: -4px;
+}
+
+.rc-slider-vertical .rc-slider-dot:first-child {
+ margin-bottom: -4px;
+}
+
+.rc-slider-vertical .rc-slider-dot:last-child {
+ margin-bottom: -4px;
+}
+
+.rc-slider-tooltip-zoom-down-enter,
+.rc-slider-tooltip-zoom-down-appear {
+ animation-duration: .3s;
+ animation-fill-mode: both;
+ display: block !important;
+ animation-play-state: paused;
+}
+
+.rc-slider-tooltip-zoom-down-leave {
+ animation-duration: .3s;
+ animation-fill-mode: both;
+ display: block !important;
+ animation-play-state: paused;
+}
+
+.rc-slider-tooltip-zoom-down-enter.rc-slider-tooltip-zoom-down-enter-active,
+.rc-slider-tooltip-zoom-down-appear.rc-slider-tooltip-zoom-down-appear-active {
+ animation-name: rcSliderTooltipZoomDownIn;
+ animation-play-state: running;
+}
+
+.rc-slider-tooltip-zoom-down-leave.rc-slider-tooltip-zoom-down-leave-active {
+ animation-name: rcSliderTooltipZoomDownOut;
+ animation-play-state: running;
+}
+
+.rc-slider-tooltip-zoom-down-enter,
+.rc-slider-tooltip-zoom-down-appear {
+ transform: scale(0, 0);
+ animation-timing-function: cubic-bezier(0.23, 1, 0.32, 1);
+}
+
+.rc-slider-tooltip-zoom-down-leave {
+ animation-timing-function: cubic-bezier(0.755, 0.05, 0.855, 0.06);
+}
+
+@keyframes rcSliderTooltipZoomDownIn {
+ 0% {
+ opacity: 0;
+ transform-origin: 50% 100%;
+ transform: scale(0, 0);
+ }
+
+ 100% {
+ transform-origin: 50% 100%;
+ transform: scale(1, 1);
+ }
+}
+
+@keyframes rcSliderTooltipZoomDownOut {
+ 0% {
+ transform-origin: 50% 100%;
+ transform: scale(1, 1);
+ }
+
+ 100% {
+ opacity: 0;
+ transform-origin: 50% 100%;
+ transform: scale(0, 0);
+ }
+}
+
+.rc-slider-tooltip {
+ position: absolute;
+ left: -9999px;
+ top: -9999px;
+ visibility: visible;
+ box-sizing: border-box;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+.rc-slider-tooltip * {
+ box-sizing: border-box;
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
+}
+
+.rc-slider-tooltip-hidden {
+ display: none;
+}
+
+.rc-slider-tooltip-placement-top {
+ padding: 4px 0 8px 0;
+}
+
+.rc-slider-tooltip-inner {
+ padding: 4px 6px 4px;
+ min-width: 24px;
+ height: 24px;
+ font-size: 12px;
+ line-height: 1;
+ color: #000;
+ text-align: center;
+ text-decoration: none;
+}
+
+.rc-slider-tooltip-arrow {
+ position: absolute;
+ width: 0;
+ height: 0;
+ border-color: transparent;
+ border-style: solid;
+}
+
+.rc-slider-tooltip-placement-top .rc-slider-tooltip-arrow {
+ bottom: 4px;
+ left: 50%;
+ margin-left: -4px;
+ border-width: 4px 4px 0;
+ border-top-color: #6c6c6c;
+}
diff --git a/packages/website/ts/pages/instant/screenshots.tsx b/packages/website/ts/pages/instant/screenshots.tsx
deleted file mode 100644
index 7dcf17fd1..000000000
--- a/packages/website/ts/pages/instant/screenshots.tsx
+++ /dev/null
@@ -1,35 +0,0 @@
-import * as _ from 'lodash';
-import * as React from 'react';
-
-import { Container } from 'ts/components/ui/container';
-import { colors } from 'ts/style/colors';
-import { ScreenWidths } from 'ts/types';
-
-export interface ScreenshotsProps {
- screenWidth: ScreenWidths;
-}
-
-export const Screenshots = (props: ScreenshotsProps) => {
- const isSmallScreen = props.screenWidth === ScreenWidths.Sm;
- const images = isSmallScreen
- ? [
- 'images/instant/rep_screenshot.png',
- 'images/instant/dai_screenshot.png',
- 'images/instant/gods_screenshot.png',
- ]
- : [
- 'images/instant/nmr_screenshot.png',
- 'images/instant/kitty_screenshot.png',
- 'images/instant/rep_screenshot.png',
- 'images/instant/dai_screenshot.png',
- 'images/instant/gods_screenshot.png',
- 'images/instant/gnt_screenshot.png',
- ];
- return (
- <Container backgroundColor={colors.instantPrimaryBackground} className="py3 flex justify-center">
- {_.map(images, image => {
- return <img className="px1 flex-none" width="300px" height="420px" src={image} key={image} />;
- })}
- </Container>
- );
-};
diff --git a/packages/website/ts/pages/instant/select.tsx b/packages/website/ts/pages/instant/select.tsx
new file mode 100644
index 000000000..d4146cfb0
--- /dev/null
+++ b/packages/website/ts/pages/instant/select.tsx
@@ -0,0 +1,74 @@
+import * as React from 'react';
+import styled from 'styled-components';
+
+export interface SelectItemConfig {
+ label: string;
+ value?: string;
+ onClick?: () => void;
+}
+
+interface SelectProps {
+ value?: string;
+ id: string;
+ items: SelectItemConfig[];
+ emptyText?: string;
+ onChange?: (ev: React.ChangeEvent<HTMLSelectElement>) => void;
+ shouldIncludeEmpty: boolean;
+}
+
+export const Select: React.FunctionComponent<SelectProps> = ({
+ value,
+ id,
+ items,
+ shouldIncludeEmpty,
+ emptyText,
+ onChange,
+}) => {
+ return (
+ <Container>
+ <StyledSelect id={id} onChange={onChange}>
+ {shouldIncludeEmpty && <option value="">{emptyText}</option>}
+ {items.map((item, index) => (
+ <option
+ key={`${id}-item-${index}`}
+ value={item.value}
+ selected={item.value === value}
+ onClick={item.onClick}
+ >
+ {item.label}
+ </option>
+ ))}
+ </StyledSelect>
+ <Caret width="12" height="7" fill="none" xmlns="http://www.w3.org/2000/svg">
+ <path d="M11 1L6 6 1 1" stroke="#666" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
+ </Caret>
+ </Container>
+ );
+};
+
+Select.defaultProps = {
+ emptyText: 'Select...',
+ shouldIncludeEmpty: true,
+};
+
+const Container = styled.div`
+ background-color: #fff;
+ border-radius: 4px;
+ display: flex;
+ width: 100%;
+ position: relative;
+`;
+
+const StyledSelect = styled.select`
+ appearance: none;
+ border: 0;
+ font-size: 1rem;
+ width: 100%;
+ padding: 20px 20px 20px 20px;
+`;
+
+const Caret = styled.svg`
+ position: absolute;
+ right: 20px;
+ top: calc(50% - 4px);
+`;