type(flow): upgrade flow-bin and add styled-components typedefs

This commit is contained in:
George Lima 2019-02-07 00:06:48 -03:00
parent 98a1fc1a4a
commit 7e8e572f6a
30 changed files with 368 additions and 781 deletions

View File

@ -3,37 +3,33 @@
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;
display: flex;
justify-content: center;
padding: 10px 30px;
font-family: ${props => props.theme.fontFamily};
font-weight: ${props => props.theme.fontWeight.bold};
font-size: ${props => `${props.theme.fontSize.regular}em`};
font-family: ${(props: PropsWithTheme<>) => props.theme.fontFamily};
font-weight: ${(props: PropsWithTheme<>) => String(props.theme.fontWeight.bold)};
font-size: ${(props: PropsWithTheme<>) => `${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: PropsWithTheme<>) => props.theme.transitionEase};
`;
const Primary = styled(DefaultButton)`
background-color: ${props => props.theme.colors.primary};
color: ${props => props.theme.colors.secondary};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.primary};
color: ${(props: PropsWithTheme<>) => props.theme.colors.secondary};
border: none;
&:hover {
background-color: ${props => darken(0.1, props.theme.colors.primary(props))};
opacity: 0.9;
}
&:disabled {
background-color: ${props => props.theme.colors.buttonBorderColor};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.buttonBorderColor};
cursor: not-allowed;
opacity: 0.8;
}
@ -41,20 +37,20 @@ const Primary = styled(DefaultButton)`
const Secondary = styled(DefaultButton)`
background-color: transparent;
color: ${props => props.theme.colors.secondary};
border: 2px solid ${props => props.theme.colors.buttonBorderColor};
color: ${(props: PropsWithTheme<>) => props.theme.colors.secondary};
border: 2px solid ${(props: PropsWithTheme<>) => props.theme.colors.buttonBorderColor};
&:hover {
border-color: ${props => props.theme.colors.primary};
border-color: ${(props: PropsWithTheme<>) => props.theme.colors.primary};
}
&:disabled {
background-color: Transparent;
cursor: not-allowed;
color: ${props => props.theme.colors.buttonBorderColor};
color: ${(props: PropsWithTheme<>) => props.theme.colors.buttonBorderColor};
&:hover {
border-color: ${props => props.theme.colors.buttonBorderColor};
border-color: ${(props: PropsWithTheme<>) => props.theme.colors.buttonBorderColor};
}
}
`;
@ -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,8 +12,8 @@ import CloseIcon from '../assets/images/close_icon.svg';
const Wrapper = styled.div`
display: flex;
width: ${props => `${props.width}px`};
background-color: ${props => props.theme.colors.background};
width: ${(props: PropsWithTheme<{ width: number }>) => `${props.width}px`};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.background};
flex-direction: column;
align-items: center;
border-radius: 6px;
@ -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

@ -14,10 +14,10 @@ import { truncateAddress } from '../utils/truncate-address';
/* eslint-disable max-len */
const MenuWrapper = styled.div`
background-image: ${props => `linear-gradient(to right, ${darken(0.05, props.theme.colors.activeItem)}, ${
background-image: ${(props: PropsWithTheme<>) => `linear-gradient(to right, ${darken(0.05, props.theme.colors.activeItem)}, ${
props.theme.colors.activeItem
})`};
border-radius: ${props => props.theme.boxBorderRadius};
border-radius: ${(props: PropsWithTheme<>) => props.theme.boxBorderRadius};
margin-left: -10px;
max-width: 400px;
overflow: hidden;
@ -28,7 +28,7 @@ const MenuItem = styled.button`
background-color: transparent;
border: none;
border-bottom-style: solid;
border-bottom-color: ${props => props.theme.colors.text};
border-bottom-color: ${(props: PropsWithTheme<>) => props.theme.colors.text};
border-bottom-width: 1px;
padding: 15px;
cursor: pointer;
@ -68,7 +68,7 @@ const Option = styled(TextComponent)`
const PopoverWithStyle = styled(Popover)`
& > .Popover-tip {
fill: ${props => props.theme.colors.activeItem};
fill: ${(props: PropsWithTheme<>) => props.theme.colors.activeItem};
}
`;
@ -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

@ -23,7 +23,7 @@ const ModalWrapper = styled.div`
const ChildrenWrapper = styled.div`
width: 350px;
background-color: ${props => props.theme.colors.background};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.background};
display: flex;
flex-direction: column;
align-items: center;
@ -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

@ -12,34 +12,34 @@ import { StatusPill } from './status-pill';
import { withSyncStatus } from '../../services/sync-status';
const Wrapper = styled.div`
height: ${props => props.theme.headerHeight};
height: ${(props: PropsWithTheme<>) => props.theme.headerHeight};
width: 100vw;
display: flex;
flex-direction: row;
background-color: ${props => props.theme.colors.background};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.background};
`;
const LogoWrapper = styled.div`
height: ${props => props.theme.headerHeight};
width: ${props => props.theme.sidebarWidth};
height: ${(props: PropsWithTheme<>) => props.theme.headerHeight};
width: ${(props: PropsWithTheme<>) => props.theme.sidebarWidth};
background-image: linear-gradient(
to right,
${props => props.theme.colors.sidebarLogoGradientBegin},
${props => props.theme.colors.sidebarLogoGradientEnd}
${(props: PropsWithTheme<>) => props.theme.colors.sidebarLogoGradientBegin},
${(props: PropsWithTheme<>) => props.theme.colors.sidebarLogoGradientEnd}
);
margin-bottom: 20px;
`;
const TitleWrapper = styled.div`
width: ${props => `calc(100% - ${props.theme.sidebarWidth})`};
height: ${props => props.theme.headerHeight};
width: ${(props: PropsWithTheme<>) => `calc(100% - ${props.theme.sidebarWidth})`};
height: ${(props: PropsWithTheme<>) => props.theme.headerHeight};
display: flex;
flex-direction: column;
align-items: flex-start;
justify-content: space-between;
padding-top: 10px;
padding-left: ${props => props.theme.layoutPaddingLeft};
padding-right: ${props => props.theme.layoutPaddingRight};
padding-left: ${(props: PropsWithTheme<>) => props.theme.layoutPaddingLeft};
padding-right: ${(props: PropsWithTheme<>) => props.theme.layoutPaddingRight};
`;
const TitleRow = styled(RowComponent)`
@ -49,12 +49,12 @@ const TitleRow = styled(RowComponent)`
`;
const Title = styled(TextComponent)`
font-size: ${props => `${props.theme.fontSize.large}em`};
font-size: ${(props: PropsWithTheme<>) => `${props.theme.fontSize.large}em`};
margin-top: 10px;
margin-bottom: 10px;
text-transform: capitalize;
letter-spacing: 0.25px;
font-weight: ${props => props.theme.fontWeight.bold};
font-weight: ${(props: PropsWithTheme<>) => 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

@ -8,11 +8,11 @@ import { ErrorModalComponent } from './error-modal';
const Layout = styled.div`
display: flex;
flex-direction: column;
width: ${props => `calc(100% - ${props.theme.sidebarWidth})`};
height: ${props => `calc(100vh - ${props.theme.headerHeight})`};
background-color: ${props => props.theme.colors.background};
padding-left: ${props => props.theme.layoutPaddingLeft};
padding-right: ${props => props.theme.layoutPaddingRight};
width: ${(props: PropsWithTheme<>) => `calc(100% - ${props.theme.sidebarWidth})`};
height: ${(props: PropsWithTheme<>) => `calc(100vh - ${props.theme.headerHeight})`};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.background};
padding-left: ${(props: PropsWithTheme<>) => props.theme.layoutPaddingLeft};
padding-right: ${(props: PropsWithTheme<>) => props.theme.layoutPaddingRight};
overflow: auto;
`;

View File

@ -20,7 +20,7 @@ const Wrapper = styled.div`
flex-direction: column;
align-items: center;
justify-content: center;
background-color: ${props => props.theme.colors.cardBackgroundColor};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.cardBackgroundColor};
`;
const CircleWrapper = styled.div`
@ -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,36 @@ 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-${props.placement}-left-radius: 0; border-${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;
@ -45,7 +52,7 @@ const SelectMenuButtonWrapper = styled.div`
width: 50px;
height: 100%;
padding: 13px;
border-left: ${props => `1px solid ${props.theme.colors.background}`};
border-left: ${(props: PropsWithTheme<>) => `1px solid ${props.theme.colors.background}`};
`;
/* eslint-disable max-len */
@ -53,10 +60,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 +75,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 }>) => `${props.placement}: ${`-${props.optionsAmount * 40}px`}`};
overflow-y: auto;
`;
@ -84,7 +91,7 @@ const Option = styled.button`
border-bottom: 1px solid #4e4b4b;
&:hover {
background-color: ${props => props.theme.colors.background};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.background};
}
&:last-child {

View File

@ -9,21 +9,22 @@ import { MENU_OPTIONS } from '../constants/sidebar';
const Wrapper = styled.div`
display: flex;
flex-direction: column;
width: ${props => props.theme.sidebarWidth};
height: ${props => `calc(100vh - ${props.theme.headerHeight})`};
font-family: ${props => props.theme.fontFamily};
background-color: ${props => props.theme.colors.sidebarBg};
width: ${(props: PropsWithTheme<>) => props.theme.sidebarWidth};
height: ${(props: PropsWithTheme<>) => `calc(100vh - ${props.theme.headerHeight})`};
font-family: ${(props: PropsWithTheme<>) => props.theme.fontFamily};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.sidebarBg};
padding-top: 15px;
position: relative;
`;
/* 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};
color: ${(props: PropsWithTheme<>) => props.theme.colors.statusPillLabel};
font-weight: ${(props: PropsWithTheme<>) => 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

@ -12,9 +12,9 @@ const Wrapper = styled.div`
`;
const TransactionsWrapper = styled.div`
border-radius: ${props => props.theme.boxBorderRadius};
border-radius: ${(props: PropsWithTheme<>) => props.theme.boxBorderRadius};
overflow: hidden;
background-color: ${props => props.theme.colors.cardBackgroundColor};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.cardBackgroundColor};
padding: 0;
margin: 0;
box-sizing: border-box;
@ -23,9 +23,9 @@ const TransactionsWrapper = styled.div`
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};
color: ${(props: PropsWithTheme<>) => props.theme.colors.transactionsDate};
font-size: ${(props: PropsWithTheme<>) => `${props.theme.fontSize.regular * 0.9}em`};
font-weight: ${(props: PropsWithTheme<>) => 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

@ -23,7 +23,7 @@ import { openExternal } from '../utils/open-external';
const Wrapper = styled.div`
width: 460px;
background-color: ${props => props.theme.colors.background};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.background};
display: flex;
flex-direction: column;
align-items: center;
@ -91,8 +91,8 @@ const Divider = styled.div`
`;
const Label = styled(TextComponent)`
font-weight: ${props => props.theme.fontWeight.bold};
color: ${props => props.theme.colors.transactionsDetailsLabel};
font-weight: ${(props: PropsWithTheme<>) => String(props.theme.fontWeight.bold)};
color: ${(props: PropsWithTheme<>) => props.theme.colors.transactionsDetailsLabel};
margin-bottom: 5px;
letter-spacing: 0.25px;
`;
@ -106,7 +106,7 @@ const Ellipsis = styled(TextComponent)`
const TransactionId = styled.button`
width: 100%;
color: ${props => props.theme.colors.text};
color: ${(props: PropsWithTheme<>) => props.theme.colors.text};
padding: 0;
background: none;
border: none;
@ -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

@ -19,7 +19,7 @@ import { formatNumber } from '../utils/format-number';
import { truncateAddress } from '../utils/truncate-address';
const Wrapper = styled(RowComponent)`
background-color: ${props => props.theme.colors.cardBackgroundColor};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.cardBackgroundColor};
padding: 15px 17px;
cursor: pointer;
@ -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,13 +43,13 @@ const TransactionTypeLabel = styled(TextComponent)`
const TransactionAddress = styled(TextComponent)`
color: #a7a7a7;
${Wrapper}:hover & {
${String(Wrapper)}:hover & {
color: #fff;
}
`;
const TransactionTime = styled(TextComponent)`
color: ${props => props.theme.colors.inactiveItem};
color: ${(props: PropsWithTheme<>) => props.theme.colors.inactiveItem};
`;
const TransactionColumn = styled(ColumnComponent)`
@ -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

@ -21,14 +21,14 @@ const AddressWrapper = styled.div`
`;
const Input = styled.input`
border-radius: ${props => props.theme.boxBorderRadius};
border-radius: ${(props: PropsWithTheme<>) => props.theme.boxBorderRadius};
border: none;
background-color: ${props => props.theme.colors.inputBackground};
color: ${props => props.theme.colors.text};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.inputBackground};
color: ${(props: PropsWithTheme<>) => props.theme.colors.text};
padding: 15px;
width: 100%;
outline: none;
font-family: ${props => props.theme.fontFamily};
font-family: ${(props: PropsWithTheme<>) => props.theme.fontFamily};
::placeholder {
opacity: 0.5;
@ -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

@ -13,17 +13,17 @@ import theme from '../theme';
const Wrapper = styled.div`
display: flex;
flex-direction: column;
background-color: ${props => props.theme.colors.cardBackgroundColor};
border-radius: ${props => props.theme.boxBorderRadius};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.cardBackgroundColor};
border-radius: ${(props: PropsWithTheme<>) => props.theme.boxBorderRadius};
padding: 37px 45px;
min-height: 250px;
position: relative;
margin-top: ${props => props.theme.layoutContentPaddingTop};
margin-top: ${(props: PropsWithTheme<>) => props.theme.layoutContentPaddingTop};
`;
const AllAddresses = styled(TextComponent)`
margin-bottom: 2.5px;
font-size: ${props => `${props.theme.fontSize.small}em`};
font-size: ${(props: PropsWithTheme<>) => `${props.theme.fontSize.small}em`};
`;
const ValueBox = styled.div`
@ -39,11 +39,11 @@ const Label = styled(TextComponent)`
const USDValue = styled(TextComponent)`
opacity: 0.5;
font-weight: ${props => props.theme.fontWeight.light};
font-weight: ${(props: PropsWithTheme<>) => String(props.theme.fontWeight.light)};
`;
const ShieldedValue = styled(Label)`
color: ${props => props.theme.colors.activeItem};
color: ${(props: PropsWithTheme<>) => props.theme.colors.activeItem};
`;
type Props = {
@ -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

@ -12,9 +12,9 @@ import ConsoleSymbol from '../assets/images/console_zcash.png';
const Wrapper = styled.div`
max-height: 100%;
overflow-y: auto;
background-color: ${props => props.theme.colors.cardBackgroundColor};
margin-top: ${props => props.theme.layoutContentPaddingTop};
border-radius: ${props => props.theme.boxBorderRadius};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.cardBackgroundColor};
margin-top: ${(props: PropsWithTheme<>) => props.theme.layoutContentPaddingTop};
border-radius: ${(props: PropsWithTheme<>) => props.theme.boxBorderRadius};
padding: 38px 33.5px;
`;
@ -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

@ -20,9 +20,9 @@ const Row = styled(RowComponent)`
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};
color: ${(props: PropsWithTheme<>) => props.theme.colors.transactionsDate};
font-size: ${(props: PropsWithTheme<>) => `${props.theme.fontSize.regular * 0.9}em`};
font-weight: ${(props: PropsWithTheme<>) => String(props.theme.fontWeight.bold)};
margin-bottom: 5px;
`;
@ -31,7 +31,7 @@ const ActionButton = styled.button`
border: none;
cursor: pointer;
width: 100%;
color: ${props => props.theme.colors.text};
color: ${(props: PropsWithTheme<>) => props.theme.colors.text};
outline: none;
display: flex;
align-items: center;
@ -46,7 +46,7 @@ const ActionButton = styled.button`
const ActionIcon = styled.img`
width: 25px;
height: 25px;
border: 1px solid ${props => props.theme.colors.text};
border: 1px solid ${(props: PropsWithTheme<>) => props.theme.colors.text};
border-radius: 100%;
margin-right: 11.5px;
padding: 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

@ -49,7 +49,7 @@ const Loader = styled.img`
`;
const FormWrapper = styled.div`
margin-top: ${props => props.theme.layoutContentPaddingTop};
margin-top: ${(props: PropsWithTheme<>) => props.theme.layoutContentPaddingTop};
width: 71%;
`;
@ -58,26 +58,31 @@ const SendWrapper = styled(ColumnComponent)`
margin-top: 60px;
`;
type AmountProps =
| {
isEmpty: boolean,
}
| Object;
const AmountWrapper = styled.div`
width: 100%;
position: relative;
&:before {
content: 'ZEC';
font-family: ${props => props.theme.fontFamily};
font-family: ${(props: PropsWithTheme<>) => props.theme.fontFamily};
position: absolute;
margin-top: 15px;
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`
@ -85,7 +90,7 @@ const ShowFeeButton = styled.button`
border: none;
cursor: pointer;
width: 100%;
color: ${props => props.theme.colors.text};
color: ${(props: PropsWithTheme<>) => props.theme.colors.text};
outline: none;
display: flex;
align-items: center;
@ -100,7 +105,7 @@ const ShowFeeButton = styled.button`
const SeeMoreIcon = styled.img`
width: 25px;
height: 25px;
border: 1px solid ${props => props.theme.colors.text};
border: 1px solid ${(props: PropsWithTheme<>) => props.theme.colors.text};
border-radius: 100%;
margin-right: 11.5px;
`;
@ -114,8 +119,8 @@ const FeeWrapper = styled.div`
const InfoCard = styled.div`
width: 100%;
background-color: ${props => props.theme.colors.cardBackgroundColor};
border-radius: ${props => props.theme.boxBorderRadius};
background-color: ${(props: PropsWithTheme<>) => props.theme.colors.cardBackgroundColor};
border-radius: ${(props: PropsWithTheme<>) => props.theme.boxBorderRadius};
`;
const InfoContent = styled.div`
@ -152,23 +157,29 @@ 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};
color: ${(props: PropsWithTheme<>) => props.theme.colors.transactionSent};
font-size: ${(props: PropsWithTheme<>) => `${props.theme.fontSize.large}em`};
font-weight: ${(props: PropsWithTheme<>) => String(props.theme.fontWeight.bold)};
`;
const SendUSDValue = styled(TextComponent)`
opacity: 0.5;
font-weight: ${props => props.theme.fontWeight.light};
font-size: ${props => `${props.theme.fontSize.medium}em`};
font-weight: ${(props: PropsWithTheme<>) => String(props.theme.fontWeight.light)};
font-size: ${(props: PropsWithTheme<>) => `${props.theme.fontSize.medium}em`};
`;
const Icon = styled.img`
@ -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

@ -23,7 +23,7 @@ import rpc from '../../services/api';
const HOME_DIR = electron.remote.app.getPath('home');
const Wrapper = styled.div`
margin-top: ${props => props.theme.layoutContentPaddingTop};
margin-top: ${(props: PropsWithTheme<>) => props.theme.layoutContentPaddingTop};
`;
const ModalContent = styled.div`
@ -43,7 +43,7 @@ const Btn = styled(Button)`
const ClipboardButton = styled(Clipboard)`
width: 50px;
border-radius: ${props => props.theme.boxBorderRadius};
border-radius: ${(props: PropsWithTheme<>) => props.theme.boxBorderRadius};
height: 45px;
margin-left: 5px;
`;
@ -56,9 +56,9 @@ const SettingsWrapper = styled.div`
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};
color: ${(props: PropsWithTheme<>) => props.theme.colors.transactionsDate};
font-size: ${(props: PropsWithTheme<>) => `${props.theme.fontSize.regular * 0.9}em`};
font-weight: ${(props: PropsWithTheme<>) => 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,419 +0,0 @@
// @flow
declare module 'styled-components' {
declare export type Interpolation =
| (<P: {}>(executionContext: P) => string)
| CSSRules
| KeyFrames
| string
| number;
declare export type CSSRules = Interpolation[];
// This is not exported on purpose, since it's an implementation detail
declare type TaggedTemplateLiteral<R> = (
strings: string[],
...interpolations: Interpolation[]
) => R;
declare export type CSSConstructor = TaggedTemplateLiteral<CSSRules>;
declare export type KeyFramesConstructor = TaggedTemplateLiteral<KeyFrames>;
declare export type CreateGlobalStyleConstructor = TaggedTemplateLiteral<React$ComponentType<*>>;
declare interface Tag<T> {
styleTag: HTMLStyleElement | null;
getIds(): string[];
hasNameForId(id: string, name: string): boolean;
insertMarker(id: string): T;
insertRules(id: string, cssRules: string[], name: ?string): void;
removeRules(id: string): void;
css(): string;
toHTML(additionalAttrs: ?string): string;
toElement(): React$Element<*>;
clone(): Tag<T>;
sealed: boolean;
}
// The `any`/weak types in here all come from `styled-components` directly, since those definitions were just copied over
declare export class StyleSheet {
static get master(): StyleSheet;
static get instance(): StyleSheet;
static reset(forceServer?: boolean): void;
id: number;
forceServer: boolean;
target: ?HTMLElement;
tagMap: { [string]: Tag<any> }; // eslint-disable-line flowtype/no-weak-types
deferred: { [string]: string[] | void };
rehydratedNames: { [string]: boolean };
ignoreRehydratedNames: { [string]: boolean };
tags: Tag<any>[]; // eslint-disable-line flowtype/no-weak-types
importRuleTag: Tag<any>; // eslint-disable-line flowtype/no-weak-types
capacity: number;
clones: StyleSheet[];
constructor(?HTMLElement): this;
rehydrate(): this;
clone(): StyleSheet;
sealAllTags(): void;
makeTag(tag: ?Tag<any>): Tag<any>; // eslint-disable-line flowtype/no-weak-types
getImportRuleTag(): Tag<any>; // eslint-disable-line flowtype/no-weak-types
getTagForId(id: string): Tag<any>; // eslint-disable-line flowtype/no-weak-types
hasId(id: string): boolean;
hasNameForId(id: string, name: string): boolean;
deferredInject(id: string, cssRules: string[]): void;
inject(id: string, cssRules: string[], name?: string): void;
remove(id: string): void;
toHtml(): string;
toReactElements(): React$ElementType[];
}
declare export class KeyFrames {
id: string;
name: string;
rules: string[];
constructor(name: string, rules: string[]): this;
inject(StyleSheet): void;
toString(): string;
getName(): string;
}
// I think any is appropriate here?
// eslint-disable-next-line flowtype/no-weak-types
declare export type Theme = { +[string]: any };
declare export var css: CSSConstructor;
declare export var keyframes: KeyFramesConstructor;
declare export var createGlobalStyle: CreateGlobalStyleConstructor;
declare export var ThemeProvider: React$ComponentType<{
children?: ?React$Node,
theme: Theme | (Theme => Theme),
}>;
// This is a bit hard to read. Not sure how to make it more readable. I think adding line-breaks makes it worse.
declare type InjectedProps = { theme: Theme | void };
declare export function withTheme<Props: {}, Component: React$ComponentType<Props>>(
WrappedComponent: Component,
): React$ComponentType<$Diff<React$ElementConfig<$Supertype<Component>>, InjectedProps>>;
// @HACK This is a cheat to hide that the underlying type is "just a string"
// once we know of a better way, we should be able to update this accordingly.
// I don't think there _is_ a good way, currently.
// @NOTE Also not too sure about the naming of this...
declare export type StyledElementType<T> = T;
declare export type StyledComponentType<C> = {
[[call]]: TaggedTemplateLiteral<C>,
+attrs: <A: {}>(
attributes: A | ((props: React$ElementConfig<C>) => A),
) => TaggedTemplateLiteral<React$ComponentType<$Diff<React$ElementConfig<C>, A>>>,
};
declare type StyledComponentList = {
a: StyledComponentType<StyledElementType<'a'>>,
abbr: StyledComponentType<StyledElementType<'abbr'>>,
address: StyledComponentType<StyledElementType<'address'>>,
area: StyledComponentType<StyledElementType<'area'>>,
article: StyledComponentType<StyledElementType<'article'>>,
aside: StyledComponentType<StyledElementType<'aside'>>,
audio: StyledComponentType<StyledElementType<'audio'>>,
b: StyledComponentType<StyledElementType<'b'>>,
base: StyledComponentType<StyledElementType<'base'>>,
bdi: StyledComponentType<StyledElementType<'bdi'>>,
bdo: StyledComponentType<StyledElementType<'bdo'>>,
big: StyledComponentType<StyledElementType<'big'>>,
blockquote: StyledComponentType<StyledElementType<'blockquote'>>,
body: StyledComponentType<StyledElementType<'body'>>,
br: StyledComponentType<StyledElementType<'br'>>,
button: StyledComponentType<StyledElementType<'button'>>,
canvas: StyledComponentType<StyledElementType<'canvas'>>,
caption: StyledComponentType<StyledElementType<'caption'>>,
cite: StyledComponentType<StyledElementType<'cite'>>,
code: StyledComponentType<StyledElementType<'code'>>,
col: StyledComponentType<StyledElementType<'col'>>,
colgroup: StyledComponentType<StyledElementType<'colgroup'>>,
data: StyledComponentType<StyledElementType<'data'>>,
datalist: StyledComponentType<StyledElementType<'datalist'>>,
dd: StyledComponentType<StyledElementType<'dd'>>,
del: StyledComponentType<StyledElementType<'del'>>,
details: StyledComponentType<StyledElementType<'details'>>,
dfn: StyledComponentType<StyledElementType<'dfn'>>,
dialog: StyledComponentType<StyledElementType<'dialog'>>,
div: StyledComponentType<StyledElementType<'div'>>,
dl: StyledComponentType<StyledElementType<'dl'>>,
dt: StyledComponentType<StyledElementType<'dt'>>,
em: StyledComponentType<StyledElementType<'em'>>,
embed: StyledComponentType<StyledElementType<'embed'>>,
fieldset: StyledComponentType<StyledElementType<'fieldset'>>,
figcaption: StyledComponentType<StyledElementType<'figcaption'>>,
figure: StyledComponentType<StyledElementType<'figure'>>,
footer: StyledComponentType<StyledElementType<'footer'>>,
form: StyledComponentType<StyledElementType<'form'>>,
h1: StyledComponentType<StyledElementType<'h1'>>,
h2: StyledComponentType<StyledElementType<'h2'>>,
h3: StyledComponentType<StyledElementType<'h3'>>,
h4: StyledComponentType<StyledElementType<'h4'>>,
h5: StyledComponentType<StyledElementType<'h5'>>,
h6: StyledComponentType<StyledElementType<'h6'>>,
head: StyledComponentType<StyledElementType<'head'>>,
header: StyledComponentType<StyledElementType<'header'>>,
hgroup: StyledComponentType<StyledElementType<'hgroup'>>,
hr: StyledComponentType<StyledElementType<'hr'>>,
html: StyledComponentType<StyledElementType<'html'>>,
i: StyledComponentType<StyledElementType<'i'>>,
iframe: StyledComponentType<StyledElementType<'iframe'>>,
img: StyledComponentType<StyledElementType<'img'>>,
input: StyledComponentType<StyledElementType<'input'>>,
ins: StyledComponentType<StyledElementType<'ins'>>,
kbd: StyledComponentType<StyledElementType<'kbd'>>,
keygen: StyledComponentType<StyledElementType<'keygen'>>,
label: StyledComponentType<StyledElementType<'label'>>,
legend: StyledComponentType<StyledElementType<'legend'>>,
li: StyledComponentType<StyledElementType<'li'>>,
link: StyledComponentType<StyledElementType<'link'>>,
main: StyledComponentType<StyledElementType<'main'>>,
map: StyledComponentType<StyledElementType<'map'>>,
mark: StyledComponentType<StyledElementType<'mark'>>,
menu: StyledComponentType<StyledElementType<'menu'>>,
menuitem: StyledComponentType<StyledElementType<'menuitem'>>,
meta: StyledComponentType<StyledElementType<'meta'>>,
meter: StyledComponentType<StyledElementType<'meter'>>,
nav: StyledComponentType<StyledElementType<'nav'>>,
noscript: StyledComponentType<StyledElementType<'noscript'>>,
object: StyledComponentType<StyledElementType<'object'>>,
ol: StyledComponentType<StyledElementType<'ol'>>,
optgroup: StyledComponentType<StyledElementType<'optgroup'>>,
option: StyledComponentType<StyledElementType<'option'>>,
output: StyledComponentType<StyledElementType<'output'>>,
p: StyledComponentType<StyledElementType<'p'>>,
param: StyledComponentType<StyledElementType<'param'>>,
picture: StyledComponentType<StyledElementType<'picture'>>,
pre: StyledComponentType<StyledElementType<'pre'>>,
progress: StyledComponentType<StyledElementType<'progress'>>,
q: StyledComponentType<StyledElementType<'q'>>,
rp: StyledComponentType<StyledElementType<'rp'>>,
rt: StyledComponentType<StyledElementType<'rt'>>,
ruby: StyledComponentType<StyledElementType<'ruby'>>,
s: StyledComponentType<StyledElementType<'s'>>,
samp: StyledComponentType<StyledElementType<'samp'>>,
script: StyledComponentType<StyledElementType<'script'>>,
section: StyledComponentType<StyledElementType<'section'>>,
select: StyledComponentType<StyledElementType<'select'>>,
small: StyledComponentType<StyledElementType<'small'>>,
source: StyledComponentType<StyledElementType<'source'>>,
span: StyledComponentType<StyledElementType<'span'>>,
strong: StyledComponentType<StyledElementType<'strong'>>,
style: StyledComponentType<StyledElementType<'style'>>,
sub: StyledComponentType<StyledElementType<'sub'>>,
summary: StyledComponentType<StyledElementType<'summary'>>,
sup: StyledComponentType<StyledElementType<'sup'>>,
table: StyledComponentType<StyledElementType<'table'>>,
tbody: StyledComponentType<StyledElementType<'tbody'>>,
td: StyledComponentType<StyledElementType<'td'>>,
textarea: StyledComponentType<StyledElementType<'textarea'>>,
tfoot: StyledComponentType<StyledElementType<'tfoot'>>,
th: StyledComponentType<StyledElementType<'th'>>,
thead: StyledComponentType<StyledElementType<'thead'>>,
time: StyledComponentType<StyledElementType<'time'>>,
title: StyledComponentType<StyledElementType<'title'>>,
tr: StyledComponentType<StyledElementType<'tr'>>,
track: StyledComponentType<StyledElementType<'track'>>,
u: StyledComponentType<StyledElementType<'u'>>,
ul: StyledComponentType<StyledElementType<'ul'>>,
var: StyledComponentType<StyledElementType<'var'>>,
video: StyledComponentType<StyledElementType<'video'>>,
wbr: StyledComponentType<StyledElementType<'wbr'>>,
// SVG
circle: StyledComponentType<StyledElementType<'circle'>>,
clipPath: StyledComponentType<StyledElementType<'clipPath'>>,
defs: StyledComponentType<StyledElementType<'defs'>>,
ellipse: StyledComponentType<StyledElementType<'ellipse'>>,
g: StyledComponentType<StyledElementType<'g'>>,
image: StyledComponentType<StyledElementType<'image'>>,
line: StyledComponentType<StyledElementType<'line'>>,
linearGradient: StyledComponentType<StyledElementType<'linearGradient'>>,
mask: StyledComponentType<StyledElementType<'mask'>>,
path: StyledComponentType<StyledElementType<'path'>>,
pattern: StyledComponentType<StyledElementType<'pattern'>>,
polygon: StyledComponentType<StyledElementType<'polygon'>>,
polyline: StyledComponentType<StyledElementType<'polyline'>>,
radialGradient: StyledComponentType<StyledElementType<'radialGradient'>>,
rect: StyledComponentType<StyledElementType<'rect'>>,
stop: StyledComponentType<StyledElementType<'stop'>>,
svg: StyledComponentType<StyledElementType<'svg'>>,
text: StyledComponentType<StyledElementType<'text'>>,
tspan: StyledComponentType<StyledElementType<'tspan'>>,
};
declare export default StyledComponentList & {
[[call]]: <S: string>(S) => $ElementType<StyledComponentList, S>,
[[call]]: <P: {}, C: React$ComponentType<P>>(C) => StyledComponentType<C>,
};
}
declare module 'styled-components/native' {
declare export type Interpolation =
| (<P: {}>(executionContext: P) => string)
| CSSRules
| KeyFrames
| string
| number;
declare export type CSSRules = Interpolation[];
// This is not exported on purpose, since it's an implementation detail
declare type TaggedTemplateLiteral<R> = (
strings: string[],
...interpolations: Interpolation[]
) => R;
declare export type CSSConstructor = TaggedTemplateLiteral<CSSRules>;
declare export type KeyFramesConstructor = TaggedTemplateLiteral<KeyFrames>;
declare export type CreateGlobalStyleConstructor = TaggedTemplateLiteral<React$ComponentType<*>>;
declare interface Tag<T> {
styleTag: HTMLStyleElement | null;
getIds(): string[];
hasNameForId(id: string, name: string): boolean;
insertMarker(id: string): T;
insertRules(id: string, cssRules: string[], name: ?string): void;
removeRules(id: string): void;
css(): string;
toHTML(additionalAttrs: ?string): string;
toElement(): React$Element<*>;
clone(): Tag<T>;
sealed: boolean;
}
// The `any`/weak types in here all come from `styled-components` directly, since those definitions were just copied over
declare export class StyleSheet {
static get master(): StyleSheet;
static get instance(): StyleSheet;
static reset(forceServer?: boolean): void;
id: number;
forceServer: boolean;
target: ?HTMLElement;
tagMap: { [string]: Tag<any> }; // eslint-disable-line flowtype/no-weak-types
deferred: { [string]: string[] | void };
rehydratedNames: { [string]: boolean };
ignoreRehydratedNames: { [string]: boolean };
tags: Tag<any>[]; // eslint-disable-line flowtype/no-weak-types
importRuleTag: Tag<any>; // eslint-disable-line flowtype/no-weak-types
capacity: number;
clones: StyleSheet[];
constructor(?HTMLElement): this;
rehydrate(): this;
clone(): StyleSheet;
sealAllTags(): void;
makeTag(tag: ?Tag<any>): Tag<any>; // eslint-disable-line flowtype/no-weak-types
getImportRuleTag(): Tag<any>; // eslint-disable-line flowtype/no-weak-types
getTagForId(id: string): Tag<any>; // eslint-disable-line flowtype/no-weak-types
hasId(id: string): boolean;
hasNameForId(id: string, name: string): boolean;
deferredInject(id: string, cssRules: string[]): void;
inject(id: string, cssRules: string[], name?: string): void;
remove(id: string): void;
toHtml(): string;
toReactElements(): React$ElementType[];
}
declare export class KeyFrames {
id: string;
name: string;
rules: string[];
constructor(name: string, rules: string[]): this;
inject(StyleSheet): void;
toString(): string;
getName(): string;
}
// I think any is appropriate here?
// eslint-disable-next-line flowtype/no-weak-types
declare export type Theme = { +[string]: any };
declare export var css: CSSConstructor;
declare export var keyframes: KeyFramesConstructor;
declare export var createGlobalStyle: CreateGlobalStyleConstructor;
declare export var ThemeProvider: React$ComponentType<{
children?: ?React$Node,
theme: Theme | (Theme => Theme),
}>;
// This is a bit hard to read. Not sure how to make it more readable. I think adding line-breaks makes it worse.
declare type InjectedProps = { theme: Theme | void };
declare export function withTheme<Props: {}, Component: React$ComponentType<Props>>(
WrappedComponent: Component,
): React$ComponentType<$Diff<React$ElementConfig<$Supertype<Component>>, InjectedProps>>;
// @HACK This is a cheat to hide that the underlying type is "just a string"
// once we know of a better way, we should be able to update this accordingly.
// I don't think there _is_ a good way, currently.
// @NOTE Also not too sure about the naming of this...
declare export type StyledElementType<T> = T;
declare export type StyledComponentType<C> = {
[[call]]: TaggedTemplateLiteral<C>,
+attrs: <A: {}>(
attributes: A,
) => TaggedTemplateLiteral<React$ComponentType<$Diff<React$ElementConfig<C>, A>>>,
};
declare type StyledComponentList = {
ActivityIndicator: StyledComponentType<React$ComponentType<{}>>,
ActivityIndicatorIOS: StyledComponentType<React$ComponentType<{}>>,
ART: StyledComponentType<React$ComponentType<{}>>,
Button: StyledComponentType<React$ComponentType<{}>>,
DatePickerIOS: StyledComponentType<React$ComponentType<{}>>,
DrawerLayoutAndroid: StyledComponentType<React$ComponentType<{}>>,
Image: StyledComponentType<React$ComponentType<{}>>,
ImageBackground: StyledComponentType<React$ComponentType<{}>>,
ImageEditor: StyledComponentType<React$ComponentType<{}>>,
ImageStore: StyledComponentType<React$ComponentType<{}>>,
KeyboardAvoidingView: StyledComponentType<React$ComponentType<{}>>,
ListView: StyledComponentType<React$ComponentType<{}>>,
MapView: StyledComponentType<React$ComponentType<{}>>,
Modal: StyledComponentType<React$ComponentType<{}>>,
NavigatorIOS: StyledComponentType<React$ComponentType<{}>>,
Picker: StyledComponentType<React$ComponentType<{}>>,
PickerIOS: StyledComponentType<React$ComponentType<{}>>,
ProgressBarAndroid: StyledComponentType<React$ComponentType<{}>>,
ProgressViewIOS: StyledComponentType<React$ComponentType<{}>>,
ScrollView: StyledComponentType<React$ComponentType<{}>>,
SegmentedControlIOS: StyledComponentType<React$ComponentType<{}>>,
Slider: StyledComponentType<React$ComponentType<{}>>,
SliderIOS: StyledComponentType<React$ComponentType<{}>>,
SnapshotViewIOS: StyledComponentType<React$ComponentType<{}>>,
Switch: StyledComponentType<React$ComponentType<{}>>,
RecyclerViewBackedScrollView: StyledComponentType<React$ComponentType<{}>>,
RefreshControl: StyledComponentType<React$ComponentType<{}>>,
SafeAreaView: StyledComponentType<React$ComponentType<{}>>,
StatusBar: StyledComponentType<React$ComponentType<{}>>,
SwipeableListView: StyledComponentType<React$ComponentType<{}>>,
SwitchAndroid: StyledComponentType<React$ComponentType<{}>>,
SwitchIOS: StyledComponentType<React$ComponentType<{}>>,
TabBarIOS: StyledComponentType<React$ComponentType<{}>>,
Text: StyledComponentType<React$ComponentType<{}>>,
TextInput: StyledComponentType<React$ComponentType<{}>>,
ToastAndroid: StyledComponentType<React$ComponentType<{}>>,
ToolbarAndroid: StyledComponentType<React$ComponentType<{}>>,
Touchable: StyledComponentType<React$ComponentType<{}>>,
TouchableHighlight: StyledComponentType<React$ComponentType<{}>>,
TouchableNativeFeedback: StyledComponentType<React$ComponentType<{}>>,
TouchableOpacity: StyledComponentType<React$ComponentType<{}>>,
TouchableWithoutFeedback: StyledComponentType<React$ComponentType<{}>>,
View: StyledComponentType<React$ComponentType<{}>>,
ViewPagerAndroid: StyledComponentType<React$ComponentType<{}>>,
WebView: StyledComponentType<React$ComponentType<{}>>,
FlatList: StyledComponentType<React$ComponentType<{}>>,
SectionList: StyledComponentType<React$ComponentType<{}>>,
VirtualizedList: StyledComponentType<React$ComponentType<{}>>,
};
declare export default StyledComponentList & {
[[call]]: <S: string>(S) => $ElementType<StyledComponentList, S>,
[[call]]: <P: {}, C: React$ComponentType<P>>(C) => StyledComponentType<C>,
};
}

View File

@ -0,0 +1,62 @@
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 = {}> =
| Object
| ({
theme: AppTheme,
} & (T | Object));

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

@ -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"