zod-form-kit
Version:
UI-agnostic form generation library based on Zod schemas with extensible adapter pattern
115 lines (114 loc) • 4.18 kB
TypeScript
import React from 'react';
import { ParsedField } from '../utils/schema-parser';
import { FieldProps } from './form-generator';
import { z } from 'zod';
export interface BaseFieldRendererProps extends FieldProps {
value: any;
error?: string;
required?: boolean;
name: string;
label?: string;
className?: string;
}
export interface StringFieldRendererProps extends BaseFieldRendererProps {
value: string;
onChange: (value: string) => void;
options?: {
minLength?: number;
maxLength?: number;
pattern?: RegExp;
format?: string;
readonly?: boolean;
};
}
export interface NumberFieldRendererProps extends BaseFieldRendererProps {
value: number;
onChange: (value: number) => void;
options?: {
min?: number;
max?: number;
step?: number;
readonly?: boolean;
};
}
export interface BooleanFieldRendererProps extends BaseFieldRendererProps {
value: boolean;
onChange: (value: boolean) => void;
}
export interface DateFieldRendererProps extends BaseFieldRendererProps {
value: Date | null;
onChange: (value: Date | null) => void;
}
export interface ArrayFieldRendererProps extends BaseFieldRendererProps {
value: any[];
onChange: (path: string, value: any) => void;
itemSchema: ParsedField;
errors: Record<string, string>;
path: string;
options?: {
minLength?: number;
maxLength?: number;
};
}
export interface ObjectFieldRendererProps extends BaseFieldRendererProps {
value: Record<string, any>;
onChange: (path: string, value: any) => void;
properties: Record<string, ParsedField>;
errors: Record<string, string>;
path: string;
}
export interface DiscriminatedUnionFieldRendererProps extends BaseFieldRendererProps {
value: Record<string, any>;
onChange: (path: string, value: any) => void;
discriminator: string;
variants: Record<string, ParsedField>;
errors: Record<string, string>;
path: string;
}
export type StringFieldRenderer = React.ComponentType<StringFieldRendererProps>;
export type NumberFieldRenderer = React.ComponentType<NumberFieldRendererProps>;
export type BooleanFieldRenderer = React.ComponentType<BooleanFieldRendererProps>;
export type DateFieldRenderer = React.ComponentType<DateFieldRendererProps>;
export type ArrayFieldRenderer = React.ComponentType<ArrayFieldRendererProps>;
export type ObjectFieldRenderer = React.ComponentType<ObjectFieldRendererProps>;
export type DiscriminatedUnionFieldRenderer = React.ComponentType<DiscriminatedUnionFieldRendererProps>;
export type FieldRendererComponent = StringFieldRenderer | NumberFieldRenderer | BooleanFieldRenderer | DateFieldRenderer | ArrayFieldRenderer | ObjectFieldRenderer | DiscriminatedUnionFieldRenderer;
export type FieldType = 'string' | 'number' | 'boolean' | 'date' | 'enum' | 'array' | 'object' | 'discriminatedUnion';
export type SchemaPatternMatcher = (zodSchema: z.ZodTypeAny, parsedField: ParsedField, formValue?: any) => boolean;
export interface SchemaPatternRendererProps extends BaseFieldRendererProps {
value: any;
onChange: (value: any) => void;
zodSchema: z.ZodTypeAny;
parsedField: ParsedField;
form: any;
path: string;
}
export type SchemaPatternRenderer = React.ComponentType<SchemaPatternRendererProps>;
export interface PatternRegistryEntry {
id: string;
matcher: SchemaPatternMatcher;
component: SchemaPatternRenderer;
priority: number;
}
export interface PluginRegistry {
fieldRenderers: Map<FieldType, FieldRendererComponent>;
patternRenderers: PatternRegistryEntry[];
uiAdapters: Map<string, UIAdapter>;
defaultAdapter?: string;
}
export interface UIAdapter {
name: string;
components: {
string?: StringFieldRenderer;
number?: NumberFieldRenderer;
boolean?: BooleanFieldRenderer;
date?: DateFieldRenderer;
array?: ArrayFieldRenderer;
object?: ObjectFieldRenderer;
discriminatedUnion?: DiscriminatedUnionFieldRenderer;
};
}
export interface PluginSystemConfig {
defaultAdapter?: string;
fallbackToDefaults?: boolean;
}