This commit is contained in:
Rizky 2024-01-24 00:14:47 +07:00
parent 7ba849f468
commit 22d6821986
15 changed files with 304 additions and 232 deletions

View File

@ -195,7 +195,6 @@ export const EDGlobal = {
global_prop: [] as string[], global_prop: [] as string[],
ui: { ui: {
zoom: localStorage.zoom || "100%", zoom: localStorage.zoom || "100%",
should_render: false,
side: { prop: true }, side: { prop: true },
layout: { layout: {
left: parseInt(localStorage.getItem("prasi-layout-left") || "250"), left: parseInt(localStorage.getItem("prasi-layout-left") || "250"),

View File

@ -1,132 +1,132 @@
import { compress, decompress } from "wasm-gzip"; import { compress, decompress } from "wasm-gzip";
import { isTextEditing } from "./active/is-editing"; import { isTextEditing } from "./active/is-editing";
import { loadCompSnapshot } from "./comp/load"; import { loadCompSnapshot } from "./comp/load";
import { PG } from "./ed-global"; import { PG, active } from "./ed-global";
import { loadSite } from "./ed-site"; import { loadSite } from "./ed-site";
import { treeRebuild } from "./tree/build"; import { treeRebuild } from "./tree/build";
export const edRoute = async (p: PG) => { export const edRoute = async (p: PG) => {
if (p.status === "ready" || p.status === "init") { if (p.status === "ready" || p.status === "init") {
if (!p.site.domain && !p.site.name) { if (!p.site.domain && !p.site.name) {
p.status = "load-site"; p.status = "load-site";
const site = await p.sync.site.load(p.site.id); const site = await p.sync.site.load(p.site.id);
if (!site) { if (!site) {
p.status = "site-not-found"; p.status = "site-not-found";
p.render(); p.render();
return; return;
} }
await loadSite(p, site, "from-route"); await loadSite(p, site, "from-route");
} }
if ( if (
p.page.cur.id !== params.page_id || p.page.cur.id !== params.page_id ||
!p.page.cur.snapshot || !p.page.cur.snapshot ||
!p.page.list[p.page.cur.id] !p.page.list[p.page.cur.id]
) { ) {
const page = p.page.list[params.page_id]; const page = p.page.list[params.page_id];
if (page && p.page.doc && page.on_update) { if (page && p.page.doc && page.on_update) {
p.page.doc.off("update", page.on_update); p.page.doc.off("update", page.on_update);
const cur = p.page.list[params.page_id]; const cur = p.page.list[params.page_id];
p.page.cur = cur.page; p.page.cur = cur.page;
p.page.doc = cur.doc; p.page.doc = cur.doc;
} }
await reloadPage(p, params.page_id, "load-route"); await reloadPage(p, params.page_id, "load-route");
} }
} }
}; };
export const reloadPage = async (p: PG, page_id: string, note: string) => { export const reloadPage = async (p: PG, page_id: string, note: string) => {
p.status = "reload"; p.status = "reload";
const remotePage = await p.sync.page.load(page_id); const remotePage = await p.sync.page.load(page_id);
if (!remotePage) { if (!remotePage) {
p.status = "page-not-found"; p.status = "page-not-found";
p.render(); p.render();
return; return;
} }
if (remotePage.comps) { if (remotePage.comps) {
for (const [id_comp, c] of Object.entries(remotePage.comps)) { for (const [id_comp, c] of Object.entries(remotePage.comps)) {
if (c && c.snapshot) { if (c && c.snapshot) {
await loadCompSnapshot(p, id_comp, c.snapshot); await loadCompSnapshot(p, id_comp, c.snapshot);
} }
} }
} }
p.page.cur = remotePage; p.page.cur = remotePage;
if (remotePage.snapshot) { if (remotePage.snapshot) {
const doc = new Y.Doc(); const doc = new Y.Doc();
Y.applyUpdate(doc, decompress(remotePage.snapshot)); Y.applyUpdate(doc, decompress(remotePage.snapshot));
let page = p.page.list[remotePage.id]; let page = p.page.list[remotePage.id];
if (!page) { if (!page) {
p.page.list[remotePage.id] = {} as any; p.page.list[remotePage.id] = {} as any;
page = p.page.list[remotePage.id]; page = p.page.list[remotePage.id];
} }
if (page.on_update && page.doc) { if (page.on_update && page.doc) {
page.doc.off("update", page.on_update); page.doc.off("update", page.on_update);
} }
page.on_update = async (bin: Uint8Array, origin: any) => { page.on_update = async (bin: Uint8Array, origin: any) => {
if (origin === "local") return; if (origin === "local") return;
const res = await p.sync.yjs.sv_local( const res = await p.sync.yjs.sv_local(
"page", "page",
p.page.cur.id, p.page.cur.id,
Buffer.from(compress(bin)), Buffer.from(compress(bin))
); );
if (res) { if (res) {
const diff_local = Y.encodeStateAsUpdate( const diff_local = Y.encodeStateAsUpdate(
doc as any, doc as any,
decompress(res.sv), decompress(res.sv)
); );
Y.applyUpdate(doc as any, decompress(res.diff), "local"); Y.applyUpdate(doc as any, decompress(res.diff), "local");
if (!isTextEditing()) { if (!isTextEditing()) {
await treeRebuild(p, { note: note + " page-on-update" }); await treeRebuild(p, { note: note + " page-on-update" });
} }
await p.sync.yjs.diff_local( await p.sync.yjs.diff_local(
"page", "page",
p.page.cur.id, p.page.cur.id,
Buffer.from(compress(diff_local)), Buffer.from(compress(diff_local))
); );
p.ui.syncing = false; p.ui.syncing = false;
p.page.entry = (doc as any) p.page.entry = (doc as any)
.getMap("map") .getMap("map")
.get("root") .get("root")
?.get("childs") ?.get("childs")
?.map((e: any) => e.get("id")) as string[]; ?.map((e: any) => e.get("id")) as string[];
if (p.ui.should_render) p.render(); if (active.should_render_main) p.render();
} }
}; };
doc.on("update", page.on_update); doc.on("update", page.on_update);
p.page.doc = doc as any; p.page.doc = doc as any;
if (p.page.doc) { if (p.page.doc) {
page.page = p.page.cur; page.page = p.page.cur;
page.doc = p.page.doc; page.doc = p.page.doc;
p.page.entry = p.page.doc p.page.entry = p.page.doc
.getMap("map") .getMap("map")
.get("root") .get("root")
?.get("childs") ?.get("childs")
?.map((e) => e.get("id")) as string[]; ?.map((e) => e.get("id")) as string[];
} }
if (p.page.doc) { if (p.page.doc) {
await treeRebuild(p, { note: note + " page-init" }); await treeRebuild(p, { note: note + " page-init" });
} }
} }
p.status = "ready"; p.status = "ready";
p.render(); p.render();
}; };

View File

@ -29,7 +29,7 @@ export const EdAddItem = () => {
const json = { const json = {
id: createId(), id: createId(),
name: `New Item`, name: `new_item`,
type: "item", type: "item",
dim: { w: "full", h: "full" }, dim: { w: "full", h: "full" },
childs: [], childs: [],

View File

@ -33,7 +33,7 @@ export const EdAddText = () => {
const json = { const json = {
id: createId(), id: createId(),
name: `New Text`, name: `new_text`,
type: "text", type: "text",
dim: { w: "full", h: "full" }, dim: { w: "full", h: "full" },
layout: { align: "center", dir: "col", gap: 0 }, layout: { align: "center", dir: "col", gap: 0 },
@ -68,7 +68,7 @@ export const EdAddText = () => {
if (mitem.get("type") === "section") { if (mitem.get("type") === "section") {
const json = { const json = {
id: createId(), id: createId(),
name: `New Item`, name: `new_item`,
type: "item", type: "item",
dim: { w: "full", h: "full" }, dim: { w: "full", h: "full" },
childs: [], childs: [],

View File

@ -105,7 +105,7 @@ const addComponent = (mitem: MItem | MSection, comp: IItem) => {
const addSection = (root: MRoot) => { const addSection = (root: MRoot) => {
const json = { const json = {
id: createId(), id: createId(),
name: `New Section`, name: `new_section`,
type: "section", type: "section",
dim: { w: "full", h: "full" }, dim: { w: "full", h: "full" },
childs: [], childs: [],

View File

@ -5,96 +5,96 @@ import { EDGlobal, IMeta, PG, active } from "../../logic/ed-global";
import { mainPerItemVisit } from "./main-per-item"; import { mainPerItemVisit } from "./main-per-item";
export const EdMain = () => { export const EdMain = () => {
const p = useGlobal(EDGlobal, "EDITOR"); const p = useGlobal(EDGlobal, "EDITOR");
const local = useLocal({ const local = useLocal({
cache: null as any, cache: null as any,
first_load: false, first_load: false,
width: 0, width: 0,
height: 0, height: 0,
}); });
let meta: undefined | IMeta = undefined; let meta: undefined | IMeta = undefined;
if (active.comp_id) { if (active.comp_id) {
if (p.comp.list[active.comp_id]) { if (p.comp.list[active.comp_id]) {
meta = p.comp.list[active.comp_id].meta[active.item_id]; meta = p.comp.list[active.comp_id].meta[active.item_id];
} else { } else {
active.comp_id = ""; active.comp_id = "";
} }
} else { } else {
meta = p.page.meta[active.item_id]; meta = p.page.meta[active.item_id];
} }
if (active.should_render_main) { if (active.should_render_main) {
local.cache = ( local.cache = (
<Vi <Vi
meta={p.page.meta} meta={p.page.meta}
api_url={p.site.config.api_url} api_url={p.site.config.api_url}
site_id={p.site.id} site_id={p.site.id}
page_id={p.page.cur.id} page_id={p.page.cur.id}
entry={p.page.entry} entry={p.page.entry}
api={p.script.api} api={p.script.api}
db={p.script.db} db={p.script.db}
script={{ init_local_effect: p.script.init_local_effect }} script={{ init_local_effect: p.script.init_local_effect }}
visit={(meta, parts) => { visit={(meta, parts) => {
return mainPerItemVisit(p, meta, parts); return mainPerItemVisit(p, meta, parts);
}} }}
onStatusChanged={(status) => { on_status_changed={(status) => {
if (status !== "ready") { if (status !== "ready") {
active.should_render_main = true; active.should_render_main = true;
local.render(); local.render();
} else { } else {
if (!local.first_load) { if (!local.first_load) {
local.first_load = true; local.first_load = true;
active.should_render_main = true; active.should_render_main = true;
local.render(); local.render();
} }
} }
}} }}
/> />
); );
active.should_render_main = false; active.should_render_main = false;
} }
return ( return (
<div <div
className={cx( className={cx(
"flex flex-1 relative overflow-auto", "flex flex-1 relative overflow-auto",
p.mode === "mobile" ? "flex-col items-center" : "", p.mode === "mobile" ? "flex-col items-center" : ""
)} )}
ref={(el) => { ref={(el) => {
if (el) { if (el) {
const bound = el.getBoundingClientRect(); const bound = el.getBoundingClientRect();
if (local.width !== bound.width || local.height !== bound.height) { if (local.width !== bound.width || local.height !== bound.height) {
local.width = bound.width; local.width = bound.width;
local.height = bound.height; local.height = bound.height;
local.render(); local.render();
} }
} }
}} }}
> >
<div className={mainStyle(p, meta)}>{local.cache}</div> <div className={mainStyle(p, meta)}>{local.cache}</div>
</div> </div>
); );
}; };
const mainStyle = (p: PG, meta?: IMeta) => { const mainStyle = (p: PG, meta?: IMeta) => {
let is_active = meta ? isMetaActive(p, meta) : false; let is_active = meta ? isMetaActive(p, meta) : false;
const scale = parseInt(p.ui.zoom.replace("%", "")) / 100; const scale = parseInt(p.ui.zoom.replace("%", "")) / 100;
let width = `${(1 / scale) * 100}%`; let width = `${(1 / scale) * 100}%`;
if (p.mode === "mobile") { if (p.mode === "mobile") {
width = `${(1 / scale) * 375}px`; width = `${(1 / scale) * 375}px`;
} }
return cx( return cx(
"absolute flex", "absolute flex",
css` css`
contain: content; contain: content;
`, `,
p.mode === "mobile" p.mode === "mobile"
? css` ? css`
border-left: 1px solid #ccc; border-left: 1px solid #ccc;
border-right: 1px solid #ccc; border-right: 1px solid #ccc;
background: white; background: white;
@ -103,22 +103,22 @@ const mainStyle = (p: PG, meta?: IMeta) => {
overflow-y: auto; overflow-y: auto;
bottom: 0px; bottom: 0px;
` `
: "inset-0", : "inset-0",
p.mode === "mobile" p.mode === "mobile"
? css` ? css`
width: ${width}; width: ${width};
height: ${`${(1 / scale) * 100}%`}; height: ${`${(1 / scale) * 100}%`};
transform: scale(${scale}); transform: scale(${scale});
transform-origin: 50% 0% 0px; transform-origin: 50% 0% 0px;
` `
: css` : css`
width: ${width}; width: ${width};
height: ${`${(1 / scale) * 100}%`}; height: ${`${(1 / scale) * 100}%`};
transform: scale(${scale}); transform: scale(${scale});
transform-origin: 0% 0% 0px; transform-origin: 0% 0% 0px;
`, `,
active.hover.id && active.hover.id &&
css` css`
.s-${active.hover.id} { .s-${active.hover.id} {
&::after { &::after {
content: " "; content: " ";
@ -132,8 +132,8 @@ const mainStyle = (p: PG, meta?: IMeta) => {
} }
} }
`, `,
is_active && is_active &&
css` css`
.s-${active.item_id} { .s-${active.item_id} {
outline: none; outline: none;
@ -148,6 +148,6 @@ const mainStyle = (p: PG, meta?: IMeta) => {
border: 2px solid #1c88f3; border: 2px solid #1c88f3;
} }
} }
`, `
); );
}; };

View File

@ -34,10 +34,12 @@ export const declareScope = (p: PG, meta: IMeta, monaco: Monaco) => {
for (const path of paths) { for (const path of paths) {
if (path.includes(meta)) { if (path.includes(meta)) {
for (const m of path) { for (const m of path) {
if (m.instances) { if (m) {
cur_path.length = 0; if (m.instances) {
cur_path.length = 0;
}
cur_path.push(m);
} }
cur_path.push(m);
} }
break; break;
} }

View File

@ -11,6 +11,7 @@ import { PanelLink } from "./panel/link";
import { PanelPadding } from "./panel/padding"; import { PanelPadding } from "./panel/padding";
import { SideBox } from "./ui/SideBox"; import { SideBox } from "./ui/SideBox";
import { SideLabel } from "./ui/SideLabel"; import { SideLabel } from "./ui/SideLabel";
import { treeRebuild } from "../../../logic/tree/build";
export const EdStyleAll = () => { export const EdStyleAll = () => {
const p = useGlobal(EDGlobal, "EDITOR"); const p = useGlobal(EDGlobal, "EDITOR");
@ -27,7 +28,7 @@ export const EdStyleAll = () => {
let mitem = meta.mitem; let mitem = meta.mitem;
if (mitem) { if (mitem) {
p.ui.should_render = true; active.should_render_main = true;
mitem.doc?.transact(() => { mitem.doc?.transact(() => {
if (mitem) { if (mitem) {
if (p.mode === "mobile") { if (p.mode === "mobile") {

View File

@ -70,8 +70,6 @@ export const FieldNumUnit: FC<{
local.render(); local.render();
}, [value, unit]); }, [value, unit]);
const [txPending, tx] = useTransition();
useEffect(() => { useEffect(() => {
// Only change the value if the drag was actually started. // Only change the value if the drag was actually started.
const onUpdate = (event: any) => { const onUpdate = (event: any) => {
@ -86,9 +84,7 @@ export const FieldNumUnit: FC<{
local.render(); local.render();
tx(() => { update(local.val + local.unit);
update(local.val + local.unit);
});
} }
}; };
@ -105,7 +101,7 @@ export const FieldNumUnit: FC<{
document.removeEventListener("pointermove", onUpdate); document.removeEventListener("pointermove", onUpdate);
document.removeEventListener("pointerup", onEnd); document.removeEventListener("pointerup", onEnd);
}; };
}, [local.drag.clientX, local.drag.old, local.val]); }, [local.drag.clientX, local.drag.old, local.val, update]);
const onStart = useCallback( const onStart = useCallback(
(event: React.MouseEvent) => { (event: React.MouseEvent) => {

View File

@ -1,8 +1,9 @@
import { NodeModel, RenderParams } from "@minoru/react-dnd-treeview"; import { NodeModel, RenderParams } from "@minoru/react-dnd-treeview";
import { FC, useEffect } from "react"; import { FC, useEffect } from "react";
import { useGlobal, useLocal } from "web-utils"; import { useGlobal, useLocal } from "web-utils";
import { EDGlobal, IMeta, active } from "../../../../logic/ed-global"; import { IItem, MItem } from "../../../../../../utils/types/item";
import { Tooltip } from "../../../../../../utils/ui/tooltip"; import { Tooltip } from "../../../../../../utils/ui/tooltip";
import { EDGlobal, IMeta, PG, active } from "../../../../logic/ed-global";
import { treeRebuild } from "../../../../logic/tree/build"; import { treeRebuild } from "../../../../logic/tree/build";
export const EdTreeName = ({ export const EdTreeName = ({
@ -101,13 +102,15 @@ export const EdTreeName = ({
} }
}} }}
onChange={(e) => { onChange={(e) => {
local.rename = e.target.value.replace(/[\W_]+/g, "_"); local.rename = e.target.value
.replace(/[^a-zA-Z\:\d\s:]+/g, "_")
.toLowerCase();
p.render(); p.render();
}} }}
/> />
) : ( ) : (
<div className="flex flex-col"> <div className="flex flex-col">
<Name name={name} is_jsx_prop={is_jsx_prop} /> <Name name={name} is_jsx_prop={is_jsx_prop} meta={node.data} />
{/* <div className={"text-[9px] text-gray-500 -mt-1"}> {/* <div className={"text-[9px] text-gray-500 -mt-1"}>
{node.id} - {item.originalId} {node.id} - {item.originalId}
</div> */} </div> */}
@ -117,20 +120,22 @@ export const EdTreeName = ({
); );
}; };
const Name: FC<{ name: string; is_jsx_prop: boolean }> = ({ const Name: FC<{ name: string; is_jsx_prop: boolean; meta?: IMeta }> = ({
name, name,
is_jsx_prop, is_jsx_prop,
meta,
}) => { }) => {
if (is_jsx_prop) { if (is_jsx_prop) {
return ( return (
<div className="flex items-center space-x-1"> <div className={cx("flex items-center space-x-1 pr-1")}>
<Tooltip <Tooltip
content={`Type: JSX Prop`} content={`Type: JSX Prop`}
className="flex text-purple-500 border border-purple-400 items-center justify-center font-mono text-[6px] px-[2px]" className="flex text-purple-500 border border-purple-400 items-center justify-center font-mono text-[6px] px-[2px]"
> >
P P
</Tooltip> </Tooltip>
<div>{name}</div> <div className="flex-1">{name}</div>
{meta && meta.mitem && <GenerateJSX mitem={meta.mitem} />}
</div> </div>
); );
} }
@ -153,3 +158,76 @@ const Name: FC<{ name: string; is_jsx_prop: boolean }> = ({
return <div>{name}</div>; return <div>{name}</div>;
}; };
const GenerateJSX: FC<{ mitem: MItem }> = ({ mitem }) => {
const p = useGlobal(EDGlobal, "EDITOR");
return (
<Tooltip
content="Generate JSX"
onClick={() => {
const genJSX = findDefaultJSX(p, mitem);
const ijson = mitem.toJSON() as IItem;
mitem.doc?.transact(() => {
syncronize(mitem as any, {
...genJSX,
name: ijson.name,
id: ijson.id,
hidden: false,
originalId: ijson.originalId,
});
});
treeRebuild(p);
p.render();
}}
>
<div
className="action-script px-1 py-[2px] rounded-sm text-purple-500 bg-white border border-purple-400 opacity-0 transition-all hover:bg-purple-700 hover:text-white hover:border-purple-700"
dangerouslySetInnerHTML={{
__html: `<svg width="9px" height="9px" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M8.69667 0.0403541C8.90859 0.131038 9.03106 0.354857 8.99316 0.582235L8.0902 6.00001H12.5C12.6893 6.00001 12.8625 6.10701 12.9472 6.27641C13.0319 6.4458 13.0136 6.6485 12.8999 6.80001L6.89997 14.8C6.76167 14.9844 6.51521 15.0503 6.30328 14.9597C6.09135 14.869 5.96888 14.6452 6.00678 14.4178L6.90974 9H2.49999C2.31061 9 2.13748 8.893 2.05278 8.72361C1.96809 8.55422 1.98636 8.35151 2.09999 8.2L8.09997 0.200038C8.23828 0.0156255 8.48474 -0.0503301 8.69667 0.0403541ZM3.49999 8.00001H7.49997C7.64695 8.00001 7.78648 8.06467 7.88148 8.17682C7.97648 8.28896 8.01733 8.43723 7.99317 8.5822L7.33027 12.5596L11.5 7.00001H7.49997C7.353 7.00001 7.21347 6.93534 7.11846 6.8232C7.02346 6.71105 6.98261 6.56279 7.00678 6.41781L7.66968 2.44042L3.49999 8.00001Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>`,
}}
></div>
</Tooltip>
);
};
export const findDefaultJSX = (p: PG, mitem: MItem): IItem => {
let resetJSXProp: any = false;
if (mitem && mitem.parent && (mitem.parent as any).get("content")) {
let name = "";
(mitem as any).parent.parent.forEach((e: any, k: any) => {
if (e === mitem.parent) {
name = k;
}
});
if (name) {
try {
const cid = (mitem as any).parent.parent.parent.get("id");
const comp = p.comp.list[cid].doc;
if (comp) {
const mchilds = comp
.getMap("map")
.get("root")
?.get("childs")
?.toJSON() as IItem[];
for (const c of mchilds) {
if (
c &&
c.name &&
c.name.startsWith("jsx:") &&
c.name.substring(4).trim() === name
) {
c.hidden = false;
c.name = name;
c.id = mitem.get("id") || "";
c.originalId = mitem.get("originalId") || "";
resetJSXProp = c;
}
}
}
} catch (e) {}
}
}
return resetJSXProp;
};

View File

@ -52,7 +52,6 @@ export const ViRender: FC<{
} }
if (!meta) return null; if (!meta) return null;
if (meta.item.hidden) return null; if (meta.item.hidden) return null;
if (meta.item.adv?.js || meta.item.component?.id) { if (meta.item.adv?.js || meta.item.component?.id) {

View File

@ -84,13 +84,7 @@ const JsxProp: FC<{
meta: IMeta; meta: IMeta;
passprop: any; passprop: any;
}> = ({ fn, meta, passprop }) => { }> = ({ fn, meta, passprop }) => {
const local = useLocal({ init: false, result: null as any }); return fn({ passprop, meta });
if (!local.init) {
local.init = true;
local.result = fn({ passprop, meta });
}
return local.result;
}; };
export const replacement = { export const replacement = {

View File

@ -1,4 +1,4 @@
import { FC, Suspense } from "react"; import { FC, Suspense, useState } from "react";
import { useGlobal } from "web-utils"; import { useGlobal } from "web-utils";
import { IMeta } from "../ed/logic/ed-global"; import { IMeta } from "../ed/logic/ed-global";
import { viLoad } from "./load/load"; import { viLoad } from "./load/load";
@ -19,7 +19,7 @@ export const Vi: FC<{
script?: { init_local_effect: Record<string, boolean> }; script?: { init_local_effect: Record<string, boolean> };
visit?: VG["visit"]; visit?: VG["visit"];
render_stat?: "enabled" | "disabled"; render_stat?: "enabled" | "disabled";
onStatusChanged?: (status: VG["status"]) => void; on_status_changed?: (status: VG["status"]) => void;
}> = ({ }> = ({
meta, meta,
entry, entry,
@ -30,10 +30,10 @@ export const Vi: FC<{
visit, visit,
script, script,
render_stat: rs, render_stat: rs,
onStatusChanged, on_status_changed,
}) => { }) => {
const vi = useGlobal(ViGlobal, "VI"); const vi = useGlobal(ViGlobal, "VI");
vi.on_status_changes = onStatusChanged; vi.on_status_changes = on_status_changed;
if (rs === "disabled") { if (rs === "disabled") {
render_stat.enabled = false; render_stat.enabled = false;

View File

@ -17,6 +17,7 @@ import { CPInstance } from "./props/CPInstance";
import { CPMaster } from "./props/CPMaster"; import { CPMaster } from "./props/CPMaster";
import { SideBox } from "./ui/SideBox"; import { SideBox } from "./ui/SideBox";
import { SideLabel } from "./ui/SideLabel"; import { SideLabel } from "./ui/SideLabel";
import { treeRebuild } from "../../../../nova/ed/logic/tree/build";
export const ESide = () => { export const ESide = () => {
const p = useGlobal(EditorGlobal, "EDITOR"); const p = useGlobal(EditorGlobal, "EDITOR");

View File

@ -36,7 +36,7 @@ export const cssFont = (
font.family = glbFont.defaultFont; font.family = glbFont.defaultFont;
} }
return cx( const res = cx(
font.color && font.color &&
` `
color: ${font.color}; color: ${font.color};
@ -69,4 +69,6 @@ export const cssFont = (
font-family: ${font.family}; font-family: ${font.family};
` `
); );
return res;
}; };