Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as React from "react"
- import Ripples from 'react-ripples'
- import styled from "styled-components"
- import { variant } from "styled-system"
- import { MdChevronLeft, MdChevronRight } from "react-icons/md"
- import { useTransition, animated } from 'react-spring'
- import { Box } from "./Box"
- import { Text } from "./Text"
- const Wrapper = styled(Box)`
- height: 400px;
- position: relative;
- width: 100%;
- display: grid;
- grid-template-columns: [left-chevron] 1fr [content] 8fr [right-chevron] 1fr;
- `
- const ContentWrapper = styled(Box)({
- gridColumn: 'content',
- position: 'relative',
- '& > div': {
- willChange: 'transform, opacity',
- position: 'absolute',
- width: '100%',
- height: '100%',
- },
- })
- const SlideControlWrapper = styled(Ripples)({
- display: 'flex',
- alignItems: 'center',
- justifyContent: 'center',
- cursor: 'pointer',
- }, variant({
- variants: {
- disabled: { opacity: 0.6, pointerEvents: 'none' }
- }
- }))
- const SlideControl = ({ children, ...props }) =>
- <SlideControlWrapper {...props}>
- {children}
- </SlideControlWrapper>
- const initialState = {
- currentIndex: 0,
- animation: {
- enter: { opacity: 1, transform: "translate3d(0%, 0, 0)" },
- leave: { opacity: 0, transform: "translate3d(100%, 0 ,0)" },
- from: { opacity: 0, transform: "translate3d(-50%, 0, 0)" },
- },
- }
- const CarouselContext = React.createContext({
- previous: () => {},
- next: () => {},
- carouselState: initialState,
- })
- export const useCarousel = () => React.useContext(CarouselContext)
- export const Provider = ({ children }) => {
- const [carouselState, setCarouselState] = React.useState(initialState)
- const previous = () => {
- setCarouselState({
- currentIndex: carouselState.currentIndex - 1,
- animation: {
- enter: { opacity: 1, transform: "translate3d(0%, 0, 0)" },
- leave: { opacity: 0, transform: "translate3d(100%, 0 ,0)" },
- from: { opacity: 0, transform: "translate3d(-50%, 0, 0)" },
- },
- })
- }
- const next = () => {
- setCarouselState({
- currentIndex: carouselState.currentIndex + 1,
- animation: {
- from: { opacity: 0, transform: "translate3d(100%, 0 ,0)" },
- enter: { opacity: 1, transform: "translate3d(0%, 0, 0)" },
- leave: { opacity: 0, transform: "translate3d(-50%, 0, 0)" },
- },
- })
- }
- return (
- <CarouselContext.Provider value={{ previous, next, carouselState }}>
- {children}
- </CarouselContext.Provider>
- )
- }
- export const Carousel = ({ items }) => {
- const { previous, carouselState, next } = useCarousel()
- const transitions = useTransition([carouselState.currentIndex], item => item, {
- reset: true,
- unique: true,
- ...carouselState.animation,
- })
- return (
- <Wrapper>
- <SlideControl
- gridColumn="left-chevron"
- onClick={previous}
- variant={carouselState.currentIndex == 0 ? "disabled" : "normal"}
- >
- <Text color="black" fontSize="48px">
- <MdChevronLeft />
- </Text>
- </SlideControl>
- <ContentWrapper height="400px">
- {transitions.map(({ item, props, key }) => <animated.div key={key} style={props}>{items[item]()}</animated.div>)}
- </ContentWrapper>
- <SlideControl
- gridColumn="right-chevron"
- onClick={next}
- variant={
- carouselState.currentIndex == items.length - 1 ? "disabled" : "normal"
- }
- >
- <Text color="black" fontSize="48px">
- <MdChevronRight />
- </Text>
- </SlideControl>
- </Wrapper>
- )
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement