or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

field-components.mdform-component.mdindex.mdregistry-system.mdtemplate-components.mdtheme-system.mdwidget-components.md

form-component.mddocs/

0

# Form Component

1

2

The Form component is the main React component that renders JSON schemas as interactive forms with validation, customization, and event handling capabilities.

3

4

## Capabilities

5

6

### Form Class

7

8

Main form component that converts JSON Schema definitions into interactive React forms.

9

10

```typescript { .api }

11

/**

12

* Main form component that renders JSON schemas as interactive forms

13

* @template T - Type of form data

14

* @template S - Type of JSON schema (extends StrictRJSFSchema)

15

* @template F - Type of form context (extends FormContextType)

16

*/

17

export default class Form<

18

T = any,

19

S extends StrictRJSFSchema = RJSFSchema,

20

F extends FormContextType = any

21

> extends Component<FormProps<T, S, F>, FormState<T, S, F>> {

22

/** Programmatically submit the form */

23

submit(): void;

24

/** Validate current form data and return whether it's valid */

25

validateForm(): boolean;

26

/** Reset form to initial state */

27

reset(): void;

28

/** Focus on the field that has the given error */

29

focusOnError(error: RJSFValidationError): void;

30

}

31

```

32

33

**Usage Examples:**

34

35

```typescript

36

import Form from "@rjsf/core";

37

import validator from "@rjsf/validator-ajv8";

38

39

// Basic form with validation

40

const MyForm = () => {

41

const schema = {

42

type: "object",

43

properties: {

44

name: { type: "string", title: "Full Name" },

45

age: { type: "number", title: "Age", minimum: 0 }

46

},

47

required: ["name"]

48

};

49

50

return (

51

<Form

52

schema={schema}

53

validator={validator}

54

onSubmit={({ formData }) => console.log(formData)}

55

/>

56

);

57

};

58

59

// Form with custom validation and error handling

60

const AdvancedForm = () => {

61

const [errors, setErrors] = useState([]);

62

const formRef = useRef<Form>(null);

63

64

const customValidate = (formData, errors) => {

65

if (formData.age < 18) {

66

errors.age.addError("Must be 18 or older");

67

}

68

return errors;

69

};

70

71

const handleSubmit = ({ formData }) => {

72

if (formRef.current?.validateForm()) {

73

console.log("Valid form data:", formData);

74

}

75

};

76

77

return (

78

<Form

79

ref={formRef}

80

schema={schema}

81

validator={validator}

82

customValidate={customValidate}

83

onSubmit={handleSubmit}

84

onError={setErrors}

85

showErrorList="top"

86

/>

87

);

88

};

89

```

90

91

### Form Props Interface

92

93

Complete configuration interface for the Form component with all available options.

94

95

```typescript { .api }

96

interface FormProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {

97

// Core required props

98

/** JSON schema object defining the form structure */

99

schema: S;

100

/** Validator implementation for form validation */

101

validator: ValidatorType<T, S, F>;

102

103

// Data management

104

/** UI schema for customizing form appearance and behavior */

105

uiSchema?: UiSchema<T, S, F>;

106

/** Initial or current form data */

107

formData?: T;

108

/** Context object passed to all fields and widgets */

109

formContext?: F;

110

111

// Form configuration

112

/** Prefix for form field IDs (default: "root") */

113

idPrefix?: string;

114

/** Separator for nested field IDs (default: "_") */

115

idSeparator?: string;

116

/** Disable the entire form */

117

disabled?: boolean;

118

/** Make the entire form read-only */

119

readonly?: boolean;

120

121

// Registry overrides

122

/** Custom field components */

123

fields?: RegistryFieldsType<T, S, F>;

124

/** Custom widget components */

125

widgets?: RegistryWidgetsType<T, S, F>;

126

/** Custom template components */

127

templates?: Partial<TemplatesType<T, S, F>>;

128

129

// Event handlers

130

/** Called when form data changes */

131

onChange?: (data: IChangeEvent<T, S, F>, id?: string) => void;

132

/** Called when validation errors occur */

133

onError?: (errors: RJSFValidationError[]) => void;

134

/** Called when form is submitted */

135

onSubmit?: (data: IChangeEvent<T, S, F>, event: FormEvent<any>) => void;

136

/** Called when a field loses focus */

137

onBlur?: (id: string, data: any) => void;

138

/** Called when a field gains focus */

139

onFocus?: (id: string, data: any) => void;

140

141

// Validation configuration

142

/** Custom validation function */

143

customValidate?: CustomValidator<T, S, F>;

144

/** Additional errors to display */

145

extraErrors?: ErrorSchema<T>;

146

/** Whether extra errors should block form submission */

147

extraErrorsBlockSubmit?: boolean;

148

/** Disable HTML5 validation */

149

noHtml5Validate?: boolean;

150

/** Validate on every change (default: false) */

151

liveValidate?: boolean;

152

/** Omit extra data on change events */

153

liveOmit?: boolean;

154

/** Omit extra data on form submission */

155

omitExtraData?: boolean;

156

/** Where to show error list: false, 'top', or 'bottom' */

157

showErrorList?: false | 'top' | 'bottom';

158

/** Transform validation errors before display */

159

transformErrors?: ErrorTransformer<T, S, F>;

160

/** Auto-focus first field with error */

161

focusOnFirstError?: boolean | ((error: RJSFValidationError) => void);

162

163

// HTML form attributes

164

/** Accept-charset HTML attribute */

165

acceptCharset?: string;

166

/** Action HTML attribute */

167

action?: string;

168

/** Autocomplete HTML attribute */

169

autoComplete?: string;

170

/** CSS class name */

171

className?: string;

172

/** Enctype HTML attribute */

173

enctype?: string;

174

/** HTML id attribute */

175

id?: string;

176

/** HTML name attribute */

177

name?: string;

178

/** HTTP method */

179

method?: string;

180

/** Custom HTML tag (default: 'form') */

181

tagName?: ElementType;

182

/** Target HTML attribute */

183

target?: string;

184

185

// Advanced configuration

186

/** Translation function for internationalization */

187

translateString?: (str: TranslatableString, params?: string[]) => string;

188

/** Experimental default form state behavior */

189

experimental_defaultFormStateBehavior?: Experimental_DefaultFormStateBehavior;

190

/** Experimental custom allOf merger */

191

experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>;

192

193

// Other

194

/** Custom submit button or form content */

195

children?: ReactNode;

196

/** Internal form wrapper component */

197

_internalFormWrapper?: ElementType;

198

}

199

```

200

201

### Form State Interface

202

203

Interface representing the internal state of the Form component.

204

205

```typescript { .api }

206

interface FormState<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {

207

/** Current form data */

208

formData: T;

209

/** Current validation errors */

210

errors: RJSFValidationError[];

211

/** Current error schema structure */

212

errorSchema: ErrorSchema<T>;

213

/** Schema-level validation errors */

214

schemaValidationErrors: RJSFValidationError[];

215

/** Schema-level error schema */

216

schemaValidationErrorSchema: ErrorSchema<T>;

217

}

218

```

219

220

### Change Event Interface

221

222

Interface for form change and submit events.

223

224

```typescript { .api }

225

interface IChangeEvent<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {

226

/** Current schema */

227

schema: S;

228

/** Current UI schema */

229

uiSchema: UiSchema<T, S, F>;

230

/** Current ID schema */

231

idSchema: IdSchema<T>;

232

/** Schema utilities instance */

233

schemaUtils: SchemaUtilsType<T, S, F>;

234

/** Current form data */

235

formData?: T;

236

/** Whether form is in edit mode */

237

edit: boolean;

238

/** Current validation errors */

239

errors: RJSFValidationError[];

240

/** Current error schema */

241

errorSchema: ErrorSchema<T>;

242

/** Status when submitted (only present on submit) */

243

status?: 'submitted';

244

}

245

```

246

247

## Advanced Usage Patterns

248

249

### Form Refs and Imperative API

250

251

```typescript

252

import { useRef } from 'react';

253

import Form from '@rjsf/core';

254

255

const FormWithRef = () => {

256

const formRef = useRef<Form>(null);

257

258

const handleCustomSubmit = () => {

259

// Validate programmatically

260

if (formRef.current?.validateForm()) {

261

// Submit programmatically

262

formRef.current.submit();

263

}

264

};

265

266

const handleReset = () => {

267

formRef.current?.reset();

268

};

269

270

return (

271

<div>

272

<Form

273

ref={formRef}

274

schema={schema}

275

validator={validator}

276

onSubmit={handleSubmit}

277

/>

278

<button onClick={handleCustomSubmit}>Custom Submit</button>

279

<button onClick={handleReset}>Reset Form</button>

280

</div>

281

);

282

};

283

```

284

285

### Custom Validation

286

287

```typescript

288

const customValidate = (formData, errors, uiSchema) => {

289

// Cross-field validation

290

if (formData.password !== formData.confirmPassword) {

291

errors.confirmPassword.addError("Passwords don't match");

292

}

293

294

// Async validation

295

if (formData.email) {

296

validateEmailAsync(formData.email).then(isValid => {

297

if (!isValid) {

298

errors.email.addError("Email already exists");

299

}

300

});

301

}

302

303

return errors;

304

};

305

306

<Form

307

schema={schema}

308

validator={validator}

309

customValidate={customValidate}

310

liveValidate={true}

311

/>

312

```

313

314

### Form Context Usage

315

316

```typescript

317

const formContext = {

318

currentUser: user,

319

theme: 'dark',

320

readonlyMode: false

321

};

322

323

<Form

324

schema={schema}

325

validator={validator}

326

formContext={formContext}

327

// Form context is available in all custom fields/widgets

328

/>

329

```

330

331

### Error Handling and Transformation

332

333

```typescript

334

const transformErrors = (errors) => {

335

return errors.map(error => ({

336

...error,

337

message: translateError(error.message, currentLocale)

338

}));

339

};

340

341

<Form

342

schema={schema}

343

validator={validator}

344

transformErrors={transformErrors}

345

showErrorList="top"

346

focusOnFirstError={true}

347

/>

348

```