fix
This commit is contained in:
parent
3a50f00936
commit
f42718892a
|
|
@ -2,6 +2,8 @@ import { useGlobal } from "web-utils";
|
|||
import { Loading } from "../../utils/ui/loading";
|
||||
import { EDGlobal } from "./logic/ed-global";
|
||||
import { edRoute } from "./logic/ed-route";
|
||||
import { EdTree } from "./panel/tree/tree";
|
||||
import { EdMain } from "./panel/main/main";
|
||||
|
||||
export const EdBase = () => {
|
||||
const p = useGlobal(EDGlobal, "EDITOR");
|
||||
|
|
@ -22,5 +24,13 @@ export const EdBase = () => {
|
|||
</div>
|
||||
);
|
||||
}
|
||||
return <div>Editor</div>;
|
||||
return (
|
||||
<div className="flex flex-col flex-1">
|
||||
<div className="flex justify-between"></div>
|
||||
<div className="flex flex-1 items-stretch">
|
||||
<EdTree />
|
||||
<EdMain />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -67,6 +67,12 @@ export const EDGlobal = {
|
|||
item: null as null | IItem,
|
||||
list: {} as Record<string, { cur: EComp; doc: DComp }>,
|
||||
},
|
||||
|
||||
ui: {
|
||||
tree: {
|
||||
open: {} as Record<string, string[]>,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export type PG = typeof EDGlobal & { render: () => void };
|
||||
|
|
|
|||
|
|
@ -0,0 +1,3 @@
|
|||
export const EdMain = () => {
|
||||
return <div className="flex flex-1"></div>;
|
||||
};
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
import { Tree as DNDTree, TreeMethods } from "@minoru/react-dnd-treeview";
|
||||
import { useGlobal, useLocal } from "web-utils";
|
||||
import { EDGlobal, EdMeta } from "../../logic/ed-global";
|
||||
import { indentHook } from "./node/item/indent-hook";
|
||||
import { nodeOnDrop } from "./node/on-drop";
|
||||
import { nodeRender } from "./node/render";
|
||||
|
||||
export const EdTreeBody = () => {
|
||||
const p = useGlobal(EDGlobal, "EDITOR");
|
||||
const local = useLocal({ tree: null as TreeMethods | null });
|
||||
const TypedTree = DNDTree<EdMeta>;
|
||||
|
||||
indentHook(p, local);
|
||||
|
||||
return (
|
||||
<TypedTree
|
||||
tree={p.page.tree}
|
||||
rootId={"root"}
|
||||
insertDroppableFirst={false}
|
||||
classes={{
|
||||
container: "flex flex-col",
|
||||
dropTarget: "drop-target",
|
||||
placeholder: "placeholder",
|
||||
draggingSource: css`
|
||||
opacity: 0.3;
|
||||
cursor: not-allowed;
|
||||
`,
|
||||
}}
|
||||
ref={(el) => {
|
||||
local.tree = el;
|
||||
}}
|
||||
sort={false}
|
||||
render={nodeRender}
|
||||
onDrop={nodeOnDrop}
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
import { NodeModel, RenderParams } from "@minoru/react-dnd-treeview";
|
||||
import { EdMeta } from "../../../../logic/ed-global";
|
||||
|
||||
export const EdTreeAction = ({
|
||||
node,
|
||||
prm,
|
||||
}: {
|
||||
node: NodeModel<EdMeta>;
|
||||
prm: RenderParams;
|
||||
}) => {
|
||||
return <></>;
|
||||
};
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import {
|
||||
NodeModel,
|
||||
NodeRender,
|
||||
RenderParams,
|
||||
} from "@minoru/react-dnd-treeview";
|
||||
import { EdMeta } from "../../../../logic/ed-global";
|
||||
|
||||
export const EdTreeCtxMenu = ({
|
||||
node,
|
||||
prm,
|
||||
}: {
|
||||
node: NodeModel<EdMeta>;
|
||||
prm: RenderParams;
|
||||
}) => {
|
||||
return <></>;
|
||||
};
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
import {
|
||||
TreeMethods
|
||||
} from "@minoru/react-dnd-treeview";
|
||||
import { useEffect } from "react";
|
||||
import { PG } from "../../../../logic/ed-global";
|
||||
|
||||
export const indentHook = (
|
||||
p: PG,
|
||||
local: { tree: null | TreeMethods; render: () => void }
|
||||
) => {
|
||||
useEffect(() => {
|
||||
const open = JSON.parse(localStorage.getItem("prasi-tree-open") || "{}");
|
||||
p.ui.tree.open = open;
|
||||
if (open[p.page.cur.id] && local.tree) {
|
||||
local.tree.open(open[p.page.cur.id]);
|
||||
local.render();
|
||||
}
|
||||
}, []);
|
||||
};
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
import { NodeModel, RenderParams } from "@minoru/react-dnd-treeview";
|
||||
import { EDGlobal, EdMeta } from "../../../../logic/ed-global";
|
||||
import { useGlobal } from "web-utils";
|
||||
const DEPTH = 8;
|
||||
export const EdTreeIndent = ({
|
||||
node,
|
||||
prm,
|
||||
}: {
|
||||
node: NodeModel<EdMeta>;
|
||||
prm: RenderParams;
|
||||
}) => {
|
||||
const p = useGlobal(EDGlobal, "EDITOR");
|
||||
const item = node.data?.item;
|
||||
if (!item) return <></>;
|
||||
return (
|
||||
<div
|
||||
className={cx("flex items-stretch cursor-pointer")}
|
||||
onClick={(e) => {
|
||||
e.stopPropagation();
|
||||
|
||||
if (item && item.type !== "text") {
|
||||
if (!p.ui.tree.open[p.page.cur.id]) {
|
||||
p.ui.tree.open[p.page.cur.id] = [];
|
||||
}
|
||||
const open = p.ui.tree.open[p.page.cur.id];
|
||||
if (!prm.isOpen) {
|
||||
open.push(item.id);
|
||||
} else {
|
||||
p.ui.tree.open[p.page.cur.id] = open.filter((e) => e !== item.id);
|
||||
}
|
||||
|
||||
localStorage.setItem(
|
||||
"prasi-tree-open",
|
||||
JSON.stringify(p.ui.tree.open)
|
||||
);
|
||||
prm.onToggle();
|
||||
}
|
||||
}}
|
||||
>
|
||||
<div
|
||||
className={cx(css`
|
||||
width: ${prm.depth * DEPTH}px;
|
||||
`)}
|
||||
></div>
|
||||
<div className={cx("flex items-center justify-center w-[20px]")}>
|
||||
{item.type === "text" && (
|
||||
<div className="-mt-[2px]">
|
||||
<Text />
|
||||
</div>
|
||||
)}
|
||||
{item.type !== "text" && prm.hasChild && (
|
||||
<>{prm.isOpen ? <ChevronDown /> : <ChevronRight />}</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const chevronSize = 13;
|
||||
const sectionSize = 17;
|
||||
|
||||
export const ChevronRight = ({ size: size }: { size?: number }) => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={size || chevronSize}
|
||||
height={size || chevronSize}
|
||||
fill="none"
|
||||
viewBox="0 0 15 15"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M6.158 3.135a.5.5 0 01.707.023l3.75 4a.5.5 0 010 .684l-3.75 4a.5.5 0 11-.73-.684L9.566 7.5l-3.43-3.658a.5.5 0 01.023-.707z"
|
||||
clipRule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const ChevronDown = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={chevronSize}
|
||||
height={chevronSize}
|
||||
fill="none"
|
||||
viewBox="0 0 15 15"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M3.135 6.158a.5.5 0 01.707-.023L7.5 9.565l3.658-3.43a.5.5 0 01.684.73l-4 3.75a.5.5 0 01-.684 0l-4-3.75a.5.5 0 01-.023-.707z"
|
||||
clipRule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
|
||||
export const ItemIcon = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={9}
|
||||
height={9}
|
||||
fill="none"
|
||||
viewBox="0 0 15 15"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M2.857 2h9.286c.473 0 .857.384.857.857v9.286a.857.857 0 01-.857.857H2.857A.857.857 0 012 12.143V2.857C2 2.384 2.384 2 2.857 2zM1 2.857C1 1.831 1.831 1 2.857 1h9.286C13.168 1 14 1.831 14 2.857v9.286A1.857 1.857 0 0112.143 14H2.857A1.857 1.857 0 011 12.143V2.857zM7.5 5a.5.5 0 100-1 .5.5 0 000 1zm-3 6a.5.5 0 100-1 .5.5 0 000 1zM5 7.5a.5.5 0 11-1 0 .5.5 0 011 0zM4.5 5a.5.5 0 100-1 .5.5 0 000 1zm6.5 5.5a.5.5 0 11-1 0 .5.5 0 011 0zM10.5 8a.5.5 0 100-1 .5.5 0 000 1zm.5-3.5a.5.5 0 11-1 0 .5.5 0 011 0zM7.5 11a.5.5 0 100-1 .5.5 0 000 1z"
|
||||
clipRule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const SectionRight = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width={sectionSize}
|
||||
height={sectionSize}
|
||||
fill="none"
|
||||
viewBox="0 0 15 15"
|
||||
>
|
||||
<path fill="currentColor" d="M6 11V4l4.5 3.5L6 11z"></path>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const SectionDown = () => (
|
||||
<svg
|
||||
width={sectionSize}
|
||||
height={sectionSize}
|
||||
viewBox="0 0 15 15"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path d="M4 6H11L7.5 10.5L4 6Z" fill="currentColor"></path>
|
||||
</svg>
|
||||
);
|
||||
|
||||
const Text = () => (
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
width="14"
|
||||
height="14"
|
||||
fill="none"
|
||||
viewBox="0 0 15 15"
|
||||
className="opacity-50 mt-[1px] mb-[-1px]"
|
||||
>
|
||||
<path
|
||||
fill="currentColor"
|
||||
fillRule="evenodd"
|
||||
d="M3.95 2.95V4.5a.45.45 0 01-.9 0v-2a.45.45 0 01.45-.45h8a.45.45 0 01.45.45v2a.45.45 0 11-.9 0V2.95h-3v9.1h1.204a.45.45 0 010 .9h-3.5a.45.45 0 110-.9H6.95v-9.1h-3z"
|
||||
clipRule="evenodd"
|
||||
></path>
|
||||
</svg>
|
||||
);
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
import { NodeModel, RenderParams } from "@minoru/react-dnd-treeview";
|
||||
import { EdMeta } from "../../../../logic/ed-global";
|
||||
|
||||
export const EdTreeName = ({
|
||||
node,
|
||||
prm,
|
||||
}: {
|
||||
node: NodeModel<EdMeta>;
|
||||
prm: RenderParams;
|
||||
}) => {
|
||||
const item = node.data?.item;
|
||||
if (!item) return <></>;
|
||||
return (
|
||||
<div className="text-[14px] flex items-center cursor-pointer flex-1">
|
||||
{item.name}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
import { DropOptions, NodeModel } from "@minoru/react-dnd-treeview";
|
||||
import { EdMeta } from "../../../logic/ed-global";
|
||||
|
||||
export const nodeOnDrop: (
|
||||
tree: NodeModel<EdMeta>[],
|
||||
options: DropOptions<EdMeta>
|
||||
) => void = () => {};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
import { NodeRender } from "@minoru/react-dnd-treeview";
|
||||
import { EdMeta } from "../../../logic/ed-global";
|
||||
import { EdTreeAction } from "./item/action";
|
||||
import { EdTreeCtxMenu } from "./item/ctx-menu";
|
||||
import { EdTreeIndent } from "./item/indent";
|
||||
import { EdTreeName } from "./item/name";
|
||||
import { indentHook } from "./item/indent-hook";
|
||||
|
||||
export const nodeRender: NodeRender<EdMeta> = (node, prm) => {
|
||||
if (!node || !node.data) return <></>;
|
||||
const item = node.data?.item;
|
||||
return (
|
||||
<div className={cx("border-b flex items-stretch hover:bg-blue-50")}>
|
||||
<EdTreeCtxMenu node={node} prm={prm} />
|
||||
<EdTreeIndent node={node} prm={prm} />
|
||||
<EdTreeName node={node} prm={prm} />
|
||||
<EdTreeAction node={node} prm={prm} />
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
import { MultiBackend, getBackendOptions } from "@minoru/react-dnd-treeview";
|
||||
import { DndProvider } from "react-dnd";
|
||||
import { useGlobal } from "web-utils";
|
||||
import { EDGlobal } from "../../logic/ed-global";
|
||||
import { EdTreeBody } from "./body";
|
||||
|
||||
export const EdTree = () => {
|
||||
const p = useGlobal(EDGlobal, "EDITOR");
|
||||
return (
|
||||
<div className="flex flex-col min-w-[300px] relative border-r">
|
||||
<div className=""></div>
|
||||
<div className="flex flex-1 overflow-y-auto overflow-x-hidden">
|
||||
<div className="absolute inset-0">
|
||||
<DndProvider backend={MultiBackend} options={getBackendOptions()}>
|
||||
<EdTreeBody />
|
||||
</DndProvider>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
Loading…
Reference in New Issue