import React, { FC, useState, useEffect, useCallback, ReactNode } from 'react' import { ButtonStyle } from './button.style' import { IButtonProps } from './button.types' import clsx from 'clsx' const withLoading = (Component: FC) => { return function withLoading({ isLoading, loadingText, typeLoading = 'text', children, style, className, ...props }: { isLoading?: boolean loadingText?: string style?: React.CSSProperties className?: string children?: ReactNode typeLoading?: 'text' | 'spin' | 'dots' | 'spinwithtext' }) { return isLoading ? ( false} > {typeLoading === 'text' && ( {loadingText ? loadingText : 'Loading...'} )} {typeLoading === 'spin' && (
{children}
)} {typeLoading === 'spinwithtext' && (
{loadingText ? loadingText : children}
)} {typeLoading === 'dots' && (
)}
) : ( {children} ) } } const withLink = (Component: FC) => { return function withLink({ href, as, target, className, ...props }: { href?: string as?: 'link' className?: string target?: '_blank' | '_self' | '_parent' | '_top' }) { return href && !!as ? ( ) : ( ) } } const withIcons = (Component: FC) => { return function withIcons({ startIcon, endIcon, children, style, className, ...props }: { startIcon?: ReactNode endIcon?: ReactNode children?: ReactNode style?: React.CSSProperties className?: string }) { return !startIcon && !endIcon ? ( {children} ) : ( {startIcon && startIcon}
{children}
{endIcon && endIcon}
) } } const Component: FC = ({ variant = 'contained', hoverEffect = true, rippleEffect = true, animation = 'none', color, style, textColor, size, children, onClick, className, ...restprops }) => { const [coords, setCoords] = useState<{ x: number; y: number }>({ x: -1, y: -1, }) const [isRippling, setIsRippling] = useState(false) const [click, setClick] = useState(false) useEffect(() => { if (coords.x !== -1 && coords.y !== -1) { setIsRippling(true) setTimeout(() => setIsRippling(false), 400) } else setIsRippling(false) }, [coords]) useEffect(() => { if (!isRippling) setCoords({ x: -1, y: -1 }) }, [isRippling]) const handleClick = useCallback((e: any) => { onClick && onClick(e) animation !== 'none' && setClick(true) const rect = e.target.getBoundingClientRect() setCoords({ x: e.clientX - rect.left, y: e.clientY - rect.top }) }, []) return ( setClick(false)} {...restprops} > {rippleEffect && isRippling && ( )} {children} ) } export const Button: FC = withIcons( withLoading(withLink(Component)), )