indicator fixes

- indicator animation ignored on 'resize' event
- fixed initial rendering
- working with element ref insead of document.querySelector
pull/192/head
Szymon Lesisz 6 years ago
parent d1eadc8033
commit 5a686cf9df

@ -1,18 +1,20 @@
/* @flow */
import styled from 'styled-components';
import styled, { css } from 'styled-components';
import colors from 'config/colors';
import React, { PureComponent } from 'react';
type Props = {
pathname: string;
wrapper: ?HTMLElement;
}
type State = {
style: {
width: number;
left: number;
}
},
shouldAnimate: boolean,
}
const Wrapper = styled.div`
@ -22,7 +24,9 @@ const Wrapper = styled.div`
width: 100px;
height: 2px;
background: ${colors.GREEN_PRIMARY};
transition: all 0.3s ease-in-out;
${props => props.animation && css`
transition: all 0.3s ease-in-out;
`}
`;
class Indicator extends PureComponent<Props, State> {
@ -34,52 +38,62 @@ class Indicator extends PureComponent<Props, State> {
width: 0,
left: 0,
},
shouldAnimate: false,
};
this.reposition = this.reposition.bind(this);
this.handleResize = this.handleResize.bind(this);
}
componentDidMount() {
this.reposition();
window.addEventListener('resize', this.reposition, false);
window.addEventListener('resize', this.handleResize, false);
}
componentWillReceiveProps(newProps: Props) {
if (this.props.pathname !== newProps.pathname) {
this.setState({
shouldAnimate: true,
});
}
}
componentDidUpdate() {
this.reposition();
this.reposition(false);
}
componentWillUnmount() {
window.removeEventListener('resize', this.reposition, false);
window.removeEventListener('resize', this.handleResize, false);
}
handleResize() {
this.reposition();
}
reposition() {
const tabs = document.querySelector('.account-tabs');
if (!tabs) return;
const active = tabs.querySelector('.active');
handleResize: () => void;
reposition(resetAnimation: boolean = true) {
if (!this.props.wrapper) return;
const { wrapper } = this.props;
const active = wrapper.querySelector('.active');
if (!active) return;
const bounds = active.getBoundingClientRect();
const left = bounds.left - wrapper.getBoundingClientRect().left;
const { state } = this;
const left = bounds.left - tabs.getBoundingClientRect().left;
if (this.state.style.left !== left) {
if (state.style.left !== left) {
this.setState({
style: {
width: bounds.width,
left,
},
shouldAnimate: resetAnimation ? false : state.shouldAnimate,
});
}
}
reposition: () => void;
handleResize() {
this.reposition();
}
render() {
if (!this.props.wrapper) return null;
return (
<Wrapper style={this.state.style} />
<Wrapper style={this.state.style} animation={this.state.shouldAnimate} />
);
}
}

@ -47,22 +47,28 @@ const StyledNavLink = styled(NavLink)`
}
`;
class TopNavigationAccount extends React.PureComponent<Props> {
wrapperRefCallback = (element: ?HTMLElement) => {
this.wrapper = element;
}
const TopNavigationAccount = (props: Props) => {
const { state, pathname } = props.location;
if (!state) return null;
wrapper: ?HTMLElement;
const basePath = `/device/${state.device}/network/${state.network}/account/${state.account}`;
render() {
const { state, pathname } = this.props.location;
if (!state) return null;
return (
<Wrapper className="account-tabs">
<StyledNavLink exact to={`${basePath}`}>Summary</StyledNavLink>
<StyledNavLink to={`${basePath}/receive`}>Receive</StyledNavLink>
<StyledNavLink to={`${basePath}/send`}>Send</StyledNavLink>
{/* <StyledNavLink to={`${basePath}/signverify`}>Sign & Verify</StyledNavLink> */}
<Indicator pathname={pathname} />
</Wrapper>
);
};
const basePath = `/device/${state.device}/network/${state.network}/account/${state.account}`;
return (
<Wrapper className="account-tabs" innerRef={this.wrapperRefCallback}>
<StyledNavLink exact to={`${basePath}`}>Summary</StyledNavLink>
<StyledNavLink to={`${basePath}/receive`}>Receive</StyledNavLink>
<StyledNavLink to={`${basePath}/send`}>Send</StyledNavLink>
{/* <StyledNavLink to={`${basePath}/signverify`}>Sign & Verify</StyledNavLink> */}
<Indicator pathname={pathname} wrapper={this.wrapper} />
</Wrapper>
);
}
}
export default TopNavigationAccount;
Loading…
Cancel
Save