import React, { useState, useEffect, useRef, createRef } from "react"; import { getClassName, randomId, renderProps } from "../utils"; import "./ButtonTouch.css"; export type IButtonTouch = { children?: React.ReactNode, componentName?: string, modeButtonTouch?: string, mode?: string, modeActive?: string, href?: string, target?: string, disabled?: boolean, hover?: boolean, ref?: any, ripple?: boolean, stopPropagation?: boolean, preventDefault?: boolean, stretched?: boolean, clickable?: boolean, onClick?: React.MouseEventHandler | undefined; [x: string]: any; }; function ButtonTouch({ children, componentName, mode = `default`, modeActive = `default`, ripple, href, target, onClick, disabled = false, hover = true, stretched = false, ref = createRef(), stopPropagation = false, preventDefault = false, clickable = false, ...props }: IButtonTouch) { const Component = href ? `a` : `button`; const childrenRed = useRef(null); const [button_id, setbutton_id] = useState( randomId(props.id, `button_touch`) ); const [rippleElements, setRippleElements] = useState([]); const [is_mobile_hover, setMobileHover] = useState(false); const [is_hover, setHover] = useState(false); const [is_active, setActive] = useState(false); const [time_is_active, setTime_is_active] = useState(0); if (href) clickable = true; if (onClick) clickable = true; if (!clickable) { stopPropagation = false; preventDefault = false; } /* Ripple эффект */ function onRippleClick( event: React.MouseEvent ) { var rect = event.currentTarget.getBoundingClientRect(); const d = Math.max( event.currentTarget.clientWidth, event.currentTarget.clientHeight ); const left = event.clientX - rect.left - d / 2 + "px"; const top = event.clientY - rect.top - d / 2 + "px"; const rippleElement = newRippleElement(d, left, top); setRippleElements([...rippleElements, rippleElement]); } const newRippleElement = (d: number, left: string, top: string) => { var key_id = Math.random(); return (
onAnimationEnd(key_id.toString())} >
); } function onAnimationEnd(key: string) { setRippleElements((rippleElements: any) => rippleElements.filter((element: any) => element.key !== key) ); } const _onClick = (e: any) => { stopPropagation && e.stopPropagation(); preventDefault && e.preventDefault(); if (clickable) { if (ripple) onRippleClick(e); } if (onClick) onClick(e); }; const onMouseUp_Event = (e: any) => { if (clickable) { if (Date.now() - time_is_active < 400) { setTimeout(() => setActive(false), 200); } else setActive(false); if (props.onMouseUp) props.onMouseUp(e); } }; const onMouseDown_Event = (e: any) => { stopPropagation && e.stopPropagation(); if (clickable) { setActive(true); setTime_is_active(Date.now()); if (props.onMouseDown) props.onMouseDown(e); } }; const onTouchEnd = (e: any) => { setActive(false); if (props.onTouchEnd) props.onTouchEnd(e); }; const onMouseMove = (e: any) => { setActive(false); if (props.onMouseMove) props.onMouseMove(e); }; const onTouchStart = (e: any) => { setMobileHover(true); if (props.onTouchStart) props.onTouchStart(e); }; const onMouseHover = (e: any) => { stopPropagation && e.stopPropagation(); if (!is_mobile_hover && clickable) { if (e.type == "mouseover") { setHover(true); } else if (e.type == "mouseout") { setHover(false); } } }; useEffect(() => { if (ripple) { if (childrenRed.current) { if (childrenRed.current.children[0]) { const borderRadius = getComputedStyle( childrenRed.current.children[0] ).borderRadius; childrenRed.current.style.borderRadius = borderRadius; } } } }, [ripple]); return ( _onClick(e)} href={href} target={target} {...renderProps(props, `button`)} /* data-* */ data-disabled={disabled} data-stretched={stretched} data-hover_mode={mode} data-hover_enabled={is_hover} data-active_mode={!ripple && is_active && modeActive} data-clickable={clickable} >
{children} {ripple && ( {rippleElements} )}
); } /* ripple className={getClassName([ onClick && ripple ? `MYUI-ripple` : ripple && mode == `background` ? `MYUI-ripple--background` : `MYUI-ripple`, ])} */ export default ButtonTouch;