UNPKG

@canard/schema-form

Version:

React-based component library that renders forms based on JSON Schema with plugin system support for validators and UI components

161 lines (160 loc) 7.16 kB
import type { CSSProperties, ComponentType } from 'react'; import type { Dictionary, Fn } from '../@aileron/declare'; import type { ChildNodeComponent } from '../components/SchemaNode'; import type { InferSchemaNode, PublicSetValueOption, SchemaNode } from '../core'; import type { FormTypeRendererProps } from './formTypeRenderer'; import type { InferJsonSchema, JsonSchemaType, JsonSchemaWithVirtual } from './jsonSchema'; import type { AllowedValue } from './value'; /** * Props that FormTypeInput Input Component must satisfy * * - `Value`: Type of value assigned to FormTypeInput Component * - `Context`: Type of UserDefinedContext passed to Form * - `WatchValues`: Type of values subscribed according to watch property defined in JsonSchema * - `Schema`: JsonSchema type of schema node assigned to FormTypeInput Component * - `Node`: Type of schema node assigned to FormTypeInput Component */ export interface FormTypeInputProps<Value extends AllowedValue = any, Context extends Dictionary = object, WatchValues extends Array<any> = Array<any>, Schema extends JsonSchemaWithVirtual = InferJsonSchema<Value>, Node extends SchemaNode = InferSchemaNode<Schema>> { /** JsonSchema of FormTypeInput Component */ jsonSchema: Schema; /** ReadOnly state of FormTypeInput Component */ readOnly: boolean; /** Disabled state of FormTypeInput Component */ disabled: boolean; /** Whether the schema node assigned to FormTypeInput Component is required */ required: boolean; /** Schema node assigned to FormTypeInput Component */ node: Node; /** JSON Schema type of this field (e.g., 'string', 'number', 'object', 'array') */ type: Node['schemaType']; /** Name of schema node assigned to FormTypeInput Component */ name: Node['name']; /** Path of schema node assigned to FormTypeInput Component */ path: Node['path']; /** Whether this field accepts null as a valid value (derived from schema type array including 'null') */ nullable: Node['nullable']; /** Errors of schema node assigned to FormTypeInput Component */ errors: Node['errors']; /** Values subscribed according to `computed.watch`(=`&watch`) property defined in JsonSchema */ watchValues: WatchValues; /** Default value of FormTypeInput Component */ defaultValue: Value | undefined; /** Current value of FormTypeInput Component */ value: Value | undefined; /** onChange handler of FormTypeInput Component */ onChange: SetStateFnWithOptions<Value | undefined>; /** onFileAttach handler of FormTypeInput Component */ onFileAttach: Fn<[file: File | File[] | undefined]>; /** Child FormTypeInput Components of this FormTypeInput Component */ ChildNodeComponents: ChildNodeComponent[]; /** Placeholder text for input fields */ placeholder: string | undefined; /** CSS class name for styling */ className: string | undefined; /** Style of FormTypeInput Component */ style: CSSProperties | undefined; /** UserDefinedContext passed to Form */ context: Context; /** Additional properties can be freely defined */ [alt: string]: any; } /** * Props that FormTypeInputPropsWithSchema must satisfy * * - `Value`: Type of value assigned to FormTypeInput Component * - `Schema`: JsonSchema type of schema node assigned to FormTypeInput Component * - `Context`: Type of UserDefinedContext passed to Form */ export type FormTypeInputPropsWithSchema<Value extends AllowedValue = any, Schema extends JsonSchemaWithVirtual = InferJsonSchema<Value>, Context extends Dictionary = object> = FormTypeInputProps<Value, Context, any[], Schema>; /** * Props that FormTypeInputPropsWithSchema must satisfy * * - `Value`: Type of value assigned to FormTypeInput Component * - `Schema`: JsonSchema type of schema node assigned to FormTypeInput Component * - `Node`: Type of schema node assigned to FormTypeInput Component */ export type FormTypeInputPropsWithNode<Value extends AllowedValue = any, Schema extends JsonSchemaWithVirtual = InferJsonSchema<Value>, Node extends SchemaNode = InferSchemaNode<Schema>> = FormTypeInputProps<Value, Dictionary, any[], Schema, Node>; /** FormTypeInputProps to use when type inference is not needed */ export interface UnknownFormTypeInputProps { jsonSchema: any; readOnly: boolean; disabled: boolean; required: boolean; node: any; name: string; path: string; type: any; nullable: boolean; errors: any[]; watchValues: any[]; defaultValue: any; value: any; onChange: SetStateFnWithOptions<any>; onFileAttach: Fn<[file: File | File[] | undefined]>; ChildNodeComponents: ChildNodeComponent<any>[]; placeholder: string | undefined; className: string | undefined; style: CSSProperties | undefined; context: any; [alt: string]: any; } export type InferFormTypeInputProps<Value> = Value extends AllowedValue ? FormTypeInputProps<Value> : UnknownFormTypeInputProps; export type ChildNodeComponentProps<Value extends AllowedValue = any> = { required?: boolean; readOnly?: boolean; disabled?: boolean; defaultValue?: Value; value?: Value; onChange?: SetStateFnWithOptions<Value>; onFileAttach?: Fn<[file: File | File[] | undefined]>; FormTypeRenderer?: ComponentType<FormTypeRendererProps>; className?: string; style?: CSSProperties; [alt: string]: any; }; export type OverridableFormTypeInputProps = Omit<ChildNodeComponentProps, 'onChange' | 'onFileAttach' | 'FormTypeRenderer'>; export type FormTypeTestFn = Fn<[hint: Hint], boolean>; type OptionalString = string | undefined; export type FormTypeTestObject = Partial<{ /** SchemaNode['schemaType'] | Array<SchemaNode['schemaType']> */ type: JsonSchemaType | JsonSchemaType[]; /** SchemaNode['path'] | Array<SchemaNode['path']> */ path: string | string[]; /** SchemaNode['required'] */ required: boolean; /** SchemaNode['nullable] */ nullable: boolean; /** JsonSchema['format'] | Array<JsonSchema['format']> | undefined */ format: OptionalString | OptionalString[]; /** JsonSchema['formType'] | Array<JsonSchema['formType']> | undefined */ formType: OptionalString | OptionalString[]; }>; export type Hint = { /** SchemaNode['schemaType'] */ type: JsonSchemaType; /** SchemaNode['path'] */ path: string; /** SchemaNode['required'] */ required: boolean; /** SchemaNode['nullable] */ nullable: boolean; /** JsonSchema */ jsonSchema: JsonSchemaWithVirtual; /** JsonSchema['format'] */ format?: string; /** JsonSchema['formType'] */ formType?: string; }; export type FormTypeInputDefinition<T = unknown> = { test: FormTypeTestFn | FormTypeTestObject; Component: ComponentType<InferFormTypeInputProps<T>>; }; export type FormTypeInputMap<T = unknown> = { [path: string]: ComponentType<InferFormTypeInputProps<T>>; }; export type SetStateFnWithOptions<S = unknown> = Fn<[ value: S | ((prevState: S) => S), options?: PublicSetValueOption ]>; export type AttachedFilesMap = Map<SchemaNode['path'], File[]>; export {};