Forms are not fun to write. They are repetitive, error-prone, and time-consuming. This library aims to make form generation as simple as possible.
The packages in this repository are designed to be un-opinionated, flexible, modular, and highly customizable.
There are two types of packages in this repository:
@react-formgen/core
) provides the core functionality for the schema-based packages. This package is not really meant to be used directly, but rather as a dependency for the schema-based packages. It serves as a "factory" for creating form providers and hooks that are schema-specific. Think of it as a "scaffolding" for the schema-based form generators.Take, for example, the JSON Schema package (@react-formgen/json-schema
). This package takes a JSON Schema and generates a form and/or a data view based on that schema. The package provides a set of hooks and a provider that you can use in your components to generate forms and data views.
Here's a visual representation of the core and schema-based package interaction:
graph LR
subgraph Core["@react-formgen/core"]
direction LR
CoreProviderHooks["createFormProviderAndHooks"]
CoreState["CoreFormState"]
end
subgraph JSONSchemaPackage["@react-formgen/json-schema"]
direction LR
JSONSchemaProviderHooks["createFormProviderAndHooks"]
JSONSchemaCoreState["CoreFormState<JSONSchema7, ErrorObject>"]
JSONSchemaState["FormState"]
JSONSchemaProvider["FormProvider"]
JSONSchemaContext["useFormContext"]
JSONSchemaDataAtPath["useFormDataAtPath"]
JSONSchemaErrorsAtPath["useErrorsAtPath"]
JSONSchemaArrayFieldset["useArrayFieldset"]
JSONSchemaInitialData["generateInitialData (JSON Schema specific)"]
JSONSchemaErrorsPath["getErrorsAtPath (JSON Schema specific)"]
JSONSchemaComponents["Components (Form, DataView, RenderTemplate)"]
JSONSchemaUtils["Utils (generateInitialData, getZeroState, resolveSchema)"]
JSONSchemaInitialData --> JSONSchemaProviderHooks
JSONSchemaErrorsPath --> JSONSchemaProviderHooks
JSONSchemaProviderHooks --> JSONSchemaProvider
JSONSchemaProviderHooks --> JSONSchemaContext
JSONSchemaProviderHooks --> JSONSchemaDataAtPath
JSONSchemaProviderHooks --> JSONSchemaErrorsAtPath
JSONSchemaProviderHooks --> JSONSchemaArrayFieldset
JSONSchemaCoreState --> JSONSchemaState
JSONSchemaCoreState --> JSONSchemaProvider
JSONSchemaCoreState --> JSONSchemaContext
JSONSchemaCoreState --> JSONSchemaDataAtPath
JSONSchemaCoreState --> JSONSchemaErrorsAtPath
JSONSchemaCoreState --> JSONSchemaArrayFieldset
end
subgraph JSONSchemaConsumers["Consumers of @react-formgen/json-schema"]
direction LR
ConsumerErrorsAtPath["useErrorsAtPath"]
ConsumerArrayFieldset["useArrayFieldset"]
ConsumerDataAtPath["useFormDataAtPath"]
ConsumerContext["useFormContext"]
ConsumerState["FormState"]
ConsumerProvider["FormProvider"]
subgraph JSONSchemaDataViewTemplates["JSONSchemaDataViewTemplates"]
StringView["CustomStringView"]
NumberView["CustomNumberView"]
BooleanView["CustomBooleanView"]
ArrayView["CustomArrayView"]
ObjectView["CustomObjectView"]
end
subgraph JSONSchemaFieldTemplates["JSONSchemaFieldTemplates"]
ArrayFieldset["CustomArrayFieldset"]
ObjectFieldset["CustomObjectFieldset"]
BooleanField["CustomBooleanField"]
NumberField["CustomNumberField"]
StringField["CustomStringField"]
end
FormTemplate["CustomFormTemplate"]
DataViewTemplate["CustomDataViewTemplate"]
DataView["DataView"]
Form["Form"]
FormTemplate --> Form
DataViewTemplate --> DataView
ConsumerErrorsAtPath ---> ObjectFieldset
ConsumerErrorsAtPath ---> BooleanField
ConsumerErrorsAtPath ---> NumberField
ConsumerErrorsAtPath ---> StringField
ConsumerArrayFieldset ---> ArrayFieldset
ConsumerDataAtPath ---> BooleanField
ConsumerDataAtPath ---> NumberField
ConsumerDataAtPath ---> StringField
ConsumerDataAtPath ---> StringView
ConsumerDataAtPath ---> NumberView
ConsumerDataAtPath ---> BooleanView
ConsumerDataAtPath ---> ArrayView
ConsumerContext ---> FormTemplate
ConsumerContext ---> DataViewTemplate
ConsumerState ---> FormTemplate
ConsumerState ---> DataViewTemplate
ConsumerProvider ---> DataView
ConsumerProvider ---> Form
JSONSchemaDataViewTemplates --> DataView
JSONSchemaFieldTemplates --> Form
end
%% Relations
Core --> JSONSchemaPackage
JSONSchemaPackage --> JSONSchemaConsumers
You can consume the JSON Schema package directly in your project, and customize the form and data view templates to suit your needs. You can also customize field templates and data view templates for full control over the look and feel of your generated forms and views.
The schema-based packages are designed to be highly customizable. You can extend them by:
Here is a quick example of how to use the JSON Schema package to generate a form:
import React from "react";
import { Form } from "@react-formgen/json-schema";
import mySchema from "./mySchema.json";
const MyFormComponent = () => {
const handleSubmit = (data) => {
console.log("Form submitted with data:", data);
};
const handleErrors = (errors) => {
console.error("Form submission errors:", errors);
};
return (
<Form
schema={mySchema}
onSubmit={handleSubmit}
onError={handleErrors}
initialData={{}} // Optional initial form data
/>
);
};
export default MyFormComponent;
npm install @react-formgen/json-schema
or
yarn add @react-formgen/json-schema
or
pnpm add @react-formgen/json-schema
Form
component. You can do this by importing a JSON file, defining the schema directly in your component, fetching it from an API, etc.import mySchema from "./mySchema.json";
Form
component to generate a form based on the schema:<Form schema={mySchema} onSubmit={handleSubmit} onError={handleErrors} />
For a read-only data view, just pass the readonly
prop to the Form
component:
<Form schema={mySchema} readonly />
That's it! You now have a form or data view generated based on your JSON Schema.
Obviously, this is a very basic example. You should customize the form and data view templates, field templates, and more to suit your needs.
Contributions are welcome. Please open an issue or submit a pull request on the GitHub repository.
This project is licensed under the MIT License. See the LICENSE file for details.