mirror of
https://github.com/comfyanonymous/ComfyUI.git
synced 2025-09-21 01:56:49 +00:00
New Menu & Workflow Management (#3112)
* menu * wip * wip * wip * wip * wip * workflow saving/loading * Support inserting workflows Move buttosn to top of lists * fix session storage implement renaming * temp * refactor, better workflow instance management * wip * progress on progress * added send to workflow various fixes * Support multiple image loaders * Support dynamic size breakpoints based on content * various fixes add close unsaved warning * Add filtering tree * prevent renaming unsaved * fix zindex on hover * fix top offset * use filename as workflow name * resize on setting change * hide element until it is drawn * remove glow * Fix export name * Fix test, revert accidental changes to groupNode * Fix colors on all themes * show hover items on smaller screen (mobile) * remove debugging code * dialog fix * Dont reorder open workflows Allow elements around canvas * Toggle body display on setting change * Fix menu disappearing on chrome * Increase delay when typing, remove margin on Safari, fix dialog location * Fix overflow issue on iOS * Add reset view button Prevent view changes causing history entries * Bottom menu wip * Various fixes * Fix merge * Fix breaking old menu position * Fix merge adding restore view to loadGraphData
This commit is contained in:
128
web/scripts/ui/components/popup.js
Normal file
128
web/scripts/ui/components/popup.js
Normal file
@@ -0,0 +1,128 @@
|
||||
// @ts-check
|
||||
|
||||
import { prop } from "../../utils.js";
|
||||
import { $el } from "../../ui.js";
|
||||
import { applyClasses } from "../utils.js";
|
||||
|
||||
export class ComfyPopup extends EventTarget {
|
||||
element = $el("div.comfyui-popup");
|
||||
|
||||
/**
|
||||
* @param {{
|
||||
* target: HTMLElement,
|
||||
* container?: HTMLElement,
|
||||
* classList?: import("../utils.js").ClassList,
|
||||
* ignoreTarget?: boolean,
|
||||
* closeOnEscape?: boolean,
|
||||
* position?: "absolute" | "relative",
|
||||
* horizontal?: "left" | "right"
|
||||
* }} param0
|
||||
* @param {...HTMLElement} children
|
||||
*/
|
||||
constructor(
|
||||
{
|
||||
target,
|
||||
container = document.body,
|
||||
classList = "",
|
||||
ignoreTarget = true,
|
||||
closeOnEscape = true,
|
||||
position = "absolute",
|
||||
horizontal = "left",
|
||||
},
|
||||
...children
|
||||
) {
|
||||
super();
|
||||
this.target = target;
|
||||
this.ignoreTarget = ignoreTarget;
|
||||
this.container = container;
|
||||
this.position = position;
|
||||
this.closeOnEscape = closeOnEscape;
|
||||
this.horizontal = horizontal;
|
||||
|
||||
container.append(this.element);
|
||||
|
||||
this.children = prop(this, "children", children, () => {
|
||||
this.element.replaceChildren(...this.children);
|
||||
this.update();
|
||||
});
|
||||
this.classList = prop(this, "classList", classList, () => applyClasses(this.element, this.classList, "comfyui-popup", horizontal));
|
||||
this.open = prop(this, "open", false, (v, o) => {
|
||||
if (v === o) return;
|
||||
if (v) {
|
||||
this.#show();
|
||||
} else {
|
||||
this.#hide();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
toggle() {
|
||||
this.open = !this.open;
|
||||
}
|
||||
|
||||
#hide() {
|
||||
this.element.classList.remove("open");
|
||||
window.removeEventListener("resize", this.update);
|
||||
window.removeEventListener("click", this.#clickHandler, { capture: true });
|
||||
window.removeEventListener("keydown", this.#escHandler, { capture: true });
|
||||
|
||||
this.dispatchEvent(new CustomEvent("close"));
|
||||
this.dispatchEvent(new CustomEvent("change"));
|
||||
}
|
||||
|
||||
#show() {
|
||||
this.element.classList.add("open");
|
||||
this.update();
|
||||
|
||||
window.addEventListener("resize", this.update);
|
||||
window.addEventListener("click", this.#clickHandler, { capture: true });
|
||||
if (this.closeOnEscape) {
|
||||
window.addEventListener("keydown", this.#escHandler, { capture: true });
|
||||
}
|
||||
|
||||
this.dispatchEvent(new CustomEvent("open"));
|
||||
this.dispatchEvent(new CustomEvent("change"));
|
||||
}
|
||||
|
||||
#escHandler = (e) => {
|
||||
if (e.key === "Escape") {
|
||||
this.open = false;
|
||||
e.preventDefault();
|
||||
e.stopImmediatePropagation();
|
||||
}
|
||||
};
|
||||
|
||||
#clickHandler = (e) => {
|
||||
/** @type {any} */
|
||||
const target = e.target;
|
||||
if (!this.element.contains(target) && this.ignoreTarget && !this.target.contains(target)) {
|
||||
this.open = false;
|
||||
}
|
||||
};
|
||||
|
||||
update = () => {
|
||||
const rect = this.target.getBoundingClientRect();
|
||||
this.element.style.setProperty("--bottom", "unset");
|
||||
if (this.position === "absolute") {
|
||||
if (this.horizontal === "left") {
|
||||
this.element.style.setProperty("--left", rect.left + "px");
|
||||
} else {
|
||||
this.element.style.setProperty("--left", rect.right - this.element.clientWidth + "px");
|
||||
}
|
||||
this.element.style.setProperty("--top", rect.bottom + "px");
|
||||
this.element.style.setProperty("--limit", rect.bottom + "px");
|
||||
} else {
|
||||
this.element.style.setProperty("--left", 0 + "px");
|
||||
this.element.style.setProperty("--top", rect.height + "px");
|
||||
this.element.style.setProperty("--limit", rect.height + "px");
|
||||
}
|
||||
|
||||
const thisRect = this.element.getBoundingClientRect();
|
||||
if (thisRect.height < 30) {
|
||||
// Move up instead
|
||||
this.element.style.setProperty("--top", "unset");
|
||||
this.element.style.setProperty("--bottom", rect.height + 5 + "px");
|
||||
this.element.style.setProperty("--limit", rect.height + 5 + "px");
|
||||
}
|
||||
};
|
||||
}
|
Reference in New Issue
Block a user