Components V2 (#562)

* components v2

* Fix type

* Adding TextBox component and some minor changes

* replacing harcoded color by the one defined in varibales

* TextBox: Replacing div by p
This commit is contained in:
nicolas 2020-02-17 10:34:28 -03:00 committed by GitHub
parent 2698dcb6e8
commit 8d81104894
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 535 additions and 0 deletions

View File

@ -0,0 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="13" height="21" viewBox="0 0 13 21">
<path fill="#B2B5B2" fill-rule="evenodd" d="M8.7 11.266V0H4.27v11.266H0l6.484 9.172 6.493-9.172z"/>
</svg>

After

Width:  |  Height:  |  Size: 195 B

View File

@ -0,0 +1,30 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import Hairline from '~/components/layout/Hairline'
import { sm, md } from '~/theme/variables'
import ArrowDown from './arrow-down.svg'
const Wrapper = styled.div`
display: flex;
align-items: center;
margin: ${md} 0;
img {
margin: 0 ${sm};
}
`
type Props = {
withArrow: boolean,
}
const DividerLine = ({ withArrow }: Props) => (
<Wrapper>
{withArrow && <img src={ArrowDown} alt="Arrow Down" />}
<Hairline />
</Wrapper>
)
export default DividerLine

View File

@ -0,0 +1,21 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import { border } from '~/theme/variables'
type Props = {
children: React.Node,
}
const Box = styled.p`
padding: 10px;
word-wrap: break-word;
border: solid 2px ${border};
`
const TextBox = ({ children }: Props) => {
return <Box>{children}</Box>
}
export default TextBox

View File

@ -0,0 +1,3 @@
// @flow
export { default as DividerLine } from './DividerLine'
export { default as TextBox } from './TextBox'

View File

@ -0,0 +1,20 @@
// @flow
import React from 'react'
import CircularProgress from '@material-ui/core/CircularProgress'
import styled from 'styled-components'
const Wrapper = styled.div`
display: flex;
height: 100%;
width: 100%;
justify-content: center;
align-items: center;
`
const Loader = () => (
<Wrapper>
<CircularProgress size={60} />
</Wrapper>
)
export default Loader

View File

@ -0,0 +1,2 @@
// @flow
export { default as Loader } from './Loader'

View File

@ -0,0 +1,7 @@
// @flow
export * from './dataDisplay'
export * from './feedback'
export * from './layouts'
export * from './safeUtils'
export * from './surfaces'
export * from './utils'

View File

@ -0,0 +1,46 @@
// @flow
import styled from 'styled-components'
export const Wrapper = styled.div`
display: grid;
grid-template-columns: 245px auto;
grid-template-rows: 62px auto 25px;
min-height: 500px;
.background {
box-shadow: 1px 2px 10px 0 rgba(212, 212, 211, 0.59);
background-color: white;
}
`
export const Nav = styled.div`
grid-column: 1/3;
grid-row: 1;
margin: 8px 0;
padding: 16px 0;
box-sizing: border-box;
display: flex;
justify-content: flex-end;
`
export const Menu = styled.div.attrs(() => ({ className: 'background' }))`
grid-column: 1;
grid-row: 2/4;
border-right: solid 2px #e8e7e6;
border-top-left-radius: 8px;
border-bottom-left-radius: 8px;
`
export const Content = styled.div.attrs(() => ({ className: 'background' }))`
grid-column: 2;
grid-row: 2;
border-top-right-radius: 8px;
`
export const Footer = styled.div.attrs(() => ({ className: 'background' }))`
grid-column: 2;
grid-row: 3;
border-bottom-right-radius: 8px;
display: flex;
justify-content: center;
align-items: center;
`

View File

@ -0,0 +1,59 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import cn from 'classnames'
import { withStyles } from '@material-ui/core/styles'
// TODO: move these styles to a generic place
import styles from './style'
const Wrapper = styled.div``
const Item = styled.div`
border-bottom: solid 2px rgb(232, 231, 230);
.container {
display: flex;
align-items: flex-end;
}
`
const IconImg = styled.img`
width: 20px;
margin-right: 10px;
`
type Props = {
items: Array<{
id: string,
name: string,
iconUrl?: string,
}>,
activeItem: string,
onItemClick: () => void,
classes: Object,
}
const List = ({ items, activeItem, onItemClick, classes }: Props) => {
return (
<Wrapper>
{items.map(i => (
<Item
key={i.id}
className={cn(
classes.menuOption,
activeItem === i.id && classes.active
)}
onClick={() => onItemClick(i.id)}
>
<div className="container">
{i.iconUrl && <IconImg src={i.iconUrl} alt={i.name} />}
<span>{i.name}</span>
</div>
</Item>
))}
</Wrapper>
)
}
export default withStyles(styles)(List)

View File

@ -0,0 +1,10 @@
// @flow
import * as LayoutComponents from './Layout'
import List from './List'
const ListContentLayout = {
...LayoutComponents,
List,
}
export default ListContentLayout

View File

@ -0,0 +1,66 @@
// @flow
import {
xs,
sm,
md,
border,
secondary,
bolderFont,
background,
largeFontSize,
fontColor,
screenSm,
} from '~/theme/variables'
const styles = () => ({
menuOption: {
alignItems: 'center',
borderRight: `solid 1px ${border}`,
boxSizing: 'border-box',
cursor: 'pointer',
flexGrow: '1',
flexShrink: '1',
fontSize: '13px',
justifyContent: 'center',
lineHeight: '1.2',
minWidth: '0',
padding: `${md} ${sm}`,
width: '100%',
[`@media (min-width: ${screenSm}px)`]: {
borderRight: 'none',
flexGrow: '0',
fontSize: largeFontSize,
justifyContent: 'flex-start',
padding: `${md} 0 ${md} ${md}`,
},
'&:last-of-type': {
borderRight: 'none',
},
'&:first-child': {
borderTopLeftRadius: sm,
},
'& svg': {
display: 'block',
marginRight: xs,
maxWidth: '16px',
[`@media (min-width: ${screenSm}px)`]: {
marginRight: sm,
},
},
'& .fill': {
fill: fontColor,
},
},
active: {
backgroundColor: background,
color: secondary,
fontWeight: bolderFont,
'& .fill': {
fill: secondary,
},
},
})
export default styles

View File

@ -0,0 +1,2 @@
// @flow
export { default as ListContentLayout } from './ListContentLayout'

View File

@ -0,0 +1,77 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import Paragraph from '~/components/layout/Paragraph'
import EtherscanBtn from '~/components/EtherscanBtn'
import CopyBtn from '~/components/CopyBtn'
import Identicon from '~/components/Identicon'
import Bold from '~/components/layout/Bold'
import { xs, border } from '~/theme/variables'
import Block from '~/components/layout/Block'
const Wrapper = styled.div`
display: flex;
align-items: center;
.icon-section {
margin-right: 10px;
}
.data-section {
display: flex;
flex-direction: column;
.address {
display: flex;
}
}
`
const StyledBlock = styled(Block)`
font-size: 12px;
line-height: 1.08;
letter-spacing: -0.5;
background-color: ${border};
width: fit-content;
padding: 5px 10px;
margin-top: ${xs};
border-radius: 3px;
`
type Props = {
safeName: string,
safeAddress: string,
ethBalance: string,
}
const AddressInfo = ({ safeName, safeAddress, ethBalance }: Props) => {
return (
<Wrapper>
<div className="icon-section">
<Identicon address={safeAddress} diameter={32} />
</div>
<div className="data-section">
{safeName && (
<Paragraph weight="bolder" noMargin>
{safeName}
</Paragraph>
)}
<div className="address">
<Paragraph weight="bolder" noMargin>
{safeAddress}
</Paragraph>
<CopyBtn content={safeAddress} />
<EtherscanBtn type="address" value={safeAddress} />
</div>
{ethBalance && (
<StyledBlock>
<Paragraph noMargin>
Balance: <Bold>{`${ethBalance} ETH`}</Bold>
</Paragraph>
</StyledBlock>
)}
</div>
</Wrapper>
)
}
export default AddressInfo

View File

@ -0,0 +1,2 @@
// @flow
export { default as AddressInfo } from './AddressInfo'

View File

@ -0,0 +1,48 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import CollapseMUI from '@material-ui/core/Collapse'
import IconButton from '@material-ui/core/IconButton'
import ExpandLess from '@material-ui/icons/ExpandLess'
import ExpandMore from '@material-ui/icons/ExpandMore'
const Wrapper = styled.div``
const Header = styled.div`
display: flex;
align-items: center;
`
const Title = styled.div``
type Props = {
title: string,
children: React.Node,
description: React.Node,
}
const Collapse = ({ title, description, children }: Props) => {
const [open, setOpen] = React.useState(false)
const handleClick = () => {
setOpen(!open)
}
return (
<Wrapper>
<Title>{title}</Title>
<Header>
<IconButton disableRipple size="small" onClick={handleClick}>
{open ? <ExpandLess /> : <ExpandMore />}
</IconButton>
{description}
</Header>
<CollapseMUI in={open} timeout="auto" unmountOnExit>
{children}
</CollapseMUI>
</Wrapper>
)
}
export default Collapse

View File

@ -0,0 +1,2 @@
// @flow
export { default as Collapse } from './Collapse'

View File

@ -0,0 +1,2 @@
// @flow
export * from './modals'

View File

@ -0,0 +1,79 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import Close from '@material-ui/icons/Close'
import { makeStyles, createStyles } from '@material-ui/core/styles'
import IconButton from '@material-ui/core/IconButton'
import Modal from '~/components/Modal'
import Hairline from '~/components/layout/Hairline'
const TitleSection = styled.div`
display: flex;
justify-content: space-between;
margin: 10px 20px;
`
const BodySection = styled.div`
padding: 10px 20px;
max-height: 460px;
overflow-y: auto;
`
const FooterSection = styled.div`
margin: 10px 20px;
`
const StyledClose = styled(Close)`
&& {
height: 35px;
width: 35px;
}
`
const useStyles = makeStyles(() =>
createStyles({
paper: {
height: 'auto',
position: 'static',
},
})
)
type Props = {
title: string,
body: React.Node,
footer: React.Node,
onClose: () => void,
}
const GenericModal = ({ title, body, footer, onClose }: Props) => {
const classes = useStyles()
return (
<Modal
title="GenericModal"
description="GenericModal"
handleClose={onClose}
paperClassName={classes.paper}
open
>
<TitleSection>
{title}
<IconButton onClick={onClose} disableRipple>
<StyledClose />
</IconButton>
</TitleSection>
<Hairline />
<BodySection>{body}</BodySection>
{footer && (
<>
<Hairline />
<FooterSection>{footer}</FooterSection>
</>
)}
</Modal>
)
}
export default GenericModal

View File

@ -0,0 +1,3 @@
// @flow
export { default as GenericModal } from './GenericModal'
export * from './utils'

View File

@ -0,0 +1,53 @@
// @flow
import React from 'react'
import styled from 'styled-components'
import Paragraph from '~/components/layout/Paragraph'
import Button from '~/components/layout/Button'
import { lg } from '~/theme/variables'
const StyledParagraph = styled(Paragraph)`
&& {
font-size: ${lg};
}
`
export const ModalTitle = ({ title }: { title: string }) => {
return (
<StyledParagraph weight="bolder" noMargin>
{title}
</StyledParagraph>
)
}
const FooterWrapper = styled.div`
display: flex;
justify-content: space-around;
`
export const ModalFooterConfirmation = ({
okText,
cancelText,
handleOk,
handleCancel,
}: {
okText: string,
cancelText: string,
handleOk: () => void,
handleCancel: () => void,
}) => {
return (
<FooterWrapper>
<Button minWidth={130} onClick={handleCancel}>
{cancelText}
</Button>
<Button
color="primary"
minWidth={130}
onClick={handleOk}
variant="contained"
>
{okText}
</Button>
</FooterWrapper>
)
}