Theme and resolver
Essentially theme is a simple function:
const fromRecord = (record) => (type) => record[type]const theme = fromRecord(components)
Component types
Section titled “Component types”All components can be divided into four logical types:
- components
form
submitButton
button
layout
title
label
description
help
errorsList
- widgets
textWidget
numberWidget
selectWidget
checkboxWidget
- templates
fieldTemplate
objectTemplate
objectPropertyTemplate
arrayTemplate
arrayItemTemplate
multiFieldTemplate
- fields
stringField
numberField
integerField
booleanField
objectField
arrayField
tupleField
nullField
oneOfField
anyOfField
Also found out that the above components are enough to display any JSON schema.
Resolver
Section titled “Resolver”To determine which field to use to display your JSON schema, the form uses resolver
.
interface Config { id: Id; name: string; title: string; schema: Schema; uiSchema: UiSchema; uiOptions: UiOptions | undefined; required: boolean;}
type ResolveFieldType = (config: Config) => FoundationalFieldType
type Resolver = (ctx: FormInternalContext<Validator>) => ResolveFieldType
It looks complicated, but let’s take a look at the basic
resolver implementation
(@sjsf/form/resolvers/basic
):
function resolver(): ResolveFieldType { return ({ schema }) => { if (schema.oneOf !== undefined) { return "oneOfField"; } if (schema.anyOf !== undefined) { return "anyOfField"; } const type = getSimpleSchemaType(schema); if (type === "array") { return isFixedItems(schema) ? "tupleField" : "arrayField"; } return `${type}Field`; }}
Yes, it’s essentially a direct mapping of schema type to field type, nothing fancy.
Let’s talk about FoundationalFieldType
.
Foundational components
Section titled “Foundational components”The FoundationalFieldType
type is a subset of the fields from the
FoundationalComponentType
type.
In turn, FoundationalComponentType
is a subset of all components
(ComponentType
) that can be explicitly used in form elements.
For example, this is possible because form
is a FoundationalComponentType
<script lang="ts"> ... const Form = $derived(getComponent(ctx, "form", config));</script>
<Form bind:ref {config} {children} {attributes} />
The main purpose of this list is to determine which components you can replace
using the ui:components
property from UiSchema
.
This is an extensible list, but by default it corresponds to the components listed in Component types.
Extra components
Section titled “Extra components”If the default set of components is insufficient, you can add the necessary components yourself.
The sjsf
library provides definitions and implementation of several extra
fields, as well as a set of definitions for extra widgets.
Fields
Section titled “Fields”Here is a list of extra fields that can be imported from @sjsf/form/fields/extra-fields/*
.
boolean-select
enum
file
files
multi-enum
tags
To use them you can import them directly
import EnumField from "@sjsf/form/fields/extra-fields/enum";
or use an include
import
import "@sjsf/form/fields/extra-fields/enum-include";
and replace the compatible field with it in uiSchema
.
const uiSchema: UISchema = { "ui:components": { stringField: EnumField, // Or if you used the `include` import stringField: "enumField" }}
Widgets
Section titled “Widgets”There are several types of extra widgets already defined in the library
(@sjsf/form/fields/extra-widgets/*
):
checkboxes
date-picker
file
multi-select
radio-buttons
radio
(group)range
rating
switch
tags
textarea
However, the ability to use them depends on the availability of a corresponding implementation in your chosen theme.