1
1
mirror of https://github.com/jxnblk/mdx-deck.git synced 2024-11-29 13:58:02 +03:00

Adjust scroll behavior

This commit is contained in:
Brent Jackson 2018-07-28 16:19:08 -04:00
parent c9157a37d9
commit 88a76c61f5

View File

@ -10,11 +10,61 @@ import debounce from 'lodash.debounce'
// todo: dynamic import
import slides from '../docs/index.mdx'
const Carousel = styled.div([], {
const CarouselRoot = styled.div([], {
display: 'flex',
overflowX: 'auto',
width: '100vw',
scrollSnapType: 'mandatory',
})
class Carousel extends React.Component {
root = React.createRef()
isScroll = false
handleScroll = debounce(e => {
if (this.isScroll) {
this.isScroll = false
return
}
const { scrollLeft } = e.target
const rect = e.target.getBoundingClientRect()
const n = Math.round(scrollLeft / rect.width)
this.props.onScroll(n)
}, 200)
scrollTo = (index) => {
if (!this.root.current) return
const el = this.root.current.querySelector('#slide-' + index)
if (!el) return
el.scrollIntoView({ behavior: 'smooth' })
}
componentDidMount () {
this.root.current.addEventListener('scroll', this.handleScroll)
}
componentWillUnmount () {
this.root.current.removeEventListener('scroll', this.handleScroll)
}
componentDidUpdate (prev) {
if (prev.index === this.props.index) return
this.isScroll = true
this.scrollTo(this.props.index)
}
render () {
const { onScroll, index, ...props } = this.props
return (
<CarouselRoot
innerRef={this.root}
{...props}
/>
)
}
}
const Slide = styled.div([], {
outline: '2px solid tomato',
flex: 'none',
@ -42,47 +92,19 @@ class App extends React.Component {
index: 0
}
root = React.createRef()
update = fn => this.setState(fn)
handleScroll = debounce(e => {
if (this.isProgrammaticScroll) return
const { scrollLeft } = e.target
const rect = e.target.getBoundingClientRect()
const n = Math.round(scrollLeft / rect.width)
console.log('scroll', e, n)
this.setState({ index: n })
}, 1000)
componentDidMount () {
this.root.current.addEventListener('scroll', this.handleScroll)
}
componentWillUnmount () {
this.root.current.removeEventListener('scroll', this.handleScroll)
}
componentDidUpdate () {
if (!this.root.current) return
const { index } = this.state
const el = this.root.current.querySelector('#slide-' + index)
if (!el) return
this.isProgrammaticScroll = true
el.scrollIntoView({
behavior: 'smooth'
})
setTimeout(() => {
console.log(this.isProgrammaticScroll)
this.isProgrammaticScroll = false
}, 1000)
}
render () {
const { slides } = this.props
const { index } = this.state
return (
<div>
<Carousel innerRef={this.root}>
<Carousel
index={index}
onScroll={index => {
this.setState({ index })
}}>
{slides.map((Component, i) => (
<Slide key={i} id={'slide-' + i}>
<Component />