Merge pull request #66 from andrerfneves/feature/flow-coverage

Feature/flow coverage
This commit is contained in:
George Lima 2019-02-08 00:50:55 -02:00 committed by GitHub
commit 9bb5d4ead6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 298 additions and 287 deletions

View File

@ -1,6 +1,7 @@
[ignore]
.*/node_modules/polished/.*
./__tests__/**.js
./flow-typed/npm/styled-components_v4.x.x.js
[include]

View File

@ -3,10 +3,6 @@
import React, { type ElementProps } from 'react';
import styled from 'styled-components';
import { Link } from 'react-router-dom';
/* eslint-disable import/no-extraneous-dependencies */
/* eslint-disable max-len */
// $FlowFixMe
import { darken } from 'polished';
const DefaultButton = styled.button`
align-items: center;
@ -14,13 +10,13 @@ const DefaultButton = styled.button`
justify-content: center;
padding: 10px 30px;
font-family: ${props => props.theme.fontFamily};
font-weight: ${props => props.theme.fontWeight.bold};
font-weight: ${props => String(props.theme.fontWeight.bold)};
font-size: ${props => `${props.theme.fontSize.regular}em`};
cursor: pointer;
outline: none;
min-width: 100px;
border-radius: 100px;
transition: background-color 0.1s ${props => props.theme.colors.transitionEase};
transition: background-color 0.1s ${props => props.theme.transitionEase};
`;
const Primary = styled(DefaultButton)`
@ -29,7 +25,7 @@ const Primary = styled(DefaultButton)`
border: none;
&:hover {
background-color: ${props => darken(0.1, props.theme.colors.primary(props))};
opacity: 0.9;
}
&:disabled {
@ -101,18 +97,12 @@ export const Button = ({
const buttonLabel = isLoading ? 'Loading...' : label;
const component = variant === 'primary' ? (
<Primary
{...props}
data-testid='PrimaryButton'
>
<Primary {...props} data-testid='PrimaryButton'>
{icon ? <Icon src={icon} /> : null}
{buttonLabel}
</Primary>
) : (
<Secondary
{...props}
data-testid='SecondaryButton'
>
<Secondary {...props} data-testid='SecondaryButton'>
{icon ? <Icon src={icon} /> : null}
{buttonLabel}
</Secondary>

View File

@ -3,12 +3,19 @@
import React, { type Node, type ElementProps } from 'react';
import styled from 'styled-components';
type FlexProps =
| {
alignItems: string,
justifyContent: string,
width: string,
}
| Object;
const Flex = styled.div`
display: flex;
flex-direction: column;
align-items: ${props => props.alignItems};
justify-content: ${props => props.justifyContent};
${props => props.width && `width: ${props.width};`}
align-items: ${(props: FlexProps) => props.alignItems};
justify-content: ${(props: FlexProps) => props.justifyContent};
${(props: FlexProps) => props.width && `width: ${props.width};`}
`;
type Props = {

View File

@ -12,7 +12,7 @@ import CloseIcon from '../assets/images/close_icon.svg';
const Wrapper = styled.div`
display: flex;
width: ${props => `${props.width}px`};
width: ${(props: PropsWithTheme<{ width: number }>) => `${String(props.width)}px`};
background-color: ${props => props.theme.colors.background};
flex-direction: column;
align-items: center;
@ -83,16 +83,10 @@ export const ConfirmDialogComponent = ({
{toggle => (
<Wrapper width={Number(width)}>
<CloseIconWrapper>
<CloseIconImg
src={CloseIcon}
onClick={handleClose(toggle)}
/>
<CloseIconImg src={CloseIcon} onClick={handleClose(toggle)} />
</CloseIconWrapper>
<TitleWrapper>
<TextComponent
value={title}
align='center'
/>
<TextComponent value={title} align='center' />
</TitleWrapper>
<Divider opacity={0.3} />
{children(handleClose(toggle))}

View File

@ -2,11 +2,18 @@
import styled from 'styled-components';
type Props = PropsWithTheme<{
color: ?string,
opacity: number,
marginBottom: string,
marginTop: string,
}>;
export const Divider = styled.div`
width: 100%;
height: 1px;
background-color: ${props => props.color || props.theme.colors.text};
opacity: ${props => props.opacity || 1};
margin-bottom: ${props => props.marginBottom || 0};
margin-top: ${props => props.marginTop || 0};
background-color: ${(props: Props) => props.color || props.theme.colors.text};
opacity: ${(props: Props) => String(props.opacity || 1)};
margin-bottom: ${(props: Props) => props.marginBottom || '0'};
margin-top: ${(props: Props) => props.marginTop || '0'};
`;

View File

@ -100,30 +100,16 @@ export class DropdownComponent extends Component<Props, State> {
} = this.props;
const body = [
<ClickOutside
onClickOutside={() => this.setState(() => ({ isOpen: false }))}
>
<ClickOutside onClickOutside={() => this.setState(() => ({ isOpen: false }))}>
<MenuWrapper>
{label && (
<MenuItem
disabled
isGroupLabel
>
<TextComponent
value={label}
isBold
/>
<MenuItem disabled isGroupLabel>
<TextComponent value={label} isBold />
</MenuItem>
)}
{options.map(({ label: optionLabel, onClick }) => (
<OptionItem
onClick={onClick}
key={optionLabel}
data-testid='DropdownOption'
>
<Option
value={truncate ? truncateAddress(optionLabel) : optionLabel}
/>
<OptionItem onClick={onClick} key={optionLabel} data-testid='DropdownOption'>
<Option value={truncate ? truncateAddress(optionLabel) : optionLabel} />
</OptionItem>
))}
</MenuWrapper>
@ -138,9 +124,12 @@ export class DropdownComponent extends Component<Props, State> {
tipSize={7}
body={body}
>
{renderTrigger(() => this.setState(state => ({
isOpen: !state.isOpen,
})), isOpen)}
{renderTrigger(
() => this.setState(state => ({
isOpen: !state.isOpen,
})),
isOpen,
)}
</PopoverWithStyle>
);
}

View File

@ -79,21 +79,17 @@ export class ErrorModalComponent extends PureComponent<Props> {
render() {
const { isVisible, message, onRequestClose } = this.props;
return !isVisible ? null : createPortal(
<ModalWrapper id='error-modal-portal-wrapper'>
<ChildrenWrapper>
<ErrorImage
src={ErrorIcon}
alt='Error Icon'
/>
<Message value={message} />
<Button
label='Ok!'
onClick={onRequestClose}
/>
</ChildrenWrapper>
</ModalWrapper>,
this.element,
);
return !isVisible
? null
: createPortal(
<ModalWrapper id='error-modal-portal-wrapper'>
<ChildrenWrapper>
<ErrorImage src={ErrorIcon} alt='Error Icon' />
<Message value={message} />
<Button label='Ok!' onClick={onRequestClose} />
</ChildrenWrapper>
</ModalWrapper>,
this.element,
);
}
}

View File

@ -54,7 +54,7 @@ const Title = styled(TextComponent)`
margin-bottom: 10px;
text-transform: capitalize;
letter-spacing: 0.25px;
font-weight: ${props => props.theme.fontWeight.bold};
font-weight: ${props => String(props.theme.fontWeight.bold)};
`;
type Props = {
@ -69,15 +69,9 @@ export const HeaderComponent = ({ title }: Props) => (
<ZcashLogo />
</LogoWrapper>
<TitleWrapper>
<TitleRow
alignItems='center'
justifyContent='space-around'
>
<TitleRow alignItems='center' justifyContent='space-around'>
<Title value={title} />
<Status
type='syncing'
progress={0}
/>
<Status type='syncing' progress={0} />
</TitleRow>
<Divider opacity={0.1} />
</TitleWrapper>

View File

@ -4,7 +4,11 @@ import styled from 'styled-components';
import { TextComponent } from './text';
type Props = PropsWithTheme<{
marginTop: string,
}>;
export const InputLabelComponent = styled(TextComponent)`
margin: ${props => props.marginTop || '20px'} 0 8.5px 0;
font-weight: ${props => props.theme.fontWeight.bold};
margin: ${(props: Props) => props.marginTop || '20px'} 0 8.5px 0;
font-weight: ${(props: Props) => String(props.theme.fontWeight.bold)};
`;

View File

@ -1,20 +1,40 @@
// @flow
/* eslint-disable max-len */
import React, { type Element } from 'react';
import styled from 'styled-components';
import theme from '../theme';
const getDefaultStyles = t => styled[t]`
border-radius: ${props => props.theme.boxBorderRadius};
type Props = {
inputType?: 'input' | 'textarea',
value: string,
onChange?: string => void,
onFocus?: (SyntheticFocusEvent<HTMLInputElement>) => void,
rows?: number,
disabled?: boolean,
type?: string,
step?: number,
name?: string,
renderRight?: () => Element<*> | null,
bgColor?: string,
};
type DefaultStylesProps = PropsWithTheme<{
bgColor: ?string,
withRightElement: boolean,
}>;
// $FlowFixMe
const getDefaultStyles: ($PropertyType<Props, 'inputType'>) => Element<*> = t => styled[t]`
border-radius: ${(props: DefaultStylesProps) => props.theme.boxBorderRadius};
border: none;
background-color: ${props => props.bgColor || props.theme.colors.inputBackground};
color: ${props => props.theme.colors.text};
background-color: ${(props: DefaultStylesProps) => props.bgColor || props.theme.colors.inputBackground};
color: ${(props: DefaultStylesProps) => props.theme.colors.text};
padding: 15px;
padding-right: ${props => (props.withRightElement ? '85px' : '15px')};
padding-right: ${(props: DefaultStylesProps) => (props.withRightElement ? '85px' : '15px')};
width: 100%;
outline: none;
font-family: ${props => props.theme.fontFamily};
font-family: ${(props: DefaultStylesProps) => props.theme.fontFamily};
::placeholder {
opacity: 0.5;
@ -34,20 +54,6 @@ const RightElement = styled.div`
const Input = getDefaultStyles('input');
const Textarea = getDefaultStyles('textarea');
type Props = {
inputType?: 'input' | 'textarea',
value: string,
onChange?: string => void,
onFocus?: (SyntheticFocusEvent<HTMLInputElement>) => void,
rows?: number,
disabled?: boolean,
type?: string,
step?: number,
name?: string,
renderRight?: () => Element<*> | null,
bgColor?: string,
};
export const InputComponent = ({
inputType,
bgColor,
@ -67,7 +73,12 @@ export const InputComponent = ({
/>
),
textarea: () => (
<Textarea onChange={evt => onChange(evt.target.value)} bgColor={bgColor} data-testid='Textarea' {...props} />
<Textarea
onChange={evt => onChange(evt.target.value)}
bgColor={bgColor}
data-testid='Textarea'
{...props}
/>
),
};

View File

@ -58,7 +58,7 @@ export class LoadingScreen extends PureComponent<Props, State> {
this.setState(() => ({ start: true }));
}, TIME_DELAY_ANIM);
ipcRenderer.on('zcashd-params-download', (event, message) => {
ipcRenderer.on('zcashd-params-download', (event: Object, message: string) => {
this.setState(() => ({ message }));
});
}
@ -85,7 +85,7 @@ export class LoadingScreen extends PureComponent<Props, State> {
opacity: 0,
}}
>
{() => props => (
{() => (props: Object) => (
<animated.div
id='loading-screen'
style={{
@ -97,10 +97,7 @@ export class LoadingScreen extends PureComponent<Props, State> {
}}
>
<CircleWrapper>
<Logo
src={zcashLogo}
alt='Zcash Logo'
/>
<Logo src={zcashLogo} alt='Zcash Logo' />
<CircleProgressComponent
progress={progress}
s // TODO: check if this has any effect

View File

@ -4,11 +4,17 @@ import React from 'react';
import styled from 'styled-components';
import type { Node, ElementProps } from 'react';
type FlexProps =
| {
alignItems: string,
justifyContent: string,
}
| Object;
const Flex = styled.div`
display: flex;
flex-direction: row;
align-items: ${props => props.alignItems};
justify-content: ${props => props.justifyContent};
align-items: ${(props: FlexProps) => props.alignItems};
justify-content: ${(props: FlexProps) => props.justifyContent};
`;
type Props = {
@ -20,7 +26,7 @@ type Props = {
};
export const RowComponent = ({ children, ...props }: Props) => (
<Flex {...props}>{React.Children.map(children, ch => ch)}</Flex>
<Flex {...props}>{React.Children.map(children, (ch: Node) => ch)}</Flex>
);
RowComponent.defaultProps = {

View File

@ -10,29 +10,38 @@ import ChevronDown from '../assets/images/chevron-down.svg';
import theme from '../theme';
/* eslint-disable max-len */
type SelectWrapperProps = PropsWithTheme<{
bgColor: ?string,
isOpen: boolean,
placement: string,
}>;
const SelectWrapper = styled.div`
align-items: center;
display: flex;
flex-direction: row;
border-radius: ${props => props.theme.boxBorderRadius};
border-radius: ${(props: SelectWrapperProps) => props.theme.boxBorderRadius};
border: none;
background-color: ${props => props.bgColor || props.theme.colors.inputBackground};
color: ${props => props.theme.colors.text};
background-color: ${(props: SelectWrapperProps) => props.bgColor || props.theme.colors.inputBackground};
color: ${(props: SelectWrapperProps) => props.theme.colors.text};
width: 100%;
outline: none;
font-family: ${props => props.theme.fontFamily};
font-family: ${(props: SelectWrapperProps) => props.theme.fontFamily};
cursor: pointer;
position: relative;
${props => props.isOpen
&& `border-${props.placement}-left-radius: 0; border-${props.placement}-right-radius: 0;`}
${(props: SelectWrapperProps) => (props.isOpen
? `border-${String(props.placement)}-left-radius: 0; border-${String(
props.placement,
)}-right-radius: 0;`
: '')}
`;
/* eslint-enable max-len */
const ValueWrapper = styled.div`
width: 95%;
padding: 13px;
opacity: ${props => (props.hasValue ? '1' : '0.2')};
opacity: ${(props: PropsWithTheme<{ hasValue: boolean }>) => (props.hasValue ? '1' : '0.2')};
text-transform: capitalize;
white-space: nowrap;
overflow: hidden;
@ -53,10 +62,10 @@ const SelectMenuButton = styled.button`
padding: 3px 7px;
outline: none;
background-color: transparent;
border: 1px solid ${props => (props.isOpen ? props.theme.colors.primary : '#29292D')};
border: 1px solid
${(props: PropsWithTheme<{ isOpen: boolean }>) => (props.isOpen ? props.theme.colors.primary : '#29292D')};
border-radius: 100%;
`;
/* eslint-enable max-len */
const Icon = styled.img`
width: 10px;
@ -68,7 +77,7 @@ const OptionsWrapper = styled.div`
flex-direction: column;
position: absolute;
width: 100%;
${props => `${props.placement}: ${`-${props.optionsAmount * 40}px`}`};
${(props: PropsWithTheme<{ placement: string, optionsAmount: number }>) => `${String(props.placement)}: ${`-${String((props.optionsAmount || 0) * 40)}px`}`};
overflow-y: auto;
`;

View File

@ -18,12 +18,13 @@ const Wrapper = styled.div`
`;
/* eslint-disable max-len */
type StyledLinkProps = PropsWithTheme<{ isActive: boolean }>;
const StyledLink = styled.a`
color: ${props => (props.isActive ? props.theme.colors.sidebarItemActive : props.theme.colors.sidebarItem)};
font-size: ${props => `${props.theme.fontSize.regular}em`};
color: ${(props: StyledLinkProps) => (props.isActive ? props.theme.colors.sidebarItemActive : props.theme.colors.sidebarItem)};
font-size: ${(props: StyledLinkProps) => `${props.theme.fontSize.regular}em`};
text-decoration: none;
font-weight: ${props => props.theme.fontWeight.bold};
background-color: ${props => (props.isActive ? `${props.theme.colors.sidebarHoveredItem}` : 'transparent')};
font-weight: ${(props: StyledLinkProps) => String(props.theme.fontWeight.bold)};
background-color: ${(props: StyledLinkProps) => (props.isActive ? `${props.theme.colors.sidebarHoveredItem}` : 'transparent')};
letter-spacing: 0.25px;
padding: 25px 20px;
height: 35px;
@ -31,13 +32,13 @@ const StyledLink = styled.a`
display: flex;
align-items: center;
outline: none;
border-right: ${props => (props.isActive ? `3px solid ${props.theme.colors.sidebarItemActive}` : 'none')};
border-right: ${(props: StyledLinkProps) => (props.isActive ? `3px solid ${props.theme.colors.sidebarItemActive}` : 'none')};
cursor: pointer;
transition: all 0.03s ${props => props.theme.colors.transitionEase};
transition: all 0.03s ${(props: StyledLinkProps) => props.theme.transitionEase};
&:hover {
color: ${props => (props.isActive ? props.theme.colors.sidebarItemActive : '#ddd')}
background-color: ${props => props.theme.colors.sidebarHoveredItem};
color: ${(props: StyledLinkProps) => (props.isActive ? props.theme.colors.sidebarItemActive : '#ddd')}
background-color: ${(props: StyledLinkProps) => props.theme.colors.sidebarHoveredItem};
}
`;
@ -47,7 +48,7 @@ const Icon = styled.img`
margin-right: 13px;
${StyledLink}:hover & {
filter: ${props => (props.isActive ? 'none' : 'brightness(300%)')};
filter: ${(props: StyledLinkProps) => (props.isActive ? 'none' : 'brightness(300%)')};
}
`;
@ -74,11 +75,7 @@ export const SidebarComponent = ({ options, location, history }: Props) => (
key={item.route}
onClick={() => (isActive ? {} : history.push(item.route))}
>
<Icon
isActive={isActive}
src={item.icon(isActive)}
Alt={`${item.route}`}
/>
<Icon isActive={isActive} src={item.icon(isActive)} Alt={`${item.route}`} />
{item.label}
</StyledLink>
);

View File

@ -34,12 +34,14 @@ const Icon = styled.img`
height: 12px;
margin-right: 8px;
animation: 2s linear infinite;
animation-name: ${props => (props.animated ? rotate : 'none')};
animation-name: ${/** $FlowFixMe */
(props: PropsWithTheme<{ animated: boolean }>) => (props.animated ? rotate : 'none')};
`;
const StatusPillLabel = styled(TextComponent)`
color: ${props => props.theme.colors.statusPillLabel};
font-weight: ${props => props.theme.fontWeight.bold};
font-weight: ${props => String(props.theme.fontWeight.bold)};
text-transform: uppercase;
font-size: 10px;
padding-top: 1px;
@ -106,7 +108,7 @@ export class StatusPill extends Component<Props, State> {
type, icon, progress, isSyncing,
} = this.state;
const showPercent = isSyncing ? `(${progress.toFixed(2)}%)` : '';
const typeText = (type === 'ready') ? 'Synced' : type;
const typeText = type === 'ready' ? 'Synced' : type;
return (
<Wrapper id='status-pill'>

View File

@ -7,16 +7,6 @@ import type { ElementProps } from 'react';
import theme from '../theme';
const Text = styled.p`
font-family: ${props => props.theme.fontFamily};
font-size: ${props => props.size};
color: ${props => props.color || props.theme.colors.text};
margin: 0;
padding: 0;
font-weight: ${props => (props.isBold ? props.theme.fontWeight.bold : props.theme.fontWeight.default)};
text-align: ${props => props.align};
`;
export type Props = {
...ElementProps<'p'>,
value: string,
@ -27,6 +17,16 @@ export type Props = {
align?: string,
};
const Text = styled.p`
font-family: ${(props: PropsWithTheme<Props>) => props.theme.fontFamily};
font-size: ${(props: PropsWithTheme<Props>) => String(props.size)};
color: ${(props: PropsWithTheme<Props>) => props.color || props.theme.colors.text};
margin: 0;
padding: 0;
font-weight: ${(props: PropsWithTheme<Props>) => String(props.isBold ? props.theme.fontWeight.bold : props.theme.fontWeight.default)};
text-align: ${(props: PropsWithTheme<Props>) => props.align || 'left'};
`;
export const TextComponent = ({
value, isBold, color, className, size, align, id,
}: Props) => (

View File

@ -25,7 +25,7 @@ const Day = styled(TextComponent)`
text-transform: uppercase;
color: ${props => props.theme.colors.transactionsDate};
font-size: ${props => `${props.theme.fontSize.regular * 0.9}em`};
font-weight: ${props => props.theme.fontWeight.bold};
font-weight: ${props => String(props.theme.fontWeight.bold)};
margin-bottom: 5px;
`;
@ -35,31 +35,25 @@ type Props = {
zecPrice: number,
};
export const TransactionDailyComponent = ({
transactionsDate,
transactions,
zecPrice,
}: Props) => (
export const TransactionDailyComponent = ({ transactionsDate, transactions, zecPrice }: Props) => (
<Wrapper data-testid='TransactionsDaily'>
<Day value={transactionsDate} />
<TransactionsWrapper>
{transactions.map(
({
date, type, address, amount, transactionId,
}, idx) => (
<Fragment key={`${address}-${type}-${amount}-${date}`}>
<TransactionItemComponent
transactionId={transactionId}
type={type}
date={date}
address={address || ''}
amount={amount}
zecPrice={zecPrice}
/>
{idx < transactions.length - 1 && <Divider />}
</Fragment>
),
)}
{transactions.map(({
date, type, address, amount, transactionId,
}, idx) => (
<Fragment key={`${address}-${type}-${amount}-${date}`}>
<TransactionItemComponent
transactionId={transactionId}
type={type}
date={date}
address={address || ''}
amount={amount}
zecPrice={zecPrice}
/>
{idx < transactions.length - 1 && <Divider />}
</Fragment>
))}
</TransactionsWrapper>
</Wrapper>
);

View File

@ -91,7 +91,7 @@ const Divider = styled.div`
`;
const Label = styled(TextComponent)`
font-weight: ${props => props.theme.fontWeight.bold};
font-weight: ${props => String(props.theme.fontWeight.bold)};
color: ${props => props.theme.colors.transactionsDetailsLabel};
margin-bottom: 5px;
letter-spacing: 0.25px;
@ -144,22 +144,13 @@ export const TransactionDetailsComponent = ({
return (
<Wrapper>
<CloseIconWrapper>
<CloseIconImg
src={CloseIcon}
onClick={handleClose}
/>
<CloseIconImg src={CloseIcon} onClick={handleClose} />
</CloseIconWrapper>
<TitleWrapper>
<TextComponent
value='Transaction Details'
align='center'
/>
<TextComponent value='Transaction Details' align='center' />
</TitleWrapper>
<DetailsWrapper>
<Icon
src={isReceived ? ReceivedIcon : SentIcon}
alt='Transaction Type Icon'
/>
<Icon src={isReceived ? ReceivedIcon : SentIcon} alt='Transaction Type Icon' />
<TextComponent
isBold
size={2.625}
@ -181,16 +172,10 @@ export const TransactionDetailsComponent = ({
<InfoRow>
<ColumnComponent>
<Label value='DATE' />
<TextComponent
value={dateFns.format(new Date(date), 'MMMM D, YYYY HH:MMA')}
/>
<TextComponent value={dateFns.format(new Date(date), 'MMMM D, YYYY HH:MMA')} />
</ColumnComponent>
<ColumnComponent>
<TextComponent
value='FEES'
isBold
color={theme.colors.transactionsDetailsLabel}
/>
<TextComponent value='FEES' isBold color={theme.colors.transactionsDetailsLabel} />
<TextComponent
value={formatNumber({
value: new BigNumber(amount).times(0.1).toNumber(),
@ -203,9 +188,7 @@ export const TransactionDetailsComponent = ({
<InfoRow>
<ColumnComponent width='100%'>
<Label value='TRANSACTION ID' />
<TransactionId
onClick={() => openExternal(ZCASH_EXPLORER_BASE_URL + transactionId)}
>
<TransactionId onClick={() => openExternal(ZCASH_EXPLORER_BASE_URL + transactionId)}>
<Ellipsis value={transactionId} />
</TransactionId>
</ColumnComponent>

View File

@ -35,7 +35,7 @@ const Icon = styled.img`
/* eslint-disable max-len */
const TransactionTypeLabel = styled(TextComponent)`
color: ${props => (props.isReceived ? props.theme.colors.transactionReceived : props.theme.colors.transactionSent)};
color: ${(props: PropsWithTheme<{ isReceived: boolean }>) => (props.isReceived ? props.theme.colors.transactionReceived : props.theme.colors.transactionSent)};
text-transform: capitalize;
`;
/* eslint-enable max-len */
@ -43,7 +43,7 @@ const TransactionTypeLabel = styled(TextComponent)`
const TransactionAddress = styled(TextComponent)`
color: #a7a7a7;
${Wrapper}:hover & {
${String(Wrapper)}:hover & {
color: #fff;
}
`;
@ -98,16 +98,9 @@ export const TransactionItemComponent = ({
>
<RowComponent alignItems='center'>
<RowComponent alignItems='center'>
<Icon
src={isReceived ? ReceivedIcon : SentIcon}
alt='Transaction Type Icon'
/>
<Icon src={isReceived ? ReceivedIcon : SentIcon} alt='Transaction Type Icon' />
<TransactionColumn>
<TransactionTypeLabel
isReceived={isReceived}
value={type}
isBold
/>
<TransactionTypeLabel isReceived={isReceived} value={type} isBold />
<TransactionTime value={transactionTime} />
</TransactionColumn>
</RowComponent>
@ -119,10 +112,7 @@ export const TransactionItemComponent = ({
value={transactionValueInZec}
color={isReceived ? theme.colors.transactionReceived : theme.colors.transactionSent}
/>
<TextComponent
value={transactionValueInUsd}
color={theme.colors.inactiveItem}
/>
<TextComponent value={transactionValueInUsd} color={theme.colors.inactiveItem} />
</ColumnComponent>
</Wrapper>
)}

View File

@ -72,7 +72,7 @@ export class WalletAddress extends Component<Props, State> {
<AddressWrapper>
<Input
value={isVisible ? address : truncateAddress(address)}
onChange={() => { }}
onChange={() => {}}
onFocus={event => event.currentTarget.select()}
/>
<Button

View File

@ -39,7 +39,7 @@ const Label = styled(TextComponent)`
const USDValue = styled(TextComponent)`
opacity: 0.5;
font-weight: ${props => props.theme.fontWeight.light};
font-weight: ${props => String(props.theme.fontWeight.light)};
`;
const ShieldedValue = styled(Label)`
@ -71,34 +71,22 @@ export const WalletSummaryComponent = ({
</ValueBox>
<RowComponent>
<ValueBox>
<ShieldedValue
value='&#9679; SHIELDED'
isBold
size={theme.fontSize.small}
/>
<ShieldedValue value='&#9679; SHIELDED' isBold size={theme.fontSize.small} />
<TextComponent
value={`ZEC ${formatNumber({ value: shielded })}`}
isBold
size={theme.fontSize.medium}
/>
<USDValue
value={`USD $${formatNumber({ value: shielded * zecPrice })}`}
/>
<USDValue value={`USD $${formatNumber({ value: shielded * zecPrice })}`} />
</ValueBox>
<ValueBox>
<Label
value='&#9679; TRANSPARENT'
isBold
size={theme.fontSize.small}
/>
<Label value='&#9679; TRANSPARENT' isBold size={theme.fontSize.small} />
<TextComponent
value={`ZEC ${formatNumber({ value: transparent })}`}
isBold
size={theme.fontSize.medium}
/>
<USDValue
value={`USD $${formatNumber({ value: transparent * zecPrice })}`}
/>
<USDValue value={`USD $${formatNumber({ value: transparent * zecPrice })}`} />
</ValueBox>
</RowComponent>
</Wrapper>

View File

@ -1,6 +1,6 @@
// @flow
import React, { Fragment } from 'react';
import React, { Fragment, type Node } from 'react';
import theme from 'styled-theming';
import { ThemeProvider, createGlobalStyle } from 'styled-components';
// $FlowFixMe
@ -31,7 +31,7 @@ const selectButtonShadow = 'rgba(238,201,76,0.65)';
const statusPillLabel = '#727272';
const transactionsDetailsLabel = transactionsDate;
const appTheme = {
const appTheme: AppTheme = {
mode: DARK,
fontFamily: 'Roboto',
fontWeight: {
@ -46,10 +46,12 @@ const appTheme = {
small: 0.667,
},
colors: {
// $FlowFixMe
primary: theme('mode', {
light: lightOne,
dark: darkOne,
}),
// $FlowFixMe
secondary: theme('mode', {
light: darkOne,
dark: lightOne,
@ -95,9 +97,7 @@ export const GlobalStyle = createGlobalStyle`
}
`;
/* eslint-disable react/prop-types */
// $FlowFixMe
export const DoczWrapper = ({ children }) => (
export const DoczWrapper = ({ children }: { children: () => Node<*> }) => (
<ThemeProvider theme={appTheme}>
<Fragment>
<GlobalStyle />

View File

@ -65,7 +65,7 @@ export class ConsoleView extends Component<Props, State> {
};
componentDidMount() {
ipcRenderer.on('zcashd-log', (event, message) => {
ipcRenderer.on('zcashd-log', (event: empty, message: string) => {
this.setState(() => ({ log: initialLog + message }));
});
}
@ -80,10 +80,7 @@ export class ConsoleView extends Component<Props, State> {
return (
<Wrapper id='console-wrapper'>
<Fragment>
<ConsoleImg
src={ConsoleSymbol}
alt='Zcashd'
/>
<ConsoleImg src={ConsoleSymbol} alt='Zcashd' />
{log.split('\n').map((item, idx) => (
<Fragment key={uuid()}>
<ConsoleText value={item} />

View File

@ -22,7 +22,7 @@ const Label = styled(InputLabelComponent)`
text-transform: uppercase;
color: ${props => props.theme.colors.transactionsDate};
font-size: ${props => `${props.theme.fontSize.regular * 0.9}em`};
font-weight: ${props => props.theme.fontWeight.bold};
font-weight: ${props => String(props.theme.fontWeight.bold)};
margin-bottom: 5px;
`;
@ -107,33 +107,16 @@ export class ReceiveView extends PureComponent<Props, State> {
<WalletAddress key={addr} address={addr} />
))}
<Row>
<ActionButton
onClick={this.toggleAdditionalOptions}
isActive={showAdditionalOptions}
>
<ActionIcon
isActive={showAdditionalOptions}
src={MenuIcon}
alt='More Options'
/>
<ActionButton onClick={this.toggleAdditionalOptions} isActive={showAdditionalOptions}>
<ActionIcon isActive={showAdditionalOptions} src={MenuIcon} alt='More Options' />
<TextComponent value={buttonText} />
</ActionButton>
<ActionButton
onClick={() => this.generateNewAddress('shielded')}
>
<ActionIcon
src={PlusIcon}
alt='New Shielded Address'
/>
<ActionButton onClick={() => this.generateNewAddress('shielded')}>
<ActionIcon src={PlusIcon} alt='New Shielded Address' />
<TextComponent value='New Shielded Address' />
</ActionButton>
<ActionButton
onClick={() => this.generateNewAddress('transparent')}
>
<ActionIcon
src={PlusIcon}
alt='New Transparent Address'
/>
<ActionButton onClick={() => this.generateNewAddress('transparent')}>
<ActionIcon src={PlusIcon} alt='New Transparent Address' />
<TextComponent value='New Transparent Address' />
</ActionButton>
</Row>
@ -150,8 +133,8 @@ export class ReceiveView extends PureComponent<Props, State> {
opacity: 0,
}}
>
{show => show
&& (props => (
{(show: boolean) => show
&& ((props: Object) => (
<animated.div
style={{
...props,
@ -161,10 +144,7 @@ export class ReceiveView extends PureComponent<Props, State> {
>
<Label value='Transparent Address (not private)' />
{transparentAddresses.map(addr => (
<WalletAddress
key={addr}
address={addr}
/>
<WalletAddress key={addr} address={addr} />
))}
</animated.div>
))

View File

@ -58,6 +58,11 @@ const SendWrapper = styled(ColumnComponent)`
margin-top: 60px;
`;
type AmountProps =
| {
isEmpty: boolean,
}
| Object;
const AmountWrapper = styled.div`
width: 100%;
position: relative;
@ -70,14 +75,14 @@ const AmountWrapper = styled.div`
margin-left: 15px;
display: block;
transition: all 0.05s ease-in-out;
opacity: ${props => (props.isEmpty ? '0' : '1')};
opacity: ${(props: AmountProps) => (props.isEmpty ? '0' : '1')};
color: #fff;
z-index: 10;
}
`;
const AmountInput = styled(InputComponent)`
padding-left: ${props => (props.isEmpty ? '15' : '50')}px;
padding-left: ${(props: AmountProps) => (props.isEmpty ? '15' : '50')}px;
`;
const ShowFeeButton = styled.button`
@ -152,22 +157,28 @@ const ConfirmItemWrapper = styled(RowComponent)`
width: 100%;
`;
type ItemLabelProps =
| {
color: string,
}
| Object;
/* eslint-disable max-len */
const ItemLabel = styled(TextComponent)`
font-weight: ${props => props.theme.fontWeight.bold};
font-size: ${props => props.theme.fontSize.small};
color: ${props => props.color || props.theme.colors.modalItemLabel};
font-weight: ${(props: PropsWithTheme<ItemLabelProps>) => String(props.theme.fontWeight.bold)};
font-size: ${(props: PropsWithTheme<ItemLabelProps>) => String(props.theme.fontSize.small)};
color: ${(props: PropsWithTheme<ItemLabelProps>) => props.color || props.theme.colors.modalItemLabel};
margin-bottom: 3.5px;
`;
const SendZECValue = styled(TextComponent)`
color: ${props => props.theme.colors.transactionSent};
font-size: ${props => `${props.theme.fontSize.large}em`};
font-weight: ${props => props.theme.fontWeight.bold};
font-weight: ${props => String(props.theme.fontWeight.bold)};
`;
const SendUSDValue = styled(TextComponent)`
opacity: 0.5;
font-weight: ${props => props.theme.fontWeight.light};
font-weight: ${props => String(props.theme.fontWeight.light)};
font-size: ${props => `${props.theme.fontSize.medium}em`};
`;
@ -509,8 +520,8 @@ export class SendView extends PureComponent<Props, State> {
height: 0,
}}
>
{show => show
&& (props => (
{(show: boolean) => show
&& ((props: Object) => (
<animated.div style={props}>
<FeeWrapper id='send-fee-wrapper'>
<RowComponent alignItems='flex-end' justifyContent='space-between'>

View File

@ -58,7 +58,7 @@ const SettingsTitle = styled(TextComponent)`
text-transform: uppercase;
color: ${props => props.theme.colors.transactionsDate};
font-size: ${props => `${props.theme.fontSize.regular * 0.9}em`};
font-weight: ${props => props.theme.fontWeight.bold};
font-weight: ${props => String(props.theme.fontWeight.bold)};
margin-bottom: 5px;
`;
@ -173,7 +173,7 @@ export class SettingsView extends PureComponent<Props, State> {
electron.remote.dialog.showSaveDialog(
undefined,
{ defaultPath: backupFileName },
async (pathToSave) => {
async (pathToSave: string) => {
if (!pathToSave) return;
const zcashDir = isDev ? `${HOME_DIR}/.zcash/testnet3` : HOME_DIR;

View File

@ -1,8 +1,11 @@
// flow-typed signature: 8ae4cfa383fc58443d8d65b5301bf1c1
// flow-typed version: 1a7d5ca288/styled-components_v4.x.x/flow_>=v0.75.x
// @flow
declare module 'styled-components' {
declare export type Interpolation =
| (<P: {}>(executionContext: P) => string)
| (<P: {}>(executionContext: PropsWithTheme<any>) => string)
| CSSRules
| KeyFrames
| string

View File

@ -0,0 +1,61 @@
type Colors = {
primary: string,
secondary: string,
sidebarBg: string,
sidebarItem: string,
sidebarItemActive: string,
sidebarHoveredItem: string,
sidebarHoveredItemLabel: string,
cardBackgroundColor: string,
text: string,
activeItem: string,
inactiveItem: string,
sidebarLogoGradientBegin: string,
sidebarLogoGradientEnd: string,
background: string,
transactionSent: string,
transactionReceived: string,
transactionsDate: string,
transactionsItemHovered: string,
inputBackground: string,
selectButtonShadow: string,
transactionsDetailsLabel: string,
statusPillLabel: string,
modalItemLabel: string,
blackTwo: string,
buttonBorderColor: string,
};
type FontSize = {
large: number,
medium: number,
regular: number,
small: number,
};
type FontWeight = {
bold: number,
default: number,
light: number,
};
type AppTheme = {
mode: string,
fontFamily: string,
fontWeight: FontWeight,
fontSize: FontSize,
colors: Colors,
sidebarWidth: string,
headerHeight: string,
layoutPaddingLeft: string,
layoutPaddingRight: string,
layoutContentPaddingTop: string,
boxBorderRadius: string,
transitionEase: string,
};
// =(
declare type PropsWithTheme<T = {}> = {
...T,
theme: AppTheme,
};

View File

@ -66,7 +66,7 @@
"eslint-plugin-jsx-a11y": "^6.0.3",
"eslint-plugin-react": "^7.12.4",
"file-loader": "^2.0.0",
"flow-bin": "^0.91.0",
"flow-bin": "^0.92.1",
"flow-coverage-report": "^0.6.1",
"flow-typed": "^2.5.1",
"glow": "^1.2.2",

View File

@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="125" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="125" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h91v20H0z"/><path fill="#4C1" d="M91 0h34v20H91z"/><path fill="url(#b)" d="M0 0h125v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,DejaVu Sans,Geneva,sans-serif" font-size="11"><text x="45.5" y="15" fill="#010101" fill-opacity=".3">flow-coverage</text><text x="45.5" y="14">flow-coverage</text><text x="107" y="15" fill="#010101" fill-opacity=".3">83%</text><text x="107" y="14">83%</text></g></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="125" height="20"><linearGradient id="b" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient><mask id="a"><rect width="125" height="20" rx="3" fill="#fff"/></mask><g mask="url(#a)"><path fill="#555" d="M0 0h91v20H0z"/><path fill="#4C1" d="M91 0h34v20H91z"/><path fill="url(#b)" d="M0 0h125v20H0z"/></g><g fill="#fff" text-anchor="middle" font-family="Verdana,DejaVu Sans,Geneva,sans-serif" font-size="11"><text x="45.5" y="15" fill="#010101" fill-opacity=".3">flow-coverage</text><text x="45.5" y="14">flow-coverage</text><text x="107" y="15" fill="#010101" fill-opacity=".3">90%</text><text x="107" y="14">90%</text></g></svg>

Before

Width:  |  Height:  |  Size: 745 B

After

Width:  |  Height:  |  Size: 745 B

View File

@ -7294,10 +7294,10 @@ flow-annotation-check@1.8.1:
glob "7.1.1"
load-pkg "^3.0.1"
flow-bin@^0.91.0:
version "0.91.0"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.91.0.tgz#f5c89729f74b2ccbd47df6fbfadbdcc89cc1e478"
integrity sha512-j+L+xNiUYnZZ27MjVI0y2c9474ZHOvdSQq0Tjwh56mEA7tfxYqp5Dcb6aZSwvs3tGMTjCrZow9aUlZf3OoRyDQ==
flow-bin@^0.92.1:
version "0.92.1"
resolved "https://registry.yarnpkg.com/flow-bin/-/flow-bin-0.92.1.tgz#32c136c07235f30c42dc0549a0790f370fad4070"
integrity sha512-F5kC5oQOR2FXROAeybJHFqgZP+moKV9fa/53QK4Q4WayTQHdA0KSl48KD1gP0A9mioRLiKUegTva/7I15cX3Iw==
flow-coverage-report@^0.6.1:
version "0.6.1"