diff --git a/example/app.tsx b/example/app.tsx index 2f45e75..4d3d993 100644 --- a/example/app.tsx +++ b/example/app.tsx @@ -1,5 +1,6 @@ import React from "react"; import * as Iso from "@eno/iso"; +import * as C from "./tree-menu.tsx"; /* const delay =(inMS:number)=> @@ -33,6 +34,32 @@ export default ()=> About + + + +

hello!

+

hello!

+

hello!

+

hello!

+ + + +

hello!

+

hello!

+

hello!

+

hello!

+

hello!

+

hello!

+

hello!

+
+
+

hello!

+

hello!

+

hello!

+
+
+ +

Title!!

suspended:

Loading!}> diff --git a/example/tree-menu.tsx b/example/tree-menu.tsx new file mode 100644 index 0000000..055a6a0 --- /dev/null +++ b/example/tree-menu.tsx @@ -0,0 +1,110 @@ +import React from "react"; + +type StateArgs = {done?:boolean, open?:boolean}; +type StateObj = {done:boolean, open:boolean}; +type StateBinding = [state:StateObj, update:(args:StateArgs)=>void]; + +const CTX = React.createContext([{done:true, open:false}, (args)=>{}] as StateBinding); + +export const Group =(props:{children:React.JSX.Element|React.JSX.Element[]})=> +{ + const [stateGet, stateSet] = React.useState({done:true, open:false} as StateObj); + return stateSet({...stateGet, ...args})]}>{props.children}; +}; + +export const Menu =(props:{children:React.JSX.Element|React.JSX.Element[]})=> +{ + const [stateGet, stateSet] = React.useContext(CTX); + const refElement:React.MutableRefObject = React.useRef( null ); + const refControl:React.MutableRefObject = React.useRef( null ); + + const classOpen = "h-auto -top-10"; + const classShut = "h-0 top-0"; + + window.TwindInst(classOpen); + window.TwindInst(classShut); + + React.useEffect(()=>refControl.current = Collapser(refElement.current as HTMLElement, true), []); + React.useEffect(()=> {refControl.current && refControl.current(stateGet.open, 1000, ()=>stateSet({done:true}))}, [stateGet.open]) + + return
}>{props.children}
; +}; + +export const Button =()=> +{ + const [stateGet, stateSet] = React.useContext(CTX); + return <> +

{JSON.stringify(stateGet)}

+ + + ; +}; + +type DoneCallback =(openState:boolean)=>void; +export type CollapseControls =(inOpen?:boolean, inMs?:number, inDone?:DoneCallback)=>void; +export function Collapser(inElement:HTMLElement, initialState = false) +{ + let userDone:DoneCallback = (openState) => {}; + let userMode = initialState; + let frameRequest = 0; + + const done = (inEvent:TransitionEvent)=> + { + if (inEvent.propertyName == "height" && inEvent.target == inElement) + { + inEvent.stopPropagation(); + if (userMode) + { + inElement.style.height = "auto"; + inElement.style.overflow = "visible"; + } + userDone(userMode); + } + }; + inElement.addEventListener("transitionend", done); + + return function(inOpen, inMs, inDone) + { + cancelAnimationFrame(frameRequest); + + if(arguments.length) + { + userDone = inDone|| ((m)=>{}) as DoneCallback; + userMode = inOpen === true; + + inElement.style.height = inElement.clientHeight + "px"; + inElement.style.overflow = "hidden"; + inElement.style.transition = "none"; + + const h1 = inElement.clientHeight; + const classesStart = inElement.className; + + inElement.style.height = ""; + inElement.className = classesStart + " " + inElement.getAttribute(`data-class-${inOpen?"open":"shut"}`); + const h2 = inElement.clientHeight; + console.log("when classes are (", inElement.className , ") height is", h2); + + inElement.style.height = h1+"px"; + inElement.className = classesStart; + + console.log("LOOK", h1, h2); + + + + + frameRequest = requestAnimationFrame(()=> + { + inElement.style.transition = ""; + frameRequest = requestAnimationFrame(()=> + { + inElement.style.height = `${h2}px`; + }); + + }); + } + else + { + inElement.removeEventListener("transitionend", done); + } + } as CollapseControls; +} \ No newline at end of file diff --git a/server.tsx b/server.tsx index 0fe76ff..1f269a0 100644 --- a/server.tsx +++ b/server.tsx @@ -304,6 +304,9 @@ console.log(`Args seen: `, Flags); const {Transpileable, TranspileURL, SocketsHandler} = Transpiler(DevMode); let {Imports, App, TwindInst, Error} = await Configure(DevMode, Path.LibDir); +//@ts-ignore +window.TwindInst = TwindInst; + if(Error) { console.log(Error); @@ -423,7 +426,7 @@ else if(App && TwindInst) import * as Twind from "https://esm.sh/v115/@twind/core@1.1.3/es2022/core.mjs"; import * as App from "@eno/app"; import {Router, Fetch, CSS, Meta} from "@eno/iso"; - Twind.install(App.CSS ? {...CSS, ...App.CSS} : CSS); + window.TwindInst = Twind.install(App.CSS ? {...CSS, ...App.CSS} : CSS); Fetch.Seed(${JSON.stringify(seed)}); const hmrWrap = H( ()=>H(App.default) ); hydrate(