Merge pull request #39 from andrerfneves/feature/new-round-pixel-perfecting
Feature/new round pixel perfecting
This commit is contained in:
commit
eea3510867
Binary file not shown.
After Width: | Height: | Size: 33 KiB |
|
@ -57,12 +57,19 @@ const Secondary = styled(DefaultButton)`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const Icon = styled.img`
|
||||||
|
height: 9px;
|
||||||
|
width: 12px;
|
||||||
|
margin-right: 10px;
|
||||||
|
`;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
label: string,
|
label: string,
|
||||||
onClick?: () => void,
|
onClick?: () => void,
|
||||||
to?: string,
|
to?: string,
|
||||||
variant?: 'primary' | 'secondary',
|
variant?: 'primary' | 'secondary',
|
||||||
disabled?: boolean,
|
disabled?: boolean,
|
||||||
|
icon?: string,
|
||||||
className?: string,
|
className?: string,
|
||||||
isLoading?: boolean,
|
isLoading?: boolean,
|
||||||
};
|
};
|
||||||
|
@ -73,25 +80,41 @@ export const Button = ({
|
||||||
to,
|
to,
|
||||||
variant,
|
variant,
|
||||||
disabled,
|
disabled,
|
||||||
|
icon,
|
||||||
className,
|
className,
|
||||||
isLoading,
|
isLoading,
|
||||||
}: Props) => {
|
}: Props) => {
|
||||||
if (to && onClick) throw new Error('Should define either "to" or "onClick"');
|
if (to && onClick) throw new Error('Should define either "to" or "onClick"');
|
||||||
|
|
||||||
const props = { onClick, disabled: disabled || isLoading, className };
|
const props = {
|
||||||
|
onClick, disabled: disabled || isLoading, icon: null, className,
|
||||||
|
};
|
||||||
const buttonLabel = isLoading ? 'Loading...' : label;
|
const buttonLabel = isLoading ? 'Loading...' : label;
|
||||||
|
|
||||||
const component = variant === 'primary' ? (
|
const component = variant === 'primary' ? (
|
||||||
<Primary {...props}>{buttonLabel}</Primary>
|
<Primary {...props}>
|
||||||
|
{icon
|
||||||
|
? <Icon src={icon} />
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
{buttonLabel}
|
||||||
|
</Primary>
|
||||||
) : (
|
) : (
|
||||||
<Secondary {...props}>{buttonLabel}</Secondary>
|
<Secondary {...props}>
|
||||||
|
{icon
|
||||||
|
? <Icon src={icon} />
|
||||||
|
: null
|
||||||
|
}
|
||||||
|
{buttonLabel}
|
||||||
|
</Secondary>
|
||||||
);
|
);
|
||||||
|
|
||||||
return to ? <Link to={String(to)}>{component}</Link> : component;
|
return to ? <Link to={String(to)}>{component}</Link> : component;
|
||||||
};
|
};
|
||||||
|
|
||||||
Button.defaultProps = {
|
Button.defaultProps = {
|
||||||
to: null,
|
to: '',
|
||||||
|
icon: null,
|
||||||
variant: 'primary',
|
variant: 'primary',
|
||||||
onClick: null,
|
onClick: null,
|
||||||
disabled: false,
|
disabled: false,
|
||||||
|
|
|
@ -9,6 +9,8 @@ import ClickOutside from 'react-click-outside';
|
||||||
|
|
||||||
import { TextComponent } from './text';
|
import { TextComponent } from './text';
|
||||||
|
|
||||||
|
import truncateAddress from '../utils/truncateAddress';
|
||||||
|
|
||||||
/* eslint-disable max-len */
|
/* eslint-disable max-len */
|
||||||
const MenuWrapper = styled.div`
|
const MenuWrapper = styled.div`
|
||||||
background-image: ${props => `linear-gradient(to right, ${darken(
|
background-image: ${props => `linear-gradient(to right, ${darken(
|
||||||
|
@ -18,6 +20,7 @@ const MenuWrapper = styled.div`
|
||||||
border-radius: ${props => props.theme.boxBorderRadius};
|
border-radius: ${props => props.theme.boxBorderRadius};
|
||||||
margin-left: -10px;
|
margin-left: -10px;
|
||||||
max-width: 400px;
|
max-width: 400px;
|
||||||
|
overflow: hidden;
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const MenuItem = styled.button`
|
const MenuItem = styled.button`
|
||||||
|
@ -30,6 +33,7 @@ const MenuItem = styled.button`
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
|
overflow: hidden;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
|
|
||||||
|
@ -50,6 +54,18 @@ const MenuItem = styled.button`
|
||||||
}
|
}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
const OptionItem = styled(MenuItem)`
|
||||||
|
&:hover {
|
||||||
|
background-color: #F9D114;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Option = styled(TextComponent)`
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
`;
|
||||||
|
|
||||||
const PopoverWithStyle = styled(Popover)`
|
const PopoverWithStyle = styled(Popover)`
|
||||||
& > .Popover-tip {
|
& > .Popover-tip {
|
||||||
fill: ${props => props.theme.colors.activeItem};
|
fill: ${props => props.theme.colors.activeItem};
|
||||||
|
@ -60,6 +76,7 @@ type Props = {
|
||||||
renderTrigger: (toggleVisibility: () => void, isOpen: boolean) => Node,
|
renderTrigger: (toggleVisibility: () => void, isOpen: boolean) => Node,
|
||||||
options: Array<{ label: string, onClick: () => void }>,
|
options: Array<{ label: string, onClick: () => void }>,
|
||||||
label?: string | null,
|
label?: string | null,
|
||||||
|
truncate?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
type State = {
|
type State = {
|
||||||
|
@ -73,11 +90,14 @@ export class DropdownComponent extends Component<Props, State> {
|
||||||
|
|
||||||
static defaultProps = {
|
static defaultProps = {
|
||||||
label: null,
|
label: null,
|
||||||
|
truncate: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { isOpen } = this.state;
|
const { isOpen } = this.state;
|
||||||
const { label, options, renderTrigger } = this.props;
|
const {
|
||||||
|
label, options, truncate, renderTrigger,
|
||||||
|
} = this.props;
|
||||||
|
|
||||||
const body = [
|
const body = [
|
||||||
<ClickOutside
|
<ClickOutside
|
||||||
|
@ -90,9 +110,9 @@ export class DropdownComponent extends Component<Props, State> {
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)}
|
)}
|
||||||
{options.map(({ label: optionLabel, onClick }) => (
|
{options.map(({ label: optionLabel, onClick }) => (
|
||||||
<MenuItem onClick={onClick} key={optionLabel}>
|
<OptionItem onClick={onClick} key={optionLabel}>
|
||||||
<TextComponent value={optionLabel} />
|
<Option value={truncate ? truncateAddress(optionLabel) : optionLabel} />
|
||||||
</MenuItem>
|
</OptionItem>
|
||||||
))}
|
))}
|
||||||
</MenuWrapper>
|
</MenuWrapper>
|
||||||
</ClickOutside>,
|
</ClickOutside>,
|
||||||
|
|
|
@ -0,0 +1,103 @@
|
||||||
|
// @flow
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import styled from 'styled-components';
|
||||||
|
|
||||||
|
import { ColumnComponent } from './column';
|
||||||
|
import { Button } from './button';
|
||||||
|
import { QRCode } from './qrcode';
|
||||||
|
|
||||||
|
import truncateAddress from '../utils/truncateAddress';
|
||||||
|
|
||||||
|
import eyeIcon from '../assets/images/eye.png';
|
||||||
|
|
||||||
|
const AddressWrapper = styled.div`
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
background-color: #000;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 7px 13px;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
const Input = styled.input`
|
||||||
|
border-radius: ${props => props.theme.boxBorderRadius};
|
||||||
|
border: none;
|
||||||
|
background-color: ${props => props.theme.colors.inputBackground};
|
||||||
|
color: ${props => props.theme.colors.text};
|
||||||
|
padding: 15px;
|
||||||
|
width: 100%;
|
||||||
|
outline: none;
|
||||||
|
font-family: ${props => props.theme.fontFamily};
|
||||||
|
|
||||||
|
::placeholder {
|
||||||
|
opacity: 0.5;
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const QRCodeWrapper = styled.div`
|
||||||
|
align-items: center;
|
||||||
|
display: flex;
|
||||||
|
background-color: #000;
|
||||||
|
border-radius: 6px;
|
||||||
|
padding: 20px;
|
||||||
|
margin-top: 10px;
|
||||||
|
width: 100%;
|
||||||
|
`;
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
address: string,
|
||||||
|
};
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
isVisible: boolean,
|
||||||
|
};
|
||||||
|
|
||||||
|
export class WalletAddress extends Component<Props, State> {
|
||||||
|
state = {
|
||||||
|
isVisible: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
show = () => {
|
||||||
|
this.setState(
|
||||||
|
() => ({ isVisible: true }),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
hide = () => {
|
||||||
|
this.setState(
|
||||||
|
() => ({ isVisible: false }),
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const { address } = this.props;
|
||||||
|
const { isVisible } = this.state;
|
||||||
|
const toggleVisibility = isVisible ? this.hide : this.show;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ColumnComponent width='100%'>
|
||||||
|
<AddressWrapper>
|
||||||
|
<Input
|
||||||
|
value={isVisible ? address : truncateAddress(address)}
|
||||||
|
onChange={() => {}}
|
||||||
|
onFocus={event => event.currentTarget.select()}
|
||||||
|
/>
|
||||||
|
<Button
|
||||||
|
icon={eyeIcon}
|
||||||
|
label={`${isVisible ? 'Hide' : 'Show'} full address and QR Code`}
|
||||||
|
onClick={toggleVisibility}
|
||||||
|
variant='secondary'
|
||||||
|
/>
|
||||||
|
</AddressWrapper>
|
||||||
|
{isVisible
|
||||||
|
? (
|
||||||
|
<QRCodeWrapper>
|
||||||
|
<QRCode value={address} />
|
||||||
|
</QRCodeWrapper>
|
||||||
|
)
|
||||||
|
: null}
|
||||||
|
</ColumnComponent>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,28 @@
|
||||||
|
---
|
||||||
|
name: Wallet Address
|
||||||
|
---
|
||||||
|
|
||||||
|
import { Playground, PropsTable } from 'docz'
|
||||||
|
|
||||||
|
import { WalletAddress } from './wallet-address.js'
|
||||||
|
import { DoczWrapper } from '../theme.js'
|
||||||
|
|
||||||
|
# Wallet Address
|
||||||
|
|
||||||
|
## Properties
|
||||||
|
|
||||||
|
<PropsTable of={WalletAddress} />
|
||||||
|
|
||||||
|
## Basic usage
|
||||||
|
|
||||||
|
<Playground>
|
||||||
|
<DoczWrapper>
|
||||||
|
{() => (
|
||||||
|
<div style={{ width: '700px' }}>
|
||||||
|
<WalletAddress
|
||||||
|
address='t14oHp2v54vfmdgQ3v3SNuQga8JKHTNi2a1'
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</DoczWrapper>
|
||||||
|
</Playground>
|
|
@ -7,11 +7,11 @@ import { normalize } from 'polished'; // eslint-disable-line
|
||||||
|
|
||||||
import { DARK } from './constants/themes';
|
import { DARK } from './constants/themes';
|
||||||
|
|
||||||
const darkOne = '#7B00DD';
|
const darkOne = '#F4B728';
|
||||||
const lightOne = '#ffffff';
|
const lightOne = '#ffffff';
|
||||||
const brandOne = '#000';
|
const brandOne = '#000';
|
||||||
const brandTwo = '#3B3B3F';
|
const brandTwo = '#3B3B3F';
|
||||||
const activeItem = '#F5CB00';
|
const activeItem = '#F4B728';
|
||||||
const text = '#FFF';
|
const text = '#FFF';
|
||||||
const cardBackgroundColor = '#000';
|
const cardBackgroundColor = '#000';
|
||||||
const sidebarLogoGradientBegin = '#F4B728';
|
const sidebarLogoGradientBegin = '#F4B728';
|
||||||
|
|
|
@ -3,10 +3,8 @@ import React from 'react';
|
||||||
import styled from 'styled-components';
|
import styled from 'styled-components';
|
||||||
|
|
||||||
import { InputLabelComponent } from '../components/input-label';
|
import { InputLabelComponent } from '../components/input-label';
|
||||||
import { InputComponent } from '../components/input';
|
|
||||||
import { QRCode } from '../components/qrcode';
|
|
||||||
import { RowComponent } from '../components/row';
|
import { RowComponent } from '../components/row';
|
||||||
import { ColumnComponent } from '../components/column';
|
import { WalletAddress } from '../components/wallet-address';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
addresses: Array<string>,
|
addresses: Array<string>,
|
||||||
|
@ -27,21 +25,14 @@ const Label = styled(InputLabelComponent)`
|
||||||
|
|
||||||
export const ReceiveView = ({ addresses }: Props) => (
|
export const ReceiveView = ({ addresses }: Props) => (
|
||||||
<Wrapper>
|
<Wrapper>
|
||||||
|
<Label value='Addresses: ' />
|
||||||
{(addresses || []).map(address => (
|
{(addresses || []).map(address => (
|
||||||
<Row
|
<Row
|
||||||
key={address}
|
key={address}
|
||||||
alignItems='center'
|
alignItems='center'
|
||||||
justifyContent='space-between'
|
justifyContent='space-between'
|
||||||
>
|
>
|
||||||
<ColumnComponent width='85%'>
|
<WalletAddress address={address} />
|
||||||
<Label value='Your Address: ' />
|
|
||||||
<InputComponent
|
|
||||||
value={address}
|
|
||||||
onChange={() => {}}
|
|
||||||
onFocus={event => event.currentTarget.select()}
|
|
||||||
/>
|
|
||||||
</ColumnComponent>
|
|
||||||
<QRCode value={address} />
|
|
||||||
</Row>
|
</Row>
|
||||||
))}
|
))}
|
||||||
</Wrapper>
|
</Wrapper>
|
||||||
|
|
Loading…
Reference in New Issue