wip fix
This commit is contained in:
parent
1cac5e3f33
commit
3379ed2ed8
|
|
@ -10,6 +10,7 @@ import { EdPropInstanceOptions } from "./prop-instance/prop-option";
|
||||||
import { reset } from "./prop-instance/prop-reset";
|
import { reset } from "./prop-instance/prop-reset";
|
||||||
import { EdPropInstanceText } from "./prop-instance/prop-text";
|
import { EdPropInstanceText } from "./prop-instance/prop-text";
|
||||||
import { EdStyleAll } from "./style/side-all";
|
import { EdStyleAll } from "./style/side-all";
|
||||||
|
import { EdPropInstanceFile } from "./prop-instance/prop-file";
|
||||||
|
|
||||||
export const EdSidePropInstance: FC<{ meta: IMeta }> = ({ meta }) => {
|
export const EdSidePropInstance: FC<{ meta: IMeta }> = ({ meta }) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
|
@ -215,8 +216,12 @@ export const EdSidePropInstance: FC<{ meta: IMeta }> = ({ meta }) => {
|
||||||
(![`"`, "'", "`"].includes(value[0]) ||
|
(![`"`, "'", "`"].includes(value[0]) ||
|
||||||
![`"`, "'", "`"].includes(value[value.length - 1]))
|
![`"`, "'", "`"].includes(value[value.length - 1]))
|
||||||
) {
|
) {
|
||||||
hasCode = true;
|
hasCode = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type === "file" && !value.startsWith("siteurl("))
|
||||||
|
hasCode = true;
|
||||||
|
|
||||||
if (value.length > 100) {
|
if (value.length > 100) {
|
||||||
hasCode = true;
|
hasCode = true;
|
||||||
}
|
}
|
||||||
|
|
@ -238,6 +243,7 @@ export const EdSidePropInstance: FC<{ meta: IMeta }> = ({ meta }) => {
|
||||||
<EdPropInstanceCode
|
<EdPropInstanceCode
|
||||||
mprop={mprop}
|
mprop={mprop}
|
||||||
name={name}
|
name={name}
|
||||||
|
comp_id={comp_id}
|
||||||
label={cprop.label}
|
label={cprop.label}
|
||||||
labelClick={labelClick}
|
labelClick={labelClick}
|
||||||
onEditCode={createEditScript(p, "value", mprop, name)}
|
onEditCode={createEditScript(p, "value", mprop, name)}
|
||||||
|
|
@ -245,6 +251,14 @@ export const EdSidePropInstance: FC<{ meta: IMeta }> = ({ meta }) => {
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
|
{type === "file" && (
|
||||||
|
<EdPropInstanceFile
|
||||||
|
mprop={mprop}
|
||||||
|
label={cprop.label}
|
||||||
|
name={name}
|
||||||
|
labelClick={labelClick}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
{type === "text" && (
|
{type === "text" && (
|
||||||
<EdPropInstanceText
|
<EdPropInstanceText
|
||||||
mprop={mprop}
|
mprop={mprop}
|
||||||
|
|
|
||||||
|
|
@ -3,17 +3,19 @@ import { FMCompDef } from "../../../../../utils/types/meta-fn";
|
||||||
import { EdPropLabel } from "./prop-label";
|
import { EdPropLabel } from "./prop-label";
|
||||||
import { useGlobal } from "web-utils";
|
import { useGlobal } from "web-utils";
|
||||||
import { EDGlobal, active } from "../../../logic/ed-global";
|
import { EDGlobal, active } from "../../../logic/ed-global";
|
||||||
|
import { reset } from "./prop-reset";
|
||||||
|
|
||||||
export const EdPropInstanceCode: FC<{
|
export const EdPropInstanceCode: FC<{
|
||||||
label?: string;
|
label?: string;
|
||||||
name: string;
|
name: string;
|
||||||
mprop: FMCompDef;
|
mprop: FMCompDef;
|
||||||
|
comp_id: string;
|
||||||
labelClick?: React.MouseEventHandler<HTMLDivElement> | undefined;
|
labelClick?: React.MouseEventHandler<HTMLDivElement> | undefined;
|
||||||
onEditCode: React.MouseEventHandler<HTMLDivElement> | undefined;
|
onEditCode: React.MouseEventHandler<HTMLDivElement> | undefined;
|
||||||
}> = ({ label, name, labelClick, onEditCode }) => {
|
}> = ({ label, name, labelClick, onEditCode, comp_id, mprop }) => {
|
||||||
const p = useGlobal(EDGlobal, "EDITOR");
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
return (
|
return (
|
||||||
<div className="flex items-center min-h-[28px]">
|
<div className="flex items-center min-h-[28px]">
|
||||||
<EdPropLabel name={label || name} labelClick={labelClick} />
|
<EdPropLabel name={label || name} labelClick={labelClick} />
|
||||||
<div className="flex-1 flex justify-end pr-1">
|
<div className="flex-1 flex justify-end pr-1">
|
||||||
<div
|
<div
|
||||||
|
|
@ -27,6 +29,9 @@ export const EdPropInstanceCode: FC<{
|
||||||
className={
|
className={
|
||||||
"my-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 items-center"
|
"my-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 items-center"
|
||||||
}
|
}
|
||||||
|
onClick={() => {
|
||||||
|
reset(p, comp_id, mprop, name);
|
||||||
|
}}
|
||||||
dangerouslySetInnerHTML={{
|
dangerouslySetInnerHTML={{
|
||||||
__html: `<svg width="12" height="12" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4.85355 2.14645C5.04882 2.34171 5.04882 2.65829 4.85355 2.85355L3.70711 4H9C11.4853 4 13.5 6.01472 13.5 8.5C13.5 10.9853 11.4853 13 9 13H5C4.72386 13 4.5 12.7761 4.5 12.5C4.5 12.2239 4.72386 12 5 12H9C10.933 12 12.5 10.433 12.5 8.5C12.5 6.567 10.933 5 9 5H3.70711L4.85355 6.14645C5.04882 6.34171 5.04882 6.65829 4.85355 6.85355C4.65829 7.04882 4.34171 7.04882 4.14645 6.85355L2.14645 4.85355C1.95118 4.65829 1.95118 4.34171 2.14645 4.14645L4.14645 2.14645C4.34171 1.95118 4.65829 1.95118 4.85355 2.14645Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>`,
|
__html: `<svg width="12" height="12" viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg"><path d="M4.85355 2.14645C5.04882 2.34171 5.04882 2.65829 4.85355 2.85355L3.70711 4H9C11.4853 4 13.5 6.01472 13.5 8.5C13.5 10.9853 11.4853 13 9 13H5C4.72386 13 4.5 12.7761 4.5 12.5C4.5 12.2239 4.72386 12 5 12H9C10.933 12 12.5 10.433 12.5 8.5C12.5 6.567 10.933 5 9 5H3.70711L4.85355 6.14645C5.04882 6.34171 5.04882 6.65829 4.85355 6.85355C4.65829 7.04882 4.34171 7.04882 4.14645 6.85355L2.14645 4.85355C1.95118 4.65829 1.95118 4.34171 2.14645 4.14645L4.14645 2.14645C4.34171 1.95118 4.65829 1.95118 4.85355 2.14645Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg>`,
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,115 @@
|
||||||
|
import {
|
||||||
|
FC,
|
||||||
|
TextareaHTMLAttributes,
|
||||||
|
useCallback,
|
||||||
|
useEffect,
|
||||||
|
useRef,
|
||||||
|
} from "react";
|
||||||
|
import { useGlobal, useLocal } from "web-utils";
|
||||||
|
import { FMCompDef } from "../../../../../utils/types/meta-fn";
|
||||||
|
import { EdPropLabel } from "./prop-label";
|
||||||
|
import { treeRebuild } from "../../../logic/tree/build";
|
||||||
|
import { EDGlobal } from "../../../logic/ed-global";
|
||||||
|
|
||||||
|
export const EdPropInstanceFile: FC<{
|
||||||
|
name: string;
|
||||||
|
label?: string;
|
||||||
|
mprop: FMCompDef;
|
||||||
|
labelClick?: React.MouseEventHandler<HTMLDivElement> | undefined;
|
||||||
|
}> = ({ label, name, mprop, labelClick }) => {
|
||||||
|
const p = useGlobal(EDGlobal, "EDITOR");
|
||||||
|
const val = mprop.get("value");
|
||||||
|
|
||||||
|
const local = useLocal({
|
||||||
|
value: unquote(val),
|
||||||
|
codeEditing: false,
|
||||||
|
timeout: null as any,
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
local.value = unquote(val);
|
||||||
|
local.render();
|
||||||
|
}, [val]);
|
||||||
|
|
||||||
|
const is_file = local.value.startsWith("siteurl(");
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex items-stretch min-h-[28px]">
|
||||||
|
<EdPropLabel name={label || name} labelClick={labelClick} />
|
||||||
|
<div className={cx("border-l flex-1")}></div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const unquote = (text: any) => {
|
||||||
|
if (typeof text === "string") {
|
||||||
|
const str = text.trim();
|
||||||
|
const first = str[0];
|
||||||
|
|
||||||
|
if (['"', "'", "`"].includes(first)) {
|
||||||
|
if (first === str[str.length - 1]) {
|
||||||
|
return str.slice(1, -1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
};
|
||||||
|
|
||||||
|
export function AutoHeightTextarea({
|
||||||
|
minRows = 1,
|
||||||
|
...props
|
||||||
|
}: TextareaHTMLAttributes<HTMLTextAreaElement> & { minRows?: number }) {
|
||||||
|
const ref = useRef<HTMLTextAreaElement>(null);
|
||||||
|
|
||||||
|
const calculateAndSetHeight = useCallback(() => {
|
||||||
|
if (!ref.current) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const {
|
||||||
|
borderBottomWidth,
|
||||||
|
borderTopWidth,
|
||||||
|
boxSizing,
|
||||||
|
lineHeight,
|
||||||
|
paddingBottom,
|
||||||
|
paddingTop,
|
||||||
|
} = window.getComputedStyle(ref.current);
|
||||||
|
ref.current.style.height = lineHeight; // set height temporarily to a single row to obtain scrollHeight, disregarding empty space after text (otherwise, scrollHeight would be equal to the height of the element) - this solves auto-shrinking of the textarea (it's not needed for auto-growing it)
|
||||||
|
const { scrollHeight } = ref.current; // scrollHeight = content height + padding top + padding bottom
|
||||||
|
|
||||||
|
if (boxSizing === "border-box") {
|
||||||
|
const minHeight =
|
||||||
|
parseFloat(lineHeight) * minRows +
|
||||||
|
parseFloat(paddingTop) +
|
||||||
|
parseFloat(paddingBottom) +
|
||||||
|
parseFloat(borderTopWidth) +
|
||||||
|
parseFloat(borderBottomWidth);
|
||||||
|
const allTextHeight =
|
||||||
|
scrollHeight +
|
||||||
|
parseFloat(borderTopWidth) +
|
||||||
|
parseFloat(borderBottomWidth);
|
||||||
|
ref.current.style.height = `${Math.max(minHeight, allTextHeight)}px`;
|
||||||
|
} else if (boxSizing === "content-box") {
|
||||||
|
const minHeight = parseFloat(lineHeight) * minRows;
|
||||||
|
const allTextHeight =
|
||||||
|
scrollHeight - parseFloat(paddingTop) - parseFloat(paddingBottom);
|
||||||
|
ref.current.style.height = `${Math.max(minHeight, allTextHeight)}px`;
|
||||||
|
} else {
|
||||||
|
console.error("Unknown box-sizing value.");
|
||||||
|
}
|
||||||
|
}, [minRows]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
calculateAndSetHeight();
|
||||||
|
}, [calculateAndSetHeight]);
|
||||||
|
|
||||||
|
const handleChange: React.ChangeEventHandler<HTMLTextAreaElement> = (e) => {
|
||||||
|
calculateAndSetHeight();
|
||||||
|
if (props.onChange) {
|
||||||
|
props.onChange(e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
calculateAndSetHeight();
|
||||||
|
|
||||||
|
return <textarea {...props} onChange={handleChange} ref={ref} />;
|
||||||
|
}
|
||||||
|
|
@ -64,6 +64,7 @@ export const EdPropPopoverForm: FC<{
|
||||||
<div className="flex space-x-1">
|
<div className="flex space-x-1">
|
||||||
{[
|
{[
|
||||||
{ label: "TXT", type: "text" },
|
{ label: "TXT", type: "text" },
|
||||||
|
{ label: "FILE", type: "file" },
|
||||||
{ label: "OPT", type: "option" },
|
{ label: "OPT", type: "option" },
|
||||||
{ label: "JSX", type: "content-element" },
|
{ label: "JSX", type: "content-element" },
|
||||||
].map((e) => {
|
].map((e) => {
|
||||||
|
|
@ -110,7 +111,10 @@ export const EdPropPopoverForm: FC<{
|
||||||
|
|
||||||
{type === "text" && (
|
{type === "text" && (
|
||||||
<div
|
<div
|
||||||
className="flex cursor-pointer items-center space-x-1 select-none"
|
className={cx(
|
||||||
|
"flex cursor-pointer items-center space-x-1 select-none",
|
||||||
|
mprop.get("is_name") && "text-green-500"
|
||||||
|
)}
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
mprop.doc?.transact(() => {
|
mprop.doc?.transact(() => {
|
||||||
(mprop.parent as any)?.forEach((p: any, k: string) => {
|
(mprop.parent as any)?.forEach((p: any, k: string) => {
|
||||||
|
|
@ -126,12 +130,9 @@ export const EdPropPopoverForm: FC<{
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
className={cx(
|
className={cx(css`
|
||||||
css`
|
width: 17px;
|
||||||
width: 17px;
|
`)}
|
||||||
`,
|
|
||||||
mprop.get("is_name") && "text-green-500"
|
|
||||||
)}
|
|
||||||
>
|
>
|
||||||
{!mprop.get("is_name") ? (
|
{!mprop.get("is_name") ? (
|
||||||
<svg
|
<svg
|
||||||
|
|
@ -151,7 +152,7 @@ export const EdPropPopoverForm: FC<{
|
||||||
</svg>
|
</svg>
|
||||||
)}
|
)}
|
||||||
</span>
|
</span>
|
||||||
<span className="text-xs">Default Name</span>
|
<span className="text-xs">As Name</span>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -312,7 +313,7 @@ export const EdPropPopoverForm: FC<{
|
||||||
meta.set("option_mode", e as any);
|
meta.set("option_mode", e as any);
|
||||||
}
|
}
|
||||||
|
|
||||||
local.render()
|
local.render();
|
||||||
}}
|
}}
|
||||||
className={cx(
|
className={cx(
|
||||||
"m-1 px-1 capitalize text-center cursor-pointer font-mono border border-slate-300 text-[11px]",
|
"m-1 px-1 capitalize text-center cursor-pointer font-mono border border-slate-300 text-[11px]",
|
||||||
|
|
|
||||||
|
|
@ -41,10 +41,30 @@ export const EdTreeIndent = ({
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
className={cx(css`
|
className={cx(
|
||||||
width: ${prm.depth * DEPTH_WIDTH}px;
|
"flex items-stretch ml-1",
|
||||||
`)}
|
prm.depth > 0 ? "-mr-2" : "-mr-1"
|
||||||
></div>
|
)}
|
||||||
|
>
|
||||||
|
{Array.from({ length: prm.depth }, (_, n) => n).map((n) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
key={n}
|
||||||
|
className={cx(
|
||||||
|
"border-l mr-2",
|
||||||
|
n === 0 && "border-l-slate-100",
|
||||||
|
n === 1 && "border-l-slate-200",
|
||||||
|
n === 2 && "border-l-slate-300",
|
||||||
|
n === 3 && "border-l-slate-300",
|
||||||
|
n === 4 && "border-l-slate-400",
|
||||||
|
n === 5 && "border-l-slate-400",
|
||||||
|
n === 6 && "border-l-slate-500",
|
||||||
|
n > 6 && "border-l-purple-600"
|
||||||
|
)}
|
||||||
|
></div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
<div className={cx("flex items-center justify-center w-[20px]")}>
|
<div className={cx("flex items-center justify-center w-[20px]")}>
|
||||||
{item.type === "text" && (
|
{item.type === "text" && (
|
||||||
<div className="-mt-[2px]">
|
<div className="-mt-[2px]">
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ export type FNCompDef = {
|
||||||
meta?: FNCompMeta;
|
meta?: FNCompMeta;
|
||||||
};
|
};
|
||||||
type FNCompMeta = {
|
type FNCompMeta = {
|
||||||
type: "text" | "option" | "content-element";
|
type: "file" | "text" | "option" | "content-element";
|
||||||
options?: string;
|
options?: string;
|
||||||
optionsBuilt?: string;
|
optionsBuilt?: string;
|
||||||
option_mode?: "dropdown" | "button";
|
option_mode?: "dropdown" | "button";
|
||||||
|
|
@ -128,12 +128,12 @@ export type FNFont = {
|
||||||
height?: number | "auto";
|
height?: number | "auto";
|
||||||
align?: "center" | "left" | "right";
|
align?: "center" | "left" | "right";
|
||||||
whitespace?:
|
whitespace?:
|
||||||
| "whitespace-normal"
|
| "whitespace-normal"
|
||||||
| "whitespace-nowrap"
|
| "whitespace-nowrap"
|
||||||
| "whitespace-pre"
|
| "whitespace-pre"
|
||||||
| "whitespace-pre-line"
|
| "whitespace-pre-line"
|
||||||
| "whitespace-pre-wrap"
|
| "whitespace-pre-wrap"
|
||||||
| "whitespace-break-spaces";
|
| "whitespace-break-spaces";
|
||||||
wordBreak?: "break-normal" | "break-words" | "break-all" | "break-keep";
|
wordBreak?: "break-normal" | "break-words" | "break-all" | "break-keep";
|
||||||
};
|
};
|
||||||
export type FMFont = TypedMap<FNFont>;
|
export type FMFont = TypedMap<FNFont>;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue