Migration from v1
Version 2 brings a lot of changes, but most of them relate to the internal mechanisms of the library and in most cases it will be enough for you to switch to the current syntax without semantic changes.
Component Renames
Section titled “Component Renames”Now:
createForm3
->createForm
createValidator2
->createFormValidator
RawForm
->BasicForm
Form2
->SimpleForm
The logic behind component naming is as follows: BasicForm
- provides
only basic functionality, while SimpleForm
- provides a simple way to
instantiate a form.
The theme
is now a single function.
Section titled “The theme is now a single function.”This change allows fields, widget templates and components to be
overridden/added simultaneously and type-safe thanks to
the @sjsf/form/lib/resolver
library.
To make it work you need to remove ...
before theme
.
import { theme } from 'theme-path'
const form = createForm({ theme, ... })
Example of field override:
import { overrideByRecord } from "@sjsf/form/lib/resolver";import { theme } from 'theme-path';
import MyField from './my-field';
const myTheme = overrideByRecord(theme, { fieldTemplate: MyField,})
The number of components in the default theme has been reduced
Section titled “The number of components in the default theme has been reduced”It was found out that the following fields and widgets are enough to display any JSON schema:
stringField
,numberField
,integerField
,booleanField
,objectField
,arrayField
,tupleField
,nullField
,oneOfField
,anyOfField
textWidget
,numberWidget
,selectWidget
,checkboxWidget
Therefore, all other fields and widgets are placed in optional extra
modules.
You can import them directly or use special imports to connect them automatically.
// Include extra fieldsimport "@sjsf/form/fields/extra-fields/boolean-select-include";import "@sjsf/form/fields/extra-fields/enum-include";import "@sjsf/form/fields/extra-fields/file-include";import "@sjsf/form/fields/extra-fields/files-include";import "@sjsf/form/fields/extra-fields/multi-enum-include";// Include extra widget for basic themeimport { theme } from "@sjsf/basic-theme";import '@sjsf/basic-theme/extra-widgets/checkboxes-include';import '@sjsf/basic-theme/extra-widgets/file-include';import "@sjsf/basic-theme/extra-widgets/multi-select-include";import "@sjsf/basic-theme/extra-widgets/textarea-include";import "@sjsf/basic-theme/extra-widgets/radio-include";import "@sjsf/basic-theme/extra-widgets/date-picker-include";
const from = createForm({ theme, ... })
However extra
fields will not be used automatically,
for this you need to use the new resolver
property or
explicitly replace one field with another in uiSchema
.
New required resolver
property
Section titled “New required resolver property”Previously, the logic for selecting a field to display the schema was spread across multiple components and could not be changed without replacing those components (RootField
, ArrayField
).
Now this logic is placed in a separate function resolver
, which allows to change/extend this algorithm without affecting UI components.
Therefore, you must add this property when calling createForm
and SimpleForm
import { resolver } from '@sjsf/from/resolvers/basic'// Or a variant reproducing the logic of the v1import { resolver } from '@sjsf/from/resolvers/compat'
const form = createForm({ resolver, ... })
UiSchema
overhaul
Section titled “UiSchema overhaul”Properties ui:widget
, ui:field
and ui:templates
are merged into ui:components
.
This property allows you to replace one component with another if they are compatible.
import MyLayout from "./my-layout.svelte";
const uiSchema: UiSchema = { "ui:components": { textWidget: "textareaWidget", layout: MyLayout, }}
Properties such as input
, content
, container
, button
and form
have been removed from ui:options
. Now each theme independently defines
a set of ui options allowing to customize its components.
Motivation - different themes use different base components and their properties
may not be compatible. For example for textWidget
from basic-theme
it
is HTMLInputAttributes
and for flowbite-theme
it is InputProps
.
Validators overhaul
Section titled “Validators overhaul”Now the validator is just a set of functions:
isValid
(called to correctly handle the following keywordsoneOf
,anyOf
andif,then,else
, required)validateFormValue
(optional)validateFormValueAsync
(optional)validateFieldValue
(optional)validateFieldValueAsync
(optional)validateAdditionalPropertyKey
(optional)
So now you can easily extend/modify the validator to suit your needs.
import type { ErrorObject } from "ajv";import { isSchemaObjectValue } from "@sjsf/form/core";import type { FormValueValidator } from "@sjsf/form";import { createFormValidator } from "@sjsf/ajv8-validator";
export function createValidator() { const validator = createFormValidator(); return { ...validator, validateFormValue(rootSchema, formValue) { const errors = validator.validateFormValue(rootSchema, formValue); // Your logic return errors }, } satisfies FormValueValidator<ErrorObject>;}
Checkbox
, Range
and Switch
widgets behavior
Section titled “Checkbox, Range and Switch widgets behavior”In v1
those widgets would set its field to some default value if its value was undefined
(this behavior can be observed when using <input type=“checkbox” bind:checked ...
)
In v2
this behavior was removed to keep the behavior uniform with other primitive input elements.
To reproduce the previous behavior, add default: <some default value>
to the JSON schema.
There are actually a lot more changes in this release, but considering their
nature (mostly internal) and the number of active users at the moment
(small relative to rjsf
) I think it is not rational to try to create a
comprehensive guide.
Feel free to get in touch about migrating to v2 on GitHub or in the Svelte ecosystem discrod channel.