Last active
January 11, 2019 11:54
-
-
Save kaneel/646d9dc97901ad67bae57845f4a24d17 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react' | |
import { default as styled } from 'styled-components' | |
import { Transition, Spring, animated } from 'react-spring' | |
const StyledCarousel = styled.div` | |
width: 100%; | |
height: 100%; | |
` | |
const StyledCarouselWrapper = styled.div` | |
text-align: center; | |
` | |
const StyledCarouselItem = styled.div` | |
position: absolute; | |
width: 100%; | |
top: 50%; | |
left: 0; | |
transform: translateY(-50%); | |
` | |
const StyledCarouselControls = styled.div` | |
position: absolute; | |
width: 100%; | |
height: 100%; | |
top: 0; | |
left: 0; | |
` | |
const StyledCarouselDots = styled.ul` | |
position: absolute; | |
bottom: 10px; | |
left: 0; | |
width: 100%; | |
list-style: none; | |
padding: 0; margin: 0; | |
display: flex; | |
align-item: center; | |
justify-content: center; | |
` | |
const StyledCarouselDot = styled.li` | |
width: 20px; | |
height: 20px; | |
border-radius: 10px; | |
cursor: pointer; | |
` | |
const StyledCarouselControl = styled.button` | |
margin: 0; | |
padding: 0; | |
position: absolute; | |
top: 0; | |
${(props) => props.next ? ` | |
right: 0; | |
&:after { | |
content: ">" | |
} | |
` : ` | |
left: 0; | |
&:after { | |
content: "<" | |
} | |
`} | |
` | |
class CarouselWrapper extends React.PureComponent { | |
render() { | |
const { slides, cursor } = this.props | |
const Component = slides[cursor] | |
return ( | |
<StyledCarouselWrapper> | |
{slides} | |
</StyledCarouselWrapper> | |
) | |
} | |
} | |
export const CarouselItem = ({ children, show }) => | |
<Spring | |
native | |
from={{ opacity: show ? 0 : 1, value: show ? 100 : 0 }} | |
to={{ opacity: show ? 1 : 0, value: show ? 0 : 100 }} | |
> | |
{ | |
({opacity, value}) => <animated.div style={{ | |
width: '100%', | |
height: '100%', | |
position: 'absolute', | |
top: 0, | |
left: 0, | |
opacity, | |
transform: value.interpolate(v => `translate3d(${v}%, 0, 0)`) | |
}}>{ | |
<StyledCarouselItem>{children}</StyledCarouselItem> | |
}</animated.div> | |
} | |
</Spring> | |
export class CarouselDot extends React.Component { | |
onClick = () => this.props.onClick(this.props.index) | |
render() { | |
const { children } = this.props | |
return ( | |
<StyledCarouselDot onClick={this.onClick}> {children} </StyledCarouselDot> | |
) | |
} | |
} | |
export class CarouselControls extends React.Component { | |
onPrev = () => { | |
const { onGoTo, cursor } = this.props | |
onGoTo(cursor - 1) | |
} | |
onNext = () => { | |
const { onGoTo, cursor } = this.props | |
onGoTo(cursor + 1) | |
} | |
render() { | |
const { slides, cursor } = this.props | |
return ( | |
<StyledCarouselControls> | |
<StyledCarouselDots> | |
{ slides.map((slide, i) => <CarouselDot onClick={this.props.onGoTo} key={i} index={i}>{i}</CarouselDot>) } | |
<StyledCarouselControl next={false} onClick={this.onPrev}>Prev</StyledCarouselControl> | |
<StyledCarouselControl next={true} onClick={this.onNext}>Next</StyledCarouselControl> | |
</StyledCarouselDots> | |
</StyledCarouselControls> | |
) | |
} | |
} | |
class Carousel extends React.Component { | |
constructor(props) { | |
super(props) | |
this.state = { | |
cursor: 0, | |
} | |
} | |
onGoTo = (nextCursor) => { | |
const { slides } = this.props | |
let cursor = nextCursor%slides.length | |
if (cursor < 0) { | |
cursor = slides.length + cursor | |
} | |
this.setState({ cursor }) | |
} | |
render() { | |
const { cursor } = this.state | |
const { slides } = this.props | |
return ( | |
<StyledCarousel> | |
<CarouselWrapper | |
cursor={cursor} | |
slides={slides.map((slide, i) => <CarouselItem key={i} show={i === cursor}>{slide}</CarouselItem>)} /> | |
<CarouselControls slides={slides} cursor={cursor} onGoTo={this.onGoTo} /> | |
</StyledCarousel> | |
) | |
} | |
} | |
export default Carousel |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment