wip fix select component

This commit is contained in:
Rizky 2023-11-30 22:49:13 +07:00
parent 3e74e0137f
commit 68ecef88ec
13 changed files with 171 additions and 106 deletions

View File

@ -5,7 +5,7 @@ import { MContent } from "../../../../utils/types/general";
import { IItem, MItem } from "../../../../utils/types/item";
import { FNCompDef, FNComponent } from "../../../../utils/types/meta-fn";
import { MSection } from "../../../../utils/types/section";
import { EdMeta, PG } from "../ed-global";
import { EdMeta, PG, active } from "../ed-global";
import { loadCompSnapshot } from "./sync-walk-comp";
import {
ensureMItemProps,
@ -154,6 +154,7 @@ export const syncWalkMap = (
ref_ids = {};
}
const old_id = item.id;
mapItem(mcomp, item, ref_ids);
item.originalId = item.id;
item.id = old_id;

View File

@ -33,7 +33,8 @@ export const EdAddItem = () => {
if (mitem) {
if (meta.item.type === 'text'
|| (meta.item.type === 'item' && meta.item.component?.id)) {
const parent = getMetaById(p, meta.parent_item.id);
const parent_id = meta.parent_item.id;
const parent = getMetaById(p, parent_id === 'root' ? meta.item.id : parent_id);
if (!parent) {
alert('Failed to add text!');
} else {

View File

@ -35,7 +35,8 @@ export const EdAddText = () => {
if (mitem) {
if (meta.item.type === 'text'
|| (meta.item.type === 'item' && meta.item.component?.id)) {
const parent = getMetaById(p, meta.parent_item.id);
const parent_id = meta.parent_item.id;
const parent = getMetaById(p, parent_id === 'root' ? meta.item.id : parent_id);
if (!parent) {
alert('Failed to add text!');
} else {

View File

@ -42,49 +42,104 @@ export const EdMain = () => {
bind={({ render }) => {
p.page.render = render;
}}
hidden={(item) => {
if (item.hidden) return true;
hidden={(meta) => {
if (meta.item.hidden) return true
return false;
}}
hover={{
get(item) {
return active.hover_id === item.id;
get(meta) {
const item = meta.item;
if (item.originalId === active.hover_id || item.id === active.hover_id)
return true;
return false
},
set(id) {
active.hover_id = id;
set(meta) {
if (meta.parent_mcomp) {
const id = meta.parent_mcomp.mitem.get('id');
if (active.instance.item_id !== id) {
const original_id = meta.parent_mcomp.mitem.get('originalId');
if (active.comp_id && original_id) {
active.item_id = original_id;
} else if (id) {
active.item_id = id;
}
p.render();
p.page.render();
return;
}
}
if (active.comp_id) {
if (meta.item.originalId) {
active.hover_id = meta.item.originalId;
} else {
console.error('Failed to hover, original id not found');
}
} else {
active.hover_id = meta.item.id
}
p.render();
p.page.render();
},
}}
active={{
get(item) {
return active.item_id === item.id;
get(meta) {
const item = meta.item;
if (item.originalId === active.item_id || item.id === active.item_id)
return true;
return false
},
set(id) {
active.item_id = id;
set(meta) {
if (meta.parent_mcomp) {
const id = meta.parent_mcomp.mitem.get('id');
const meta = getMetaById(p, id);
if (meta.item.type === 'text') {
setTimeout(async () => {
await waitUntil(() => document.querySelector(`.v-text-${id}`))
const vtext = document.querySelector(`.v-text-${id}`) as HTMLInputElement;
if (vtext)
vtext.focus()
})
if (active.instance.item_id !== id) {
const original_id = meta.parent_mcomp.mitem.get('originalId');
if (active.comp_id && original_id) {
active.item_id = original_id;
} else if (id) {
active.item_id = id;
}
p.render();
p.page.render();
return;
}
}
if (active.comp_id) {
if (meta.item.originalId) {
active.item_id = meta.item.originalId;
} else {
console.error('Failed to select, original id not found');
}
} else {
active.item_id = meta.item.id
}
p.render();
p.page.render();
},
text(item, className) {
text(meta) {
const { item } = meta;
if (active.text.id !== item.id) {
active.text.id = item.id;
active.text.content = item.html;
active.text.content = item.html || "";
}
return <div
className={cx(className, `v-text-${item.id} outline-none`)}
className={cx(`v-text-${item.id} outline-none`)}
contentEditable
autoFocus
spellCheck={false}
@ -99,7 +154,7 @@ export const EdMain = () => {
meta.mitem.set('html', active.text.content)
}
}}
dangerouslySetInnerHTML={{ __html: item.html }}></div>
dangerouslySetInnerHTML={{ __html: item.html || "" }}></div>
}
}}
/>

View File

@ -1,15 +1,18 @@
import { IContent } from "../../../../../../../utils/types/general";
import { PG } from "../../../../../logic/ed-global";
import { treeRebuild } from "../../../../../logic/tree/build";
import { getMetaById, treeRebuild } from "../../../../../logic/tree/build";
export const edActionDelete = async (p: PG, item: IContent) => {
const mitem = p.page.meta[item.id].mitem;
if (mitem) {
mitem.parent.forEach((e, k) => {
if (e == mitem) {
mitem.parent.delete(k);
}
});
await treeRebuild(p);
const meta = getMetaById(p, item.id);
if (meta) {
const mitem = meta.mitem;
if (mitem) {
mitem.parent.forEach((e, k) => {
if (e == mitem) {
mitem.parent.delete(k);
}
});
await treeRebuild(p);
}
}
};

View File

@ -74,7 +74,7 @@ export const EdTreeName = ({
) : (
<div className="flex flex-col">
<Name name={node.text} is_jsx_prop={is_jsx_prop} />
{/* <div className={"text-[11px] text-gray-500 -mt-1"}>{item.id}</div> */}
<div className={"text-[9px] text-gray-500 -mt-1"}>{item.id} - {item.originalId}</div>
</div>
)}
</div>

View File

@ -156,18 +156,22 @@ export const treeItemKeyMap = (p: PG, prm: RenderParams, item: IContent) => {
if (e.key === "Backspace" || e.key === "Delete") {
let last = "";
let found = null as HTMLInputElement | null;
p.page.meta[item.id].parent_item.mitem?.get("childs")?.forEach((e) => {
if (e.get("id") === item.id) {
const meta = getMetaById(p, item.id);
if (meta) {
meta.parent_item.mitem?.get("childs")?.forEach((e) => {
if (e.get("id") === item.id) {
found = document.querySelector(`.tree-${last}`);
}
if (!found) {
last = e.get("id");
}
});
if (!found) {
last = meta.parent_item.mitem?.get("id") || "";
found = document.querySelector(`.tree-${last}`);
}
if (!found) {
last = e.get("id");
}
});
if (!found) {
last = p.page.meta[item.id].parent_item.mitem?.get("id") || "";
found = document.querySelector(`.tree-${last}`);
}
edActionDelete(p, item);

View File

@ -20,17 +20,17 @@ export const ViewGlobal = {
api: null as any,
},
view: {
hidden: undefined as undefined | ((item: IContent) => boolean),
hidden: undefined as undefined | ((meta: EdMeta) => boolean),
active: undefined as
| undefined
| {
get: (item: IContent) => boolean;
set: (id: string) => void;
text?: (item: IText) => ReactNode
get: (meta: EdMeta) => boolean;
set: (meta: EdMeta) => void;
text?: (meta: EdMeta) => ReactNode
},
hover: undefined as
| undefined
| { get: (item: IContent) => boolean; set: (id: string) => void },
| { get: (meta: EdMeta) => boolean; set: (meta: EdMeta) => void },
},
};

View File

@ -1,39 +1,40 @@
import { FC, Fragment, ReactNode } from "react";
import { useGlobal } from "web-utils";
import { IItem } from "../../../../utils/types/item";
import { ISection } from "../../../../utils/types/section";
import { IText } from "../../../../utils/types/text";
import { EdMeta } from "../../../ed/logic/ed-global";
import { ViewGlobal } from "../../logic/global";
import { ViewMeta } from "./meta";
export const ViewMetaChildren: FC<{ item: IItem | IText | ISection, className?: string }> = ({
item,
export const ViewMetaChildren: FC<{
meta: EdMeta,
className?: string
}> = ({
meta,
className
}) => {
const v = useGlobal(ViewGlobal, "VIEW");
const children: Record<string, ReactNode> = {};
if (item.type !== "text") {
for (const child of item.childs) {
if (child.id) {
children[child.id] = (<ViewMeta id={child.id} key={child.id} />);
const v = useGlobal(ViewGlobal, "VIEW");
const children: Record<string, ReactNode> = {};
const item = meta.item;
if (item.type !== "text") {
for (const child of item.childs) {
if (child.id) {
children[child.id] = (<ViewMeta id={child.id} key={child.id} />);
}
}
} else {
if (item.id) {
if (v.view.active?.text && v.view.active?.get(meta)) {
children[item.id] = <Fragment key={item.id}>
{v.view.active.text(meta)}
</Fragment>;
} else {
children[item.id] = <span
key={item.id}
dangerouslySetInnerHTML={{ __html: item.html || '&nbsp;' }
}>
</span >;
}
}
}
} else {
if (item.id) {
if (v.view.active?.text && v.view.active?.get(item)) {
children[item.id] = <Fragment key={item.id}>
{v.view.active.text(item)}
</Fragment>;
} else {
children[item.id] = <span
key={item.id}
dangerouslySetInnerHTML={{ __html: item.html || '&nbsp;' }
}>
</span >;
}
}
}
return <>{Object.values(children)}</>;
};
return <>{item.id}{Object.values(children)}</>;
};

View File

@ -24,7 +24,7 @@ export const ViewMeta: FC<{ id: string; scopeIndex?: Record<string, any> }> = ({
}
if (item.hidden && v.view.hidden) {
if (v.view.hidden(item)) {
if (v.view.hidden(meta)) {
return null;
}
}

View File

@ -14,17 +14,17 @@ export const ViewMetaRender: FC<{
const item = meta.item;
if (meta.is_layout && !v.layout.show) {
return <ViewMetaChildren key={item.id} item={item} />;
return <ViewMetaChildren key={item.id} meta={meta} />;
}
if (!className) {
_className = produceCSS(item, {
mode: v.mode,
hover: v.view.hover ? v.view.hover.get(item) : undefined,
active: v.view.active ? v.view.active.get(item) : undefined,
hover: v.view.hover ? v.view.hover.get(meta) : undefined,
active: v.view.active ? v.view.active.get(meta) : undefined,
});
}
return (
<div
className={_className}
@ -32,23 +32,23 @@ export const ViewMetaRender: FC<{
onPointerOver={
v.view.hover
? (e) => {
e.stopPropagation();
e.preventDefault();
v.view.hover?.set(item.id);
}
e.stopPropagation();
e.preventDefault();
v.view.hover?.set(meta);
}
: props?.onPointerOver
}
onClick={
v.view.active
? (e) => {
e.stopPropagation();
e.preventDefault();
v.view.active?.set(item.id);
}
e.stopPropagation();
e.preventDefault();
v.view.active?.set(meta);
}
: props?.onClick
}
>
<ViewMetaChildren item={item} />
<ViewMetaChildren meta={meta} />
</div>
);
};

View File

@ -23,10 +23,10 @@ export const ViewMetaScript: FC<{
const w = window as any;
const className = produceCSS(item, {
mode: v.mode,
hover: v.view.hover ? v.view.hover.get(item) : undefined,
active: v.view.active ? v.view.active.get(item) : undefined,
hover: v.view.hover ? v.view.hover.get(meta) : undefined,
active: v.view.active ? v.view.active.get(meta) : undefined,
});
const children = <ViewMetaChildren key={item.id} item={item} />;
const children = <ViewMetaChildren key={item.id} meta={meta} />;
let args = {};
if (js && meta) {
@ -86,14 +86,14 @@ export const ViewMetaScript: FC<{
? (e: any) => {
e.stopPropagation();
e.preventDefault();
v.view.hover?.set(item.id);
v.view.hover?.set(meta);
}
: undefined,
onClick: v.view.active
? (e: any) => {
e.stopPropagation();
e.preventDefault();
v.view.active?.set(item.id);
v.view.active?.set(meta);
}
: undefined,
},

View File

@ -1,8 +1,7 @@
import { FC, ReactNode, Suspense } from "react";
import { useGlobal } from "web-utils";
import { IContent } from "../../utils/types/general";
import { IText } from "../../utils/types/text";
import { Loading } from "../../utils/ui/loading";
import { EdMeta } from "../ed/logic/ed-global";
import { ViewGlobal } from "./logic/global";
import { vInit } from "./logic/init";
import { newLoadCode } from "./logic/load-code-new";
@ -22,12 +21,12 @@ type ViewProp = {
layout?: { show: boolean };
isEditor?: boolean;
bind?: (arg: { render: () => void }) => void;
hidden?: (item: IContent) => boolean;
hover?: { get: (item: IContent) => boolean; set: (id: string) => void };
hidden?: (item: EdMeta) => boolean;
hover?: { get: (item: EdMeta) => boolean; set: (meta: EdMeta) => void };
active?: {
get: (item: IContent) => boolean;
set: (id: string) => void;
text?: (item: IText, className: string) => ReactNode
get: (item: EdMeta) => boolean;
set: (item: EdMeta) => void;
text?: (item: EdMeta) => ReactNode
};
};