import React, { type ReactNode } from 'react'; import { useFieldArray, type useForm } from 'react-hook-form'; import { PiArrowDownLight, PiArrowUpLight, PiMinusLight, PiPlus, PiPlusLight } from 'react-icons/pi'; import { JsonSchema, type JsonSchemaDef } from '@wener/common/jsonschema'; import { match, P } from 'ts-pattern'; import { cn } from '../utils/cn'; type FormContext = ReturnType; type RenderSettingFormOptions = { schema: JsonSchemaDef; level?: number; path?: string[]; forms: FormContext; }; export function renderSettingFormFromSchema({ schema, level = 0, path = [], forms }: RenderSettingFormOptions) { const { register, control } = forms; return match(schema) .returnType() .with({ type: 'string' }, (schema) => { let type = 'text'; if (schema.sensitive) { type = 'password'; } return ; }) .with({ anyOf: P.array() }, ({ anyOf }) => { return ( ); }) .with({ type: 'array' }, (schema) => { const { title } = schema; const itemSchema = schema.items as JsonSchemaDef; const isPrimitive = JsonSchema.isPrimitiveType(itemSchema); const { append, remove, swap, fields } = useFieldArray({ name: path.join('.'), control }); return (
{Boolean(title) &&

{String(title)}

}
{fields.map((field, index) => { const isLast = index === fields.length - 1; const isFirst = index === 0; let controller = (
{!isPrimitive &&
#{index + 1}
}
); return (
{!isPrimitive && controller} {renderSettingFormFromSchema({ schema: itemSchema, level: level + 1, path: path.concat(index.toString()), forms, })} {isPrimitive && controller}
); })}
); }) .with({ type: 'object' }, (schema) => { const { title } = schema; return (
{Boolean(title) && (

{String(title)}

)} {Object.entries(schema.properties as Record).map(([key, prop]) => { if (['array', 'object'].includes(String(prop.type))) { return (
{renderSettingFormFromSchema({ schema: prop, level: level + 1, path: path.concat(key), forms })}
); } let content: ReactNode = null; if (prop.type === 'boolean') { content = (
); } else { content = ( <>
{prop.title}
{renderSettingFormFromSchema({ schema: prop, level: level + 1, path: path.concat(key), forms })} ); } return (
{content}
); })}
); }) .otherwise((schema) => { return
不支持的 Schema: {JSON.stringify(schema)}
; }); }