import { Popover } from "@mantine/core"; import { IconBug } from "@tabler/icons-react"; import { autoFormatString } from "core/utils"; import type { JSONSchema } from "json-schema-to-ts"; import { type ChangeEvent, type ComponentPropsWithoutRef, useState } from "react"; import { IconButton } from "ui/components/buttons/IconButton"; import { JsonViewer } from "ui/components/code/JsonViewer"; import * as Formy from "ui/components/form/Formy"; import { ErrorMessage } from "ui/components/form/Formy"; import { Form, useFieldContext, useFormContext, usePrefixContext } from "ui/components/form/json-schema-form2/Form"; import { isType } from "ui/components/form/json-schema-form2/utils"; const schema = { type: "object", properties: { name: { type: "string", maxLength: 2 }, description: { type: "string", maxLength: 2 }, age: { type: "number", description: "Age of you" }, deep: { type: "object", properties: { nested: { type: "string", maxLength: 2 } } } } //required: ["description"] } as const satisfies JSONSchema; const simpleSchema = { type: "object", properties: { tags: { type: "array", items: { type: "string" } } } } as const satisfies JSONSchema; export default function JsonSchemaForm2() { return (

Form

{/*

*/} {/*
*/} {/*
*/}
{/*
*/}
); } const Field = ({ name = "", schema: _schema }: { name?: string; schema?: Exclude }) => { const { value, errors, pointer, required, ...ctx } = useFieldContext(name); const schema = _schema ?? ctx.schema; if (!schema) return `"${name}" (${pointer}) has no schema`; if (isType(schema.type, ["object", "array"])) { return null; } const label = schema.title ?? name; //autoFormatString(name.split("/").pop()); return ( 0}> {label} {required ? "*" : ""}
{schema.description && {schema.description}} {errors.length > 0 && ( {errors.map((e) => e.message).join(", ")} )}
); }; const FieldComponent = ({ schema, ...props }: { schema: JSONSchema } & ComponentPropsWithoutRef<"input">) => { if (!schema || typeof schema === "boolean") return null; const common = {}; if (schema.enum) { if (!Array.isArray(schema.enum)) return null; return ; } if (isType(schema.type, ["number", "integer"])) { return ; } return ; }; const ObjectField = ({ path = "" }: { path?: string }) => { const { schema } = usePrefixContext(path); if (!schema) return null; const properties = schema.properties ?? {}; const label = schema.title ?? path; console.log("object", { path, schema, properties }); return (
Object: {label} {Object.keys(properties).map((prop) => { const schema = properties[prop]; const pointer = `${path}/${prop}`; console.log("--", prop, pointer, schema); if (schema.anyOf || schema.oneOf) { return ; } if (isType(schema.type, "object")) { console.log("object", { prop, pointer, schema }); return ; } if (isType(schema.type, "array")) { return ; } return ; })}
); }; const AnyOfField = ({ path = "" }: { path?: string }) => { const [selected, setSelected] = useState(null); const { schema, select } = usePrefixContext(path); if (!schema) return null; const schemas = schema.anyOf ?? schema.oneOf ?? []; const options = schemas.map((s, i) => ({ value: i, label: s.title ?? `Option ${i + 1}` })); const selectSchema = { enum: options }; function handleSelect(e: ChangeEvent) { const i = e.target.value ? Number(e.target.value) : null; setSelected(i); select(path, i !== null ? i : undefined); } console.log("options", options, schemas, selected !== null && schemas[selected]); return ( <>
anyOf: {path} ({selected})
{selected !== null && ( )} ); }; const ArrayField = ({ path = "" }: { path?: string }) => { return "array: " + path; }; const AutoForm = ({ prefix = "" }: { prefix?: string }) => { const { schema } = usePrefixContext(prefix); if (!schema) return null; if (isType(schema.type, "object")) { return ; } if (isType(schema.type, "array")) { return ; } return ; };