1
0
mirror of https://github.com/trezor/trezor-wallet synced 2024-11-30 20:28:09 +00:00

merge master

This commit is contained in:
slowbackspace 2019-01-22 15:17:52 +01:00
commit 0f005062fe
11 changed files with 116 additions and 30 deletions

View File

@ -37,6 +37,11 @@ const Wrapper = styled.button`
background: ${colors.GREEN_TERTIARY}; background: ${colors.GREEN_TERTIARY};
} }
&:focus {
border-color: ${colors.INPUT_FOCUSED_BORDER};
box-shadow: 0 0px 6px 0 ${colors.INPUT_FOCUSED_SHADOW};
}
${props => props.isDisabled && css` ${props => props.isDisabled && css`
pointer-events: none; pointer-events: none;
color: ${colors.TEXT_SECONDARY}; color: ${colors.TEXT_SECONDARY};
@ -48,6 +53,10 @@ const Wrapper = styled.button`
color: ${colors.TEXT_SECONDARY}; color: ${colors.TEXT_SECONDARY};
border: 1px solid ${colors.DIVIDER}; border: 1px solid ${colors.DIVIDER};
&:focus {
border-color: ${colors.INPUT_FOCUSED_BORDER};
}
&:hover { &:hover {
color: ${colors.TEXT_PRIMARY}; color: ${colors.TEXT_PRIMARY};
background: ${colors.DIVIDER}; background: ${colors.DIVIDER};
@ -64,6 +73,11 @@ const Wrapper = styled.button`
border: 0px; border: 0px;
color: ${colors.TEXT_SECONDARY}; color: ${colors.TEXT_SECONDARY};
&:focus {
color: ${colors.TEXT_PRIMARY};
box-shadow: none;
}
&:hover, &:hover,
&:active { &:active {
color: ${colors.TEXT_PRIMARY}; color: ${colors.TEXT_PRIMARY};

View File

@ -15,6 +15,7 @@ const Wrapper = styled.div`
position: relative; position: relative;
height: 70px; height: 70px;
width: 320px; width: 320px;
z-index: 10;
display: flex; display: flex;
align-items: center; align-items: center;
background: ${props => (props.disabled ? colors.GRAY_LIGHT : 'transparent')}; background: ${props => (props.disabled ? colors.GRAY_LIGHT : 'transparent')};

View File

@ -11,17 +11,16 @@ const styles = isSearchable => ({
width: '100%', width: '100%',
color: colors.TEXT_SECONDARY, color: colors.TEXT_SECONDARY,
}), }),
control: (base, { isDisabled }) => ({ control: (base, { isDisabled, isFocused }) => ({
...base, ...base,
minHeight: 'initial', minHeight: 'initial',
height: '40px', height: '40px',
borderRadius: '2px', borderRadius: '2px',
borderColor: colors.DIVIDER, borderColor: isFocused ? colors.INPUT_FOCUSED_BORDER : colors.DIVIDER,
boxShadow: 'none', boxShadow: isFocused ? `0 0px 6px 0 ${colors.INPUT_FOCUSED_SHADOW}` : 'none',
background: isDisabled ? colors.LANDING : colors.WHITE, background: isDisabled ? colors.LANDING : colors.WHITE,
'&:hover': { '&:hover': {
cursor: isSearchable ? 'text' : 'pointer', cursor: isSearchable ? 'text' : 'pointer',
borderColor: colors.DIVIDER,
}, },
}), }),
indicatorSeparator: () => ({ indicatorSeparator: () => ({

View File

@ -67,6 +67,11 @@ const StyledTextarea = styled(Textarea)`
color: ${colors.TEXT_SECONDARY}; color: ${colors.TEXT_SECONDARY};
} }
&:focus {
border-color: ${colors.INPUT_FOCUSED_BORDER};
box-shadow: 0 0px 6px 0 ${colors.INPUT_FOCUSED_SHADOW};
}
&:disabled { &:disabled {
pointer-events: none; pointer-events: none;
background: ${colors.GRAY_LIGHT}; background: ${colors.GRAY_LIGHT};

View File

@ -59,6 +59,11 @@ const StyledInput = styled.input`
background-color: ${colors.WHITE}; background-color: ${colors.WHITE};
transition: ${TRANSITION.HOVER}; transition: ${TRANSITION.HOVER};
&:focus {
border-color: ${colors.INPUT_FOCUSED_BORDER};
box-shadow: 0 0px 6px 0 ${colors.INPUT_FOCUSED_SHADOW};
}
&:disabled { &:disabled {
pointer-events: none; pointer-events: none;
background: ${colors.GRAY_LIGHT}; background: ${colors.GRAY_LIGHT};

View File

@ -72,3 +72,12 @@ export const FADE_IN = keyframes`
opacity: 1; opacity: 1;
} }
`; `;
export const SLIDE_DOWN = keyframes`
0% {
transform: translateY(-100%);
}
100% {
transform: translateY(0%);
}
`;

View File

@ -34,4 +34,7 @@ export default {
LABEL_COLOR: '#A9A9A9', LABEL_COLOR: '#A9A9A9',
TOOLTIP_BACKGROUND: '#333333', TOOLTIP_BACKGROUND: '#333333',
INPUT_FOCUSED_BORDER: '#A9A9A9',
INPUT_FOCUSED_SHADOW: '#d6d7d7',
}; };

View File

@ -8,18 +8,21 @@ import colors from 'config/colors';
import { FONT_SIZE } from 'config/variables'; import { FONT_SIZE } from 'config/variables';
const Wrapper = styled.div` const Wrapper = styled.div`
padding: 0px 24px 8px 19px;
box-shadow: 0 3px 8px rgba(0,0,0,0.06);
background: ${colors.WHITE}; background: ${colors.WHITE};
box-shadow: 0 3px 8px rgba(0,0,0,0.06);
`; `;
const Item = styled.div` const Item = styled.div`
padding: 4px 2px; padding: 6px 24px;
display: flex; display: flex;
align-items: center; align-items: center;
font-size: ${FONT_SIZE.BASE}; font-size: ${FONT_SIZE.BASE};
cursor: pointer; cursor: pointer;
color: ${colors.TEXT_SECONDARY}; color: ${colors.TEXT_SECONDARY};
&:hover {
background: ${colors.GRAY_LIGHT};
}
`; `;
const Label = styled.div` const Label = styled.div`

View File

@ -3,6 +3,11 @@ import React, { PureComponent } from 'react';
import styled from 'styled-components'; import styled from 'styled-components';
import TrezorConnect from 'trezor-connect'; import TrezorConnect from 'trezor-connect';
import type { TrezorDevice } from 'flowtype'; import type { TrezorDevice } from 'flowtype';
import COLORS from 'config/colors';
import { FONT_SIZE, FONT_WEIGHT } from 'config/variables';
import { SLIDE_DOWN } from 'config/animations';
import Button from 'components/Button'; import Button from 'components/Button';
import * as deviceUtils from 'utils/device'; import * as deviceUtils from 'utils/device';
import MenuItems from './components/MenuItems'; import MenuItems from './components/MenuItems';
@ -12,9 +17,18 @@ import type { Props } from '../common';
import Divider from '../Divider'; import Divider from '../Divider';
const Wrapper = styled.div``; const Wrapper = styled.div`
position: absolute;
width: 100%;
padding-bottom: 8px;
border-bottom: 1px solid #E3E3E3;
background: white;
box-shadow: 0 3px 8px rgba(0,0,0,0.06);
animation: ${SLIDE_DOWN} 0.25s cubic-bezier(0.17, 0.04, 0.03, 0.94) forwards;
`;
const ButtonWrapper = styled.div` const ButtonWrapper = styled.div`
margin-top: 10px; margin: 10px 0;
padding: 0 10px; padding: 0 10px;
display: flex; display: flex;
`; `;
@ -22,6 +36,14 @@ const StyledButton = styled(Button)`
flex: 1; flex: 1;
`; `;
const StyledDivider = styled(Divider)`
background: #fff;
color: ${COLORS.TEXT_PRIMARY};
font-weight: ${FONT_WEIGHT.MEDIUM};
font-size: ${FONT_SIZE.BASE};
border: none;
`;
type DeviceMenuItem = { type DeviceMenuItem = {
type: string; type: string;
label: string; label: string;
@ -32,6 +54,7 @@ class DeviceMenu extends PureComponent<Props> {
super(props); super(props);
this.mouseDownHandler = this.mouseDownHandler.bind(this); this.mouseDownHandler = this.mouseDownHandler.bind(this);
this.blurHandler = this.blurHandler.bind(this); this.blurHandler = this.blurHandler.bind(this);
this.myRef = React.createRef();
} }
componentDidMount(): void { componentDidMount(): void {
@ -63,6 +86,10 @@ class DeviceMenu extends PureComponent<Props> {
} }
} }
getMenuHeight(): number {
return this.myRef.current ? this.myRef.current.getBoundingClientRect().height : 0;
}
blurHandler(): void { blurHandler(): void {
this.props.toggleDeviceDropdown(false); this.props.toggleDeviceDropdown(false);
} }
@ -96,26 +123,28 @@ class DeviceMenu extends PureComponent<Props> {
return deviceUtils.isDeviceAccessible(this.props.wallet.selectedDevice); return deviceUtils.isDeviceAccessible(this.props.wallet.selectedDevice);
} }
myRef: { current: ?HTMLDivElement }
render() { render() {
const { devices, onSelectDevice, forgetDevice } = this.props; const { devices, onSelectDevice, forgetDevice } = this.props;
const { transport } = this.props.connect; const { transport } = this.props.connect;
const { selectedDevice } = this.props.wallet; const { selectedDevice } = this.props.wallet;
return ( return (
<Wrapper> <Wrapper ref={this.myRef}>
{this.showMenuItems() && <MenuItems device={selectedDevice} {...this.props} />} {this.showMenuItems() && <MenuItems device={selectedDevice} {...this.props} />}
{this.showDivider() && <Divider hasBorder textLeft="Other devices" />} {this.showDivider() && <StyledDivider hasBorder textLeft="Other devices" />}
<DeviceList <DeviceList
devices={devices} devices={devices}
selectedDevice={selectedDevice} selectedDevice={selectedDevice}
onSelectDevice={onSelectDevice} onSelectDevice={onSelectDevice}
forgetDevice={forgetDevice} forgetDevice={forgetDevice}
/> />
<ButtonWrapper> {deviceUtils.isWebUSB(transport) && (
{deviceUtils.isWebUSB(transport) && ( <ButtonWrapper>
<StyledButton isWebUsb>Check for devices</StyledButton> <StyledButton isWebUsb>Check for devices</StyledButton>
)} </ButtonWrapper>
</ButtonWrapper> )}
</Wrapper> </Wrapper>
); );
} }

View File

@ -23,10 +23,11 @@ const TextLeft = styled.p`
`; `;
const Divider = ({ const Divider = ({
textLeft, textRight, hasBorder = false, textLeft, textRight, hasBorder = false, className,
}) => ( }) => (
<Wrapper <Wrapper
hasBorder={hasBorder} hasBorder={hasBorder}
className={className}
> >
<TextLeft>{textLeft}</TextLeft> <TextLeft>{textLeft}</TextLeft>
<p>{textRight}</p> <p>{textRight}</p>
@ -34,6 +35,7 @@ const Divider = ({
); );
Divider.propTypes = { Divider.propTypes = {
className: PropTypes.string,
textLeft: PropTypes.string, textLeft: PropTypes.string,
textRight: PropTypes.string, textRight: PropTypes.string,
hasBorder: PropTypes.bool, hasBorder: PropTypes.bool,

View File

@ -57,6 +57,7 @@ const Footer = styled.div.attrs(props => ({
const Body = styled.div` const Body = styled.div`
width: 320px; width: 320px;
min-height: ${props => (props.minHeight ? `${props.minHeight}px` : '0px')};
`; `;
const Help = styled.div` const Help = styled.div`
@ -110,42 +111,48 @@ const TransitionMenu = (props: TransitionMenuProps): React$Element<TransitionGro
type State = { type State = {
animationType: ?string; animationType: ?string;
shouldRenderDeviceSelection: boolean;
clicked: boolean; clicked: boolean;
bodyMinHeight: number;
} }
class LeftNavigation extends React.PureComponent<Props, State> { class LeftNavigation extends React.PureComponent<Props, State> {
constructor(props: Props) { constructor(props: Props) {
super(props); super(props);
this.deviceMenuRef = React.createRef();
const { location } = this.props.router; const { location } = this.props.router;
const hasNetwork = location && location.state && location.state.network; const hasNetwork = location && location.state && location.state.network;
this.state = { this.state = {
animationType: hasNetwork ? 'slide-left' : null, animationType: hasNetwork ? 'slide-left' : null,
shouldRenderDeviceSelection: false,
clicked: false, clicked: false,
bodyMinHeight: 0,
}; };
} }
componentDidMount() {
this.recalculateBodyMinHeight();
}
componentWillReceiveProps(nextProps: Props) { componentWillReceiveProps(nextProps: Props) {
const { dropdownOpened, selectedDevice } = nextProps.wallet; const { selectedDevice } = nextProps.wallet;
const { location } = nextProps.router; const { location } = nextProps.router;
const hasNetwork = location && location.state.network; const hasNetwork = location && location.state.network;
const deviceReady = selectedDevice && selectedDevice.features && selectedDevice.mode === 'normal'; const deviceReady = selectedDevice && selectedDevice.features && selectedDevice.mode === 'normal';
if (dropdownOpened) {
this.setState({ shouldRenderDeviceSelection: true }); if (hasNetwork) {
} else if (hasNetwork) {
this.setState({ this.setState({
shouldRenderDeviceSelection: false,
animationType: 'slide-left', animationType: 'slide-left',
}); });
} else { } else {
this.setState({ this.setState({
shouldRenderDeviceSelection: false,
animationType: deviceReady ? 'slide-right' : null, animationType: deviceReady ? 'slide-right' : null,
}); });
} }
} }
componentDidUpdate() {
this.recalculateBodyMinHeight();
}
shouldRenderAccounts() { shouldRenderAccounts() {
const { selectedDevice } = this.props.wallet; const { selectedDevice } = this.props.wallet;
const { location } = this.props.router; const { location } = this.props.router;
@ -153,7 +160,6 @@ class LeftNavigation extends React.PureComponent<Props, State> {
&& location && location
&& location.state && location.state
&& location.state.network && location.state.network
&& !this.state.shouldRenderDeviceSelection
&& this.state.animationType === 'slide-left'; && this.state.animationType === 'slide-left';
} }
@ -163,9 +169,19 @@ class LeftNavigation extends React.PureComponent<Props, State> {
} }
shouldRenderCoins() { shouldRenderCoins() {
return !this.state.shouldRenderDeviceSelection && this.state.animationType !== 'slide-left'; return this.state.animationType !== 'slide-left';
} }
recalculateBodyMinHeight() {
if (this.deviceMenuRef.current) {
this.setState({
bodyMinHeight: this.deviceMenuRef.current.getMenuHeight(),
});
}
}
deviceMenuRef: { current: any };
render() { render() {
const { props } = this; const { props } = this;
let menu; let menu;
@ -183,7 +199,7 @@ class LeftNavigation extends React.PureComponent<Props, State> {
); );
} }
const { selectedDevice } = props.wallet; const { selectedDevice, dropdownOpened } = props.wallet;
const isDeviceAccessible = deviceUtils.isDeviceAccessible(selectedDevice); const isDeviceAccessible = deviceUtils.isDeviceAccessible(selectedDevice);
return ( return (
<StickyContainer <StickyContainer
@ -218,8 +234,8 @@ class LeftNavigation extends React.PureComponent<Props, State> {
)} )}
{...this.props} {...this.props}
/> />
<Body> <Body minHeight={this.state.bodyMinHeight}>
{this.state.shouldRenderDeviceSelection && <DeviceMenu {...this.props} />} {dropdownOpened && <DeviceMenu ref={this.deviceMenuRef} {...this.props} />}
{isDeviceAccessible && menu} {isDeviceAccessible && menu}
</Body> </Body>
<Footer key="sticky-footer"> <Footer key="sticky-footer">