From c78b1fafba54e6c5855b80e994f2cb7d553ac5fa Mon Sep 17 00:00:00 2001 From: Seth Trowbridge Date: Sun, 28 May 2023 14:10:05 -0400 Subject: [PATCH] click away --- example/tree-menu.tsx | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/example/tree-menu.tsx b/example/tree-menu.tsx index 8cb3701..37fdf41 100644 --- a/example/tree-menu.tsx +++ b/example/tree-menu.tsx @@ -34,13 +34,15 @@ export const Menu =(props:{children:React.JSX.Element|React.JSX.Element[]})=> Classes[stateName as keyof MenuClassStates] = Window.TwindInst(Classes[stateName as keyof MenuClassStates]); } } - + React.useEffect(()=> { refElement.current?.setAttribute("style", ""); refControl.current = refElement.current && Collapser(refElement.current, stateGet.open ? "Open" : "Shut", Classes); }, []); React.useEffect(()=> {refControl.current && refControl.current(stateGet.open ? "Open" : "Shut", ()=>stateSet({done:true}))}, [stateGet.open]) + useAway(refElement, ()=>stateSet({open:false, done:false})); + return
} class={Classes.Shut} style="transition:none;"> { (!stateGet.open && stateGet.done) ? null : props.children}
; @@ -56,6 +58,28 @@ export const Button =()=> ; }; +type Handler = (e:MouseEvent)=>void +const Refs:Map> = new Map(); +window.innerWidth && document.addEventListener("click", e=> +{ + const path = e.composedPath(); + Refs.forEach( (handlerRef, element)=> handlerRef.current && (path.includes(element) ? null : handlerRef.current(e)) ); +} +, true); +const useAway =(inRef:React.Ref, handleAway:Handler)=> +{ + const refHandler:React.MutableRefObject = React.useRef(handleAway); + refHandler.current = handleAway; + + React.useEffect(()=> + { + inRef.current && Refs.set(inRef.current, refHandler); + return ()=> inRef.current && Refs.delete(inRef.current); + } + , []); +}; + + type StyleSize = [classes:string, width:number, height:number]; type StylePack = Record; type StyleCalc = Record;