Reusable defaults
Even with a simple setup, resulting code is very verbose. Therefore, it is convenient to create a file with a re-export of the selected resolver, theme, validator and translation.
export { resolver } from "@sjsf/form/resolvers/compat";import "@sjsf/form/fields/extra-fields/enum-include";import "@sjsf/form/fields/extra-fields/file-include";
export { theme } from "@sjsf/basic-theme";import "@sjsf/basic-theme/extra-widgets/textarea-include";import "@sjsf/basic-theme/extra-widgets/file-include";
export { translation } from "@sjsf/form/translations/en";
import { createFormValidator } from "@sjsf/ajv8-validator";
// NOTE: One validator will be used for all formsexport const validator = createFormValidator();
And use it like this
import * as defaults from '$lib/form-defaults'
const form = createForm({ ...defaults, ... })
Factory
Section titled “Factory”You could go further and create a wrapper around the createForm
.
import { type FormOptions, type Validator, createForm } from "@sjsf/form";
import * as defaults from "./form-defaults";
type Defaults = keyof typeof defaults;
export type MyValidator = (typeof defaults)["validator"];
export type MyFormOptions<T, V extends Validator> = Omit< FormOptions<T, V>, Defaults> & Partial<Pick<FormOptions<T, V>, Defaults>>;
export function createMyForm< T, V extends Validator, O extends MyFormOptions<T, V>>(options: O) { return createForm( new Proxy(options, { get(target, p, receiver) { if (!(p in target)) { return defaults[p as Defaults]; } return Reflect.get(target, p, receiver); }, }) as unknown as FormOptions< T, O extends { validator: V } ? V : MyValidator > );}
Component
Section titled “Component”You also can create your own form component.
<script lang="ts" generics="T, V extends Validator, O extends MyFormOptions<T, V>"> import { BasicForm, type Validator } from "@sjsf/form";
import { type MyFormOptions, createMyForm } from "./my-form";
const props: O = $props();
const form = createMyForm<T, V, O>(props);</script>
<BasicForm {form} />