collapse context reset
This commit is contained in:
parent
9fc85f1901
commit
dc601637a8
18
js/people.js
18
js/people.js
@ -89,16 +89,20 @@ export default () => {
|
||||
<div class="px-2">
|
||||
<${PersonForm}/>
|
||||
<${PersonTable}/>
|
||||
|
||||
<${Tree.Branch}>
|
||||
<${Tree.Button}><//>
|
||||
<${Tree.Menu}>
|
||||
<div class=${"p-4"}>
|
||||
<p>
|
||||
The method addEventListener() works by adding a function, or an object that implements EventListener, to the list of event listeners for the specified event type on the EventTarget on which it's called. If the function or object is already in the list of event listeners for this target, the function or object is not added a second time.
|
||||
</p>
|
||||
</div>
|
||||
<${Tree.Button}/>
|
||||
<${Tree.Menu} class="shadow-lg rounded-lg bg-white">
|
||||
<p>hey</p>
|
||||
<${Tree.Branch}>
|
||||
<${Tree.Button} class="p-4 bg-red-500 text-white"/>
|
||||
<${Tree.Menu}>
|
||||
<p>sup.</p>
|
||||
<//>
|
||||
<//>
|
||||
<//>
|
||||
<//>
|
||||
|
||||
</div>
|
||||
</div>`;
|
||||
};
|
||||
|
29
js/tree.js
29
js/tree.js
@ -1,7 +1,7 @@
|
||||
import { html } from "htm";
|
||||
import * as React from "preact";
|
||||
|
||||
/** @typedef {({children, classes}:{children:preact.VNode, classes:string|null})=>preact.VNode} BasicElement */
|
||||
/** @typedef {(props:{children:preact.VNode, class:string|null})=>preact.VNode} BasicElement */
|
||||
/** @typedef {{Open:boolean, Done:boolean}} Stage*/
|
||||
/** @typedef {[set:Stage, get:React.StateUpdater<Stage>]} Binding */
|
||||
|
||||
@ -9,6 +9,8 @@ const BranchContext = React.createContext(
|
||||
/** @type Binding */ ([{ Open: false, Done: true }, (_n) => {}]),
|
||||
);
|
||||
|
||||
export { BranchContext as Context };
|
||||
|
||||
/** @type BasicElement */
|
||||
export const Branch = (props) => {
|
||||
/** @type Binding */ const stage = React.useState(
|
||||
@ -17,7 +19,8 @@ export const Branch = (props) => {
|
||||
/** @type Binding */ const stageParent = React.useContext(BranchContext);
|
||||
|
||||
React.useEffect(() => {
|
||||
const [{ Open, Done }, Shut] = stageParent;
|
||||
const [{ Open, Done }] = stageParent;
|
||||
const [, Shut] = stage;
|
||||
if (!Open && Done) {
|
||||
Shut({ Open: false, Done: true });
|
||||
}
|
||||
@ -40,7 +43,7 @@ export const Button = (props) => {
|
||||
console.log(value);
|
||||
};
|
||||
|
||||
return html`<button onClick=${handler} class=${props.classes}>stage: ${
|
||||
return html`<button onClick=${handler} class=${props.class}>stage: ${
|
||||
JSON.stringify(stageGet)
|
||||
}
|
||||
${props.children}
|
||||
@ -51,22 +54,25 @@ export const Button = (props) => {
|
||||
export const Menu = (props) => {
|
||||
const [stageGet, stageSet] = React.useContext(BranchContext);
|
||||
const refElement = React.useRef(null);
|
||||
/** @type {React.MutableRefObject<null|Toggler>} */
|
||||
const refCollapser = React.useRef(null);
|
||||
|
||||
React.useEffect(() => {
|
||||
refCollapser.current = Collapser(refElement.current);
|
||||
refElement.current &&
|
||||
(refCollapser.current = Collapser(refElement.current));
|
||||
}, []);
|
||||
|
||||
React.useEffect(() => {
|
||||
refCollapser.current(
|
||||
const instant = stageGet.Open == false && stageGet.Done;
|
||||
refCollapser.current && refCollapser.current(
|
||||
stageGet.Open,
|
||||
stageGet.Open == false && stageGet.Done ? 0 : 600,
|
||||
instant ? 0 : 600,
|
||||
() => stageSet({ ...stageGet, Done: true }),
|
||||
);
|
||||
}, [stageGet.Open]);
|
||||
|
||||
return html`
|
||||
<div ref=${refElement} class=${props.classes}>
|
||||
<div ref=${refElement} class=${props.class}>
|
||||
${props.children}
|
||||
</div>
|
||||
`;
|
||||
@ -74,18 +80,18 @@ export const Menu = (props) => {
|
||||
|
||||
/** @typedef {(Open:boolean)=>void} UserDone */
|
||||
/** @typedef {(inOpen:boolean, inMilliseconds:number, inUserDone:UserDone)=>void} Toggler */
|
||||
/** @type {(inElement:HTMLElement)=>Toggler} */
|
||||
/** @typedef {(inElement:HTMLElement)=>Toggler} Collapse */
|
||||
/** @type Collapse */
|
||||
const Collapser = (inElement) => {
|
||||
console.log("Collapser initialized");
|
||||
|
||||
/** @type UserDone */
|
||||
let userDone = () => {};
|
||||
let userMode = false;
|
||||
const collapse = inElement;
|
||||
/** @type {(inEvent:TransitionEvent)=>void} */
|
||||
const done = (inEvent) => {
|
||||
if (inEvent.propertyName == "height" && inEvent.target == collapse) {
|
||||
inEvent.stopPropagation();
|
||||
if (collapse.clientHeight > 0) {
|
||||
if (userMode) {
|
||||
collapse.style.height = "auto";
|
||||
collapse.style.overflow = "visible";
|
||||
userDone(true);
|
||||
@ -96,6 +102,7 @@ const Collapser = (inElement) => {
|
||||
};
|
||||
/** @type Toggler */
|
||||
const show = (inOpen, inMs, inDone) => {
|
||||
userMode = inOpen;
|
||||
collapse.removeEventListener("transitionend", done);
|
||||
userDone = inDone;
|
||||
collapse.addEventListener("transitionend", done);
|
||||
|
Loading…
Reference in New Issue
Block a user