import { ReactNode , ReactElement , MutableRefObject , CSSProperties , MouseEvent , useState , useMemo , useRef } from 'react' ; import PropTypes from 'prop-types' ; import { cx } from '@emotion/css' ; import { jsx , useTheme } from '@emotion/react' ; import { WithAnimatorOutputProps , AnimatorFlow } from '@arwes/animator' ; import { useBleeps } from '@arwes/bleeps' ; import { FRAME_SVG_EFFECTS } from '../FrameSVG' ; import { FrameUnderline } from '../FrameUnderline' ; import { generateStyles } from './Button.styles' ; interface ButtonProps { FrameComponent ? : any ; palette ? : string ; active ? : boolean ; disabled ? : boolean ; onClick ? : ( event : MouseEvent < HTMLButtonElement > ) => void ; className ? : string ; style ? : CSSProperties ; rootRef ? : MutableRefObject < HTMLButtonElement | null > | ( ( node : HTMLButtonElement ) => void ) ; children ? : ReactNode ; } const Button = ( props ) : ReactElement => { const { animator : animatorSettings , FrameComponent , palette , disabled , active , onClick , className , style , rootRef , children } = props ; const theme = useTheme ( ) ; const bleeps = useBleeps ( ) ; const styles = useMemo ( ( ) => generateStyles ( theme , { palette , disabled } ) , [ theme , palette , disabled ] ) ; const effectsRef = useRef < FRAME_SVG_EFFECTS | null > ( null ) ; const [ flow , setFlow ] = useState < AnimatorFlow | null > ( null ) ; const buttonOnClick = ( event ) : void => { const isAnimated = ! ! flow ; const isEntered = isAnimated ? flow ?. entered : true ; if ( ! disabled && isEntered ) { effectsRef . current ?. highlight ( ) ; bleeps . click ?. play ( ) ; onClick ?. ( event ) ; } } ; return ( < FrameComponent animator = { { ... animatorSettings , onTransition : ( flow ) => { setFlow ( flow ) ; animatorSettings ?. onTransition ?. ( flow ) ; } } } as = 'button' className = { cx ( 'arwes-button' , className ) } css = { [ styles . root , ! ! flow && ! flow . entered && styles . rootIsTransitioning ] } style = { style } rootRef = { rootRef } effectsRef = { effectsRef } palette = { palette } disabled = { disabled } hideShapes = { ! active } hover onClick = { buttonOnClick } > { children } < /FrameComponent>); } ; Button . propTypes = { FrameComponent : PropTypes . any . isRequired , palette : PropTypes . string , active : PropTypes . bool , disabled : PropTypes . bool , onClick : PropTypes . func , className : PropTypes . string , style : PropTypes . object , rootRef : PropTypes . any , children : PropTypes . any } ; Button . defaultProps = { FrameComponent : FrameUnderline } ; export { ButtonProps , Button } ;