"use client" import React, { useId, useRef, useState, forwardRef, useCallback, useImperativeHandle } from 'react'; import {Ripple} from "./ripple"; import {Ripples} from "./ripple"; import {RippleAreaProps} from "./ripple.types"; const TIMEOUT : number = 550; const rippleAreaContext = React.createContext(false); const RippleArea = forwardRef( function RippleArea({central = false, callback, ...props} : RippleAreaProps, ref) { const [ripples, setRipples] = useState>([]), rippleDomain = useRef(null), clicked = useRef(false), uniqueKey = useRef(0), uniqueId = useId(); let classes = props.className ? `m3 m3-ripple-domain ${props.className}`.trimEnd() : "m3 m3-ripple-domain"; const start = useCallback((event : any, cb : (state : boolean) => void) : void => { clicked.current = true; cb(clicked.current); const rippleDomainChar = rippleDomain.current ? rippleDomain.current.getBoundingClientRect() : { width: 0, height: 0, left: 0, top: 0, } let rippleX : number = !central ? event.clientX - rippleDomainChar.left : rippleDomainChar.width / 2, rippleY : number = !central ? event.clientY - rippleDomainChar.top : rippleDomainChar.height / 2, rippleSizeX : number = Math.max(Math.abs(rippleDomainChar.width - rippleX), rippleX) * 2 + 2, rippleSizeY : number = Math.max(Math.abs(rippleDomainChar.height - rippleY), rippleY) * 2 + 2, rippleS : number = (rippleSizeX ** 2 + rippleSizeY ** 2) ** 0.5; setRipples((prevRipples : Array) => { if(prevRipples.length === 0){ return [ ] } else { let old = [...prevRipples]; old.push( ) return old; } } ) uniqueKey.current += 1; }, []); const stop = useCallback((_event : any, cb : (state : boolean) => void) => { clicked.current = false; cb(clicked.current); setRipples((prevRipples : Array) => { if(prevRipples.length > 0) { let old = [...prevRipples]; old.shift(); return old; } return prevRipples }); },[]); useImperativeHandle(ref, () => ({ start, stop, }), [start, stop]); return ( {ripples} ); } ) export {rippleAreaContext, RippleArea};