diff options
author | Francesco Agosti <francesco.agosti93@gmail.com> | 2018-10-11 09:27:54 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-10-11 09:27:54 +0800 |
commit | a5a033c359a1a00a144ae0655080b4e6d0e43c88 (patch) | |
tree | 50b79c4061c91753030bafa34ff6a60a5c97ea02 /packages/instant/src/components | |
parent | 01ccd8ff1a995f6b74f52533bc595cbc428b9eef (diff) | |
parent | 50442c3ebbf7a27e49f04a7f0512dcfed9686857 (diff) | |
download | dexon-sol-tools-a5a033c359a1a00a144ae0655080b4e6d0e43c88.tar dexon-sol-tools-a5a033c359a1a00a144ae0655080b4e6d0e43c88.tar.gz dexon-sol-tools-a5a033c359a1a00a144ae0655080b4e6d0e43c88.tar.bz2 dexon-sol-tools-a5a033c359a1a00a144ae0655080b4e6d0e43c88.tar.lz dexon-sol-tools-a5a033c359a1a00a144ae0655080b4e6d0e43c88.tar.xz dexon-sol-tools-a5a033c359a1a00a144ae0655080b4e6d0e43c88.tar.zst dexon-sol-tools-a5a033c359a1a00a144ae0655080b4e6d0e43c88.zip |
Merge pull request #1114 from 0xProject/feature/instant/redux-styles-container
[instant] Add styles and redux to instant
Diffstat (limited to 'packages/instant/src/components')
-rw-r--r-- | packages/instant/src/components/amount_input.tsx | 47 | ||||
-rw-r--r-- | packages/instant/src/components/buy_button.tsx | 19 | ||||
-rw-r--r-- | packages/instant/src/components/instant_heading.tsx | 45 | ||||
-rw-r--r-- | packages/instant/src/components/order_details.tsx | 62 | ||||
-rw-r--r-- | packages/instant/src/components/ui/button.tsx | 60 | ||||
-rw-r--r-- | packages/instant/src/components/ui/container.tsx | 64 | ||||
-rw-r--r-- | packages/instant/src/components/ui/flex.tsx | 37 | ||||
-rw-r--r-- | packages/instant/src/components/ui/index.ts | 5 | ||||
-rw-r--r-- | packages/instant/src/components/ui/input.tsx | 40 | ||||
-rw-r--r-- | packages/instant/src/components/ui/text.tsx | 80 | ||||
-rw-r--r-- | packages/instant/src/components/zero_ex_instant.tsx | 17 | ||||
-rw-r--r-- | packages/instant/src/components/zero_ex_instant_container.tsx | 20 |
12 files changed, 495 insertions, 1 deletions
diff --git a/packages/instant/src/components/amount_input.tsx b/packages/instant/src/components/amount_input.tsx new file mode 100644 index 000000000..38810063d --- /dev/null +++ b/packages/instant/src/components/amount_input.tsx @@ -0,0 +1,47 @@ +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; +import * as React from 'react'; + +import { ColorOption } from '../style/theme'; + +import { Container, Input } from './ui'; + +export interface AmountInputProps { + fontColor?: ColorOption; + fontSize?: string; + value?: BigNumber; + onChange?: (value?: BigNumber) => void; +} + +export class AmountInput extends React.Component<AmountInputProps> { + public render(): React.ReactNode { + const { fontColor, fontSize, value } = this.props; + return ( + <Container borderBottom="1px solid rgba(255,255,255,0.3)" display="inline-block"> + <Input + fontColor={fontColor} + fontSize={fontSize} + onChange={this._handleChange} + value={!_.isUndefined(value) ? value.toString() : ''} + placeholder="0.00" + width="2em" + /> + </Container> + ); + } + private readonly _handleChange = (event: React.ChangeEvent<HTMLInputElement>): void => { + const value = event.target.value; + let bigNumberValue; + if (!_.isEmpty(value)) { + try { + bigNumberValue = new BigNumber(event.target.value); + } catch { + // We don't want to allow values that can't be a BigNumber, so don't even call onChange. + return; + } + } + if (!_.isUndefined(this.props.onChange)) { + this.props.onChange(bigNumberValue); + } + }; +} diff --git a/packages/instant/src/components/buy_button.tsx b/packages/instant/src/components/buy_button.tsx new file mode 100644 index 000000000..5a32b9575 --- /dev/null +++ b/packages/instant/src/components/buy_button.tsx @@ -0,0 +1,19 @@ +import * as React from 'react'; + +import { ColorOption } from '../style/theme'; + +import { Button, Container, Text } from './ui'; + +export interface BuyButtonProps {} + +export const BuyButton: React.StatelessComponent<BuyButtonProps> = props => ( + <Container padding="20px" width="100%"> + <Button width="100%"> + <Text fontColor={ColorOption.white} fontWeight={600} fontSize="20px"> + Buy + </Text> + </Button> + </Container> +); + +BuyButton.displayName = 'BuyButton'; diff --git a/packages/instant/src/components/instant_heading.tsx b/packages/instant/src/components/instant_heading.tsx new file mode 100644 index 000000000..be0414b8d --- /dev/null +++ b/packages/instant/src/components/instant_heading.tsx @@ -0,0 +1,45 @@ +import * as React from 'react'; + +import { SelectedAssetAmountInput } from '../containers/selected_asset_amount_input'; +import { ColorOption } from '../style/theme'; + +import { Container, Flex, Text } from './ui'; + +export interface InstantHeadingProps {} + +export const InstantHeading: React.StatelessComponent<InstantHeadingProps> = props => ( + <Container backgroundColor={ColorOption.primaryColor} padding="20px" width="100%" borderRadius="3px 3px 0px 0px"> + <Container marginBottom="5px"> + <Text + letterSpacing="1px" + fontColor={ColorOption.white} + opacity={0.7} + fontWeight={500} + textTransform="uppercase" + fontSize="12px" + > + I want to buy + </Text> + </Container> + <Flex direction="row" justify="space-between"> + <Container> + <SelectedAssetAmountInput fontSize="45px" /> + <Container display="inline-block" marginLeft="10px"> + <Text fontSize="45px" fontColor={ColorOption.white} textTransform="uppercase"> + rep + </Text> + </Container> + </Container> + <Flex direction="column" justify="space-between"> + <Container marginBottom="5px"> + <Text fontSize="16px" fontColor={ColorOption.white} fontWeight={500}> + 0 ETH + </Text> + </Container> + <Text fontSize="16px" fontColor={ColorOption.white} opacity={0.7}> + $0.00 + </Text> + </Flex> + </Flex> + </Container> +); diff --git a/packages/instant/src/components/order_details.tsx b/packages/instant/src/components/order_details.tsx new file mode 100644 index 000000000..dbf2c1f0b --- /dev/null +++ b/packages/instant/src/components/order_details.tsx @@ -0,0 +1,62 @@ +import * as React from 'react'; + +import { ColorOption } from '../style/theme'; + +import { Container, Flex, Text } from './ui'; + +export interface OrderDetailsProps {} + +export const OrderDetails: React.StatelessComponent<OrderDetailsProps> = props => ( + <Container padding="20px" width="100%"> + <Container marginBottom="10px"> + <Text + letterSpacing="1px" + fontColor={ColorOption.primaryColor} + fontWeight={600} + textTransform="uppercase" + fontSize="14px" + > + Order Details + </Text> + </Container> + <OrderDetailsRow name="Token Price" primaryValue=".013 ETH" secondaryValue="$24.32" /> + <OrderDetailsRow name="Fee" primaryValue=".005 ETH" secondaryValue="$1.04" /> + <OrderDetailsRow name="Total Cost" primaryValue="1.66 ETH" secondaryValue="$589.56" shouldEmphasize={true} /> + </Container> +); + +OrderDetails.displayName = 'OrderDetails'; + +export interface OrderDetailsRowProps { + name: string; + primaryValue: string; + secondaryValue: string; + shouldEmphasize?: boolean; +} + +export const OrderDetailsRow: React.StatelessComponent<OrderDetailsRowProps> = props => { + const fontWeight = props.shouldEmphasize ? 700 : 400; + return ( + <Container padding="10px 0px" borderTop="1px dashed" borderColor={ColorOption.feintGrey}> + <Flex justify="space-between"> + <Text fontWeight={fontWeight} fontColor={ColorOption.grey}> + {props.name} + </Text> + <Container> + <Container marginRight="3px" display="inline-block"> + <Text fontColor={ColorOption.lightGrey}>({props.secondaryValue}) </Text> + </Container> + <Text fontWeight={fontWeight} fontColor={ColorOption.grey}> + {props.primaryValue} + </Text> + </Container> + </Flex> + </Container> + ); +}; + +OrderDetailsRow.defaultProps = { + shouldEmphasize: false, +}; + +OrderDetailsRow.displayName = 'OrderDetailsRow'; diff --git a/packages/instant/src/components/ui/button.tsx b/packages/instant/src/components/ui/button.tsx new file mode 100644 index 000000000..1fcb2591c --- /dev/null +++ b/packages/instant/src/components/ui/button.tsx @@ -0,0 +1,60 @@ +import { darken, saturate } from 'polished'; +import * as React from 'react'; + +import { ColorOption, styled } from '../../style/theme'; + +export interface ButtonProps { + backgroundColor?: ColorOption; + borderColor?: ColorOption; + width?: string; + padding?: string; + type?: string; + isDisabled?: boolean; + onClick?: (event: React.MouseEvent<HTMLElement>) => void; + className?: string; +} + +const PlainButton: React.StatelessComponent<ButtonProps> = ({ children, isDisabled, onClick, type, className }) => ( + <button type={type} className={className} onClick={isDisabled ? undefined : onClick} disabled={isDisabled}> + {children} + </button> +); + +const darkenOnHoverAmount = 0.1; +const darkenOnActiveAmount = 0.2; +const saturateOnFocusAmount = 0.2; +export const Button = styled(PlainButton)` + cursor: ${props => (props.isDisabled ? 'default' : 'pointer')}; + transition: background-color, opacity 0.5s ease; + padding: ${props => props.padding}; + border-radius: 3px; + outline: none; + width: ${props => props.width}; + background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; + border: ${props => (props.borderColor ? `1px solid ${props.theme[props.borderColor]}` : 'none')}; + &:hover { + background-color: ${props => + !props.isDisabled + ? darken(darkenOnHoverAmount, props.theme[props.backgroundColor || 'white']) + : ''} !important; + } + &:active { + background-color: ${props => + !props.isDisabled ? darken(darkenOnActiveAmount, props.theme[props.backgroundColor || 'white']) : ''}; + } + &:disabled { + opacity: 0.5; + } + &:focus { + background-color: ${props => saturate(saturateOnFocusAmount, props.theme[props.backgroundColor || 'white'])}; + } +`; + +Button.defaultProps = { + backgroundColor: ColorOption.primaryColor, + width: 'auto', + isDisabled: false, + padding: '1em 2.2em', +}; + +Button.displayName = 'Button'; diff --git a/packages/instant/src/components/ui/container.tsx b/packages/instant/src/components/ui/container.tsx new file mode 100644 index 000000000..c45f6e5e9 --- /dev/null +++ b/packages/instant/src/components/ui/container.tsx @@ -0,0 +1,64 @@ +import * as React from 'react'; + +import { ColorOption, styled } from '../../style/theme'; +import { cssRuleIfExists } from '../../style/util'; + +export interface ContainerProps { + display?: string; + position?: string; + top?: string; + right?: string; + bottom?: string; + left?: string; + width?: string; + maxWidth?: string; + margin?: string; + marginTop?: string; + marginRight?: string; + marginBottom?: string; + marginLeft?: string; + padding?: string; + borderRadius?: string; + border?: string; + borderColor?: ColorOption; + borderTop?: string; + borderBottom?: string; + className?: string; + backgroundColor?: ColorOption; + hasBoxShadow?: boolean; +} + +const PlainContainer: React.StatelessComponent<ContainerProps> = ({ children, className }) => ( + <div className={className}>{children}</div> +); + +export const Container = styled(PlainContainer)` + box-sizing: border-box; + ${props => cssRuleIfExists(props, 'display')} + ${props => cssRuleIfExists(props, 'position')} + ${props => cssRuleIfExists(props, 'top')} + ${props => cssRuleIfExists(props, 'right')} + ${props => cssRuleIfExists(props, 'bottom')} + ${props => cssRuleIfExists(props, 'left')} + ${props => cssRuleIfExists(props, 'width')} + ${props => cssRuleIfExists(props, 'max-width')} + ${props => cssRuleIfExists(props, 'margin')} + ${props => cssRuleIfExists(props, 'margin-top')} + ${props => cssRuleIfExists(props, 'margin-right')} + ${props => cssRuleIfExists(props, 'margin-bottom')} + ${props => cssRuleIfExists(props, 'margin-left')} + ${props => cssRuleIfExists(props, 'padding')} + ${props => cssRuleIfExists(props, 'border-radius')} + ${props => cssRuleIfExists(props, 'border')} + ${props => cssRuleIfExists(props, 'border-top')} + ${props => cssRuleIfExists(props, 'border-bottom')} + ${props => (props.hasBoxShadow ? `box-shadow: 0px 2px 10px rgba(0, 0, 0, 0.1)` : '')}; + background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; + border-color: ${props => (props.borderColor ? props.theme[props.borderColor] : 'none')}; +`; + +Container.defaultProps = { + display: 'block', +}; + +Container.displayName = 'Container'; diff --git a/packages/instant/src/components/ui/flex.tsx b/packages/instant/src/components/ui/flex.tsx new file mode 100644 index 000000000..327e91926 --- /dev/null +++ b/packages/instant/src/components/ui/flex.tsx @@ -0,0 +1,37 @@ +import * as React from 'react'; + +import { ColorOption, styled } from '../../style/theme'; +import { cssRuleIfExists } from '../../style/util'; + +export interface FlexProps { + direction?: 'row' | 'column'; + flexWrap?: 'wrap' | 'nowrap'; + justify?: 'flex-start' | 'center' | 'space-around' | 'space-between' | 'space-evenly' | 'flex-end'; + align?: 'flex-start' | 'center' | 'space-around' | 'space-between' | 'space-evenly' | 'flex-end'; + width?: string; + backgroundColor?: ColorOption; + className?: string; +} + +const PlainFlex: React.StatelessComponent<FlexProps> = ({ children, className }) => ( + <div className={className}>{children}</div> +); + +export const Flex = styled(PlainFlex)` + display: flex; + flex-direction: ${props => props.direction}; + flex-wrap: ${props => props.flexWrap}; + justify-content: ${props => props.justify}; + align-items: ${props => props.align}; + ${props => cssRuleIfExists(props, 'width')} + background-color: ${props => (props.backgroundColor ? props.theme[props.backgroundColor] : 'none')}; +`; + +Flex.defaultProps = { + direction: 'row', + flexWrap: 'nowrap', + justify: 'center', + align: 'center', +}; + +Flex.displayName = 'Flex'; diff --git a/packages/instant/src/components/ui/index.ts b/packages/instant/src/components/ui/index.ts new file mode 100644 index 000000000..bf5f6c700 --- /dev/null +++ b/packages/instant/src/components/ui/index.ts @@ -0,0 +1,5 @@ +export { Text, Title } from './text'; +export { Button } from './button'; +export { Flex } from './flex'; +export { Container } from './container'; +export { Input } from './input'; diff --git a/packages/instant/src/components/ui/input.tsx b/packages/instant/src/components/ui/input.tsx new file mode 100644 index 000000000..f8c6b6ef6 --- /dev/null +++ b/packages/instant/src/components/ui/input.tsx @@ -0,0 +1,40 @@ +import * as React from 'react'; + +import { ColorOption, styled } from '../../style/theme'; + +export interface InputProps { + className?: string; + value?: string; + width?: string; + fontSize?: string; + fontColor?: ColorOption; + placeholder?: string; + onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void; +} + +const PlainInput: React.StatelessComponent<InputProps> = ({ value, className, placeholder, onChange }) => ( + <input className={className} value={value} onChange={onChange} placeholder={placeholder} /> +); + +export const Input = styled(PlainInput)` + font-size: ${props => props.fontSize}; + width: ${props => props.width}; + padding: 0.1em 0em; + font-family: 'Inter UI'; + color: ${props => props.theme[props.fontColor || 'white']}; + background: transparent; + outline: none; + border: none; + &::placeholder { + color: ${props => props.theme[props.fontColor || 'white']}; + opacity: 0.5; + } +`; + +Input.defaultProps = { + width: 'auto', + fontColor: ColorOption.white, + fontSize: '12px', +}; + +Input.displayName = 'Input'; diff --git a/packages/instant/src/components/ui/text.tsx b/packages/instant/src/components/ui/text.tsx new file mode 100644 index 000000000..9fb8ea26f --- /dev/null +++ b/packages/instant/src/components/ui/text.tsx @@ -0,0 +1,80 @@ +import { darken } from 'polished'; +import * as React from 'react'; + +import { ColorOption, styled } from '../../style/theme'; + +export interface TextProps { + fontColor?: ColorOption; + fontFamily?: string; + fontStyle?: string; + fontSize?: string; + opacity?: number; + letterSpacing?: string; + textTransform?: string; + lineHeight?: string; + className?: string; + minHeight?: string; + center?: boolean; + fontWeight?: number | string; + textDecorationLine?: string; + onClick?: (event: React.MouseEvent<HTMLElement>) => void; + hoverColor?: string; + noWrap?: boolean; + display?: string; +} + +const PlainText: React.StatelessComponent<TextProps> = ({ children, className, onClick }) => ( + <div className={className} onClick={onClick}> + {children} + </div> +); + +const darkenOnHoverAmount = 0.3; +export const Text = styled(PlainText)` + font-family: ${props => props.fontFamily}; + font-style: ${props => props.fontStyle}; + font-weight: ${props => props.fontWeight}; + font-size: ${props => props.fontSize}; + opacity: ${props => props.opacity}; + text-decoration-line: ${props => props.textDecorationLine}; + ${props => (props.lineHeight ? `line-height: ${props.lineHeight}` : '')}; + ${props => (props.center ? 'text-align: center' : '')}; + color: ${props => props.fontColor && props.theme[props.fontColor]}; + ${props => (props.minHeight ? `min-height: ${props.minHeight}` : '')}; + ${props => (props.onClick ? 'cursor: pointer' : '')}; + transition: color 0.5s ease; + ${props => (props.noWrap ? 'white-space: nowrap' : '')}; + ${props => (props.display ? `display: ${props.display}` : '')}; + ${props => (props.letterSpacing ? `letter-spacing: ${props.letterSpacing}` : '')}; + ${props => (props.textTransform ? `text-transform: ${props.textTransform}` : '')}; + &:hover { + ${props => + props.onClick + ? `color: ${props.hoverColor || darken(darkenOnHoverAmount, props.theme[props.fontColor || 'white'])}` + : ''}; + } +`; + +Text.defaultProps = { + fontFamily: 'Inter UI', + fontStyle: 'normal', + fontWeight: 400, + fontColor: ColorOption.black, + fontSize: '15px', + textDecorationLine: 'none', + noWrap: false, + display: 'inline-block', +}; + +Text.displayName = 'Text'; + +export const Title: React.StatelessComponent<TextProps> = props => <Text {...props} />; + +Title.defaultProps = { + fontSize: '20px', + fontWeight: 600, + opacity: 1, + fontColor: ColorOption.primaryColor, +}; + +Title.displayName = 'Title'; diff --git a/packages/instant/src/components/zero_ex_instant.tsx b/packages/instant/src/components/zero_ex_instant.tsx index 67e1b683d..0e6230d1b 100644 --- a/packages/instant/src/components/zero_ex_instant.tsx +++ b/packages/instant/src/components/zero_ex_instant.tsx @@ -1,5 +1,20 @@ import * as React from 'react'; +import { Provider } from 'react-redux'; + +import { store } from '../redux/store'; +import { fonts } from '../style/fonts'; +import { theme, ThemeProvider } from '../style/theme'; + +import { ZeroExInstantContainer } from './zero_ex_instant_container'; + +fonts.include(); export interface ZeroExInstantProps {} -export const ZeroExInstant: React.StatelessComponent<ZeroExInstantProps> = () => <div>ZeroExInstant</div>; +export const ZeroExInstant: React.StatelessComponent<ZeroExInstantProps> = () => ( + <Provider store={store}> + <ThemeProvider theme={theme}> + <ZeroExInstantContainer /> + </ThemeProvider> + </Provider> +); diff --git a/packages/instant/src/components/zero_ex_instant_container.tsx b/packages/instant/src/components/zero_ex_instant_container.tsx new file mode 100644 index 000000000..716227b51 --- /dev/null +++ b/packages/instant/src/components/zero_ex_instant_container.tsx @@ -0,0 +1,20 @@ +import * as React from 'react'; + +import { ColorOption } from '../style/theme'; + +import { BuyButton } from './buy_button'; +import { InstantHeading } from './instant_heading'; +import { OrderDetails } from './order_details'; +import { Container, Flex } from './ui'; + +export interface ZeroExInstantContainerProps {} + +export const ZeroExInstantContainer: React.StatelessComponent<ZeroExInstantContainerProps> = props => ( + <Container hasBoxShadow={true} width="350px" backgroundColor={ColorOption.white} borderRadius="3px"> + <Flex direction="column" justify="flex-start"> + <InstantHeading /> + <OrderDetails /> + <BuyButton /> + </Flex> + </Container> +); |