react-images
Version:
A mobile-friendly, highly customizable, carousel component for displaying media in ReactJS
99 lines (86 loc) • 2.6 kB
JavaScript
// @flow
import React, { type ElementType } from 'react'
import { Transition } from 'react-transition-group'
const easing = 'cubic-bezier(0.23, 1, 0.32, 1)' // easeOutQuint
const verticalOffset = 40
type func = () => void
type Props = {
component: ElementType,
in: boolean,
innerProps: Object, // TODO
onEntered?: func,
onExited?: func,
}
// ==============================
// Fade
// ==============================
export const Fade = ({ component: Tag, onEntered, onExited, in: inProp, innerProps: originalProps, ...props }: Props) => {
const enter = 300
const exit = 500
const fadeStyle = {
transition: 'opacity 200ms',
opacity: 0,
}
const fadeTransition = {
entering: { opacity: 0 },
entered: { opacity: 1 },
exiting: { opacity: 0, transitionDuration: `${exit}ms` },
}
return (
<Transition appear mountOnEnter unmountOnExit onEntered={onEntered} onExited={onExited} key="fade" in={inProp} timeout={{ enter, exit }}>
{status => {
const innerProps = {
...originalProps,
style: {
...fadeStyle,
...fadeTransition[status],
},
}
if (status === 'exited') return null
return <Tag innerProps={innerProps} {...props} />
}}
</Transition>
)
}
// ==============================
// Slide Up
// ==============================
export const SlideUp = ({ component: Tag, onEntered, onExited, in: inProp, innerProps: originalProps, ...props }: Props) => {
const enter = 300
const exit = 500
const restingTransform = 'translate3d(0, 0, 0)'
const slideStyle = {
transition: `transform ${enter}ms ${easing}, opacity ${enter}ms ${easing}`,
transform: restingTransform,
}
const slideTransition = {
entering: {
opacity: 0,
transform: `translate3d(0, ${verticalOffset}px, 0) scale(0.9)`,
},
entered: {
opacity: 1,
transform: restingTransform,
},
exiting: {
opacity: 0,
transform: `translate3d(0, ${verticalOffset}px, 0) scale(0.9)`,
transition: `transform ${exit}ms ${easing}, opacity ${exit}ms ${easing}`,
},
}
return (
<Transition appear in={inProp} mountOnEnter onEntered={onEntered} onExited={onExited} timeout={{ enter, exit }} unmountOnExit>
{status => {
if (status === 'exited') return null
const innerProps = {
...originalProps,
style: {
...slideStyle,
...slideTransition[status],
},
}
return <Tag innerProps={innerProps} {...props} />
}}
</Transition>
)
}