wip fix prop
This commit is contained in:
parent
73dba58f36
commit
d92ae3305e
|
|
@ -7,7 +7,7 @@ import {
|
||||||
} from "@minoru/react-dnd-treeview";
|
} from "@minoru/react-dnd-treeview";
|
||||||
import { FC } from "react";
|
import { FC } from "react";
|
||||||
import { HTML5Backend } from "react-dnd-html5-backend";
|
import { HTML5Backend } from "react-dnd-html5-backend";
|
||||||
import { useGlobal } from "web-utils";
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
import { IItem } from "../../../../utils/types/item";
|
import { IItem } from "../../../../utils/types/item";
|
||||||
import { EDGlobal, EdMeta } from "../../logic/ed-global";
|
import { EDGlobal, EdMeta } from "../../logic/ed-global";
|
||||||
import { EdPropCompTreeItem, PropItem } from "./prop-comp/tree-item";
|
import { EdPropCompTreeItem, PropItem } from "./prop-comp/tree-item";
|
||||||
|
|
@ -18,7 +18,7 @@ const propRef = {
|
||||||
|
|
||||||
export const EdSidePropComp: FC<{ meta: EdMeta }> = ({ meta }) => {
|
export const EdSidePropComp: FC<{ meta: EdMeta }> = ({ meta }) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
const local = useLocal({});
|
||||||
const item = meta?.item as IItem;
|
const item = meta?.item as IItem;
|
||||||
if (!item) return null;
|
if (!item) return null;
|
||||||
const TypedTree = DNDTree<PropItem>;
|
const TypedTree = DNDTree<PropItem>;
|
||||||
|
|
@ -94,7 +94,13 @@ export const EdSidePropComp: FC<{ meta: EdMeta }> = ({ meta }) => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
render={EdPropCompTreeItem}
|
render={(node, params) => (
|
||||||
|
<EdPropCompTreeItem
|
||||||
|
node={node}
|
||||||
|
params={params}
|
||||||
|
render={local.render}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
rootId={"root"}
|
rootId={"root"}
|
||||||
classes={treeClasses}
|
classes={treeClasses}
|
||||||
dropTargetOffset={10}
|
dropTargetOffset={10}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
import { PG } from "../../../logic/ed-global";
|
||||||
|
|
||||||
|
export const createEditScript = (p: PG, name: string) => {
|
||||||
|
return () => {};
|
||||||
|
};
|
||||||
|
|
@ -0,0 +1,250 @@
|
||||||
|
import { FC } from "react";
|
||||||
|
import { FMCompDef, FNCompDef } from "../../../../../utils/types/meta-fn";
|
||||||
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
|
import { TypedMap } from "yjs-types";
|
||||||
|
import { createEditScript } from "./edit-script";
|
||||||
|
import { EDGlobal } from "../../../logic/ed-global";
|
||||||
|
|
||||||
|
export const propPopover = {
|
||||||
|
name: "",
|
||||||
|
};
|
||||||
|
|
||||||
|
export const EdPropPopover: FC<{ mprop: FMCompDef; name: string }> = ({
|
||||||
|
mprop,
|
||||||
|
name,
|
||||||
|
}) => {
|
||||||
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
const mmeta = mprop.get("meta");
|
||||||
|
const local = useLocal({
|
||||||
|
name,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!mmeta) return null;
|
||||||
|
const type = mmeta.get("type");
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"flex text-sm flex-col items-stretch space-y-1 py-1 w-[300px]"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="px-2 py-1 flex space-x-1">
|
||||||
|
{[
|
||||||
|
{ label: "TXT", type: "text" },
|
||||||
|
{ label: "OPT", type: "option" },
|
||||||
|
{ label: "JSX", type: "content-element" },
|
||||||
|
].map((e) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={e.type}
|
||||||
|
className={cx(
|
||||||
|
type === e.type
|
||||||
|
? "bg-blue-500 text-white"
|
||||||
|
: "hover:bg-blue-100",
|
||||||
|
" px-2 cursor-pointer"
|
||||||
|
)}
|
||||||
|
onClick={() => {
|
||||||
|
mmeta.set("type", e.type as any);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{e.label}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
<div className="border-t border-slate-300 px-2 pt-2 pb-1 flex flex-col items-stretch">
|
||||||
|
<div className="uppercase text-xs text-slate-500">Name</div>
|
||||||
|
<input
|
||||||
|
spellCheck={false}
|
||||||
|
type="text"
|
||||||
|
className="p-1 outline-none border focus:border-blue-500"
|
||||||
|
value={local.name}
|
||||||
|
onChange={(e) => {
|
||||||
|
local.name = e.currentTarget.value
|
||||||
|
.toLowerCase()
|
||||||
|
.replace(/\W/gi, "_");
|
||||||
|
local.render();
|
||||||
|
}}
|
||||||
|
onBlur={() => {
|
||||||
|
if (local.name !== name) {
|
||||||
|
const keys = Object.keys(mprop.parent?.toJSON());
|
||||||
|
if ([...keys, ...keywords].includes(local.name)) {
|
||||||
|
alert(`Cannot use "${local.name}" as name`);
|
||||||
|
local.name = name;
|
||||||
|
local.render();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mprop.doc?.transact(() => {
|
||||||
|
const parent = mprop.parent as TypedMap<
|
||||||
|
Record<string, FMCompDef>
|
||||||
|
>;
|
||||||
|
parent.set(local.name, parent.get(name)?.clone() as any);
|
||||||
|
parent.delete(name);
|
||||||
|
});
|
||||||
|
propPopover.name = local.name;
|
||||||
|
local.render();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter") {
|
||||||
|
e.currentTarget.blur();
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{type === "content-element" && (
|
||||||
|
<div className="border-t border-slate-300 pl-2 pt-1 flex justify-between items-center">
|
||||||
|
<div className="uppercase text-xs label self-stretch flex items-center">
|
||||||
|
Visible
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="m-1 px-1 bg-white cursor-pointer hover:bg-blue-500 hover:text-white hover:border-blue-500 font-mono border border-slate-300 text-[11px]"
|
||||||
|
onClick={createEditScript(p, "master-visible")}
|
||||||
|
>
|
||||||
|
EDIT CODE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{type !== "content-element" && (
|
||||||
|
<>
|
||||||
|
<div
|
||||||
|
className={cx(
|
||||||
|
"border-t border-slate-300 pl-2 flex justify-between items-center",
|
||||||
|
css`
|
||||||
|
margin-bottom: -0.25rem !important;
|
||||||
|
|
||||||
|
> .label {
|
||||||
|
padding-top: 0.75rem;
|
||||||
|
padding-bottom: 0.75rem;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div className="uppercase text-xs label self-stretch flex items-center">
|
||||||
|
Generator
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="m-1 px-1 bg-white cursor-pointer hover:bg-blue-500 hover:text-white hover:border-blue-500 font-mono border border-slate-300 text-[11px] flex "
|
||||||
|
onClick={createEditScript(p, "master-gen")}
|
||||||
|
>
|
||||||
|
EDIT CODE
|
||||||
|
</div>
|
||||||
|
<div className=" border-l border-slate-300 mr-2 self-stretch"></div>
|
||||||
|
<div className="uppercase text-xs label self-stretch flex items-center">
|
||||||
|
Visible
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className="m-1 px-1 bg-white cursor-pointer hover:bg-blue-500 hover:text-white hover:border-blue-500 font-mono border border-slate-300 text-[11px]"
|
||||||
|
onClick={createEditScript(p, "master-visible")}
|
||||||
|
>
|
||||||
|
EDIT CODE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="border-t border-slate-300 pl-2 pt-1 flex justify-between items-center">
|
||||||
|
<div className="uppercase text-xs">VALUE</div>
|
||||||
|
<div
|
||||||
|
className="m-1 px-1 bg-white cursor-pointer hover:bg-blue-500 hover:text-white hover:border-blue-500 font-mono border border-slate-300 text-[11px]"
|
||||||
|
onClick={createEditScript(p, "master-value")}
|
||||||
|
>
|
||||||
|
EDIT CODE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{type === "option" && (
|
||||||
|
<div className="border-t border-slate-300 pl-2 pt-1 flex justify-between items-center select-none">
|
||||||
|
<div className="uppercase text-xs">MODE</div>
|
||||||
|
|
||||||
|
<div className="flex pr-1">
|
||||||
|
{["button", "dropdown"].map((e) => (
|
||||||
|
<div
|
||||||
|
key={e}
|
||||||
|
onClick={() => {
|
||||||
|
const meta = mprop.get("meta");
|
||||||
|
if (meta) {
|
||||||
|
meta.set("option_mode", e as any);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
className={cx(
|
||||||
|
"m-1 px-1 capitalize text-center cursor-pointer font-mono border border-slate-300 text-[11px]",
|
||||||
|
e === mmeta.get("option_mode") ||
|
||||||
|
(e === "button" && !mmeta.get("option_mode"))
|
||||||
|
? "bg-blue-500 text-white"
|
||||||
|
: `hover:bg-blue-500 hover:text-white bg-white hover:border-blue-500`
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{e}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{type === "option" && (
|
||||||
|
<div className="border-t border-slate-300 pl-2 pt-1 flex justify-between items-center">
|
||||||
|
<div className="uppercase text-xs">OPTIONS</div>
|
||||||
|
|
||||||
|
<div
|
||||||
|
className="m-1 px-1 bg-white cursor-pointer hover:bg-blue-500 hover:text-white hover:border-blue-500 font-mono border border-slate-300 text-[11px]"
|
||||||
|
onClick={createEditScript(p, "master-option")}
|
||||||
|
>
|
||||||
|
EDIT CODE
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const keywords = [
|
||||||
|
"await",
|
||||||
|
"break",
|
||||||
|
"case",
|
||||||
|
"catch",
|
||||||
|
"class",
|
||||||
|
"const",
|
||||||
|
"continue",
|
||||||
|
"debugger",
|
||||||
|
"default",
|
||||||
|
"delete",
|
||||||
|
"do",
|
||||||
|
"else",
|
||||||
|
"enum",
|
||||||
|
"export",
|
||||||
|
"extends",
|
||||||
|
"false",
|
||||||
|
"finally",
|
||||||
|
"for",
|
||||||
|
"function",
|
||||||
|
"if",
|
||||||
|
"implements",
|
||||||
|
"import",
|
||||||
|
"in",
|
||||||
|
"instanceof",
|
||||||
|
"interface",
|
||||||
|
"let",
|
||||||
|
"new",
|
||||||
|
"null",
|
||||||
|
"package",
|
||||||
|
"private",
|
||||||
|
"protected",
|
||||||
|
"public",
|
||||||
|
"return",
|
||||||
|
"super",
|
||||||
|
"switch",
|
||||||
|
"static",
|
||||||
|
"this",
|
||||||
|
"throw",
|
||||||
|
"try",
|
||||||
|
"true",
|
||||||
|
"typeof",
|
||||||
|
"var",
|
||||||
|
"void",
|
||||||
|
"while",
|
||||||
|
"with",
|
||||||
|
"yield",
|
||||||
|
];
|
||||||
|
|
@ -1,6 +1,9 @@
|
||||||
import { NodeRender } from "@minoru/react-dnd-treeview";
|
import { NodeRender } from "@minoru/react-dnd-treeview";
|
||||||
|
import { FC } from "react";
|
||||||
import { MItem } from "../../../../../utils/types/item";
|
import { MItem } from "../../../../../utils/types/item";
|
||||||
import { FMCompDef, FNCompDef } from "../../../../../utils/types/meta-fn";
|
import { FMCompDef, FNCompDef } from "../../../../../utils/types/meta-fn";
|
||||||
|
import { Popover } from "../../../../../utils/ui/popover";
|
||||||
|
import { EdPropPopover, propPopover } from "./prop-popover";
|
||||||
|
|
||||||
export type PropItem = {
|
export type PropItem = {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
@ -9,8 +12,12 @@ export type PropItem = {
|
||||||
prop: FNCompDef;
|
prop: FNCompDef;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const EdPropCompTreeItem: NodeRender<PropItem> = (node, params) => {
|
export const EdPropCompTreeItem: FC<{
|
||||||
if (node.id === "root" || node.id === 'proot') {
|
node: Parameters<NodeRender<PropItem>>[0];
|
||||||
|
params: Parameters<NodeRender<PropItem>>[1];
|
||||||
|
render: () => void;
|
||||||
|
}> = ({ node, params, render }) => {
|
||||||
|
if (node.id === "root" || node.id === "proot") {
|
||||||
return <></>;
|
return <></>;
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
|
|
@ -34,9 +41,27 @@ export const EdPropCompTreeItem: NodeRender<PropItem> = (node, params) => {
|
||||||
></path>
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 pl-1 hover:bg-blue-100 cursor-pointer">
|
{node.data && (
|
||||||
{node.text}
|
<Popover
|
||||||
</div>
|
placement="left-start"
|
||||||
|
autoFocus={false}
|
||||||
|
backdrop={false}
|
||||||
|
open={propPopover.name === node.text}
|
||||||
|
popoverClassName="bg-white shadow-lg border border-slate-300"
|
||||||
|
onOpenChange={(open) => {
|
||||||
|
if (!open) {
|
||||||
|
propPopover.name = "";
|
||||||
|
} else {
|
||||||
|
propPopover.name = node.text;
|
||||||
|
}
|
||||||
|
render();
|
||||||
|
}}
|
||||||
|
content={<EdPropPopover mprop={node.data.mprop} name={node.text} />}
|
||||||
|
className="flex-1 pl-1 hover:bg-blue-100 cursor-pointer"
|
||||||
|
>
|
||||||
|
{node.text}
|
||||||
|
</Popover>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue