Skip to content

Commit f8c8bea

Browse files
authored
[docs] Dynamic forms guide (#319)
* [docs] WIP: Add dynamic forms guide * [docs] Add `Dynamic forms` guide
1 parent 4cdb723 commit f8c8bea

File tree

5 files changed

+239
-0
lines changed

5 files changed

+239
-0
lines changed

.changeset/wicked-things-eat.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"docs2": minor
3+
---
4+
5+
Add `Dynamic forms` guide
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
<script lang="ts">
2+
import { SimpleForm, type Schema, type UiSchema } from "@sjsf/form";
3+
4+
import * as defaults from "@/lib/form/defaults";
5+
6+
const schema = {
7+
type: "object",
8+
properties: {
9+
foo: {
10+
type: "string",
11+
description:
12+
"If you enter anything here then `bar` will become required",
13+
},
14+
bar: {
15+
type: "string",
16+
description: "If you enter anything here then `baz` will appear",
17+
},
18+
},
19+
dependencies: {
20+
foo: ["bar"],
21+
bar: {
22+
properties: {
23+
baz: {
24+
enum: ["string", "number", "boolean"],
25+
description:
26+
"If you select anything here, the corresponding field will appear",
27+
},
28+
},
29+
},
30+
baz: {
31+
oneOf: [
32+
{
33+
properties: {
34+
baz: {
35+
const: "string",
36+
},
37+
string: {
38+
type: "string",
39+
},
40+
},
41+
},
42+
{
43+
properties: {
44+
baz: {
45+
const: "number",
46+
},
47+
number: {
48+
type: "number",
49+
},
50+
},
51+
},
52+
{
53+
properties: {
54+
baz: {
55+
const: "boolean",
56+
},
57+
boolean: {
58+
type: "boolean",
59+
},
60+
},
61+
},
62+
],
63+
},
64+
},
65+
} as const satisfies Schema;
66+
67+
const uiSchema: UiSchema = {
68+
baz: {
69+
"ui:components": {
70+
stringField: "enumField",
71+
},
72+
},
73+
};
74+
</script>
75+
76+
<SimpleForm {...defaults} {schema} {uiSchema} />
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
title: Dynamic forms
3+
sidebar:
4+
order: 57
5+
---
6+
7+
import { Code, Card, LinkCard, Tabs, TabItem } from '@astrojs/starlight/components';
8+
9+
import FormCard from '@/components/form-card.astro'
10+
11+
import OneOfForm from './one-of.svelte'
12+
import oneOfFromCode from './one-of.svelte?raw'
13+
14+
import DependenciesForm from './dependencies.svelte'
15+
import dependenciesFormCode from './dependencies.svelte?raw'
16+
17+
import IfElseThenFrom from './if-then-else.svelte'
18+
import ifElseThenFromCode from './if-then-else.svelte?raw'
19+
20+
Using the following JSON Schema keywords, you can build forms that change in
21+
response to user input.
22+
23+
## oneOf / anyOf
24+
25+
Fields `oneOf` or `anyOf` can be used as a **virtual selector**.
26+
This selector **does not modify form data directly** but determines which schema is active.
27+
28+
When the form is initialized with `initialValue`, SJSF **automatically selects the most suitable schema** based on the data.
29+
30+
<Tabs>
31+
<TabItem label="Form">
32+
<FormCard>
33+
<OneOfForm client:only="svelte" />
34+
</FormCard>
35+
</TabItem>
36+
<TabItem label="form.svelte">
37+
<Code code={oneOfFromCode} lang="svelte" />
38+
</TabItem>
39+
</Tabs>
40+
41+
42+
## dependencies
43+
44+
The `dependencies` keyword allows you to declare relationships between fields,
45+
where the presence or value of one field affects the schema of others.
46+
47+
<Tabs>
48+
<TabItem label="Form">
49+
<FormCard>
50+
<DependenciesForm client:only="svelte" />
51+
</FormCard>
52+
</TabItem>
53+
<TabItem label="form.svelte">
54+
<Code code={dependenciesFormCode} lang="svelte" />
55+
</TabItem>
56+
</Tabs>
57+
58+
## if/then/else
59+
60+
The `if/then/else` keywords allow you to define conditional schema branches based on form data.
61+
62+
<Tabs>
63+
<TabItem label="Form">
64+
<FormCard>
65+
<IfElseThenFrom client:only="svelte" />
66+
</FormCard>
67+
</TabItem>
68+
<TabItem label="form.svelte">
69+
<Code code={ifElseThenFromCode} lang="svelte" />
70+
</TabItem>
71+
</Tabs>
72+
73+
74+
## patternProperties
75+
76+
If your schema uses the `patternProperties` keyword, see the [advanced example](/examples/advanced/)
77+
`pattern-properties-validator` to improve the user experience.
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<script lang="ts">
2+
import { SimpleForm, type Schema } from "@sjsf/form";
3+
4+
import * as defaults from "@/lib/form/defaults";
5+
6+
const schema = {
7+
type: "object",
8+
properties: {
9+
isCompany: {
10+
type: "boolean",
11+
title: "Registering as a company",
12+
},
13+
},
14+
required: ["isCompany"],
15+
if: {
16+
properties: {
17+
isCompany: { const: true },
18+
},
19+
required: ["isCompany"],
20+
},
21+
then: {
22+
properties: {
23+
companyName: {
24+
type: "string",
25+
title: "Company name",
26+
},
27+
},
28+
required: ["companyName"],
29+
},
30+
else: {
31+
properties: {
32+
fullName: {
33+
type: "string",
34+
title: "Full name",
35+
},
36+
},
37+
required: ["fullName"],
38+
},
39+
} as const satisfies Schema;
40+
</script>
41+
42+
<SimpleForm {...defaults} {schema} />
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<script lang="ts">
2+
import { SimpleForm, type Schema } from "@sjsf/form";
3+
4+
import * as defaults from "@/lib/form/defaults";
5+
6+
const schema = {
7+
type: "object",
8+
properties: {
9+
common: {
10+
type: "string",
11+
},
12+
},
13+
oneOf: [
14+
{
15+
title: "Foo schema",
16+
properties: {
17+
foo: {
18+
type: "string",
19+
},
20+
},
21+
},
22+
{
23+
title: "Bar schema",
24+
properties: {
25+
bar: {
26+
type: "string",
27+
},
28+
},
29+
},
30+
],
31+
} as const satisfies Schema;
32+
33+
const initialValue = {
34+
common: "hello",
35+
bar: "world",
36+
};
37+
</script>
38+
39+
<SimpleForm {...defaults} {schema} {initialValue} />

0 commit comments

Comments
 (0)