Browse Source

StickyBackToTop

master
Gaëtan Renaudeau 7 years ago
parent
commit
552019a22a
  1. 2
      src/components/AccountPage/index.js
  2. 2
      src/components/DashboardPage/index.js
  3. 94
      src/components/StickyBackToTop.js
  4. 1
      src/components/base/Box/index.js
  5. 2
      src/components/layout/Default.js

2
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<Props, State> {
/>
</Box>
<OperationsList account={account} title={t('app:account.lastOperations')} />
<StickyBackToTop />
</Fragment>
) : (
<EmptyStateAccount account={account} />

2
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<Props, State> {
withAccount
/>
)}
<StickyBackToTop />
</Fragment>
</Fragment>
) : (

94
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<Props, State> {
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(
<Container align="center" justify="center" visible={visible} onClick={this.onClick}>
<ArrowUp size={16} />
</Container>,
el,
)
}
}
export default StickyBackToTop

1
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 })``

2
src/components/layout/Default.js

@ -63,6 +63,8 @@ class Default extends Component<Props> {
<ModalComponent key={name} />
))}
<div id="sticky-back-to-top-root" />
<Box grow horizontal bg="white">
<SideBar />

Loading…
Cancel
Save