cleanup
This commit is contained in:
parent
f6da848c2b
commit
0e2946e4e6
108
js/tree.js
108
js/tree.js
@ -21,6 +21,7 @@ export const Branch = (props) => {
|
|||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
const [{ Open, Done, Away }] = stageParent;
|
const [{ Open, Done, Away }] = stageParent;
|
||||||
const [, Shut] = stage;
|
const [, Shut] = stage;
|
||||||
|
|
||||||
if (!Open && Done) {
|
if (!Open && Done) {
|
||||||
Shut({ Open: false, Done: true, Away });
|
Shut({ Open: false, Done: true, Away });
|
||||||
}
|
}
|
||||||
@ -37,33 +38,12 @@ export const Button = (props) => {
|
|||||||
/** @type Binding */
|
/** @type Binding */
|
||||||
const [stageGet, stageSet] = React.useContext(BranchContext);
|
const [stageGet, stageSet] = React.useContext(BranchContext);
|
||||||
|
|
||||||
/** @type React.MutableRefObject<Handler|null> */
|
|
||||||
const refHandler = React.useRef(null);
|
|
||||||
React.useEffect(() => {
|
|
||||||
console.log("recreating handler", stageGet);
|
|
||||||
refHandler.current = (away) => {
|
|
||||||
console.log("set: away");
|
|
||||||
stageSet((state) => ({ ...state, Away: away }));
|
|
||||||
};
|
|
||||||
}, [stageGet]);
|
|
||||||
|
|
||||||
/** @type React.MutableRefObject<HTMLElement|null> */
|
|
||||||
const refEl = React.useRef(null);
|
|
||||||
useAway(refEl, refHandler);
|
|
||||||
|
|
||||||
const handleClick = () => {
|
const handleClick = () => {
|
||||||
console.log("set: open");
|
console.log("set: open");
|
||||||
stageSet((state) => ({ ...state, Open: !state.Open, Done: false }));
|
stageSet((state) => ({ ...state, Open: !state.Open, Done: false }));
|
||||||
};
|
};
|
||||||
|
|
||||||
React.useEffect(() => {
|
return html`<button onClick=${handleClick} class=${props.class}>stage: ${
|
||||||
console.log("away *changed*");
|
|
||||||
if (stageGet.Away && stageGet.Open) {
|
|
||||||
handleClick();
|
|
||||||
}
|
|
||||||
}, [stageGet.Away]);
|
|
||||||
|
|
||||||
return html`<button ref=${refEl} onClick=${handleClick} class=${props.class}>stage: ${
|
|
||||||
JSON.stringify(stageGet)
|
JSON.stringify(stageGet)
|
||||||
}
|
}
|
||||||
${props.children}
|
${props.children}
|
||||||
@ -82,14 +62,20 @@ export const Menu = (props) => {
|
|||||||
(refCollapser.current = Collapser(refElement.current));
|
(refCollapser.current = Collapser(refElement.current));
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
React.useEffect(() => {
|
const instant = stageGet.Open == false && stageGet.Done;
|
||||||
const instant = stageGet.Open == false && stageGet.Done;
|
refCollapser.current && refCollapser.current(
|
||||||
refCollapser.current && refCollapser.current(
|
stageGet.Open,
|
||||||
stageGet.Open,
|
instant ? 0 : 600,
|
||||||
instant ? 0 : 600,
|
() => stageSet({ ...stageGet, Done: true }),
|
||||||
() => stageSet({ ...stageGet, Done: true }),
|
);
|
||||||
);
|
|
||||||
}, [stageGet]);
|
/** @type React.MutableRefObject<Handler|null> */
|
||||||
|
const refHandler = React.useRef(null);
|
||||||
|
refHandler.current = (away) => {
|
||||||
|
console.log("set: away");
|
||||||
|
stageSet((state) => ({ ...state, Away: away }));
|
||||||
|
};
|
||||||
|
useAway(refElement, refHandler);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div ref=${refElement} class=${props.class}>
|
<div ref=${refElement} class=${props.class}>
|
||||||
@ -99,68 +85,58 @@ export const Menu = (props) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
/** @typedef {(Open:boolean)=>void} UserDone */
|
/** @typedef {(Open:boolean)=>void} UserDone */
|
||||||
/** @typedef {(inOpen:boolean, inMilliseconds:number, inUserDone:UserDone)=>void} Toggler */
|
/** @typedef {(inOpen:boolean, inMilliseconds:number, inUserDone:UserDone)=>void | (()=>void) } Toggler */
|
||||||
/** @typedef {(inElement:HTMLElement)=>Toggler} Collapse */
|
/** @typedef {(inElement:HTMLElement)=>Toggler} Collapse */
|
||||||
/** @type Collapse */
|
/** @type Collapse */
|
||||||
const Collapser = (inElement) => {
|
const Collapser = (inElement) => {
|
||||||
/** @type UserDone */
|
/** @type UserDone */
|
||||||
let userDone = () => {};
|
let userDone = () => {};
|
||||||
let userMode = false;
|
let userMode = false;
|
||||||
const collapse = inElement;
|
/** @type number */ let frameRequest;
|
||||||
/** @type {(inEvent:TransitionEvent)=>void} */
|
/** @type {(inEvent:TransitionEvent)=>void} */
|
||||||
const done = (inEvent) => {
|
const done = (inEvent) => {
|
||||||
if (inEvent.propertyName == "height" && inEvent.target == collapse) {
|
if (inEvent.propertyName == "height" && inEvent.target == inElement) {
|
||||||
inEvent.stopPropagation();
|
inEvent.stopPropagation();
|
||||||
if (userMode) {
|
if (userMode) {
|
||||||
collapse.style.height = "auto";
|
inElement.style.height = "auto";
|
||||||
collapse.style.overflow = "visible";
|
inElement.style.overflow = "visible";
|
||||||
userDone(true);
|
|
||||||
} else {
|
|
||||||
userDone(false);
|
|
||||||
}
|
}
|
||||||
|
userDone(userMode);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inElement.addEventListener("transitionend", done);
|
||||||
|
|
||||||
/** @type Toggler */
|
/** @type Toggler */
|
||||||
const show = (inOpen, inMs, inDone) => {
|
const show = (inOpen, inMs, inDone) => {
|
||||||
userMode = inOpen;
|
cancelAnimationFrame(frameRequest);
|
||||||
collapse.removeEventListener("transitionend", done);
|
if ((!inOpen && !inMs) && !inDone) {
|
||||||
userDone = inDone;
|
inElement.removeEventListener("transitionend", done);
|
||||||
collapse.addEventListener("transitionend", done);
|
} else {
|
||||||
|
userDone = inDone;
|
||||||
collapse.style.height = collapse.clientHeight + "px";
|
userMode = inOpen;
|
||||||
collapse.style.overflow = "hidden";
|
inElement.style.height = inElement.clientHeight + "px";
|
||||||
collapse.style.transition = "none";
|
inElement.style.overflow = "hidden";
|
||||||
requestAnimationFrame(() => {
|
inElement.style.transition = "none";
|
||||||
collapse.style.height = `${inOpen ? collapse.scrollHeight : 0}px`;
|
frameRequest = requestAnimationFrame(() => {
|
||||||
collapse.style.transition = `height ${inMs / 1000}s`;
|
inElement.style.height = `${inOpen ? inElement.scrollHeight : 0}px`;
|
||||||
});
|
inElement.style.transition = `height ${inMs / 1000}s`;
|
||||||
|
});
|
||||||
|
}
|
||||||
};
|
};
|
||||||
return show;
|
return show;
|
||||||
};
|
};
|
||||||
|
|
||||||
/** @typedef {(away:boolean, e:Event)=>void} Handler */
|
/** @typedef {(away:boolean, e:Event)=>void} Handler */
|
||||||
/** @type {(inRef:React.MutableRefObject<HTMLElement|null>, inHandler:React.MutableRefObject<Handler|null>)=>void} */
|
/** @type {(inRef:React.MutableRefObject<HTMLElement|null>, inHandler:React.MutableRefObject<Handler|null>)=>void} */
|
||||||
export const useAway = (inRef, inHandler) => {
|
export const useAway = (inRef, inHandlerRef) => {
|
||||||
/** @type React.MutableRefObject<(e:Event)=>void> */
|
/** @type React.MutableRefObject<(e:Event)=>void> */
|
||||||
const handlerClick = React.useRef((e) => {
|
const handlerClick = React.useRef((e) => {
|
||||||
const index = inRef.current ? e.composedPath().indexOf(inRef.current) : -1;
|
const index = inRef.current ? e.composedPath().indexOf(inRef.current) : -1;
|
||||||
inHandler.current && inHandler.current(index < 0, e);
|
inHandlerRef.current && inHandlerRef.current(index < 0, e);
|
||||||
});
|
});
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
document.addEventListener("click", handlerClick.current);
|
document.addEventListener("click", handlerClick.current);
|
||||||
return () => document.removeEventListener("click", handlerClick.current);
|
return () => document.removeEventListener("click", handlerClick.current);
|
||||||
});
|
}, []);
|
||||||
};
|
|
||||||
|
|
||||||
const GlobalClick = {
|
|
||||||
Bind: () => {
|
|
||||||
if (!GlobalClick.Live) {
|
|
||||||
GlobalClick.Live = true;
|
|
||||||
document.addEventListener("click", (inEvent) => {
|
|
||||||
GlobalClick.Path = inEvent.composedPath();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Live: false,
|
|
||||||
Path: [],
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user