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 | |
parent | 01ccd8ff1a995f6b74f52533bc595cbc428b9eef (diff) | |
parent | 50442c3ebbf7a27e49f04a7f0512dcfed9686857 (diff) | |
download | dexon-0x-contracts-a5a033c359a1a00a144ae0655080b4e6d0e43c88.tar.gz dexon-0x-contracts-a5a033c359a1a00a144ae0655080b4e6d0e43c88.tar.zst dexon-0x-contracts-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')
22 files changed, 653 insertions, 6 deletions
diff --git a/packages/instant/package.json b/packages/instant/package.json index 26c370e4c..ff40ba2ea 100644 --- a/packages/instant/package.json +++ b/packages/instant/package.json @@ -43,15 +43,19 @@ }, "homepage": "https://github.com/0xProject/0x-monorepo/packages/instant/README.md", "dependencies": { - "@0xproject/connect": "^2.0.4", + "@0xproject/asset-buyer": "^2.0.0", "@0xproject/types": "^1.1.4", "@0xproject/typescript-typings": "^2.0.2", - "@0xproject/utils": "^1.0.11", + "@0xproject/utils": "^2.0.2", "@0xproject/web3-wrapper": "^3.0.3", "ethereum-types": "^1.0.11", "lodash": "^4.17.10", + "polished": "^2.2.0", "react": "^16.5.2", - "react-dom": "^16.5.2" + "react-dom": "^16.5.2", + "react-redux": "^5.0.7", + "redux": "^4.0.0", + "styled-components": "^3.4.9" }, "devDependencies": { "@0xproject/tslint-config": "^1.0.8", @@ -59,8 +63,10 @@ "@types/enzyme-adapter-react-16": "^1.0.3", "@types/lodash": "^4.14.116", "@types/node": "*", - "@types/react": "16.4.7", + "@types/react": "^16.4.16", "@types/react-dom": "^16.0.8", + "@types/react-redux": "^6.0.9", + "@types/redux": "^3.6.0", "awesome-typescript-loader": "^5.2.1", "copyfiles": "^1.2.0", "enzyme": "^3.6.0", diff --git a/packages/instant/public/index.html b/packages/instant/public/index.html index 45968a3c9..fb041745e 100644 --- a/packages/instant/public/index.html +++ b/packages/instant/public/index.html @@ -6,6 +6,19 @@ <meta name="viewport" content="width=device-width, initial-scale=1"> <title>0x Instant Dev Environment</title> <script type="text/javascript" src="/main.bundle.js" charset="utf-8"></script> + <style> + #zeroExInstantContainer { + display: flex; + justify-content: center; + align-items: center; + height: 100vh; + } + + body { + margin: 0; + background-color: rgba(0, 0, 0, 0.2); + } + </style> </head> <body> 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> +); diff --git a/packages/instant/src/containers/selected_asset_amount_input.tsx b/packages/instant/src/containers/selected_asset_amount_input.tsx new file mode 100644 index 000000000..800a4c568 --- /dev/null +++ b/packages/instant/src/containers/selected_asset_amount_input.tsx @@ -0,0 +1,36 @@ +import { BigNumber } from '@0xproject/utils'; +import * as React from 'react'; +import { connect } from 'react-redux'; +import { Dispatch } from 'redux'; + +import { State } from '../redux/reducer'; +import { ColorOption } from '../style/theme'; +import { Action, ActionTypes } from '../types'; + +import { AmountInput } from '../components/amount_input'; + +export interface SelectedAssetAmountInputProps { + fontColor?: ColorOption; + fontSize?: string; +} + +interface ConnectedState { + value?: BigNumber; +} + +interface ConnectedDispatch { + onChange?: (value?: BigNumber) => void; +} + +const mapStateToProps = (state: State, _ownProps: SelectedAssetAmountInputProps): ConnectedState => ({ + value: state.selectedAssetAmount, +}); + +const mapDispatchToProps = (dispatch: Dispatch<Action>): ConnectedDispatch => ({ + onChange: value => dispatch({ type: ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT, data: value }), +}); + +export const SelectedAssetAmountInput: React.ComponentClass<SelectedAssetAmountInputProps> = connect( + mapStateToProps, + mapDispatchToProps, +)(AmountInput); diff --git a/packages/instant/src/redux/reducer.ts b/packages/instant/src/redux/reducer.ts new file mode 100644 index 000000000..5026895ae --- /dev/null +++ b/packages/instant/src/redux/reducer.ts @@ -0,0 +1,31 @@ +import { BigNumber } from '@0xproject/utils'; +import * as _ from 'lodash'; + +import { Action, ActionTypes } from '../types'; + +export interface State { + ethUsdPrice?: string; + selectedAssetAmount?: BigNumber; +} + +export const INITIAL_STATE: State = { + ethUsdPrice: undefined, + selectedAssetAmount: undefined, +}; + +export const reducer = (state: State = INITIAL_STATE, action: Action): State => { + switch (action.type) { + case ActionTypes.UPDATE_ETH_USD_PRICE: + return { + ...state, + ethUsdPrice: action.data, + }; + case ActionTypes.UPDATE_SELECTED_ASSET_AMOUNT: + return { + ...state, + selectedAssetAmount: action.data, + }; + default: + return state; + } +}; diff --git a/packages/instant/src/redux/store.ts b/packages/instant/src/redux/store.ts new file mode 100644 index 000000000..fcd19f9a8 --- /dev/null +++ b/packages/instant/src/redux/store.ts @@ -0,0 +1,6 @@ +import * as _ from 'lodash'; +import { createStore, Store as ReduxStore } from 'redux'; + +import { reducer, State } from './reducer'; + +export const store: ReduxStore<State> = createStore(reducer); diff --git a/packages/instant/src/style/fonts.ts b/packages/instant/src/style/fonts.ts new file mode 100644 index 000000000..975a30a61 --- /dev/null +++ b/packages/instant/src/style/fonts.ts @@ -0,0 +1,10 @@ +import { injectGlobal } from './theme'; + +export const fonts = { + include: () => { + // Inject the inter-ui font into the page + return injectGlobal` + @import url('https://rsms.me/inter/inter-ui.css'); + `; + }, +}; diff --git a/packages/instant/src/style/theme.ts b/packages/instant/src/style/theme.ts new file mode 100644 index 000000000..cf9da5378 --- /dev/null +++ b/packages/instant/src/style/theme.ts @@ -0,0 +1,27 @@ +import * as styledComponents from 'styled-components'; + +const { default: styled, css, injectGlobal, keyframes, ThemeProvider } = styledComponents; + +export type Theme = { [key in ColorOption]: string }; + +export enum ColorOption { + primaryColor = 'primaryColor', + black = 'black', + lightGrey = 'lightGrey', + grey = 'grey', + feintGrey = 'feintGrey', + darkGrey = 'darkGrey', + white = 'white', +} + +export const theme: Theme = { + primaryColor: '#512D80', + black: 'black', + lightGrey: '#999999', + grey: '#666666', + feintGrey: '#DEDEDE', + darkGrey: '#333333', + white: 'white', +}; + +export { styled, css, injectGlobal, keyframes, ThemeProvider }; diff --git a/packages/instant/src/style/util.ts b/packages/instant/src/style/util.ts new file mode 100644 index 000000000..c9df0f834 --- /dev/null +++ b/packages/instant/src/style/util.ts @@ -0,0 +1,11 @@ +import { ObjectMap } from '@0xproject/types'; +import * as _ from 'lodash'; + +export const cssRuleIfExists = (props: ObjectMap<any>, rule: string): string => { + const camelCaseRule = _.camelCase(rule); + const ruleValueIfExists = props[camelCaseRule]; + if (!_.isUndefined(ruleValueIfExists)) { + return `${rule}: ${ruleValueIfExists};`; + } + return ''; +}; diff --git a/packages/instant/src/types.ts b/packages/instant/src/types.ts new file mode 100644 index 000000000..d150bd8ab --- /dev/null +++ b/packages/instant/src/types.ts @@ -0,0 +1,9 @@ +export enum ActionTypes { + UPDATE_ETH_USD_PRICE, + UPDATE_SELECTED_ASSET_AMOUNT, +} + +export interface Action { + type: ActionTypes; + data?: any; +} diff --git a/packages/instant/tslint.json b/packages/instant/tslint.json index ffaefe83a..f71532e5d 100644 --- a/packages/instant/tslint.json +++ b/packages/instant/tslint.json @@ -1,3 +1,7 @@ { - "extends": ["@0xproject/tslint-config"] + "extends": ["@0xproject/tslint-config"], + "rules": { + "custom-no-magic-numbers": false, + "semicolon": [true, "always", "ignore-bound-class-methods"] + } } |