diff --git a/src/components/AccountPage/index.js b/src/components/AccountPage/index.js index 6930a879..f64ee39a 100644 --- a/src/components/AccountPage/index.js +++ b/src/components/AccountPage/index.js @@ -34,6 +34,7 @@ import Button from 'components/base/Button' import FormattedVal from 'components/base/FormattedVal' import PillsDaysCount from 'components/PillsDaysCount' import OperationsList from 'components/OperationsList' +import StickyBackToTop from 'components/StickyBackToTop' import AccountHeader from './AccountHeader' import EmptyStateAccount from './EmptyStateAccount' @@ -181,6 +182,7 @@ class AccountPage extends PureComponent { /> + ) : ( diff --git a/src/components/DashboardPage/index.js b/src/components/DashboardPage/index.js index ce1bec31..cf4efa45 100644 --- a/src/components/DashboardPage/index.js +++ b/src/components/DashboardPage/index.js @@ -25,6 +25,7 @@ import Box from 'components/base/Box' import PillsDaysCount from 'components/PillsDaysCount' import Text from 'components/base/Text' import OperationsList from 'components/OperationsList' +import StickyBackToTop from 'components/StickyBackToTop' import AccountCard from './AccountCard' import AccountsOrder from './AccountsOrder' @@ -174,6 +175,7 @@ class DashboardPage extends PureComponent { withAccount /> )} + ) : ( diff --git a/src/components/StickyBackToTop.js b/src/components/StickyBackToTop.js new file mode 100644 index 00000000..13dc2f6c --- /dev/null +++ b/src/components/StickyBackToTop.js @@ -0,0 +1,94 @@ +// @flow +import React, { PureComponent } from 'react' +import ReactDOM from 'react-dom' +import PropTypes from 'prop-types' +import styled from 'styled-components' +import Box from 'components/base/Box' +import ArrowUp from 'icons/ArrowUp' + +const Container = styled(Box)` + position: fixed; + z-index: 10; + bottom: 100px; + right: 20px; + border-radius: 50%; + box-shadow: 0 2px 4px 0 rgba(102, 102, 102, 0.25); + cursor: pointer; + height: 36px; + width: 36px; + color: white; + background-color: #6490f1; + transition: all 0.5s; + opacity: ${p => (p.visible ? 1 : 0)}; + pointer-events: ${p => (!p.visible ? 'none' : 'initial')}; + + &:focus { + width: 200px; + } +` + +type Props = { + scrollThreshold: number, +} + +type State = { + visible: boolean, +} + +class StickyBackToTop extends PureComponent { + static contextTypes = { + // FIXME when we move to "real" scroll container, potential solution (instead of context): http://greweb.me/2016/09/relay-scrolling-connections/ + getScrollbar: PropTypes.func, + } + + static defaultProps = { + scrollThreshold: 800, + } + + state = { + visible: false, + } + + componentDidMount() { + this.context.getScrollbar(scrollbar => { + const listener = () => { + const { scrollTop } = scrollbar + const visible = scrollTop > this.props.scrollThreshold + this.setState(previous => { + if (previous.visible !== visible) { + return { visible } + } + return null + }) + } + scrollbar.addListener(listener) + this.releaseListener = () => scrollbar.removeListener(listener) + }) + } + + componentWillUnmount() { + this.releaseListener() + } + + onClick = () => { + this.context.getScrollbar(scrollbar => { + scrollbar.scrollTo(0, 0, 400) + }) + } + + releaseListener = () => {} + + render() { + const { visible } = this.state + const el = document.getElementById('sticky-back-to-top-root') + if (!el) return null + return ReactDOM.createPortal( + + + , + el, + ) + } +} + +export default StickyBackToTop diff --git a/src/components/base/Box/index.js b/src/components/base/Box/index.js index 679c167c..abbdcb32 100644 --- a/src/components/base/Box/index.js +++ b/src/components/base/Box/index.js @@ -72,6 +72,7 @@ const Box = styled.div` margin-left: ${p => (p.horizontal && p.flow ? `${p.theme.space[p.flow]}px` : '')}; } ` +// ^FIXME this `> * + * happen for all Box but we only need it when we do "grids".. which is not often. margin should be made explicit on user land. const RawCard = styled(Box).attrs({ bg: 'white', p: 3, boxShadow: 0, borderRadius: 1 })`` diff --git a/src/components/layout/Default.js b/src/components/layout/Default.js index 8c9d7127..e87ac31e 100644 --- a/src/components/layout/Default.js +++ b/src/components/layout/Default.js @@ -63,6 +63,8 @@ class Default extends Component { ))} +
+