Files
react/components/shared/css-transition.tsx
witt 7facec3849 feat(scaleable): add scaleable props to each component (#531)
* feat(scaleable): add scaleable props to each component

* chore(scaleable): update the exported type

* feat: apply scaleable to components

chore: remove with-default

test: improve testcase for scaleable

chore: resolve test warning

ci: upgrade nodejs to latest lts

docs: fix type error in document site

* docs: update documents to be compatible with scaleable

chore: fix build errors

* chore: remove all size-related attributes

docs: improve guide document

* docs: add scaleable documentation

test: update snapshots

chore: remove unused

* feat: add scaleable to grid components

* docs: improve docs

* test: update snapshots

* fix(grid): fix basic component props
2021-08-13 17:10:57 +08:00

76 lines
1.8 KiB
TypeScript

import React, { useEffect, useState } from 'react'
interface Props {
visible?: boolean
enterTime?: number
leaveTime?: number
clearTime?: number
className?: string
name?: string
}
const defaultProps = {
visible: false,
enterTime: 60,
leaveTime: 60,
clearTime: 60,
className: '',
name: 'transition',
}
export type CssTransitionProps = Props
const CssTransition: React.FC<React.PropsWithChildren<CssTransitionProps>> = ({
children,
className,
visible,
enterTime,
leaveTime,
clearTime,
name,
...props
}: React.PropsWithChildren<CssTransitionProps> & typeof defaultProps) => {
const [classes, setClasses] = useState<string>('')
const [renderable, setRenderable] = useState<boolean>(visible)
useEffect(() => {
const statusClassName = visible ? 'enter' : 'leave'
const time = visible ? enterTime : leaveTime
if (visible && !renderable) {
setRenderable(true)
}
setClasses(`${name}-${statusClassName}`)
// set class to active
const timer = setTimeout(() => {
setClasses(`${name}-${statusClassName} ${name}-${statusClassName}-active`)
clearTimeout(timer)
}, time)
// remove classess when animation over
const clearClassesTimer = setTimeout(() => {
if (!visible) {
setClasses('')
setRenderable(false)
}
clearTimeout(clearClassesTimer)
}, time + clearTime)
return () => {
clearTimeout(timer)
clearTimeout(clearClassesTimer)
}
}, [visible, renderable])
if (!React.isValidElement(children) || !renderable) return null
return React.cloneElement(children, {
...props,
className: `${children.props.className} ${className} ${classes}`,
})
}
CssTransition.defaultProps = defaultProps
CssTransition.displayName = 'GeistCssTransition'
export default CssTransition