Files
khata-ui/react-openapi/components/fields/FormField.tsx

86 lines
2.1 KiB
TypeScript

import * as React from 'react';
import { ResourceField } from '../../types/config';
import { FieldComponentProps, FieldComponents } from '../../types/overrides';
import ObjectField from './ObjectField';
export interface FormFieldProps {
name: string;
field: ResourceField;
value: any;
onChange: (val: any) => void;
disabled?: boolean;
uploadFile?: (file: File) => Promise<string | null>;
uploading?: boolean;
baseUrl?: string;
relationDataMap?: Record<string, any[]>;
components: FieldComponents;
}
export default function FormField({
name,
field,
value,
onChange,
disabled,
uploadFile,
uploading,
baseUrl,
relationDataMap = {},
components,
}: FormFieldProps) {
const fieldProps: FieldComponentProps = {
name,
field,
value,
onChange,
disabled,
baseUrl,
relationDataMap,
uploadFile,
uploading,
};
const childComponents = components;
// 1. Object (recursive) - requires parent FormField for recursion
if (field.type === 'object' && field.schema && !field.relation) {
const renderChild = (childProps: FieldComponentProps) => (
<FormField
name={childProps.name}
field={childProps.field}
value={childProps.value}
onChange={childProps.onChange}
disabled={childProps.disabled}
uploadFile={childProps.uploadFile}
uploading={childProps.uploading}
baseUrl={childProps.baseUrl}
relationDataMap={childProps.relationDataMap}
components={components}
/>
);
return <ObjectField {...fieldProps} renderField={renderChild} />;
}
// 2. Image
if (field.type === 'image') {
const ImageField = components.image;
if (!ImageField) return null;
return <ImageField {...fieldProps} />;
}
// 3. Relation
if (field.relation && relationDataMap[field.relation]) {
const RelationFieldComp = components.relation;
if (!RelationFieldComp) return null;
return <RelationFieldComp {...fieldProps} />;
}
// 4. Lookup by field type
const Component = components[field.type] || components.default;
if (Component) {
return <Component {...fieldProps} />;
}
return null;
}