wip fix
This commit is contained in:
parent
65da157965
commit
07c55a63d6
|
|
@ -63,7 +63,7 @@ const target = {
|
||||||
instance_item_id: false as any,
|
instance_item_id: false as any,
|
||||||
};
|
};
|
||||||
export const active = {
|
export const active = {
|
||||||
hover_id: "",
|
hover: { id: "", renderTree: () => {}, renderMain: () => {} },
|
||||||
text: { id: "", content: "", timeout: null as any, el: null as any },
|
text: { id: "", content: "", timeout: null as any, el: null as any },
|
||||||
get item_id() {
|
get item_id() {
|
||||||
if (target.active_id === false) {
|
if (target.active_id === false) {
|
||||||
|
|
|
||||||
|
|
@ -212,7 +212,7 @@ export const syncWalkMap = (
|
||||||
string,
|
string,
|
||||||
FNCompDef
|
FNCompDef
|
||||||
>;
|
>;
|
||||||
|
const propvis = {};
|
||||||
if (mprops) {
|
if (mprops) {
|
||||||
const mitem_comp = mitem.get("component");
|
const mitem_comp = mitem.get("component");
|
||||||
if (mitem_comp) {
|
if (mitem_comp) {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { useEffect } from "react";
|
import { ReactNode, useEffect } from "react";
|
||||||
import { useGlobal } from "web-utils";
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
import { Loading } from "../../../../utils/ui/loading";
|
import { Loading } from "../../../../utils/ui/loading";
|
||||||
import { View } from "../../../view/view";
|
import { View } from "../../../view/view";
|
||||||
import { EDGlobal, EdMeta, active } from "../../logic/ed-global";
|
import { EDGlobal, EdMeta, active } from "../../logic/ed-global";
|
||||||
|
|
@ -9,146 +9,173 @@ import { code } from "../popup/code/code";
|
||||||
|
|
||||||
export const EdMain = () => {
|
export const EdMain = () => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
const local = useLocal({
|
||||||
|
el: null as ReactNode,
|
||||||
|
});
|
||||||
|
active.hover.renderMain = local.render;
|
||||||
|
|
||||||
|
if (code.mode && !p.page.building) {
|
||||||
|
local.el = (
|
||||||
|
<View
|
||||||
|
mode={p.mode}
|
||||||
|
code_mode={code.mode}
|
||||||
|
layout={{ show: false }}
|
||||||
|
isEditor={true}
|
||||||
|
api_url={p.site.config.api_url}
|
||||||
|
component={{
|
||||||
|
async load(id_comp) {
|
||||||
|
await loadComponent(p, id_comp);
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
load={{
|
||||||
|
mode: "tree_meta",
|
||||||
|
meta: p.page.meta,
|
||||||
|
entry: p.page.entry,
|
||||||
|
scope: p.page.scope,
|
||||||
|
}}
|
||||||
|
site_id={p.site.id}
|
||||||
|
page_id={p.page.cur.id}
|
||||||
|
bind={({ render }) => {
|
||||||
|
p.page.render = render;
|
||||||
|
}}
|
||||||
|
hidden={(meta) => {
|
||||||
|
if (meta.item.hidden) return true;
|
||||||
|
return false;
|
||||||
|
}}
|
||||||
|
hover={{
|
||||||
|
get(meta) {
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
set(meta) {
|
||||||
|
const outer = getOuterItem(meta);
|
||||||
|
if (outer) {
|
||||||
|
if (active.hover.id !== outer.id) {
|
||||||
|
active.hover.id = outer.id;
|
||||||
|
active.hover.renderTree();
|
||||||
|
active.hover.renderMain();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
active={{
|
||||||
|
get(meta) {
|
||||||
|
return active.item_id === meta.item.id;
|
||||||
|
},
|
||||||
|
set(meta) {
|
||||||
|
const outer = getOuterItem(meta);
|
||||||
|
if (outer) {
|
||||||
|
active.item_id = outer.id;
|
||||||
|
}
|
||||||
|
|
||||||
|
p.render();
|
||||||
|
p.page.render();
|
||||||
|
focus();
|
||||||
|
},
|
||||||
|
text({ meta }) {
|
||||||
|
const { item } = meta;
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
return () => {
|
||||||
|
active.text.id = "";
|
||||||
|
p.render();
|
||||||
|
};
|
||||||
|
}, []);
|
||||||
|
|
||||||
|
const updateWithTimeout = (timeout: number) => {
|
||||||
|
return new Promise<void>((resolve) => {
|
||||||
|
const saving = {
|
||||||
|
id: active.text.id,
|
||||||
|
content: active.text.content,
|
||||||
|
};
|
||||||
|
|
||||||
|
clearTimeout(active.text.timeout);
|
||||||
|
active.text.timeout = setTimeout(() => {
|
||||||
|
const meta = getMetaById(p, saving.id);
|
||||||
|
if (meta && meta.mitem) {
|
||||||
|
meta.mitem.set("html", saving.content);
|
||||||
|
}
|
||||||
|
resolve();
|
||||||
|
}, timeout);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
if (active.text.id !== item.id) {
|
||||||
|
clearTimeout(active.text.timeout);
|
||||||
|
active.text.id = item.id;
|
||||||
|
active.text.content = item.html || "";
|
||||||
|
active.text.el = (
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
`v-text-${item.id} v-text-${item.originalId} outline-none`
|
||||||
|
)}
|
||||||
|
ref={(ref) => {
|
||||||
|
if (ref !== document.activeElement && ref) {
|
||||||
|
const renaming = document.querySelector(".rename-item");
|
||||||
|
const modals = document.querySelectorAll(
|
||||||
|
"[data-floating-ui-portal]"
|
||||||
|
);
|
||||||
|
if (modals.length === 0 && !renaming) {
|
||||||
|
ref.focus();
|
||||||
|
setEndOfContenteditable(ref);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onPointerDownCapture={(e) => {
|
||||||
|
e.stopPropagation();
|
||||||
|
}}
|
||||||
|
contentEditable
|
||||||
|
spellCheck={false}
|
||||||
|
onInput={(e) => {
|
||||||
|
const val = e.currentTarget.innerHTML;
|
||||||
|
item.html = val;
|
||||||
|
active.text.id = item.id;
|
||||||
|
active.text.content = val;
|
||||||
|
updateWithTimeout(100);
|
||||||
|
}}
|
||||||
|
dangerouslySetInnerHTML={{ __html: item.html || "" }}
|
||||||
|
></div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return active.text.el;
|
||||||
|
},
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cx(
|
className={cx(
|
||||||
"flex flex-1 relative overflow-auto ",
|
"flex flex-1 relative overflow-auto ",
|
||||||
css`
|
css`
|
||||||
contain: content;
|
contain: content;
|
||||||
`
|
`,
|
||||||
|
active.hover.id &&
|
||||||
|
active.hover.id !== active.item_id &&
|
||||||
|
css`
|
||||||
|
.s-${active.hover.id} {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&::after {
|
||||||
|
content: " ";
|
||||||
|
pointer-events: none;
|
||||||
|
position: absolute;
|
||||||
|
z-index: 100;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
top: 0;
|
||||||
|
border: 2px solid #b2d2fd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
{/* <div className="absolute bg-white px-1 z-10">{active.hover.id}</div> */}
|
||||||
<div className="absolute inset-0 flex flex-col">
|
<div className="absolute inset-0 flex flex-col">
|
||||||
{!!p.page.building && <Loading backdrop={false} />}
|
{!!p.page.building && <Loading backdrop={false} />}
|
||||||
{!p.page.building && code.mode !== "" && (
|
{!p.page.building && code.mode !== "" && local.el}
|
||||||
<View
|
|
||||||
mode={p.mode}
|
|
||||||
code_mode={code.mode}
|
|
||||||
layout={{ show: false }}
|
|
||||||
isEditor={true}
|
|
||||||
api_url={p.site.config.api_url}
|
|
||||||
component={{
|
|
||||||
async load(id_comp) {
|
|
||||||
await loadComponent(p, id_comp);
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
load={{
|
|
||||||
mode: "tree_meta",
|
|
||||||
meta: p.page.meta,
|
|
||||||
entry: p.page.entry,
|
|
||||||
scope: p.page.scope,
|
|
||||||
}}
|
|
||||||
site_id={p.site.id}
|
|
||||||
page_id={p.page.cur.id}
|
|
||||||
bind={({ render }) => {
|
|
||||||
p.page.render = render;
|
|
||||||
}}
|
|
||||||
hidden={(meta) => {
|
|
||||||
if (meta.item.hidden) return true;
|
|
||||||
return false;
|
|
||||||
}}
|
|
||||||
hover={{
|
|
||||||
get(meta) {
|
|
||||||
return active.hover_id === meta.item.id;
|
|
||||||
},
|
|
||||||
set(meta) {
|
|
||||||
const outer = getOuterItem(meta);
|
|
||||||
if (outer) {
|
|
||||||
active.hover_id = outer.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.render();
|
|
||||||
p.page.render();
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
active={{
|
|
||||||
get(meta) {
|
|
||||||
return active.item_id === meta.item.id;
|
|
||||||
},
|
|
||||||
set(meta) {
|
|
||||||
const outer = getOuterItem(meta);
|
|
||||||
console.log(meta);
|
|
||||||
|
|
||||||
if (outer) {
|
|
||||||
active.item_id = outer.id;
|
|
||||||
}
|
|
||||||
|
|
||||||
p.render();
|
|
||||||
p.page.render();
|
|
||||||
focus();
|
|
||||||
},
|
|
||||||
text({ meta }) {
|
|
||||||
const { item } = meta;
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
return () => {
|
|
||||||
active.text.id = "";
|
|
||||||
p.render();
|
|
||||||
};
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
const updateWithTimeout = (timeout: number) => {
|
|
||||||
return new Promise<void>((resolve) => {
|
|
||||||
const saving = {
|
|
||||||
id: active.text.id,
|
|
||||||
content: active.text.content,
|
|
||||||
};
|
|
||||||
|
|
||||||
clearTimeout(active.text.timeout);
|
|
||||||
active.text.timeout = setTimeout(() => {
|
|
||||||
const meta = getMetaById(p, saving.id);
|
|
||||||
if (meta && meta.mitem) {
|
|
||||||
meta.mitem.set("html", saving.content);
|
|
||||||
}
|
|
||||||
resolve();
|
|
||||||
}, timeout);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (active.text.id !== item.id) {
|
|
||||||
clearTimeout(active.text.timeout);
|
|
||||||
active.text.id = item.id;
|
|
||||||
active.text.content = item.html || "";
|
|
||||||
active.text.el = (
|
|
||||||
<div
|
|
||||||
className={cx(
|
|
||||||
`v-text-${item.id} v-text-${item.originalId} outline-none`
|
|
||||||
)}
|
|
||||||
ref={(ref) => {
|
|
||||||
if (ref !== document.activeElement && ref) {
|
|
||||||
const renaming =
|
|
||||||
document.querySelector(".rename-item");
|
|
||||||
const modals = document.querySelectorAll(
|
|
||||||
"[data-floating-ui-portal]"
|
|
||||||
);
|
|
||||||
if (modals.length === 0 && !renaming) {
|
|
||||||
ref.focus();
|
|
||||||
setEndOfContenteditable(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
onPointerDownCapture={(e) => {
|
|
||||||
e.stopPropagation();
|
|
||||||
}}
|
|
||||||
contentEditable
|
|
||||||
spellCheck={false}
|
|
||||||
onInput={(e) => {
|
|
||||||
const val = e.currentTarget.innerHTML;
|
|
||||||
item.html = val;
|
|
||||||
active.text.id = item.id;
|
|
||||||
active.text.content = val;
|
|
||||||
updateWithTimeout(100);
|
|
||||||
}}
|
|
||||||
dangerouslySetInnerHTML={{ __html: item.html || "" }}
|
|
||||||
></div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return active.text.el;
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ export const EdTreeBody = () => {
|
||||||
const local = useLocal({ tree: null as TreeMethods | null, comp_id: "" });
|
const local = useLocal({ tree: null as TreeMethods | null, comp_id: "" });
|
||||||
const TypedTree = DNDTree<EdMeta>;
|
const TypedTree = DNDTree<EdMeta>;
|
||||||
|
|
||||||
|
active.hover.renderTree = local.render;
|
||||||
|
|
||||||
expandTreeHook(p, local);
|
expandTreeHook(p, local);
|
||||||
|
|
||||||
if (active.comp_id && local.comp_id !== active.comp_id) {
|
if (active.comp_id && local.comp_id !== active.comp_id) {
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,7 @@ import { EdTreeIndent } from "./item/indent";
|
||||||
import { EdTreeName } from "./item/name";
|
import { EdTreeName } from "./item/name";
|
||||||
import { treeItemKeyMap } from "./key-map";
|
import { treeItemKeyMap } from "./key-map";
|
||||||
|
|
||||||
const jsxPropLoadingRender = {} as Record<string, string>;
|
const jsxPropVis = {} as Record<string, string>;
|
||||||
const jsxPropVisCache = {} as Record<string, any>;
|
|
||||||
|
|
||||||
export const nodeRender: NodeRender<EdMeta> = (node, prm) => {
|
export const nodeRender: NodeRender<EdMeta> = (node, prm) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
@ -30,11 +29,29 @@ export const nodeRender: NodeRender<EdMeta> = (node, prm) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (node.data?.jsx_prop_root && node.data?.jsx_prop_name) {
|
if (node.data?.jsx_prop_root && node.data?.jsx_prop_name) {
|
||||||
|
const prop_name = node.data?.jsx_prop_name;
|
||||||
const meta = getMetaById(p, node.data?.parent_item.id);
|
const meta = getMetaById(p, node.data?.parent_item.id);
|
||||||
if (meta) {
|
|
||||||
if (meta.propvis) {
|
if (meta && prop_name && !active.comp_id) {
|
||||||
jsxPropVisCache[meta.item.id] = meta.propvis;
|
if (!meta.propvis) {
|
||||||
if (meta.propvis[node.data.jsx_prop_name] === false) return <></>;
|
if (!meta.parent_mcomp) {
|
||||||
|
setTimeout(local.render, 100);
|
||||||
|
const id = meta.item.originalId || meta.item.id;
|
||||||
|
if (!jsxPropVis[id] || jsxPropVis[id] === prop_name) {
|
||||||
|
jsxPropVis[id] = prop_name;
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={"relative border-b flex items-stretch min-h-[26px]"}
|
||||||
|
>
|
||||||
|
<Loading backdrop={false} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
return <></>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (meta.propvis[prop_name] === false) return <></>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -61,7 +78,7 @@ export const nodeRender: NodeRender<EdMeta> = (node, prm) => {
|
||||||
active.item_id === item.id
|
active.item_id === item.id
|
||||||
? ["bg-blue-100"]
|
? ["bg-blue-100"]
|
||||||
: [isComponent && `bg-purple-50`],
|
: [isComponent && `bg-purple-50`],
|
||||||
active.hover_id === item.id && "bg-blue-50"
|
active.hover.id === item.id && "bg-blue-50"
|
||||||
)}
|
)}
|
||||||
onKeyDown={treeItemKeyMap(p, prm, item)}
|
onKeyDown={treeItemKeyMap(p, prm, item)}
|
||||||
onContextMenu={(event) => {
|
onContextMenu={(event) => {
|
||||||
|
|
@ -80,12 +97,12 @@ export const nodeRender: NodeRender<EdMeta> = (node, prm) => {
|
||||||
p.page.render();
|
p.page.render();
|
||||||
}}
|
}}
|
||||||
onMouseOver={() => {
|
onMouseOver={() => {
|
||||||
active.hover_id = item.id;
|
active.hover.id = item.id;
|
||||||
p.render();
|
active.hover.renderTree();
|
||||||
p.page.render();
|
active.hover.renderMain();
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{active.hover_id === item.id && (
|
{active.hover.id === item.id && (
|
||||||
<div
|
<div
|
||||||
className={cx("absolute left-0 bottom-0 top-0 w-[4px] bg-blue-300")}
|
className={cx("absolute left-0 bottom-0 top-0 w-[4px] bg-blue-300")}
|
||||||
></div>
|
></div>
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ export const produceCSS = (
|
||||||
): string => {
|
): string => {
|
||||||
try {
|
try {
|
||||||
return cx([
|
return cx([
|
||||||
item.name,
|
`s-${item.id}`,
|
||||||
css`
|
css`
|
||||||
display: flex;
|
display: flex;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue