npm i @sjsf/form@next @sjsf/ajv8-validator@next ajv@8 @sjsf/basic-theme@nextyarn add @sjsf/form@next @sjsf/ajv8-validator@next ajv@8 @sjsf/basic-theme@nextpnpm add @sjsf/form@next @sjsf/ajv8-validator@next ajv@8 @sjsf/basic-theme@nextbun add @sjsf/form@next @sjsf/ajv8-validator@next ajv@8 @sjsf/basic-theme@nextUsage
<script lang="ts"> import { createForm, BasicForm, getValueSnapshot } from "@sjsf/form";
import { schema, uiSchema, initialValue, type Data, withFile, } from "../data"; import * as defaults from "./defaults";
const form = createForm<Data>({ ...defaults, // required due to several forms on the page idPrefix: "basic", initialValue, schema, uiSchema, onSubmit: ({ name }) => window.alert(`Hello, ${name}`), });</script>
<BasicForm {form} />
<pre>{JSON.stringify(getValueSnapshot(form), withFile, 2)}</pre>import { formatFileSize } from "@sjsf/form/validators/file-size";import type { Schema, UiSchemaRoot } from "@sjsf/form";import type { FromSchema } from "json-schema-to-ts";
export const schema = { title: "User Registration", description: "Simple user registration form", type: "object", required: ["name", "email", "age"], properties: { name: { type: "string", title: "Full Name", minLength: 2, maxLength: 50, }, email: { type: "string", title: "Email", format: "email", }, age: { type: "integer", title: "Age", minimum: 13, maximum: 120, }, country: { type: "string", title: "Country", enum: ["US", "CA", "UK", "DE", "FR"], }, experience: { type: "string", title: "Work Experience", enum: ["beginner", "intermediate", "advanced"], }, skills: { type: "array", title: "Skills", items: { type: "string", enum: ["HTML", "CSS", "JS/TS", "Svelte"], }, uniqueItems: true, minItems: 4 }, bio: { type: "string", title: "About You", maxLength: 200, }, startDate: { type: "string", title: "Available Start Date", format: "date", }, resume: { title: "Upload Resume", }, },} as const satisfies Schema;
export type Data = FromSchema<typeof schema>;
export const uiSchema: UiSchemaRoot = { "ui:options": { layouts: { "object-properties": { style: "display: grid; grid-template-columns: repeat(2, 1fr); gap: 1rem;", }, }, translations: { submit: "Register", }, }, name: { "ui:options": { text: { autocomplete: "name", }, flowbite3Text: { autocomplete: "name", }, }, }, country: { "ui:components": { stringField: "enumField", }, "ui:options": { enumNames: [ "United States", "Canada", "United Kingdom", "Germany", "France", ], }, }, skills: { "ui:components": { arrayField: "multiEnumField", }, "ui:options": { layouts: { "field-content": { style: "display: flex; flex-wrap: wrap; gap: 0.5rem;", }, }, }, }, bio: { "ui:components": { textWidget: "textareaWidget", }, "ui:options": { layouts: { "object-property": { style: "grid-row: span 2;", }, }, textarea: { rows: 5, }, flowbite3Textarea: { rows: 5, }, }, }, experience: { "ui:components": { stringField: "enumField", selectWidget: "radioWidget", }, "ui:options": { layouts: { "field-content": { style: "display: flex; flex-wrap: wrap; gap: 0.5rem;", }, }, shadcn4RadioGroup: { style: "grid-auto-flow: column; grid-auto-columns: max-content;", }, enumNames: ["0-2 years", "3-7 years", "8+ years"], }, }, startDate: { "ui:components": { textWidget: "datePickerWidget", }, }, resume: { "ui:components": { unknownField: "unknownNativeFileField", }, },};
export const initialValue: Data = { name: "Sarah Johnson", email: "sarah.johnson@invalid", age: 28, country: "CA", skills: ["HTML", "CSS", "JS/TS", "Svelte"], experience: "intermediate", startDate: new Date().toLocaleDateString("en-CA"), bio: "Bio",};
export function withFile(_: string, value: any) { if (value instanceof File) { return `File(${value.name}, ${formatFileSize(value.size)})`; } return value;}export { translation } from "@sjsf/form/translations/en";
export { resolver } from "@sjsf/form/resolvers/basic";import "@sjsf/form/fields/extra/enum-include";import "@sjsf/form/fields/extra/multi-enum-include";import "@sjsf/form/fields/extra/unknown-native-file-include";
export { theme } from "@sjsf/basic-theme";import "@sjsf/basic-theme/extra-widgets/textarea-include";import "@sjsf/basic-theme/extra-widgets/checkboxes-include";import "@sjsf/basic-theme/extra-widgets/radio-include";import "@sjsf/basic-theme/extra-widgets/file-include";import "@sjsf/basic-theme/extra-widgets/date-picker-include";
export { createFormIdBuilder as idBuilder } from "@sjsf/form/id-builders/modern";
export { createFormMerger as merger } from "@sjsf/form/mergers/modern";
import type { ValidatorFactoryOptions } from "@sjsf/form";import { addFormComponents, createFormValidator } from "@sjsf/ajv8-validator";import addFormats from "ajv-formats";
export const validator = <T>(options: ValidatorFactoryOptions) => createFormValidator<T>({ ...options, ajvPlugins: (ajv) => addFormComponents(addFormats(ajv)), });