diff --git a/comps/form/field/FieldInput.tsx b/comps/form/field/FieldInput.tsx
index 5e44c36..ebefd78 100755
--- a/comps/form/field/FieldInput.tsx
+++ b/comps/form/field/FieldInput.tsx
@@ -5,6 +5,7 @@ import { FMLocal, FieldLocal } from "../typings";
import { genFieldMitem, updateFieldMItem } from "../utils/gen-mitem";
import { fieldMapping } from "./mapping";
import { FieldLoading } from "./raw/FieldLoading";
+import { TypeCustom } from "./type/TypeCustom";
const modify = {
timeout: null as any,
@@ -28,7 +29,7 @@ export const FieldInput: FC<{
);
let found = null as any;
- if (childs && childs.length > 0) {
+ if (childs && childs.length > 0 && field.type !== "custom") {
for (const child of childs) {
const mp = (fieldMapping as any)[field.type];
if (child.component?.id === mp.id) {
@@ -65,7 +66,7 @@ export const FieldInput: FC<{
}
useEffect(() => {
- if (isEditor && !found) {
+ if (isEditor && !found && field.type !== "custom") {
genFieldMitem({ _meta, _item, _sync, field, fm });
}
}, []);
@@ -100,15 +101,21 @@ export const FieldInput: FC<{
) : (
- {!found &&
}
- {found && (
-
- {found}
-
+ {field.type === "custom" ? (
+
+ ) : (
+ <>
+ {!found &&
}
+ {found && (
+
+ {found}
+
+ )}
+ >
)}
)}
diff --git a/comps/form/field/type/TypeCustom.tsx b/comps/form/field/type/TypeCustom.tsx
new file mode 100755
index 0000000..21d83db
--- /dev/null
+++ b/comps/form/field/type/TypeCustom.tsx
@@ -0,0 +1,29 @@
+import { FC, isValidElement } from "react";
+import { FMLocal, FieldLocal } from "../../typings";
+import { useLocal } from "@/utils/use-local";
+import { FieldTypeText } from "./TypeText";
+
+export const TypeCustom: FC<{ field: FieldLocal; fm: FMLocal }> = ({
+ field,
+ fm,
+}) => {
+ const local = useLocal({ custom: null as any }, async () => {
+ if (field.custom) {
+ local.custom = await field.custom();
+ local.render();
+ }
+ });
+
+ let el = null as any;
+ if (local.custom) {
+ if (isValidElement(local.custom)) {
+ el = local.custom;
+ } else {
+ if (local.custom.field === "text") {
+ el = ;
+ }
+ }
+ }
+
+ return <>{el}>;
+};
diff --git a/comps/form/field/type/TypeText.tsx b/comps/form/field/type/TypeText.tsx
index 8b5c2c1..9f580df 100755
--- a/comps/form/field/type/TypeText.tsx
+++ b/comps/form/field/type/TypeText.tsx
@@ -17,24 +17,26 @@ export const FieldTypeText: FC<{
field.prop = prop;
return (
- {
- fm.data[field.name] = ev.currentTarget.value;
- fm.render();
- }}
- value={value || ""}
- disabled={field.disabled}
- className="c-flex-1 c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full"
- spellCheck={false}
- onFocus={() => {
- field.focused = true;
- field.render();
- }}
- onBlur={() => {
- field.focused = false;
- field.render();
- }}
- />
+ <>
+ {
+ fm.data[field.name] = ev.currentTarget.value;
+ fm.render();
+ }}
+ value={value || ""}
+ disabled={field.disabled}
+ className="c-flex-1 c-bg-transparent c-outline-none c-px-2 c-text-sm c-w-full"
+ spellCheck={false}
+ onFocus={() => {
+ field.focused = true;
+ field.render();
+ }}
+ onBlur={() => {
+ field.focused = false;
+ field.render();
+ }}
+ />
+ >
);
};
diff --git a/comps/form/typings.ts b/comps/form/typings.ts
index fbd4224..fcb2083 100755
--- a/comps/form/typings.ts
+++ b/comps/form/typings.ts
@@ -1,5 +1,5 @@
import { GFCol } from "@/gen/utils";
-import { ReactNode } from "react";
+import { ReactElement, ReactNode } from "react";
import { FieldOptions } from "../form-old/type";
import { FormHook } from "../form-old/utils/utils";
import { editorFormData } from "./utils/ed-data";
@@ -56,6 +56,7 @@ export type FieldProp = {
_meta: any;
_item: any;
_sync: any;
+ custom?: () => Promise;
};
export type FMInternal = {
@@ -112,6 +113,7 @@ export type FieldInternal = {
required_msg: FieldProp["required_msg"];
col?: GFCol;
Child: () => ReactNode;
+ custom: FieldProp["custom"];
input: Record & {
render: () => void;
};
@@ -196,3 +198,12 @@ export const fieldType = (item: any, meta: any, fm: FMLocal) => {
`;
}
};
+
+export type CustomField =
+ | { field: "text"; type: "text" | "password" | "number" }
+ | { field: "relation"; type: "has-many" | "has-one" };
+
+export const FieldTypeCustom = `type CustomField =
+ { field: "text", type: "text" | "password" | "number" }
+| { field: "relation", type: "has-many" | "has-one" }
+`;
diff --git a/comps/form/utils/use-field.tsx b/comps/form/utils/use-field.tsx
index 2c47690..d1720a9 100755
--- a/comps/form/utils/use-field.tsx
+++ b/comps/form/utils/use-field.tsx
@@ -19,6 +19,7 @@ export const useField = (arg: FieldProp) => {
prefix: arg.prefix,
suffix: arg.suffix,
width: arg.width,
+ custom: arg.custom,
required: arg.required === "y",
required_msg: arg.required_msg,
disabled: arg.disabled === "y",
diff --git a/data.ts b/data.ts
index d8ad1ee..0eaa08a 100755
--- a/data.ts
+++ b/data.ts
@@ -1,3 +1,4 @@
+export { FieldTypeCustom } from "@/comps/form/typings";
export { FieldTypeText } from "./comps/form/field/type/TypeText";
export { FieldTypeRelation } from "./comps/form/field/type/TypeRelation";
export { Form } from "@/comps/form/Form";