Merge pull request #531 from trezor/feature/better-menu-indicator

Simplify indicator
pull/535/head
Maroš 5 years ago committed by GitHub
commit 14791868de
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -1,101 +0,0 @@
/* @flow */
import styled, { css } from 'styled-components';
import { colors } from 'trezor-ui-components';
import React, { PureComponent } from 'react';
type Props = {
pathname: string,
wrapper: () => ?HTMLElement,
};
type State = {
style: {
width: number,
left: number,
},
shouldAnimate: boolean,
};
const Wrapper = styled.div`
position: absolute;
bottom: 0px;
left: 0;
width: 100px;
height: 2px;
background: ${colors.GREEN_PRIMARY};
${props =>
props.animation &&
css`
transition: all 0.3s ease-in-out;
`}
`;
class Indicator extends PureComponent<Props, State> {
constructor(props: Props) {
super(props);
this.state = {
style: {
width: 0,
left: 0,
},
shouldAnimate: false,
};
this.handleResize = this.handleResize.bind(this);
}
componentDidMount() {
window.addEventListener('resize', this.handleResize, false);
}
componentWillReceiveProps(newProps: Props) {
if (this.props.pathname !== newProps.pathname) {
this.setState({
shouldAnimate: true,
});
}
}
componentDidUpdate() {
this.reposition(false);
}
componentWillUnmount() {
window.removeEventListener('resize', this.handleResize, false);
}
handleResize() {
this.reposition();
}
handleResize: () => void;
reposition(resetAnimation: boolean = true) {
const wrapper = this.props.wrapper();
if (!wrapper) return;
const active = wrapper.querySelector('.active');
if (!active) return;
const bounds = active.getBoundingClientRect();
const left = bounds.left - wrapper.getBoundingClientRect().left + wrapper.scrollLeft;
const { state } = this;
if (state.style.left !== left) {
this.setState({
style: {
width: bounds.width,
left,
},
shouldAnimate: resetAnimation ? false : state.shouldAnimate,
});
}
}
render() {
if (!this.props.wrapper) return null;
return <Wrapper style={this.state.style} animation={this.state.shouldAnimate} />;
}
}
export default Indicator;

@ -10,7 +10,6 @@ import type { State } from 'flowtype';
import { FormattedMessage } from 'react-intl'; import { FormattedMessage } from 'react-intl';
import l10nMessages from './index.messages'; import l10nMessages from './index.messages';
import Indicator from './components/Indicator';
type OwnProps = {||}; type OwnProps = {||};
@ -27,14 +26,13 @@ type LocalState = {
}; };
const Wrapper = styled.div` const Wrapper = styled.div`
position: relative;
display: flex; display: flex;
height: 100%; height: 100%;
flex: 1; flex: 1;
align-items: center; align-items: center;
padding: 0px 30px 0 35px;
overflow-y: hidden; overflow-y: hidden;
overflow-x: auto; overflow-x: auto;
padding: 0px 30px 0 35px;
@media screen and (max-width: ${SCREEN_SIZE.MD}) { @media screen and (max-width: ${SCREEN_SIZE.MD}) {
justify-content: space-between; justify-content: space-between;
@ -51,7 +49,10 @@ const StyledNavLink = styled(NavLink)`
color: ${colors.TEXT_SECONDARY}; color: ${colors.TEXT_SECONDARY};
margin: 0px 4px; margin: 0px 4px;
padding: 20px 35px; padding: 20px 35px;
display: flex;
height: 100%;
white-space: nowrap; white-space: nowrap;
border-bottom: 2px solid ${colors.WHITE};
@media screen and (max-width: ${SCREEN_SIZE.MD}) { @media screen and (max-width: ${SCREEN_SIZE.MD}) {
padding: 20px 10px; padding: 20px 10px;
@ -64,7 +65,6 @@ const StyledNavLink = styled(NavLink)`
&.active, &.active,
&:hover { &:hover {
transition: all 0.3s ease-in-out;
color: ${colors.TEXT_PRIMARY}; color: ${colors.TEXT_PRIMARY};
} }
@ -75,27 +75,23 @@ const StyledNavLink = styled(NavLink)`
&:last-child { &:last-child {
margin-right: 0px; margin-right: 0px;
} }
`;
class TopNavigationAccount extends React.PureComponent<Props, LocalState> { &.has-bottom-border {
constructor(props: Props) { border-bottom: 2px solid ${colors.GREEN_PRIMARY};
super(props);
this.state = {
wrapper: null,
};
} }
`;
wrapperRefCallback = (element: ?HTMLElement) => { const LinkContent = styled.div`
this.setState({ display: flex;
wrapper: element, justify-content: center;
}); align-items: center;
}; padding-top: 4px;
`;
wrapper: ?HTMLElement;
class TopNavigationAccount extends React.PureComponent<Props, LocalState> {
render() { render() {
const { config } = this.props.localStorage; const { config } = this.props.localStorage;
const { state, pathname } = this.props.router.location; const { state } = this.props.router.location;
if (!state) return null; if (!state) return null;
const { network } = this.props.selectedAccount; const { network } = this.props.selectedAccount;
if (!network) return null; if (!network) return null;
@ -107,22 +103,32 @@ class TopNavigationAccount extends React.PureComponent<Props, LocalState> {
}`; }`;
return ( return (
<Wrapper className="account-tabs" ref={this.wrapperRefCallback}> <Wrapper>
<StyledNavLink exact to={`${basePath}`}> <StyledNavLink activeClassName="has-bottom-border" exact to={`${basePath}`}>
<FormattedMessage {...l10nMessages.TR_NAV_SUMMARY} /> <LinkContent>
<FormattedMessage {...l10nMessages.TR_NAV_SUMMARY} />
</LinkContent>
</StyledNavLink> </StyledNavLink>
<StyledNavLink to={`${basePath}/receive`}> <StyledNavLink activeClassName="has-bottom-border" to={`${basePath}/receive`}>
<FormattedMessage {...l10nMessages.TR_NAV_RECEIVE} /> <LinkContent>
<FormattedMessage {...l10nMessages.TR_NAV_RECEIVE} />
</LinkContent>
</StyledNavLink> </StyledNavLink>
<StyledNavLink to={`${basePath}/send`}> <StyledNavLink activeClassName="has-bottom-border" to={`${basePath}/send`}>
<FormattedMessage {...l10nMessages.TR_NAV_SEND} /> <LinkContent>
<FormattedMessage {...l10nMessages.TR_NAV_SEND} />
</LinkContent>
</StyledNavLink> </StyledNavLink>
{networkConfig.hasSignVerify && ( {networkConfig.hasSignVerify && (
<StyledNavLink to={`${basePath}/signverify`}> <StyledNavLink
<FormattedMessage {...l10nMessages.TR_NAV_SIGN_AND_VERIFY} /> activeClassName="has-bottom-border"
to={`${basePath}/signverify`}
>
<LinkContent>
<FormattedMessage {...l10nMessages.TR_NAV_SIGN_AND_VERIFY} />
</LinkContent>
</StyledNavLink> </StyledNavLink>
)} )}
<Indicator pathname={pathname} wrapper={() => this.state.wrapper} />
</Wrapper> </Wrapper>
); );
} }

Loading…
Cancel
Save