@sanity/form-toolkit 2.1.0 → 2.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +33 -3
- package/dist/form-renderer/index.d.mts +66 -0
- package/dist/form-renderer/index.d.ts +66 -0
- package/dist/form-renderer/index.js +128 -0
- package/dist/form-renderer/index.js.map +1 -0
- package/dist/form-renderer/index.mjs +128 -0
- package/dist/form-renderer/index.mjs.map +1 -0
- package/dist/form-schema/index.d.mts +23 -64
- package/dist/form-schema/index.d.ts +23 -64
- package/dist/form-schema/index.js +72 -185
- package/dist/form-schema/index.js.map +1 -1
- package/dist/form-schema/index.mjs +72 -186
- package/dist/form-schema/index.mjs.map +1 -1
- package/package.json +9 -1
- package/src/{form-schema → form-renderer}/components/default-field.tsx +11 -3
- package/src/{form-schema → form-renderer}/components/types.ts +0 -2
- package/src/form-renderer/index.ts +4 -0
- package/src/form-schema/components/validation-type.tsx +14 -0
- package/src/form-schema/index.ts +12 -6
- package/src/form-schema/schema-types/form-field.ts +66 -52
- package/src/form-schema/schema-types/form.ts +50 -53
- package/src/form-schema/schema-types/index.ts +3 -2
- package/src/form-schema/structure/document-view.tsx +0 -78
- package/src/form-schema/structure/index.ts +0 -11
- /package/src/{form-schema → form-renderer}/components/form-renderer.tsx +0 -0
package/README.md
CHANGED
|
@@ -170,15 +170,45 @@ import {formSchema} from '@sanity/form-toolkit/form-schema'
|
|
|
170
170
|
|
|
171
171
|
export default defineConfig({
|
|
172
172
|
//...
|
|
173
|
-
plugins: [
|
|
173
|
+
plugins: [
|
|
174
|
+
formSchema({
|
|
175
|
+
// Optionally, use your own schemas for additional formFields
|
|
176
|
+
fields: [
|
|
177
|
+
defineField({
|
|
178
|
+
name: 'myField',
|
|
179
|
+
type: 'myObjectType',
|
|
180
|
+
}),
|
|
181
|
+
],
|
|
182
|
+
}),
|
|
183
|
+
],
|
|
184
|
+
})
|
|
185
|
+
```
|
|
186
|
+
|
|
187
|
+
This will create a "form" document type.
|
|
188
|
+
Then, add a field to your schema with type `form`
|
|
189
|
+
|
|
190
|
+
```ts
|
|
191
|
+
// ./src/schemaTypes/page.ts
|
|
192
|
+
import {defineField, defineType} from 'sanity'
|
|
193
|
+
|
|
194
|
+
export default defineType({
|
|
195
|
+
name: 'page',
|
|
196
|
+
type: 'document',
|
|
197
|
+
fields: [
|
|
198
|
+
defineField({
|
|
199
|
+
name: 'form',
|
|
200
|
+
type: 'reference',
|
|
201
|
+
to: [{type: 'form'}],
|
|
202
|
+
}),
|
|
203
|
+
],
|
|
174
204
|
})
|
|
175
205
|
```
|
|
176
206
|
|
|
177
|
-
|
|
207
|
+
Finally, pass a `form` document to the `FormRenderer` component
|
|
178
208
|
|
|
179
209
|
```tsx
|
|
180
210
|
import React, {type FC} from 'react'
|
|
181
|
-
import {FormRenderer, type FormDataProps} from '@sanity/form-toolkit/form-
|
|
211
|
+
import {FormRenderer, type FormDataProps} from '@sanity/form-toolkit/form-renderer'
|
|
182
212
|
|
|
183
213
|
interface NativeFormExampleProps {
|
|
184
214
|
formData: FormDataProps
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type {ComponentType} from 'react'
|
|
2
|
+
import type {FC} from 'react'
|
|
3
|
+
import type {HTMLProps} from 'react'
|
|
4
|
+
|
|
5
|
+
declare type FieldChoice = {
|
|
6
|
+
label: string
|
|
7
|
+
value: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare interface FieldComponentProps {
|
|
11
|
+
field: FormField
|
|
12
|
+
fieldState: FieldState
|
|
13
|
+
error?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare type FieldOptions = {
|
|
17
|
+
placeholder?: string
|
|
18
|
+
defaultValue?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare interface FieldState {
|
|
22
|
+
value?: string | number | readonly string[]
|
|
23
|
+
onChange: (value: unknown) => void
|
|
24
|
+
onBlur?: () => void
|
|
25
|
+
ref?: unknown
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export declare type FormDataProps = {
|
|
29
|
+
title: string
|
|
30
|
+
id: {
|
|
31
|
+
current: string
|
|
32
|
+
}
|
|
33
|
+
fields?: FormField[]
|
|
34
|
+
submitButton?: {
|
|
35
|
+
text: string
|
|
36
|
+
position: 'left' | 'center' | 'right'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare type FormField = {
|
|
41
|
+
type: string
|
|
42
|
+
label?: string
|
|
43
|
+
name: string
|
|
44
|
+
required?: boolean
|
|
45
|
+
validation?: ValidationRule[]
|
|
46
|
+
options?: FieldOptions
|
|
47
|
+
choices?: FieldChoice[]
|
|
48
|
+
_key?: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export declare const FormRenderer: FC<FormRendererProps>
|
|
52
|
+
|
|
53
|
+
declare interface FormRendererProps extends HTMLProps<HTMLFormElement> {
|
|
54
|
+
formData?: FormDataProps
|
|
55
|
+
getFieldState?: (fieldName: string) => FieldState
|
|
56
|
+
getFieldError?: (fieldName: string) => string | undefined
|
|
57
|
+
fieldComponents?: Record<string, ComponentType<FieldComponentProps>>
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare type ValidationRule = {
|
|
61
|
+
type: string
|
|
62
|
+
value: string
|
|
63
|
+
message: string
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export {}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import type {ComponentType} from 'react'
|
|
2
|
+
import type {FC} from 'react'
|
|
3
|
+
import type {HTMLProps} from 'react'
|
|
4
|
+
|
|
5
|
+
declare type FieldChoice = {
|
|
6
|
+
label: string
|
|
7
|
+
value: string
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
declare interface FieldComponentProps {
|
|
11
|
+
field: FormField
|
|
12
|
+
fieldState: FieldState
|
|
13
|
+
error?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
declare type FieldOptions = {
|
|
17
|
+
placeholder?: string
|
|
18
|
+
defaultValue?: string
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
declare interface FieldState {
|
|
22
|
+
value?: string | number | readonly string[]
|
|
23
|
+
onChange: (value: unknown) => void
|
|
24
|
+
onBlur?: () => void
|
|
25
|
+
ref?: unknown
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export declare type FormDataProps = {
|
|
29
|
+
title: string
|
|
30
|
+
id: {
|
|
31
|
+
current: string
|
|
32
|
+
}
|
|
33
|
+
fields?: FormField[]
|
|
34
|
+
submitButton?: {
|
|
35
|
+
text: string
|
|
36
|
+
position: 'left' | 'center' | 'right'
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
declare type FormField = {
|
|
41
|
+
type: string
|
|
42
|
+
label?: string
|
|
43
|
+
name: string
|
|
44
|
+
required?: boolean
|
|
45
|
+
validation?: ValidationRule[]
|
|
46
|
+
options?: FieldOptions
|
|
47
|
+
choices?: FieldChoice[]
|
|
48
|
+
_key?: string
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export declare const FormRenderer: FC<FormRendererProps>
|
|
52
|
+
|
|
53
|
+
declare interface FormRendererProps extends HTMLProps<HTMLFormElement> {
|
|
54
|
+
formData?: FormDataProps
|
|
55
|
+
getFieldState?: (fieldName: string) => FieldState
|
|
56
|
+
getFieldError?: (fieldName: string) => string | undefined
|
|
57
|
+
fieldComponents?: Record<string, ComponentType<FieldComponentProps>>
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare type ValidationRule = {
|
|
61
|
+
type: string
|
|
62
|
+
value: string
|
|
63
|
+
message: string
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export {}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: !0 });
|
|
3
|
+
var jsxRuntime = require("react/jsx-runtime");
|
|
4
|
+
const DefaultField = ({ field, fieldState, error }) => {
|
|
5
|
+
const { type, label, name, options = {}, choices = [], validation = [] } = field;
|
|
6
|
+
if (!type || !name) return null;
|
|
7
|
+
const validationRules = validation.reduce((acc, v) => (acc[v.type] = v.value, acc), {}), { value, onChange, onBlur, ref } = fieldState, handleChange = (e) => {
|
|
8
|
+
onChange(e.target.value);
|
|
9
|
+
}, handleCheckboxChange = (e, choiceValue) => {
|
|
10
|
+
if (Array.isArray(value)) {
|
|
11
|
+
const newValue = e.target.checked ? [...value, choiceValue] : value.filter((v) => v !== choiceValue);
|
|
12
|
+
onChange(newValue);
|
|
13
|
+
} else
|
|
14
|
+
onChange(e.target.checked ? choiceValue : "");
|
|
15
|
+
}, renderInput = () => {
|
|
16
|
+
switch (type) {
|
|
17
|
+
case "submit":
|
|
18
|
+
return /* @__PURE__ */ jsxRuntime.jsx("button", { type: "submit", children: label || "Submit" });
|
|
19
|
+
case "textarea":
|
|
20
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
21
|
+
"textarea",
|
|
22
|
+
{
|
|
23
|
+
ref,
|
|
24
|
+
name,
|
|
25
|
+
onChange: handleChange,
|
|
26
|
+
onBlur,
|
|
27
|
+
placeholder: options.placeholder,
|
|
28
|
+
...validationRules,
|
|
29
|
+
value: value ?? ""
|
|
30
|
+
}
|
|
31
|
+
);
|
|
32
|
+
case "select":
|
|
33
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
34
|
+
"select",
|
|
35
|
+
{
|
|
36
|
+
ref,
|
|
37
|
+
name,
|
|
38
|
+
value: value ?? "",
|
|
39
|
+
onChange: handleChange,
|
|
40
|
+
...validationRules,
|
|
41
|
+
onBlur,
|
|
42
|
+
children: choices?.map((choice, i) => /* @__PURE__ */ jsxRuntime.jsx("option", { value: choice.value, children: choice.label }, i))
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
case "radio":
|
|
46
|
+
return choices?.map((choice, i) => /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
|
|
47
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
48
|
+
"input",
|
|
49
|
+
{
|
|
50
|
+
type: "radio",
|
|
51
|
+
name,
|
|
52
|
+
ref,
|
|
53
|
+
value: choice.value,
|
|
54
|
+
checked: value === choice.value,
|
|
55
|
+
onChange: handleChange,
|
|
56
|
+
onBlur,
|
|
57
|
+
...validationRules
|
|
58
|
+
}
|
|
59
|
+
),
|
|
60
|
+
choice.label
|
|
61
|
+
] }, i));
|
|
62
|
+
case "checkbox":
|
|
63
|
+
return choices?.map((choice, i) => /* @__PURE__ */ jsxRuntime.jsxs("label", { children: [
|
|
64
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
65
|
+
"input",
|
|
66
|
+
{
|
|
67
|
+
type: "checkbox",
|
|
68
|
+
name,
|
|
69
|
+
ref,
|
|
70
|
+
value: choice.value,
|
|
71
|
+
checked: Array.isArray(value) ? value.includes(choice.value) : value === choice.value,
|
|
72
|
+
onChange: (e) => handleCheckboxChange(e, choice.value),
|
|
73
|
+
onBlur,
|
|
74
|
+
...validationRules
|
|
75
|
+
}
|
|
76
|
+
),
|
|
77
|
+
choice.label
|
|
78
|
+
] }, i));
|
|
79
|
+
default:
|
|
80
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
81
|
+
"input",
|
|
82
|
+
{
|
|
83
|
+
type,
|
|
84
|
+
ref,
|
|
85
|
+
name,
|
|
86
|
+
value: value ?? options.defaultValue ?? "",
|
|
87
|
+
onChange: handleChange,
|
|
88
|
+
...validationRules,
|
|
89
|
+
onBlur,
|
|
90
|
+
placeholder: options.placeholder
|
|
91
|
+
}
|
|
92
|
+
);
|
|
93
|
+
}
|
|
94
|
+
};
|
|
95
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
|
|
96
|
+
label && !["hidden", "submit"].includes(type) && /* @__PURE__ */ jsxRuntime.jsx("label", { htmlFor: name, children: label }),
|
|
97
|
+
renderInput(),
|
|
98
|
+
error && /* @__PURE__ */ jsxRuntime.jsx("span", { className: "error", children: error })
|
|
99
|
+
] });
|
|
100
|
+
}, FormRenderer = (props) => {
|
|
101
|
+
const {
|
|
102
|
+
formData,
|
|
103
|
+
getFieldState = (name) => ({
|
|
104
|
+
value: void 0,
|
|
105
|
+
onChange: () => {
|
|
106
|
+
},
|
|
107
|
+
name
|
|
108
|
+
// Pass name to field for native form handling
|
|
109
|
+
}),
|
|
110
|
+
getFieldError,
|
|
111
|
+
fieldComponents = {},
|
|
112
|
+
children
|
|
113
|
+
} = props, renderField = (field) => {
|
|
114
|
+
const CustomComponent = fieldComponents[field.type], fieldState = getFieldState(field.name), error = getFieldError?.(field.name);
|
|
115
|
+
return CustomComponent ? /* @__PURE__ */ jsxRuntime.jsx(CustomComponent, { field, fieldState, error }) : /* @__PURE__ */ jsxRuntime.jsx(DefaultField, { field, fieldState, error });
|
|
116
|
+
}, elProps = Object.assign({}, props);
|
|
117
|
+
return delete elProps.formData, delete elProps.getFieldState, delete elProps.getFieldError, delete elProps.fieldComponents, /* @__PURE__ */ jsxRuntime.jsxs("form", { ...elProps, id: elProps.id ?? formData?.id?.current, children: [
|
|
118
|
+
formData?.fields?.map((field) => /* @__PURE__ */ jsxRuntime.jsx("div", { className: "form-field", children: renderField(field) }, field._key)),
|
|
119
|
+
children,
|
|
120
|
+
renderField({
|
|
121
|
+
type: "submit",
|
|
122
|
+
name: "submit",
|
|
123
|
+
label: formData?.submitButton?.text || "Submit"
|
|
124
|
+
})
|
|
125
|
+
] });
|
|
126
|
+
};
|
|
127
|
+
exports.FormRenderer = FormRenderer;
|
|
128
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../src/form-renderer/components/default-field.tsx","../../src/form-renderer/components/form-renderer.tsx"],"sourcesContent":["import type {ChangeEvent, FC, LegacyRef} from 'react'\n\nimport type {FieldComponentProps} from './types'\n\nexport const DefaultField: FC<FieldComponentProps> = ({field, fieldState, error}) => {\n const {type, label, name, options = {}, choices = [], validation = []} = field\n if (!type || !name) return null\n const validationRules = validation.reduce((acc: Record<string, string>, v) => {\n acc[v.type] = v.value\n return acc\n }, {})\n const {value, onChange, onBlur, ref} = fieldState\n\n const handleChange = (\n e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>,\n ) => {\n onChange(e.target.value)\n }\n\n const handleCheckboxChange = (e: ChangeEvent<HTMLInputElement>, choiceValue: string) => {\n if (Array.isArray(value)) {\n const newValue = e.target.checked\n ? [...value, choiceValue]\n : value.filter((v: string) => v !== choiceValue)\n onChange(newValue)\n } else {\n onChange(e.target.checked ? choiceValue : '')\n }\n }\n\n const renderInput = () => {\n switch (type) {\n case 'submit':\n return <button type=\"submit\">{label || 'Submit'}</button>\n case 'textarea':\n return (\n <textarea\n ref={ref as LegacyRef<HTMLTextAreaElement>}\n name={name}\n onChange={handleChange}\n onBlur={onBlur}\n placeholder={options.placeholder}\n {...validationRules}\n value={value ?? ''}\n />\n )\n\n case 'select':\n return (\n <select\n ref={ref as LegacyRef<HTMLSelectElement>}\n name={name}\n value={value ?? ''}\n onChange={handleChange}\n {...validationRules}\n onBlur={onBlur}\n >\n {choices?.map((choice, i) => (\n <option key={i} value={choice.value}>\n {choice.label}\n </option>\n ))}\n </select>\n )\n\n case 'radio':\n return choices?.map((choice, i) => (\n <label key={i}>\n <input\n type=\"radio\"\n name={name}\n ref={ref as LegacyRef<HTMLInputElement>}\n value={choice.value}\n checked={value === choice.value}\n onChange={handleChange}\n onBlur={onBlur}\n {...validationRules}\n />\n {choice.label}\n </label>\n ))\n\n case 'checkbox':\n return choices?.map((choice, i) => (\n <label key={i}>\n <input\n type=\"checkbox\"\n name={name}\n ref={ref as LegacyRef<HTMLInputElement>}\n value={choice.value}\n checked={Array.isArray(value) ? value.includes(choice.value) : value === choice.value}\n onChange={(e) => handleCheckboxChange(e, choice.value)}\n onBlur={onBlur}\n {...validationRules}\n />\n {choice.label}\n </label>\n ))\n\n default:\n return (\n <input\n type={type}\n ref={ref as LegacyRef<HTMLInputElement>}\n name={name}\n value={value ?? options.defaultValue ?? ''}\n onChange={handleChange}\n {...validationRules}\n onBlur={onBlur}\n placeholder={options.placeholder}\n />\n )\n }\n }\n\n return (\n <>\n {label && !['hidden', 'submit'].includes(type) && <label htmlFor={name}>{label}</label>}\n {renderInput()}\n {error && <span className=\"error\">{error}</span>}\n </>\n )\n}\n","import type {ComponentType, FC, HTMLProps} from 'react'\n\nimport {DefaultField} from './default-field'\nimport type {FieldComponentProps, FieldState, FormDataProps, FormField} from './types'\n\ninterface FormRendererProps extends HTMLProps<HTMLFormElement> {\n formData?: FormDataProps\n // Function to get field state for a given field name\n getFieldState?: (fieldName: string) => FieldState\n // Function to get field error for a given field name\n getFieldError?: (fieldName: string) => string | undefined\n // Override default field components\n fieldComponents?: Record<string, ComponentType<FieldComponentProps>>\n}\n\nexport const FormRenderer: FC<FormRendererProps> = (props) => {\n const {\n formData,\n getFieldState = (name) => ({\n value: undefined,\n onChange: () => {},\n name, // Pass name to field for native form handling\n }),\n getFieldError,\n fieldComponents = {},\n children,\n } = props\n const renderField = (field: FormField) => {\n const CustomComponent = fieldComponents[field.type]\n const fieldState = getFieldState(field.name)\n const error = getFieldError?.(field.name)\n\n if (CustomComponent) {\n return <CustomComponent field={field} fieldState={fieldState} error={error} />\n }\n\n return <DefaultField field={field} fieldState={fieldState} error={error} />\n }\n const elProps = Object.assign({}, props)\n delete elProps.formData\n delete elProps.getFieldState\n delete elProps.getFieldError\n delete elProps.fieldComponents\n\n return (\n <form {...elProps} id={elProps.id ?? formData?.id?.current}>\n {formData?.fields?.map((field) => (\n <div key={field._key} className=\"form-field\">\n {renderField(field)}\n </div>\n ))}\n\n {children}\n\n {renderField({\n type: 'submit',\n name: 'submit',\n label: formData?.submitButton?.text || 'Submit',\n })}\n </form>\n )\n}\n"],"names":["jsx","jsxs","Fragment"],"mappings":";;;AAIO,MAAM,eAAwC,CAAC,EAAC,OAAO,YAAY,YAAW;AACnF,QAAM,EAAC,MAAM,OAAO,MAAM,UAAU,IAAI,UAAU,CAAC,GAAG,aAAa,CAAA,EAAM,IAAA;AACzE,MAAI,CAAC,QAAQ,CAAC,KAAa,QAAA;AACrB,QAAA,kBAAkB,WAAW,OAAO,CAAC,KAA6B,OACtE,IAAI,EAAE,IAAI,IAAI,EAAE,OACT,MACN,CAAE,CAAA,GACC,EAAC,OAAO,UAAU,QAAQ,QAAO,YAEjC,eAAe,CACnB,MACG;AACM,aAAA,EAAE,OAAO,KAAK;AAAA,EAAA,GAGnB,uBAAuB,CAAC,GAAkC,gBAAwB;AAClF,QAAA,MAAM,QAAQ,KAAK,GAAG;AACxB,YAAM,WAAW,EAAE,OAAO,UACtB,CAAC,GAAG,OAAO,WAAW,IACtB,MAAM,OAAO,CAAC,MAAc,MAAM,WAAW;AACjD,eAAS,QAAQ;AAAA,IACnB;AACE,eAAS,EAAE,OAAO,UAAU,cAAc,EAAE;AAAA,EAEhD,GAEM,cAAc,MAAM;AACxB,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,eAAQA,2BAAA,IAAA,UAAA,EAAO,MAAK,UAAU,mBAAS,UAAS;AAAA,MAClD,KAAK;AAED,eAAAA,2BAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,UAAU;AAAA,YACV;AAAA,YACA,aAAa,QAAQ;AAAA,YACpB,GAAG;AAAA,YACJ,OAAO,SAAS;AAAA,UAAA;AAAA,QAClB;AAAA,MAGJ,KAAK;AAED,eAAAA,2BAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA,OAAO,SAAS;AAAA,YAChB,UAAU;AAAA,YACT,GAAG;AAAA,YACJ;AAAA,YAEC,UAAS,SAAA,IAAI,CAAC,QAAQ,MACrBA,2BAAAA,IAAC,UAAe,EAAA,OAAO,OAAO,OAC3B,UAAO,OAAA,MAAA,GADG,CAEb,CACD;AAAA,UAAA;AAAA,QACH;AAAA,MAGJ,KAAK;AACH,eAAO,SAAS,IAAI,CAAC,QAAQ,sCAC1B,SACC,EAAA,UAAA;AAAA,UAAAA,2BAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL;AAAA,cACA;AAAA,cACA,OAAO,OAAO;AAAA,cACd,SAAS,UAAU,OAAO;AAAA,cAC1B,UAAU;AAAA,cACV;AAAA,cACC,GAAG;AAAA,YAAA;AAAA,UACN;AAAA,UACC,OAAO;AAAA,QAAA,EAAA,GAXE,CAYZ,CACD;AAAA,MAEH,KAAK;AACH,eAAO,SAAS,IAAI,CAAC,QAAQ,sCAC1B,SACC,EAAA,UAAA;AAAA,UAAAA,2BAAA;AAAA,YAAC;AAAA,YAAA;AAAA,cACC,MAAK;AAAA,cACL;AAAA,cACA;AAAA,cACA,OAAO,OAAO;AAAA,cACd,SAAS,MAAM,QAAQ,KAAK,IAAI,MAAM,SAAS,OAAO,KAAK,IAAI,UAAU,OAAO;AAAA,cAChF,UAAU,CAAC,MAAM,qBAAqB,GAAG,OAAO,KAAK;AAAA,cACrD;AAAA,cACC,GAAG;AAAA,YAAA;AAAA,UACN;AAAA,UACC,OAAO;AAAA,QAAA,EAAA,GAXE,CAYZ,CACD;AAAA,MAEH;AAEI,eAAAA,2BAAA;AAAA,UAAC;AAAA,UAAA;AAAA,YACC;AAAA,YACA;AAAA,YACA;AAAA,YACA,OAAO,SAAS,QAAQ,gBAAgB;AAAA,YACxC,UAAU;AAAA,YACT,GAAG;AAAA,YACJ;AAAA,YACA,aAAa,QAAQ;AAAA,UAAA;AAAA,QACvB;AAAA,IAAA;AAAA,EAGR;AAEA,SAEKC,2BAAA,KAAAC,qBAAA,EAAA,UAAA;AAAA,IAAA,SAAS,CAAC,CAAC,UAAU,QAAQ,EAAE,SAAS,IAAI,KAAMF,2BAAAA,IAAA,SAAA,EAAM,SAAS,MAAO,UAAM,MAAA,CAAA;AAAA,IAC9E,YAAY;AAAA,IACZ,SAASA,2BAAA,IAAC,QAAK,EAAA,WAAU,SAAS,UAAM,MAAA,CAAA;AAAA,EAAA,GAC3C;AAEJ,GC3Ga,eAAsC,CAAC,UAAU;AACtD,QAAA;AAAA,IACJ;AAAA,IACA,gBAAgB,CAAC,UAAU;AAAA,MACzB,OAAO;AAAA,MACP,UAAU,MAAM;AAAA,MAAC;AAAA,MACjB;AAAA;AAAA,IAAA;AAAA,IAEF;AAAA,IACA,kBAAkB,CAAC;AAAA,IACnB;AAAA,EAAA,IACE,OACE,cAAc,CAAC,UAAqB;AACxC,UAAM,kBAAkB,gBAAgB,MAAM,IAAI,GAC5C,aAAa,cAAc,MAAM,IAAI,GACrC,QAAQ,gBAAgB,MAAM,IAAI;AAEpC,WAAA,kBACMA,2BAAA,IAAA,iBAAA,EAAgB,OAAc,YAAwB,MAAc,CAAA,IAGtEA,2BAAAA,IAAA,cAAA,EAAa,OAAc,YAAwB,MAAc,CAAA;AAAA,KAErE,UAAU,OAAO,OAAO,CAAA,GAAI,KAAK;AAChC,SAAA,OAAA,QAAQ,UACf,OAAO,QAAQ,eACf,OAAO,QAAQ,eACf,OAAO,QAAQ,iBAGZC,2BAAA,KAAA,QAAA,EAAM,GAAG,SAAS,IAAI,QAAQ,MAAM,UAAU,IAAI,SAChD,UAAA;AAAA,IAAA,UAAU,QAAQ,IAAI,CAAC,UACrBD,2BAAAA,IAAA,OAAA,EAAqB,WAAU,cAC7B,UAAY,YAAA,KAAK,EADV,GAAA,MAAM,IAEhB,CACD;AAAA,IAEA;AAAA,IAEA,YAAY;AAAA,MACX,MAAM;AAAA,MACN,MAAM;AAAA,MACN,OAAO,UAAU,cAAc,QAAQ;AAAA,IACxC,CAAA;AAAA,EAAA,GACH;AAEJ;;"}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { jsxs, Fragment, jsx } from "react/jsx-runtime";
|
|
2
|
+
const DefaultField = ({ field, fieldState, error }) => {
|
|
3
|
+
const { type, label, name, options = {}, choices = [], validation = [] } = field;
|
|
4
|
+
if (!type || !name) return null;
|
|
5
|
+
const validationRules = validation.reduce((acc, v) => (acc[v.type] = v.value, acc), {}), { value, onChange, onBlur, ref } = fieldState, handleChange = (e) => {
|
|
6
|
+
onChange(e.target.value);
|
|
7
|
+
}, handleCheckboxChange = (e, choiceValue) => {
|
|
8
|
+
if (Array.isArray(value)) {
|
|
9
|
+
const newValue = e.target.checked ? [...value, choiceValue] : value.filter((v) => v !== choiceValue);
|
|
10
|
+
onChange(newValue);
|
|
11
|
+
} else
|
|
12
|
+
onChange(e.target.checked ? choiceValue : "");
|
|
13
|
+
}, renderInput = () => {
|
|
14
|
+
switch (type) {
|
|
15
|
+
case "submit":
|
|
16
|
+
return /* @__PURE__ */ jsx("button", { type: "submit", children: label || "Submit" });
|
|
17
|
+
case "textarea":
|
|
18
|
+
return /* @__PURE__ */ jsx(
|
|
19
|
+
"textarea",
|
|
20
|
+
{
|
|
21
|
+
ref,
|
|
22
|
+
name,
|
|
23
|
+
onChange: handleChange,
|
|
24
|
+
onBlur,
|
|
25
|
+
placeholder: options.placeholder,
|
|
26
|
+
...validationRules,
|
|
27
|
+
value: value ?? ""
|
|
28
|
+
}
|
|
29
|
+
);
|
|
30
|
+
case "select":
|
|
31
|
+
return /* @__PURE__ */ jsx(
|
|
32
|
+
"select",
|
|
33
|
+
{
|
|
34
|
+
ref,
|
|
35
|
+
name,
|
|
36
|
+
value: value ?? "",
|
|
37
|
+
onChange: handleChange,
|
|
38
|
+
...validationRules,
|
|
39
|
+
onBlur,
|
|
40
|
+
children: choices?.map((choice, i) => /* @__PURE__ */ jsx("option", { value: choice.value, children: choice.label }, i))
|
|
41
|
+
}
|
|
42
|
+
);
|
|
43
|
+
case "radio":
|
|
44
|
+
return choices?.map((choice, i) => /* @__PURE__ */ jsxs("label", { children: [
|
|
45
|
+
/* @__PURE__ */ jsx(
|
|
46
|
+
"input",
|
|
47
|
+
{
|
|
48
|
+
type: "radio",
|
|
49
|
+
name,
|
|
50
|
+
ref,
|
|
51
|
+
value: choice.value,
|
|
52
|
+
checked: value === choice.value,
|
|
53
|
+
onChange: handleChange,
|
|
54
|
+
onBlur,
|
|
55
|
+
...validationRules
|
|
56
|
+
}
|
|
57
|
+
),
|
|
58
|
+
choice.label
|
|
59
|
+
] }, i));
|
|
60
|
+
case "checkbox":
|
|
61
|
+
return choices?.map((choice, i) => /* @__PURE__ */ jsxs("label", { children: [
|
|
62
|
+
/* @__PURE__ */ jsx(
|
|
63
|
+
"input",
|
|
64
|
+
{
|
|
65
|
+
type: "checkbox",
|
|
66
|
+
name,
|
|
67
|
+
ref,
|
|
68
|
+
value: choice.value,
|
|
69
|
+
checked: Array.isArray(value) ? value.includes(choice.value) : value === choice.value,
|
|
70
|
+
onChange: (e) => handleCheckboxChange(e, choice.value),
|
|
71
|
+
onBlur,
|
|
72
|
+
...validationRules
|
|
73
|
+
}
|
|
74
|
+
),
|
|
75
|
+
choice.label
|
|
76
|
+
] }, i));
|
|
77
|
+
default:
|
|
78
|
+
return /* @__PURE__ */ jsx(
|
|
79
|
+
"input",
|
|
80
|
+
{
|
|
81
|
+
type,
|
|
82
|
+
ref,
|
|
83
|
+
name,
|
|
84
|
+
value: value ?? options.defaultValue ?? "",
|
|
85
|
+
onChange: handleChange,
|
|
86
|
+
...validationRules,
|
|
87
|
+
onBlur,
|
|
88
|
+
placeholder: options.placeholder
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
};
|
|
93
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
94
|
+
label && !["hidden", "submit"].includes(type) && /* @__PURE__ */ jsx("label", { htmlFor: name, children: label }),
|
|
95
|
+
renderInput(),
|
|
96
|
+
error && /* @__PURE__ */ jsx("span", { className: "error", children: error })
|
|
97
|
+
] });
|
|
98
|
+
}, FormRenderer = (props) => {
|
|
99
|
+
const {
|
|
100
|
+
formData,
|
|
101
|
+
getFieldState = (name) => ({
|
|
102
|
+
value: void 0,
|
|
103
|
+
onChange: () => {
|
|
104
|
+
},
|
|
105
|
+
name
|
|
106
|
+
// Pass name to field for native form handling
|
|
107
|
+
}),
|
|
108
|
+
getFieldError,
|
|
109
|
+
fieldComponents = {},
|
|
110
|
+
children
|
|
111
|
+
} = props, renderField = (field) => {
|
|
112
|
+
const CustomComponent = fieldComponents[field.type], fieldState = getFieldState(field.name), error = getFieldError?.(field.name);
|
|
113
|
+
return CustomComponent ? /* @__PURE__ */ jsx(CustomComponent, { field, fieldState, error }) : /* @__PURE__ */ jsx(DefaultField, { field, fieldState, error });
|
|
114
|
+
}, elProps = Object.assign({}, props);
|
|
115
|
+
return delete elProps.formData, delete elProps.getFieldState, delete elProps.getFieldError, delete elProps.fieldComponents, /* @__PURE__ */ jsxs("form", { ...elProps, id: elProps.id ?? formData?.id?.current, children: [
|
|
116
|
+
formData?.fields?.map((field) => /* @__PURE__ */ jsx("div", { className: "form-field", children: renderField(field) }, field._key)),
|
|
117
|
+
children,
|
|
118
|
+
renderField({
|
|
119
|
+
type: "submit",
|
|
120
|
+
name: "submit",
|
|
121
|
+
label: formData?.submitButton?.text || "Submit"
|
|
122
|
+
})
|
|
123
|
+
] });
|
|
124
|
+
};
|
|
125
|
+
export {
|
|
126
|
+
FormRenderer
|
|
127
|
+
};
|
|
128
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","sources":["../../src/form-renderer/components/default-field.tsx","../../src/form-renderer/components/form-renderer.tsx"],"sourcesContent":["import type {ChangeEvent, FC, LegacyRef} from 'react'\n\nimport type {FieldComponentProps} from './types'\n\nexport const DefaultField: FC<FieldComponentProps> = ({field, fieldState, error}) => {\n const {type, label, name, options = {}, choices = [], validation = []} = field\n if (!type || !name) return null\n const validationRules = validation.reduce((acc: Record<string, string>, v) => {\n acc[v.type] = v.value\n return acc\n }, {})\n const {value, onChange, onBlur, ref} = fieldState\n\n const handleChange = (\n e: ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>,\n ) => {\n onChange(e.target.value)\n }\n\n const handleCheckboxChange = (e: ChangeEvent<HTMLInputElement>, choiceValue: string) => {\n if (Array.isArray(value)) {\n const newValue = e.target.checked\n ? [...value, choiceValue]\n : value.filter((v: string) => v !== choiceValue)\n onChange(newValue)\n } else {\n onChange(e.target.checked ? choiceValue : '')\n }\n }\n\n const renderInput = () => {\n switch (type) {\n case 'submit':\n return <button type=\"submit\">{label || 'Submit'}</button>\n case 'textarea':\n return (\n <textarea\n ref={ref as LegacyRef<HTMLTextAreaElement>}\n name={name}\n onChange={handleChange}\n onBlur={onBlur}\n placeholder={options.placeholder}\n {...validationRules}\n value={value ?? ''}\n />\n )\n\n case 'select':\n return (\n <select\n ref={ref as LegacyRef<HTMLSelectElement>}\n name={name}\n value={value ?? ''}\n onChange={handleChange}\n {...validationRules}\n onBlur={onBlur}\n >\n {choices?.map((choice, i) => (\n <option key={i} value={choice.value}>\n {choice.label}\n </option>\n ))}\n </select>\n )\n\n case 'radio':\n return choices?.map((choice, i) => (\n <label key={i}>\n <input\n type=\"radio\"\n name={name}\n ref={ref as LegacyRef<HTMLInputElement>}\n value={choice.value}\n checked={value === choice.value}\n onChange={handleChange}\n onBlur={onBlur}\n {...validationRules}\n />\n {choice.label}\n </label>\n ))\n\n case 'checkbox':\n return choices?.map((choice, i) => (\n <label key={i}>\n <input\n type=\"checkbox\"\n name={name}\n ref={ref as LegacyRef<HTMLInputElement>}\n value={choice.value}\n checked={Array.isArray(value) ? value.includes(choice.value) : value === choice.value}\n onChange={(e) => handleCheckboxChange(e, choice.value)}\n onBlur={onBlur}\n {...validationRules}\n />\n {choice.label}\n </label>\n ))\n\n default:\n return (\n <input\n type={type}\n ref={ref as LegacyRef<HTMLInputElement>}\n name={name}\n value={value ?? options.defaultValue ?? ''}\n onChange={handleChange}\n {...validationRules}\n onBlur={onBlur}\n placeholder={options.placeholder}\n />\n )\n }\n }\n\n return (\n <>\n {label && !['hidden', 'submit'].includes(type) && <label htmlFor={name}>{label}</label>}\n {renderInput()}\n {error && <span className=\"error\">{error}</span>}\n </>\n )\n}\n","import type {ComponentType, FC, HTMLProps} from 'react'\n\nimport {DefaultField} from './default-field'\nimport type {FieldComponentProps, FieldState, FormDataProps, FormField} from './types'\n\ninterface FormRendererProps extends HTMLProps<HTMLFormElement> {\n formData?: FormDataProps\n // Function to get field state for a given field name\n getFieldState?: (fieldName: string) => FieldState\n // Function to get field error for a given field name\n getFieldError?: (fieldName: string) => string | undefined\n // Override default field components\n fieldComponents?: Record<string, ComponentType<FieldComponentProps>>\n}\n\nexport const FormRenderer: FC<FormRendererProps> = (props) => {\n const {\n formData,\n getFieldState = (name) => ({\n value: undefined,\n onChange: () => {},\n name, // Pass name to field for native form handling\n }),\n getFieldError,\n fieldComponents = {},\n children,\n } = props\n const renderField = (field: FormField) => {\n const CustomComponent = fieldComponents[field.type]\n const fieldState = getFieldState(field.name)\n const error = getFieldError?.(field.name)\n\n if (CustomComponent) {\n return <CustomComponent field={field} fieldState={fieldState} error={error} />\n }\n\n return <DefaultField field={field} fieldState={fieldState} error={error} />\n }\n const elProps = Object.assign({}, props)\n delete elProps.formData\n delete elProps.getFieldState\n delete elProps.getFieldError\n delete elProps.fieldComponents\n\n return (\n <form {...elProps} id={elProps.id ?? formData?.id?.current}>\n {formData?.fields?.map((field) => (\n <div key={field._key} className=\"form-field\">\n {renderField(field)}\n </div>\n ))}\n\n {children}\n\n {renderField({\n type: 'submit',\n name: 'submit',\n label: formData?.submitButton?.text || 'Submit',\n })}\n </form>\n )\n}\n"],"names":[],"mappings":"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"}
|
|
@@ -1,69 +1,28 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {FC} from 'react'
|
|
3
|
-
import type {HTMLProps} from 'react'
|
|
1
|
+
import {FieldDefinition} from 'sanity'
|
|
4
2
|
import {Plugin as Plugin_2} from 'sanity'
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
export declare type FormDataProps = {
|
|
30
|
-
title: string
|
|
31
|
-
id: {
|
|
32
|
-
current: string
|
|
33
|
-
}
|
|
34
|
-
fields?: FormField[]
|
|
35
|
-
submitButton?: {
|
|
36
|
-
text: string
|
|
37
|
-
position: 'left' | 'center' | 'right'
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
declare type FormField = {
|
|
42
|
-
type: string
|
|
43
|
-
label?: string
|
|
44
|
-
name: string
|
|
45
|
-
required?: boolean
|
|
46
|
-
validation?: ValidationRule[]
|
|
47
|
-
options?: FieldOptions
|
|
48
|
-
choices?: FieldChoice[]
|
|
49
|
-
_key?: string
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export declare const FormRenderer: FC<FormRendererProps>
|
|
53
|
-
|
|
54
|
-
declare interface FormRendererProps extends HTMLProps<HTMLFormElement> {
|
|
55
|
-
formData?: FormDataProps
|
|
56
|
-
getFieldState?: (fieldName: string) => FieldState
|
|
57
|
-
getFieldError?: (fieldName: string) => string | undefined
|
|
58
|
-
fieldComponents?: Record<string, ComponentType<FieldComponentProps>>
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export declare const formSchema: Plugin_2<void>
|
|
62
|
-
|
|
63
|
-
declare type ValidationRule = {
|
|
64
|
-
type: string
|
|
65
|
-
value: string
|
|
66
|
-
message: string
|
|
4
|
+
/**
|
|
5
|
+
* Usage in `sanity.config.ts` (or .js)
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import {defineConfig} from 'sanity'
|
|
9
|
+
* import {formSchema} from '@sanity/form-toolkit'
|
|
10
|
+
*
|
|
11
|
+
* export default defineConfig({
|
|
12
|
+
* // ...
|
|
13
|
+
* plugins: [formSchema()],
|
|
14
|
+
* })
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare type FieldsOption = Array<FieldDefinition>
|
|
18
|
+
|
|
19
|
+
export declare const formSchema: Plugin_2<FormSchemaPluginOptions | undefined>
|
|
20
|
+
|
|
21
|
+
declare interface FormSchemaPluginOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Array of field definitions to be used in the form schema.
|
|
24
|
+
*/
|
|
25
|
+
fields?: FieldsOption
|
|
67
26
|
}
|
|
68
27
|
|
|
69
28
|
export {}
|
|
@@ -1,69 +1,28 @@
|
|
|
1
|
-
import
|
|
2
|
-
import type {FC} from 'react'
|
|
3
|
-
import type {HTMLProps} from 'react'
|
|
1
|
+
import {FieldDefinition} from 'sanity'
|
|
4
2
|
import {Plugin as Plugin_2} from 'sanity'
|
|
5
3
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
export declare type FormDataProps = {
|
|
30
|
-
title: string
|
|
31
|
-
id: {
|
|
32
|
-
current: string
|
|
33
|
-
}
|
|
34
|
-
fields?: FormField[]
|
|
35
|
-
submitButton?: {
|
|
36
|
-
text: string
|
|
37
|
-
position: 'left' | 'center' | 'right'
|
|
38
|
-
}
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
declare type FormField = {
|
|
42
|
-
type: string
|
|
43
|
-
label?: string
|
|
44
|
-
name: string
|
|
45
|
-
required?: boolean
|
|
46
|
-
validation?: ValidationRule[]
|
|
47
|
-
options?: FieldOptions
|
|
48
|
-
choices?: FieldChoice[]
|
|
49
|
-
_key?: string
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
export declare const FormRenderer: FC<FormRendererProps>
|
|
53
|
-
|
|
54
|
-
declare interface FormRendererProps extends HTMLProps<HTMLFormElement> {
|
|
55
|
-
formData?: FormDataProps
|
|
56
|
-
getFieldState?: (fieldName: string) => FieldState
|
|
57
|
-
getFieldError?: (fieldName: string) => string | undefined
|
|
58
|
-
fieldComponents?: Record<string, ComponentType<FieldComponentProps>>
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
export declare const formSchema: Plugin_2<void>
|
|
62
|
-
|
|
63
|
-
declare type ValidationRule = {
|
|
64
|
-
type: string
|
|
65
|
-
value: string
|
|
66
|
-
message: string
|
|
4
|
+
/**
|
|
5
|
+
* Usage in `sanity.config.ts` (or .js)
|
|
6
|
+
*
|
|
7
|
+
* ```ts
|
|
8
|
+
* import {defineConfig} from 'sanity'
|
|
9
|
+
* import {formSchema} from '@sanity/form-toolkit'
|
|
10
|
+
*
|
|
11
|
+
* export default defineConfig({
|
|
12
|
+
* // ...
|
|
13
|
+
* plugins: [formSchema()],
|
|
14
|
+
* })
|
|
15
|
+
* ```
|
|
16
|
+
*/
|
|
17
|
+
export declare type FieldsOption = Array<FieldDefinition>
|
|
18
|
+
|
|
19
|
+
export declare const formSchema: Plugin_2<FormSchemaPluginOptions | undefined>
|
|
20
|
+
|
|
21
|
+
declare interface FormSchemaPluginOptions {
|
|
22
|
+
/**
|
|
23
|
+
* Array of field definitions to be used in the form schema.
|
|
24
|
+
*/
|
|
25
|
+
fields?: FieldsOption
|
|
67
26
|
}
|
|
68
27
|
|
|
69
28
|
export {}
|