# Technical Documentation: rjsf-team/react-jsonschema-form

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/rjsf-team/react-jsonschema-form)

### Overview (`README.md`)

[![Build Status][build-shield]][build-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]

<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/core/logo.png" alt="Logo" width="180" height="120">
  </a>

  <h3 align="center">react-jsonschema-form</h3>

  <p align="center">
    A simple <a href="http://facebook.github.io/react/">React</a> component capable of using <a href="http://json-schema.org/">JSON Schema</a> to declaratively build and customize web forms.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>

[](https://rjsf-team.github.io/react-jsonschema-form/)

## Supported Themes

- [Ant Design v5](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/antd)
- [Bootstrap v3](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/core)
- [Chakra UI v3](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/chakra-ui)
- [Daisy UI v5](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/daisyui)
- [Fluent UI v9](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/fluentui-rc)
- [Mantine](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/mantine)
- [Material UI v7](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/mui)
- [React-Bootstrap (Bootstrap v5)](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/react-bootstrap)
- [Semantic UI v2](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/semantic-ui)
- [Shad CN](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/shadcn)

## API Libraries

- [@rjsf/utils](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/utils)
- [@rjsf/validator-ajv8](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/validator-ajv8)
- [@rjsf/validator-ata](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/validator-ata)
- [@rjsf/validator-cfworker](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/validator-cfworker)

## Documentation

Read our [documentation](https://rjsf-team.github.io/react-jsonschema-form/docs), powered by [Docusaurus](https://docusaurus.io/).

## Live Playground

A [live playground](https://rjsf-team.github.io/react-jsonschema-form/) is hosted on GitHub Pages.

## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing) to get started.

## Credits

Testing powered by BrowserStack<br>
<a target="_blank" href="https://www.browserstack.com/"><img width="200" src="https://user-images.githubusercontent.com/1689183/51487090-4ea04f80-1d57-11e9-9a91-79b7ef8d2013.png"></a>

[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/

---

### Overview (`docs/README.md`)

# docs (DEPRECATED)

[The react-jsonschema-form documentation has been moved here](../packages/docs)

---

### Overview (`packages/antd/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]

<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/antd/logo.png" alt="Logo" width="120" height="120">
  </a>

  <h3 align="center">@rjsf/antd</h3>

  <p align="center">
  Ant Design theme, fields and widgets for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Ant Design theme, fields and widgets for `react-jsonschema-form`.

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/antd)

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [Ant Design](https://github.com/ant-design/ant-design)



## Getting Started

### Prerequisites

- `antd >= 5`
- `@ant-design/icons >= 5`
- `dayjs >= 1.8.0`
- `@rjsf/core >= 6`
- `@rjsf/utils >= 6`
- `@rjsf/validator-ajv8 >= 6`

```sh
npm install antd @ant-design/icons dayjs @rjsf/core @rjsf/utils @rjsf/validator-ajv8
```

### Installation

```sh
npm install @rjsf/antd
```

## Usage

```javascript
import Form from '@rjsf/antd';
```

or

```javascript
import { withTheme } from '@rjsf/core';
import { Theme as AntDTheme } from '@rjsf/antd';

// Make modifications to the theme with your own fields and widgets

const Form = withTheme(AntDTheme);
```



## Roadmap

See the general [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/antd/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/antd
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/antd.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/antd
[product-screenshot]: https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/antd/screenshot.png

---

### Overview (`packages/chakra-ui/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]


<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="./logo.png" alt="Logo" width="340">
  </a>

  <h3 align="center">@rjsf/chakra-ui</h3>

  <p align="center">
  Chakra UI theme, fields and widgets for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Optional Chakra UI Theme properties](#optional-chakra-ui-theme-properties)
  - [Custom Chakra uiSchema Chakra Property](#custom-chakra-uischema-chakra-property)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/chakra-ui)

Exports `chakra-ui` theme, fields and widgets for `react-jsonschema-form`.

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [Chakra UI](https://chakra-ui.com/)
- [TypeScript](https://www.typescriptlang.org/)



## Getting Started

### Prerequisites

- `@chakra-ui/react >= 3`
- `chakra-react-select >= 6`
- `@rjsf/core >= 6`
- `@rjsf/utils >= 6`
- `@rjsf/validator-ajv8 >= 6`

Refer to the [rjsf installation guide](https://rjsf-team.github.io/react-jsonschema-form/docs/#installation) and [chakra-ui installation guide](https://chakra-ui.com/docs/getting-started#installation) and for more details.

---

### Installation

```bash
yarn add @chakra-ui/react chakra-react-select @rjsf/core @rjsf/utils @rjsf/validator-ajv8
```

## Usage

```bash
yarn add @rjsf/chakra-ui
```



```js
import Form from '@rjsf/chakra-ui';
```

or

```js
import { withTheme } from '@rjsf/core';
import { Theme as ChakraUITheme } from '@rjsf/chakra-ui';

// Make modifications to the theme with your own fields and widgets

const Form = withTheme(ChakraUITheme);
```

## Optional Chakra UI Theme properties

- To pass additional properties to widgets, see this [guide](https://rjsf-team.github.io/react-jsonschema-form/docs/usage/objects#additional-properties).

You can use `ChakraProvider`, to customize the components at a theme level.\
And, `uiSchema` allows for the use of a `"chakra"` `"ui:option"` to customize the styling of the form widgets.

#### Custom Chakra uiSchema Chakra Property

```json
{
  "ui:options": {
    "chakra": {
      "p": "1rem",
      "color": "blue.200",
      "sx": {
        "margin": "0 auto"
      }
    }
  }
}
```

It accepts the theme accessible [style props](https://chakra-ui.com/docs/features/style-props) provided by [Chakra](https://chakra-ui.com/docs/getting-started) and [Emotion](https://emotion.sh/docs/introduction).



## Roadmap

See the [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues) for a list of proposed features (and known issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/chakra-ui/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/chakra-ui
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/chakra-ui.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/chakra-ui
[product-screenshot]: ./screenshot.png

---

### Overview (`packages/core/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]

<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/core/logo.png" alt="Logo" width="180" height="120">
  </a>

  <h3 align="center">@rjsf/core</h3>

  <p align="center">
  Core logic and classic Bootstrap 3 theme for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Core logic and classic Bootstrap 3 theme for `react-jsonschema-form`.

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/core)

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [Bootstrap 3](https://getbootstrap.com/docs/3.3/)



## Getting Started

### Prerequisites

- `Bootstrap 3`

To use the default Bootstrap 3 theme, add a Bootstrap 3 CSS tag to your HTML page:

```html
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" />
```

### Installation

```sh
npm install @rjsf/core
```

## Usage

```javascript
import Form from '@rjsf/core';
```



## Roadmap

See the general [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/core/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/core
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/core.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/core
[product-screenshot]: https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/core/screenshot.png

---

### Overview (`packages/daisyui/README.md`)

# @rjsf/daisyui

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![License][license-shield]][license-url]

A [DaisyUI](https://daisyui.com/) theme for [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/).

This package integrates [DaisyUI](https://daisyui.com/), [Tailwind CSS](https://tailwindcss.com/), and [RJSF](https://github.com/rjsf-team/react-jsonschema-form/) to provide a modern, customizable form experience.

## Screenshots

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/daisyui)

## Features

- Complete DaisyUI styling for all RJSF form elements
- Responsive design with mobile-friendly layouts
- Connected card styling for nested elements and arrays
- Consistent visual hierarchy for complex forms
- Support for all RJSF field types including:
  - Text inputs with proper styling and validation states
  - Select dropdowns with customizable option rendering
  - Checkboxes and radio buttons with optimized layouts
  - Arrays with add/remove/reorder functionality
  - Objects with proper nesting and visual hierarchy
  - Date/time inputs with cross-browser compatibility
- Support for custom themes via DaisyUI's theme system
- Accessible form components following WAI-ARIA practices

## Getting Started

### Prerequisites

- `daisyui >= 5`
- `@fluentui/react-icons >= 2`
- `@fluentui/react-migration-v0-v9 >= 9`
- `@rjsf/core >= 6`
- `@rjsf/utils >= 6`
- `@rjsf/validator-ajv8 >= 6`

### Installation

```bash
npm install @rjsf/daisyui @rjsf/core @rjsf/utils @rjsf/validator-ajv8 tailwindcss daisyui
```

## Usage

```jsx
import { Form } from '@rjsf/daisyui';
import validator from '@rjsf/validator-ajv8';

function App() {
  return (
    <Form schema={schema} uiSchema={uiSchema} validator={validator} onChange={console.log} onSubmit={console.log} />
  );
}
```

## Theme Customization

The form components use DaisyUI's theme system. You can customize the theme by adding DaisyUI theme classes to your HTML:

```html
<html data-theme="light">
  
</html>
```

For dynamic theme switching, you can change the data-theme attribute in your application code.

## Tailwind Configuration

Make sure your `src/index.css` includes the DaisyUI plugin:

```css
@import 'tailwindcss';
@source "../node_modules/@rjsf/daisyui";
@plugin "daisyui" {
  themes: all;
}
```
It's necessary to explicitely include the library as a source, as tailwindcss by [default](https://tailwindcss.com/docs/detecting-classes-in-source-files#explicitly-registering-sources) ignores everything in `.gitignore` 
## Customization

### Grid Layout

The DaisyUI theme supports the standard RJSF layout grid system. You can use grid layouts by incorporating the `LayoutGridField` in your UI schema:

```
/* Detailed source-code truncated for AI context efficiency. */
```

The DaisyUI theme uses a flexible grid system based on Tailwind CSS's flex utilities. This grid layout integrates with the standard RJSF layout system, providing a consistent experience across all themes.

## Theme Configuration

DaisyUI itself provides a variety of themes. To use a specific theme, add the `data-theme` attribute to your root element:

```jsx
<div data-theme='dark'>
  <Form schema={schema} validator={validator} />
</div>
```

You can also dynamically change themes in your application:

```jsx
import { useState } from 'react';
import { Form } from '@rjsf/daisyui';
import validator from '@rjsf/validator-ajv8';

function App() {
  const [theme, setTheme] = useState('light');

  return (
    <div data-theme={theme}>
      <select value={theme} onChange={(e) => setTheme(e.target.value)}>
        <option value='light'>Light</option>
        <option value='dark'>Dark</option>
        <option value='cupcake'>Cupcake</option>
        <option value='cyberpunk'>Cyberpunk</option>
        <option value='synthwave'>Synthwave</option>
        {/* Add more themes as needed */}
      </select>

      <Form schema={schema} validator={validator} />
    </div>
  );
}
```

## Development

To develop locally:

```bash
# Clone the repository
git clone https://github.com/rjsf-team/react-jsonschema-form.git
cd react-jsonschema-form

# Install dependencies
npm install

# Build packages
npm run build

# Run playground
npm run start:playground
```

To test the DaisyUI theme specifically, select it from the themes dropdown in the playground.

## License

Apache-2.0

[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[npm-shield]: https://img.shields.io/npm/v/@rjsf/daisyui/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/daisyui
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/daisyui.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/daisyui
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg?style=flat-square
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://github.com/rjsf-team/react-jsonschema-form/blob/main/LICENSE

---

### Overview (`packages/docs/README.md`)

# react-jsonschema-form Documentation

This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.

### Installation

```
$ pnpm install
```

### Local Development

```
$ pnpm start
```

This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.

### Build

```
$ pnpm build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### Deployment

Deployment is handled automatically by GitHub pages.

---

### Overview (`packages/fluentui-rc/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]

<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/fluentui-rc/logo.png?raw=true" alt="Logo" width="120" height="120">
  </a>

  <h3 align="center">@rjsf/fluentui-rc</h3>

  <p align="center">
    Fluent UI React Components (v9) theme, fields and widgets for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Fluent UI React Components (v9) theme, fields and widgets for `react-jsonschema-form`.

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/fluentui-rc)

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [Fluent UI React Components (v9)](https://react.fluentui.dev/)
- [TypeScript](https://www.typescriptlang.org/)



## Getting Started

### Prerequisites

- `@fluentui/react-components >= 9`
- `@fluentui/react-icons >= 2`
- `@fluentui/react-migration-v0-v9 >= 9`
- `@rjsf/core >= 6`
- `@rjsf/utils >= 6`
- `@rjsf/validator-ajv8 >= 6`

```bash
yarn add @fluentui/react-components @fluentui/react-icons @fluentui/react-migration-v0-v9 @rjsf/core @rjsf/utils @rjsf/validator-ajv8
```

### Installation

```bash
yarn add @rjsf/fluentui-rc
```



## Usage

```js
import Form from '@rjsf/fluentui-rc';
```

or

```js
import { withTheme } from '@rjsf/core';
import { Theme as FluentUIRCTheme } from '@rjsf/fluentui-rc';

// Make modifications to the theme with your own fields and widgets

const Form = withTheme(FluentUIRCTheme);
```



## Roadmap

See the [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues) for a list of proposed features (and known issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/fluentui-rc/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/fluentui-rc
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/fluentui-rc.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/fluentui-rc
[product-screenshot]: https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/fluentui-rc/screenshot.png?raw=true

---

### Overview (`packages/mantine/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]


<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/mantine/logo.png" alt="Logo" width="120" height="120">
  </a>

  <h3 align="center">rjsf-mantine</h3>

  <p align="center">
  Mantine theme, fields and widgets for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Optional Mantine Theme properties](#optional-mantine-theme-properties)
    - [Mantine Widget Optional Properties](#mantine-widget-optional-properties)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

`Mantine` theme, fields and widgets for `react-jsonschema-form`.

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/mantine)

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [Mantine](https://mantine.dev/)



## Getting Started

- See the [getting started guide](https://mantine.dev/getting-started/) on Mantine documentation.

### Prerequisites

- `@mantine/core >= 8`
- `@mantine/hooks >= 8`
- `@mantine/dates >= 8`
- `dayjs >= 1.8.0`
- `@rjsf/core >= 6.0.0`

```sh
npm install @mantine/core @mantine/hooks @mantine/dates dayjs @rjsf/core
```

### Installation

```sh
npm install @rjsf/mantine
```



## Usage

```javascript
import Form from '@rjsf/mantine';
```

or

```javascript
import { withTheme } from '@rjsf/core';
import { Theme as MantineTheme } from '@rjsf/mantine';

// Make modifications to the theme with your own fields and widgets

const Form = withTheme(MantineTheme);
```

## Optional Mantine Theme properties

- To pass additional properties to widgets, see this [guide](https://rjsf-team.github.io/react-jsonschema-form/docs/usage/objects#additional-properties).

#### Mantine Widget Optional Properties

- [Mantine props for CheckboxWidget](https://mantine.dev/core/checkbox/?t=props)
- [Mantine props for ColorWidget](https://mantine.dev/core/color-input/?t=props)
- [Mantine props for DateWidget](https://mantine.dev/dates/date-input/?t=props)
- [Mantine props for DateTimeWidget](https://mantine.dev/dates/date-input/?t=props)
- [Mantine props for PasswordWidget](https://mantine.dev/core/password-input/?t=props)
- [Mantine props for RadioWidget](https://mantine.dev/core/radio/?t=props)
- [Mantine props for RangeWidget](https://mantine.dev/core/slider/?t=props)
- [Mantine props for SelectWidget](https://mantine.dev/core/select/?t=props)
- [Mantine props for UpDownWidget](https://mantine.dev/core/number-input/?t=props)
- [Mantine props for TextWidget](https://mantine.dev/core/text-input/?t=props)
- [Mantine props for TextAreaWidget](https://mantine.dev/core/textarea/?t=props)
- [Mantine props for TimeWidget](https://mantine.dev/dates/time-input/?t=props)



## Roadmap

See the [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues) for a list of proposed features (and known issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/mantine/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/mantine
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/mantine.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/mantine
[product-screenshot]: https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/mantine/screenshot.png

---

### Overview (`packages/mui/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]


<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/7ebc86621d8df8c21f0c39bcca6d476f6f7a2051/packages/mui/logo.png" alt="Logo" width="120" height="120">
  </a>

  <h3 align="center">@rjsf/mui</h3>

  <p align="center">
  Material UI theme, fields and widgets for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
  - [Material UI version 7](#material-ui-version-7)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Exports `MUI` version 5 theme, fields, and widgets for `react-jsonschema-form`.

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/mui)

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [Material UI 7](https://mui.com/)
- [TypeScript](https://www.typescriptlang.org/)



## Getting Started

### Prerequisites

NOTE: Material UI 7 requires React 18, so you will need to upgrade

- `@mui/material >= 7`
- `@mui/icons-material >= 7`
- `@emotion/react >= 11`
- `@emotion/styled >= 11`
- `@rjsf/core >= 6`
- `@rjsf/utils >= 6`
- `@rjsf/validator-ajv8 >= 6`

```bash
yarn add @mui/material @mui/icons-material @emotion/react @emotion/styled @rjsf/core @rjsf/utils @rjsf/validator-ajv8
```

### Installation

```bash
yarn add @rjsf/mui
```



## Usage

### Material UI version 7

```js
import Form from '@rjsf/mui';
```

or

```js
import { withTheme } from '@rjsf/core';
import { Theme } from '@rjsf/mui';

// Make modifications to the theme with your own fields and widgets

const Form = withTheme(Theme);
```

### Customizing MUI-specific props

You can pass MUI-specific props (like `sx`, `rjsfSlotProps`, `variant`, etc.) directly to any MUI component rendered by a Template or Widget via `ui:options` in the `uiSchema`.

```json
"myField": {
  "ui:options": {
    "mui": {
      "variant": "filled",
      "sx": {
        "backgroundColor": "background.paper"
      },
      "rjsfSlotProps": {
        "input": {
          "endAdornment": "kg"
        }
      }
    }
  }
}
```

For more details on available properties and `rjsfSlotProps` targets, see the [Material UI Customization Documentation](https://rjsf-team.github.io/react-jsonschema-form/docs/api-reference/themes/mui/uiSchema/).




## Roadmap

See the [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues) for a list of proposed features (and known issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/mui/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/mui
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/mui.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/mui
[product-screenshot]: https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/e2e1181d1020f18cad0c80c661ddae28edb9794e/packages/mui/screenshot.png

---

### Overview (`packages/primereact/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]

<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/main/packages/primereact/logo.png" alt="Logo" width="120" height="120">
  </a>

<h3 align="center">@rjsf/primereact</h3>

  <p align="center">
  PrimeReact theme, fields, and widgets for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>

## Table of Contents

- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)

## About The Project

PrimeReact theme, fields, and widgets for `react-jsonschema-form`.

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/primereact)

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [PrimeReact](https://github.com/primefaces/primereact)

## Getting Started

### Prerequisites

- `primereact >= 8.0.0`
- `primeicons >= 6.0.0`
- `@rjsf/core >= 6`
- `@rjsf/utils >= 6`
- `@rjsf/validator-ajv8 >= 6`

```sh
npm install primereact primeicons @rjsf/core
```

### Installation

```sh
npm install @rjsf/primereact
```

## Usage

```javascript
import Form from '@rjsf/primereact';
```

or

```javascript
import { withTheme } from '@rjsf/core';
import { Theme as PrimeReactTheme } from '@rjsf/primereact';

// Customize the theme with your own fields and widgets

const Form = withTheme(PrimeReactTheme);
```

## Roadmap

See the general [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues).

## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.

## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub
repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)

[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg

[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions

[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg

[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors

[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square

[license-url]: https://choosealicense.com/licenses/apache-2.0/

[npm-shield]: https://img.shields.io/npm/v/@rjsf/primereact/latest.svg?style=flat-square

[npm-url]: https://www.npmjs.com/package/@rjsf/primereact

[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/primereact.svg?style=flat-square

[npm-dl-url]: https://www.npmjs.com/package/@rjsf/primereact

---

### Overview (`packages/react-bootstrap/README.md`)

<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="bootstrap-logo.png" alt="Logo" width="140" height="120">
  </a>

  <h3 align="center">@rjsf/react-bootstrap</h3>

  <p align="center">
  Bootstrap 5 theme, fields and widgets for <a href="https://github.com/mozilla-services/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
   <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Exports `react-bootstrap` theme, fields and widgets for `react-jsonschema-form`.

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/react-bootstrap)

### Built With

- [react-jsonschema-form](https://github.com/mozilla-services/react-jsonschema-form/)
- [Bootstrap-5](https://getbootstrap.com/docs/5.3/)
- [TypeScript](https://www.typescriptlang.org/)



## Getting Started

### Prerequisites

- `react-bootstrap >= 2.0.0`
- `@rjsf/core >= 6`
- `@rjsf/utils >= 6`
- `@rjsf/validator-ajv8 >= 6`

```bash
yarn add react-bootstrap @rjsf/core @rjsf/utils @rjsf/validator-ajv8
```

### Installation

```bash
yarn add @rjsf/react-bootstrap
```

## Usage

```js
import Form from 'packages/react-bootstrap';
```

or

```js
import { withTheme } from '@rjsf/core';
import { Theme as BootstrapTheme } from 'packages/react-bootstrap';

const Form = withTheme(BootstrapTheme);
```



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/react-bootstrap/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/react-bootstrap
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/react-bootstrap.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/react-bootstrap
[product-screenshot]: https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/react-bootstrap/screenshot.png

---

### Overview (`packages/semantic-ui/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]


<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/semantic-ui/logo.png" alt="Logo" width="120" height="120">
  </a>

  <h3 align="center">rjsf-semantic-ui</h3>

  <p align="center">
  Semantic UI theme, fields and widgets for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Optional Semantic UI Theme properties](#optional-semantic-ui-theme-properties)
  - [Semantic Widget Optional Properties](#semantic-widget-optional-properties)
  - [Custom Semantic Widget Properties](#custom-semantic-widget-properties)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Exports `semantic-ui` theme, fields and widgets for `react-jsonschema-form`.

[<img src="./screenshot.png" alt="product-screenshot" width="800" />](https://rjsf-team.github.io/@rjsf/semantic-ui)

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [Semantic UI](https://react.semantic-ui.com/)



## Getting Started

- See the [getting started guide](https://react.semantic-ui.com/usage) on react-semantic-ui.

### Prerequisites

- `@semantic-ui-react >= 2`
- `@semantic-ui-css >= 2` ([default theme for semantic-ui](https://github.com/Semantic-Org/Semantic-UI-CSS)); see [theming guide](https://react.semantic-ui.com/theming) if you wish to customize
- `@rjsf/core >= 6`
- `@rjsf/utils >= 6`
- `@rjsf/validator-ajv8 >= 6`

```sh
yarn add semantic-ui-css semantic-ui-react @rjsf/core
```

### Installation

```sh
yarn add @rjsf/semantic-ui
```



## Usage

```javascript
import Form from '@rjsf/semantic-ui';
```

or

```javascript
import { withTheme } from '@rjsf/core';
import { Theme as SemanticUITheme } from '@rjsf/semantic-ui';

// Make modifications to the theme with your own fields and widgets

const Form = withTheme(SemanticUITheme);
```

## Optional Semantic UI Theme properties

- To pass additional properties to widgets, see this [guide](https://rjsf-team.github.io/react-jsonschema-form/docs/usage/objects#additional-properties).

#### Semantic Widget Optional Properties

- [Semantic props for TextWidget](https://react.semantic-ui.com/elements/input/)
- [Semantic props for CheckboxWidget](https://react.semantic-ui.com/modules/checkbox/)
- [Semantic props for SelectWidget](https://react.semantic-ui.com/modules/dropdown/)
- [Semantic props for RangeWidget](https://react.semantic-ui.com/elements/input/)
- [Semantic props for RadioWidget](https://react.semantic-ui.com/addons/radio/)
- [Semantic props for PasswordWidget](https://react.semantic-ui.com/elements/input/)
- [Semantic props for UpDownWidget](https://react.semantic-ui.com/elements/input/)
- [Semantic props for TextAreaWidget](https://react.semantic-ui.com/addons/text-area/)

#### Custom Semantic Widget Properties

Below are the current default options for all widgets:

```json
{
  "ui:options": {
    "semantic": {
      "fluid": true,
      "inverted": false,
      "errorOptions": {
        "size": "small",
        "pointing": "above"
      }
    }
  }
}
```



## Roadmap

See the [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues) for a list of proposed features (and known issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/semantic-ui/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/semantic-ui
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/semantic-ui.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/semantic-ui
[product-screenshot]: https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/semantic-ui/screenshot.png

---

### Overview (`packages/shadcn/README.md`)

<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="./shadcn.png" alt="Logo" width="180" height="180">
  </a>

<h3 align="center">@rjsf/shadcn</h3>

  <p align="center">
  Shadcn theme, fields and widgets for <a href="https://github.com/mozilla-services/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
   <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
    - [Built With](#built-with)
- [Getting Started](#getting-started)
    - [Prerequisites](#prerequisites)
    - [Installation](#installation)
- [Usage](#usage)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Exports `shadcn` theme, fields and widgets for `react-jsonschema-form`.

[](https://rjsf-team.github.io/@rjsf/shadcn)

[Live demo](https://react-jsonschema-form-shadcn-boilerplate.vercel.app/)

### Built With

- [react-jsonschema-form](https://github.com/mozilla-services/react-jsonschema-form/)
- [shadcn](https://ui.shadcn.com/)
- [Typescript](https://www.typescriptlang.org/)



## Getting Started

### Prerequisites

- `@rjsf/core >= 6`
- `@rjsf/utils >= 6`
- `@rjsf/validator-ajv8 >= 6`

```bash
yarn add @rjsf/core @rjsf/utils @rjsf/validator-ajv8
```

### Installation

```bash
yarn add @rjsf/shadcn
```

## Usage

```js
import Form from '@rjsf/shadcn';
```

or

```js
import {withTheme} from '@rjsf/core';
import {Theme as shadcnTheme} from '@rjsf/shadcn';

const Form = withTheme(shadcnTheme);
```



## Theming

### Using Tailwind

Follow shadCN installation guide [here](https://ui.shadcn.com/docs/installation) for your application

The color of the RJSF will automatically apply with your shadCN config.

#### Tailwind v3
Add the following line to your tailwind.config.ts
```typescript
  content: [
    "./src/**/*.{html,js}",
    "node_modules/@rjsf/shadcn/src/**/*.{js,ts,jsx,tsx,mdx}" // Add this line
  ],
```
#### Tailwind v4
Add the following line to your equivalent global.css
```css
@source "../node_modules/@rjsf/shadcn";
```

### Not using Tailwind

#### Use the theme on demo site

A prebuilt stylesheet for each bundled theme is included in the npm package. Simply do

```
import '@rjsf/shadcn/dist/[theme].css';
e.g:
import '@rjsf/shadcn/dist/default.css';
```

Note that these stylesheets are complete Tailwind builds and include Tailwind's preflight reset, so importing one
will also restyle the rest of your page. If your application already builds Tailwind, use the
[Using Tailwind](#using-tailwind) section above instead.

Supported themes are:

- default
- amethyst-haze
- caffeine
- claude
- clean-slate
- neo-brutalism
- pastel-dreams
- soft-pop
- twitter
- vercel

#### Coloring

- Generate a theme from [official shadCN site](https://ui.shadcn.com/themes)
  or  [tweakcn](https://tweakcn.com/editor/theme)
- Navigate to `packages/shadcn/src/css`, create a new file called [your-theme].css
- Replace the base layer code with your new color
- Follow the next section to build your CSS file

#### Build your CSS file

If you are not using tailwind but still wants to use this theme, you can follow these steps:

- Clone the repository

```
cd packages/shadcn
npm i
npm run build:css
```

- Include the built `dist/[your-theme].css` in your application

## Dark mode (Tailwind only)

Check out this section by [shadCN](https://ui.shadcn.com/docs/dark-mode)

## RTL (Tailwind only)

### Installation

```bash
npm install @radix-ui/react-direction --save
```

### Implementation

1. Wrap your layout with DirectionProvider:

    ```tsx
    import {DirectionProvider as RadixDirectionProvider} from '@radix-ui/react-direction;
    
    function Layout({children, direction}) {
        return (
            <RadixDirectionProvider dir={direction}>
                {children}
            </RadixDirectionProvider>
        );
    }
    ```

2. Set HTML direction attribute:

    ```html
    <html dir="rtl" lang="en">
    ```

3. You can refer to `direction-context.tsx`, `direction-provider.tsx` and `rtl-toggle.tsx` from demo repository for
   implementation.

## Updating to latest shadCN version

- Simply copy the shadcn components into shadcn/src/components/ui and rebuilt the packages or using the shadcn CLI at
  the root level with the components.json
- For RTL version, you might need component from [here](https://github.com/shadcn-ui/ui/pull/1638)
  by [nahasco](https://github.com/nahasco)
- [Fancy multi-select](https://craft.mxkaske.dev/post/fancy-multi-select)



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub
repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg

[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions

[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg

[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors

[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square

[license-url]: https://choosealicense.com/licenses/apache-2.0/

[npm-shield]: https://img.shields.io/npm/v/@rjsf/shadcn/latest.svg?style=flat-square

[npm-url]: https://www.npmjs.com/package/@rjsf/shadcn

[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/shadcn.svg?style=flat-square

[npm-dl-url]: https://www.npmjs.com/package/@rjsf/shadcn

[product-screenshot]: https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/shadcn/screenshot.png

---

### Overview (`packages/snapshot-tests/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]

<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <img src="https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/core/logo.png" alt="Logo" width="180" height="120">
  </a>

  <h3 align="center">@rjsf/snapshot-tests</h3>

  <p align="center">
  A set of snapshot tests to be used for testing RJSF themes.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
- [Getting Started](#getting-started)
  - [Installation](#installation)
- [Usage](#usage)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Package with snapshot test suits for testing themes for `react-jsonschema-form`.



## Getting Started

### Installation

```sh
npm install @rjsf/snapshot-tests
```

## Usage

```tsx
import { arrayTests } from '@rjsf/snapshot-tests'; // OR
// import { formTests } from '@rjsf/snapshot-tests';
// import { gridTests } from '@rjsf/snapshot-tests';
// import { objectTests } from '@rjsf/snapshot-tests';

import Form from '../src';

arrayTests(Form); // OR
// formTests(Form);
// gridTests(Form);
// objectTests(Form);
```


## Roadmap

See the general [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/snapshot-tests/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/snapshot-tests
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/snapshot-tests.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/snapshot-tests
[product-screenshot]: https://raw.githubusercontent.com/rjsf-team/react-jsonschema-form/59a8206e148474bea854bbb004f624143fbcbac8/packages/snapshot-tests/screenshot.png

---

### Overview (`packages/utils/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]


<br />
<p align="center">
  <h3 align="center">@rjsf/utils</h3>

  <p align="center">
  Utility functions for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Exports `utils` functions for `react-jsonschema-form`.

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [TypeScript](https://www.typescriptlang.org/)



## Getting Started

### Installation

```bash
yarn add @rjsf/utils
```



## Usage

```jsx
import * as Utils from '@rjsf/utils';
```

## Documentation

[Utility function documentation](https://rjsf-team.github.io/react-jsonschema-form/docs/api-reference/utility-functions/)



## Roadmap

See the [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues) for a list of proposed features (and known issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/utils/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/utils
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/utils.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/utils

---

### Overview (`packages/validator-ajv8/README.md`)

[![Build Status][build-shield]][build-url]
[![npm][npm-shield]][npm-url]
[![npm downloads][npm-dl-shield]][npm-dl-url]
[![Contributors][contributors-shield]][contributors-url]
[![Apache 2.0 License][license-shield]][license-url]


<br />
<p align="center">

  <h3 align="center">@rjsf/validator-ajv8</h3>

  <p align="center">
  AJV-8 based validator plugin for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>



## Table of Contents

- [Table of Contents](#table-of-contents)
- [About The Project](#about-the-project)
  - [Built With](#built-with)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
- [Usage](#usage)
- [Roadmap](#roadmap)
- [Contributing](#contributing)
- [Contact](#contact)



## About The Project

Exports `validator-ajv8` plugin for `react-jsonschema-form`.

### Built With

- [react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form/)
- [AJV](https://github.com/ajv-validator/ajv/)
- [TypeScript](https://www.typescriptlang.org/)



## Getting Started

### Prerequisites

#### React JsonSchema Form Utils

- `@rjsf/utils >= 5.0.0`

```bash
yarn add @rjsf/core
```

### Installation

```bash
yarn add @rjsf/validator-ajv8
```



## Usage

```tsx
import { RJSFSchema } from 'packages/utils/dist/index';
import Form from 'packages/core/dist/index';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

<Form schema={schema} validator={validator} />;
```

or, using a more complex example using custom validator with custom formats

```tsx
import { RJSFSchema } from '@rjsf/utils';
import Form from '@rjsf/core';
import { customizeValidator } from '@rjsf/validator-ajv8';

const customFormats = {
  'phone-us': /\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}$/,
};

const validator = customizeValidator({
  customFormats,
});

const schema: RJSFSchema = {
  type: 'string',
  format: 'phone-us',
};

<Form schema={schema} validator={validator} />;
```

or, using a more complex example using a custom with additional meta schema

```tsx
import { RJSFSchema } from '@rjsf/utils';
import Form from '@rjsf/core';
import { customizeValidator } from '@rjsf/validator-ajv8';

const metaSchemaDraft06 = require('ajv/lib/refs/json-schema-draft-06.json');

const validator = customizeValidator({
  additionalMetaSchemas: [metaSchemaDraft06],
});

const schema: RJSFSchema = {
  $schema: 'http://json-schema.org/draft-06/schema#',
  type: 'string',
};

<Form schema={schema} validator={validator} />;
```

or, using a more complex example using custom validator config override options

```tsx
import { RJSFSchema } from '@rjsf/utils';
import Form from '@rjsf/core';
import { customizeValidator } from '@rjsf/validator-ajv8';

const validator = customizeValidator({
  ajvOptionsOverrides: {
    $data: true,
    verbose: true,
  },
});

const schema: RJSFSchema = {
  type: 'string',
};

<Form schema={schema} validator={validator} />;
```

or, using a more complex example using `ajv-formats` custom [format options](https://github.com/ajv-validator/ajv-formats).

```tsx
import { RJSFSchema } from '@rjsf/utils';
import Form from '@rjsf/core';
import { customizeValidator } from '@rjsf/validator-ajv8';

const validator = customizeValidator({
  ajvFormatOptions: {
    keywords: true,
    formats: ['date', 'time'],
  },
});

const schema: RJSFSchema = {
  type: 'string',
};

<Form schema={schema} validator={validator} />;
```

Finally, you can combine both additional meta schemas, custom formats, custom validator config override options and `ajv-formats` custom [format options](https://github.com/ajv-validator/ajv-formats).

```tsx
import { RJSFSchema } from '@rjsf/utils';
import Form from '@rjsf/core';
import { customizeValidator } from '@rjsf/validator-ajv8';

const metaSchemaDraft06 = require('ajv/lib/refs/json-schema-draft-06.json');

const customFormats = {
  'phone-us': /\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}$/,
};

const validator = customizeValidator({
  additionalMetaSchemas: [metaSchemaDraft06],
  customFormats,
  ajvOptionsOverrides: {
    $data: true,
    verbose: true,
  },
  ajvFormatOptions: {
    keywords: true,
    formats: ['date', 'time'],
  },
});

const schema: RJSFSchema = {
  $schema: 'http://json-schema.org/draft-06/schema#',
  type: 'string',
  format: 'phone-us',
};

<Form schema={schema} validator={validator} />;
```



## Roadmap

See the [open issues](https://github.com/rjsf-team/react-jsonschema-form/issues) for a list of proposed features (and known issues).



## Contributing

Read our [contributors' guide](https://rjsf-team.github.io/react-jsonschema-form/docs/contributing/) to get started.



## Contact

rjsf team: [https://github.com/orgs/rjsf-team/people](https://github.com/orgs/rjsf-team/people)

GitHub repository: [https://github.com/rjsf-team/react-jsonschema-form](https://github.com/rjsf-team/react-jsonschema-form)




[build-shield]: https://github.com/rjsf-team/react-jsonschema-form/workflows/CI/badge.svg
[build-url]: https://github.com/rjsf-team/react-jsonschema-form/actions
[contributors-shield]: https://img.shields.io/github/contributors/rjsf-team/react-jsonschema-form.svg
[contributors-url]: https://github.com/rjsf-team/react-jsonschema-form/graphs/contributors
[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue.svg?style=flat-square
[license-url]: https://choosealicense.com/licenses/apache-2.0/
[npm-shield]: https://img.shields.io/npm/v/@rjsf/validator-ajv8/latest.svg?style=flat-square
[npm-url]: https://www.npmjs.com/package/@rjsf/validator-ajv8
[npm-dl-shield]: https://img.shields.io/npm/dm/@rjsf/validator-ajv8.svg?style=flat-square
[npm-dl-url]: https://www.npmjs.com/package/@rjsf/validator-ajv8

---

### Overview (`packages/validator-ata/README.md`)

[![Apache 2.0 License][license-shield]][license-url]

<br />
<p align="center">
  <a href="https://github.com/rjsf-team/react-jsonschema-form">
    <h3 align="center">@rjsf/validator-ata</h3>
  </a>

  <p align="center">
  <a href="https://github.com/ata-core/ata-validator">ata-validator</a> based validator plugin for <a href="https://github.com/rjsf-team/react-jsonschema-form/"><code>react-jsonschema-form</code></a>.
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/docs/"><strong>Explore the docs »</strong></a>
    <br />
    <br />
    <a href="https://rjsf-team.github.io/react-jsonschema-form/">View Playground</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Report Bug</a>
    ·
    <a href="https://github.com/rjsf-team/react-jsonschema-form/issues">Request Feature</a>
  </p>
</p>

## Table of Contents

- [About](#about)
- [Installation](#installation)
- [Usage](#usage)
- [Customization](#customization)
- [Differences from validator-ajv8](#differences-from-validator-ajv8)

## About

`@rjsf/validator-ata` plugs [`ata-validator`](https://github.com/ata-core/ata-validator) into `react-jsonschema-form` as a drop-in alternative to `@rjsf/validator-ajv8`. The public API mirrors `validator-ajv8` so swapping is a one-line change in the validator import. Error format, custom-format hook, custom validation, and error transformation all work the same way.

ata is a JSON Schema validator that targets Draft 2020-12 (98.5% spec compliance, 95.3% schemasafe pass rate) and is Standard Schema compliant. Its differentiators relative to AJV: pattern checks are RE2-backed (no ReDoS surface), and schemas can be compiled at build time for environments where bundle size or CSP restricts runtime codegen.

## Installation

```bash
npm install @rjsf/validator-ata
```

`ata-validator` is a dependency of this package and is installed with it.

## Usage

```ts
import Form from '@rjsf/core';
import validator from '@rjsf/validator-ata';

<Form schema={schema} validator={validator} />;
```

### Customization

```ts
import { customizeValidator } from '@rjsf/validator-ata';

const validator = customizeValidator({
  customFormats: {
    'phone-us': /\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}$/,
    'area-code': /\d{3}/,
  },
  ataOptionsOverrides: {
    verbose: true,
  },
});
```

`customizeValidator` accepts:

- **`customFormats`** — same shape as `validator-ajv8`. Values may be a `RegExp`, an anchored regex source string, or a `(value: string) => boolean` predicate.
- **`ataOptionsOverrides`** — plain `ata-validator` options spread on top of the defaults; use this to flip `coerceTypes`, `removeAdditional`, `verbose`, or `abortEarly`.
- **`additionalMetaSchemas`** — extra schemas registered via `Validator#addSchema` for cross-schema `$ref` resolution.
- **`extenderFn`** — hook applied against a freshly-built `Validator` (e.g. for adding additional formats or schemas in one place).
- **`suppressDuplicateFiltering`** — passthrough to the RJSF error processor; same semantics as in `validator-ajv8`.

A `Localizer` may be supplied as the second argument. ata error objects use the same field names as AJV (`keyword`, `instancePath`, `schemaPath`, `params`, `message`, `parentSchema`), so localizers that mutate `message` in place port across without changes. The pre-quote dance that the AJV validator runs against `ajv-i18n` is intentionally not replicated here — ata's error params are frozen, and the existing locale catalogues for AJV are not portable to ata's keyword set.

## Differences from validator-ajv8

The `ValidatorType` contract is identical, and the shared `@rjsf/utils` schema test suite passes against this validator with the deltas below. Behavior outside of this list mirrors `validator-ajv8`.

- **Precompiled validators** are supported. See [Precompiled validators](https://rjsf-team.github.io/react-jsonschema-form/docs/usage/validation#precompiled-validators-with-rjsfvalidator-ata) in the docs.
- **`ajvOptionsOverrides`, `ajvFormatOptions`, `AjvClass`** have no equivalents and are intentionally not accepted. `ataOptionsOverrides` replaces the first; built-in formats are always installed and don't require an opt-in flag.
- **`isValid` and `rawValidation` deep-clone `formData` before passing it to ata**. ata's default-applier writes `default` values into the input object during validation, while AJV treats validation as a pure operation. The clone preserves the AJV contract RJSF expects when probing data through repeated `isValid` calls (oneOf/anyOf option resolution).
- **Custom-keyword extensions** (e.g. `ajv-errors`, `ajv-merge-patch`) have no ata-side counterpart yet. Schemas using these keywords will validate (ata silently ignores unknown keywords) but the extension semantics are not applied.

## Contributing

See the monorepo [CONTRIBUTING.md](../../CONTRIBUTING.md). Issues and PRs welcome on either the validator package or [ata-validator](https://github.com/ata-core/ata-validator) itself.

[license-shield]: https://img.shields.io/badge/license-Apache%202.0-blue
[license-url]: https://github.com/rjsf-team/react-jsonschema-form/blob/main/LICENSE.md

---

### Overview (`packages/validator-cfworker/README.md`)

# @rjsf/validator-cfworker

`@rjsf/validator-cfworker` is an additional validator option for CSP-constrained RJSF users.
It uses [`@cfworker/json-schema`](https://github.com/cfworker/cfworker/tree/main/packages/json-schema) to interpret schemas without `eval` or `new Function`, and defaults to JSON Schema draft 2020-12.

**It is not an AJV replacement.** Choose it when an eval-free runtime is more important than AJV-specific keywords, extensions, localization, or code generation.

```tsx
import Form from '@rjsf/core';
import validator from '@rjsf/validator-cfworker';

export default function Example() {
  return <Form schema={{ type: 'string' }} validator={validator} />;
}
```

## Behavior

- Implements RJSF's `ValidatorType<T, S, F>` interface.
- Normalizes `undefined` before validation: undefined object members are omitted so `required` errors surface, while undefined array entries become `null`.
- Caches schema-bound engine instances by schema `$id` (or the RJSF schema hash) and refreshes them when the schema or root schema changes.
- Supports `customValidate`, `transformErrors`, custom formats, duplicate `anyOf`/`oneOf` filtering, and the RJSF `color` and `data-url` formats.
- Supports draft 4, draft 7, draft 2019-09, and draft 2020-12 through the `draft` customization option; the default is draft 2020-12.

```ts
import { customizeValidator } from '@rjsf/validator-cfworker';

const validator = customizeValidator({
  draft: '2020-12',
  shortCircuit: false,
  customFormats: {
    'phone-us': /\(?\d{3}\)?[\s-]?\d{3}[\s-]?\d{4}$/,
  },
});
```

## Unsupported-keyword matrix

Unknown keywords are annotations to the underlying engine, so unsupported extensions are not validation constraints.

| Keyword or extension | Status | Notes |
| --- | --- | --- |
| `$dynamicRef` / `$dynamicAnchor` | Unsupported | Tracked upstream in [`cfworker/json-schema#150`](https://github.com/cfworker/cfworker/issues/150). |
| AJV `$data` references | Unsupported | AJV-specific extension; use literal schema values. |
| OpenAPI `discriminator` | Unsupported | Use standard `oneOf` constraints without discriminator semantics. |
| `errorMessage` from `ajv-errors` | Unsupported | Use RJSF's `transformErrors` hook instead. |

Precompiled-validator mode is intentionally outside this initial package. Runtime error messages also differ from AJV, and there is no `ajv-i18n` equivalent.

## Upstream state and provenance

This package is ported from [`glama-ai/rjsf-validator-cfworker`](https://github.com/glama-ai/rjsf-validator-cfworker), whose structure was intentionally kept compatible with RJSF.
The original MIT copyright and license are preserved in [LICENSE](./LICENSE); the RJSF integration and subsequent changes are distributed under the monorepo's Apache-2.0 license.

The underlying `@cfworker/json-schema` package's latest release is from January 2025. Its tracker includes open correctness reports for duplicate schema URIs ([#335](https://github.com/cfworker/cfworker/issues/335)) and `additionalProperties` behavior ([#336](https://github.com/cfworker/cfworker/issues/336)), as well as the `$dynamicRef` gap above.
This wrapper's per-schema cache avoids repeat registration on RJSF's `isValid` path, but it does not change the upstream engine's other semantics.
The package is therefore presented as an additional option for CSP-constrained users.

---

### Index (`docs/index.md`)

# react-jsonschema-form

The react-jsonschema-form docs have been moved [here](https://rjsf-team.github.io/react-jsonschema-form/docs).

---

### Packages Docs Docs 01 Quickstart (`packages/docs/docs/01-quickstart.md`)

# Quickstart

Let's walk through setup of a form after installing the dependency properly.
NOTE: As of version 5, the `Form` now requires you to provide a `validator` implementation. We recommend the one from `@rjsf/validator-ajv8`.

## Form schema

First, specify a schema using the [JSON Schema specification](https://json-schema.org/). The below schema renders a single string field:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Test form',
  type: 'string',
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

You can also render an object with multiple fields with the below schema:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Test form',
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
    age: {
      type: 'number',
    },
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

For more information and examples of JSON Schema properties that this library supports, see [Using JSON Schema](json-schema/single.md).

## Form uiSchema

The uiSchema is used to add more customization to the form's look and feel. Use the `classNames`
attribute of the uiSchema to add a custom CSS class name to the form:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Test form',
  type: 'string',
};

const uiSchema: UiSchema = {
  'ui:classNames': 'custom-css-class',
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

To customize object fields in the uiSchema, the structure of the
uiSchema should be `{key: value}`, where `key` is the property key and `value` is an
object with the uiSchema configuration for that particular property. For example:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Test form',
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
    age: {
      type: 'number',
    },
  },
};

const uiSchema: UiSchema = {
  name: {
    'ui:classNames': 'custom-class-name',
  },
  age: {
    'ui:classNames': 'custom-class-age',
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

## Form initialization

Often you'll want to prefill a form with existing data; this is done by passing a `formData` prop object matching the schema:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    title: {
      type: 'string',
    },
    done: {
      type: 'boolean',
    },
  },
};

const formData = {
  title: 'First task',
  done: true,
};

render(<Form schema={schema} formData={formData} validator={validator} />, document.getElementById('app'));
```

> Note: If your form has a single field, pass a single value to `formData`. ex: `formData="Charlie"`

> WARNING: If you have situations where your parent component can re-render, make sure you listen to the `onChange` event and update the data you pass to the `formData` attribute.

### Form event handlers

You can use event handlers such as `onChange`, `onError`, `onSubmit`, `onFocus`, and `onBlur` on the `<Form />` component; see the [Form Props Reference](./api-reference/form-props.md) for more details.

### Controlled component

By default, `<Form />` is an [uncontrolled component](https://reactjs.org/docs/uncontrolled-components.html). To make it a controlled component, use the
`onChange` and `formData` props as in the below example:

```tsx
import Form from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';

const App = () => {
  const [formData, setFormData] = React.useState(null);
  return (
    <Form
      schema={{ type: 'string' }}
      formData={formData}
      onChange={(e) => setFormData(e.formData)}
      validator={validator}
    />
  );
};

render(<App />, document.getElementById('app'));
```

---

### Packages Docs Docs Advanced Customization Index (`packages/docs/docs/advanced-customization/index.mdx`)

---
title: Advanced Customization
description: Advanced customization documentation for react-jsonschema-form.

---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Docs Api Reference Index (`packages/docs/docs/api-reference/index.mdx`)

---
title: API Reference
description: API documentation for react-jsonschema-form.
---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Docs Json Schema Index (`packages/docs/docs/json-schema/index.mdx`)

---
title: JSON Schema
description: Documentation for how to use JSON Schema constructs in react-jsonschema-form.,
---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Docs Migration Guides Index (`packages/docs/docs/migration-guides/index.mdx`)

---
title: Migration Guides
description: Guides for upgrading to new major versions of react-jsonschema-form
---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Docs Usage Index (`packages/docs/docs/usage/index.mdx`)

---
title: Usage and Customization
description: How to use react-jsonschema-form and customize your form behavior and appearance.

---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 3.2.1 00 Quickstart (`packages/docs/versioned_docs/version-3.2.1/00-quickstart.md`)

# Quickstart

Let's walk through setup of a form after installing the dependency properly.

## Form schema

First, specify a schema using the [JSON Schema specification](https://json-schema.org/). The below schema renders a single string field:

```jsx
const schema = {
  title: "Test form",
  type: "string"
};

render((
  <Form schema={schema} />
), document.getElementById("app"));
```

You can also render an object with multiple fields with the below schema:

```jsx
const schema = {
  title: "Test form",
  type: "object",
  properties: {
    name: {
      type: "string"
    },
    age: {
      type: "number"
    }
  }
};

render((
  <Form schema={schema} />
), document.getElementById("app"));
```

For more information and examples of JSON Schema properties that this library supports, see [Using JSON Schema](./usage/single.md).

## Form uiSchema

The uiSchema is used to add more customization to the form's look and feel. Use the `classNames`
attribute of the uiSchema to add a custom CSS class name to the form:


```jsx
const schema = {
  title: "Test form",
  type: "string"
};

const uiSchema = {
  classNames: "custom-css-class"
};

render((
  <Form schema={schema} uiSchema={uiSchema} />
), document.getElementById("app"));
```

To customize object fields in the uiSchema, the structure of the
uiSchema should be `{key: value}`, where `key` is the property key and `value` is an
object with the uiSchema configuration for that particular property. For example:

```jsx
const schema = {
  title: "Test form",
  type: "object",
  properties: {
    name: {
      type: "string"
    },
    age: {
      type: "number"
    }
  }
};

const uiSchema = {
  name: {
    classNames: "custom-class-name"
  },
  age: {
    classNames: "custom-class-age"
  }
}

render((
  <Form schema={schema} />
), document.getElementById("app"));
```

## Form initialization

Often you'll want to prefill a form with existing data; this is done by passing a `formData` prop object matching the schema:

```jsx
const schema = {
  type: "object",
  properties: {
    title: {
      type: "string"
    },
    done: {
      type: "boolean"
    }
  }
};

const formData = {
  title: "First task",
  done: true
};

render((
  <Form schema={schema}
        formData={formData} />
), document.getElementById("app"));
```

> Note: If your form has a single field, pass a single value to `formData`. ex: `formData="Charlie"`

> WARNING: If you have situations where your parent component can re-render, make sure you listen to the `onChange` event and update the data you pass to the `formData` attribute.

### Form event handlers

You can use event handlers such as `onChange`, `onError`, `onSubmit`, `onFocus`, and `onBlur` on the `<Form />` component; see the [Form Props Reference](/docs/api-reference/form-props.md) for more details.

### Controlled component

By default, `<Form />` is an [uncontrolled component](https://reactjs.org/docs/uncontrolled-components.html). To make it a controlled component, use the
`onChange` and `formData` props as in the below example:

```jsx
const App = () => {
  const [formData, setFormData] = React.useState(null);
  return (<Form
    schema={{type: "string"}}
    formData={formData}
    onChange={e => setFormData(e.formData)}
  />);
};

render((
  <App />
), document.getElementById("app"));
```

---

### Packages Docs Versioned Docs Version 4.2.3 00 Quickstart (`packages/docs/versioned_docs/version-4.2.3/00-quickstart.md`)

# Quickstart

Let's walk through setup of a form after installing the dependency properly.

## Form schema

First, specify a schema using the [JSON Schema specification](https://json-schema.org/). The below schema renders a single string field:

```jsx
const schema = {
  title: "Test form",
  type: "string"
};

render((
  <Form schema={schema} />
), document.getElementById("app"));
```

You can also render an object with multiple fields with the below schema:

```jsx
const schema = {
  title: "Test form",
  type: "object",
  properties: {
    name: {
      type: "string"
    },
    age: {
      type: "number"
    }
  }
};

render((
  <Form schema={schema} />
), document.getElementById("app"));
```

For more information and examples of JSON Schema properties that this library supports, see [Using JSON Schema](./usage/single.md).

## Form uiSchema

The uiSchema is used to add more customization to the form's look and feel. Use the `classNames`
attribute of the uiSchema to add a custom CSS class name to the form:


```jsx
const schema = {
  title: "Test form",
  type: "string"
};

const uiSchema = {
  classNames: "custom-css-class"
};

render((
  <Form schema={schema} uiSchema={uiSchema} />
), document.getElementById("app"));
```

To customize object fields in the uiSchema, the structure of the
uiSchema should be `{key: value}`, where `key` is the property key and `value` is an
object with the uiSchema configuration for that particular property. For example:

```jsx
const schema = {
  title: "Test form",
  type: "object",
  properties: {
    name: {
      type: "string"
    },
    age: {
      type: "number"
    }
  }
};

const uiSchema = {
  name: {
    classNames: "custom-class-name"
  },
  age: {
    classNames: "custom-class-age"
  }
}

render((
  <Form schema={schema} />
), document.getElementById("app"));
```

## Form initialization

Often you'll want to prefill a form with existing data; this is done by passing a `formData` prop object matching the schema:

```jsx
const schema = {
  type: "object",
  properties: {
    title: {
      type: "string"
    },
    done: {
      type: "boolean"
    }
  }
};

const formData = {
  title: "First task",
  done: true
};

render((
  <Form schema={schema}
        formData={formData} />
), document.getElementById("app"));
```

> Note: If your form has a single field, pass a single value to `formData`. ex: `formData="Charlie"`

> WARNING: If you have situations where your parent component can re-render, make sure you listen to the `onChange` event and update the data you pass to the `formData` attribute.

### Form event handlers

You can use event handlers such as `onChange`, `onError`, `onSubmit`, `onFocus`, and `onBlur` on the `<Form />` component; see the [Form Props Reference](./api-reference/form-props.md) for more details.

### Controlled component

By default, `<Form />` is an [uncontrolled component](https://reactjs.org/docs/uncontrolled-components.html). To make it a controlled component, use the
`onChange` and `formData` props as in the below example:

```jsx
const App = () => {
  const [formData, setFormData] = React.useState(null);
  return (<Form
    schema={{type: "string"}}
    formData={formData}
    onChange={e => setFormData(e.formData)}
  />);
};

render((
  <App />
), document.getElementById("app"));
```

---

### Packages Docs Versioned Docs Version 5.24.10 01 Quickstart (`packages/docs/versioned_docs/version-5.24.10/01-quickstart.md`)

# Quickstart

Let's walk through setup of a form after installing the dependency properly.
NOTE: As of version 5, the `Form` now requires you to provide a `validator` implementation. We recommend the one from `@rjsf/validator-ajv8`.

## Form schema

First, specify a schema using the [JSON Schema specification](https://json-schema.org/). The below schema renders a single string field:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Test form',
  type: 'string',
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

You can also render an object with multiple fields with the below schema:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Test form',
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
    age: {
      type: 'number',
    },
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

For more information and examples of JSON Schema properties that this library supports, see [Using JSON Schema](json-schema/single.md).

## Form uiSchema

The uiSchema is used to add more customization to the form's look and feel. Use the `classNames`
attribute of the uiSchema to add a custom CSS class name to the form:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Test form',
  type: 'string',
};

const uiSchema: UiSchema = {
  'ui:classNames': 'custom-css-class',
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

To customize object fields in the uiSchema, the structure of the
uiSchema should be `{key: value}`, where `key` is the property key and `value` is an
object with the uiSchema configuration for that particular property. For example:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Test form',
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
    age: {
      type: 'number',
    },
  },
};

const uiSchema: UiSchema = {
  name: {
    'ui:classNames': 'custom-class-name',
  },
  age: {
    'ui:classNames': 'custom-class-age',
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

## Form initialization

Often you'll want to prefill a form with existing data; this is done by passing a `formData` prop object matching the schema:

```tsx
import Form from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    title: {
      type: 'string',
    },
    done: {
      type: 'boolean',
    },
  },
};

const formData = {
  title: 'First task',
  done: true,
};

render(<Form schema={schema} formData={formData} validator={validator} />, document.getElementById('app'));
```

> Note: If your form has a single field, pass a single value to `formData`. ex: `formData="Charlie"`

> WARNING: If you have situations where your parent component can re-render, make sure you listen to the `onChange` event and update the data you pass to the `formData` attribute.

### Form event handlers

You can use event handlers such as `onChange`, `onError`, `onSubmit`, `onFocus`, and `onBlur` on the `<Form />` component; see the [Form Props Reference](./api-reference/form-props.md) for more details.

### Controlled component

By default, `<Form />` is an [uncontrolled component](https://reactjs.org/docs/uncontrolled-components.html). To make it a controlled component, use the
`onChange` and `formData` props as in the below example:

```tsx
import Form from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';

const App = () => {
  const [formData, setFormData] = React.useState(null);
  return (
    <Form
      schema={{ type: 'string' }}
      formData={formData}
      onChange={(e) => setFormData(e.formData)}
      validator={validator}
    />
  );
};

render(<App />, document.getElementById('app'));
```

---

### Packages Docs Versioned Docs Version 3.2.1 Advanced Customization Index (`packages/docs/versioned_docs/version-3.2.1/advanced-customization/index.mdx`)

---
title: Advanced Customization
description: Advanced customization documentation for react-jsonschema-form.

---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 3.2.1 Api Reference Index (`packages/docs/versioned_docs/version-3.2.1/api-reference/index.mdx`)

---
title: API Reference
description: API documentation for react-jsonschema-form.
---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 3.2.1 Usage Index (`packages/docs/versioned_docs/version-3.2.1/usage/index.mdx`)

---
title: Usage and Customization
description: How to use react-jsonschema-form and customize your form behavior and appearance.

---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 4.2.3 Advanced Customization Index (`packages/docs/versioned_docs/version-4.2.3/advanced-customization/index.mdx`)

---
title: Advanced Customization
description: Advanced customization documentation for react-jsonschema-form.

---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 4.2.3 Api Reference Index (`packages/docs/versioned_docs/version-4.2.3/api-reference/index.mdx`)

---
title: API Reference
description: API documentation for react-jsonschema-form.
---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 4.2.3 Usage Index (`packages/docs/versioned_docs/version-4.2.3/usage/index.mdx`)

---
title: Usage and Customization
description: How to use react-jsonschema-form and customize your form behavior and appearance.

---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 5.24.10 Advanced Customization Index (`packages/docs/versioned_docs/version-5.24.10/advanced-customization/index.mdx`)

---
title: Advanced Customization
description: Advanced customization documentation for react-jsonschema-form.

---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 5.24.10 Api Reference Index (`packages/docs/versioned_docs/version-5.24.10/api-reference/index.mdx`)

---
title: API Reference
description: API documentation for react-jsonschema-form.
---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 5.24.10 Json Schema Index (`packages/docs/versioned_docs/version-5.24.10/json-schema/index.mdx`)

---
title: JSON Schema
description: Documentation for how to use JSON Schema constructs in react-jsonschema-form.,
---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 5.24.10 Migration Guides Index (`packages/docs/versioned_docs/version-5.24.10/migration-guides/index.mdx`)

---
title: Migration Guides
description: Guides for upgrading to new major versions of react-jsonschema-form
---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Versioned Docs Version 5.24.10 Usage Index (`packages/docs/versioned_docs/version-5.24.10/usage/index.mdx`)

---
title: Usage and Customization
description: How to use react-jsonschema-form and customize your form behavior and appearance.

---

import DocCardList from '@theme/DocCardList';

<p>{frontMatter.description}</p>

<DocCardList  />

---

### Packages Docs Package.Json (`packages/docs/package.json`)

{
  "name": "@rjsf/docs",
  "version": "6.11.0",
  "private": true,
  "scripts": {
    "docusaurus": "docusaurus",
    "start": "docusaurus start",
    "build": "docusaurus build",
    "swizzle": "docusaurus swizzle",
    "deploy": "docusaurus deploy",
    "clear": "docusaurus clear",
    "serve": "docusaurus serve",
    "write-translations": "docusaurus write-translations",
    "write-heading-ids": "docusaurus write-heading-ids",
    "typecheck": "tsc",
    "precommit": "lint-staged",
    "cs-check": "oxfmt --check \"src/**/*.{ts,tsx}\"",
    "cs-format": "oxfmt \"src/**/*.{ts,tsx}\""
  },
  "lint-staged": {
    "src/**/*.{ts,tsx}": [
      "oxfmt"
    ]
  },
  "dependencies": {
    "@docusaurus/core": "^3.10.2",
    "@docusaurus/preset-classic": "^3.10.2",
    "@mdx-js/react": "^3.1.1",
    "prism-react-renderer": "^2.4.1"
  },
  "devDependencies": {
    "@docusaurus/module-type-aliases": "^3.10.2",
    "@docusaurus/plugin-content-docs": "^3.10.2",
    "@docusaurus/types": "^3.10.2",
    "@tsconfig/docusaurus": "^2.0.9"
  },
  "browserslist": {
    "production": [
      ">0.5%",
      "not dead",
      "not op_mini all"
    ],
    "development": [
      "last 1 chrome version",
      "last 1 firefox version",
      "last 1 safari version"
    ]
  },
  "engines": {
    "node": ">=20"
  }
}

---

### Packages Docs Tsconfig.Json (`packages/docs/tsconfig.json`)

{
  // This file is not used in compilation. It is here just for a nice editor experience.
  "extends": "@tsconfig/docusaurus/tsconfig.json",
  "compilerOptions": {
    "resolveJsonModule": true
  }
}

---

### Packages Docs Docs 00 Introduction (`packages/docs/docs/00-introduction.mdx`)

---
id: intro
title: Introduction
slug: /
---

# react-jsonschema-form



A simple [React](https://reactjs.org/) component capable of building HTML forms out of a [JSON schema](http://json-schema.org/).

A [live playground](https://rjsf-team.github.io/react-jsonschema-form/) is hosted on GitHub Pages:

<a target='_blank' href='https://rjsf-team.github.io/react-jsonschema-form/'>
  
</a>

## Philosophy

react-jsonschema-form is meant to automatically generate a React form based on a [JSON Schema](http://json-schema.org/). If you want to generate a form for any data, sight unseen, simply given a JSON schema, react-jsonschema-form may be for you. If you have _a priori_ knowledge of your data and want a toolkit for generating forms for it, you might look elsewhere.

react-jsonschema-form also comes with tools such as `uiSchema` and other form props to customize the look and feel of the form beyond the default themes.

## Installation

First install the dependencies from npm, along with a validator implementation (such as `@rjsf/validator-ajv8`):

```bash
$ npm install @rjsf/core @rjsf/utils @rjsf/validator-ajv8 --save
```

Then import the dependencies as follows:

```ts
import Form from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';
```

Our latest version requires React 16+.

## Usage

```tsx
import Form from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Todo',
  type: 'object',
  required: ['title'],
  properties: {
    title: { type: 'string', title: 'Title', default: 'A new task' },
    done: { type: 'boolean', title: 'Done?', default: false },
  },
};

const log = (type) => console.log.bind(console, type);

render(
  <Form
    schema={schema}
    validator={validator}
    onChange={log('changed')}
    onSubmit={log('submitted')}
    onError={log('errors')}
  />,
  document.getElementById('app')
);
```

## Theming

For more information on what themes we support, see [Using Themes](usage/themes).



## License

Apache 2

## Credits

<table>
    <tr>
        <th>
            <img src="https://avatars1.githubusercontent.com/u/1066228?s=200&v=4" alt="mozilla-services-logo" style={{maxHeight: '100px'}} />
        </th>
        <td>
            This project initially started as a <a href="https://github.com/mozilla-services">mozilla-services</a> project.
        </td>
    </tr>
    <tr>
        <th>
            <img src="https://user-images.githubusercontent.com/1689183/51487090-4ea04f80-1d57-11e9-9a91-79b7ef8d2013.png" alt='browserstack logo'  style={{maxHeight: '100px'}}/>
        </th>
        <td>
            Testing is powered by <a href="https://www.browserstack.com/" >BrowserStack</a>.
        </td>
    </tr>
    <tr>
        <th>
            <img src="https://www.netlify.com/img/global/badges/netlify-color-accent.svg" alt='netlify logo'  style={{maxHeight: '100px'}}/>
        </th>
        <td>
            Deploy Previews are provided by <a href="https://www.netlify.com">Netlify</a>.
        </td>
    </tr>
</table>

## Who uses react-jsonschema-form?

- ...

Add your own company / organization by making a [pull request](https://github.com/rjsf-team/react-jsonschema-form/pulls).

---

### Packages Docs Docs Contributing (`packages/docs/docs/contributing.md`)

# Contributing

## Development server

We are using `Vite` to power our `playground`, which caches all the built `@rjsf/*` distributions.
In order to test the `playground` locally after a new clone or fresh pull from `main`, run the following from the root directory of the monorepo:

```bash
pnpm install
pnpm run build
cd packages/playground
pnpm start
```

This will start the live development server showcasing components at [localhost:8080](http://localhost:8080).

Whenever you make changes to source code, stop the running playground and return to the root directory and rerun `pnpm run build`.
Thanks to `nx` caching, this should only rebuild what is necessary.
After the build is complete, return to the root of the `playground` and restart the server via `pnpm start`.

### First time step

If this is the first time you have cloned the repo, run the `pnpm run prepare` script that will set up `husky` to provide a git precommit hook that will format and lint any code you have added to a PR.

### Optional development process

With the large number of packages, sometimes running `pnpm run build` or `pnpm start` from the root directory will overwhelm an underpowered computer.
If that is the situation for you, you can instead use `pnpm run build-serial` to build the packages one at a time instead of all at once.
Also, if you are only working on one package, you can `pnpm run build` and `pnpm run test` from within the subdirectory.
Finally, you can simply `pnpm start` inside of the `playground` directory to test changes if you have already built all of your packages, without needing to watch all of the packages via the root directory `pnpm start`.

### Troubleshooting build failures

Sometimes your local builds fail and you can't figure out why. This is most likely to happen after rebase to `main` due
to `package.json` changes upstream. There are two commands you can use to (hopefully) get your environment back to a
working state. Try running the following two commands:

```bash
pnpm run refresh-node-modules
pnpm run clean-build
```

The first command will delete all of the `node_modules` directories in the environment and then rerun `pnpm install`.
The second command cleans up the typescript build cache files before retrying the build.

Worst case scenario when neither of those commands work, try running `pnpm run nuke-build-env` and then rerun the two commands.

## Cloud builds

When building in environments with limited memory, such as Netlify, it's recommended to use `pnpm run build-serial` that builds the packages serially.

## Coding style

All the JavaScript/Typescript code in this project conforms to the [prettier](https://github.com/prettier/prettier) coding style.
Code is automatically prettified upon commit using precommit hooks, assuming you followed the `First time step` above.

You can also run `pnpm cs-format` within any package directory you are changing.

## Documentation

We use [Docusaurus](https://docusaurus.io/) to build our documentation. To run documentation locally, run:

```bash
cd packages/docs
pnpm start
```

Documentation will be served on [localhost:3000](http://localhost:3000).

## Tests

You can run all tests from the root directory OR from `packages` subdirectory using the following command:

```bash
pnpm run test
```

### Snapshot testing

All the themes, including `core` use snapshot testing (NOTE: `core` also has extensive non-snapshot tests).
The source-code of these snapshot tests reside in the `core` package in the `testSnap` directory and are shared with all the themes.
In order to support the various themes, the code for the tests are actually functions that take two parameters:

- `Form`: ComponentType&lt;FormProps> - The component from the theme implementation
- `[customOptions]`: \{ [key: string]: TestRendererOptions } - an optional map of `react-test-renderer` `TestRendererOptions` implementations that some themes need to be able properly run

There are functions in the `testSnap` directory: `arrayTests`, `formTests` and `objectTests`, each with its own definition of `customOptions`

Each theme will basically run these functions by creating a `Xxx.test.tsx` file (where `Xxx` is `Array`, `Form` or `Object`) that looks like the following:

```tsx
import { arrayTests } from '@rjsf/snapshot-tests'; // OR
// import { formTests } from '@rjsf/snapshot-tests';
// import { objectTests } from '@rjsf/snapshot-tests';

import Form from '../src';

arrayTests(Form); // OR
// formTests(Form);
// objectTests(Form);
```

Anytime you add a new feature, be sure to update the appropriate `xxxTests()` function in the `testSnap` directory and do `pnpm run test` from the root directory to update all the snapshots.
If you add a theme-only feature, it is ok to update the appropriate `Xxx.test.tsx` file to add (or update) the theme-specific `describe()` block.
For example:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import { arrayTests } from '@rjsf/snapshot-tests';

import Form from '../src';

formTests(Form);

describe('Theme specific tests', () => {
  it('test a theme-specific option', () => {
    const schema: RJSFSchema = {
      type: 'object',
      properties: {
        name: {
          type: 'string',
        },
      },
    };
    const uiSchema: UiSchema = {
      // Enable the theme specific feature
    };
    const tree = renderer.create(<Form schema={schema} uiSchema={uiSchema} validator={validator} />).toJSON();
    expect(tree).toMatchSnapshot();
  });
});
```

See the `antd` `Form.test.tsx` for a specific example of this.

### Code coverage

Code coverage reports are currently available only for the `@rjsf/core` theme package.
They are generated using [nyc](https://github.com/istanbuljs/nyc) each time the `pnpm test-coverage` script is run.
The full report can be seen by opening `./coverage/lcov-report/index.html`.

#### Utils and validator-ajv8 code coverage

100% code coverage is required by the `@rjsf/utils` and `@rjsf/validator-ajv8` tests.
If you make changes to those libraries, you will have to maintain that coverage, otherwise the tests will fail.

> NOTE: All three of these directories share the same tests for verifying `validator` based APIs. See the documentation in the `getTestValidator()` functions for more information.

## Releasing

To release, go to the main branch (NOT a fork) and then create a new branch with the version number (with an `rc` prefix instead of `v`).
For instance if you are about to create the new `6.100.10` branch, then you would run the following commands:

```bash
git checkout -b rc6.100.10
pnpm exec nx release version --git-tag
git commit -m "Releasing 6.100.10"
git push
pnpm run update-version-tags
```

Make sure you use [semver](https://semver.org/) for version numbering when selecting the version.
The `pnpm exec nx release version --git-tag` command will update the `package*.json` files and create a new version tag.
Committing and pushing the branch will allow you to create the PR on GitHub.
The `pnpm run update-version-tags` will push the tags up to GitHub.

Then, make a PR to main. Merge the PR into main -- make sure you use "merge commit", not squash and merge, so that
the original commit where the tag was based on is still present in the main branch.

Then, create a release in the GitHub "Releases" tab, select the new tag that you have added,
and add a description of the changes in the new release. You can copy
the latest changelog entry in `CHANGELOG.md` to make the release notes, and update as necessary.

This will trigger a GitHub Actions pipeline that will build and publish all packages to npm.

The package is published through an automation token belonging to the
[rjsf-bot](https://www.npmjs.com/~rjsf-bot) user on npm. This token
is stored as the `NPM_TOKEN` secret on GitHub Actions.

### Releasing docs

Docs are automatically published to GitHub Pages when the `main` branch is updated.

We are currently in the process of automatically configuring versionable documentation on our new docs site.

### Releasing the playground

The playground automatically gets deployed from GitHub Pages.

If you need to manually publish the latest playground to [https://rjsf-team.github.io/react-jsonschema-form/](https://rjsf-team.github.io/react-jsonschema-form/), though, run:

```bash
cd packages/playground
pnpm run publish-to-gh-pages
```

### Releasing a new package

Publishing a new `@rjsf/*` package requires additional setup. The package must first be published locally, then in the NPM web app, you must set up "Trusted Publishing" so future releases can be published via GitHub Actions. The steps to accomplish this are:

1. Create the new release as described above. Existing packages will be published, but the jobs to publish new package(s) will fail.
2. Locally, check out the release tag (e.g. `git checkout v6.8.0`). You may need to `git fetch --tags`. Make sure your `git status` is clean.
3. `cd packages/new-package`
4. `pnpm login` (login to an account with RJSF publishing privileges)
5. `pnpm publish --no-git-checks`.

The new package will be released. Then, set up Trusted Publishing:

1. Navigate to the new package in NPM (e.g. `https://www.npmjs.com/package/@rjsf/new-package`)
2. Go to Settings -> Trusted Publisher -> GitHub Actions
3. Set up the fields to match an existing package (e.g. look at `@rjsf/core`).
   1. Organization or user: `rjsf-team`
   2. Repository: `react-jsonschema-form`
   3. Workflow filename: `release.yml`
   4. Allow `npm publish`

---

### Packages Docs Versioned Sidebars Version 3.2.1 Sidebars.Json (`packages/docs/versioned_sidebars/version-3.2.1-sidebars.json`)

{
  "docs": [
    {
      "type": "autogenerated",
      "dirName": "."
    }
  ]
}

---

### Packages Docs Versioned Sidebars Version 4.2.3 Sidebars.Json (`packages/docs/versioned_sidebars/version-4.2.3-sidebars.json`)

{
  "docs": [
    {
      "type": "autogenerated",
      "dirName": "."
    }
  ]
}

---

### Packages Docs Versioned Sidebars Version 5.24.10 Sidebars.Json (`packages/docs/versioned_sidebars/version-5.24.10-sidebars.json`)

{
  "docs": [
    {
      "type": "autogenerated",
      "dirName": "."
    }
  ]
}

---

### Packages Docs Docs Advanced Customization Custom Templates (`packages/docs/docs/advanced-customization/custom-templates.md`)

# Custom Templates

This is an advanced feature that lets you customize even more aspects of the form:

|                       | Custom Field                              | Custom Template                                                | Custom Widget                                                             |
| --------------------- | ----------------------------------------- | -------------------------------------------------------------- | ------------------------------------------------------------------------- |
| **What it does**      | Overrides all behaviour                   | Overrides just the layout (not behaviour)                      | Overrides just the input box (not layout, labels, or help, or validation) |
| **Usage**             | Global or per-field                       | Global or per-field                                            | Global or per-field                                                       |
| **Global Example**    | `<Form fields={{ MyCustomField }} />`     | `<Form templates={{ ArrayFieldTemplate: MyArrayTemplate }} />` | `<Form widgets={{ MyCustomWidget }} />`                                   |
| **Per-Field Example** | `"ui:field": MyCustomField`               | `"ui:ArrayFieldTemplate": MyArrayTemplate`                     | `"ui:widget":MyCustomWidget`                                              |
| **Documentation**     | [Custom Fields](custom-widgets-fields.md) | See documentation below                                        | [Custom Widgets](custom-widgets-fields.md)                                |

In version 5, all existing `templates` were consolidated into a new `TemplatesType` interface that is provided as part of the `Registry`.
They can also be overloaded globally on the `Form` via the `templates` prop as well as globally or per-field through the `uiSchema`.
Further, many new templates were added or repurposed from existing `widgets` and `fields` in an effort to simplify the effort needed by theme authors to build new and/or maintain current themes.
These new templates can also be overridden by individual users to customize the specific needs of their application.
A special category of templates, `ButtonTemplates`, were also added to support the easy replacement of the `Submit` button on the form, the `Add` and `Remove` buttons associated with `additionalProperties` and `patternProperties` on objects and elements of arrays, as well as the `Move up` and `Move down` buttons used for reordering arrays.
This category, unlike the others, can only be overridden globally via the `templates` prop on `Form`.

Below is the table that lists all the `templates`, their props interface, their `uiSchema` name and from where they originated in the previous version of RJSF:

| Template                                                        | Props Type                         | UiSchema name                    | Origin                                                                                                                                                               |
| --------------------------------------------------------------- | ---------------------------------- | -------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [ArrayFieldTemplate](#arrayfieldtemplate)                           | ArrayFieldTemplateProps            | ui:ArrayFieldTemplate            | Formerly `Form.ArrayFieldTemplate` or `Registry.ArrayFieldTemplate`                                                                                                  |
| [ArrayFieldDescriptionTemplate](#arrayfielddescriptiontemplate)     | ArrayFieldDescriptionProps         | ui:ArrayFieldDescriptionTemplate | Formerly part of `@rjsf/core` ArrayField, refactored as a template, used in all `ArrayFieldTemplate` implementations                                                 |
| [ArrayFieldItemTemplate](#arrayfielditemtemplate)                   | ArrayFieldItemTemplateProps        | ui:ArrayFieldItemTemplate        | Formerly an internal class for `ArrayFieldTemplate`s in all themes, refactored as a template in each theme, used in all `ArrayFieldTemplate` implementations         |
| [ArrayFieldItemButtonsTemplate](#arrayfielditembuttonstemplate)     | ArrayFieldItemButtonsTemplateProps | ui:ArrayFieldItemButonsTemplate  | Formerly an internal class for `ArrayFieldItemTemplate`s in all themes, refactored as a template in the `core`, used in all `ArrayFieldItemTemplate` implementations |
| [ArrayFieldTitleTemplate](#arrayfieldtitletemplate)                 | ArrayFieldTitleProps               | ui:ArrayFieldTitleTemplate       | Formerly part of `@rjsf/core` ArrayField, refactored as a template, used in all `ArrayFieldTemplate` implementations.                                                |
| [BaseInputTemplate](#baseinputtemplate)                             | WidgetProps                        | ui:BaseInputTemplate             | Formerly a `widget` in `@rjsf.core` moved to `templates` and newly implemented in each theme to maximize code reuse.                                                 |
| [CyclicSchemaExpandTemplate](#cyclicschemaexpandtemplate)           | CyclicSchemaExpandProps            | ui:CyclicSchemaExpandTemplate    | Added in RJSF v6 to support circular `$ref` cycle detection                                                                                                          |
| [DescriptionFieldTemplate](#descriptionfieldtemplate)               | DescriptionFieldProps              | ui:DescriptionFieldTemplate      | Formerly a `field` in `@rjsf.core` moved to `templates` with the `Template` suffix. Previously implemented in each theme.                                            |
| [ErrorListTemplate](#errorlisttemplate)                             | ErrorListProps                     | ui:ErrorListTemplate             | Formerly `Form.ErrorList` moved to `templates` with the `Templates` suffix. Previously implemented in each theme.                                                    |
| [FallbackFieldTemplate](#fallbackfieldtemplate)                     | FallbackFieldTemplateProps         | ui:FallbackFieldTemplate         | Added in RJSF v6                                                                                                                                                     |
| [FieldErrorTemplate](#fielderrortemplate)                       | FieldErrorProps                    | ui:FieldErrorTemplate            | Formerly internal `ErrorList` component accessible only to `SchemaField`                                                                                             |
| [FieldHelpTemplate](#fieldhelptemplate)                         | FieldHelpProps                     | ui:FieldHelpTemplate             | Formerly internal `Help` component accessible only to `SchemaField`                                                                                                  |
| [FieldTemplate](#fieldtemplate)                                 | FieldTemplateProps                 | ui:FieldTemplate                 | Formerly `Form.FieldTemplate` or `Registry.FieldTemplate`                                                                                                            |
| [GridTemplate](#gridtemplate)                                   | GridTemplateProps                  | ui:GridTemplate                  | Theme dependent implementations of a Grid element for either rows or columns                                                                                         |
| [MultiSchemaFieldTemplate](#multischemafieldtemplate)           | MultiSchemaFieldTemplateProps      | ui:MultiSchemaFieldTemplate      | Formerly part of `@rjsf/core `MultiSchemaField`, refactored as a template                                                                                            |
| [ObjectFieldTemplate](#objectfieldtemplate)                     | ObjectFieldTemplateProps           | ui:ObjectFieldTemplate           | Formerly `Form.ObjectFieldTemplate` or `Registry.ObjectFieldTemplate`                                                                                                |
| [OptionalDataControlsTemplate](#optionaldatacontrolstemplate)   | OptionalDataControlsTemplateProps  | ui:OptionalDataControlsTemplate  | New feature in V6                                                                                                                                                    |
| [TitleFieldTemplate](#titlefieldtemplate)                       | TitleFieldProps                    | ui:TitleFieldTemplate            | Formerly a `field` in `@rjsf.core` moved to `templates` with the `Template` suffix. Previously implemented in each theme.                                            |
| [UnsupportedFieldTemplate](#unsupportedfieldtemplate)           | UnsupportedFieldProps              | ui:UnsupportedFieldTemplate      | Formerly a `field` in `@rjsf.core` moved to `templates` with the `Template` suffix.                                                                                  |
| [WrapIfAdditionalTemplate](#wrapifadditionaltemplate)           | WrapIfAdditionalTemplateProps      | ui:WrapIfAdditionalTemplate      | Formerly an internal component in `@rjsf.core`. Previously implemented in most themes.                                                                               |
| [ButtonTemplates.AddButton](#addbutton)                         | IconButtonProps                    | n/a                              | Formerly an internal implementation in each theme                                                                                                                    |
| [ButtonTemplates.MoveDownButton](#movedownbutton)               | IconButtonProps                    | n/a                              | Formerly an internal implementation in each theme                                                                                                                    |
| [ButtonTemplates.MoveUpButton](#moveupbutton)                   | IconButtonProps                    | n/a                              | Formerly an internal implementation in each theme                                                                                                                    |
| [ButtonTemplates.RemoveButton](#removebutton)                   | IconButtonProps                    | n/a                              | Formerly an internal implementation in each theme                                                                                                                    |
| [ButtonTemplates.SubmitButton](#submitbutton)                   | SubmitButtonProps                  | n/a                              | Formerly a `field` in each theme move to `templates.ButtonTemplates`                                                                                                 |

## ArrayFieldTemplate

You can use an `ArrayFieldTemplate` to customize how your arrays are rendered.
This allows you to customize your array, and each element in the array.
If you only want to customize how the array's title, description or how the array items are presented, you may want to consider providing your own [ArrayFieldDescriptionTemplate](#arrayfielddescriptiontemplate), [ArrayFieldItemTemplate](#arrayfielditemtemplate) and/or [ArrayFieldTitleTemplate](#arrayfieldtitletemplate) instead.
You can also customize arrays by specifying a widget in the relevant `ui:widget` schema, more details over on [Custom Widgets](../json-schema/arrays.md#custom-widgets).

```tsx
import { ArrayFieldTemplateProps, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

function ArrayFieldTemplate(props: ArrayFieldTemplateProps) {
  return (
    <div>
      {props.items.map((element) => element.children)}
      {props.canAdd && <button type='button' onClick={props.onAddClick}></button>}
    </div>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ArrayFieldTemplate }} />,
  document.getElementById('app'),
);
```

You also can provide your own field template to a uiSchema by specifying a `ui:ArrayFieldTemplate` property with your Component :

```tsx
import { UiSchema } from '@rjsf/utils';
import ArrayFieldTemplate from './ArrayFieldTemplate';

const uiSchema: UiSchema = {
  'ui:ArrayFieldTemplate': ArrayFieldTemplate,
};
```

or a string value from the `Registry` :

```tsx
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:ArrayFieldTemplate': 'CustomArrayFieldTemplate',
};
```

Please see the [customArray.tsx sample](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/playground/src/samples/customArray.tsx) from the [playground](https://rjsf-team.github.io/react-jsonschema-form/) for another example.

The following props are passed to each `ArrayFieldTemplate`:

- `canAdd`: A boolean value stating whether new elements can be added to the array.
- `className`: The className string.
- `disabled`: A boolean value stating if the array is disabled.
- `fieldPathId`: An object containing the id for this object & ids for its properties.
- `items`: An array of React nodes representing the items in the array.
- `onAddClick: (event?) => void`: A function that adds a new item to the end of the array.
- `readonly`: A boolean value stating if the array is read-only.
- `required`: A boolean value stating if the array is required.
- `hideError`: A boolean value stating if the field is hiding its errors.
- `schema`: The schema object for this array.
- `uiSchema`: The uiSchema object for this array field.
- `title`: A string value containing the title for the array.
- `formData`: The formData for this array.
- `errorSchema`: The optional validation errors for the array field and the items within it, in the form of an `ErrorSchema`
- `rawErrors`: An array of strings listing all generated error messages from encountered errors for this widget
- `registry`: The `registry` object.

> Note: Array and object field templates are always rendered inside the FieldTemplate. To fully customize an array field template, you may need to specify both `ui:FieldTemplate` and `ui:ArrayFieldTemplate`.

## ArrayFieldDescriptionTemplate

The out-of-the-box version of this template will render the `DescriptionFieldTemplate` with a generated id, if there is a `description` otherwise nothing is rendered.
If you want different behavior for the rendering of the description of an array field, you can customize this template.
If you want a different behavior for the rendering of ALL descriptions in the `Form`, see [DescriptionFieldTemplate](#descriptionfieldtemplate)

```tsx
import { ArrayFieldDescriptionProps, RJSFSchema, descriptionId } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

function ArrayFieldDescriptionTemplate(props: ArrayFieldDescriptionProps) {
  const { description, fieldPathId } = props;
  const id = descriptionId(fieldPathId);
  return (
    <details id={id}>
      <summary>Description</summary>
      {description}
    </details>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ArrayFieldDescriptionTemplate }} />,
  document.getElementById('app'),
);
```

You also can provide your own field template to a uiSchema by specifying a `ui:ArrayFieldDescriptionTemplate` property with your Component :

```tsx
import { UiSchema } from '@rjsf/utils';
import ArrayFieldDescriptionTemplate from './ArrayFieldDescriptionTemplate';

const uiSchema: UiSchema = {
  'ui:ArrayFieldDescriptionTemplate': ArrayFieldDescriptionTemplate,
};
```

or a string value from the `Registry` :

```tsx
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:ArrayFieldDescriptionTemplate': 'CustomArrayFieldDescriptionTemplate',
};
```

The following props are passed to each `ArrayFieldDescriptionTemplate`:

- `description`: The description of the array field being rendered.
- `fieldPathId`: The FieldPathId of the field in the hierarchy
- `schema`: The schema object for this array field.
- `uiSchema`: The uiSchema object for this array field.
- `registry`: The `registry` object.

## ArrayFieldItemTemplate

The `ArrayFieldItemTemplate` is used to render the representation of a single item in an array.
All of the `ArrayFieldTemplate` implementations in all themes get this template from the `registry` in order to render array fields items.
Each theme has an implementation of the `ArrayFieldItemTemplate` to render an array field item in a manner best suited to the theme.
If you want to change how an array field item is rendered you can customize this template (for instance to remove the buttons rendered by `ArrayFieldItemButtonsTemplate`).

```tsx
import { ArrayFieldItemTemplateProps, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

function ArrayFieldItemTemplate(props: ArrayFieldItemTemplateProps) {
  const { children, className } = props;
  return <div className={className}>{children}</div>;
}

render(
  <Form schema={schema} validator={validator} templates={{ ArrayFieldItemTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to each `ArrayFieldItemTemplate`:

- `children`: The html for the item's content.
- `buttonsProps`: The props to pass to the `ArrayFieldItemButtonTemplate`.
- `className`: The className string.
- `disabled`: A boolean value stating if the array item is disabled.
- `hasToolbar`: A boolean value stating whether the array item has a toolbar.
- `index`: A number stating the index the array item occurs in `items`.
- `totalItems`: A number stating the total number `items` in the array.
- `itemKey`: A stable, unique key for the array item.
- `readonly`: A boolean value stating if the array item is read-only.
- `schema`: The schema object for this array item.
- `uiSchema`: The uiSchema object for this array item.
- `registry`: The `registry` object.
- `parentUiSchema`: The UI schema of the array item's parent array field, used for customization in some themes

## ArrayFieldItemButtonTemplate

The `ArrayFieldItemButtonTemplate` is used to render the representation of the buttons used for copying, moving and deleting an item in an array.
All of the `ArrayFieldItemTemplate` implementations in all themes get this template from the `registry` in order to render array fields items' buttons.
Currently, only the `core` them has an implementation of this template as the button rendering is identical across all themes.
If you want to change how an array field item's buttons are rendered you can customize this template (for instance to remove the move up/down and remove buttons).

```tsx
import { useMemo } from 'react';
import { ArrayFieldTemplateItemButtonsType, buttonId, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

function ArrayFieldItemButtonsTemplate(props: ArrayFieldTemplateItemButtonsType) {
  const { disabled, readonly, hasCopy, fieldPathId, index, onCopyIndexClick, registry, uiSchema } = props;
  const { CopyButton } = registry.templates.ButtonTemplates;
  const onCopyClick = useMemo(() => onCopyIndexClick(index), [index, onCopyIndexClick]);
  if (!hasCopy) {
    return undefined;
  }
  return (
    <CopyButton
      id={buttonId(fieldPathId, 'copy')}
      className='array-item-copy'
      disabled={disabled || readonly}
      onClick={onCopyClick}
      uiSchema={uiSchema}
      registry={registry}
    />
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ArrayFieldItemButtonsTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to each `ArrayFieldItemButtonsTemplate`:

- `className`: The className string.
- `disabled`: A boolean value stating if the array item is disabled.
- `canAdd`: A boolean value stating whether new elements can be added to the array.
- `hasCopy`: A boolean value stating whether the array item can be copied.
- `hasMoveDown`: A boolean value stating whether the array item can be moved down.
- `hasMoveUp`: A boolean value stating whether the array item can be moved up.
- `hasRemove`: A boolean value stating whether the array item can be removed.
- `fieldPathId`: The FieldPathId of the field in the hierarchy.
- `index`: A number stating the index the array item occurs in `items`.
- `totalItems`: A number stating the total number `items` in the array.
- `onAddItem: event?) => void`: Callback function that adds a new item below this item.
- `onCopyItem: (event?) => void`: Callback function that copies this item below itself.
- `onRemoveItem: (event?) => void`: Callback function that removes the item from the list.
- `onMoveUpItem: (event?) => void`: Callback function that moves the item up one spot in the list
- `onMoveDownItem: (event?) => void`: Callback function that moves the item down one spot in the list
- `readonly`: A boolean value stating if the array item is read-only.
- `schema`: The schema object for this array item.
- `style`: The optional style to pass to all of the buttons
- `uiSchema`: The uiSchema object for this array item.
- `registry`: The `registry` object.

## ArrayFieldTitleTemplate

The out-of-the-box version of this template will render the `TitleFieldTemplate` with a generated id, if there is a `title` otherwise nothing is rendered.
If you want a different behavior for the rendering of the title of an array field, you can customize this template.
If you want a different behavior for the rendering of ALL titles in the `Form`, see [TitleFieldTemplate](#titlefieldtemplate)

```tsx
import { ArrayFieldTitleTemplateProps, RJSFSchema, titleId } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

function ArrayFieldTitleTemplate(props: ArrayFieldTitleProps) {
  const { title, fieldPathId } = props;
  const id = titleId(fieldPathId);
  return <h1 id={id}>{title}</h1>;
}

render(
  <Form schema={schema} validator={validator} templates={{ ArrayFieldTitleTemplate }} />,
  document.getElementById('app'),
);
```

You also can provide your own template to a uiSchema by specifying a `ui:ArrayFieldDescriptionTemplate` property with your Component :

```tsx
import { UiSchema } from '@rjsf/utils';
import ArrayFieldDescriptionTemplate from './ArrayFieldDescriptionTemplate';

const uiSchema: UiSchema = {
  'ui:ArrayFieldDescriptionTemplate': ArrayFieldDescriptionTemplate,
};
```

or a string value from the `Registry` :

```tsx
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:ArrayFieldDescriptionTemplate': 'CustomArrayFieldDescriptionTemplate',
};
```

The following props are passed to each `ArrayFieldTitleTemplate`:

- `title`: The title of the array field being rendered.
- `fieldPathId`: The FieldPathId of the field in the hierarchy.
- `schema`: The schema object for this array field.
- `uiSchema`: The uiSchema object for this array field.
- `required`: A boolean value stating if the field is required
- `registry`: The `registry` object.

## BaseInputTemplate

The `BaseInputTemplate` is the template to use to render the basic `<input>` component for a theme.
It is used as the template for rendering many of the `<input>` based widgets that differ by `type` and callbacks only.
For example, the `TextWidget` implementation in `core` is simply a wrapper around `BaseInputTemplate` that it gets from the `registry`.
Additionally, each theme implements its own version of `BaseInputTemplate` without needing to provide a different implementation of `TextWidget`.

If you desire a different implementation for the `<input>` based widgets, you can customize this template.
For instance, say you have a `CustomTextInput` component that you want to integrate:

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Wrapping BaseInputTemplate to customize it

Sometimes you just need to pass some additional properties to the existing `BaseInputTemplate`.
The way to do this varies based upon whether you are using `core` or some other theme (such as `mui`):

```tsx
import { BaseInputTemplateProps } from '@rjsf/utils';
import { getDefaultRegistry } from '@rjsf/core';
import { Templates } from '@rjsf/mui';

const {
  templates: { BaseInputTemplate },
} = getDefaultRegistry(); // To get templates from core
// const { BaseInputTemplate } = Templates; // To get templates from a theme do this

function MyBaseInputTemplate(props: BaseInputTemplateProps) {
  const customProps = {};
  // get your custom props from where you need to
  return <BaseInputTemplate {...props} {...customProps} />;
}
```

The following props are passed to the `BaseInputTemplate`:

- `id`: The generated id for this widget;
- `schema`: The JSONSchema subschema object for this widget;
- `uiSchema`: The uiSchema for this widget;
- `value`: The current value for this widget;
- `placeholder`: The placeholder for the widget, if any;
- `required`: The required status of this widget;
- `disabled`: A boolean value stating if the widget is disabled;
- `hideError`: A boolean value stating if the widget is hiding its errors.
- `readonly`: A boolean value stating if the widget is read-only;
- `autofocus`: A boolean value stating if the widget should autofocus;
- `label`: The computed label for this widget, as a string
- `multiple`: A boolean value stating if the widget can accept multiple values;
- `onChange`: The value change event handler; call it with the new value every time it changes;
- `onChangeOverride`: A `BaseInputTemplate` implements a default `onChange` handler that it passes to the HTML input component to handle the `ChangeEvent`. Sometimes a widget may need to handle the `ChangeEvent` using custom logic. If that is the case, that widget should provide its own handler via this prop;
- `onKeyChange`: The key change event handler (only called for fields with `additionalProperties` and `patternProperties`); pass the new value every time it changes;
- `onBlur`: The input blur event handler; call it with the widget id and value;
- `onFocus`: The input focus event handler; call it with the widget id and value;
- `options`: A map of options passed as a prop to the component (see [Custom widget options](./custom-widgets-fields.md#custom-widget-options)).
- `options.enumOptions`: For enum fields, this property contains the list of options for the enum as an array of \{ label, value } objects. If the enum is defined using the oneOf/anyOf syntax, the entire schema object for each option is appended onto the \{ schema, label, value } object.
- `rawErrors`: An array of strings listing all generated error messages from encountered errors for this widget.
- `registry`: The `registry` object

## CyclicSchemaExpandTemplate

The `CyclicSchemaExpandTemplate` is the template rendered by `CyclicSchemaField` when a circular `$ref` cycle is detected in the schema.
RJSF automatically detects when a `$ref` would recurse indefinitely (e.g. a schema whose property references its own root) and stops rendering at the cycle boundary.
At that point `CyclicSchemaField` renders this template, which shows a warning message and an expand button that the user can click to render one additional level of the recursive structure.

Each theme provides its own implementation.
You can replace the template globally via the `templates` prop on `Form`, or per-field via `ui:CyclicSchemaExpandTemplate` in the `uiSchema`.

```tsx
import { CyclicSchemaExpandProps, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

// A schema that is self-referencing
const schema: RJSFSchema = {
  $schema: 'http://json-schema.org/draft-07/schema#',
  type: 'object',
  title: 'Node',
  properties: {
    value: { type: 'string' },
    child: { $ref: '#' },
  },
};

function CyclicSchemaExpandTemplate<T = any>(props: CyclicSchemaExpandProps<T>) {
  const { name, fieldPathId, onExpand } = props;
  const buttonId = `${fieldPathId.$id}-button`;
  return (
    <div className='cyclic-expand'>
      <span className='warning'>Circular reference detected for field &quot;{name}&quot;</span>
      <button id={buttonId} type='button' onClick={() => onExpand(fieldPathId.$id)}>
        Expand
      </button>
    </div>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ CyclicSchemaExpandTemplate }} />,
  document.getElementById('app'),
);
```

You can also provide a per-field template via `uiSchema`:

```tsx
import { UiSchema } from '@rjsf/utils';
import CyclicSchemaExpandTemplate from './CyclicSchemaExpandTemplate';

const uiSchema: UiSchema = {
  'ui:CyclicSchemaExpandTemplate': CyclicSchemaExpandTemplate,
};
```

or a string value from the `Registry`:

```tsx
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:CyclicSchemaExpandTemplate': 'CustomCyclicSchemaExpandTemplate',
};
```

The following props are passed to the `CyclicSchemaExpandTemplate` as defined by `CyclicSchemaExpandProps` in `@rjsf/utils`:

- `name`: The unique name of the field at the cycle boundary, usually the property name within its parent object.
- `fieldPathId`: The `FieldPathId` of the field in the hierarchy; use `fieldPathId.$id` to get the HTML id string.
- `onExpand`: Callback to call when the user wants to render one additional level; receives the field's id string.
- `schema`: The schema object for the field at the cycle boundary.
- `uiSchema`: The uiSchema object for this field.
- `registry`: The `registry` object.

## DescriptionFieldTemplate

Each theme implements a `DescriptionFieldTemplate` used to render the description of a field.
If you want to customize how descriptions are rendered you can.

```tsx
import { DescriptionFieldProps, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
  title: 'My input',
  description: 'input description',
};

function DescriptionFieldTemplate(props: DescriptionFieldProps) {
  const { description, id } = props;
  return (
    <details id={id}>
      <summary>Description</summary>
      {description}
    </details>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ DescriptionFieldTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to the `DescriptionFieldTemplate`:

- `description`: The description of the field being rendered.
- `id`: The id of the field in the hierarchy.
- `schema`: The schema object for the field.
- `uiSchema`: The uiSchema object for the field.
- `registry`: The `registry` object.

## ErrorListTemplate

The `ErrorListTemplate` is the template that renders the all the errors associated with the fields in the `Form`, at the top.
Each theme implements a `ErrorListTemplate` used to render its errors using components for the theme's toolkit.
If you want to customize how all the errors are rendered you can.

```tsx
import { ErrorListProps, RJSFValidationError, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
  title: 'My input',
  description: 'input description',
};

function ErrorListTemplate(props: ErrorListProps) {
  const { errors } = props;
  return (
    <details id={id}>
      <summary>Errors</summary>
      <ul>
        {errors.map((error: RJSFValidationError, i: number) => {
          return (
            <li key={i} className='error'>
              {error.stack}
            </li>
          );
        })}
      </ul>
    </details>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ErrorListTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to the `ErrorListTemplate`:

- `schema`: The schema that was passed to `Form`
- `uiSchema`: The uiSchema that was passed to `Form`
- `errors`: An array of all errors in this `Form`.
- `errorSchema`: The `ErrorSchema` constructed by `Form`

## FallbackFieldTemplate

The `FallbackFieldTemplate` is the template that renders opt-in fallback UI to control fields of unknown or unhandled types. Usage of this feature is controlled by the [`useFallbackUiForUnsupportedType` Form prop](../api-reference/form-props.md#usefallbackuiforunsupportedtype).

```tsx
import { FallbackFieldTemplateProps, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'unknownType',
  title: 'My input',
};

function FallbackFieldTemplate(props: FallbackFieldTemplateProps) {
  const { typeSelector, schemaField } = props;
  return (
    <div className={'row'}>
      <div className={'col-xs-4'}>{typeSelector}</div>
      <div className={'col-xs-8'}>{schemaField}</div>
    </div>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ FallbackFieldTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to the `FallbackFieldTemplate`:

- `schema`: The schema for the field
- `uiSchema`: The uiSchema for the field
- `registry`: The `Registry` object
  1

## FieldErrorTemplate

The `FieldErrorTemplate` is the template that renders all the errors associated a single field.
If you want to customize how the errors are rendered you can.

```tsx
import { FieldErrorProps, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
  title: 'My input',
  description: 'input description',
};

function FieldErrorTemplate(props: FieldErrorProps) {
  const { errors } = props;
  return (
    <details id={id}>
      <summary>Errors</summary>
      <ul>
        {errors.map((error: string, i: number) => {
          return (
            <li key={i} className='error'>
              {error.stack}
            </li>
          );
        })}
      </ul>
    </details>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ FieldErrorTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to the `FieldErrorTemplate`:

- `schema`: The schema for the field
- `uiSchema`: The uiSchema for the field
- `fieldPathId`: The FieldPathId of the field in the hierarchy
- `errors`: An array of all errors for this field
- `errorSchema`: The `ErrorSchema` for this field
- `registry`: The `Registry` object

## FieldHelpTemplate

The `FieldHelpTemplate` is the template that renders the help associated a single field.
If you want to customize how the help is rendered you can.

```tsx
import { FieldHelpProps, RJSFSchema, helpId } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
  title: 'My input',
  description: 'input description',
};

function FieldHelpTemplate(props: FieldHelpProps) {
  const { help, fieldPathId } = props;
  const id = helpId(fieldPathId);
  return <aside id={id}>{help}</aside>;
}

render(
  <Form schema={schema} validator={validator} templates={{ FieldHelpTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to the `FieldHelpTemplate`:

- `schema`: The schema for the field
- `uiSchema`: The uiSchema for the field
- `fieldPathId`: The FieldPathId of the field in the hierarchy
- `help`: The help information to be rendered
- `registry`: The `Registry` object

## FieldTemplate

To take control over the inner organization of each field (each form row), you can define a _field template_ for your form.

A field template is basically a React stateless component being passed field-related props, allowing you to structure your form row as you like.

```tsx
import { FieldTemplateProps, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

function CustomFieldTemplate(props: FieldTemplateProps) {
  const { id, classNames, style, label, help, required, description, errors, children } = props;
  return (
    <div className={classNames} style={style}>
      <label htmlFor={id}>
        {label}
        {required ? '*' : null}
      </label>
      {description}
      {children}
      {errors}
      {help}
    </div>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ FieldTemplate: CustomFieldTemplate }} />,
  document.getElementById('app'),
);
```

You also can provide your own field template to a uiSchema by specifying a `ui:FieldTemplate` property with your Component :

```tsx
import { UiSchema } from '@rjsf/utils';
import CustomFieldTemplate from './CustomFieldTemplate';

const uiSchema: UiSchema = {
  'ui:FieldTemplate': CustomFieldTemplate,
};
```

or a string value from the `Registry` :

```tsx
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:FieldTemplate': 'CustomFieldTemplate',
};
```

If you want to handle the rendering of each element yourself, you can use the props `rawHelp`, `rawDescription` and `rawErrors`.

The following props are passed to a custom field template component:

- `id`: The id of the field in the hierarchy. You can use it to render a label targeting the wrapped widget.
- `classNames`: A string containing the base Bootstrap CSS classes, merged with any [custom ones](../api-reference/uiSchema.md#classnames) defined in your uiSchema.
- `style`: An object containing the `StyleHTMLAttributes` defined in the `uiSchema`.
- `label`: The computed label for this field, as a string.
- `description`: A component instance rendering the field description, if one is defined (this will use any [custom `DescriptionFieldTemplate`](#descriptionfieldtemplate) defined in the `templates` passed to the `Form`).
- `rawDescription`: A string containing any `ui:description` uiSchema directive defined.
- `children`: The field or widget component instance for this field row.
- `errors`: A component instance listing any encountered errors for this field.
- `rawErrors`: An array of strings listing all generated error messages from encountered errors for this field.
- `help`: A component instance rendering any `ui:help` uiSchema directive defined.
- `rawHelp`: A string containing any `ui:help` uiSchema directive defined. **NOTE:** `rawHelp` will be `undefined` if passed `ui:help` is a React component instead of a string.
- `hidden`: A boolean value stating if the field should be hidden.
- `required`: A boolean value stating if the field is required.
- `readonly`: A boolean value stating if the field is read-only.
- `hideError`: A boolean value stating if the field is hiding its errors
- `disabled`: A boolean value stating if the field is disabled.
- `displayLabel`: A boolean value stating if the label should be rendered or not. This is useful for nested fields in arrays where you don't want to clutter the UI.
- `schema`: The schema object for this field.
- `uiSchema`: The uiSchema object for this field.
- `onChange`: The value change event handler; Can be called with a new value to change the value for this field.
- `formData`: The formData for this field.
- `registry`: The `registry` object.

> Note: you can only define a single global field template for a form, but you can set individual field templates per property using `"ui:FieldTemplate"`.

## GridTemplate

The `GridTemplate` is the template that renders a theme dependent Grid for either a row or column.
While it has only two explicit properties, it extends the `GenericObjectTemplate` in order to support passing any of the properties associated with a Grid implementation for any theme.
If you want to customize how grids are rendered you can.

```tsx
import { Grid2 } from '@mui/material';
import { GridTemplateProps } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';
import classNames from 'classnames';

const schema: RJSFSchema = {
  type: 'string',
  title: 'My input',
  description: 'input description',
};

function GridTemplate(props: FieldHelpProps) {
  const { children, column, className, ...rest } = props;
  return (
    <Grid2 item={column} {...rest} className={`${className} my-custom-grid-styling`}>
      {children}
    </Grid2>
  );
}

render(<Form schema={schema} validator={validator} templates={{ GridTemplate }} />, document.getElementById('app'));
```

The following props are passed to the `GridTemplate`:

- `children`: The contents of the grid template
- `column`: Optional flag indicating whether the grid element represents a column, necessary for themes which have components for Rows vs Column

## MultiSchemaFieldTemplate

Each theme implements a `MultiSchemaFieldTemplate` used to render the layout of a MultiSchemaField, i.e. a field described by a `oneOf` or `anyOf` schema.
The template typically renders a Widget used to select the schema to use, as well as a field for the selected schema.

```tsx
import { MultiSchemaFieldTemplateProps, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    myField: {
      oneOf: [
        {
          type: 'string',
          title: 'String Field',
          description: 'A field that accepts a string',
        },
        {
          type: 'number',
          title: 'Number Field',
          description: 'A field that accepts a number',
        },
      ],
    },
  },
};

function MultiSchemaFieldTemplate(props: MultiSchemaFieldTemplateProps) {
  const { selector, optionSchemaField } = props;
  return (
    <div className='my-multi-schema-field-class'>
      {selector}
      <hr />
      {optionSchemaField}
    </div>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ MultiSchemaFieldTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to the `MultiSchemaFieldTemplate`:

- `selector`: The rendered Widget used to select a multischema option.
- `optionSchemaField`: The rendered SchemaField representing the selected option.
- `schema`: The schema object for the field.
- `uiSchema`: The uiSchema object for the field.
- `registry`: The `registry` object.

## ObjectFieldTemplate

```tsx
import { ObjectFieldTemplateProps, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  title: 'Object title',
  description: 'Object description',
  properties: {
    name: {
      type: 'string',
    },
    age: {
      type: 'number',
    },
  },
};

function ObjectFieldTemplate(props: ObjectFieldTemplateProps) {
  return (
    <div>
      {props.title}
      {props.description}
      {props.properties.map((element) => (
        <div className='property-wrapper'>{element.content}</div>
      ))}
    </div>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ObjectFieldTemplate }} />,
  document.getElementById('app'),
);
```

You also can provide your own field template to a uiSchema by specifying a `ui:ObjectFieldTemplate` property with your Component :

```tsx
import { UiSchema } from '@rjsf/utils';
import ObjectFieldTemplate from './ObjectFieldTemplate';

const uiSchema: UiSchema = {
  'ui:ObjectFieldTemplate': ObjectFieldTemplate,
};
```

or a string value from the `Registry` :

```tsx
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:ObjectFieldTemplate': 'ObjectFieldTemplate',
};
```

Please see the [customObject.tsx sample](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/playground/src/samples/customObject.tsx) from the [playground](https://rjsf-team.github.io/react-jsonschema-form/) for a better example.

The following props are passed to each `ObjectFieldTemplate` as defined by the `ObjectFieldTemplateProps` in `@rjsf/utils`:

- `title`: A string value containing the title for the object.
- `description`: A string value containing the description for the object.
- `disabled`: A boolean value stating if the object is disabled.
- `properties`: An array of object representing the properties in the object. Each of the properties represent a child with properties described below.
- `onAddProperty: () => void`: Callback to use in order to add an new additionalProperty to the object field (to be used with additionalProperties and patternProperties)
- `readonly`: A boolean value stating if the object is read-only.
- `required`: A boolean value stating if the object is required.
- `hideError`: A boolean value stating if the field is hiding its errors.
- `schema`: The schema object for this object.
- `uiSchema`: The uiSchema object for this object field.
- `fieldPathId`: The FieldPathId of the field in the hierarchy
- `errorSchema`: The optional validation errors in the form of an `ErrorSchema`
- `formData`: The form data for the object.
- `registry`: The `registry` object.

The following props are part of each element in `properties`:

- `content`: The html for the property's content.
- `name`: A string representing the property name.
- `disabled`: A boolean value stating if the object property is disabled.
- `readonly`: A boolean value stating if the property is read-only.
- `hidden`: A boolean value stating if the property should be hidden.

> Note: Array and object field templates are always rendered inside the FieldTemplate. To fully customize an object field template, you may need to specify both `ui:FieldTemplate` and `ui:ObjectFieldTemplate`.

## OptionalDataControlsTemplate

Each theme implements a `OptionalDataControlsTemplate` used to render the `Optional Data Controls` when that feature has been enabled

```
/* Detailed source-code truncated for AI context efficiency. */
```

The following props are passed to each `OptionalDataControlsTemplate` as defined by the `OptionalDataControlsTemplateProps` in `@rjsf/utils`:

- `id`: The generated id for this Optional Data Control instance.
- `label`: The label to use for the Optional Data Control
- `onAddClick`: Optional callback to call when clicking on the Optional Data Control to add data
- `onRemoveClick`: Optional callback to call when clicking on the Optional Data Control to remove data
- `schema`: The schema object for this object.
- `uiSchema`: The uiSchema object for this object field.
- `registry`: The `registry` object.

## TitleFieldTemplate

Each theme implements a `TitleFieldTemplate` used to render the title of a field.
If you want to customize how titles are rendered you can.

```tsx
import { RJSFSchema, TitleFieldProps } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
  title: 'My input',
  description: 'input description',
};

function TitleFieldTemplate(props: TitleFieldProps) {
  const { id, required, title } = props;
  return (
    <header id={id}>
      {title}
      {required && <mark>*</mark>}
    </header>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ TitleFieldTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to each `TitleFieldTemplate`:

- `id`: The id of the field in the hierarchy.
- `title`: The title of the field being rendered.
- `schema`: The schema object for the field.
- `uiSchema`: The uiSchema object for the field.
- `required`: A boolean value stating if the field is required
- `registry`: The `registry` object.

## UnsupportedFieldTemplate

The `UnsupportedField` component is used to render a field in the schema is one that is not supported by react-jsonschema-form.
If you want to customize how an unsupported field is rendered (perhaps for localization purposes) you can.

```tsx
import { RJSFSchema, UnsupportedFieldProps } from '@rjsf/utils';
import { FormattedMessage } from 'react-intl';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'invalid',
};

function UnsupportedFieldTemplate(props: UnsupportedFieldProps) {
  const { schema, reason } = props;
  return (
    <div>
      <FormattedMessage defaultMessage='Unsupported field schema, reason = {reason}' value={{ reason }} />
      <pre>{JSON.stringify(schema, null, 2)}</pre>
    </div>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ UnsupportedFieldTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to each `UnsupportedFieldTemplate`:

- `schema`: The schema object for this unsupported field.
- `fieldPathId`: The FieldPathId of the field in the hierarchy
- `reason`: The reason why the schema field has an unsupported type.
- `registry`: The `registry` object.

## WrapIfAdditionalTemplate

The `WrapIfAdditionalTemplate` is used by the `FieldTemplate` to conditionally render additional controls if `additionalProperties` or `patternProperties` are present in the schema.
You may customize `WrapIfAdditionalTemplate` if you wish to change the layout or behavior of user-controlled `additionalProperties` and `patternProperties`.

```tsx
import { RJSFSchema, WrapIfAdditionalTemplateProps } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  additionalProperties: true,
};

function WrapIfAdditionalTemplate(props: WrapIfAdditionalTemplateProps) {
  const {
    id,
    label,
    onKeyRename,
    onKeyRenameBlur,
    onRemoveProperty,
    schema,
    children,
    uiSchema,
    registry,
    classNames,
    style,
  } = props;
  const { RemoveButton } = registry.templates.ButtonTemplates;
  const additional = ADDITIONAL_PROPERTY_FLAG in schema;

  if (!additional) {
    return <div>{children}</div>;
  }

  return (
    <div className={classNames} style={style}>
      <label label={keyLabel} id={`${id}-key`}>
        Custom Field Key
      </label>
      <input className='form-control' type='text' id={`${id}-key`} onBlur={onKeyRenameBlur} defaultValue={label} />
      <div>{children}</div>
      <RemoveButton onClick={onRemoveProperty} uiSchema={uiSchema} />
    </div>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ WrapIfAdditionalTemplate }} />,
  document.getElementById('app'),
);
```

The following props are passed to the `WrapIfAdditionalTemplate`:

- `children`: The children of the component, typically specified by the `FieldTemplate`.

- `id`: The id of the field in the hierarchy. You can use it to render a label targeting the wrapped widget.
- `classNames`: A string containing the base Bootstrap CSS classes, merged with any [custom ones](../api-reference/uiSchema.md#classnames) defined in your uiSchema.
- `style`: An object containing the `StyleHTMLAttributes` defined in the `uiSchema`.
- `label`: The computed label for this field, as a string.
- `required`: A boolean value stating if the field is required.
- `readonly`: A boolean value stating if the field is read-only.
- `disabled`: A boolean value stating if the field is disabled.
- `schema`: The schema object for this field.
- `uiSchema`: The uiSchema object for this field.
- `onKeyRename`: Callback used to handle the changing of an additional property key's name with the new value
- `onKeyRenameBlur`: Callback used to handle the changing of an additional property key's name when the input is blurred. The event's target's value will be used as the new value. Its a wrapper callback around `onKeyRename`
- `onRemoveProperty`: Callback used to handle the removal of the additionalProperty

## ButtonTemplates

There are several buttons that are potentially rendered in the `Form`.
Each of these buttons have been customized in the themes, and can be customized by you as well.
All but one of these buttons (i.e. the `SubmitButton`) are rendered currently as icons with title text for a description.

Each button template (except for the `SubmitButton`) accepts, as props, the standard [HTML button attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) along with the following:

- `iconType`: An alternative specification for the type of the icon button.
- `icon`: The name representation or actual react element implementation for the icon.
- `uiSchema`: The uiSchema object for this field.
- `registry`: The `registry` object.

### AddButton

The `AddButton` is used to render an add action on a `Form` for both a new `additionalProperties` or `patternProperties` element for an object or a new element in an array.
You can customize the `AddButton` to render something other than the icon button that is provided by a theme as follows:

```tsx
import React from 'react';
import { IconButtonProps, RJSFSchema } from '@rjsf/utils';
import { FormattedMessage } from 'react-intl';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

function AddButton(props: IconButtonProps) {
  const { icon, iconType, ...btnProps } = props;
  return (
    <button {...btnProps}>
      {icon} <FormattedMessage defaultMessage='Add' />
    </button>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ButtonTemplates: { AddButton } }} />,
  document.getElementById('app'),
);
```

### MoveDownButton

The `MoveDownButton` is used to render a move down action on a `Form` for elements in an array.
You can customize the `MoveDownButton` to render something other than the icon button that is provided by a theme as follows:

```tsx
import React from 'react';
import { IconButtonProps, RJSFSchema } from '@rjsf/utils';
import { FormattedMessage } from 'react-intl';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

function MoveDownButton(props: IconButtonProps) {
  const { icon, iconType, ...btnProps } = props;
  return (
    <button {...btnProps}>
      {icon} <FormattedMessage defaultMessage='Move Down' />
    </button>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ButtonTemplates: { MoveDownButton } }} />,
  document.getElementById('app'),
);
```

### MoveUpButton

The `MoveUpButton` is used to render a move up action on a `Form` for elements in an array.
You can customize the `MoveUpButton` to render something other than the icon button that is provided by a theme as follows:

```tsx
import React from 'react';
import { IconButtonProps, RJSFSchema } from '@rjsf/utils';
import { FormattedMessage } from 'react-intl';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

function MoveUpButton(props: IconButtonProps) {
  const { icon, iconType, ...btnProps } = props;
  return (
    <button {...btnProps}>
      {icon} <FormattedMessage defaultMessage='Move Up' />
    </button>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ButtonTemplates: { MoveUpButton } }} />,
  document.getElementById('app'),
);
```

### RemoveButton

The `RemoveButton` is used to render a remove action on a `Form` for both a existing `additionalProperties` or `patternProperties` element for an object or an existing element in an array.
You can customize the `RemoveButton` to render something other than the icon button that is provided by a theme as follows:

```tsx
import React from 'react';
import { IconButtonProps, RJSFSchema } from '@rjsf/utils';
import { FormattedMessage } from 'react-intl';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

function RemoveButton(props: IconButtonProps) {
  const { icon, iconType, ...btnProps } = props;
  return (
    <button {...btnProps}>
      {icon} <FormattedMessage defaultMessage='Remove' />
    </button>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ButtonTemplates: { RemoveButton } }} />,
  document.getElementById('app'),
);
```

### SubmitButton

The `SubmitButton` is already very customizable via the `UISchemaSubmitButtonOptions` capabilities in the `uiSchema` but it can also be fully customized as you see fit.

> NOTE: However you choose to implement this, making it something other than a `submit` type `button` may result in the `Form` not submitting when pressed.
> You could also choose to provide your own submit button as the [children prop](../api-reference/form-props.md#children) of the `Form` should you so choose.

```tsx
import React from 'react';
import { getSubmitButtonOptions, RJSFSchema, SubmitButtonProps } from '@rjsf/utils';
import { FormattedMessage } from 'react-intl';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

function SubmitButton(props: SubmitButtonProps) {
  const { uiSchema } = props;
  const { norender } = getSubmitButtonOptions(uiSchema);
  if (norender) {
    return null;
  }
  return (
    <button type='submit'>
      <FormattedMessage defaultMessage='Okay' />
    </button>
  );
}

render(
  <Form schema={schema} validator={validator} templates={{ ButtonTemplates: { SubmitButton } }} />,
  document.getElementById('app'),
);
```

The following prop is passed to a `SubmitButton`:

- `uiSchema`: The uiSchema object for this field, used to extract the `UISchemaSubmitButtonOptions`.
- `registry`: The `registry` object.

## Custom Templates

You can now add custom components to the registry and reference them in your `uiSchema` using string keys.

### Adding Custom Templates to the Registry

```tsx
import CustomArrayFieldTemplate from './CustomArrayFieldTemplate';
import { UiSchema } from '@rjsf/utils';

// Add the custom template to the registry
const registry = { templates: { CustomArrayFieldTemplate } };

// Use the custom template in the uiSchema
const uiSchema: UiSchema = { 'ui:ArrayFieldTemplate': 'CustomArrayFieldTemplate' };
```

---

### Packages Docs Docs Advanced Customization Custom Themes (`packages/docs/docs/advanced-customization/custom-themes.md`)

# Custom Themes

The `withTheme` component provides an easy way to extend the functionality of react-jsonschema-form by passing in a theme object that defines custom/overridden widgets and fields, as well as any of the other possible properties of the standard rjsf `Form` component.
This theme-defining object is passed as the only parameter to the HOC (`withTheme(ThemeObj)`), and the HOC will return a themed-component which you use instead of the standard `Form` component.

## Usage

```tsx
import React, { Component } from 'react';
import validator from '@rjsf/validator-ajv8';
import { withTheme, ThemeProps } from '@rjsf/core';

const theme: ThemeProps = { widgets: { test: () => <div>test</div> } };

const ThemedForm = withTheme(theme);

const Demo = () => <ThemedForm schema={schema} uiSchema={uiSchema} validator={validator} />;
```

## Theme object properties

The Theme object consists of the same properties as the rjsf `Form` component (such as **widgets**, **fields** and **templates**).
The themed-Form component merges together any theme-specific **widgets**, **fields** and **templates** with the default **widgets**, **fields** and **templates**.
For instance, providing a single widget in **widgets** will merge this widget with all the default widgets of the rjsf `Form` component, but overrides the default if the theme's widget's name matches the default widget's name.
Thus, for each default widget or field not specified/overridden, the themed-form will rely on the defaults from the rjsf `Form`.
Note that you are not required to pass in either custom **widgets**, **fields** or **templates** when using the custom-themed HOC component;
you can essentially redefine the default Form by simply doing `const Form = withTheme({});`.

### Widgets and fields

**widgets** and **fields** should be in the same format as shown [here](./custom-widgets-fields.md).

Example theme with custom widget:

```tsx
import { WidgetProps, RegistryWidgetsType } from '@rjsf/utils';
import { ThemeProps } from '@rjsf/core';

const MyCustomWidget = (props: WidgetProps) => {
  return (
    <input
      type='text'
      className='custom'
      value={props.value}
      required={props.required}
      onChange={(event) => props.onChange(event.target.value)}
    />
  );
};

const myWidgets: RegistryWidgetsType = {
  myCustomWidget: MyCustomWidget,
};

const ThemeObject: ThemeProps = { widgets: myWidgets };
export default ThemeObject;
```

The above can be similarly done for **fields** and **templates**.

### Templates

Each template should be passed into the theme object via the **templates** object just as you would into the rjsf Form component. Here is an example of how to use a custom [ArrayFieldTemplate](./custom-templates.md#arrayfieldtemplate) and [ErrorListTemplate](./custom-templates.md#errorlisttemplate) in the theme object:

```tsx
import { ArrayFieldTemplateProps, ErrorListProps } from '@rjsf/utils';
import { ThemeProps } from '@rjsf/core';

function MyArrayFieldTemplate(props: ArrayFieldTemplateProps) {
  return (
    <div>
      {props.items.map((element) => element.children)}
      {props.canAdd && <button type='button' onClick={props.onAddClick}></button>}
    </div>
  );
}

function MyErrorListTemplate(props: ErrorListProps) {
  const { errors } = props;
  return (
    <ul>
      {errors.map((error) => (
        <li key={error.stack}>{error.stack}</li>
      ))}
    </ul>
  );
}

const ThemeObject: ThemeProps = {
  templates: {
    ArrayFieldTemplate: MyArrayFieldTemplate,
    ErrorListTemplate: MyErrorListTemplate,
  },
  widgets: myWidgets,
};

export default ThemeObject;
```

## Overriding other Form props

Just as the theme can override **widgets**, **fields**, any of the **templates**, and set default values to properties like **showErrorList**, you can do the same with the instance of the withTheme() Form component.

```tsx
import { ThemeProps } from '@rjsf/core';

const ThemeObject: ThemeProps = {
  templates: {
    ArrayFieldTemplate: MyArrayFieldTemplate,
  },
  fields: myFields,
  showErrorList: false,
  widgets: myWidgets,
};
```

Thus, the user has higher priority than the withTheme HOC, and the theme has higher priority than the default values of the rjsf Form component (**User** > **Theme** > **Defaults**).

---

### Packages Docs Docs Advanced Customization Custom Widgets Fields (`packages/docs/docs/advanced-customization/custom-widgets-fields.md`)

# Custom Widgets and Fields

The API allows to specify your own custom _widget_ and _field_ components:

- A _widget_ represents a HTML tag for the user to enter data, eg. `input`, `select`, etc.
- A _field_ usually wraps one or more widgets and most often handles internal field state; think of a field as a form row, including the labels.

## Customizing the default fields and widgets

You can override any default field and widget, including the internal widgets like the `CheckboxWidget` that `BooleanField`
renders for boolean values. You can override any field and widget just by providing the customized fields/widgets in the
`fields` and `widgets` props:

```tsx
import { RJSFSchema, UiSchema, WidgetProps, RegistryWidgetsType } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'boolean',
  default: true,
};

const uiSchema: UiSchema = {
  'ui:widget': 'checkbox',
};

const CustomCheckbox = function (props: WidgetProps) {
  return (
    <button id='custom' className={props.value ? 'checked' : 'unchecked'} onClick={() => props.onChange(!props.value)}>
      {String(props.value)}
    </button>
  );
};

const widgets: RegistryWidgetsType = {
  CheckboxWidget: CustomCheckbox,
};

render(
  <Form schema={schema} uiSchema={uiSchema} validator={validator} widgets={widgets} />,
  document.getElementById('app'),
);
```

This allows you to create a reusable customized form class with your custom fields and widgets:

```tsx
import { RegistryFieldsType, RegistryWidgetsType } from '@rjsf/utils';
import { FormProps } from '@rjsf/core';

const customFields: RegistryFieldsType = { StringField: CustomString };
const customWidgets: RegistryWidgetsType = { CheckboxWidget: CustomCheckbox };

function MyForm(props: FormProps) {
  return <Form fields={customFields} widgets={customWidgets} {...props} />;
}
```

The default fields you can override are:

- `ArrayField`
- `ArraySchemaField`
- `BooleanField`
- `DescriptionField`
- `OneOfField`
- `AnyOfField`
- `LayoutGridField`
- `LayoutMultiSchemaField`
- `LayoutHeaderField`
- `NullField`
- `NumberField`
- `ObjectField`
- `SchemaField`
- `StringField`
- `TitleField`
- `UnsupportedField`
- `FallbackField`
- `CyclicSchemaField`

The default widgets you can override are:

- `AltDateTimeWidget`
- `AltDateWidget`
- `CheckboxesWidget`
- `CheckboxWidget`
- `ColorWidget`
- `DateTimeWidget`
- `DateWidget`
- `EmailWidget`
- `FileWidget`
- `HiddenWidget`
- `PasswordWidget`
- `RadioWidget`
- `RangeWidget`
- `SelectWidget`
- `TextareaWidget`
- `TextWidget`
- `TimeWidget`
- `UpDownWidget`
- `URLWidget`

## Raising errors from within a custom widget or field

You can raise custom 'live validation' errors by overriding the `onChange` method to provide feedback while users are actively changing the form data.
If you do set errors this way, you must also clear them this way by passing `undefined` to the `onChange()` for the `errorSchema` parameter.

:::warning

While these errors are retained during validation, it is still preferred for you to use the [`customValidate` Form prop](../api-reference/form-props.md#customvalidate) mechanism instead.

:::

```tsx
import { ErrorSchema, RJSFSchema, UiSchema, WidgetProps, RegistryWidgetsType } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'text',
  default: 'hello',
};

const uiSchema: UiSchema = {
  'ui:widget': 'text',
};

const CustomTextWidget = function (props: WidgetProps) {
  const { id, value } = props;
  const raiseErrorOnChange = ({ target: { value } }: ChangeEvent<HTMLInputElement>) => {
    let raiseError: ErrorSchema | undefined;
    if (value !== 'test') {
      raiseError = {
        __errors: ['Value must be "test"'],
      };
    }
    props.onChange(value, [], raiseError, id);
  };

  return <input id={id} onChange={raiseErrorOnChange} value={value || ''} />;
};

const widgets: RegistryWidgetsType = {
  TextWidget: CustomTextWidget,
};

render(
  <Form schema={schema} uiSchema={uiSchema} validator={validator} widgets={widgets} />,
  document.getElementById('app'),
);
```

This creates a custom text widget that raises an error if the input value does not match 'test'.

## Adding your own custom widgets

You can provide your own custom widgets to a uiSchema for the following json data types:

- `string`
- `number`
- `integer`
- `boolean`
- `array`

```tsx
import { RJSFSchema, UiSchema, WidgetProps } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: Schema = {
  type: 'string',
};

const uiSchema: UiSchema = {
  'ui:widget': (props: WidgetProps) => {
    return (
      <input
        type='text'
        className='custom'
        value={props.value}
        required={props.required}
        onChange={(event) => props.onChange(event.target.value)}
      />
    );
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

The following props are passed to custom widget components:

- `id`: The generated id for this widget, used to provide unique `name`s and `id`s for the HTML field elements rendered by widgets;
- `name`: The unique name of the field, usually derived from the name of the property in the JSONSchema; Provided in support of custom widgets;
- `schema`: The JSONSchema subschema object for this widget;
- `uiSchema`: The uiSchema for this widget;
- `value`: The current value for this widget;
- `placeholder`: The placeholder for the widget, if any;
- `required`: The required status of this widget;
- `disabled`: A boolean value stating if the widget is disabled;
- `readonly`: A boolean value stating if the widget is read-only;
- `autofocus`: A boolean value stating if the widget should autofocus;
- `label`: The computed label for this widget, as a string
- `hideLabel`: A boolean value, if true, will cause the label to be hidden. This is useful for nested fields where you don't want to clutter the UI. Customized via `label` in the `UiSchema`;
- `multiple`: A boolean value stating if the widget can accept multiple values;
- `onChange`: The value change event handler; call it with the new value every time it changes;
- `onKeyChange`: The key change event handler (only called for fields with `additionalProperties`); pass the new value every time it changes;
- `onBlur`: The input blur event handler; call it with the widget id and value;
- `onFocus`: The input focus event handler; call it with the widget id and value;
- `options`: A map of options passed as a prop to the component (see [Custom widget options](#custom-widget-options)).
- `options.enumOptions`: For enum fields, this property contains the list of options for the enum as an array of \{ label, value } objects. If the enum is defined using the oneOf/anyOf syntax, the entire schema object for each option is appended onto the \{ schema, label, value } object.
- `rawErrors`: An array of strings listing all generated error messages from encountered errors for this widget.
- `registry`: A [registry](#the-registry-object) object (read next).

### Custom component registration

Alternatively, you can register them all at once by passing the `widgets` prop to the `Form` component, and reference their identifier from the `uiSchema`:

```tsx
import { RJSFSchema, UiSchema, WidgetProps, RegistryWidgetsType } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const MyCustomWidget = (props: WidgetProps) => {
  return (
    <input
      type='text'
      className='custom'
      value={props.value}
      required={props.required}
      onChange={(event) => props.onChange(event.target.value)}
    />
  );
};

const widgets: RegistryWidgetsType = {
  myCustomWidget: MyCustomWidget,
};

const schema: RJSFSchema = {
  type: 'string',
};

const uiSchema: UiSchema = {
  'ui:widget': 'myCustomWidget',
};

render(
  <Form schema={schema} uiSchema={uiSchema} validator={validator} widgets={widgets} />,
  document.getElementById('app'),
);
```

This is useful if you expose the `uiSchema` as pure JSON, which can't carry functions.

### Custom widget options

If you need to pass options to your custom widget, you can add a `ui:options` object containing those properties. If the widget has `defaultProps`, the options will be merged with the (optional) options object from `defaultProps`:

```tsx
import { RJSFSchema, UiSchema, WidgetProps } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

function MyCustomWidget(props: WidgetProps) {
  const { options } = props;
  const { color, backgroundColor } = options;
  return <input style={{ color, backgroundColor }} />;
}

MyCustomWidget.defaultProps = {
  options: {
    color: 'red',
  },
};

const uiSchema: UiSchema = {
  'ui:widget': MyCustomWidget,
  'ui:options': {
    backgroundColor: 'yellow',
  },
};

// renders red on yellow input
render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

> Note: This also applies to [registered custom components](#custom-component-registration).

### Customizing widgets' text input

All the widgets that render a text input use the `BaseInputTemplate` component internally. If you need to customize all text inputs without customizing all widgets individually, you can provide a `BaseInputTemplate` component in the `templates` property of `Form` (see [Custom Templates](./custom-templates.md#baseinputtemplate)).

### Wrapping an existing widget to customize it

Sometimes you just need to customize the properties that are passed to an existing widget.
The way to do this varies based upon whether you are using core or some other theme (such as mui).

Here is an example of modifying the `SelectWidget` to change the ordering of `enumOptions`:

```tsx
import { WidgetProps } from '@rjsf/utils';
import { getDefaultRegistry } from '@rjsf/core';
import { Widgets } from '@rjsf/mui';

import myOptionsOrderFunction from './myOptionsOrderFunction';

const {
  widgets: { SelectWidget },
} = getDefaultRegistry(); // To get widgets from core
// const { SelectWidget } = Widgets; // To get widgets from a theme do this

function MySelectWidget(props: WidgetProps) {
  const { options } = props;
  let { enumOptions } = options;
  // Reorder the `enumOptions` however you want
  enumOptions = myOptionsOrderFunction(enumOptions);
  return <SelectWidget {...props} options={{ ...options, enumOptions }} />;
}
```

## Custom field components

You can provide your own field components to a uiSchema for basically any json schema data type, by specifying a `ui:field` property.

For example, let's create and register a dumb `geo` component handling a _latitude_ and a _longitude_:

```tsx
import { RJSFSchema, UiSchema, FieldProps, RegistryFieldsType } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  required: ['lat', 'lon'],
  properties: {
    lat: { type: 'number' },
    lon: { type: 'number' },
  },
};

// Define a custom component for handling the root position object
class GeoPosition extends React.Component<FieldProps> {
  constructor(props: FieldProps) {
    super(props);
    this.state = { ...props.formData };
  }

  onChange(name) {
    return (event) => {
      this.setState(
        {
          [name]: parseFloat(event.target.value),
        },
        () => this.props.onChange(this.state),
      );
    };
  }

  render() {
    const { lat, lon } = this.state;
    return (
      <div>
        <input type='number' value={lat} onChange={this.onChange('lat')} />
        <input type='number' value={lon} onChange={this.onChange('lon')} />
      </div>
    );
  }
}

// Define the custom field component to use for the root object
const uiSchema: UiSchema = { 'ui:field': 'geo' };

// Define the custom field components to register; here our "geo"
// custom field component
const fields: RegistryFieldsType = { geo: GeoPosition };

// Render the form with all the properties we just defined passed
// as props
render(
  <Form schema={schema} uiSchema={uiSchema} validator={validator} fields={fields} />,
  document.getElementById('app'),
);
```

> Note: Registered fields can be reused across the entire schema.

### Field props

A field component will always be passed the following props:

- `schema`: The JSON subschema object for this field;
- `uiSchema`: The [uiSchema](../api-reference/uiSchema.md) for this field;
- `idSchema`: The FieldPathId of the field in the hierarchy
- `formData`: The data for this field;
- `errorSchema`: The tree of errors for this field and its children;
- `registry`: A [registry](#the-registry-object) object (read next).
- `required`: The required status of this field;
- `disabled`: A boolean value stating if the field is disabled;
- `readonly`: A boolean value stating if the field is read-only;
- `autofocus`: A boolean value stating if the field should autofocus;
- `name`: The unique name of the field, usually derived from the name of the property in the JSONSchema
- `rawErrors`: `An array of strings listing all generated error messages from encountered errors for this field
- `onChange`: The field change event handler; called with the updated field value, the optional change path for the value (defaults to an empty array), an optional ErrorSchema and the optional id of the field being changed
- `onBlur`: The input blur event handler; call it with the field id and value;
- `onFocus`: The input focus event handler; call it with the field id and value;

## The `registry` object

The `registry` is an object containing the registered core, theme and custom fields and widgets as well as the root schema, form context, schema utils.

- `fields`: The set of all fields used by the `Form`. Includes fields from `core`, theme-specific fields and any [custom registered fields](#custom-field-components);
- `widgets`: The set of all widgets used by the `Form`. Includes widgets from `core`, theme-specific widgets and any [custom registered widgets](#custom-component-registration), if any;
- `templates`: The set of templates used by the `Form`. Includes templates from `core`, theme-specific templates and any custom registered templates
- `rootSchema`: The root schema, as passed to the `Form`, which can contain referenced [definitions](../json-schema/definitions.md);
- `schemaUtils`: The current implementation of the `SchemaUtilsType` (from `@rjsf/utils`) in use by the `Form`. Used to call any of the validation-schema-based utility functions.
- `translateString`: The string translation function to use when displaying any of the RJSF strings in templates, fields or widgets
- `globalFormOptions`: The global Form Options that are available for all templates, fields and widgets to access
- `globalUiOptions`: The optional global UI Options that are available for all templates, fields and widgets to access

The registry is passed down the component tree, so you can access it from your custom field, custom widget, custom template and `SchemaField` components.

### Custom SchemaField

**Warning:** This is a powerful feature as you can override the whole form behavior and easily mess it up. Handle with care.

You can provide your own implementation of the `SchemaField` base React component for rendering any JSONSchema field type, including objects and arrays. This is useful when you want to augment a given field type with supplementary powers.

To proceed so, pass a `fields` object having a `SchemaField` property to your `Form` component; here's an example:

```tsx
import { RJSFSchema, FieldProps, RegistryFieldsType } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const CustomSchemaField = function (props: FieldProps) {
  return (
    <div id='custom'>
      <p>Yeah, I'm pretty dumb.</p>
      <div>My props are: {JSON.stringify(props)}</div>
    </div>
  );
};

const fields: RegistryFieldsType = {
  SchemaField: CustomSchemaField,
};

const schema: RJSFSchema = {
  type: 'string',
};

render(<Form schema={schema} validator={validator} fields={fields} />, document.getElementById('app'));
```

If you're curious how this could ever be useful, have a look at the [Kinto formbuilder](https://github.com/Kinto/formbuilder) repository to see how it's used to provide editing capabilities to any form field.

Props passed to a custom SchemaField are the same as [the ones passed to a custom field](#field-props).

### Custom ArraySchemaField

Everything that was mentioned above for a `Custom SchemaField` applies, but this is only used to render the Array item `children` that are then passed to the `ArrayFieldItemTemplate`.
By default, `ArraySchemaField` is not actually implemented in the `fields` list since `ArrayField` falls back to `SchemaField` if `ArraySchemaField` is not provided.
If you want to customize how the individual items for an array are rendered, provide your implementation of `ArraySchemaField` as a `fields` override.

```tsx
import { RJSFSchema, UiSchema, FieldProps, RegistryFieldsType } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const CustomArraySchemaField = function (props: FieldProps) {
  const { index, registry } = props;
  const { SchemaField } = registry.fields;
  const name = `Index ${index}`;
  return <SchemaField {...props} name={name} />;
};

const fields: RegistryFieldsType = {
  ArraySchemaField: CustomArraySchemaField,
};

const schema: RJSFSchema = {
  type: 'string',
};

render(<Form schema={schema} validator={validator} fields={fields} />, document.getElementById('app'));
```

### Custom Field by Id

**Warning:** This is a powerful feature as you can override the whole form behavior and easily mess it up. Handle with care.

You can provide your own implementation of the field component that applies to any schema or sub-schema based on the schema's `$id` value. This is useful when your custom field should be conditionally applied based on the schema rather than the property name or data type.

To provide a custom field in this way, the `fields` prop should be an object which contains a key that matches the `$id` value of the schema which should have a custom field; here's an example:

```tsx
import { RJSFSchema, FieldProps, RegistryFieldsType } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const CustomIdField = function (props: FieldProps) {
  return (
    <div id='custom'>
      <p>Yeah, I'm pretty dumb.</p>
      <div>My props are: {JSON.stringify(props)}</div>
    </div>
  );
};

const fields: RegistryFieldsType = {
  '/schemas/my-id': CustomIdField,
};

const schema: RJSFSchema = {
  $id: '/schemas/my-id',
  type: 'string',
};

render(<Form schema={schema} validator={validator} fields={fields} />, document.getElementById('app'));
```

### Wrapping an existing field to customize it

Sometimes you just need to customize the properties that are passed to an existing field.

Here is an example of wrapping the `ObjectField` to tweak the `onChange` handler to look for a specific kind of bad data:

```tsx
import { useCallback } from 'react';
import { FieldProps } from '@rjsf/utils';
import { getDefaultRegistry } from '@rjsf/core';

import checkBadData from './checkBadData';

const {
  fields: { ObjectField },
} = getDefaultRegistry();

function MyObjectField(props: FieldProps) {
  const { onChange } = props;
  const onChangeHandler = useCallback(
    (newFormData: T | undefined, path: (number | string)[], es?: ErrorSchema<T>, id?: string) => {
      let data = newFormData;
      let error = es;
      if (checkBadData(newFormData)) {
        // Format the `error` and fix the `data` here
      }
      onChange(data, path, error, id);
    },
    [onChange],
  );
  return <ObjectField {...props} onChange={onChangeHandler} />;
}
```

---

### Packages Docs Docs Advanced Customization Internals (`packages/docs/docs/advanced-customization/internals.md`)

# Internals

Miscellaneous internals of react-jsonschema-form are listed here.

## JSON Schema supporting status

This component follows [JSON Schema](http://json-schema.org/documentation.html) specs. We currently support JSON Schema-07 by default, but we also support other JSON schema versions through the [custom schema validation](../usage/validation.md#custom-meta-schema-validation) feature. Due to the limitation of form widgets, there are some exceptions as follows:

- `additionalItems` keyword for arrays

  This keyword works when `items` is an array. `additionalItems: true` is not supported because there's no widget to represent an item of any type. In this case it will be treated as no additional items allowed. `additionalItems` being a valid schema is supported.

- `anyOf`, `allOf`, and `oneOf`, or multiple `types` (i.e. `"type": ["string", "array"]`)

  The `anyOf` and `oneOf` keywords are supported; however, properties declared inside the `anyOf/oneOf` should not overlap with properties "outside" of the `anyOf/oneOf`.

  You can also use `oneOf` with [schema dependencies](../json-schema/dependencies.md#schema-dependencies) to dynamically add schema properties based on input data.

  The `allOf` keyword is supported; it uses [@x0k/json-schema-merge](https://github.com/x0k/json-schema-merge/) to merge subschemas to render the final combined schema in the form. When these subschemas are incompatible, though (or if the library has an error merging it), the `allOf` keyword is dropped from the schema.

- `"additionalProperties":false` produces incorrect schemas when used with [schema dependencies](../json-schema/dependencies.md#schema-dependencies). This library does not remove extra properties, which causes validation to fail. It is recommended to avoid setting `"additionalProperties":false` when you use schema dependencies. See [#848](https://github.com/rjsf-team/react-jsonschema-form/issues/848) [#902](https://github.com/rjsf-team/react-jsonschema-form/issues/902) [#992](https://github.com/rjsf-team/react-jsonschema-form/issues/992)

## Handling of schema defaults

This library automatically fills default values defined in the [JSON Schema](http://json-schema.org/documentation.html) as initial values in your form. This also works for complex structures in the schema. If a field has a default defined, it should always appear as default value in form. This also works when using [schema dependencies](../json-schema/dependencies.md#schema-dependencies).

Since there is a complex interaction between any supplied original form data and any injected defaults, this library tries to do the injection in a way which keeps the original intention of the original form data.

Check out the defaults example on the [live playground](https://rjsf-team.github.io/react-jsonschema-form/) to see this in action.

### Merging of defaults into the form data

There are three different cases which need to be considered for the merging. Objects, arrays and scalar values. This library always deeply merges any defaults with the existing form data for objects.

This are the rules which are used when injecting the defaults:

- When there is a scalar in the form data, nothing is changed.
- When the value is `undefined` in the form data, the default is created in the form data.
- When the value is an object in the form data, the defaults are deeply merged into the form data, using the rules defined here for the deep merge.
- Then the value is an array in the form data, defaults are only injected in existing array items. No new array items will be created, even if the schema has minItems or additional items defined.

A boolean property that is listed in its parent's `required` array and has no `default` of its own is populated with `false`. You can turn this off using the experimental [`requiredBooleanDefault`](../api-reference/form-props.md#requiredbooleandefault) flag, so that the property stays `undefined` until the user answers it.

### Merging of defaults within the schema

In the schema itself, defaults of parent elements are propagated into children. So when you have a schema which defines a deeply nested object as default, these defaults will be applied to children of the current node. This also merges objects defined at different levels together, with the deeper (descendant) default taking precedence for any overlapping properties by default. You can change this behavior using the experimental [`nestedDefaultsPrecedence`](../api-reference/form-props.md#nesteddefaultsprecedence) flag. If the parent node defines properties which are not defined in the child, they will be merged so that the default for the child will be the merged defaults of parent and child.

For arrays this is not the case. Defining an array, when a parent also defines an array, will be overwritten. This is only true when arrays are used in the same level, for objects within these arrays, they will be deeply merged again.

## Custom array field buttons

The `ArrayField` component provides a UI to add, copy, remove and reorder array items, and these buttons use [Bootstrap glyphicons](http://getbootstrap.com/components/#glyphicons).
If you don't use glyphicons but still want to provide your own icons or texts for these buttons, you can easily do so using CSS:

> NOTE this only applies to the `@rjsf/core` theme

```css
i.glyphicon {
  display: none;
}
.btn-add::after {
  content: 'Add';
}
.array-item-copy::after {
  content: 'Copy';
}
.array-item-move-up::after {
  content: 'Move Up';
}
.array-item-move-down::after {
  content: 'Move Down';
}
.array-item-remove::after {
  content: 'Remove';
}
```

## Submit form programmatically

You can use the reference to get your `Form` component and call the `submit` method to submit the form programmatically without a submit button.
This method will dispatch the `submit` event of the form, and the function, that is passed to `onSubmit` props, will be called.

```tsx
import { createRef } from 'react';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import { Form } from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';

const onSubmit = ({ formData }) => console.log('Data submitted: ', formData);
let yourForm;

const schema: RJSFSchema = {
  type: 'string',
};

const formRef = createRef<Form>();

render(
  <Form schema={schema} validator={validator} onSubmit={onSubmit} ref={formRef} />,
  document.getElementById('app'),
);

formRef.current.submit();
```

## Update field value in form programmatically

You can use the reference to get your `Form` component and call the `setFieldValue(fieldPath: string | FieldPathList, newValue?: T): void` method to change the value of a field.
This method will dispatch the `onChange` event of the form.

```tsx
import { createRef } from 'react';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import { Form } from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';

const onChange = ({ formData }) => console.log('Data updated to: ', formData);
let yourForm;

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    foo: {
      type: 'object',
      required: ['input'],
      properties: {
        input: {
          type: 'string',
        },
      },
    },
  },
  required: ['foo'],
};

const formRef = createRef<Form>();

render(
  <Form schema={schema} validator={validator} onSubmit={onSubmit} ref={formRef} />,
  document.getElementById('app'),
);

formRef.current.setFieldValue('foo.input', 'value');
formRef.current.setFieldValue(['foo'], { input: 'newvalue' });
formRef.current.setFieldValue('', { foo: { input: 'another value' } });
formRef.current.setFieldValue([], { foo: { input: 'more values' } });
```

---

### Packages Docs Docs Advanced Customization Typescript (`packages/docs/docs/advanced-customization/typescript.md`)

# Typescript Support

RJSF fully supports Typescript.
The [types and functions](../api-reference/utility-functions.md) exported by `@rjsf/utils` are fully typed (as needed) using one or more of the following 3 optional generics:

- `T = any`: This represents the type of the `formData` and defaults to `any`.
- `S extends StrictRJSFSchema = RJSFSchema`: This represents the type of the `schema` and extends the `StrictRJSFSchema` type and defaults to the `RJSFSchema` type.
- `F extends FormContextType = any`: This represents the type of the `formContext`, extends the `FormContextType` type and defaults to `any`.

Every other library in the `@rjsf/*` ecosystem use these same generics in their functions and React component definitions.
For instance, in the `@rjsf/core` library the definitions of the `Form` component and the `withTheme()` and `getDefaultRegistry()` functions are as follows:

```ts
export default class Form<
  T = any,
  S extends StrictRJSFSchema = RJSFSchema,
  F extends FormContextType = any
> extends Component<FormProps<T, S, F>, FormState<T, S, F>> {
  // ... class implementation
}

export default function withTheme<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(
  themeProps: ThemeProps<T, S, F>
) {
  // ... function implementation
}

export default function getDefaultRegistry<
  T = any,
  S extends StrictRJSFSchema = RJSFSchema,
  F extends FormContextType = any
>(): Omit<Registry<T, S, F>, 'schemaUtils'> {
  // ... function implementation
}
```

Out of the box, the defaults for these generics will work for all use-cases.
Providing custom types for any of these generics may be useful for situations where the caller is working with typed `formData`, `schema` or `formContext` props, Typescript is complaining and type casting isn't allowed.

## Overriding generics

### T

The generic `T` is used to represent the type of the `formData` property passed into `Form`.
If you are working with a simple, unchanging JSON Schema and you have defined a type for the `formData` you are working with, you can override this generic as follows:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import { customizeValidator } from '@rjsf/validator-ajv8';
import { Form } from '@rjsf/core';

interface FormData {
  foo?: string;
  bar?: number;
}

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    foo: { type: 'string' },
    bar: { type: 'number' },
  },
};

const formData: FormData = {};

const validator = customizeValidator<FormData>();

render(<Form<FormData> schema={schema} validator={validator} formData={formData} />, document.getElementById('app'));
```

### S

The generic `S` is used to represent the type of the `schema` property passed into `Form`.
If you are using something like the [Ajv utility types for schemas](https://ajv.js.org/guide/typescript.html#utility-types-for-schemas) typing system, you can override this generic as follows:

```tsx
import { JSONSchemaType } from 'ajv';
import { RJSFSchema } from '@rjsf/utils';
import { customizeValidator } from '@rjsf/validator-ajv8';
import { Form } from '@rjsf/core';

interface FormData {
  foo?: string;
  bar?: number;
}

type MySchema = JSONSchemaType<FormData>;

const schema: MySchema = {
  type: 'object',
  properties: {
    foo: { type: 'string' },
    bar: { type: 'number' },
  },
};

const validator = customizeValidator<any, MySchema>();

render(<Form<any, MySchema> schema={schema} validator={validator} />, document.getElementById('app'));

// Alternatively since you have the type, you could also use this
// const validator = customizeValidator<FormData, MySchema>();
// render((
//  <Form<FormData, MySchema> schema={schema} validator={validator} />
//), document.getElementById("app"));
```

> NOTE: using this `Ajv typing system` has not been tested extensively with RJSF, so use carefully

### F

The generic `F` is used to represent the type of the `formContext` property passed into `Form`.
If you have a type for this data, you can override this generic as follows:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import { customizeValidator } from '@rjsf/validator-ajv8';
import { Form } from '@rjsf/core';

interface FormContext {
  myCustomWidgetData: object;
}

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    foo: { type: 'string' },
    bar: { type: 'number' },
  },
};

const formContext: FormContext = {
  myCustomWidgetData: {
    enableCustomFeature: true,
  },
};

const validator = customizeValidator<any, RJSFSchema, FormContext>();

render(
  <Form<any, RJSFSchema, FormContext> schema={schema} validator={validator} formContext={formContext} />,
  document.getElementById('app')
);
```

## Overriding generics in core

As shown in previous examples, overriding the default `Form` from `@rjsf/core` is pretty straight forward.
Using the `withTheme()` function is just as easy:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import { customizeValidator } from '@rjsf/validator-ajv8';
import { withTheme, ThemeProps } from '@rjsf/core';

interface FormData {
  foo?: string;
  bar?: number;
}

type MySchema = JSONSchemaType<FormData>;

const schema: MySchema = {
  type: 'object',
  properties: {
    foo: { type: 'string' },
    bar: { type: 'number' },
  },
};

interface FormContext {
  myCustomWidgetData: object;
}

const theme: ThemeProps<FormData, MySchema, FormContext> = {
  widgets: { test: () => <div>test</div> },
};

const ThemedForm = withTheme<FormData, MySchema, FormContext>(theme);

const validator = customizeValidator<FormData, MySchema, FormContext>();

const Demo = () => <ThemedForm schema={schema} uiSchema={uiSchema} validator={validator} />;
```

## Overriding generics in other themes

Since all the other themes in RJSF are extensions of `@rjsf/core`, overriding parts of these themes with custom generics is a little different.
The exported `Theme` and `Form` from any of the themes have been created using the generic defaults, and as a result, do not take generics themselves.
In order to override generics, special `generateForm()` and `generateTheme()` functions are exported for your use.

### Overriding a Theme

If you are doing something like the following to create a new theme based on `@rjsf/mui` to extend one or more `templates`:

```tsx
import React from 'react';
import { WidgetProps } from '@rjsf/utils';
import { ThemeProps, withTheme } from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';
import { Theme } from '@rjsf/mui';

const OldBaseInputTemplate = Theme.templates.BaseInputTemplate;

// Force the underlying `TextField` component to always use size="small"
function MyBaseInputTemplate(props: WidgetProps) {
  return <OldBaseInputTemplate {...props} size='small' />;
}

const myTheme: ThemeProps = {
  ...Theme,
  templates: {
    ...Theme.templates,
    BaseInputTemplate: MyBaseInputTemplate,
  },
};

const ThemedForm = withTheme(myTheme);

const Demo = () => <ThemedForm schema={schema} uiSchema={uiSchema} validator={validator} />;
```

Then you would use the new `generateTheme()` and `generateForm()` functions as follows:

```tsx
import React from 'react';
import { WidgetProps } from '@rjsf/utils';
import { ThemeProps, withTheme } from '@rjsf/core';
import { customizeValidator } from '@rjsf/validator-ajv8';
import { generateTheme } from '@rjsf/mui';

interface FormData {
  foo?: string;
  bar?: number;
}

type MySchema = JSONSchemaType<FormData>;

const schema: MySchema = {
  type: 'object',
  properties: {
    foo: { type: 'string' },
    bar: { type: 'number' },
  },
};

interface FormContext {
  myCustomWidgetData: object;
}

const Theme: ThemeProps<FormData, MySchema, FormContext> = generateTheme<FormData, MySchema, FormContext>();

const OldBaseInputTemplate = Theme.templates.BaseInputTemplate;

// Force the underlying `TextField` component to always use size="small"
function MyBaseInputTemplate(props: WidgetProps<FormData, MySchema, FormContext>) {
  return <OldBaseInputTemplate {...props} size='small' />;
}

const myTheme: ThemeProps<FormData, MySchema, FormContext> = {
  ...Theme,
  templates: {
    ...Theme.templates,
    BaseInputTemplate: MyBaseInputTemplate,
  },
};

const ThemedForm = withTheme<FormData, MySchema, FormContext>(myTheme);

const validator = customizeValidator<FormData, MySchema, FormContext>();

// You could also do since they are effectively the same:
// const ThemedForm = generateForm<FormData, MySchema, FormContext>(myTheme);

const Demo = () => <ThemedForm schema={schema} uiSchema={uiSchema} validator={validator} />;
```

> NOTE: The same approach works for extending `widgets` and `fields` as well.

---

### Packages Docs Docs Api Reference LayoutGridField (`packages/docs/docs/api-reference/LayoutGridField.md`)

# LayoutGridField

The `LayoutGridField` will render a schema, uiSchema and formData combination out into a `GridTemplate` in the shape
described in the uiSchema. To define the grid to use to render the elements within a field in the schema, provide in
the uiSchema for that field the object contained under a `ui:layoutGrid` element. E.g. (as a JSON object):

```json
{
  "field1" : {
    "ui:field": "LayoutGridField",
    "ui:layoutGrid": {
      "ui:row": { ... }
    }
  }
}
```

See the [LayoutGridField usage](../usage/layout-grid.md) for more detailed walk-through on how to use the component. This page is condensed
version of the `uiSchema` APIs for faster reference.

## `ui:row`

The outermost level of a `LayoutGridField` is the `ui:row` that defines the nested rows, columns, and/or condition
elements (i.e. "grid elements") in the grid. This definition is either a simple "grid elements" OR an object with
native `GridTemplate` implementation-specific props and a `children` array of "grid elements". E.g. (as JSON objects):

Simple `ui:row` definition, without additional `GridTemplate` props:

```json
{
  "ui:row": [
    { "ui:row"|"ui:col"|"ui:columns"|"ui:condition": ... },
    ...
  ]
}
```

Complex `ui:row` definition, with additional `GridTemplate` (this example uses `@mui/material/Grid2` native props):

```json
{
  "ui:row": {
    "spacing": 2,
    "size": {
      "md": 4
    },
    "alignContent": "flex-start",
    "className": "GridRow",
    "children": [
        {
          "ui:row"|"ui:col"|"ui:columns"|"ui:condition": ...
        },
        ...
      ]
    }
  }
```

> NOTE: Special note about the native `className` prop values. All className values will automatically be looked up in
> the `formContext.lookupMap` in case they have been defined using a CSS-in-JS approach. In other words, from the
> example above, if the `Form` was constructed with a `layoutGridLookupMap` set to `{ GridRow: cssInJs.GridRowClass }`
> then when rendered, the native `GridTemplate` will get the `className` with the value from
> `cssInJs.GridRowClass`. This automatic lookup will happen for any of the "grid elements" when rendering with
> `GridTemplate` props. If multiple className values are present, for example:
> `{ className: 'GridRow GridColumn' }`, the classNames are split apart, looked up individually, and joined
> together to form one className with the values from `cssInJs.GridRowClass` and `cssInJs.GridColumnClass`. See the
> [example](../usage/layout-grid.md#named-lookup-support-for-classname) in the usage documentation.

## `ui:col`

The `ui:col` grid element is used to specify the list of columns within a grid row. A `ui:col` element can take on
several forms:

1. a simple list of dotted-path field names within the root field;
2. a list of objects containing the dotted-path field `name` any other props that are gathered into `ui:options` for the field;
3. a list with a one-off `render` functional component with or without a non-field `name` identifier and any other to-be-spread props; and
4. an object with native `GridTemplate` implementation specific props and a `children` array with 1) or 2) or even a nested `ui:row` or a `ui:condition` containing a `ui:row` (although this should be used carefully). E.g. (as JSON objects):

Simple `ui:col` definition, without additional `GridTemplate` props and form 1 only children:

```json
{
  "ui:col": ["innerField", "inner.grandChild", ...]
}
```

Complicated `ui:col` definition, without additional `GridTemplate` props and form 2 only children:

```json
{
  "ui:col": [
    { "name": "innerField", "fullWidth": true },
    { "name": "inner.grandChild", "fullWidth": false },
    ...
  ]
}
```

More complicated `ui:col` definition, without additional `GridTemplate` props and form 2 children, one being a
one-off `render` functional component without a non-field `name` identifier

```json
{
  "ui:col": [
    "innerField",
    {
      "render": "WizardNavButton",
      "isNext": true,
      "size": "large"
    }
  ]
}
```

Most complicated `ui:col` definition, additional `GridTemplate` props and form 1, 2 and 3 children (this example
uses @mui/material/Grid2 native props):

```json
{
  "ui:col": {
    "size": { "md": 4 },
    "className": "GridColumn",
    "children": [
      "innerField",
      { "name": "inner.grandChild", "fullWidth": true },
      { "name": "customRender", "render": "CustomRender", "toSpread": "prop-value" },
      { "ui:row|ui:condition": ... },
      ...
    ]
  }
}
```

> NOTE: If a `name` prop does not exist or its value does not match any field in a schema, then it is assumed to be a
> custom `render` component. If the `render` prop does not exist, a null render will occur. If `render` is a
> string, its value will be looked up in the `formContext.lookupMap` first before defaulting to a null render. If the
> resulting looked up `render` is not a function (React components are functions), then it will be a null render.

## `ui:columns`

The `ui:columns` grid element is syntactic sugar to specify a set of `ui:col` columns that all share the same set of
native `GridTemplate` props. In other words rather than writing the following configuration that renders a
`<GridTemplate>` element with 3 `<GridTemplate column className="GridColumn col-md-4">` nodes and 2
`<GridTemplate column className="col-md-6">` nodes within it (one for each of the fields contained in the `children`
list):

```json
{
  "ui:row": {
    "children": [
      {
        "ui:col": {
          "className": "GridColumn col-md-4",
          "children": ["innerField"]
        }
      },
      {
        "ui:col": {
          "className": "GridColumn col-md-4",
          "children": ["inner.grandChild"]
        }
      },
      {
        "ui:col": {
          "className": "GridColumn col-md-4",
          "children": [{ "name": "inner.grandChild2" }]
        }
      },
      {
        "ui:col": {
          "className": "col-md-6",
          "children": ["innerField2"]
        }
      },
      {
        "ui:col": {
          "className": "col-md-6",
          "children": ["inner.grandChild3"]
        }
      }
    ]
  }
}
```

One can write this instead:

```json
{
  "ui:row": {
    "children": [
      {
        "ui:columns": {
          "className": "GridColumn col-md-4",
          "children": ["innerField", "inner.grandChild", { "name": "inner.grandChild2", "fullWidth": true }]
        }
      },
      {
        "ui:columns": {
          "className": "col-md-6",
          "children": ["innerField2", "inner.grandChild3"]
        }
      }
    ]
  }
}
```

> NOTE: This syntax differs from `"ui:col": { "className": "col-md-6", "children": ["innerField2", "inner.grandChild3"] }` in that
> the `ui:col` will render the two children fields inside a single `<GridTemplate "className": "col-md-6",>`
> element.

## `ui:condition`

The final grid element, `ui:condition`, allows for conditionally displaying "grid elements" within a row based on the
current value of a field as it relates to a (list of) hard-coded value(s). There are four elements that make up a
`ui:condition`:

1. the dotted-path `field` name within the root field that makes up the left-side of the condition;
2. the hard-coded `value` (single or list) that makes up the right-side of the condition;
3. the `operator` that controls how the left and right sides of the condition are compared; and
4. the `children` array that defines the "grid elements" to display if the condition passes.

A `ui:condition` uses one of three `operators` when deciding if a condition passes:

1. The `all` operator will pass when the right-side and left-side contains all the same value(s);
2. the `some` operator will pass when the right-side and left-side contain as least one value in common;
3. the `none` operator will pass when the right-side and left-side do not contain any values in common. E.g. (as JSON objects):

Here is how to render an if-then-else for `field2` which is an enum that has 3 known values and supports allowing
any other value:

```json
{
  "ui:row": [
    {
      "ui:condition": {
        "field": "field2",
        "operator": "all",
        "value": "value1",
        "children": [
          { "ui:row": [...] }
        ],
      }
    },
    {
      "ui:condition": {
        "field": "field2",
        "operator": "some",
        "value": ["value2", "value3"],
        "children": [
          { "ui:row": [...] }
        ],
      }
    },
    {
      "ui:condition": {
        "field": "field2",
        "operator": "none",
        "value": ["value1", "value2", "value3"],
        "children": [
          { "ui:row": [...] }
        ]
      }
    }
  ]
}
```

---

### Packages Docs Docs Api Reference Dynamic Ui Schema Examples (`packages/docs/docs/api-reference/dynamic-ui-schema-examples.md`)

# Dynamic uiSchema Examples

## Backward Compatibility Examples

### Example 1: Traditional Static uiSchema (No Changes Required)

```typescript
import { UiSchema } from '@rjsf/utils';

// This continues to work exactly as before
const uiSchema: UiSchema = {
  guests: {
    items: {
      name: { 'ui:placeholder': 'Enter guest name' },
      age: { 'ui:widget': 'updown' },
      relationship: { 'ui:widget': 'select' },
    },
  },
};
```

### Example 2: Dynamic uiSchema with Function

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Example 3: Using Form Context

```typescript
import { UiSchema, FormContextType } from '@rjsf/utils';

interface ParticipantData {
  name?: string;
  email?: string;
  workshop?: string;
}

interface MyFormContext extends FormContextType {
  eventType?: 'conference' | 'workshop' | 'webinar';
}

const uiSchema: UiSchema<any, any, MyFormContext> = {
  participants: {
    items: (itemData: ParticipantData | undefined, index: number, formContext?: MyFormContext): UiSchema => {
      // Access form-wide settings
      const isConference = formContext?.eventType === 'conference';

      return {
        name: { 'ui:placeholder': 'Participant name' },
        email: { 'ui:widget': 'email' },
        // Show workshop selection only for conference events
        workshop: isConference ? { 'ui:widget': 'select' } : { 'ui:widget': 'hidden' },
      };
    },
  },
};
```

### Example 4: Falsy Return Values

```typescript
import { UiSchema, FormContextType } from '@rjsf/utils';

interface ItemData {
  needsCustomUI?: boolean;
  field1?: string;
  field2?: string;
}

const uiSchema: UiSchema = {
  items: {
    items: (itemData: ItemData | undefined, index: number): UiSchema | null | undefined => {
      // Only apply custom UI to specific items
      if (itemData?.needsCustomUI) {
        return {
          field1: { 'ui:widget': 'textarea' },
          field2: { 'ui:help': 'This item needs special attention' },
        };
      }

      // Return null or undefined to use default UI rendering
      // This is useful for conditionally applying custom UI
      return null;
    },
  },
};
```

### Example 5: Dynamic UI for Fixed Arrays

For fixed/tuple arrays (where schema.items is an array), the dynamic function can be applied to each position:

```typescript
import { RJSFSchema, UiSchema } from '@rjsf/utils';

interface DetailsData {
  age?: number;
  role?: string;
}

const schema: RJSFSchema = {
  type: 'array',
  items: [
    { type: 'string', title: 'First Name' },
    { type: 'string', title: 'Last Name' },
    { type: 'object', title: 'Details', properties: { age: { type: 'number' }, role: { type: 'string' } } },
  ],
};

const uiSchema: UiSchema = {
  items: [
    { 'ui:placeholder': 'Enter first name' }, // Static UI for first item
    { 'ui:placeholder': 'Enter last name' }, // Static UI for second item
    // Dynamic UI for third item based on its data
    (itemData: DetailsData | undefined, index: number): UiSchema => {
      if (itemData?.role === 'admin') {
        return {
          age: { 'ui:widget': 'hidden' },
          role: { 'ui:help': 'Admin role selected' },
        };
      }
      return {
        age: { 'ui:widget': 'updown' },
        role: { 'ui:widget': 'select' },
      };
    },
  ],
};
```

## Schema Example

```typescript
import { RJSFSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    guests: {
      type: 'array',
      items: {
        type: 'object',
        properties: {
          name: { type: 'string', title: 'Name' },
          age: { type: 'number', title: 'Age' },
          relationship: {
            type: 'string',
            title: 'Relationship',
            enum: ['adult', 'child', 'senior'],
          },
          guardianName: { type: 'string', title: 'Guardian Name' },
          mealPreference: {
            type: 'string',
            title: 'Meal Preference',
            enum: ['vegetarian', 'vegan', 'standard', 'gluten-free'],
          },
        },
        required: ['name', 'relationship'],
      },
    },
  },
};
```

## Key Benefits

1. **Backward Compatible**: Existing forms with object-based `uiSchema.items` continue to work without any changes
2. **Progressive Enhancement**: Developers can opt-in to dynamic behavior when needed
3. **Flexible**: Access to item data, index, and form context enables complex UI logic
4. **Safe**: Built-in error handling prevents the entire form from crashing if your function throws an error. When an error occurs for a specific item, it will be caught and logged to the developer console, and the UI for that item will fall back to the default rendering. This ensures the rest of the form remains functional while making debugging easier.
5. **On-Demand Execution**: The function is executed on-demand during the render cycle. However, as it runs for each array item, performance should be carefully managed for large lists (see Performance Considerations below).

## Key Behaviors

- **Falsy Returns**: If your function returns a falsy value (e.g., `null` or `undefined`), the UI for that specific item will fall back to its default rendering. This allows you to conditionally apply custom UI only when needed.
- **Error Handling**: If your function throws an error, it will be caught and logged to the console. The form will continue to work, using default UI for the affected item.
- **New Items**: When a new item is added to the array, `itemData` will be `undefined` or contain default values from the schema. Always use optional chaining (`?.`) to safely access properties.

## Performance Considerations

When using dynamic `uiSchema.items` functions, keep in mind:

- The function is executed **on every render** for **each array item**
- For large arrays, this can impact performance if the function performs expensive operations
- Best practices:
  - Keep the function logic lightweight and fast
  - Avoid heavy computations or external API calls within the function
  - Consider memoizing results if the same inputs produce the same outputs
  - For complex logic, pre-compute values and store them in formContext or component state

Example of a performance-optimized approach:

```typescript
import React, { PropsWithChildren, useMemo } from 'react';
import Form from '@rjsf/core';
import { RJSFSchema, UiSchema, FormContextType, IChangeEvent } from '@rjsf/utils';

interface ItemData {
  type?: string;
  field?: any;
}

interface ExpensiveDataConfig {
  widget: string;
}

interface MyFormProps {
  schema: RJSFSchema;
  formData?: any;
}

// In your React component that renders the form:
function MyFormComponent({ schema, formData }: PropsWithChildren<MyFormProps>) {
  // Pre-compute expensive data once, and only re-compute if dependencies change
  const expensiveData = useMemo<Record<string, ExpensiveDataConfig>>(() => computeExpensiveData(), [/* dependencies */]);

  const defaultConfig: ExpensiveDataConfig = { widget: 'text' };

  // Define the uiSchema inside the component so it can access the memoized data
  const uiSchema: UiSchema = {
    myArrayField: { // Target your specific array field
      items: (itemData: ItemData | undefined, index: number, formContext?: FormContextType): UiSchema => {
        // Use the pre-computed data - this is very fast
        const config = expensiveData[itemData?.type || ''] || defaultConfig;

        return {
          field: { 'ui:widget': config.widget }
        };
      }
    }
  };

  return <Form schema={schema} uiSchema={uiSchema} formData={formData} />;
}

// Placeholder for the expensive computation function
declare function computeExpensiveData(): Record<string, ExpensiveDataConfig>;
```

---

### Packages Docs Docs Api Reference Form Props (`packages/docs/docs/api-reference/form-props.md`)

---
title: <Form /> Props
---

# &lt;Form /> props

## acceptCharset

The value of this prop will be passed to the `accept-charset` [HTML attribute on the form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-accept-charset).

## action

The value of this prop will be passed to the `action` [HTML attribute on the form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-action).

Note that this just renders the `action` attribute in the HTML markup. There is no real network request being sent to this `action` on submit. Instead, react-jsonschema-form catches the submit event with `event.preventDefault()` and then calls the [`onSubmit`](#onSubmit) function, where you could send a request programmatically with `fetch` or similar.

## autoComplete

The value of this prop will be passed to the `autocomplete` [HTML attribute on the form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-autocomplete).

## className

The value of this prop will be passed to the `class` [HTML attribute on the form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form).

## children

You can provide custom buttons to your form via the `Form` component's `children`. If no children are provided, by default a `Submit` button will be rendered.

For other ways to modify the default `Submit` button, see both the [Submit Button Options](./uiSchema.md#submitbuttonoptions) and the [SubmitButton Template](../advanced-customization/custom-templates.md#submitbutton) documentation.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

render(
  <Form schema={schema} validator={validator}>
    <div>
      <button type='submit'>Submit</button>
      <button type='button'>Cancel</button>
    </div>
  </Form>,
  document.getElementById('app'),
);
```

> **Warning:** There needs to be a button or an input with `type="submit"` to trigger the form submission (and then the form validation).

## customValidate

Formerly the `validate` prop.
The `customValidate` prop requires a function that specifies custom validation rules for the form.
See [Validation](../usage/validation.md) for more information.

## experimental_componentUpdateStrategy

Experimental feature to specify an alternative component update strategy that accepts one of the following value:
React's default `Component` rendering strategy is to re-render on every state change, see `shouldComponentUpdate` docs.
`PureComponent`'s strategy uses shallow equality. One can also always update (not recommended for performance reasons, but can be useful for testing)

| Option     | Description                                       |
| ---------- | ------------------------------------------------- |
| customDeep | Legacy behavior - uses RJSF's deepEquals function |
| shallow    | shallow equality                                  |
| always     | component always rerenders                        |

## experimental_defaultFormStateBehavior

Experimental features to specify different form state behavior.
Currently, this only affects the handling of optional array fields where `minItems` is set and handling of setting defaults based on the value of `emptyObjectFields`.

> **Warning:** This API is experimental and unstable, therefore breaking changes may be shipped in minor or patch releases. If you want to use this feature, we recommend pinning exact versions of `@rjsf/\*` packages in your package.json file or be ready to update your use of it when necessary.

The following subsections represent the different keys in this object, with the tables explaining the values and their meanings.

### arrayMinItems

This optional subsection is an object with two optional fields, `populate` and `mergeExtraDefaults`.
When not specified, it defaults to `{ populate: 'all', mergeExtraDefaults: false }`.

#### arrayMinItems.populate

Optional enumerated flag controlling how array minItems are populated, defaulting to `all`:

| Flag Value     | Description                                                                                                                                        |
| -------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
| `all`          | Legacy behavior - populate minItems entries with default values initially and include empty array when no values have been defined.                |
| `requiredOnly` | Ignore `minItems` on a field when calculating defaults unless the field is required.                                                               |
| `never`        | Ignore `minItems` on a field when calculating defaults for required and non-required. Value will set only if defined `default` and from `formData` |

#### arrayMinItems.computeSkipPopulate

The signature and documentation for this property is as follow:

##### computeSkipPopulate &lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

A function that determines whether to skip populating the array with default values based on the provided validator, schema, and root schema.
If the function returns `true`, the array will not be populated with default values.
If the function returns `false`, the array will be populated with default values according to the `populate` option.

###### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that is used to detect valid schema conditions
- schema: S - The schema for which resolving a condition is desired
- [rootSchema]: S - The root schema that will be forwarded to all the APIs

###### Returns

- boolean: A boolean indicating whether to skip populating the array with default values.

##### Example

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    stringArray: {
      type: 'array',
      items: { type: 'string' },
      minItems: 1,
    },
    numberArray: {
      type: 'array',
      items: { type: 'number' },
      minItems: 1,
    },
  },
  required: ['stringArray', 'numberArray'],
};

const computeSkipPopulateNumberArrays = (validator, schema, rootSchema) =>
  // These conditions are needed to narrow down the type of the schema.items
  !Array.isArray(schema?.items) &&
  typeof schema?.items !== 'boolean' &&
  schema?.items?.type === 'number',

render(
  <Form
    schema={schema}
    validator={validator}
    experimental_defaultFormStateBehavior={{
      arrayMinItems: {
        computeSkipPopulate: computeSkipPopulateNumberArrays,
      },
    }}
  />,
  document.getElementById('app')
);
```

#### arrayMinItems.mergeExtraDefaults

Optional boolean flag, defaulting to `false` when not specified.
When `formData` is provided and does not contain `minItems` worth of data, this flag controls whether the extra data provided by the defaults is appended onto the existing `formData` items to ensure the `minItems` condition is met.
When `false` (legacy behavior), only the `formData` provided is merged into the default form state, even if there are fewer than the `minItems`.
When `true`, the defaults are appended onto the end of the `formData` until the `minItems` condition is met.

### emptyObjectFields

Optional enumerated flag controlling how empty object fields are populated, defaulting to `populateAllDefaults`:

| Flag Value                 | Description                                                                                                                 |
| -------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `populateAllDefaults`      | Legacy behavior - set default when there is a primitive value, an non-empty object field, or the field itself is required   |
| `populateRequiredDefaults` | Only sets default when a value is an object and its parent field is required, or it is a primitive value and it is required |
| `skipDefaults`             | Does not set defaults                                                                                                       |
| `skipEmptyDefaults`        | Does not set an empty default. It will still apply the default value if a default property is defined in your schema        |

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: { type: 'string' },
  minItems: 3,
};

render(
  <Form
    schema={schema}
    validator={validator}
    experimental_defaultFormStateBehavior={{
      emptyObjectFields: 'populateRequiredDefaults',
    }}
  />,
  document.getElementById('app'),
);
```

### allOf

Optional enumerated flag controlling how empty defaults are populated when `allOf` schemas are provided, defaulting to `skipDefaults`:

| Flag Value         | Description                                                                                                               |
| ------------------ | ------------------------------------------------------------------------------------------------------------------------- |
| `skipDefaults`     | Skip parsing defaults from `allOf` schemas nested inside the schema defaults are computed from, with the exceptions below |
| `populateDefaults` | Generate default values for properties in the `allOf` schema including `if-then-else` syntax                              |

`skipDefaults` only skips the `allOf` schemas nested inside the schema that defaults are computed from, not that schema's own `allOf`.
Which schema that is depends on what the form is doing:

- When the form computes defaults from the root schema, a root-level `allOf` provides its defaults with either value.
- Some actions compute defaults from a subschema as if it were the root, such as adding an array item or optional data, or switching a `oneOf` or `anyOf` option, so that subschema's own `allOf` provides its defaults with either value. When switching options, though, the `if` of an `if-then-else` in the new option's `allOf` is checked against the data of the option being left, so under `skipDefaults` its `then` default is filled in only when that data matches the `if`.
- The option picked on the initial render is not computed as if it were the root, even when its `oneOf` or `anyOf` is in the root schema, so under `skipDefaults` its `allOf` is left out until the user switches away from that option and back.

The branch of an `if-then-else` is picked from the form data, not from the computed defaults, except in a `dependencies` entry, as the last item below says:

- When the `if` lists a property in `required` and only a default provides that property, the `then` default is left out until the form data holds the value, for instance on the initial render.
- Without `required`, a missing property still satisfies the `if`'s `properties`, so such an `if` passes with no data, and its `then` default is filled in even when the `if` does not match the defaulted value.
- With one `allOf` entry per `enum` value and no form data, the default `allOf` merger merges the `then` defaults of all the entries, and the first entry that defaults a property wins. An `experimental_customMergeAllOf` that throws on the conflicting `default`s drops the whole `allOf` instead.

An `allOf` in an object property or in an array's `items` is skipped as a whole, plain property defaults included, so it usually needs `populateDefaults` to provide its defaults.
This is specific to `allOf`:

- An `if-then-else` placed directly in a nested object schema is resolved with either value, unless `emptyObjectFields` is `skipEmptyDefaults`. For example, under `skipDefaults`, `items: { type: 'object', if, then }` fills in the `then` default, while `items: { type: 'object', allOf: [{ if, then }] }` does not.
- Adding a direct `if` to that `items` schema resolves its whole `allOf` too, unless `emptyObjectFields` is `skipEmptyDefaults`.
- With an `experimental_customMergeAllOf` built on a deep merger, such as `createDeepAllOfMerge` from `@x0k/json-schema-merge` given a shallow merge built with that library's `createMerger` and `createShallowAllOfMerge`, merging an `allOf` also turns a property's `allOf: [{ if, then }]` into a direct `if-then-else`, so that property's `then` default is filled in under `skipDefaults`, unless `emptyObjectFields` is `skipEmptyDefaults`. That happens wherever an `allOf` is merged: the root's own `allOf`, or the `allOf` of an object or `items` schema that also has a direct `if`, but not a nested `allOf` on its own.
- A `dependencies` entry in a nested object schema is resolved once its property has a value, its `allOf` and `if-then-else` included, even when `emptyObjectFields` is `skipEmptyDefaults`. A default counts as that value, and the entry's `if` is checked against it, so an `if` that lists the property in `required` passes with no form data, while one that does not match the default fails. For example, under `skipDefaults`, `items: { type: 'object', properties: { animal: { default: 'Cat' } }, dependencies: { animal: { allOf: [{ if, then }] } } }` fills in the `then` default. A root `dependencies` entry counts a default only while the form data is empty: once the form data holds any value, the entry is applied only when the form data holds its property.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Example',
  type: 'object',
  properties: {
    animalInfo: {
      properties: {
        animal: {
          type: 'string',
          default: 'Cat',
          enum: ['Cat', 'Fish'],
        },
      },
      allOf: [
        {
          if: {
            properties: {
              animal: {
                const: 'Cat',
              },
            },
          },
          then: {
            properties: {
              food: {
                type: 'string',
                default: 'meat',
                enum: ['meat', 'grass', 'fish'],
              },
            },
            required: ['food'],
          },
        },
      ],
    },
  },
};

render(
  <Form
    schema={schema}
    validator={validator}
    experimental_defaultFormStateBehavior={{
      allOf: 'populateDefaults',
    }}
  />,
  document.getElementById('app'),
);
```

### constAsDefaults

Optional enumerated flag controlling how const values are merged into the form data as defaults when dealing with undefined values, defaulting to `always`.
The defaulting behavior for this flag will always be controlled by the `emptyObjectField` flag value.
For instance, if `populateRequiredDefaults` is set and the const value is not required, it will not be set.

| Flag Value  | Description                                                                                                                                                                                                                     |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `always`    | A const value will always be merged into the form as a default. If there is are const values in a `oneOf` (for instance to create an enumeration with title different from the values), the first const value will be defaulted |
| `skipOneOf` | If const is in a `oneOf` it will NOT pick the first value as a default                                                                                                                                                          |
| `never`     | A const value will never be used as a default                                                                                                                                                                                   |

### mergeDefaultsIntoFormData

Optional enumerated flag controlling how the defaults are merged into the form data when dealing with undefined values, defaulting to `useFormDataIfPresent`.

NOTE: If there is a default for a field and the `formData` is unspecified, the default ALWAYS merges.

| Flag Value                      | Description                                                                                                                               |
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `useFormDataIfPresent`          | Legacy behavior - Do not merge defaults if there is a value for a field in `formData` even if that value is explicitly set to `undefined` |
| `useDefaultIfFormDataUndefined` | If the value of a field within the `formData` is `undefined`, then use the default value instead                                          |

### nestedDefaultsPrecedence

Optional enumerated flag controlling how defaults defined on multiple levels are merged together for overlapping properties, defaulting to `descendantWins`.

| Flag Value       | Description                                                                                       |
| -----------------| --------------------------------------------------------------------------------------------------|
| `descendantWins` | The innermost (descendant) default value definition takes precedence over its ancestor's defaults |
| `ancestorWins`   | The outermost (ancestor) default value definition takes precedence over any descendant's defaults |

#### Example

In the following example, the `animal` property is a descendant of the root schema and both define a default value for `animal`. By default, the `animal`'s default value `Cat` would take precedence over its ancestor's `Fish`. However, since `nestedDefaultsPrecedence` is set to `ancestorWins`, the root schema's default value takes precedence and `animal` is set to `Fish` by default.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  default: {
    animal: 'Fish',
  },
  properties: {
    animal: {
      type: 'string',
      default: 'Cat',
      enum: ['Cat', 'Fish'],
    },
  },
};

render(
  <Form
    schema={schema}
    validator={validator}
    experimental_defaultFormStateBehavior={{
      nestedDefaultsPrecedence: 'ancestorWins',
    }}
  />,
  document.getElementById('app'),
);
```

### requiredBooleanDefault

Optional enumerated flag controlling whether a boolean listed in its parent's `required` array, with no `default` of its own, is populated with `false`, defaulting to `populateFalse`.
An explicit schema `default`, a parent default and an existing `formData` value always take precedence; this flag only decides what happens when none of them provides a value.

| Flag Value      | Description                                                                                                                    |
| --------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `populateFalse` | A required boolean with no `default` is set to `false`                                                                         |
| `skip`          | No value is synthesized; the property stays `undefined` until the user answers it, so `required` remains a validation concern |

#### Example

In the following example, `agree` is required but has no `default`. By default it would start as `false`, and the form would report `{ agree: false }` through `onChange` on mount. With `requiredBooleanDefault` set to `skip`, `formData` stays `{}` until the user answers, and validation reports `agree` as missing until then. This is the behavior to choose when a boolean question is rendered with an explicit "unanswered" state, for example a `- - -` / Yes / No select, rather than a checkbox.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    agree: {
      type: 'boolean',
      title: 'Do you agree?',
    },
  },
  required: ['agree'],
};

render(
  <Form
    schema={schema}
    validator={validator}
    experimental_defaultFormStateBehavior={{
      requiredBooleanDefault: 'skip',
    }}
  />,
  document.getElementById('app'),
);
```

## experimental_customMergeAllOf

The `experimental_customMergeAllOf` function allows you to provide a custom implementation for merging `allOf` schemas. This can be particularly useful in case the where the default merge library ([@x0k/json-schema-merge](https://github.com/x0k/json-schema-merge/)) doesn't satisfy your functional or performance requirements.

By providing your own implementation, you can potentially achieve significant performance improvements. For instance, if your use case only requires a subset of JSON Schema features, you can implement a faster, more tailored merging strategy.

If you're looking for alternative `allOf` merging implementations, you might consider [allof-merge](https://github.com/udamir/allof-merge).

**Warning:** This is an experimental feature. Only use this if you fully understand the implications of custom `allOf` merging and are prepared to handle potential edge cases. Incorrect implementations may lead to unexpected behavior or validation errors.

```tsx
import { Form } from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';

const customMergeAllOf = (schema: RJSFSchema): RJSFSchema => {
  // Your custom implementation here
};

render(
  <Form schema={schema} validator={validator} experimental_customMergeAllOf={customMergeAllOf} />,
  document.getElementById('app'),
);
```

## disabled

It's possible to disable the whole form by setting the `disabled` prop. The `disabled` prop is then forwarded down to each field of the form.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

render(<Form schema={schema} validator={validator} disabled />, document.getElementById('app'));
```

If you just want to disable some fields, see the `ui:disabled` parameter in `uiSchema`.

## readonly

It's possible to make the whole form read-only by setting the `readonly` prop. The `readonly` prop is then forwarded down to each field of the form.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

render(<Form schema={schema} validator={validator} readonly />, document.getElementById('app'));
```

If you just want to make some fields read-only, see the `ui:readonly` parameter in `uiSchema`.

## enctype

The value of this prop will be passed to the `enctype` [HTML attribute on the form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-enctype).

## extraErrors

This prop allows passing in custom errors that are augmented with the existing JSON Schema errors on the form; it can be used to implement asynchronous validation.
By default, these are non-blocking errors, meaning that you can still submit the form when these are the only errors displayed to the user.
See [Validation](../usage/validation.md) for more information.

## extraErrorsBlockSubmit

If set to true, causes the `extraErrors` to become blocking when the form is submitted.

## fields

Dictionary of registered fields in the form. See [Custom Widgets and Fields](../advanced-customization/custom-widgets-fields.md) for more information.

## focusOnFirstError

If set to true, then the first field with an error will receive the focus when the form is submitted with errors.

You can also provide a custom callback function to handle what happens when this function is called.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, RJSFValidationError } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

const focusOnError = (error: RJSFValidationError) => {
  console.log('I need to handle focusing this error');
};

render(<Form schema={schema} validator={validator} focusOnFirstError={focusOnError} />, document.getElementById('app'));
```

## formContext

You can provide a `formContext` object to the Form, which is passed down to all fields and widgets. Useful for implementing context aware fields and widgets.

See [AntD Customization](themes/antd/uiSchema.md#formcontext) for formContext customizations for the `antd` theme.
See [Semantic UI Customization](themes/semantic-ui/uiSchema.md#formcontext) for formContext customizations for the `semantic-ui` theme.

## formData

The data for the form, used to load a "controlled" form with its current data. If you want an "uncontrolled" form with initial data, then use `initialFormData` instead.

## id

The value of this prop will be passed to the `id` [HTML attribute on the form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form).

## idPrefix

To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids (the default is `root`).

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

render(<Form schema={schema} validator={validator} idPrefix={'rjsf_prefix'} />, document.getElementById('app'));
```

This will render `<input id="rjsf_prefix_key">` instead of `<input id="root_key">`

## idSeparator

To avoid using a path separator that is present in field names, it is possible to change the separator used for ids (the default is `_`).

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    first: {
      type: 'string',
    },
  },
};

render(<Form schema={schema} validator={validator} idSeparator={'/'} />, document.getElementById('app'));
```

This will render `<input id="root/first">` instead of `<input
id="root_first">` when rendering `first`.

## initialFormData

The initial data for the form, used to fill an "uncontrolled" form with existing data on the initial render and when `reset()` is called programmatically.

## nameGenerator

The `nameGenerator` prop allows you to customize how HTML `name` attributes are generated for form fields. This is essential when submitting form data to backend frameworks that expect specific naming conventions for structured data.

**Default behavior:** When no `nameGenerator` is provided, the `name` attribute will equal the `id` attribute (e.g., `root_tasks_0_title`).

RJSF provides two built-in generators:

**`bracketNameGenerator`** - Generates bracket notation for PHP/Rails (e.g., `root[tasks][0][title]`). Automatically appends `[]` for multi-value fields like checkboxes.

**`dotNotationNameGenerator`** - Generates dot notation for other frameworks (e.g., `root.tasks.0.title`).

```tsx
import { Form } from '@rjsf/core';
import { bracketNameGenerator, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    firstName: { type: 'string' },
    tasks: {
      type: 'array',
      items: {
        type: 'object',
        properties: {
          title: { type: 'string' },
        },
      },
    },
  },
};

render(
  <Form schema={schema} validator={validator} nameGenerator={bracketNameGenerator} />,
  document.getElementById('app'),
);
```

You can also create a custom generator by implementing the `NameGeneratorFunction` type, which receives `path` (array of path segments), `idPrefix` (typically `'root'`), and optional `isMultiValue` (boolean for multi-value fields).

## liveOmit

Flag that describes when live omit will be performed. Live omit happens only when `omitExtraData` is also set to
to `true` and the form's data is updated by the user.

If no value (or `false`) is provided, then live omit will not happen. If `true` or `onChange` is provided for
the flag, then live omit will be performed after processing of all pending changes has completed. If `onBlur`
is provided, then live omit will be performed when a field that was updated is blurred (as a performance
optimization).

> NOTE: The `boolean` options for this flag is deprecated and will be removed in a future major release

## liveValidate

Flag that describes when live validation will be performed. Live validation means that the form will perform
validation and show any validation errors whenever the form data is updated, rather than just on submit.

If no value (or `false`) is provided, then live validation will not happen. If `true` or `onChange` is provided for
the flag, then live validation will be performed after processing of all pending changes has completed. If `onBlur`
is provided, then live validation will be performed when a field that was updated is blurred (as a performance
optimization).

> NOTE: The `boolean` options for this flag is deprecated and will be removed in a future major release

## method

The value of this prop will be passed to the `method` [HTML attribute on the form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-method).

## name

The value of this prop will be passed to the `name` [HTML attribute on the form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-name).

## noHtml5Validate

If set to true, turns off HTML5 validation on the form. Set to `false` by default.

## noValidate

If set to true, turns off all validation. Set to `false` by default.

> NOTE: In a future major release, this flag may be deleted replaced by making `validator` prop optional

## omitExtraData

If set to true, then extra form data values that are not in any form field will be removed whenever `onSubmit` is called. Set to `false` by default.

## onBlur

Sometimes you may want to trigger events or modify external state when a field has been touched, so you can pass an `onBlur` handler, which will receive the id of the input that was blurred and the field value.

## onChange

If you plan on being notified every time the form data are updated, you can pass an `onChange` handler, which will receive the same first argument as `onSubmit` any time a value is updated in the form.
It will also receive, as the second argument, the `id` of the field which experienced the change.
Generally, this will be the `id` of the field for which input data is modified.
In the case of adding/removing of new fields in arrays or objects with `additionalProperties` or `patternProperties` and the rearranging of items in arrays, the `id` will be that of the array or object itself, rather than the item/field being added, removed or moved.

## onError

To react when submitted form data are invalid, pass an `onError` handler. It will be passed the list of encountered errors:

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};
const onError = (errors) => console.log('I have', errors.length, 'errors to fix');

render(<Form schema={schema} validator={validator} onError={onError} />, document.getElementById('app'));
```

## onFocus

Sometimes you may want to trigger events or modify external state when a field has been focused, so you can pass an `onFocus` handler, which will receive the id of the input that is focused and the field value.

## onSubmit

You can pass a function as the `onSubmit` prop of your `Form` component to listen to when the form is submitted and its data are valid.
It will be passed a result object having a `formData` attribute, which is the valid form data you're usually after.
The original event will also be passed as a second parameter:

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};
const onSubmit = ({ formData }, e) => console.log('Data submitted: ', formData);

render(<Form schema={schema} validator={validator} onSubmit={onSubmit} />, document.getElementById('app'));
```

> Note: If there are fields in the `formData` that are not represented in the schema, they will be retained by default. If you would like to remove those extra values on form submission, you may need to set the `omitExtraData` and/or `liveOmit` props.

## removeEmptyOptionalObjects

> **Deprecated**: This prop no longer has any effect and will be removed in a future release. The behavior of pruning optional empty objects is now built into [`omitExtraData`](#omitextradata) — enable that prop instead.

When a JSON Schema has a required field inside an optional object, any user interaction with that optional object "activates" it. Even if the user clears all the fields within that object, the empty object property (e.g., `{ test: {} }` or `{ test: { field1: "" } }`) remains in the `formData`. Because the object contains required fields that are now empty, the form becomes unsubmittable.

Previously, setting `removeEmptyOptionalObjects` to `true` caused the form to recursively prune these optional empty objects from the `formData` during `onChange`, `onBlur`, and `onSubmit`. This pruning is now performed automatically by `omitExtraData`.

## schema

**Required**! Form schema. We support JSON schema draft-07 by default. See [Schema Reference](https://json-schema.org/draft-07/json-schema-release-notes.html) for more information.

## showErrorList

When this prop is set to `top` or `bottom`, a list of errors (or the custom error list defined in the `ErrorList`) will also show at the `bottom` or `top` of the form. When set to false, only inline input validation errors will be shown. Set to `top` by default. See [Validation](../usage/validation.md) for more information.

## tagName

It's possible to change the default `form` tag name to a different HTML tag, which can be helpful if you are nesting forms. However, native browser form behaviour, such as submitting when the `Enter` key is pressed, may no longer work.

```tsx
<Form
  tagName="div"
  ...
/>
```

You can also provide a class/function component.

```tsx
const CustomForm = props => <form {...props} style={...} className={...} />
// ...
<Form
  tagName={CustomForm}
  ...
/>
```

## target

The value of this prop will be passed to the `target` [HTML attribute on the form](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/form#attr-target).

## templates

Dictionary of registered templates in the form. See [Custom Templates](../advanced-customization/custom-templates.md) for more information.

## transformErrors

A function can be passed to this prop in order to make modifications to the default errors resulting from JSON Schema validation. See [Validation](../usage/validation.md) for more information.

## translateString

Optional string translation function, if provided, allows users to change the translation of the RJSF internal strings.
Some strings contain replaceable parameter values as indicated by `%1`, `%2`, etc.
The number after the `%` indicates the order of the parameter.
The ordering of parameters is important because some languages may choose to put the second parameter before the first in its translation. In addition to replaceable parameters, some of the strings support the use of markdown and simple html.

One can use the [documentation](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/utils/src/enums.ts) of the `TranslatableString` enums to determine which enum values contain replaceable parameters and which support markdown and simple html.

One could use this function to alter one or more of the existing english strings to better suit one's application or fully translate all strings into a different language.
Below is an example of changing a few of the english strings to something else:

```ts
import { TranslatableString, englishStringTranslator, replaceStringParameters } from '@rjsf/utils';

function fixupSomeEnglishStrings(stringToTranslate: TranslatableString, params?: string[]): string {
  switch (stringToTranslate) {
    case TranslatableString.NewStringDefault:
      return ''; // Use an empty string for the new additionalProperties string default value
    case TranslatableString.KeyLabel:
      return replaceStringParameters('%1 Key Name', params); // Add "Name" onto the end of the WrapIfAdditionalTemplate key label
    default:
      return englishStringTranslator(stringToTranslate, params); // Fallback to the default english
  }
}
```

## uiSchema

Form uiSchema. See [uiSchema Reference](uiSchema.md) for more information.

## useFallbackUiForUnsupportedType

If set to true, when an unsupported schema type is encountered, the form will render a fallback UI instead of displaying an error. The fallback UI will display a widget that allows the user to select a JSON Schema primitive type, and a field containing the form data that matches the selected type. Set to false by default.

## validator

**Required**! An implementation of the `ValidatorType` interface that is needed for form validation to work.
`@rjsf/validator-ajv8` exports the implementation of this interface from RJSF version 4.

## widgets

Dictionary of registered widgets in the form. See [Custom Widgets and Fields](../advanced-customization/custom-widgets-fields.md) for more information.

---

### Packages Docs Docs Api Reference UiSchema (`packages/docs/docs/api-reference/uiSchema.md`)

# uiSchema

JSON Schema is limited for describing how a given data type should be rendered as a form input component. That's why this library introduces the concept of uiSchema.

A UI schema is basically an object literal providing information on **how** the form should be rendered, while the JSON schema tells **what**.

The uiSchema object follows the tree structure of the form field hierarchy, and defines how each property should be rendered.

Note that almost every property within uiSchema can be rendered in one of two ways: `{"ui:options": {[property]: [value]}}`, or `{"ui:[property]": value}`.

In other words, the following `uiSchema`s are equivalent:

```json
{
  "ui:title": "Title",
  "ui:description": "Description",
  "ui:classNames": "my-class",
  "ui:submitButtonOptions": {
    "props": {
      "disabled": false,
      "className": "btn btn-info"
    },
    "norender": false,
    "submitText": "Submit"
  }
}
```

```json
{
  "ui:options": {
    "title": "Title",
    "description": "Description",
    "classNames": "my-class",
    "submitButtonOptions": {
      "props": {
        "disabled": false,
        "className": "btn btn-info"
      },
      "norender": false,
      "submitText": "Submit"
    }
  }
}
```

For a full list of what is supported in the `uiSchema` see the `UiSchema` type in [@rjsf/utils/types.ts](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/utils/src/types.ts).
Be sure to pay attention to the hierarchical intersection to these other types: `UIOptionsBaseType` and `TemplatesType`.

## Exceptions to the equivalence

There are 4 properties that exist in a `UiSchema` that will not be found in an inner `ui:options` object.

### `ui:globalOptions`

The set of globally relevant `UiSchema` options that are read from the root-level `UiSchema` and stored in the `registry` for use everywhere.

```ts
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:globalOptions': { copyable: true },
};
```

### `ui:definitions`

The `ui:definitions` property allows you to define reusable UI customizations for schema `$ref` references. This is particularly useful for:

- **Recursive schemas** - Define uiSchema once for a self-referencing schema node
- **Reused definitions** - Apply consistent UI to schemas used in multiple places
- **oneOf/anyOf branches** - Provide different uiSchema for branches that reference different definitions

The keys in `ui:definitions` must match the exact `$ref` path used in the schema (e.g., `#/definitions/address` or `#/$defs/node`).

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  definitions: {
    address: {
      type: 'object',
      properties: {
        street_address: { type: 'string' },
        city: { type: 'string' },
      },
    },
    node: {
      type: 'object',
      properties: {
        name: { type: 'string' },
        children: {
          type: 'array',
          items: { $ref: '#/definitions/node' }, // Recursive reference
        },
      },
    },
  },
  type: 'object',
  properties: {
    billing_address: { $ref: '#/definitions/address' },
    shipping_address: { $ref: '#/definitions/address' },
    tree: { $ref: '#/definitions/node' },
  },
};

const uiSchema: UiSchema = {
  'ui:definitions': {
    '#/definitions/address': {
      street_address: { 'ui:placeholder': 'Street and number' },
      city: { 'ui:placeholder': 'City name' },
    },
    '#/definitions/node': {
      name: { 'ui:placeholder': 'Enter node name' },
      children: { 'ui:options': { orderable: false } },
    },
  },
  // Local overrides take precedence over ui:definitions
  shipping_address: {
    street_address: { 'ui:placeholder': 'Shipping street (overrides definition)' },
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

#### Local Overrides

You can override specific properties from `ui:definitions` by providing values at the field path. Local values are merged with definitions, with local values taking precedence.

#### oneOf/anyOf with Same Property Names

When using `oneOf` or `anyOf` with branches that have properties with the same name, each branch's `$ref` maps to its own entry in `ui:definitions`, ensuring correct UI is applied:

```tsx
const schema: RJSFSchema = {
  definitions: {
    person: { type: 'object', properties: { name: { type: 'string' } } },
    company: { type: 'object', properties: { name: { type: 'string' } } },
  },
  type: 'object',
  properties: {
    contact: {
      oneOf: [
        { title: 'Person', $ref: '#/definitions/person' },
        { title: 'Company', $ref: '#/definitions/company' },
      ],
    },
  },
};

const uiSchema: UiSchema = {
  'ui:definitions': {
    '#/definitions/person': {
      name: { 'ui:placeholder': 'Full name (e.g., John Doe)' },
    },
    '#/definitions/company': {
      name: { 'ui:placeholder': 'Company name (e.g., Acme Inc.)' },
    },
  },
};
```

### `ui:rootFieldId` (deprecated)

> DEPRECATED: Use `Form.idPrefix` instead, will be removed in a future major version

By default, this library will generate ids unique to the form for all rendered widgets.
If you plan on using multiple instances of the `Form` component in a same page, it's wise to declare a root prefix for these, using the `ui:rootFieldId` uiSchema directive:

```ts
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:rootFieldId': 'myform',
};
```

This will make all widgets have an id prefixed with `myform`.

### `ui:field`

The `ui:field` property overrides the `Field` implementation used for rendering any field in the form's hierarchy.
Specify either the name of a field that is used to look up an implementation from the `fields` list or an actual one-off `Field` component implementation itself.

See [Custom Widgets and Fields](../advanced-customization/custom-widgets-fields.md#custom-field-components) for more information about how to use this property.

### `ui:fieldReplacesAnyOrOneOf`

By default, any field that is rendered for an `anyOf`/`oneOf` schema will be wrapped inside the `AnyOfField` or `OneOfField` component.
This default behavior may be undesirable if your custom field already handles behavior related to choosing one or more subschemas contained in the `anyOf`/`oneOf` schema.
By providing a `true` value for this flag in association with a custom `ui:field`, the wrapped components will be omitted, so just one instance of the custom field will be rendered.
If the flag is omitted or set to `false`, your custom field will be wrapped by `AnyOfField`/`OneOfField`.

### `ui:options`

The `ui:options` property cannot be nested inside itself and thus is the last exception.

## `ui:XXX` or `ui:options.XXX`

All the properties that follow can be specified in the `uiSchema` in either of the two equivalent ways.

> NOTE: The properties specific to array items can be found [here](../json-schema/arrays.md#array-item-uiSchema-options). For advanced dynamic UI schema capabilities for array items, see the [Dynamic UI Schema Examples](./dynamic-ui-schema-examples.md).

### widget

The `ui:widget` property overrides the `Widget` implementation used for rendering any field in the form's hierarchy.
Specify either the name of a widget that is used to look up an implementation from the `widgets` list or an actual one-off `Widget` component implementation itself.

See [Custom Widgets and Fields](../advanced-customization/custom-widgets-fields.md) for more information about how to use this property.

### classNames

The uiSchema object accepts a `ui:classNames` property for each field of the schema:

```tsx
import { UiSchema } from '@rjsf/utils';

const uiSchema = {
  title: {
    'ui:classNames': 'task-title foo-bar',
  },
};
```

Will result in:

```html
<div class="field field-string task-title foo-bar">
  <label>
    <span>Title*</span>
    <input value="My task" required="" type="text" />
  </label>
</div>
```

### style

The uiSchema object accepts a `ui:style` property for each field of the schema:

```tsx
import { UiSchema } from '@rjsf/utils';

const uiSchema = {
  title: {
    'ui:style': { color: 'red' },
  },
};
```

Will result in:

```html
<div class="field field-string task-title" style={{ color: "red" }}>
  <label>
    <span>Title*</span>
    <input value="My task" required="" type="text">
  </label>
</div>
```

### allowClearTextInputs

The optional `ui:allowClearTextInputs` uiSchema directive enables a clear/reset button for text-based input widgets.
When set to true, a clear button will be displayed when the input field has a value and is not readonly or disabled.
When omitted, no clear button will be displayed for text input fields.

When clicked, the property value will be set to the `ui:emptyValue`, if defined.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:allowClearTextInputs': true,
};
```

It can also be enabled globally by setting the `allowClearTextInputs` option to `true` in the `ui:globalOptions`
uiSchema directive.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:globalOptions': {
    allowClearTextInputs: true,
  },
};
```

### autocomplete

If you want to mark a text input, select or textarea input to use the HTML autocomplete feature, set the `ui:autocomplete` uiSchema directive to a valid [HTML autocomplete value](https://developer.mozilla.org/en-US/docs/Web/HTML/Attributes/autocomplete#values).

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:widget': 'textarea',
  'ui:autocomplete': 'on',
};
```

### autocapitalize

To control automatic capitalization on virtual keyboards for a text input, set the `ui:autocapitalize` uiSchema
directive to a valid [HTML autocapitalize value](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autocapitalize#value).

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:autocapitalize': 'words',
};
```

### autofocus

If you want to automatically focus on a text input or textarea input, set the `ui:autofocus` uiSchema directive to `true`.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:widget': 'textarea',
  'ui:autofocus': true,
};
```

### description

Sometimes it's convenient to change the description of a field. This is the purpose of the `ui:description` uiSchema directive:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:widget': 'password',
  'ui:description': 'The best password',
};
```

### deprecatedHandling

The `ui:deprecatedHandling` uiSchema directive controls how a field marked as `deprecated` in the JSON Schema is rendered.

Accepts one of three values:

- `'label'` (default): The field is rendered normally with `"(deprecated)"` appended to its label.
- `'disable'`: The field is rendered but all its child widgets are disabled.
- `'hide'`: The field is completely hidden from the form.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    legacyField: { type: 'string', deprecated: true },
  },
};

const uiSchema: UiSchema = {
  legacyField: {
    'ui:options': {
      deprecatedHandling: 'disable',
    },
  },
};
```

It can also be set globally by specifying the `deprecatedHandling` option in the `ui:globalOptions` uiSchema directive, which applies the chosen behavior to every deprecated field in the form.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    legacyField: { type: 'string', deprecated: true },
    anotherOldField: { type: 'number', deprecated: true },
  },
};

const uiSchema: UiSchema = {
  'ui:globalOptions': {
    deprecatedHandling: 'hide',
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### disabled

The `ui:disabled` uiSchema directive will disable all child widgets from a given field.

> Note: If you're wondering about the difference between a `disabled` field and a `readonly` one: Marking a field as read-only will render it greyed out, but its text value will be selectable. Disabling it will prevent its value to be selected at all.

### enableMarkdownInDescription

The `ui:enableMarkdownInDescription` uiSchema directive enables the support of Markdown syntax within the description of
a field.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string', description: '**bolded** text in the description' };
const uiSchema: UiSchema = {
  'ui:enableMarkdownInDescription': true,
};
render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

It can also be enabled globally by setting the `enableMarkdownInDescription` option to `true` in the `ui:globalOptions`
uiSchema directive.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string', description: '**bolded** text in the description' };
const uiSchema: UiSchema = {
  'ui:globalOptions': {
    enableMarkdownInDescription: true,
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### enableMarkdownInHelp

The `ui:enableMarkdownInHelp` uiSchema directive enables the support of Markdown syntax within the help displayed for
a field.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:enableMarkdownInHelp': true,
  'ui:help': '**bolded** text in the help',
};
render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

It can also be enabled globally by setting the `enableMarkdownInHelp` option to `true` in the `ui:globalOptions`
uiSchema directive.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:globalOptions': {
    enableMarkdownInHelp: true,
  },
  'ui:help': '**bolded** text in the help',
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### enableOptionalDataFieldForType

The `ui:enableOptionalDataFieldForType` uiSchema directive enables support for displaying the `Optional Data Controls` feature.
The intention of this feature is to allow developers to provide a condensed UI for users who don't care to enter an optional list of array items or set of optional object fields (see [examples](#add-optional-data-controls) below).

This directive takes, as its value, an array in one of four forms:

1. `[]` - Disables the feature at a global or field level
2. `['array']` - Enables the feature only for optional arrays at a global or field level
3. `['object']` - Enables the feature only for optional object at a global or field level
4. `['array', 'object']`- Enables the feature for both optional object and arrays at a global or field level

It can be specified in either the `ui:globalOptions` to turn the feature on for everything or in a specific field's `uiSchema`
To work properly this option must be coupled with the [emptyObjectFields](./form-props.md#emptyobjectfields) experimental feature on `Form` using the `populateRequiredDefaults` or `skipDefaults` options.

When enabled for either (or both) the `array` or `object` types, any optional object or array field which has an "undefined" value in `formData` will NOT render any of the container's UI elements.
Instead the object/array container's field title will have an "Add optional data" icon button that, when clicked will cause an empty container data element to be added to `formData`.

When enabled for either (or both) the `array` or `object` types, any optional object or array field which has an "defined" value in `formData` will render all of the container's UI elements as normal AND the object/array container's field title will have a "Remove optional data" icon button that, when clicked will set the data for field in the `formData` to "undefined".

Here is an example of what the UI will look like when enabled using the following `Form` configuration:

```tsx
const schema: RJSFSchema = {
  title: 'test',
  properties: {
    nestedObjectOptional: {
      type: 'object',
      properties: {
        test: {
          type: 'string',
        },
      },
    },
    nestedArrayOptional: {
      type: 'array',
      items: {
        type: 'string',
      },
    },
  },
};
const uiSchema = {
  'ui:globalOptions': {
    enableOptionalDataFieldForType: ['object', 'array'],
  },
};
const experimental_defaultFormStateBehavior = {
  // Set the emptyObjectFields to only populate required defaults to highlight the code working
  emptyObjectFields: 'populateRequiredDefaults',
};

render(
  <Form
    schema={schema}
    validator={validator}
    uiSchema={uiSchema}
    experimental_defaultFormStateBehavior={experimental_defaultFormStateBehavior}
    templates={{ OptionalDataControlsTemplate }}
  />,
  document.getElementById('app'),
);
```

#### Add Optional Data Controls



#### Remove Optional Data Controls



### emptyValue

The `ui:emptyValue` uiSchema directive provides the value to store when the input for a field is emptied, whether by typing or by clicking the `ui:allowClearTextInputs` clear button. It defaults to `undefined`, which omits the field from the form data entirely.

### enumDisabled

To disable an option, use the `enumDisabled` property in uiSchema.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'string',
  enum: ['one', 'two', 'three'],
};

const uiSchema: UiSchema = {
  'ui:enumDisabled': ['two'],
};
```

### enumNames

Allows a user to provide labels for enum values in the schema. Can be an array (matched by index) or a map (matched by value).

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'number',
  enum: [1, 2, 3],
};

// Array form (matched by index)
const uiSchemaArray: UiSchema = {
  'ui:enumNames': ['one', 'two', 'three'],
};

// Map form (matched by value)
const uiSchemaMap: UiSchema = {
  'ui:enumNames': { 1: 'one', 2: 'two', 3: 'three' },
};
```

### enumOrder

Controls the display order of enum options. Use `'*'` to represent remaining values in their original schema order. Unlisted values not covered by `'*'` are dropped.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'string',
  enum: ['apple', 'banana', 'cherry', 'date'],
};

const uiSchema: UiSchema = {
  'ui:enumOrder': ['cherry', '*', 'apple'],
};
```

### filePreview

The `FileWidget` can be configured to show a preview of an image or a download link for non-images using this flag.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'string',
  format: 'data-url',
};
const uiSchema: UiSchema = {
  'ui:options': {
    filePreview: true,
  },
};
```

### help

Sometimes it's convenient to add text next to a field to guide the end user filling it. This is the purpose of the `ui:help` uiSchema directive:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:widget': 'password',
  'ui:help': 'Hint: Make it strong!',
};
```



Help texts work for any kind of field at any level, and will always be rendered immediately below the field component widget(s) (after contextualized errors, if any).

### hideError

The `ui:hideError` uiSchema directive will, if set to `true`, hide the default error display for the given field AND all of its child fields in the hierarchy.

If you need to enable the default error display of a child in the hierarchy after setting `hideError: true` on the parent field, simply set `hideError: false` on the child.

This is useful when you have a custom field or widget that utilizes either the `rawErrors` or the `errorSchema` to manipulate and/or show the error(s) for the field/widget itself.

### inputType

To change the input type (for example, `tel` or `email`) you can specify the `inputType` in the `ui:options` uiSchema directive.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:options': {
    inputType: 'tel',
  },
};
```

### label

Field labels are rendered by default.
Labels may be omitted on a per-field by setting the `label` option to `false` in the `ui:options` uiSchema directive.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:options': {
    label: false,
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

They can also be omitted globally by setting the `label` option to `false` in the `ui:globalOptions` uiSchema directive.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:globalOptions': {
    label: false,
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### optionValueFormat

Controls how enum-backed widgets (`select`, `radio`, `checkboxes`) encode option values in their DOM `value` attributes. Accepts `'indexed'` (default) or `'realValue'`.

- `'indexed'`: options are encoded as their array index (e.g. `value="0"`, `value="1"`). This is the historical behavior and keeps non-primitive enum values (objects, arrays) addressable without stringifying them.
- `'realValue'`: primitive option values are stringified directly (e.g. `value="admin"`, `value="42"`, `value="true"`). This enables native HTML form submission and browser autocomplete since the submitted value matches the enum value. Non-primitive values (objects, arrays) still fall back to their index because `String(obj)` would produce `"[object Object]"`.

The form data passed to `onChange` is always the typed enum value; this option only affects the DOM-level encoding. Can be specified in `ui:globalOptions` to apply to all enum-backed fields, or per-field in `ui:options`.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    role: { type: 'string', enum: ['admin', 'editor', 'viewer'] },
  },
};

// Form-wide
const uiSchema: UiSchema = {
  'ui:globalOptions': {
    optionValueFormat: 'realValue',
  },
};

// Or per-field
const fieldUiSchema: UiSchema = {
  role: {
    'ui:options': {
      optionValueFormat: 'realValue',
    },
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### order

This property allows you to reorder the properties that are shown for a particular object. See [Objects](../json-schema/objects.md) for more information.

### placeholder

You can add placeholder text to an input by using the `ui:placeholder` uiSchema directive:

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string', format: 'uri' };
const uiSchema: UiSchema = {
  'ui:placeholder': 'http://',
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

Fields using `enum` can also use `ui:placeholder`. The value will be used as the text for the empty option in the select widget.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string', enum: ['First', 'Second'] };
const uiSchema: UiSchema = {
  'ui:placeholder': 'Choose an option',
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### readonly

The `ui:readonly` uiSchema directive will mark all child widgets from a given field as read-only. This is equivalent to setting the `readOnly` property in the schema.

> Note: If you're wondering about the difference between a `disabled` field and a `readonly` one: Marking a field as read-only will render it greyed out, but its text value will be selectable. Disabling it will prevent its value to be selected at all.

### rows

You can set the initial height of a textarea widget by specifying `rows` option.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:options': {
    widget: 'textarea',
    rows: 15,
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### title

Sometimes it's convenient to change a field's title. This is the purpose of the `ui:title` uiSchema directive:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = { type: 'string' };
const uiSchema: UiSchema = {
  'ui:widget': 'password',
  'ui:title': 'Your password',
};
```

### submitButtonOptions

Sometimes it's convenient to change the behavior of the submit button for the form. This is the purpose of the `ui:submitButtonOptions` uiSchema directive:

You can pass any other prop to the submit button if you want, by default, this library will set the following options / props mentioned below for all submit buttons:

#### `norender` option

You can set this property to `true` to remove the submit button completely from the form. Nice option, if the form is just for viewing purposes.

#### `submitText` option

You can use this option to change the text of the submit button. Set to "Submit" by default.

#### `props` section

You can pass any other prop to the submit button if you want, via this section.

##### `disabled` prop

You can use this option to disable the submit button.

##### `className` prop

You can use this option to specify a class name for the submit button.

```tsx
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:submitButtonOptions': {
    props: {
      disabled: false,
      className: 'btn btn-info',
    },
    norender: false,
    submitText: 'Submit',
  },
};
```

## `duplicateKeySuffixSeparator` option

When using `additionalProperties`, key collision is prevented by appending a unique integer suffix to the duplicate key.
For example, when you add a key named `myKey` to a form where `myKey` is already defined, then your new key will become `myKey-1`.
You can use `ui:duplicateKeySuffixSeparator` to override the default separator, `"-"` with a string of your choice on a per-field basis.

You can also set this in the `ui:globalOptions` to have the same separator used everywhere.

```ts
import { UiSchema } from '@rjsf/utils';

const uiSchema = {
  'ui:globalOptions': {
    duplicateKeySuffixSeparator: '_',
  },
};
```

## Using uiSchema with oneOf, anyOf

### anyOf

The uiSchema will work with elements inside an `anyOf` as long as the uiSchema defines the `anyOf` key at the same level as the `anyOf` within the `schema`.
Because the `anyOf` in the `schema` is an array, so must be the one in the `uiSchema`.
If you want to override the titles of the first two elements within the `anyOf` list you would do the following:

```ts
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'object',
  anyOf: [
    {
      title: 'Strings',
      type: 'string',
    },
    {
      title: 'Numbers',
      type: 'number',
    },
    {
      title: 'Booleans',
      type: 'boolean',
    },
  ],
};

const uiSchema: UiSchema = {
  anyOf: [
    {
      'ui:title': 'Custom String Title',
    },
    {
      'ui:title': 'Custom Number Title',
    },
  ],
};
```

> NOTE: Because the third element in the `schema` does not have an associated element in the `uiSchema`, it will keep its original title.

### oneOf

The uiSchema will work with elements inside an `oneOf` as long as the uiSchema defines the `oneOf` key at the same level as the `oneOf` within the `schema`.
Because the `oneOf` in the `schema` is an array, so must be the one in the `uiSchema`.
If you want to override the titles of the first two elements within the `oneOf` list you would do the following:

```ts
import { RJSFSchema, UiSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'object',
  oneOf: [
    {
      title: 'Strings',
      type: 'string',
    },
    {
      title: 'Numbers',
      type: 'number',
    },
    {
      title: 'Booleans',
      type: 'boolean',
    },
  ],
};

const uiSchema: UiSchema = {
  oneOf: [
    {
      'ui:title': 'Custom String Title',
    },
    {
      'ui:title': 'Custom Number Title',
    },
  ],
};
```

> NOTE: Because the third element in the `schema` does not have an associated element in the `uiSchema`, it will keep its original title.

## Theme Options

- [AntD Customization](themes/antd/uiSchema.md)
- [Chakra-UI Customization](themes/chakra-ui/uiSchema.md)
- [MUI Customization](themes/mui/uiSchema.md)
- [PrimeReact Customization](themes/primereact/uiSchema.md)
- [Semantic-UI Customization](themes/semantic-ui/uiSchema.md)

---

### Packages Docs Docs Api Reference Utility Functions (`packages/docs/docs/api-reference/utility-functions.md`)

# RJSF utility functions, constants and types

In version 5, the utility functions from `@rjsf/core/utils` were refactored into their own library called `@rjsf/utils`.
These utility functions are separated into two distinct groups.
The first, larger, group are the [functions](#non-validator-utility-functions) that do NOT require a `ValidatorType` interface be provided as one of their parameters.
The second, smaller, group are the [functions](#validator-based-utility-functions) that DO require a `ValidatorType` interface be provided as a parameter.
There is also a helper [function](#schema-utils-creation-function) used to create a `SchemaUtilsType` implementation from a `ValidatorType` implementation and `rootSchema` object.

## Constants

The `@rjsf/utils` package exports a set of constants that represent all the keys into various elements of a RJSFSchema or UiSchema that are used by the various utility functions.
In addition to those keys, there is the special `ADDITIONAL_PROPERTY_FLAG` flag that is added to a schema under certain conditions by the `retrieveSchema()` utility.

These constants can be found on GitHub [here](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/utils/src/constants.ts).

## Types

Additionally, the Typescript types used by the utility functions represent nearly all the types used by RJSF.
Those types are exported for use by `@rjsf/core` and all the themes, as well as any customizations you may build.

These types can be found on GitHub [here](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/utils/src/types.ts).

**`ObjectPath`** — Used by the path utilities (`getByPath`, `setByPath`, `hasByPath`, `unsetByPath`) to address a value inside a plain object. It is `string | number | FieldPathList`. A bare **string is always a single literal key**: `'a.b'` means the key `'a.b'`, never the nested path `a` → `b`. To walk a dotted path string, split it explicitly with [toPath()](#topath) first, or pass a `FieldPathList` (`(string | number)[]`) of segments. Reads and existence checks resolve **own** properties only, so inherited members never appear as form data.

**`SchemaFieldPath`** — Used when navigating a JSON Schema subtree (for example with `getFromSchema` and `findFieldInSchema` on `SchemaUtilsType`, documented under [Validator-based utility functions](#validator-based-utility-functions)). It is `string | FieldPathList`: either a dotted path or an array of segments with the same rules as `FieldPathList` (`(string | number)[]`). A numeric segment denotes an array index or an object key that is numeric. Navigation skips only `undefined` or empty-string segments, so segment **`0`** is always honored (this avoids the bug from treating `0` as a falsy path unit).

## Enums

There are enumerations in `@rjsf/utils` that are exported for use by `@rjsf/core` and all the themes, as well as any customizations you may build.

These enums can be found on GitHub [here](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/utils/src/enums.ts).

## Non-Validator utility functions

### allowAdditionalItems()

Checks the schema to see if it is allowing additional items, by verifying that `schema.additionalItems` is an object.
The user is warned in the console if `schema.additionalItems` has the value `true`.

#### Parameters

- schema: S - The schema object to check

#### Returns

- boolean: True if additional items is allowed, otherwise false

### ariaDescribedByIds()

Return a list of element ids that contain additional information about the field that can be used to as the aria description of the field.

#### Parameters

- id: FieldPathId | string - Either simple string id or an FieldPathId from which to extract it
- [includeExamples=false]: boolean - Optional flag, if true, will add the `examplesId` into the list

#### Returns

- string: The string containing the list of ids for use in an `aria-describedBy` attribute

### asNumber()

Attempts to convert the string into a number. If an empty string is provided, then `undefined` is returned.
If a `null` is provided, it is returned.
If the string ends in a `.` then the string is returned because the user may be in the middle of typing a float number.
If a number ends in a pattern like `.0`, `.20`, `.030`, string is returned because the user may be typing number that will end in a non-zero digit.
Otherwise, the string is wrapped by `Number()` and if that result is not `NaN`, that number will be returned, otherwise the string `value` will be.

#### Parameters

- value: string | null - The string or null value to convert to a number

#### Returns

- undefined | null | string | number: The `value` converted to a number when appropriate, otherwise the `value`

### bracketNameGenerator()

Generates bracketed names for form fields.

#### Parameters

- path: FieldPathList - The path of field path units to use when generating the name
- idPrefix: string - The prefix to use at the start of the generated name
- [isMultiValue]: boolean | undefined - Optional flag, if true, will append `[]` to the end of the name for multi-value fields (e.g., checkboxes, multi-select)

#### Returns

- string: The generated bracketed name (e.g., `root[tasks][0][title]`, or `root[hobbies][]` for multi-value fields)

### buttonId()

Return a consistent `id` for the `btn` button element

#### Parameters

- id: FieldPathId | string - The id of the parent component for the option
- btn: 'add' | 'copy' | 'moveDown' | 'moveUp' | 'remove' - The button type for which to generate the id

#### Returns

- string: The consistent id for the button from the given `id` and `btn` type

### canExpand&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Checks whether the field described by `schema`, having the `uiSchema` and `formData` supports expanding.
The UI for the field can expand if it has additional properties, is not forced as non-expandable by the `uiSchema` and the `formData` object doesn't already have `schema.maxProperties` elements.

#### Parameters

- schema: S - The schema for the field that is being checked
- [uiSchema=\{}]: UiSchema&lt;T, S, F> - The uiSchema for the field
- [formData]: T | undefined - The formData for the field

#### Returns

- boolean: True if the schema element has additionalProperties or patternProperties keywords, is expandable, and not at the maxProperties limit

### createErrorHandler&lt;T = any>()

Given a `formData` object, recursively creates a `FormValidation` error handling structure around it

#### Parameters

- formData: T - The form data around which the error handler is created

#### Returns

- FormValidation&lt;T>: A `FormValidation` object based on the `formData` structure

### dataURItoBlob()

Given the `FileReader.readAsDataURL()` based `dataURI` extracts that data into an actual Blob along with the name
of that Blob if provided in the URL. If no name is provided, then the name falls back to `unknown`.

#### Parameters

- dataURI: string - The `DataUrl` potentially containing name and raw data to be converted to a Blob

#### Returns

- \{ blob: Blob, name: string }: An object containing a Blob and its name, extracted from the URI

### dateRangeOptions&lt;S extends StrictRJSFSchema = RJSFSchema>()

Returns a list of options for a date range between `start` and `stop`.
If the start date is greater than the end date, then the date range is reversed.
If `start` and `stop` are negative numbers (or zero), then they will be treated as relative to the current year.

#### Parameters

- start: number - The starting point of the date range
- stop: number - The ending point of the date range

#### Returns

- EnumOptionsType&lt;S>[]: The list of EnumOptionsType for the date range between `start` and `stop`

#### Throws

- Error when `start` and `stop` aren't both %lt;= 0 or > 0

### deepEquals()

Implements a deep equals that treats all functions as equivalent and tracks circular references, so self-referential inputs do not recurse infinitely.

#### Parameters

- a: any - The first element to compare
- b: any - The second element to compare

#### Returns

- boolean: True if the `a` and `b` are deeply equal, false otherwise

### descriptionId()

Return a consistent `id` for the field description element.

#### Parameters

- id: FieldPathId | string - Either simple string id or an FieldPathId from which to extract it

#### Returns

- string: The consistent id for the field description element from the given `id`

### dotNotationNameGenerator()

Generates dot-notation names for form fields. Multi-value fields are handled the same as single-value fields in dot notation.

#### Parameters

- path: FieldPathList - The path of field path units to use when generating the name
- idPrefix: string - The prefix to use at the start of the generated name
- [_isMultiValue]: boolean | undefined - Optional flag (unused in dot notation)

#### Returns

- string: The generated dot-notation name (e.g., `root.tasks.0.title`)

### englishStringTranslator()

Translates a `TranslatableString` value `stringToTranslate` into english.
When a `params` array is provided, each value in the array is used to replace any of the replaceable parameters in the `stringToTranslate` using the `%1`, `%2`, etc. replacement specifiers.

#### Parameters

stringToTranslate: TranslatableString - The `TranslatableString` value to convert to english
[params]: string[] - The optional list of replaceable parameter values to substitute to the english string

#### Returns

- string: The `stringToTranslate` itself with any replaceable parameter values substituted

### enumOptionsDeselectValue&lt;S extends StrictRJSFSchema = RJSFSchema>()

Removes the enum option value at the `valueIndex` from the currently `selected` (list of) value(s).
If `selected` is a list, then that list is updated to remove the enum option value with the `valueIndex` in `allEnumOptions`.
If it is a single value, then if the enum option value with the `valueIndex` in `allEnumOptions` matches `selected`, undefined is returned, otherwise the `selected` value is returned.

#### Parameters

- valueIndex: string | number - The index of the value to be removed from the selected list or single value
- [selected]: EnumOptionsType&lt;S>["value"] | EnumOptionsType&lt;S>["value"][] | undefined - The current (list of) selected value(s)
- [allEnumOptions=[]]: EnumOptionsType&lt;S>[] - The list of all the known enumOptions

#### Returns

- EnumOptionsType&lt;S>["value"][]: The updated `selected` list with the `value` removed from it

### enumOptionSelectedValue&lt;S extends StrictRJSFSchema = RJSFSchema>()

Computes the value to pass to a select element's `value` attribute.
When `format` is `'realValue'`, converts form data values to strings.
When `format` is `'indexed'` (the default), resolves to index-based values via `enumOptionsIndexForValue`.
Returns `emptyValue` when the current value is empty.

#### Parameters

- value: any - The current form data value
- enumOptions: EnumOptionsType&lt;S>[] | undefined - The available enum options
- multiple: boolean - Whether the select allows multiple selections
- [format='indexed']: OptionValueFormat - How option values are encoded on the DOM
- emptyValue: any - The value to return when the selection is empty

#### Returns

- any: The value to use for the select element's `value` attribute

### enumOptionsIndexForValue&lt;S extends StrictRJSFSchema = RJSFSchema>()

Returns the index(es) of the options in `allEnumOptions` whose value(s) match the ones in `value`.
All the `enumOptions` are filtered based on whether they are a "selected" `value` and the index of each selected one is then stored in an array.
If `multiple` is true, that array is returned, otherwise the first element in the array is returned.

#### Parameters

- value: EnumOptionsType&lt;S>["value"] | EnumOptionsType&lt;S>["value"][] - The single value or list of values for which indexes are desired
- [allEnumOptions=[]]: EnumOptionsType&lt;S>[] - The list of all the known enumOptions
- [multiple=false]: boolean - Optional flag, if true will return a list of index, otherwise a single one

#### Returns

- string | string[] | undefined: A single string index for the first `value` in `allEnumOptions`, if not `multiple`. Otherwise, the list of indexes for (each of) the value(s) in `value`.

### enumOptionsIsSelected&lt;S extends StrictRJSFSchema = RJSFSchema>()

Determines whether the given `value` is (one of) the `selected` value(s).

#### Parameters

- value: EnumOptionsType&lt;S>["value"] - The value being checked to see if it is selected
- selected: EnumOptionsType&lt;S>["value"] | EnumOptionsType&lt;S>["value"][] - The current selected value or list of values
- [allEnumOptions=[]]: EnumOptionsType&lt;S>[] - The list of all the known enumOptions

#### Returns

- boolean: true if the `value` is one of the `selected` ones, false otherwise

### enumOptionsSelectValue&lt;S extends StrictRJSFSchema = RJSFSchema>()

Add the `value` to the list of `selected` values in the proper order as defined by `allEnumOptions`.

#### Parameters

- valueIndex: string | number - The index of the value that should be selected
- selected: EnumOptionsType&lt;S>["value"][] - The current list of selected values
- [allEnumOptions=[]]: EnumOptionsType&lt;S>[] - The list of all the known enumOptions

#### Returns

- EnumOptionsType&lt;S>["value"][]: The updated list of selected enum values with `value` added to it in the proper location

### enumOptionsValueForIndex&lt;S extends StrictRJSFSchema = RJSFSchema>()

Returns the value(s) from `allEnumOptions` at the index(es) provided by `valueIndex`.
If `valueIndex` is not an array AND the index is not valid for `allEnumOptions`, `emptyValue` is returned.
If `valueIndex` is an array, AND it contains an invalid index, the returned array will have the resulting undefined values filtered out, leaving only valid values or in the worst case, an empty array.

#### Parameters

- valueIndex: string | number | Array&lt;string | number> - The index(es) of the value(s) that should be returned
- [allEnumOptions=[]]: EnumOptionsType&lt;S>[] - The list of all the known enumOptions
- [emptyValue]: EnumOptionsType&lt;S>["value"] | undefined - The value to return when the non-array `valueIndex` does not refer to a real option

#### Returns

- EnumOptionsType&lt;S>["value"] | EnumOptionsType&lt;S>["value"][] | undefined: The single or list of values specified by the single or list of indexes if they are valid. Otherwise, `emptyValue` or an empty list.

### enumOptionValueDecoder&lt;S extends StrictRJSFSchema = RJSFSchema>()

Decodes a string from a DOM value attribute back to a typed enum value.
When `format` is `'realValue'`, does a reverse lookup: finds the enum option whose `String(value)` matches the input string and returns the original typed value.
For object/array values that were encoded as indices, falls back to index resolution.
When `format` is `'indexed'` (the default), uses index-based resolution via `enumOptionsValueForIndex`.

#### Parameters

- value: string | string[] - The string value(s) from the DOM
- enumOptions: EnumOptionsType&lt;S>[] | undefined - The available enum options
- [format='indexed']: OptionValueFormat - How the values were encoded on the DOM
- emptyValue: unknown - The value to return for empty/missing selections

#### Returns

- unknown: The original typed enum value(s)

### enumOptionValueEncoder()

Encodes an enum option value into a string for a DOM value attribute.
When `format` is `'realValue'`, primitive values are converted via `String()`.
Non-primitive values (objects, arrays) fall back to the index since `String()` would produce `"[object Object]"`.
When `format` is `'indexed'` (the default), returns the index as a string.

#### Parameters

- value: unknown - The typed enum value
- index: number - The option's position in the enumOptions array
- [format='indexed']: OptionValueFormat - How to encode the value for the DOM attribute

#### Returns

- string: The string to use as the DOM value attribute

### logUnsupportedDefaultForEnum&lt;S extends StrictRJSFSchema = RJSFSchema>()

Logs a warning when a single-select enum widget has a schema default that is not one of its enum options.
Multi-select widgets are ignored because they do not use the same single-value default handling.

#### Parameters

- id: string - The field id used in the warning message
- schema: S - The schema whose default value is checked
- [enumOptions]: EnumOptionsType&lt;S>[] - The enum options available to the widget
- [multiple=false]: boolean - Whether the widget allows multiple selections

### errorId()

Return a consistent `id` for the field error element.

#### Parameters

- id: FieldPathId | string - Either simple string id or an FieldPathId from which to extract it

#### Returns

- string: The consistent id for the field error element from the given `id`

### examplesId()

Return a consistent `id` for the field examples element.

#### Parameters

- id: FieldPathId | string - Either simple string id or an FieldPathId from which to extract it

#### Returns

- string: The consistent id for the field examples element from the given `id`

### findSchemaDefinition&lt;S extends StrictRJSFSchema = RJSFSchema>()

Given the name of a `$ref` from within a schema, using the `rootSchema`, look up and return the sub-schema using the path provided by that reference.
If `#` is not the first character of the reference, or the path does not exist in the schema, then throw an Error.
Otherwise, return the sub-schema. Also deals with nested `$ref`s in the sub-schema.

#### Parameters

- $ref: string - The ref string for which the schema definition is desired
- [rootSchema={}]: S - The root schema in which to search for the definition

#### Returns

- S: The sub-schema within the `rootSchema` which matches the `$ref` if it exists

#### Throws

- Error indicating that no schema for that reference exists

### getByPath&lt;R = unknown>()

Gets the value at `path` of `obj`, returning `defaultValue` when the resolved value is `undefined`.
A bare string `path` is a single literal key, not a dotted path; use [toPath()](#topath) to split a dotted path string into segments first.
Every segment must be an **own** property, matching [hasByPath()](#hasbypath), so the two can be used as a guard/read pair.
Inherited members are never resolved: `getByPath({}, 'toString')` returns `defaultValue` rather than `Function.prototype.toString`. For the plain form data and schemas RJSF navigates, an inherited member is never data, and the own-property rule also makes prototype internals such as `__proto__` unreachable unless they are genuine own data keys.

An empty segment list resolves to nothing, so `defaultValue` is returned rather than `obj` itself; this matches [hasByPath()](#hasbypath), which is `false` for an empty path.

The value at a runtime-computed path cannot be known statically, so `R` is the caller's declaration of the expected type (like `Map.get()`); it defaults to `unknown`, which forces narrowing when no type is given.

#### Parameters

- obj: unknown - The object to query
- path: ObjectPath - The single key or list of path segments at which to get the value
- [defaultValue]: R - The value returned when the resolved value is `undefined`

#### Returns

- R: The resolved value, otherwise `defaultValue`

#### Example

```typescript
getByPath({ a: { b: 1 } }, ['a', 'b']); // 1
getByPath({ 'a.b': 1 }, 'a.b'); // 1, a bare string is one literal key
getByPath({ a: { b: 1 } }, toPath('a.b')); // 1
getByPath({ a: {} }, ['a', 'missing'], 'fallback'); // 'fallback'
getByPath({}, 'toString', 'fallback'); // 'fallback', inherited members are not read
getByPath({ a: 1 }, [], 'fallback'); // 'fallback', an empty path resolves to nothing
```

### getChangedFields(a: unknown, b: unknown, deep?: boolean)

Compares two objects and returns the names of the fields that have changed.
This function iterates over each field of object `a`, using `_.isEqual` to compare the field value with the corresponding field value in object `b`.
If the values are different, the field name will be included in the returned array.

When `deep` is true, a field holding a nested object or a same-length array is descended into and the dotted path of the deepest field that changed is returned instead of the name of the top-level field holding it.
A key that contains a `.` or a `[` is descended into like any other: the path it produces cannot be told apart from a path through nested keys, and neither can the entry an `ErrorSchema` keeps for it, since [toErrorSchema()](#toerrorschema) spells such a name out as a path in the same way.

#### Parameters

- a: unknown - The first object, representing the original data to compare.
- b: unknown - The second object, representing the updated data to compare.
- [deep=false]: boolean - Optional flag that, when true, returns the dotted path of the deepest field that changed.

#### Returns

- string[] : An array of field names that have changed.

#### Example

```typescript
const a = { name: 'John', age: 30 };
const b = { name: 'John', age: 31 };
const changedFields = getChangedFields(a, b);
console.log(changedFields); // Output: ['age']
```

#### Example (deep)

```typescript
const a = { items: [{ qux: '', corge: '' }] };
const b = { items: [{ qux: 'a', corge: '' }] };
console.log(getChangedFields(a, b)); // Output: ['items']
console.log(getChangedFields(a, b, true)); // Output: ['items.0.qux']
```

### getDecimalSeparator(languages?: string | string[])

Determines the locale-specific decimal separator.
It uses the provided locale or the first locale in navigator.languages (if available) and falls back to "en".

#### Parameters

- languages?: string | string[] - Optional array of locales or a single locale string.

#### Returns

- string : The decimal separator character (typically '.' or ',').

#### Example

```typescript
const separator = getDecimalSeparator('fr');
console.log(separator); // Output: ','
```

### getDiscriminatorFieldFromSchema&lt;S extends StrictRJSFSchema = RJSFSchema>()

Returns the `discriminator.propertyName` when defined in the `schema` if it is a string. A warning is generated when it is not a string.
Returns `undefined` when a valid discriminator is not present.

#### Parameters

- schema: S - The schema from which the discriminator is potentially obtained

#### Returns

- string | undefined: The `discriminator.propertyName` if it exists in the schema, otherwise `undefined`

### getDateElementProps()

Given date & time information with optional yearRange & format, returns props for DateElement

#### Parameters

- date: DateObject - Object containing date with optional time information
- time: boolean - Determines whether to include time or not
- [yearRange=[1900, new Date().getFullYear() + 2]]: [number, number] - Controls the list of years to be displayed
- [format='YMD']: DateElementFormat - Controls the order in which day, month and year input element will be displayed

#### Returns

- Array of props for DateElement

### getInputProps&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Using the `schema`, `defaultType` and `options`, extract out the props for the `<input>` element that make sense.

#### Parameters

- schema: S - The schema for the field provided by the widget
- [defaultType]: string | undefined - The default type, if any, for the field provided by the widget
- [options={}]: UIOptionsType&lt;T, S, F> - The UI Options for the field provided by the widget
- [autoDefaultStepAny=true]: boolean - Determines whether to auto-default step=any when the type is number and no step

#### Returns

- InputPropsType: The extracted `InputPropsType` object

### getOptionMatchingSimpleDiscriminator()

Compares the value of `discriminatorField` within `formData` against the value of `discriminatorField` within schema for each `option`. Returns index of first `option` whose discriminator matches formData. Returns `undefined` if there is no match.

This function does not work with discriminators of `"type": "object"` and `"type": "array"`

#### Parameters

- [formData]: T | undefined - The current formData, if any, used to figure out a match
- options: S[] - The list of options to find a matching options from
- [discriminatorField]: string | undefined - The optional name of the field within the options object whose value is used to determine which option is selected

#### Returns

- number | undefined: index of the matched option

### getOptionValueFormat()

Resolves the effective `optionValueFormat` for enum-backed widgets.
Provides a single source of truth for the default DOM encoding format (`'indexed'`) used by `SelectWidget`, `RadioWidget`, and `CheckboxesWidget`.
Widgets should call this helper once and pass the result to `enumOptionValueEncoder`, `enumOptionValueDecoder`, and `enumOptionSelectedValue` rather than reading `options.optionValueFormat` directly.

#### Parameters

- [options]: \{ optionValueFormat?: OptionValueFormat } | undefined - The widget options (typically from the `options` prop, already resolved from `ui:options` and `ui:globalOptions`)

#### Returns

- OptionValueFormat: The resolved `OptionValueFormat`, defaulting to `'indexed'` when not set

### getPropertySchema&lt;S extends StrictRJSFSchema = RJSFSchema>()

Returns the sub-schema declared for `property` in the `properties` of `schema`, falling back to an empty schema when the schema has no such property.
Callers treat the properties of a schema as schemas of the same type `S`, which the `JSONSchema7` typing of `properties` cannot express, so this function owns that single assertion rather than repeating it at every lookup.

#### Parameters

- schema: S | undefined - The schema, if any, from which to read the property sub-schema
- property: string - The name of the property whose sub-schema is desired

#### Returns

- S: The sub-schema for `property`, or an empty schema when it is not declared

### getSchemaType()

Gets the type of a given `schema`.
If the type is not explicitly defined, then an attempt is made to infer it from other elements of the schema as follows:

- schema.const: Returns the `guessType()` of that value
- schema.enum: Returns `string`
- schema.properties: Returns `object`
- schema.additionalProperties: Returns `object`
- schema.patternProperties: Returns `object`
- type is an array with a length of 2 and one type is 'null': Returns the other type

#### Parameters

- schema: S - The schema for which to get the type

#### Returns

- string | string[] | undefined: The type of the schema

### getSubmitButtonOptions&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Extracts any `ui:submitButtonOptions` from the `uiSchema` and merges them onto the `DEFAULT_OPTIONS`

#### Parameters

- [uiSchema={}]: UiSchema&lt;T, S, F> - the UI Schema from which to extract submit button props

#### Returns

- UISchemaSubmitButtonOptions: The merging of the `DEFAULT_OPTIONS` with any custom ones

### getTemplate&lt;Name extends keyof TemplatesType&lt;T, S, F>, T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Returns the template with the given `name` from either the `uiSchema` if it is defined or from the `registry`
otherwise. NOTE, since `ButtonTemplates` are not overridden in `uiSchema` only those in the `registry` are returned.

#### Parameters

- name: Name - The name of the template to fetch, restricted to the keys of `TemplatesType`
- registry: Registry&lt;T, S, F> - The `Registry` from which to read the template
- [uiOptions=\{}]: UIOptionsType&lt;T, S, F> - The `UIOptionsType` from which to read an alternate template

#### Returns

- TemplatesType&lt;T, S, F>[Name] - The template from either the `uiSchema` or `registry` for the `name`

### getTestIds()

Returns an object of test IDs that can only be used in test mode.
If the function is called in a test environment (`NODE_ENV === 'test'`, this is set by jest) then a Proxy object will be returned.
If a key within the returned object is accessed, if the value already exists the object will return that value, otherwise it will create that key
with a generated `uuid` value and return the generated ID.
If it is called outside of a test environment, the function will return an empty object, therefore returning `undefined` for any property within the object and excluding the prop from the rendered output of the component in which it is used.
To use this helper, you will want to generate a separate object for each component to avoid potential overlapping of ID names.
You will also want to export the object for use in tests, because the keys will be generated in the component file, and used in the test file.
Within the component file, add: `export const TEST_IDS = getTestIds();`
Then pass `TEST_IDS.examplePropertyName` as the value of the test ID attribute of the intended component.
This will allow you to use `TEST_IDS.examplePropertyName` within your tests, while keeping the test IDs out of your rendered output.

#### Returns

- TestIdShape: An object that auto-generates test ids upon request the first time and then returns the same value on subsequent calls

### getUiOptions&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Get all passed options from ui:options, and ui:&lt;optionName>, returning them in an object with the `ui:` stripped off.
Any `globalOptions` will always be returned, unless they are overridden by options in the `uiSchema`.

#### Parameters

- [uiSchema={}]: UiSchema&lt;T, S, F> - The UI Schema from which to get any `ui:xxx` options
- [globalOptions={}]: GlobalUISchemaOptions - The optional Global UI Schema from which to get any fallback `xxx` options

#### Returns

- UIOptionsType&lt;T, S, F> An object containing all of the `ui:xxx` options with the `ui:` stripped off along with all `globalOptions`

### getWidget&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Given a schema representing a field to render and either the name or actual `Widget` implementation, returns the
React component that is used to render the widget. If the `widget` is already a React component, then it is wrapped
with a `MergedWidget`. Otherwise an attempt is made to look up the widget inside of the `registeredWidgets` map based
on the schema type and `widget` name. If no widget component can be found an `Error` is thrown.

#### Parameters

- schema: S - The schema for the field
- widget: Widget&lt;T, S, F> | string - Either the name of the widget OR a `Widget` implementation to use
- [registeredWidgets={}]: RegistryWidgetsType&lt;T, S, F> - A registry of widget name to `Widget` implementation

#### Returns

- Widget&lt;T, S, F>: The `Widget` component to use

#### Throws

- An error if there is no `Widget` component that can be returned

### hasByPath()

Determines whether `obj` has an **own** property at `path`.
A bare string `path` is a single literal key, not a dotted path; use [toPath()](#topath) to split a dotted path string into segments first.
Every segment is checked with `Object.hasOwn()`, so inherited properties report `false` — `hasByPath({}, 'toString')` is `false`. [getByPath()](#getbypath) applies the same own-property rule, so the two can be used as a guard/read pair.

#### Parameters

- obj: unknown - The object to query
- path: ObjectPath - The single key or list of path segments to check for

#### Returns

- boolean: True if the own property exists at `path`, otherwise false

#### Example

```typescript
hasByPath({ a: { b: undefined } }, ['a', 'b']); // true, the key exists
hasByPath({ a: { b: 1 } }, 'a.b'); // false, there is no key named 'a.b'
hasByPath({}, 'toString'); // false, inherited properties are not own properties
```

### hashObject()

Stringifies an `object` and returns the hash of the resulting string.
Sorts object fields in consistent order before stringify to prevent different hash ids for the same object.

#### Parameters

- object: object - The object for which the hash is desired

#### Returns

- string: The string obtained from the hash of the stringified object

### hashString()

Hashes a string using the algorithm based on Java's hashing function.

#### Parameters

- string: string - The string for which to get the hash

#### Returns

- string: The resulting hash of the string in hex format

### guessType()

Given a specific `value` attempts to guess the type of a schema element. In the case where we have to implicitly
create a schema, it is useful to know what type to use based on the data we are defining.

#### Parameters

- value: any - The value from which to guess the type

#### Returns

- string: The best guess for the object type

### hashForSchema&lt;S extends StrictRJSFSchema = RJSFSchema>()

Stringifies the schema and returns the hash of the resulting string.

#### Parameters

- schema: S - The schema for which the hash is desired

#### Returns

- string: The string obtained from the hash of the stringified schema

### hasWidget&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Detects whether the `widget` exists for the `schema` with the associated `registryWidgets` and returns true if it does, or false if it doesn't.

#### Parameters

- schema: S - The schema for the field
- widget: Widget&lt;T, S, F> | string - Either the name of the widget OR a `Widget` implementation to use
- [registeredWidgets={}]: RegistryWidgetsType&lt;T, S, F> - A registry of widget name to `Widget` implementation

#### Returns

- boolean: True if the widget exists, false otherwise

### helpId()

Return a consistent `id` for the field help element.

#### Parameters

- id: FieldPathId | string - Either simple string id or an FieldPathId from which to extract it

#### Returns

- string: The consistent id for the field help element from the given `id`

### isConstant&lt;S extends StrictRJSFSchema = RJSFSchema>()

This function checks if the given `schema` matches a single constant value.
This happens when either the schema has an `enum` array with a single value or there is a `const` defined.

#### Parameters

- schema: S - The schema for a field

#### Returns

- boolean: True if the `schema` has a single constant value, false otherwise

### isCustomWidget&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Checks to see if the `uiSchema` contains the `widget` field and that the widget is not `hidden`

#### Parameters

- uiSchema: UiSchema&lt;T, S, F> - The UI Schema from which to detect if it is customized

#### Returns

- boolean: True if the `uiSchema` describes a custom widget, false otherwise

### isFixedItems&lt;S extends StrictRJSFSchema = RJSFSchema>()

Detects whether the given `schema` contains fixed items.
This is the case when `schema.items` is a non-empty array that only contains objects.

#### Parameters

- schema: S - The schema in which to check for fixed items

#### Returns

- boolean: True if there are fixed items in the schema, false otherwise

### isFormDataAvailable&lt;T = any>()

Determines whether the given `formData` represents valid form data, such as a primitive type, an array, or a non-empty object.

#### Parameters

- formData: T - The data to check

#### Returns

- boolean: True if `formData` is not undefined, null, a primitive type or an array or an empty object

### isObject()

Determines whether a `thing` is an object for the purposes of RSJF.
In this case, `thing` is an object if it has the type `object` but is NOT null, an array or a File.

#### Parameters

- thing: any - The thing to check to see whether it is an object

#### Returns

- boolean: True if it is a non-null, non-array, non-File object

### isPlainObject()

Determines whether `thing` is a plain object, i.e. one created by the `Object` constructor or with a `null` prototype.
Unlike [isObject()](#isobject), class instances such as `Error` are not plain objects, which matters when recursively walking a structure whose nested values are expected to be plain data.

#### Parameters

- thing: unknown - The thing to check to see whether it is a plain object

#### Returns

- boolean: True if it is a plain object, otherwise false. When true, `thing` is narrowed to `Record<string, unknown>`

### isRootSchema&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Helper to check whether a JSON schema object is the root schema. The schema is a root schema with root `properties`
key or a root `$ref` key. If the `schemaToCompare` has a root `oneOf` property, the function will
return false. Else if `schemaToCompare` and `rootSchema` are the same object or equal, the function will return
`true`. Else if the `rootSchema` has a $ref, it will be resolved using `schemaUtils.resolveSchema` utility. If the
resolved schema matches the `schemaToCompare` the function will return `true`. Otherwise, it will return false.

#### Parameters

- registry: Registry&lt;T, S, F> - The `Registry` used to get the `rootSchema` and `schemaUtils`
- schemaToCompare: S - The JSON schema object to check. If `schemaToCompare` is an root schema, the function will return true.

#### Returns

- boolean: True if the `uiSchema` describes a custom widget, false otherwise

### isValueEmpty()

Returns true when a form value is considered empty: `null`, `undefined`, or `''` (empty string), an empty array (`[]`), or a plain object whose every own value is itself empty (checked recursively). Scalar values such as `0` and `false` are not considered empty.

#### Parameters

- value: unknown - The value to check

#### Returns

- boolean: True if the value is considered empty, false otherwise

### labelValue()

Helper function that will return the value to use for a widget `label` based on `hideLabel`.
The `fallback` is used as the return value from the function when `hideLabel` is true.
Due to the implementation of theme components, it may be necessary to return something other than `undefined` to cause the theme component to not render a label.
Some themes require may `false` and others may require an empty string.

#### Parameters

- [label]: string | ReactElement | undefined - The label string or component to render when not hidden
- [hideLabel]: boolean| undefined - Flag, if true, will cause the label to be hidden
- [fallback]: undefined | false | '' - One of 3 values, `undefined` (the default), `false` or an empty string

- #### Returns

- string | boolean | undefined: `fallback` if `hideLabel` is true, otherwise `label`

### localToUTC()

Converts a local Date string into a UTC date string

#### Parameters

- dateString: string - The string representation of a date as accepted by the `Date()` constructor

#### Returns

- string | undefined: A UTC date string if `dateString` is truthy, otherwise undefined

### lookupFromFormContext&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any, R = unknown>()

Given a React JSON Schema Form registry or formContext object, return the value associated with `toLookup`.
This might be contained within the lookup map in the formContext.
If no such value exists, return the `fallback` value.

#### Parameters

- regOrFc: Registry&lt;T, S, F> | Registry&lt;T, S, F>['formContext'] - The @rjsf registry or form context in which the lookup will occur
- toLookup: string - The name of the field in the lookup map in the form context to get the value for
- [fallback]: R - The fallback value to use if the form context does not contain a value for `toLookup`

#### Returns

- R: The value associated with `toLookup` in the form context or `fallback`

### mergeDefaultsWithFormData&lt;T = any>()

Merges the `defaults` object of type `T` into the `formData` of type `T`

When merging defaults and form data, we want to merge in this specific way:

- objects are deeply merged
- arrays are merged in such a way that:
  - when the array is set in form data, only array entries set in form data are deeply merged; additional entries from the defaults are ignored unless `mergeExtraArrayDefaults` is true, in which case the extras are appended onto the end of the form data
  - when the array is not set in form data, the default is copied over
- scalars are overwritten/set by form data

#### Parameters

- [defaults]: T | undefined - The defaults to merge
- [formData]: T | undefined - The form data into which the defaults will be merged
- [mergeExtraArrayDefaults=false]: boolean - If true, any additional default array entries are appended onto the formData
- [defaultSupercedesUndefined=false]: boolean - If true, an explicit undefined value will be overwritten by the default value

#### Returns

- T | undefined: The resulting merged form data with defaults

### mergeObjects()

Recursively merge deeply nested objects.

#### Parameters

- obj1: GenericObjectType - The first object to merge
- obj2: GenericObjectType - The second object to merge
- [concatArrays=false]: boolean | "preventDuplicates" - Optional flag that, when true, will cause arrays to be concatenated. Use "preventDuplicates" to merge arrays in a manner that prevents any duplicate entries from being merged.

#### Returns

@returns - A new object that is the merge of the two given objects

### mergeSchemas()

Recursively merge deeply nested schemas.
The difference between mergeSchemas and mergeObjects is that mergeSchemas only concats arrays for values under the 'required' keyword, and when it does, it doesn't include duplicate values. NOTE: Uses shallow comparison for the duplicate checking.

#### Parameters

- obj1: GenericObjectType - The first object to merge
- obj2: GenericObjectType - The second object to merge

#### Returns

- GenericObjectType: The merged schema object

### optionalControlsId()

Return a consistent `id` for the optional data controls `element`

#### Parameters

- id: string - The id of the parent component for the option
- element: 'Add' | 'Msg' | 'Remove' - The element type for which to generate the id

#### Returns

- string: The consistent id for the optional data controls element from the given `id` and `element` type

### optionId()

Return a consistent `id` for the `optionIndex`s of a `Radio` or `Checkboxes` widget

#### Parameters

- id: string - The id of the parent component for the option
- optionIndex: number - The index of the option for which the id is desired

#### Returns

- string: An id for the option index based on the parent `id`

### noop()

A function that does nothing and returns `undefined`, useful as a placeholder for an optional callback or as the implementation of a mocked function.

#### Returns

- void

### optionsList&lt;T = any, S extends StrictRJSFSchema = RJSFSchema,F extends FormContextType = any>()

Gets the list of options from the `schema`. If the schema has an enum list, then those enum values are returned.
The labels for the options will be extracted from `ui:enumNames` in the `uiSchema` if provided, otherwise the label will be the same as the `value`. If `ui:enumOrder` is provided, the options will be reordered accordingly.

If the schema has a `oneOf` or `anyOf`, then the value is the list of either:

-
- The `const` values from the schema if present
- If the schema has a discriminator and the label using either the `schema.title` or the value. If a `uiSchema` is
  provided, and it has the `ui:enumNames` matched with `enum` or it has an associated `oneOf` or `anyOf` with a list of
  objects containing `ui:title` then the UI schema values will replace the values from the schema.

#### Parameters

- schema: S - The schema from which to extract the options list
- [uiSchema]: UiSchema&lt;T, S, F> - The optional uiSchema from which to get alternate labels for the options

#### Returns

- \{ schema?: S, label: string, value: any }: The list of options from the schema

### orderProperties()

Given a list of `properties` and an `order` list, returns a list that contains the `properties` ordered correctly.
If `order` is not an array, then the untouched `properties` list is returned.
Otherwise `properties` is ordered per the `order` list.
If `order` contains a '_' then any `properties` that are not mentioned explicity in `order` will be places in the location of the `_`.

#### Parameters

- properties: string[] - The list of property keys to be ordered
- order: string[] - An array of property keys to be ordered first, with an optional '\*' property

#### Returns

- string[]: A list with the `properties` ordered

#### Throws

- Error when the properties cannot be ordered correctly

### pad()

Returns a string representation of the `num` that is padded with leading "0"s if necessary

#### Parameters

- num: number - The number to pad
- width: number - The width of the string at which no lead padding is necessary

#### Returns

- string: The number converted to a string with leading zero padding if the number of digits is less than `width`

### parseDateString()

Parses the `dateString` into a `DateObject`, including the time information when `includeTime` is true

#### Parameters

- dateString: string - The date string to parse into a DateObject
- [includeTime=true]: boolean - Optional flag, if false, will not include the time data into the object

#### Returns

- DateObject: The date string converted to a `DateObject`

#### Throws

- Error when the date cannot be parsed from the string

### rangeSpec&lt;S extends StrictRJSFSchema = RJSFSchema>()

Extracts the range spec information `{ step?: number, min?: number, max?: number }` that can be spread onto an HTML input from the range analog in the schema `{ multipleOf?: number, minimum?: number, maximum?: number }`.

#### Parameters

- schema: S - The schema from which to extract the range spec

#### Returns

- RangeSpecType: A range specification from the schema

### replaceStringParameters()

Potentially substitutes all replaceable parameters with the associated value(s) from the `params` if available.
When a `params` array is provided, each value in the array is used to replace any of the replaceable parameters in the `inputString` using the `%1`, `%2`, etc. replacement specifiers.

#### Parameters

- inputString: string - The string which will be potentially updated with replacement parameters
- [params]: string[] - The optional list of replaceable parameter values to substitute into the english string

#### Returns

- string: The updated string with any replacement specifiers replaced

### resolveDefaultWidget&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Computes the widget name a field falls back to when no `ui:widget` is specified, along with the `enumOptions` (if any) that back a `select`-like fallback.
The default is `select` when `schema` has enumerable options, the schema's `format` when a widget is registered for it, or `text` otherwise.

#### Parameters

- schema: S - The schema for the field
- uiSchema: UiSchema&lt;T, S, F> | undefined - The uiSchema for the field
- schemaUtils: SchemaUtilsType&lt;T, S, F> - The `SchemaUtilsType` used to detect whether `schema` has enumerable options
- [registeredWidgets={}]: RegistryWidgetsType&lt;T, S, F> - A registry of widget name to `Widget` implementation

#### Returns

- \{ defaultWidget: string, enumOptions: EnumOptionsType&lt;S>[] | undefined }: The default widget name and the `enumOptions`, if any, computed along the way

### resolveUiSchema&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Resolves the uiSchema for a given schema, considering `ui:definitions` stored in the registry.
Called at runtime for each field. When the schema contains a `$ref`, looks up the corresponding uiSchema definition from `registry.uiSchemaDefinitions` and merges it with local overrides.
For schemas with `oneOf`/`anyOf` branches, also populates `uiSchema[keyword][i]` for branches whose `$ref` matches a definition, so `MultiSchemaField` can read dropdown option titles.

Resolution order (later sources override earlier):

1. `ui:definitions[$ref]` - base definition from registry
2. `localUiSchema` - local overrides at current path

#### Parameters

- schema: S - The JSON schema (may contain `$ref` or `RJSF_REF_KEY`)
- localUiSchema: UiSchema&lt;T, S, F> | undefined - The uiSchema at the current path (local overrides)
- registry: Registry&lt;T, S, F> - The registry containing `uiSchemaDefinitions`

#### Returns

- UiSchema&lt;T, S, F>: The resolved uiSchema with definitions merged in

### schemaHasNestedConditional&lt;S extends StrictRJSFSchema = RJSFSchema>()

Recursively checks whether the given raw `schema` contains a `dependencies` or `if` keyword anywhere below its top level, e.g. inside a nested object's `properties`, a `$ref`, an array's tuple `items`, or a `patternProperties` entry.
`retrieveSchema()` only resolves the `dependencies`/`if` declared directly on the schema it is given, so a root-level retrieved schema never reflects a conditional branch switch that happens deeper in the tree.
`Form` uses this to detect when a comparison of root-level retrieved schemas can't be trusted to decide whether sanitization is needed.

#### Parameters

- schema: S | boolean | undefined - The raw schema node to search
- rootSchema: S - The root schema, used to resolve any `$ref`s encountered while searching
- atRoot: boolean = true - Whether `schema` is the root of the search, whose own `dependencies`/`if` don't count
- seenRefs: string[] = [] - The `$ref`s already resolved along this branch of the search, to guard against cycles

#### Returns

- boolean: True if a `dependencies` or `if` keyword exists below the root of the schema

### schemaRequiresTrueValue&lt;S extends StrictRJSFSchema = RJSFSchema>()

Check to see if a `schema` specifies that a value must be true. This happens when:

- `schema.const` is truthy
- `schema.enum` == `[true]`
- `schema.anyOf` or `schema.oneOf` has a single value which recursively returns true
- `schema.allOf` has at least one value which recursively returns true

#### Parameters

- schema: S - The schema to check

#### Returns

- boolean: True if the schema specifies a value that must be true, false otherwise

### setByPath&lt;O>()

Sets `value` at `path` of `obj`, mutating and returning `obj`.
A bare string `path` is a single literal key, not a dotted path; use [toPath()](#topath) to split a dotted path string into segments first.
Missing intermediate containers are created: arrays when the next segment is a valid array index, plain objects otherwise, or always plain objects when `createIntermediateObjects` is true.
A path containing a `__proto__` segment is refused and `obj` is returned unmodified, preventing prototype pollution. `constructor` and `prototype` are legal JSON Schema property names and are written normally: intermediate containers are read as own properties only, so `['constructor', 'prototype', 'x']` shadows `constructor` with a fresh object instead of reaching `Object.prototype`.

#### Parameters

- obj: O - The object to modify
- path: ObjectPath - The single key or list of path segments at which to set the value
- value: unknown - The value to set
- [createIntermediateObjects=false]: boolean - When true, always create plain objects for missing intermediate containers, even for numeric path segments

#### Returns

- O: The mutated `obj`

#### Example

```typescript
setByPath({}, ['a', 'b'], 1); // { a: { b: 1 } }
setByPath({}, ['a', 0], 1); // { a: [1] }, a numeric next segment creates an array
setByPath({}, ['a', 0], 1, true); // { a: { 0: 1 } }, createIntermediateObjects forces an object
setByPath({}, 'a.b', 1); // { 'a.b': 1 }, a bare string is one literal key
```

### shallowEquals()

Implements a shallow equals comparison that uses `Object.is()` for comparing values.
This function compares objects by checking if all keys and their values are equal using `Object.is()`.

#### Parameters

- a: any - The first element to compare
- b: any - The second element to compare

#### Returns

- boolean: True if the `a` and `b` are shallow equal, false otherwise

### shouldRender()

Determines whether the given `component` should be rerendered by comparing its current set of props and state against the next set.
If either of those two sets are not the same, then the component should be rerendered.

#### Parameters

- component: React.Component - A React component being checked
- nextProps: any - The next set of props against which to check
- nextState: any - The next set of state against which to check

#### Returns

- True if boolean: the component should be re-rendered, false otherwise

### shouldRenderOptionalField&lt;T = any, S extends StrictRJSFSchema = RJSFSchema,F extends FormContextType = any>()

Determines whether the field information from the combination of `schema` and `required` along with the
`enableOptionalDataFieldForType` settings from the global UI options in the `registry` all indicate that this field
should be rendered with the Optional Data Controls UI.

#### Parameters

- registry: Registry&lt;T, S, F> - The `registry` object
- schema: S - The schema for the field
- required - Flag indicating whether the field is required
- [uiSchema]: UiSchema&lt;T, S, F> - The optional uiSchema for the field

#### Returns

- boolean: True if the field should be rendered with the optional field UI, otherwise false

### sortedJSONStringify()

Stringifies an `object`, sorts object fields in consistent order before stringifying it.

#### Parameters

- object: object - The object for which the sorted stringify is desired

#### Returns

- string: The stringified object with keys sorted in a consistent order

### titleId()

Return a consistent `id` for the field title element.

#### Parameters

- id: FieldPathId | string - Either simple string id or an FieldPathId from which to extract it

#### Returns

- string: The consistent id for the field title element from the given `id`

### toConstant&lt;S extends StrictRJSFSchema = RJSFSchema>()

Returns the constant value from the schema when it is either a single value enum or has a const key.
Otherwise, throws an error.

#### Parameters

- schema: S - The schema from which to obtain the constant value

#### Returns

- string | number | boolean: The constant value for the schema

#### Throws

- Error when the schema does not have a constant value

### toDateString()

Returns a UTC date string for the given `dateObject`.
If `time` is false, then the time portion of the string is removed.

#### Parameters

- dateObject: DateObject - The `DateObject` to convert to a date string
- [time=true]: boolean - Optional flag used to remove the time portion of the date string if false

#### Returns

- string: The UTC date string

### toErrorList&lt;T = any>()

Converts an `errorSchema` into a list of `RJSFValidationErrors`

#### Parameters

- errorSchema: ErrorSchema&lt;T> - The `ErrorSchema` instance to convert
- [fieldPath=[]]: string[] | undefined - The current field path, defaults to [] if not specified

#### Returns

- RJSFValidationErrors[]: The list of `RJSFValidationErrors` extracted from the `errorSchema`

### toErrorSchema&lt;T = any>()

Transforms a RJSF validation errors list into an `ErrorSchema`

```ts
const changesThis = [
  { property: '.level1.level2[2].level3', message: 'err a', stack: '.level1.level2[2].level3 err a' },
  { property: '.level1.level2[2].level3', message: 'err b', stack: '.level1.level2[2].level3 err b' },
  { property: '.level1.level2[4].level3', message: 'err b', stack: '.level1.level2[4].level3 err b' },
];
const intoThis = {
  level1: {
    level2: {
      2: { level3: { errors: ['err a', 'err b'] } },
      4: { level3: { errors: ['err b'] } },
    },
  },
};
```

#### Parameters

- errors: RJSFValidationError[] - The list of RJSFValidationError objects

#### Returns

- ErrorSchema&lt;T>: The `ErrorSchema` built from the list of `RJSFValidationErrors`

### toFieldPathId()

Constructs the `FieldPathId` for `fieldPath`. If `parentPathId` is provided, the `fieldPath` is appended to the end
of the parent path. Then the `ID_KEY` of the resulting `FieldPathId` is constructed from the `idPrefix` and
`idSeparator` contained within the `globalFormOptions`. If `fieldPath` is passed as an empty string, it will simply
generate the path from the `parentPath` (if provided) and the `idPrefix` and `idSeparator`

#### Parameters

- fieldPath: string | number - The property name or array index of the current field element
- globalFormOptions: GlobalFormOptions - The `GlobalFormOptions` used to get the `idPrefix` and `idSeparator`
- [parentPath]: FieldPathId | FieldPathList | undefined - The optional `FieldPathId` or `FieldPathList` of the parent element for this field element

#### Returns

- FieldPathId: The `FieldPathId` for the given `fieldPath` and the optional `parentPathId`

### toPath()

Converts a dotted path string, such as the `property` of a validation error, into its list of path segments.
Array indexes may be written bracketed (`'a[0].b'`) or dotted (`'a.0.b'`), and empty segments — from a leading `.`, a trailing `.` or a `..` run — are dropped.
Only the grammar RJSF itself produces is supported: dots and brackets are always separators, so quoted keys are not recognized and keys containing dots must be addressed with a segment list instead of a string.

#### Parameters

- path: string - The string path to convert, such as `'.level1.level2[2].level3'`

#### Returns

- string[]: The list of path segments, such as `['level1', 'level2', '2', 'level3']`

#### Example

```typescript
toPath('.level1.level2[2].level3'); // ['level1', 'level2', '2', 'level3']
toPath('a.0.b'); // ['a', '0', 'b']
getByPath(formData, toPath(error.property)); // the usual pairing with the path utilities
```

### unsetByPath()

Removes the own property at `path` of `obj`, mutating `obj`.
A bare string `path` is a single literal key, not a dotted path; use [toPath()](#topath) to split a dotted path string into segments first.

#### Parameters

- obj: unknown - The object to modify
- path: ObjectPath - The single key or list of path segments at which to remove the property

#### Returns

- boolean: True if the property was removed or did not exist, otherwise false. A non-configurable property returns false rather than throwing in strict mode

#### Example

```typescript
const obj = { a: { b: 1 } };
unsetByPath(obj, ['a', 'b']); // true, obj is now { a: {} }
unsetByPath(obj, ['a', 'missing']); // true, nothing to remove
```

### unwrapErrorHandler&lt;T = any>()

Unwraps the `errorHandler` structure into the associated `ErrorSchema`, stripping the `addError()` functions from it

#### Parameters

- errorHandler: FormValidation&lt;T> - The `FormValidation` error handling structure

#### Returns

- ErrorSchema&lt;T>: The `ErrorSchema` resulting from the stripping of the `addError()` function

### useAltDateWidgetProps&lt;T = unknown, S extends StrictRJSFSchema = RJSFSchema,F extends FormContextType = any&gt;`()

Hook which encapsulates the logic needed to render an `AltDateWidget` with optional `time` elements. It contains
the `state` of the current date(/time) selections in the widget. It returns a `UseAltDateWidgetResult` object
that contains the `elements: DateElementProp[]` and three callbacks needed to change one of the rendered `elements`,
and to handle the clicking of the `clear` and `setNow` buttons.

#### Parameters

- props: WidgetProps&lt;T, S, F> - The `WidgetProps` for the `AltDateWidget`

#### Returns

- UseAltDateWidgetResult: The `UseAltDateWidgetResult` to be used within a `AltDateWidget` implementation

### useDeepCompareMemo&lt;T = unknown>()

Hook that stores and returns a `T`. If `newValue` is the same as the stored one, then the stored one is returned to
avoid having a component rerender due it being a different object. Otherwise, the `newValue` is stored and returned.

#### Parameters

- newValue: T - The potential new `T` value

#### Returns

- T: The latest stored `T` value

### useFileWidgetProps()

Hook which encapsulates the logic needed to read and convert a `value` of `File` or `File[]` into the
`filesInfo: FileInfoType[]` and the two callback implementations needed to change the list or to remove a
`File` from the list. To be used by theme specific `FileWidget` implementations.

#### Parameters

- value: string | string[] | undefined | null - The current value of the `FileWidget`
- onChange: (value: string | null | (string | null)[]) => void - The onChange handler for the `FileWidget`
- [multiple=false] - Flag indicating whether the control supports multiple selections

#### Returns

- UseFileWidgetPropsResult: The `UseFileWidgetPropsResult` to be used within a `FileWidget` implementation

### utcToLocal()

Converts a UTC date string into a local Date format

#### Parameters

- jsonDate: string - A UTC date string

#### Returns

- string: An empty string when `jsonDate` is falsey, otherwise a date string in local format

### validationDataMerge&lt;T = any>()

Merges the errors in `additionalErrorSchema` into the existing `validationData` by combining the hierarchies in the two `ErrorSchema`s and then appending the error list from the `additionalErrorSchema` obtained by calling `toErrorList()` on the `errors` in the `validationData`.
If no `additionalErrorSchema` is passed, then `validationData` is returned.

#### Parameters

- validationData: ValidationData&lt;T> - The current `ValidationData` into which to merge the additional errors
- [additionalErrorSchema]: ErrorSchema&lt;T> | undefined - The optional additional set of errors in an `ErrorSchema`
- [preventDuplicates=false]: boolean - Optional flag, if true, will call `mergeObjects()` with `preventDuplicates`

#### Returns

- ValidationData&lt;T>: The `validationData` with the additional errors from `additionalErrorSchema` merged into it, if provided.

### withIdRefPrefix&lt;S extends StrictRJSFSchema = RJSFSchema>()

Recursively prefixes all `$ref`s in a schema with the value of the `ROOT_SCHEMA_PREFIX` constant.
This is used in isValid to make references to the rootSchema

#### Parameters

- schemaNode: S - The object node to which a `ROOT_SCHEMA_PREFIX` is added when a `$ref` is part of it

#### Returns

- S: A copy of the `schemaNode` with updated `$ref`s

## Validator-based utility functions

### findFieldInSchema&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Finds the field at the given path within the root or a nested `schema` node, following `oneOf` / `anyOf` using `formData` where needed. If nothing matches the path, `{ field: undefined, isRequired: undefined }` is returned. When a leaf is found, the result includes whether that leaf is required under its parent.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
- rootSchema: S - The root schema that will be forwarded to all the APIs
- schema: S - The node within the JSON schema in which to search
- path: SchemaFieldPath - Dotted path or segment list to the desired field; see [`SchemaFieldPath`](#types)
- [formData={}]: T - The form data that is used to determine which anyOf/oneOf option to descend
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- FoundFieldType&lt;S>: An object that contains the field and its required state. If no field can be found then `{ field: undefined, isRequired: undefined }` is returned.

### findSelectedOptionInXxxOf&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Finds the option inside the `schema['any/oneOf']` list which has the `properties[selectorField].default` or `properties[selectorField].const` that matches the `formData[selectorField]` value.
For the purposes of this function, `selectorField` is either `schema.discriminator.propertyName` or `fallbackField`.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
- rootSchema: S | undefined - The root schema that will be forwarded to all the APIs
- schema: S - The schema element in which to search for the selected anyOf/oneOf option
- fallbackField: string - The field to use as a backup selector field if the schema does not have a required field
- xxx: 'anyOf' | 'oneOf' - Either `anyOf` or `oneOf`, defines which value is being sought
- [formData={}]: T - The form data that is used to determine which anyOf/oneOf option to descend
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- S | undefined: The anyOf/oneOf option that matches the selector field in the schema or undefined if nothing is selected

### getDefaultFormState&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Returns the superset of `formData` that includes the given set updated to include any missing fields that have computed to have defaults provided in the `schema`.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- theSchema: S - The schema for which the default state is desired
- [formData]: T | undefined - The current formData, if any, onto which to provide any missing defaults
- [rootSchema]: S | undefined - The root schema, used to primarily to look up `$ref`s
- [includeUndefinedValues=false]: boolean | "excludeObjectChildren" - Optional flag, if true, cause undefined values to be added as defaults. If "excludeObjectChildren", cause undefined values for this object and pass `includeUndefinedValues` as false when computing defaults for any nested object properties.
- [experimental_defaultFormStateBehavior]: Experimental_DefaultFormStateBehavior - See `Form` documentation for the [experimental_defaultFormStateBehavior](./form-props.md#experimental_defaultFormStateBehavior) prop
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop
- [initialDefaultsGenerated]: boolean - Optional flag, indicates whether or not initial defaults have been generated

#### Returns

- T: The resulting `formData` with all the defaults provided

### getDisplayLabel&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Determines whether the combination of `schema` and `uiSchema` properties indicates that the label for the `schema` should be displayed in a UI.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- schema: S - The schema for which the display label flag is desired
- [uiSchema={}]: UiSchema&lt;T, S, F> - The UI schema from which to derive potentially displayable information
- [rootSchema]: S | undefined - The root schema, used to primarily to look up `$ref`s
- [globalOptions={}]: GlobalUISchemaOptions - The optional Global UI Schema from which to get any fallback `xxx` options

#### Returns

- boolean: True if the label should be displayed or false if it should not

### getClosestMatchingOption&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Determines which of the given `options` provided most closely matches the `formData`.
Returns the index of the option that is valid and is the closest match, or 0 if there is no match.

The closest match is determined using the number of matching properties, and more heavily favors options with matching readOnly, default, or const values.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- rootSchema: S - The root schema, used to primarily to look up `$ref`s
- [formData]: T | undefined - The current formData, if any, used to figure out a match
- options: S[] - The list of options to find a matching options from
- [selectedOption=-1]: number - The index of the currently selected option, defaulted to -1 if not specified
- [discriminatorField]: string | undefined - The optional name of the field within the options object whose value is used to determine which option is selected
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- number: The index of the option that is the closest match to the `formData` or the `selectedOption` if no match

### getDisplayLabel&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Determines whether the combination of `schema` and `uiSchema` properties indicates that the label for the `schema` should be displayed in a UI.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- schema: S - The schema for which the display label flag is desired
- [uiSchema={}]: UiSchema&lt;T, S, F> - The UI schema from which to derive potentially displayable information
- [rootSchema]: S | undefined - The root schema, used to primarily to look up `$ref`s
- [globalOptions={}]: GlobalUISchemaOptions - The optional Global UI Schema from which to get any fallback `xxx` options
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- boolean: True if the label should be displayed or false if it should not

### getFromSchema&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Reads the value at `path` within a schema, additionally retrieving `$ref`s as needed to resolve schemas containing potentially nested `$ref`s.
The `path` accepts a [`SchemaFieldPath`](#types) (dotted string or `FieldPathList`-style segment array).

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
- rootSchema: S - The root schema that will be forwarded to all the APIs
- schema: S - The current node within the JSON schema recursion
- path: SchemaFieldPath - Dotted path or segment list to the desired field; see [`SchemaFieldPath`](#types)
- defaultValue: T | S - The value to return if a value is not found for the `pathList` path
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- T | S: The inner schema from the `schema` for the given `path` or the `defaultValue` if not found

### getFirstMatchingOption&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Given the `formData` and list of `options`, attempts to find the index of the first option that matches the data.
Always returns the first option if there is nothing that matches.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- [formData]: T | undefined - The current formData, if any, used to figure out a match
- options: S[] - The list of options to find a matching options from
- rootSchema: S - The root schema, used to primarily to look up `$ref`s
- [discriminatorField]: string | undefined - The optional name of the field within the options object whose value is used to determine which option is selected

#### Returns

- number: The index of the first matched option or 0 if none is available

### isMultiSelect&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Checks to see if the `schema` combination represents a multi-select

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- schema: S - The schema for which check for a multi-select flag is desired
- [rootSchema]: S | undefined - The root schema, used to primarily to look up `$ref`s
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- boolean: True if schema contains a multi-select, otherwise false

### isSelect&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Checks to see if the `schema` combination represents a select

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- theSchema: S - The schema for which check for a select flag is desired
- [rootSchema]: S | undefined - The root schema, used to primarily to look up `$ref`s
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- boolean: True if schema contains a select, otherwise false

### relaxOptionsForScoring&lt;S extends StrictRJSFSchema = RJSFSchema>()

Normalises a list of `oneOf`/`anyOf` options for use in option-scoring only (not for filtering).
Boolean schemas are converted to their object equivalents (`true` → `{}`, `false` → `{not:{}}`).
When `resolveRefs` is `true`, each object option is first passed through `resolveAllReferences` so that `$ref`-based options expose their `additionalProperties` constraint before relaxation.
Any option whose `additionalProperties` is `false` is widened to `true` so that `getClosestMatchingOption` / `validator.isValid()` does not produce false negatives when the form data contains keys not listed in `properties`.

#### Parameters

- options: Array&lt;S | boolean> - The raw `oneOf`/`anyOf` array, which may contain boolean schemas
- [resolveRefs=false]: boolean - When `true`, resolve `$ref`s in each option before relaxing; pass `rootSchema` as well. Set `false` (default) when refs are already resolved at the call site
- [rootSchema]: S | undefined - Required when `resolveRefs` is `true`; the root schema used to look up `$ref`s

#### Returns

- S[]: A new array of plain schema objects with `additionalProperties` relaxed where needed

### removeOptionalEmptyObjects&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

> NOTE: This function is deprecated and will be removed in a future release. The equivalent pruning behavior is now built into `omitExtraData` — use that instead.

Recursively removes optional objects from the `formData` that are empty (i.e., all their fields are undefined, null, empty strings, or themselves empty optional objects).
This solves the problem where interacting with fields inside an optional object "activates" it permanently, making the form unsubmittable when the optional object has required inner fields.
An object property is considered "optional" when it is NOT listed in its parent schema's `required` array.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- schema: S - The JSON schema describing the `formData`
- [rootSchema]: S | undefined - The root schema, used primarily to look up `$ref`s
- [formData]: T | undefined - The current form data to prune

#### Returns

- T | undefined: A new copy of `formData` with empty optional objects removed, or `undefined` if the entire formData was pruned

### retrieveSchema&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Retrieves an expanded schema that has had all of its conditions, additional properties, references and dependencies
resolved and merged into the `schema` given a `validator`, `rootSchema` and `rawFormData` that is used to do the
potentially recursive resolution.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be forwarded to all the APIs
- schema: S - The schema for which retrieving a schema is desired
- [rootSchema={}]: S - The root schema that will be forwarded to all the APIs
- [rawFormData]: T | undefined - The current formData, if any, to assist retrieving a schema
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- RJSFSchema: The schema having its conditions, additional properties, references and dependencies resolved

### omitExtraData&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Takes a schema and formData and returns a copy of the formData with any fields not defined in the schema removed.
This is useful for ensuring that only data that is relevant to the schema is preserved.
Objects with `additionalProperties` keyword set to `true` will not have their extra fields removed.

```ts
const schema = {
  type: 'object',
  properties: {
    child1: {
      type: 'object',
      properties: {
        name: { type: 'string' },
      },
    },
    child2: {
      type: 'object',
      properties: {
        name: { type: 'string' },
      },
      additionalProperties: true,
    },
  },
};

const formData = {
  child1: {
    name: 'John Doe',
    extraField: 'This should be removed',
  },
  child2: {
    name: 'Jane Doe',
    extraField: 'This should NOT be removed',
  },
};

const filteredFormData = omitExtraData(validator, schema, schema, formData);
console.log(filteredFormData);
/*
{
  child1: {
    name: "John Doe",
  },
  child2: {
    name: "Jane Doe",
    extraField: "This should NOT be removed",
  },
}
*/
```

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- schema: S - The schema to use for filtering the formData
- [rootSchema]: S | undefined - The root schema, used to primarily to look up `$ref`s
- [formData]: T | undefined - The formData to filter

#### Returns

- T: The new form data, with any fields not defined in the schema removed

### sanitizeDataForNewSchema&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Sanitize the `data` associated with the `oldSchema` so it is considered appropriate for the `newSchema`.
If the new schema does not contain any properties, then `undefined` is returned to clear all the form data.
Due to the nature of schemas, this sanitization happens recursively for nested objects of data.
Also, any properties in the old schema that are non-existent in the new schema are set to `undefined`.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- rootSchema: S - The root JSON schema of the entire form
- [newSchema]: S | undefined - The new schema for which the data is being sanitized
- [oldSchema]: S | undefined - The old schema from which the data originated
- [data={}]: any - The form data associated with the schema, defaulting to an empty object when undefined
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- T: The new form data, with all the fields uniquely associated with the old schema set to `undefined`. Will return `undefined` if the new schema is not an object containing properties.

### toPathSchema&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

> NOTE: This function is deprecated and will be removed as an exported `@rjsf/utils` function in a future release.

Generates an `PathSchema` object for the `schema`, recursively

#### Parameters

- validator: ValidatorType&lt;T, S, F> - An implementation of the `ValidatorType` interface that will be used when necessary
- schema: S - The schema for which the `PathSchema` is desired
- [name='']: string - The base name for the schema
- [rootSchema]: S | undefined - The root schema, used to primarily to look up `$ref`s
- [formData]: T | undefined - The current formData, if any, to assist retrieving a schema
- [experimental_customMergeAllOf]: Experimental_CustomMergeAllOf&lt;S&gt; - See `Form` documentation for the [experimental_customMergeAllOf](./form-props.md#experimental_custommergeallof) prop

#### Returns

- PathSchema&lt;T> - The `PathSchema` object for the `schema`

## Schema utils creation function

### createSchemaUtils&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Creates a `SchemaUtilsType` interface that is based around the given `validator` and `rootSchema` parameters.
The resulting interface implementation will forward the `validator` and `rootSchema` to all the wrapped APIs.

#### Parameters

- validator: ValidatorType&lt;T, S, F> - an implementation of the `ValidatorType` interface that will be forwarded to all the APIs
- rootSchema: S - The root schema that will be forwarded to all the APIs

#### Returns

- SchemaUtilsType&lt;T, S, F> - An implementation of a `SchemaUtilsType` interface

## ErrorSchema builder class

### ErrorSchemaBuilder&lt;T = any>(initialSchema?: ErrorSchema&lt;T>) constructor

The `ErrorSchemaBuilder&lt;T>` is used to build an `ErrorSchema&lt;T>` since the definition of the `ErrorSchema` type is designed for reading information rather than writing it.
Use this class to add, replace or clear errors in an error schema by using either dotted path or an array of path names.
Once you are done building the `ErrorSchema`, you can get the result and/or reset all the errors back to an initial set and start again.

#### Parameters

- [initialSchema]: ErrorSchema&lt;T> | undefined - The optional set of initial errors, that will be cloned into the class

#### Returns

- ErrorSchemaBuilder&lt;T> - The instance of the `ErrorSchemaBuilder` class

### ErrorSchema getter function

Returns the `ErrorSchema` that has been updated by the methods of the `ErrorSchemaBuilder`

Usage:

```ts
import { ErrorSchemaBuilder, ErrorSchema } from "@rjsf/utils";

const builder = new ErrorSchemaBuilder();

// Do some work using the builder
...

const errorSchema: ErrorSchema = builder.ErrorSchema;
```

### resetAllErrors()

Resets all errors in the `ErrorSchemaBuilder` back to the `initialSchema` if provided, otherwise an empty set.

#### Parameters

- [initialSchema]: ErrorSchema&lt;T> | undefined - The optional set of initial errors, that will be cloned into the class

#### Returns

- ErrorSchemaBuilder&lt;T> - The instance of the `ErrorSchemaBuilder` class

### addErrors()

Adds the `errorOrList` to the list of errors in the `ErrorSchema` at either the root level or the location within the schema described by the `pathOfError`.
The path is either a dotted string, with optional bracketed array indexes such as `'level1.level2[2]'`, or a list of segments; see [toPath()](#topath) for the grammar a string path accepts.

#### Parameters

- errorOrList: string | string[] - The error or list of errors to add into the `ErrorSchema`
- [pathOfError]: string | (string | number)[] | undefined - The optional path into the `ErrorSchema` at which to add the error(s)

#### Returns

- ErrorSchemaBuilder&lt;T> - The instance of the `ErrorSchemaBuilder` class

### setErrors()

Sets/replaces the `errorOrList` as the error(s) in the `ErrorSchema` at either the root level or the location within the schema described by the `pathOfError`.
The path is either a dotted string, with optional bracketed array indexes such as `'level1.level2[2]'`, or a list of segments; see [toPath()](#topath) for the grammar a string path accepts.

#### Parameters

- errorOrList: string | string[] - The error or list of errors to add into the `ErrorSchema`
- [pathOfError]: string | (string | number)[] | undefined - The optional path into the `ErrorSchema` at which to add the error(s)

#### Returns

- ErrorSchemaBuilder&lt;T> - The instance of the `ErrorSchemaBuilder` class

### clearErrors()

Clears the error(s) in the `ErrorSchema` at either the root level or the location within the schema described by the `pathOfError`.
The path is either a dotted string, with optional bracketed array indexes such as `'level1.level2[2]'`, or a list of segments; see [toPath()](#topath) for the grammar a string path accepts.

#### Parameters

- [pathOfError]: string | (string | number)[] | undefined - The optional path into the `ErrorSchema` at which to add the error(s)

#### Returns

- ErrorSchemaBuilder&lt;T> - The instance of the `ErrorSchemaBuilder` class

---

### Packages Docs Docs Api Reference Validator Ajv8 (`packages/docs/docs/api-reference/validator-ajv8.md`)

# @rjsf/validator-ajv8 APIs

In RJSF version 6, the original, embedded AJV 6 validator implementation from earlier versions was removed in favor of the `@rjsf/validator-ajv8` package.
`@rjsf/validator-ajv8` uses the AJV 8 package, including adding support for using precompiled validators.
Below are the exported API functions that are provided by this package.
See the [Validation documentation](../usage/validation.md) for examples of using these APIs.

## Types

There are a few Typescript types that are exported by `@rjsf/validator-ajv8` in support of the APIs.

These types can be found on GitHub [here](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/validator-ajv8/src/types.ts).

## APIs

### customizeValidator&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Creates and returns a customized implementation of the `ValidatorType` with the given customization `options` if provided.
If a `localizer` is provided, it is used to translate the messages generated by the underlying AJV validation.

#### Parameters

- [options={}]: CustomValidatorOptionsType - The optional map of `CustomValidatorOptionsType` options that are used to create the `ValidatorType` instance. Supported options:
  - `additionalMetaSchemas`: Additional meta schemas the validator can access
  - `customFormats`: Additional custom format validators
  - `ajvOptionsOverrides`: Config overrides passed to the AJV constructor
  - `ajvFormatOptions`: Options for `ajv-formats`; pass `false` to disable format support entirely
  - `AjvClass`: The AJV class to construct (e.g. `Ajv2019`, `Ajv2020`)
  - `extenderFn`: A function called to extend the AJV instance (e.g. `ajvErrors()`)
  - `suppressDuplicateFiltering`: Controls filtering of duplicate `anyOf`/`oneOf` errors using the `SuppressDuplicateFilteringType` type. `'none'` (default) filters duplicates for both; `'anyOf'` suppresses filtering for `anyOf` (oneOf duplicates still filtered); `'oneOf'` suppresses filtering for `oneOf` (anyOf duplicates still filtered); `'all'` disables all duplicate filtering.
- [localizer]: Localizer | undefined - If provided, is used to localize a list of Ajv `ErrorObject`s after running the form validation using AJV

#### Returns

- AJV8Validator&lt;T, S, F>: The custom validator implementation resulting from the set of parameters provided

### compileSchemaValidators&lt;S extends StrictRJSFSchema = RJSFSchema>()

The function used to compile a schema into an output file in the form that allows it to be used as a precompiled validator.
The main reasons for using a precompiled validator is reducing code size, improving validation speed and, most importantly, avoiding dynamic code compilation when prohibited by a browser's Content Security Policy.
For more information about AJV code compilation see: https://ajv.js.org/standalone.html

#### Parameters

- schema: S - The schema to be compiled into a set of precompiled validators functions
- output: string - The name of the file into which the precompiled validator functions will be generated
- [options={}]: CustomValidatorOptionsType - The set of `CustomValidatorOptionsType` information used to alter the AJV validator used for compiling the schema. They are the same options that are passed to the `customizeValidator()` function in order to modify the behavior of the regular AJV-based validator.

### createPrecompiledValidator&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Creates and returns a `ValidatorType` interface that is implemented with a precompiled validator.
If a `localizer` is provided, it is used to translate the messages generated by the underlying AJV validation.

> NOTE: The `validateFns` parameter is an object obtained by importing from a precompiled validation file created via the `compileSchemaValidators()` function.

#### Parameters

- validateFns: ValidatorFunctions - The map of the validation functions that are created by the `compileSchemaValidators()` function
- rootSchema: S - The root schema that was used with the `compileSchemaValidators()` function
- [localizer]: Localizer | undefined - If provided, is used to localize a list of Ajv `ErrorObject`s after running the form validation using AJV
- [suppressDuplicateFiltering]: `SuppressDuplicateFilteringType | undefined` - Controls filtering of duplicate `anyOf`/`oneOf` errors. See `customizeValidator()` for full description of each value.

#### Returns

- ValidatorType&lt;T, S, F>: The precompiled validator implementation resulting from the set of parameters provided

---

### Packages Docs Docs Api Reference Validator Ata (`packages/docs/docs/api-reference/validator-ata.md`)

# @rjsf/validator-ata APIs

`@rjsf/validator-ata` is an alternative to `@rjsf/validator-ajv8`, backed by [`ata-validator`](https://www.npmjs.com/package/ata-validator) instead of AJV.
The public surface mirrors the AJV package, so swapping the import is enough for the form to keep working: `customizeValidator()`, `ValidatorType<T, S, F>`, custom formats, `transformErrors`, `customValidate`, and `suppressDuplicateFiltering` all behave the same.

See the [Validation documentation](../usage/validation.md) for examples of using these APIs.

## Differences from `@rjsf/validator-ajv8`

- AJV-only options (`AjvClass`, `ajvFormatOptions`, `ajvOptionsOverrides`) are not accepted. The closest equivalent is `ataOptionsOverrides`, which is spread on top of the default `ata-validator` options.
- The `ata-validator` format set is always installed, so there is no opt-in flag for formats.
- `ata-validator`'s error params are frozen, so the pre-quote pass that `validator-ajv8` runs for `ajv-i18n` is unnecessary. Localizers that mutate `message` in place still work as-is.
- Precompiled validators (`compileSchemaValidators` / `createPrecompiledValidator`) are supported. `ata-validator`'s `bundleStandalone` output is adapted into the validator function map the precompiled consumer expects. Error output matches the non-precompiled validator, including per-field errors for schema-valued `additionalProperties` (with `ata-validator` `>= 0.17.4`); an invalid `anyOf` reports a single error on the field, the same as the runtime path. One constraint carries over from the standalone (AOT) path: custom formats must be a RegExp or pre-anchored string pattern, since a function checker cannot be serialized into the bundle and is rejected at compile time.

## Types

There are a few TypeScript types that are exported by `@rjsf/validator-ata` in support of the APIs. These types can be found on GitHub [here](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/validator-ata/src/types.ts).

## APIs

### customizeValidator&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Creates and returns a customized implementation of the `ValidatorType` with the given customization `options` if provided.
If a `localizer` is provided, it is used to translate the messages generated by the underlying `ata-validator` validation.

#### Parameters

- [options={}]: CustomValidatorOptionsType - The optional map of `CustomValidatorOptionsType` options that are used to create the `ValidatorType` instance. Supported options:
  - `additionalMetaSchemas`: Additional schemas registered for cross-schema `$ref` resolution
  - `customFormats`: Custom format checkers; values can be functions, RegExps, or pre-anchored regex source strings
  - `ataOptionsOverrides`: Overrides spread on top of the default `ata-validator` options (e.g. `coerceTypes`, `removeAdditional`, `verbose`, `abortEarly`)
  - `extenderFn`: A function called against the constructed `Validator` instance for additional setup; returning a different instance is supported
  - `suppressDuplicateFiltering`: Controls filtering of duplicate `anyOf`/`oneOf` errors using the `SuppressDuplicateFilteringType` type. `'none'` (default) filters duplicates for both; `'anyOf'` suppresses filtering for `anyOf` (oneOf duplicates still filtered); `'oneOf'` suppresses filtering for `oneOf` (anyOf duplicates still filtered); `'all'` disables all duplicate filtering.
- [localizer]: Localizer | undefined - If provided, is used to localize a list of `ata-validator` `ValidationError`s after running the form validation

#### Returns

- ValidatorType&lt;T, S, F>: The custom validator implementation resulting from the set of parameters provided

### compileSchemaValidators&lt;S extends StrictRJSFSchema = RJSFSchema>()

Compiles a schema into an output file that can be loaded later as a precompiled validator.
The main reasons for using a precompiled validator are reducing code size, improving startup time by skipping schema compilation, and avoiding dynamic code generation when a browser's Content Security Policy forbids it.
Under the hood this calls `ata-validator`'s `bundleStandalone` and wraps the result in the map the precompiled consumer expects.

> NOTE: Custom formats passed through `options.customFormats` must be a RegExp or a pre-anchored string pattern. A function checker cannot be serialized into the standalone bundle and is rejected at compile time.

#### Parameters

- schema: S - The schema to be compiled into a set of precompiled validator functions
- output: string - The name of the file into which the precompiled validator functions are generated
- [options={}]: CustomValidatorOptionsType - The `CustomValidatorOptionsType` options accepted by `customizeValidator()`, with limits: `extenderFn`, extra schemas without an `$id` and the `ataOptionsOverrides` keys `coerceTypes`, `removeAdditional` and `keywords` cannot be carried into the generated file and are ignored with a warning, the generated file never fills in `default` values, and `suppressDuplicateFiltering` belongs to `createPrecompiledValidator()`. See the precompiled section of `usage/validation.md`

### createPrecompiledValidator&lt;T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()

Creates and returns a `ValidatorType` interface that is implemented with a precompiled validator.
If a `localizer` is provided, it is used to translate the messages generated by the underlying `ata-validator` validation.

> NOTE: The `validateFns` parameter is an object obtained by importing from a precompiled validation file created via the `compileSchemaValidators()` function.

#### Parameters

- validateFns: ValidatorFunctions - The map of the validation functions that are created by the `compileSchemaValidators()` function
- rootSchema: S - The root schema that was used with the `compileSchemaValidators()` function
- [localizer]: Localizer | undefined - If provided, is used to localize the list of `ata-validator` `ValidationError`s after running the form validation
- [suppressDuplicateFiltering]: `SuppressDuplicateFilteringType | undefined` - Controls filtering of duplicate `anyOf`/`oneOf` errors. See `customizeValidator()` for the full description of each value.

#### Returns

- ValidatorType&lt;T, S, F>: The precompiled validator implementation resulting from the set of parameters provided

---

### Packages Docs Docs Api Reference Validator Cfworker (`packages/docs/docs/api-reference/validator-cfworker.md`)

# @rjsf/validator-cfworker APIs

`@rjsf/validator-cfworker` is an additional, eval-free validator option for CSP-constrained applications. It is backed by [`@cfworker/json-schema`](https://github.com/cfworker/cfworker/tree/main/packages/json-schema), interprets schemas without `eval` or `new Function`, and defaults to JSON Schema draft 2020-12.

It is not an AJV replacement. See the package [README](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/validator-cfworker) for the unsupported-keyword matrix and current upstream-state notes.

## Differences from `@rjsf/validator-ajv8`

- AJV-only options and extensions such as `AjvClass`, `$data`, `discriminator`, and `ajv-errors`'s `errorMessage` are not supported.
- `$dynamicRef` and `$dynamicAnchor` are not currently supported by the underlying engine.
- Error messages differ from AJV, and there is no `ajv-i18n` localizer equivalent. Use `transformErrors` to customize messages.
- Precompiled-validator mode is not part of this initial package.
- The wrapper normalizes `undefined` form-data values before validation and caches validators by schema id to make repeated RJSF `isValid()` calls safe.

## Types

The package exports `CustomValidatorOptionsType`, `CFWorkerValidationError`, `CFWorkerFormatChecker`, and `SuppressDuplicateFilteringType` from [`src/types.ts`](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/validator-cfworker/src/types.ts).

## APIs

### `customizeValidator<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>()`

Creates a `ValidatorType<T, S, F>` backed by `@cfworker/json-schema`.

#### Parameters

- `options.additionalMetaSchemas`: additional schemas registered for cross-schema `$ref` resolution
- `options.customFormats`: format checkers expressed as functions, regular expressions, or regular-expression source strings
- `options.draft`: `'4'`, `'7'`, `'2019-09'`, or `'2020-12'`; defaults to `'2020-12'`
- `options.extenderFn`: hook called with every newly constructed engine validator
- `options.shortCircuit`: stop at the first error; defaults to `false`
- `options.suppressDuplicateFiltering`: `'none'`, `'anyOf'`, `'oneOf'`, or `'all'`

#### Returns

- `ValidatorType<T, S, F>`: the customized validator implementation

```ts
import { customizeValidator } from '@rjsf/validator-cfworker';

const validator = customizeValidator({
  draft: '2020-12',
  customFormats: { slug: /^[a-z0-9-]+$/ },
});
```

---

### Packages Docs Docs Json Schema Arrays (`packages/docs/docs/json-schema/arrays.md`)

# Arrays

Arrays are defined with a type equal to `array`, and array items' schemas are specified in the `items` keyword.

## Arrays of a single field

Arrays of a single field type can be specified as follows:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

## Arrays of objects

Arrays of objects can be specified as follows:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'object',
    properties: {
      name: {
        type: 'string',
      },
    },
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

## uiSchema for array items

To specify a uiSchema that applies to array items, specify the uiSchema value within the `items` property:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

const uiSchema = {
  items: {
    'ui:widget': 'textarea',
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

> NOTE: The `items` property in `uiSchema` can also accept a function for dynamic UI schema generation based on array item data. See [Dynamic UI Schema Examples](../api-reference/dynamic-ui-schema-examples.md) for advanced use cases.

## The `additionalItems` keyword

The `additionalItems` keyword allows the user to add additional items of a given schema. For example:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
  additionalItems: {
    type: 'boolean',
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

## Array item uiSchema options

Any of these options can be set globally if they are contained within the `ui:globalOptions` block.
They can also be overridden on a per-field basis inside a `ui:options` block as shown below.

### `orderable` option

Array items are orderable by default, and react-jsonschema-form renders move up/down buttons alongside them. The uiSchema `orderable` options allows you to disable ordering:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

const uiSchema: UiSchema = {
  'ui:options': {
    orderable: false,
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### `addable` option

If either `items` or `additionalItems` contains a schema object, an add button for new items is shown by default. You can turn this off with the `addable` option in `uiSchema`:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

const uiSchema: UiSchema = {
  'ui:options': {
    addable: false,
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### `copyable` option

A copy button is **NOT** shown by default for an item if `items` contains a schema object, or the item is an `additionalItems` instance.
You can turn this **ON** with the `copyable` option in `uiSchema`:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

const uiSchema: UiSchema = {
  'ui:options': {
    copyable: true,
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### `removable` option

A remove button is shown by default for an item if `items` contains a schema object, or the item is an `additionalItems` instance. You can turn this off with the `removable` option in `uiSchema`:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  items: {
    type: 'string',
  },
};

const uiSchema: UiSchema = {
  'ui:options': {
    removable: false,
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

## Multiple-choice list

The default behavior for array fields is a list of text inputs with add/remove buttons. There are two alternative widgets for picking multiple elements from a list of choices. Typically, this applies when a schema has an `enum` list for the `items` property of an `array` field, and the `uniqueItems` property set to `true`.

Example:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  title: 'A multiple-choice list',
  items: {
    type: 'string',
    enum: ['foo', 'bar', 'fuzz', 'qux'],
  },
  uniqueItems: true,
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

By default, this will render a multiple select box. If you prefer a list of checkboxes, just set the uiSchema `ui:widget` directive to `checkboxes` for that field:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  title: 'A multiple-choice list',
  items: {
    type: 'string',
    enum: ['foo', 'bar', 'fuzz', 'qux'],
  },
  uniqueItems: true,
};

const uiSchema: UiSchema = {
  'ui:widget': 'checkboxes',
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

## Custom widgets

In addition to [ArrayFieldTemplate](../advanced-customization/custom-templates.md#arrayfieldtemplate) you use your own widget by providing it to the uiSchema with the property of `ui:widget`.

Example:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const CustomSelectComponent = (props) => {
  return (
    <select>
      {props.value.map((item, index) => (
        <option key={index} id='custom-select'>
          {item}
        </option>
      ))}
    </select>
  );
};

const schema: RJSFSchema = {
  type: 'array',
  title: 'A multiple-choice list',
  items: {
    type: 'string',
  },
};

const uiSchema: UiSchema = {
  'ui:widget': 'CustomSelect',
};

const widgets = {
  CustomSelect: CustomSelectComponent,
};

render(
  <Form schema={schema} uiSchema={uiSchema} widgets={widgets} validator={validator} />,
  document.getElementById('app'),
);
```

## Specifying the minimum or maximum number of items

Note that when an array property is marked as `required`, an empty array is considered valid. If the array needs to be populated, you can specify the minimum number of items using the `minItems` property.

Example:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  minItems: 2,
  title: 'A multiple-choice list',
  items: {
    type: 'string',
    enum: ['foo', 'bar', 'fuzz', 'qux'],
  },
  uniqueItems: true,
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

You can also specify the maximum number of items in an array using the `maxItems` property.

## Inline checkboxes

By default, checkboxes are stacked. If you prefer them inline, set the `inline` property to `true`:

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'array',
  minItems: 2,
  title: 'A multiple-choice list',
  items: {
    type: 'string',
    enum: ['foo', 'bar', 'fuzz', 'qux'],
  },
  uniqueItems: true,
};

const uiSchema: UiSchema = {
  'ui:widget': 'checkboxes',
  'ui:options': {
    inline: true,
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

---

### Packages Docs Docs Json Schema Definitions (`packages/docs/docs/json-schema/definitions.md`)

# Schema definitions and references

This library partially supports [inline schema definition dereferencing](http://json-schema.org/draft/2019-09/json-schema-core.html#ref), which allows you to re-use parts of your schema:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  definitions: {
    address: {
      type: 'object',
      properties: {
        street_address: { type: 'string' },
        city: { type: 'string' },
        state: { type: 'string' },
      },
      required: ['street_address', 'city', 'state'],
    },
  },
  type: 'object',
  properties: {
    billing_address: { $ref: '#/definitions/address' },
    shipping_address: { $ref: '#/definitions/address' },
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

Note that this library only supports local definition referencing. The value in the `$ref` keyword should be a [JSON Pointer](https://tools.ietf.org/html/rfc6901) in URI fragment identifier format.

## uiSchema for Schema Definitions

To customize the UI for schemas referenced via `$ref`, use the `ui:definitions` property in your uiSchema. This works for both reused and recursive schemas.

See [ui:definitions](../api-reference/uiSchema.md#uidefinitions) for full details and more examples.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  definitions: {
    node: {
      type: 'object',
      properties: {
        name: { type: 'string' },
        children: {
          type: 'array',
          items: { $ref: '#/definitions/node' },
        },
      },
    },
  },
  type: 'object',
  properties: {
    tree: { $ref: '#/definitions/node' },
  },
};

const uiSchema: UiSchema = {
  'ui:definitions': {
    '#/definitions/node': {
      name: { 'ui:placeholder': 'Node name' },
    },
  },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

---

### Packages Docs Docs Json Schema Dependencies (`packages/docs/docs/json-schema/dependencies.md`)

# Dependencies

react-jsonschema-form supports the `dependencies` keyword from an earlier draft of JSON Schema (note that this is not part of the latest JSON Schema spec, though). Dependencies can be used to create dynamic schemas that change fields based on what data is entered.

## Property dependencies

This library supports conditionally making fields required based on the presence of other fields.

### Unidirectional

In the following example the `billing_address` field will be required if `credit_card` is defined.

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',

  properties: {
    name: { type: 'string' },
    credit_card: { type: 'number' },
    billing_address: { type: 'string' },
  },

  required: ['name'],

  dependencies: {
    credit_card: ['billing_address'],
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

### Bidirectional

In the following example the `billing_address` field will be required if `credit_card` is defined and the `credit_card`
field will be required if `billing_address` is defined, making them both required if either is defined.

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',

  properties: {
    name: { type: 'string' },
    credit_card: { type: 'number' },
    billing_address: { type: 'string' },
  },

  required: ['name'],

  dependencies: {
    credit_card: ['billing_address'],
    billing_address: ['credit_card'],
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

_(Sample schemas courtesy of the [Space Telescope Science Institute](https://spacetelescope.github.io/understanding-json-schema/reference/object.html#property-dependencies))_

## Schema dependencies

This library also supports modifying portions of a schema based on form data.

### Conditional

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',

  properties: {
    name: { type: 'string' },
    credit_card: { type: 'number' },
  },

  required: ['name'],

  dependencies: {
    credit_card: {
      properties: {
        billing_address: { type: 'string' },
      },
      required: ['billing_address'],
    },
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

In this example the `billing_address` field will be displayed in the form if `credit_card` is defined.

_(Sample schemas courtesy of the [Space Telescope Science Institute](https://spacetelescope.github.io/understanding-json-schema/reference/object.html#schema-dependencies))_

### Dynamic

The JSON Schema standard says that the dependency is triggered if the property is present. However, sometimes it's useful to have more sophisticated rules guiding the application of the dependency. For example, maybe you have three possible values for a field, and each one should lead to adding a different question. For this, we support a very restricted use of the `oneOf` keyword.

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Person',
  type: 'object',
  properties: {
    'Do you have any pets?': {
      type: 'string',
      enum: ['No', 'Yes: One', 'Yes: More than one'],
      default: 'No',
    },
  },
  required: ['Do you have any pets?'],
  dependencies: {
    'Do you have any pets?': {
      oneOf: [
        {
          properties: {
            'Do you have any pets?': {
              enum: ['No'],
            },
          },
        },
        {
          properties: {
            'Do you have any pets?': {
              enum: ['Yes: One'],
            },
            'How old is your pet?': {
              type: 'number',
            },
          },
          required: ['How old is your pet?'],
        },
        {
          properties: {
            'Do you have any pets?': {
              enum: ['Yes: More than one'],
            },
            'Do you want to get rid of any?': {
              type: 'boolean',
            },
          },
          required: ['Do you want to get rid of any?'],
        },
      ],
    },
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

In this example the user is prompted with different follow-up questions dynamically based on their answer to the first question.

In these examples, the "Do you have any pets?" question is validated against the corresponding property in each schema in the `oneOf` array. If exactly one matches, the rest of that schema is merged with the existing schema.

---

### Packages Docs Docs Json Schema Objects (`packages/docs/docs/json-schema/objects.md`)

# Objects

## Object properties

Objects are defined with a type equal to `object` and properties specified in the `properties` keyword.

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'My title',
  description: 'My description',
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
    age: {
      type: 'number',
    },
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

## Required properties

You can specify which properties are required using the `required` attribute:

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'My title',
  description: 'My description',
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
    age: {
      type: 'number',
    },
  },
  required: ['name'],
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

## Specifying property order

Since the order of object properties in Javascript and JSON is not guaranteed, the `uiSchema` object spec allows you to define the order in which properties are rendered using the `ui:order` property:

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    foo: { type: 'string' },
    bar: { type: 'string' },
  },
};

const uiSchema: UiSchema = {
  'ui:order': ['bar', 'foo'],
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

If a guaranteed fixed order is only important for some fields, you can insert a wildcard `"*"` item in your `ui:order` definition. All fields that are not referenced explicitly anywhere in the list will be rendered at that point:

```ts
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:order': ['bar', '*'],
};
```

## Additional and pattern properties

The `additionalProperties` keyword allows the user to add properties with arbitrary key names. Set this keyword equal to a schema object:

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
  },
  additionalProperties: {
    type: 'number',
    enum: [1, 2, 3],
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

In this way, an add button for new properties is shown by default.

You can also define `uiSchema` options for `additionalProperties` by setting the `additionalProperties` attribute in the `uiSchema`.

The `patternProperties` keyword allows the user to add properties with names that match one or more of the specified regular expressions

```tsx
import { Form } from '@rjsf/core';
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    name: {
      type: 'string',
    },
  },
  patternProperties: {
    '^foo+$': {
      type: 'number',
      enum: [1, 2, 3],
    },
  },
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

Also in this case, an add button for new properties is shown by default.

### `expandable` option

You can turn support for `additionalProperties` and `patternProperties` off with the `expandable` option in `uiSchema`:

```ts
import { UiSchema } from '@rjsf/utils';

const uiSchema: UiSchema = {
  'ui:options': {
    expandable: false,
  },
};
```

---

### Packages Docs Docs Json Schema Oneof (`packages/docs/docs/json-schema/oneof.md`)

# oneOf, anyOf, and allOf

react-jsonschema-form supports custom widgets for oneOf, anyOf, and allOf.

- A schema with `oneOf` is valid if _exactly one_ of the subschemas is valid.
- A schema with `anyOf` is valid if _at least one_ of the subschemas is valid.
- A schema with `allOf` is valid if _all_ of the subschemas are valid.

## oneOf

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  oneOf: [
    {
      properties: {
        lorem: {
          type: 'string',
        },
      },
      required: ['lorem'],
    },
    {
      properties: {
        ipsum: {
          type: 'string',
        },
      },
      required: ['ipsum'],
    },
  ],
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

## anyOf

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'object',
  anyOf: [
    {
      properties: {
        lorem: {
          type: 'string',
        },
      },
      required: ['lorem'],
    },
    {
      properties: {
        lorem: {
          type: 'string',
        },
        ipsum: {
          type: 'string',
        },
      },
    },
  ],
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

## allOf

When `allOf` is specified in a schema, react-jsonschema-form uses the [@x0k/json-schema-merge](https://github.com/x0k/json-schema-merge/) library to merge the specified subschemas to create a combined subschema that is valid. For example, the below schema evaluates to a combined subschema of `{type: "boolean"}`:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'Field',
  allOf: [
    {
      type: ['string', 'boolean'],
    },
    {
      type: 'boolean',
    },
  ],
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

---

### Packages Docs Docs Json Schema Single (`packages/docs/docs/json-schema/single.md`)

# Single fields

The simplest example of a JSON Schema contains only a single field. The field type is determined by the `type` parameter.

## Field types

The base field types in JSON Schema include:

- `string`
- `number`
- `integer`
- `boolean`
- `null`

Here is an example of a string field:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

## Titles and descriptions

Fields can have titles and descriptions specified by the `title` keyword in the schema and the `description` keyword in the schema, respectively. These two can also be overridden by the `ui:title` and `ui:description` keywords in the uiSchema.

Description can render markdown. This feature is disabled by default. It needs to be enabled by the `ui:enableMarkdownInDescription` keyword and setting to `true`. Read more about markdown options in the `markdown-to-jsx` official [docs](https://markdown-to-jsx.quantizor.dev/).

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  title: 'My form',
  description: 'My description',
  type: 'string',
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

## Deprecated fields

The JSON Schema `deprecated` keyword can be used to indicate that a field is no longer supported.

The `deprecated` keyword is a JSON Schema Draft 2019-09 feature. You may need to configure your schema validator to properly recognize it. See the [Validation](../usage/validation.md#ajvclass) documentation for more details.

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
  deprecated: true,
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

By default, RJSF will append ` (deprecated)` to the field label. You can customize this behavior using the `deprecatedHandling` option in the uiSchema. See [deprecatedHandling](../api-reference/uiSchema.md#deprecatedhandling) for more details.

## Enumerated values

All base schema types support the `enum` attribute, which restricts the user to select among a list of options. For example:

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
  enum: ['one', 'two', 'three'],
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

### Custom labels for `enum` fields

JSON Schema supports the following approaches to enumerations using `oneOf`/`anyOf`; react-jsonschema-form supports it as well.

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'number',
  anyOf: [
    {
      type: 'number',
      title: 'one',
      enum: [1],
    },
    {
      type: 'number',
      title: 'two',
      enum: [2],
    },
    {
      type: 'number',
      title: 'three',
      enum: [3],
    },
  ],
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

```tsx
import { RJSFSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'number',
  oneOf: [
    { const: 1, title: 'one' },
    { const: 2, title: 'two' },
    { const: 3, title: 'three' },
  ],
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

If you use `enum` in your JSON Schema, you may instead specify `ui:enumNames` in your `uiSchema`, which RJSF can use to label an enumeration. `ui:enumNames` can be an array (matched by index) or a map (matched by value):

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'number',
  enum: [1, 2, 3],
};

// Array form (matched by index)
const uiSchema: UiSchema = {
  'ui:enumNames': ['one', 'two', 'three'],
};

// Map form (matched by value)
const uiSchema: UiSchema = {
  'ui:enumNames': { 1: 'one', 2: 'two', 3: 'three' },
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### Ordering `enum` fields

To control the display order of enum options, use `ui:enumOrder`. Use `'*'` to represent all remaining values in their original schema order. Unlisted values not covered by `'*'` are dropped.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'string',
  enum: ['apple', 'banana', 'cherry', 'date'],
};

const uiSchema: UiSchema = {
  'ui:enumOrder': ['cherry', '*', 'apple'],
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

### Disabled attribute for `enum` fields

To disable an option, use the `ui:enumDisabled` property in the uiSchema.

```tsx
import { RJSFSchema, UiSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: 'boolean',
  enum: [true, false],
};

const uiSchema: UiSchema = {
  'ui:enumDisabled': [true],
};

render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, document.getElementById('app'));
```

## Nullable types

JSON Schema supports specifying multiple types in an array; however, react-jsonschema-form only supports a restricted subset of this -- nullable types, in which an element is either a given type or equal to null.

```tsx
import { RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  type: ['string', 'null'],
};

render(<Form schema={schema} validator={validator} />, document.getElementById('app'));
```

---

### Packages Docs Docs Migration Guides V2.X Upgrade Guide (`packages/docs/docs/migration-guides/v2.x upgrade guide.md`)

# 2.x Upgrade Guide

## Changes from v1 -> v2

### Breaking changes

- We now officially support the @rjsf/material-ui theme. We use a monorepo with Lerna and have published two packages (@rjsf/core and @rjsf/material-ui) with this version number. Note that react-jsonschema-form has been renamed to @rjsf/core ([#1642](https://github.com/rjsf-team/react-jsonschema-form/pull/1642))
- Combine all themes into a single playground ([#1539](https://github.com/rjsf-team/react-jsonschema-form/pull/1539), [#1607](https://github.com/rjsf-team/react-jsonschema-form/pull/1607), [#1623](https://github.com/rjsf-team/react-jsonschema-form/pull/1623))
- Remove ui:order console warning about extraneous properties ([#1508](https://github.com/rjsf-team/react-jsonschema-form/pull/1508))
- Capitalized Yes and No defaults ([#1395](https://github.com/rjsf-team/react-jsonschema-form/pull/1395))
- Fix id of oneof and anyof select ([#1212](https://github.com/rjsf-team/react-jsonschema-form/pull/1212)). The oneof select id is now suffixed by \_\_oneof_select and the anyof select by \_\_anyof_select.
- React 16+ is now a peer dependency ([#1408](https://github.com/rjsf-team/react-jsonschema-form/pull/1408))
- We no longer actively support Node version < 8 ([#1462](https://github.com/rjsf-team/react-jsonschema-form/pull/1462))
- Removed setState, setImmediate, safeRenderCompletion helpers/hacks ([#1454](https://github.com/rjsf-team/react-jsonschema-form/pull/1454), [#1720](https://github.com/rjsf-team/react-jsonschema-form/pull/1720))
- Inject defaults in arrays ([#1499](https://github.com/rjsf-team/react-jsonschema-form/pull/1499))

### Features

- Add material-ui theme in the main repo ([#1420](https://github.com/rjsf-team/react-jsonschema-form/pull/1420)) (note: has not been fully integrated yet -- this will be fully integrated when we publish multiple packages with lerna - [#1501](https://github.com/rjsf-team/react-jsonschema-form/pull/1501))
- Add extraErrors prop for async validation ([#1444](https://github.com/rjsf-team/react-jsonschema-form/pull/1444))
- Add support for overriding UnsupportedField ([#1660](https://github.com/rjsf-team/react-jsonschema-form/pull/1660))

### Fixes

- Fix issue with false as formData on radio components ([#1438](https://github.com/rjsf-team/react-jsonschema-form/pull/1438))
- Security patches ([#1458](https://github.com/rjsf-team/react-jsonschema-form/pull/1458), [#1459](https://github.com/rjsf-team/react-jsonschema-form/pull/1459))
- Memo components in custom widgets and fields. ([#1447](https://github.com/rjsf-team/react-jsonschema-form/pull/1447))
- Introduce Form autoComplete attribute and deprecate autocomplete ([#1483](https://github.com/rjsf-team/react-jsonschema-form/pull/1483))
- Rewrite mergeSchemas to fix schema dependencies merging ([#1476](https://github.com/rjsf-team/react-jsonschema-form/pull/1476))
- Update arrays correctly when changing index ([#1485](https://github.com/rjsf-team/react-jsonschema-form/pull/1485))
- Update anyOf schema to correctly update items in an array ([#1491](https://github.com/rjsf-team/react-jsonschema-form/pull/1491))
- Update schema to re-render when idschema changes ([#1493](https://github.com/rjsf-team/react-jsonschema-form/pull/1493))
- Make sure BooleanField supports an overridable DescriptionField ([#1594](https://github.com/rjsf-team/react-jsonschema-form/pull/1594))
- Export typings ([#1607](https://github.com/rjsf-team/react-jsonschema-form/pull/1607))

---

### Packages Docs Docs Migration Guides V3.X Upgrade Guide (`packages/docs/docs/migration-guides/v3.x upgrade guide.md`)

# 3.x Upgrade Guide

## Breaking changes

### Node support

Dropped support for Node 8, 9, 10. Minimum supported version of Node.js is now 12.

### Dereferenced schemas for `anyOf`/`allOf` options

`MultiSchemaField`'s `options` interface is different. Before, an option could include a `$ref`. Now, any option with a reference will be resolved/dereferenced when given as props for `MultiSchemaField`.

### Help field IDs

IDs for [Help fields](../api-reference/uiSchema.md#help) are now suffixed by `__help` so that the IDs are unique. Previously, their IDs would be nonexistent or the same as the fields that they were describing.

### Bring your own polyfills

core-js@2 has been removed from @rjsf/core. See more about [the rationale here](https://github.com/rjsf-team/react-jsonschema-form/pull/2211#issue-563700810).

If you're using a framework like [Create React App](https://create-react-app.dev/docs/supported-browsers-features#supported-browsers), [Gatsby](https://www.gatsbyjs.com/docs/how-to/custom-configuration/browser-support/), [Next.js](https://nextjs.org/docs/basic-features/supported-browsers-features), or transpiling code through something like `@babel/preset-env`, polyfills are already included there and you won't have to do anything.

If you were directly depending on @rjsf/core's @babel/runtime pulling in core-js@2, just `npm install core-js` and using a side effectful import at the top of your entry point (`import 'core-js'`) might be enough.

For a slightly more elaborate setup, [@babel/preset-env](https://babeljs.io/docs/en/babel-preset-env#how-does-it-work) is probably a good second choice.

From `@babel/preset-env`'s docs

> We leverage [`browserslist`, `compat-table`, and `electron-to-chromium`] to maintain mappings of which version of our supported target environments gained support of a JavaScript syntax or browser feature, as well as a mapping of those syntaxes and features to Babel transform plugins and core-js polyfills.

---

### Packages Docs Docs Migration Guides V4.X Upgrade Guide (`packages/docs/docs/migration-guides/v4.x upgrade guide.md`)

# 4.x Upgrade Guide

## Breaking changes

### React version

No longer actively supporting React version < 16.3. The minimum supported version of React is now 16.3. [Discussion can be found here](https://github.com/rjsf-team/react-jsonschema-form/pull/2605#discussion_r792685354)

### @rjsf/material-ui package - Minimum version of material-ui 4

If you are using the material-ui 4 theme, @material-ui/core and @material-ui/icons packages should be updated to the latest versions. The minimum versions supported for @material-ui/core and @material-ui/icons are 4.12.0 and 4.11.1 respectively. This change is required for [support for the material-ui version 5 theme](https://github.com/rjsf-team/react-jsonschema-form/tree/main/packages/material-ui)

---

### Packages Docs Docs Migration Guides V5.X Upgrade Guide (`packages/docs/docs/migration-guides/v5.x upgrade guide.md`)

# 5.x Upgrade Guide

## Breaking changes

There were several significant **breaking changes** in RJSF version 5 that were necessary in order to support the following new features:

- Schema validation was decoupled from `@rjsf/core` to resolve issue [#2693](https://github.com/rjsf-team/react-jsonschema-form/issues/2693). Additionally, in order to break a circular dependency in the validation refactor, the `@rjsf/core/utils.js` file was split out into its own `@rjsf/utils` package as was suggested in [#1655](https://github.com/rjsf-team/react-jsonschema-form/issues/1655).
- The theme for Material UI version 5 (i.e. `@rjsf/mui`) was split out of the theme for version 4 (i.e. `@rjsf/material-ui`) to resolve the following issues: [#2762](https://github.com/rjsf-team/react-jsonschema-form/issues/2762), [#2858](https://github.com/rjsf-team/react-jsonschema-form/issues/2858), [#2905](https://github.com/rjsf-team/react-jsonschema-form/issues/2905), [#2945](https://github.com/rjsf-team/react-jsonschema-form/issues/2945)
- As part of the fix for [#2526](https://github.com/rjsf-team/react-jsonschema-form/issues/2526) all the existing templates in the previous version were moved into a new `templates` dictionary, similar to how `widgets` and `fields` work. This `templates` dictionary was added to the `Registry` and also the `Form` props, replacing the `ArrayFieldTemplate`, `FieldTemplate`, `ObjectFieldTemplate` and `ErrorList` props. In addition, several of the `fields` and `widgets` based components were moved into the `templates` dictionary as they were more like templates than true `Field`s or `Widget`s. Also fixes [#2945](https://github.com/rjsf-team/react-jsonschema-form/issues/2945)
- Fixed `anyOf` and `oneOf` getting incorrect, potentially duplicate ids when combined with array [#2197](https://github.com/rjsf-team/react-jsonschema-form/issues/2197)
- `CheckboxesWidget`, `RadioWidget` and `SelectWidget` in all themes now use indexes into `enumOptions[]` rather than `option.value` to allow for objects in `enumOptions` - [#1494](https://github.com/rjsf-team/react-jsonschema-form/issues/1494)

### Node support

Version 5 is dropping official support for Node 12 as it is no longer a [maintained version](https://nodejs.org/en/about/releases/).
Please use Node 18 when making any changes to `package.json` and `package-lock.json` files.
All PR and branch builds are running against Node 14, 16 and 18.

### React version

RJSF is no longer actively supporting React version < 16.14.x.
React 17 is officially supported on all the themes where the underlying theme library also supports React 17.

Unfortunately, there is required work pending to properly support React 18, so use it at your own risk.

### New packages

There are four new packages added in RJSF version 5:

- `@rjsf/utils`: All of the [utility functions](../api-reference/utility-functions.md) previously imported from `@rjsf/core/utils` as well as the Typescript types for RJSF version 5.
  - The following new utility functions were added: `ariaDescribedByIds()`, `createSchemaUtils()`, `descriptionId()`, `enumOptionsDeselectValue()`, `enumOptionsIndexForValue()`, `enumOptionsIsSelected()`, `enumOptionsSelectValue()`, `enumOptionsValueForIndex()`, `errorId()`, `examplesId()`, `getClosestMatchingOption()`, `getFirstMatchingOption()`, `getInputProps()`, `helpId()`, `mergeValidationData()`, `optionId()`, `sanitizeDataForNewSchema()` and `titleId()`
- `@rjsf/validator-ajv6`: The [ajv](https://github.com/ajv-validator/ajv)-v6-based validator refactored out of `@rjsf/core@4.x`, that implements the `ValidatorType` interface defined in `@rjsf/utils`.
- `@rjsf/validator-ajv8`: The [ajv](https://github.com/ajv-validator/ajv)-v8-based validator that is an upgrade of the `@rjsf/validator-ajv6`, that implements the `ValidatorType` interface defined in `@rjsf/utils`. See the ajv 6 to 8 [migration guide](https://ajv.js.org/v6-to-v8-migration.html) for more information.
- `@rjsf/mui`: Previously `@rjsf/material-ui/v5`, now provided as its own theme.

### `id` BREAKING CHANGES

In many of the themes the `id`s for the `Title`, `Description` and `Examples` blocks were update to all have a consistent value of `xxx__title`, `xxx__description` and `xxx__examples`, respectively, where `xxx` is the id of the field.
In addition, some of the `id`s for various input values were updated to be consistent across themes or to fix small bugs.
For instance, the values for radio buttons in the `RadioWidget` and checkboxes in the `CheckboxesWidget` are of the form `xxx-${option.value}`, where `xxx` is the id of the field.

### `enumOptions[]` widgets BREAKING CHANGES

Schemas may have `enumOptions[]` where values are objects rather than primitive types. Examples of such schemas have been added to the playground. These schemas did not work in RJSF prior to v5.
In every theme, the `enumOptions[]` rendering widgets `CheckboxesWidget`, `RadioWidget` and `SelectWidget` previously used the `enumOptions[].value` to as the value used for the underlying `checkbox`, `radio` and `select.option` elements.
Now, these `CheckboxesWidget`, `RadioWidget` and `SelectWidget` components use the index of the `enumOptions[]` in the list as the value for the underlying elements.
If you need to build a custom widget for this kind of `enumOptions`, there are a set of `enumOptionsXXX` functions in `@rjsf/utils` to support your implementation.

### `@rjsf/core` BREAKING CHANGES

#### Types

In version 4, RJSF exported all its types directly from `@rjsf/core`.
In version 5, only the types for the `Form` component and the `withTheme()` HOC are exported directly from `@rjsf/core`.
All the rest of the types for RJSF are now exported from the new `@rjsf/utils` package.

NOTE: The types in `@rjsf/utils` have been improved significantly from those in version 4 and as a result may require you to fix your Typescript typings and add some casts.

Some of the most notable changes are:

- `RJSFSchema` has replaced the use of `JSON7Schema` for future compatibility reasons.
  - Currently `RJSFSchema` is simply an alias to `JSON7Schema` so this change is purely a naming one.
  - It is highly recommended to update your use of `JSON7Schema` with `RJSFSchema` so that when the RJSF begins supporting a newer JSON Schema version out-of-the-box, your code won't be affected.
- `RJSFSchemaDefinition` has replaced the use of `JSONSchema7Definition` for the same reasons.

- The use of the generic `T` (defaulting to `any`) for the `formData` type has been expanded to cover all type hierarchies that use `formData`.
- `StrictRJSFSchema` and `RJSFSchema` have replaced the use of `JSON7Schema` for future compatibility reasons.
  - `RJSFSchema` is `StrictRJSFSchema` joined with the `GenericObjectType` (i.e. `{ [key: string]: any }`) to allow for additional syntax related to newer draft versions
  - All definitions of `schema` and `rootSchema` elements have been replaced with a generic that is defined as `S extends StrictRJSFSchema = RJSFSchema`
  - It is highly recommended to update your use of `JSON7Schema` with `RJSFSchema` since that is the default for the new generic used for `schema` and `rootSchema`
- A new generic `F` (extending `FormContextType` defaulting to `any`) was added for the `formContext` type, and all types in the hierarchy that use `formContext` have had that generic added to them.
- The new `CustomValidator`, `ErrorTransformer`, `ValidationData`, `ValidatorType` and `SchemaUtilsType` types were added to support the decoupling of the validation implementation.
- The new `TemplatesType`, `ArrayFieldDescriptionProps`, `ArrayFieldTitleProps`, `UnsupportedFieldProps`, `IconButtonProps`, `SubmitButtonProps` and `UIOptionsBaseType` were added to support the consolidation (and expansion) of `templates` in the `Registry` and `Form`.
- **BREAKING CHANGE** The `DescriptionField` and `TitleField` props were removed from the `ArrayFieldTemplateProps` and `ObjectFieldTemplateProps` as they can now be derived from the `templates` or `uiSchema` via the new `getTemplate()` utility function.
- **BREAKING CHANGE** The `fields` prop was removed from the `FieldTemplateProps` as you can simply use `registry.fields` instead.
- **BREAKING CHANGE** The `showErrorList` prop was changed to accept `false`, `"top"` or `"bottom"`. `true` is no longer a valid value. The default value is `"top"`, which has identical behavior to the default value/`true` in v4.
  You can view all these [types](https://github.com/rjsf-team/react-jsonschema-form/blob/main/packages/utils/src/types.ts) on GitHub.

#### Form props

In version 5, the `Form` component's two optional props `additionalMetaSchemas` and `customFormats` were replaced with the new, required `validator` prop, in order to support the decoupling of the validation implementation.
This new `validator` prop is expected to be an implementation of the `ValidatorType` interface.
The new `@rjsf/validator-ajv6` package contains the refactored implementation of the version 4 validator; It was provided for backwards compatibility with RJSF v4, and it is deprecated.  
The new `@rjsf/validator-ajv8` package contains the refactored implementation of the version 4 validator, that has been converted to use the `Ajv 8` validator and has more capabilities than the `Ajv 6` one. See the [Ajv migration guide](https://ajv.js.org/v6-to-v8-migration.html) for more information.

There are two ways to use this new package to provide a `validator` for a `Form`.
First, you can simply import the default validator from the package and pass it to a `Form`.

```tsx
import { RJSFSchema } from "@rjsf/utils";
import Form from "@rjsf/core";
import validator from "@rjsf/validator-ajv8";

// Your schema
const schema: RJSFSchema = { ... };

render((
  <Form schema={schema} validator={validator} />
), document.getElementById("app"));
```

Second, if you were actually providing one (or both) of the removed optional props to your `Form`, you can continue using them by creating a customized validator.

```tsx
import { RJSFSchema } from "@rjsf/utils";
import Form from "@rjsf/core";
import { customizeValidator, CustomValidatorOptionsType } from "@rjsf/validator-ajv8";

// Your schema, additionalMetaSchemas and/or customFormats
const schema: RJSFSchema = { ... };
const additionalMetaSchemas: CustomValidatorOptionsType['additionalMetaSchemas'] = [{ ... }];
const customFormats: CustomValidatorOptionsType['customFormats'] = { ... };

const validator = customizeValidator({ additionalMetaSchemas, customFormats });

render((
  <Form schema={schema} validator={validator} />
), document.getElementById("app"));
```

##### `formElement` converted to RefObject

The `formElement` variable that stored the ref to the inner `<form />` was converted from a simple variable assigned via a [callback ref](https://reactjs.org/docs/refs-and-the-dom.html#callback-refs) (ala React < 16.3) to a React.RefObject created using the `React.createRef()` API.
As a result, if you were using the `formElement` ref, you will need to update it to use `formElement.current`:

```tsx
import { RJSFSchema } from "@rjsf/utils";
import Form from "@rjsf/core";
import validator from "@rjsf/validator-ajv8";

// Your schema
const schema: RJSFSchema = { ... };

const formRef = React.createRef();

render((
  <Form ref={formRef} schema={schema} validator={validator} />
), document.getElementById("app"));

...
// Previously, to reset the form one would have called:
//   formRef.current.formElement.reset();
// Now one calls:
formRef.current.formElement.current.reset();
```

##### `validate` prop renamed

Additionally, in version 5, the `validate` prop on `Form` was renamed to `customValidate` to avoid confusion with the new `validator` prop.

##### `fields` prop changes

In previous versions, it was possible to provide an override to the `DescriptionField`, `TitleField` and/or `UnsupportedField` components by providing a custom implementation in the `fields` prop on the `Form`.
Since these components do not actually support the `FieldProps` interface, they were moved into the `templates` dictionary instead.
If you were previously overriding any (or all) of these components, you can override them now via the `templates` prop on `Form` instead:

```tsx
import { DescriptionFieldProps, RJSFSchema, TitleFieldProps } from "@rjsf/utils";
import Form from "@rjsf/core";
import validator from "@rjsf/validator-ajv8";

// Your schema
const schema: RJSFSchema = { ... };

// Your custom fields
const CustomDescriptionField = (props: DescriptionFieldProps) => { ... };
const CustomTitleField = (props: TitleFieldProps) => { ... };
const CustomUnsupportedField = (props: ObjectFieldTemplateProps) => { ...
};

const templates: Partial<TemplatesType> = {
  DescriptionFieldTemplate: CustomDescriptionField,
  TitleFieldTemplate: CustomTitleField,
  UnsupportedFieldTemplate: CustomUnsupportedField,
};

render((
  <Form schema={schema} validator={validator} templates={templates}/>
), document.getElementById("app"));
```

##### new `templates` prop

Additionally, in version 5, the `ArrayFieldTemplate`, `FieldTemplate`, `ObjectFieldTemplate` and `ErrorList` props were replaced with the `templates` prop as part of the `TemplatesType` consolidation.
If you were previously overriding any (or all) of these templates, you can simply consolidate them into the new `templates` prop on `Form` instead:

```tsx
import { ArrayFieldTemplateProps, ErrorListProps, FieldTemplateProps, ObjectFieldTemplateProps, RJSFSchema } from "@rjsf/utils";
import Form from "@rjsf/core";
import validator from "@rjsf/validator-ajv8";

// Your schema
const schema: RJSFSchema = { ... };

// Your custom templates
const CustomArrayFieldTemplate = (props: ArrayFieldTemplateProps) => { ... };
const CustomFieldTemplate = (props: FieldTemplateProps) => { ... };
const CustomObjectFieldTemplate = (props: ObjectFieldTemplateProps) => { ... };
const CustomErrorField = (props: ErrorListProps) => { ... };

const templates: Partial<TemplatesType> = {
  ArrayFieldTemplate: CustomArrayFieldTemplate,
  FieldTemplate: CustomFieldTemplate,
  ObjectFieldTemplate: CustomObjectFieldTemplate,
  ErrorFieldTemplate: CustomErrorField,
};

render((
  <Form schema={schema} validator={validator} templates={templates} />
), document.getElementById("app"));
```

NOTE: In version 5, the `ArrayField` implementation was refactored to add 3 additional templates for presenting arrays along with the `ArrayFieldTemplate`.
If you were updating the `ArrayFieldTemplate` to modify just a subset of the UI, it may be easier for you to implement one of the other new templates instead.
See the [Custom Templates](../advanced-customization/custom-templates.md) documentation for more details.

##### `widgets` prop change

In the previous version, it was possible to provide an override to the `SubmitButton` component by providing a custom implementation in the `widgets` prop on the `Form`.
Since this component only requires a tiny fraction of the `WidgetProps` interface, it was moved into the `templates.ButtonTemplates` dictionary instead with its own, reduced set of props.
If you were previously overriding this component, you can override it now via the `templates` prop on `Form` instead:

```tsx
import { RJSFSchema, SubmitButtonProps } from "@rjsf/utils";
import Form from "@rjsf/core";
import validator from "@rjsf/validator-ajv8";

// Your schema
const schema: RJSFSchema = { ... };

// Your custom button
const CustomSubmitButton = (props: SubmitButtonProps) => { ...
};

const templates: Partial<TemplatesType> = {
  ButtonTemplates: {
    SubmitButton: CustomSubmitButton,
  }
};

render((
  <Form schema={schema} validator={validator} templates={templates}/>
), document.getElementById("app"));
```

#### utils.js

In version 5, all the utility functions that were previously accessed via `import { utils } from '@rjsf/core';` are now available via `import utils from '@rjsf/utils';`.
Because of the decoupling of validation from `@rjsf/core` there is a breaking change for all the [validator-based utility functions](../api-reference/utility-functions.md#validator-based-utility-functions), since they now require an additional `ValidatorType` parameter.
More over, one previously exported function `resolveSchema()` is no longer exposed in the `@rjsf/utils`, so use `retrieveSchema()` instead.
Finally, the function `getMatchingOption()` has been deprecated in favor of `getFirstMatchingOption()`.

If you have built custom fields or widgets that utilized any of these breaking-change functions, don't worry, there is a quick and easy solution for you.
The `registry` has a breaking-change which removes the previously deprecated `definitions` property while adding the new `schemaUtils` property.
This new `registry.schemaUtils` property implements the `SchemaUtilsType` interface, which allows you to call a version of each of these breaking-change functions without the need for passing either a `validator` or `rootSchema`.
Because all fields and widgets are guaranteed to be passed the `registry` as a prop, if your custom field/widget happens to use either the `registry.definitions` object or a breaking-change validator-based utility function you make the following changes:

```tsx
import { RJSFSchema, FieldProps } from '@rjsf/utils';

function YourField(props: FieldProps) {
  const { registry } = props;
// Change `registry.definitions` to `registry.rootSchema.definitions`
// const { definitions } = registry; <- version 4
  const { rootSchema } = registry;
  const { definitions } = rootSchema;
...
}
```

```tsx
// Change breaking-change function to schemaUtils instead, otherwise import from @rjsf/utils
// import { utils } from '@rjsf/core'; <- version 4
// const { isMultiSelect, resolveSchema, getUiOptions } = utils; <- version 4
import { RJSFSchema, WidgetProps, getUiOptions } from '@rjsf/utils';

function YourWidget(props: WidgetProps) {
  const { registry, uiSchema } = props;
  const { schemaUtils } = registry;
// const matchingOption = getMatchingOption({}, options, rootSchema); <- version 4
// const isMultiSelect = isMultiSelect(schema, rootSchema); <- version 4
// const newSchema = resolveSchema(schema, formData, rootSchema); <- version 4
  const matchingOption = schemaUtils.getFirstMatchingOption({}, options);
  const isMultiSelect = schemaUtils.isMultiSelect(schema);
  const newSchema: RJSFSchema = schemaUtils.retrieveSchema(schema, formData);
  const options = getUiOptions(uiSchema);

...
}
```

#### validator.js

Because of the decoupling of validation from `@rjsf/core` this file was refactored into its own `@rjsf/validator-ajv8` package.
During that refactor a few **breaking changes** were made to how it works related to custom validation and `ErrorSchema` conversion.

##### toErrorList param changed

In previous versions, the `toErrorList()` function used to take a `fieldName` string defaulted to `root`, and used it to format the `stack` message.
In version 5, `fieldName` was changed to `fieldPath` string array defaulted to an empty array, and is used to recursively add the field name to the errors as the `property` object along with the raw `message`.
The result is that if you had an `ErrorSchema` that looks like:

```tsx
const errorSchema: ErrorSchema = {
  __errors: ['error message 1'],
  password: { __errors: 'passwords do not match' },
};
```

The returned result from calling `toErrorList(errorSchema)` has changed as follows:

```tsx
// version 4 result
[{ stack: 'root: error message 1' }, { stack: 'password: passwords do not match' }][
  // version 5 result
  ({ property: '.', message: 'error message 1', stack: '. error message 1' },
  {
    property: '.password',
    message: 'passwords do not match',
    stack: '.password passwords do not match',
  })
];
```

##### Custom validation and extraErrors

In previous versions, when using a custom validator on the `Form`, any errors that were generated were inconsistently inserted into the validations `errors` list.
In addition, there was an [issue](https://github.com/rjsf-team/react-jsonschema-form/issues/1596) where the non-`stack` AJV error information was lost when custom validation generated errors.
This issue has been fixed.
Also, when `extraErrors` were provided, they were being inconsistently inserted into the `errors` list and the non-`stack` AJV error information was lost.
In version 5, all of these errors will be consistently appended onto the end of the validation `errors` list, and the additional AJV error information is maintained.

In other words, if custom validation or `extraErrors` produced the following `ErrorSchema`:

```tsx
{
  __errors: [ "Please correct your password"],
  password2: { __errors: "passwords do not match" }
}
```

And the AJV validation produced the following `ErrorSchema`:

```tsx
{
  __errors: [
    {
      message: 'should NOT be shorter than 3 characters',
      name: 'minLength',
      params: { limit: 3 },
      property: '.password2',
      schemaPath: '#/properties/password2/minLength',
      stack: '.password2 should NOT be shorter than 3 characters',
    },
  ];
}
```

The resulting `errors` list has changed as follows:

```tsx
// version 4
[
  { stack: 'root: Please correct your password' },
  { stack: 'password2: passwords do not match' },
  { stack: 'password2: should NOT be shorter than 3 characters' },
][
  // version 5
  ({
    message: 'should NOT be shorter than 3 characters',
    name: 'minLength',
    params: { limit: 3 },
    property: '.password2',
    schemaPath: '#/properties/password2/minLength',
    stack: '.password2 should NOT be shorter than 3 characters',
  },
  {
    property: '.',
    message: 'Please correct your password',
    stack: '. Please correct your password',
  },
  {
    property: '.',
    message: 'passwords do not match',
    stack: '.password2 passwords do not match',
  })
];
```

#### Generate correct ids when arrays are combined with `anyOf`/`oneOf`

In v4, with arrays inside `anyOf` or `oneOf`, the parent name was not used to generate ids.
For example, given a schema such as:

```json
{
  "type": "object",
  "properties": {
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "anyOf": [
          {
            "properties": {
              "foo": {
                "type": "string"
              }
            }
          },
          {
            "properties": {
              "bar": {
                "type": "string"
              }
            }
          }
        ]
      }
    }
  }
}
```

We would get fields with id `root_foo` and `root_bar`.
As you can imagine, we could end up with duplicated ids if there's actually a `foo` or a `bar` in the root of the schema.

From v5, the child fields will correctly use the parent id when generating its own id, generating ids such as `root_items_0_foo`.

#### Deprecations added in v5

##### getMatchingOption()

The utility function `getMatchingOption()` was deprecated in favor of the more aptly named `getFirstMatchingOption()` which has the exact same implementation.

##### Non-standard `enumNames` property

`enumNames` is a non-standard JSON Schema field that was deprecated in version 5.
`enumNames` could be included in the schema to apply labels that differed from an enumeration value.
This behavior can still be accomplished with `oneOf` or `anyOf` containing `const` values, so `enumNames` support will be removed from a future major version of RJSF.
For more information, see [#532](https://github.com/rjsf-team/react-jsonschema-form/issues/532).

##### uiSchema.classNames

In versions previous to 5, `uiSchema.classNames` was the only property that did not require the `ui:` prefix.
Additionally, it did not support being added into the `ui:options` object.
This was fixed in version 5 to be consistent with all the other properties in the `uiSchema`, so the `uiSchema.classNames` support may be removed from a future major version of RJSF.

If you are using `classNames` as follows, simply add the `ui:` prefix to it to remove the deprecation warning that will be displayed for each `uiSchema.classNames` you have:

```tsx
import { UiSchema } from '@rjsf/utils';

// This uiSchema will log a deprecation warning to the console
const uiSchemaLog: UiSchema = {
  title: {
    classNames: 'myClass',
  },
};
// This uiSchema will not
const uiSchemaNoLog: UiSchema = {
  title: {
    'ui:classNames': 'myClass',
  },
};
```

### `@rjsf/material-ui` BREAKING CHANGES

This theme was simplified back to working only with Material UI version 4 after an unsuccessful attempt to have it fully support both versions 4 and 5 simultaneously.
As a result, the `MuiComponentContext`, `MuiForm5`, `Theme5` components and the `useMuiComponent` hook were removed from the export.
In addition, the `/v4` and `/v5` sub-packages were also removed.

#### Migrating for Material UI version 4

If you were using this theme for Material UI version 4 AND you were using the sub-package, simply remove the `/v4` from your imports.

If you modified your Typescript configuration for the `/v4` sub-package, remove the following from your `tsconfig.json`:

```
{
  ...
  "compilerOptions": {
    ...
    "baseUrl": ".",
    "paths": {
      "@rjsf/material-ui/*": ["node_modules/@rjsf/material-ui/dist/*"]
    }
  }
}
```

If you modified your Jest configuration for the `/v4` sub-package, remove the following from your `jest.config.json`:

```
  "moduleNameMapper": {
    "@rjsf/material-ui/v4": "<rootDir>/node_modules/@rjsf/material-ui/dist/v4.js"
  },
```

#### Migrating for Material UI version 5

If you were using this theme for Material UI version 5, you will want to use `@rjsf/mui` instead.
See below for some before and after examples.

If you modified your Typescript configuration for the `/v5` sub-package, remove the following from your `tsconfig.json`:

```
{
  ...
  "compilerOptions": {
    ...
    "baseUrl": ".",
    "paths": {
      "@rjsf/material-ui/*": ["node_modules/@rjsf/material-ui/dist/*"]
    }
  }
}
```

If you modified your Jest configuration for the `/v5` sub-package, remove the following from your `jest.config.json`:

```
  "moduleNameMapper": {
    "@rjsf/material-ui/v5": "<rootDir>/node_modules/@rjsf/material-ui/dist/v5.js"
  },
```

##### Before

```tsx
import Form5 from '@rjsf/material-ui';
```

or

```tsx
import Form from '@rjsf/material-ui/v5';
```

or

```tsx
import { withTheme } from '@rjsf/core';
import { Theme } from '@rjsf/material-ui/v5';
// Make modifications to the theme with your own fields and widgets
const Form = withTheme(Theme);
```

or

```tsx
import { withTheme } from '@rjsf/core';
import { Theme as Theme5 } from '@rjsf/material-ui';
// Make modifications to the theme with your own fields and widgets
const Form = withTheme(Theme5);
```

##### After

```tsx
import Form from '@rjsf/mui';
```

or

```tsx
import { withTheme } from '@rjsf/core';
import { Theme } from '@rjsf/mui';
// Make modifications to the theme with your own fields and widgets
const Form = withTheme(Theme);
```

---

### Packages Docs Docs Migration Guides V6.X Upgrade Guide (`packages/docs/docs/migration-guides/v6.x upgrade guide.md`)

# 6.x Upgrade Guide

## New packages

There are 5 new packages added in RJSF version 6:

- `@rjsf/daisyui`: This is new theme based on the `daisyui` toolkit
- `@rjsf/mantine`: This is new theme based on the `mantine` toolkit
- `@rjsf/primereact`: This is a new theme based on the `PrimeReact` toolkit
- `@rjsf/react-bootstrap`: This is rename of the `bootstrap-4` theme with an upgrade to the latest version of `react-bootstrap`
- `@rjsf/shadcn`: This is new theme based on the `shadcn` toolkit

## New deprecations

### UiSchema.rootFieldId

The `ui:rootFieldId` notation on `UiSchema` was deprecated in favor of `Form.idPrefix`.
This notation will be removed in a future major version release

### @rjsf/semantic-ui

The `semantic-ui` theme is deprecated and will be removed in a future major version release unless `sematic-ui-react` version 3 is released with React 19 support.
Although that seems unlikely as no changes have been made to version 3 since December 2023.

## Breaking changes

### CJS build changes

Due to making all of the `package.json` files for the `@rjsf/*` libraries include `"type": "module"` to better support modern `ESM` builds, the generation of the Common JS distributions were updated to produce `.cjs` files rather than `.js` files.
Hopefully this will not cause any issues with existing uses of the libraries. If so, one may need to switch from doing an `import` of the CJS build to doing a `require()`.

### Theme removals

The following themes were removed due to duplication of a framework with a newer theme

#### bootstrap-4

The older `bootstrap-4` theme has been removed in favor of the `react-bootstrap` theme

#### fluent-ui

The older `fluent-ui` theme has been removed in favor of the `fluentui-rc` theme

#### material-ui

The older `material-ui` theme has been removed in favor of the `mui` theme

### validator-ajv6

This deprecated validator has been removed. Use the `validator-ajv8`.

### Theme version support changes

#### @rjsf/antd

Version 6 is dropping official support for `antd` version 4. You must upgrade to version 5.

#### @rjsf/chakra-ui

Version 6 is dropping official support for `@chakra-ui` version 2. You must upgrade to version 3. We are also requiring
`chakra-react-select` version >=6 as a result.

#### @mui version 5 and 6

Version 6 is dropping official support for `@mui/material` and `@mui/icons-material` versions 5 and 6 due to the adoption
of breaking changes in version 7. You must upgrade to version 7.

#### @rjsf/semantic-ui

Version 6 is dropping official support for `semantic-ui-react` version 1. You must upgrade to version 2.

### Node support

Version 6 is dropping official support for Node 14, 16, and 18 as they are no longer [maintained versions](https://nodejs.org/en/about/releases/).
Please use Node 22 when making any changes to `package.json` and `package-lock.json` files.
All PR and branch builds are running against Node 20 and 22.

### React version

RJSF is no longer actively supporting React version < 18.x.
React 18 is officially supported on all the themes.

React 19 support is expected before the end of beta (although several developers have already upgraded with no problems).

### Form POTENTIAL BREAKING CHANGES

The `onChange()` and `onSubmit()` callbacks were accidentally returning extra data along with what was listed in the `IChangeEvent` interface.
In v6, this was fixed so that only the data described by the `IChangeEvent` interface is returned.
If you were relying on that extra data in the callbacks, we are sorry for the inconvenience.

A bug was fixed such that live validation will no longer be triggered on the data provided during the initial rendering of the `Form`.
If you require that your initial data have errors shown, then you can [programmatically validate](../usage/validation/#validate-form-programmatically) it after the initial render.

### IdSchema replacement BREAKING CHANGE

The recursive `IdSchema` type and all its usages was replaced with a much simpler `FieldPathId` type.
This was done to remove a performance headache associated with having to recursively generate the `IdSchema` for every change made to `formData`.
Moreover, after some evaluation, 99% of the use cases for the `IdSchema` were simply to get the `id` for a field.

`FieldPathId` is defined as:

```typescript
/** The list of path elements that represents where in the schema a field is located. When the item in the field list is
 * a string, then it represents the name of the property within an object. When it is a number, then it represents the
 * index within an array.
 *
 * For example:
 * `[]` represents the root object of the schema
 * `['foo', 'bar']` represents the `bar` element contained within the `foo` element of the schema
 * `['baz', 1]` represents the second element in the list `baz` of the schema
 */
export type FieldPathList = (string | number)[];

/** Type describing an id and path used for a field */
export type FieldPathId = {
  /** The id for a field */
  $id: string;
  /** The path for a field */
  path: FieldPathList;
};
```

#### idSchema props

In addition, everywhere the `idSchema: IdSchema<T>` prop was part of a RJSF type, it was replaced with `fieldPathId: FieldPathId`.

The affected types are:

- FieldErrorProps
- FieldHelpProps
- FieldProps
- UnsupportedFieldProps
- ArrayFieldTitleProps
- ArrayFieldDescriptionProps
- ArrayFieldItemButtonsTemplateProps
- ArrayFieldTemplateProps
- ObjectFieldTemplateProps

If you have built a custom component using one of those types that used `idSchema: IdSchema`, simply replace that type and property name with `fieldPathId: FieldPathId`.

For example, if you had a custom field:

```tsx
import { FieldProps } from '@rjsf/utils';

// Version 5-based custom widget
function CustomField(props: FieldProps) {
  const {
    idSchema: { $id },
    formData,
    value,
  } = props;

  return <div id={$id}>// Your field implementation</div>;
}

// Version 6-based custom widget
function CustomField(props: FieldProps) {
  const {
    fieldPathId: { $id },
    formData,
    value,
  } = props;

  return <div id={$id}>// Your field implementation</div>;
}
```

#### toIdSchema() removed

Finally, the `toIdSchema()` utility function was deleted and replaced with a new `toFieldPathId()` function documented [here](../api-reference/utility-functions.md#tofieldpathid)

### formContext BREAKING CHANGES

Removed the unnecessary `formContext` property from the following interfaces since it is readily available in the `registry`.
If you were using the `formContext` in your custom `template`, `field` or `widget`, simply get it from the `registry` instead.

Interfaces with `formContext` removed:

- `ErrorListProps` - The properties that are passed to an `ErrorListTemplate` implementation
- `FieldProps` - The properties that are passed to a `Field` implementation
- `FieldTemplateProps` - The properties that are passed to a `FieldTemplate` implementation
- `ArrayFieldTemplateProps` - The properties that are passed to an `ArrayFieldTemplate` implementation
- `WidgetProps` - The properties that are passed to a `Widget` implementation

### Fields BREAKING CHANGES

#### FieldProps.onChange

The `onChange` handling for fields has been changed to fix a serious bug related to nearly simultaneous updates losing data.
Previously in 5.x, data change handling worked by passing a complete `newFormData` object up to the `Form` from the underlying `Field`s.
In 6.x, data change handling now works by passing just the changed `newValue` for a `Field` and the `path` array of the `Field` within the `formData`, with the `Form` itself being responsible for injecting the changed data into the `formData`.

As a result, the `FieldProps` interface was updated with the following breaking change so that custom `Field` authors are forced to respond to this update:

```typescript
// Version 5's `onChange` handler:

/** The field change event handler; called with the updated form data and an optional `ErrorSchema` */
onChange: (newFormData: T | undefined, es?: ErrorSchema<T>, id?: string) => any;

// Version 6's `onChange` handler:
/** The field change event handler; called with the updated field value, the optional change path for the value
 * (defaults to an empty array), an optional ErrorSchema and the optional id of the field being changed
 */
onChange: (newValue: T | undefined, path: FieldPathList, es?: ErrorSchema<T>, id?: string) => void;
```

In order to support letting the `Form` know what the path of the change was, a new `path: FieldPathList` parameter was injected into the handler before the `es?: ErrorSchema<T>` parameter.
If you have written a custom `Field` that implements merging the new value into the `newFormData`, now you just need to pass that value and provide the `fieldPathId.path` to the `onChange` function.

Here is an example of a custom `Field` that was updated due to this change:

```
/* Detailed source-code truncated for AI context efficiency. */
```

The same change also applies to the `ErrorSchema` object being passed to the `Form`.
Therefore, if your custom `Field` also updated the `ErrorSchema` to add a new error, now you just need to pass that error as well.
Finally, the errors are preserved across validations, so if you want to clear an error you passed via `onChange`, you will have to pass `undefined`

Here is an example of a custom `Field` that was updated due to this change:

```tsx
import { FieldProps } from '@rjsf/utils';
import { getDefaultRegistry } from '@rjsf/core';

const { StringField } = getDefaultRegistry().fields;

// Version 5-based custom field
function StringFieldError(props: FieldProps) {
  const onChange = (newFormData: any | undefined, es?: ErrorSchema, id?: string) => {
    let raiseError = es;
    if (newFormData === 'test') {
      raiseError = {
        ...es,
        __errors: ['Value cannot be "test"'],
      };
    }
    props.onChange(newFormData, raiseError, id);
  };
  return <StringField {...props} onChange={onChange} />;
}

// Version 6-based custom field
function StringFieldError(props: FieldProps) {
  const onChange = (newValue: any | undefined, path: FieldPathList, es?: ErrorSchema, id?: string) => {
    let raiseError = es;
    if (newValue === 'test') {
      raiseError = {
        __errors: ['Value cannot be "test"'],
      };
    }
    props.onChange(newValue, path, raiseError, id);
  };
  return <StringField {...props} onChange={onChange} />;
}
```

#### FieldProps.idPrefix and FieldProps.idSeparator refactor

The `idPrefix` and `idSeparator` props were refactored from the `FieldProps` interface to the new `GlobalFormOptions` interface,
If your custom implementation required either of those props, you can simply obtain them from the `registry.globalFormOptions` variable instead.

### FieldTemplateProps and WrapIfAdditionalTemplateProps BREAKING CHANGES

During the conversion of `ObjectField` to a stateless functional component, the `additionalProperties`-based props in these two interfaces were simplified by replacing two callback-generators with memoized callbacks.

If you have your own implementation of the `FieldTemplate` and/or `WrapIfAdditionalTemplate` template(s), you will have to rename the props mentioned below with their replacements.

#### onKeyChange replacement

The `onKeyChange: (value: string) => () => void` callback-generator function was replaced with the following 2 memoized callbacks, (one is a helper callback, since most of the key renames were triggered off of an input blur):

```typescript
/** Callback used to handle the changing of an additional property key's name with the new value
 */
onKeyRename: (newKey: string) => void;
/** Callback used to handle the changing of an additional property key's name when the input is blurred. The event's
 * target's value will be used as the new value. Its a wrapper callback around `onKeyRename`
 */
onKeyRenameBlur: (event: FocusEvent<HTMLInputElement>) => void;
```

#### onDropPropertyClick replacement

The `onDropPropertyClick: (value: string) => () => void` callback-generator function was replaced with the following memoized callback:

```typescript
/** Callback used to handle the removal of the additionalProperty */
onRemoveProperty: () => void;
```

### ObjectFieldTemplateProps BREAKING CHANGES

During the conversion of `ObjectField` to a stateless functional component, the `additionalProperties`-based prop in this interface was simplified by replacing a callback-generator with a memoized callback.

If you have your own implementation of the `ObjectFieldTemplate` template, you will have to rename the prop mentioned below with its replacement.

#### onAddClick replacement

The `onAddClick: (schema: S) => () => void` callback-generator function was replaced with the following memoized callback:

```typescript
/** Callback to use in order to add an new additionalProperty to the object field  (to be used with
 * additionalProperties and patternProperties)
 */
onAddProperty: () => void;
```

### Registry BREAKING CHANGES

A new required prop, `globalFormOptions: GlobalFormOptions`, was added to the `Registry` interface.
This could affect your tests if you have your own way of creating `registry` objects to test your custom widgets, fields and/or templates.
If you are creating `Registry` objects, you simply need to add an empty object to the `globalFormOptions` prop.
You may also, provide values for any of the optional props contained within the `GlobalFormOptions` type.

The definition of the `GlobalFormOptions` object is:

```typescript
/** The set of options from the `Form` that will be available on the `Registry` for use in everywhere the `registry` is
 * available.
 */
export type GlobalFormOptions = {
  /** To avoid collisions with existing ids in the DOM, it is possible to change the prefix used for ids;
   * Default is `root`. This prop is passed to the `toFieldPathId()` function within the RJSF field implementations.
   */
  readonly idPrefix?: string;
  /** To avoid using a path separator that is present in field names, it is possible to change the separator used for
   * ids; Default is `_`. This prop is passed to the `toFieldPathId()` function within the RJSF field implementations.
   */
  readonly idSeparator?: string;
  /** The component update strategy used by the Form and its fields for performance optimization */
  readonly experimental_componentUpdateStrategy?: 'customDeep' | 'shallow' | 'always';
  /** Optional function to generate custom HTML name attributes for form elements. Receives the field path segments
   * and element type (object or array), and returns a custom name string. This allows backends like PHP/Rails
   * (`root[tasks][0][title]`) or Django (`root__tasks-0__title`) to receive form data in their expected format.
   */
  readonly nameGenerator?: NameGeneratorFunction;
};
```

To help support this change for test writers, a new `getTestRegistry()` function has been provided in `@rjsf/core`.

### Templates BREAKING CHANGES

#### ArrayFieldTemplateItemType renamed

The type `ArrayFieldTemplateItemType` was renamed to `ArrayFieldItemTemplateProps` type, which matches the template properties naming pattern.

Also changed the `key: string` prop to `itemKey: string` to avoid a name collision with React

#### ArrayFieldItemTemplate BREAKING CHANGES

The `ArrayFieldItemTemplateProps` was refactored to extract the following props into out a new `ArrayFieldItemButtonsTemplateProps`:

- `canAdd`: A boolean value stating whether new items can be added to the array.
- `hasCopy`: A boolean value stating whether the array item can be copied.
- `hasMoveDown`: A boolean value stating whether the array item can be moved down.
- `hasMoveUp`: A boolean value stating whether the array item can be moved up.
- `hasRemove`: A boolean value stating whether the array item can be removed.
- ~~`onAddIndexClick: (index) => (event?) => void`: Returns a function that adds a new item at `index`.~~
- ~~`onCopyIndexClick: (index: number) => (event?: any) => void;`: Returns a function that copies the item at `index` into the position at `index + 1`.~~
- ~~`onDropIndexClick: (index) => (event?) => void`: Returns a function that removes the item at `index`.~~
- ~~`onReorderClick: (index, newIndex) => (event?) => void`: Returns a function that swaps the items at `index` with `newIndex`.~~

In addition to this refactor, the conversion of the `ArrayField` template to functional components caused the replacement of the 4 callback-generator functions with 5 memoizable functions.

##### onAddIndexClick replacement

The `onAddIndexClick: (index) => (event?) => void` callback-generator function was replaced with the following memoized callback:

```typescript
/** Callback function that adds a new item below this item */
onAddItem: (event?: any) => void;
```

##### onCopyIndexClick replacement

The `onCopyIndexClick: (index: number) => (event?: any) => void;` callback-generator function was replaced with a simpler, memoized callback:

```typescript
/** Callback function that copies this item below itself */
onCopyItem: (event?: any) => void;
```

##### onDropIndexClick replacement

The `onDropIndexClick: (index) => (event?) => void` callback-generator function was replaced with the following memoized callback:

```typescript
/** Callback function that removes the item from the list */
onRemoveItem: (event?: any) => void;
```

##### onReorderClick replacement

The `onReorderClick: (index, newIndex) => (event?) => void` callback-generator function was replaced with the following 2 memoized callbacks:

```typescript
/** Callback function that moves the item up one spot in the list */
onMoveUpItem: (event?: any) => void;
/** Callback function that moves the item down one spot in the list */
onMoveDownItem: (event?: any) => void;
```

A new `buttonsProps` prop was added of the type `ArrayFieldItemButtonsTemplateProps`

This new type was then used to create a new `ArrayFieldItemButtonsTemplate` in the `Registry.templates`.
See [ArrayFieldItemButtonTemplate](../advanced-customization/custom-templates.md#arrayfielditembuttontemplate)

If you have implemented your own `ArrayFieldItemTemplate` or `ArrayField` then you will have to account for these changes.

#### ArrayFieldTemplate BREAKING CHANGE

In order to support the conversion of `ArrayField` to functional components, the `items` property was changed from an
array of `ArrayFieldItemTemplateProps` information to an array of React elements. These elements are result of the `ArrayField`
actually rendering the `ArrayFieldItemTemplate` directly, rather than deferring it the `ArrayFieldTemplate`.

If you previously provided a custom `ArrayFieldTemplate` to do the full rendering of your arrays, now you will have to
separate the logic of generating the items into your own custom `ArrayFieldItemTemplate`. For example:

```
/* Detailed source-code truncated for AI context efficiency. */
```

```
/* Detailed source-code truncated for AI context efficiency. */
```

> NOTE: the example above could also have implemented an `ArrayFieldItemButtonsTemplate` for the `buttonProps` related code.

##### Potential BREAKING CHANGE

This template was also updated to support the new [Optional Data Controls](#optional-data-controls) feature by adding a new `optionalDataControl` prop to the `ArrayFieldTemplateProps` interface.

If you have your own implementation of `ArrayFieldTemplate` and want to support this new feature, please refer to any of the `ArrayFieldTemplate` implementation for whatever theme you are using and pick up the changes.

#### ArrayFieldTitleTemplate POTENTIAL BREAKING CHANGE

This template was updated to support the new [Optional Data Controls](#optional-data-controls) feature by adding a new `optionalDataControl` prop to the `ArrayFieldTitleProps` interface.

If you have your own implementation of `ArrayFieldTitleTemplate` and want to support this new feature, please refer to the `ArrayFieldTitleTemplate` implementation for `@rjsf/core` or whatever theme you are using and pick up the changes.

#### GridTemplate

A new, theme-dependent template `GridTemplate` was added to support the new layout feature and must be provided if you are building your own `registry.templates` rather than overloading them via the `templates` props.

#### MultiSchemaFieldTemplate

This new template was created to extract styling applied to the `MultiSchemaField` component in the `@rjsf/core` package.

If you have styled your form using the following classNames and you do NOT use the `@rjsf/core` theme, you may need to adjust your styles, as they may have been removed from your theme: `panel`, `panel-default`, `panel-body`, `form-group`.

#### ObjectFieldTemplate POTENTIAL BREAKING CHANGE

This template was updated to support the new [Optional Data Controls](#optional-data-controls) feature by adding a new `optionalDataControl` prop to the `ObjectFieldTemplateProps` interface.

If you have your own implementation of `ObjectFieldTemplate` and want to support this new feature, please refer to the `ObjectFieldTemplate` implementation for whatever theme you are using and pick up the changes.

#### OptionalDataControlsTemplate POTENTIAL BREAKING CHANGE

This new template was created to support the new [Optional Data Controls](#optional-data-controls) feature.

If you are implementing your own theme you may need to add this new template if you anticipate supporting this new feature.

#### TitleFieldTemplate POTENTIAL BREAKING CHANGE

This template was updated to support the new [Optional Data Controls](#optional-data-controls) feature by adding a new `optionalDataControl` prop to the `TitleFieldProps` interface.

If you have your own implementation of `TitleFieldTemplate` and want to support this new feature, please refer to the `TitleFieldTemplate` implementation for whatever theme you are using and pick up the changes.

#### SchemaField - Addition of FallbackField POTENTIAL BREAKING CHANGE

The `SchemaField` was updated to use the new `FallbackField`, which adds opt-in support to replace the `UnsupportedField` with an interactive UI instead of an error message.
If you have your own implementation of `SchemaField` and want to support this new feature, please refer to the `SchemaField` implementation in `@rjsf/core` and pick up the changes.

The `UnsupportedField` component is unaffected by these changes, and is still used by the new `FallbackField`.

#### SchemaUtilsType

Five new functions were added to this type, so if you have your own implementation of this type, you will need to add them to yours.
The following new functions match the 5 new validator-based utility API functions mentioned below:

- `findFieldInSchema(path: string | string[], schema: S, formData?: T): FoundFieldType<S>`
- `findSelectedOptionInXxxOf(schema: S, fallbackField: string, xxx: 'anyOf' | `oneOf`, formData?: T): S | undefined;`
- `getFromSchema(schema: S, path: string | string[], defaultValue: T): T;`
- `getFromSchema(schema: S, path: string | string[], defaultValue: S): S;`
- `getFromSchema(schema: S, path: string | string[], defaultValue: T | S): S | T;`

In addition the `toIdSchema()` function was removed on this type in concert with the `toIdSchema()` function removal, so update your implementation to remove this as well.

### Removed deprecations

The following deprecations were removed from the code base in v6

#### FormProps.acceptcharset

The `acceptcharset` prop on `Form` was removed. Use the `acceptCharset` prop instead. I.e.:

```tsx
<Form acceptCharset='ISO-8859-1' />
```

#### getMatchingOption()

The `getMatchingOption()` function in `@rjsf/utils` was removed. Use the `getFirstMatchingOption()` function instead.
I.e.:

```ts
import { getFirstMatchingOption, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  // your schema goes here
};

const formData = {
  /* your form data goes here */
};
const options: RJSFSchema[] = [
  /* your options extracted from the schema go here */
];

const option = getFirstMatchingOption(validator, formData, options, schema);
```

#### SchemaUtilsType.getMatchingOption()

The `getMatchingOption()` function in the `SchemaUtilsType` was removed. Use the `getFirstMatchingOption()` funciton on
the type instead. I.e.:

```ts
import { createSchemaUtils, RJSFSchema } from '@rjsf/utils';
import validator from '@rjsf/validator-ajv8';

const schema: RJSFSchema = {
  // your schema goes here
};

const formData = {
  /* your form data goes here */
};
const options: RJSFSchema[] = [
  /* your options extracted from the schema go here */
];
const schemaUtils = createSchemaUtils(validator, schema);

const option = schemaUtils.getFirstMatchingOption(formData, options);
```

#### mergeValidationData()

The `mergeValidationData()` function from `@rjsf/utils` was removed. Use the `validationDataMerge()` function instead.
I.e.:

```ts
import { validationDataMerge, ValidationData, ErrorSchema } from '@rjsf/utils';

const validationData: ValidationData = {
  errors: [
    /* Your validation errors go here */
  ],
  errorSchema: {
    /* Your error schema goes here */
  },
};

const additionalErrorSchema: ErrorSchema = {
  /* Your additional error schema goes here */
};

const merged = validationDataMerge(validationData, additionalErrorSchema);
```

#### SchemaUtilsType.mergeValidationData()

The `mergeValidationData()` function in the `SchemaUtilsType` was removed. Use the standalone `validationDataMerge()`
function instead. I.e.:

```ts
import { toErrorList } from '@rjsf/utils';

const validationData: ValidationData = {
  errors: [
    /* Your validation errors go here */
  ],
  errorSchema: {
    /* Your error schema goes here */
  },
};

const additionalErrorSchema: ErrorSchema = {
  /* Your additional error schema goes here */
};

const merged = validationDataMerge(validationData, additionalErrorSchema);
```

#### ValidatorType.toErrorList()

The `toErrorList()` function on the `ValidatorType` interface was removed. Use the standalone `toErrorList()` function
from `@rjsf/utils` instead. I.e.:

```ts
import { validationDataMerge, ErrorSchema, RJSFValidationError, toErrorList } from '@rjsf/utils';

const errorSchema: ErrorSchema = {
  /* Your error schema goes here */
};

const validationErrors: RJSFValidationError[] = toErrorList(errorSchema);
```

#### RJSF_ADDITONAL_PROPERTIES_FLAG

The constant `RJSF_ADDITONAL_PROPERTIES_FLAG` was removed from `@rjsf/utils`. Use the `RJSF_ADDITIONAL_PROPERTIES_FLAG`
constant instead. I.e.:

```ts
import { RJSF_ADDITIONAL_PROPERTIES_FLAG } from '@rjsf/utils';
```

#### UiSchema.classNames

The `classNames` notation on `UiSchema` was removed. Use the `ui:classNames` notation instead. I.e.:

```json
{
  "someField": {
    "ui:classNames": "someCustomClass"
  }
}
```

#### schema.enumNames

The custom `enumNames` property support on a JSON Schema that RJSF invented has been removed. Please use the `UiSchema`
replacement, `ui:enumNames` instead. I.e.:

```ts
import { UiSchema, RJSFSchema } from '@rjsf/utils';

const schema: RJSFSchema = {
  type: 'object',
  properties: {
    attendance: {
      title: 'How did you attend the event?',
      enum: ['person', 'phone', 'video'],
    },
    rating: {
      title: 'How would you rate this event?',
      enum: ['0', '1', '2', '3', '4'],
    },
  },
};

const uiSchema: UiSchema = {
  attendance: {
    'ui:enumNames': ['I joined in person', 'I called in using the phone number', 'I joined using the video link'],
  },
  rating: {
    'ui:enumNames': ["I did't like it", 'It was meh', 'It was ok', 'I liked it', 'I loved it'],
  },
};
```

Use the `ui:enumNames` in the `UiSchema` instead.

### Other BREAKING CHANGES

#### Primitive field handling in oneOf/anyOf schemas

A bug fix was implemented that changes how primitive fields (boolean, string, number, etc.) are handled when switching between oneOf/anyOf schema options with `mergeDefaultsIntoFormData: "useDefaultIfFormDataUndefined"`.

**Previous (buggy) behavior**: Undefined primitive fields were incorrectly set to empty objects `{}` when switching between schema variants.

**New (correct) behavior**: Undefined primitive fields now remain `undefined` or receive proper default values according to their type when switching between schema variants.

This change fixes [#4709](https://github.com/rjsf-team/react-jsonschema-form/issues/4709) and was implemented in [#4710](https://github.com/rjsf-team/react-jsonschema-form/pull/4710).

**Impact**: If your application was incorrectly relying on undefined primitive fields becoming `{}` objects, you may need to update your form validation or data processing logic to handle proper primitive values or `undefined` instead.

#### Optional array defaulting (POTENTIAL)

A bug fix was implemented that changes how optional arrays are initialized during the `formData` defaulting phase.

**Previous (buggy) behavior**: Optional arrays were initialized to `[]`.

**New (correct) behavior**: Optional arrays are no longer initialized.

**Impact**: If your application was incorrectly relying on optional arrays being initialized this way, you may need to update it to handle the corrected behavior.

#### SchemaField removed Bootstrap 3 classes

In fixing [#2280](https://github.com/rjsf-team/react-jsonschema-form/issues/2280), the following `Bootstrap 3` classes
(`form-group`, `has-error` and `has-danger` error classes) were removed from the `classNames` prop passed down to the
`FieldTemplate`. They were instead moved into the `core` theme's `WrapIfAdditionalTemplate` to ensure that theme was
unchanged.

Additionally, the Bootstrap 3 classes `panel`, `panel-default`, `panel-body`, and `form-group` were removed from the
`MultiSchemaField` component in the `@rjsf/core` package, and moved into the `core` theme's `MultiSchemaFieldTemplate`
to ensure that the theme was unchanged.

As a result, the themes (other than `core`) will no longer render these classes.

If you use a non-`core` theme and were relying on them for in your application's styling or behavior (via css overrides
perhaps), then you can still use the non-`Bootstrap 3` RJSF marker class (see below) or your specific theme's error classes.

#### Prefixed RJSF template and field marker classes

Many of the `core` RJSF templates and field implementations that are shared across all themes were updated to add the
`rjsf-` prefix to the marker classes that are being added to the rendered HTML. The following table highlights the old
and new marker classes. If you were relying on any of these classes, simply do a rename:

| old marker class               | new marker class                    |
| ------------------------------ | ----------------------------------- |
| `field`                        | `rjsf-field`                        |
| `field-<schema.type>`          | `rjsf-field-<schema.type>`          |
| `field-array`                  | `rjsf-field-array`                  |
| `field-array-of-<schema.type>` | `rjsf-field-array-of-<schema.type>` |
| `field-array-fixed-items`      | `rjsf-field-array-fixed-items`      |
| `field-error`                  | `rjsf-field-error`                  |
| `field-hidden`                 | `rjsf-field-hidden`                 |
| `array-item`                   | `rjsf-array-item`                   |
| `config-error`                 | `rjsf-config-error`                 |
| `array-item-add`               | `rjsf-array-item-add`               |
| `array-item-copy`              | `rjsf-array-item-copy`              |
| `array-item-move-down`         | `rjsf-array-item-move-down`         |
| `array-item-move-up`           | `rjsf-array-item-move-up`           |
| `array-item-remove`            | `rjsf-array-item-remove`            |
| `object-property-expand`       | `rjsf-object-property-expand`       |
| `object-property-remove`       | `rjsf-object-property-remove`       |

#### optionsList

The generics ordering on the `optionsList()` function was changed from `<S, T, F>` to `<T, S, F>` to be consistent with the rest of the APIs.

## New Features

### New types

The following new types were added to `@rjsf/utils`:

- `ArrayFieldItemTemplateProps`: The properties of each element in the ArrayFieldTemplateProps.items array.
- `ContainerFieldTemplateProps`: The common properties of the two container templates: `ArrayFieldTemplateProps` and `ObjectFieldTemplateProps`
- `FallbackFieldProps`: The properties passed to the new `FallbackField` component
- `FallbackFieldTemplate`: The properties passed to the new `FallbackFieldTemplate` component
- `FieldPathList` - The list of path elements that represents where in the schema a field is located
- `FieldPathId` - Type describing an id and path used for a field
- `FoundFieldType`: The interface for the return value of the `findFieldInSchema` function
- `GlobalFormOptions`: The set of options from the `Form` that will be available on the `Registry` for use in everywhere the `registry` is available.
- `GridTemplateProps`: The properties that are passed to a `GridTemplate`
- `MultiSchemaFieldTemplateProps`: The properties that are passed to a `MultiSchemaFieldTemplate`
- `OptionalDataControlsTemplateProps`: The properties that are passed to a OptionalDataControlsTemplate implementation
- `TestIdShape`: The interface for the test ID proxy objects that are returned by the `getTestId` utility function

### New non-validator utility functions

Many new or formerly internally private utility functions are available in `@rjsf/utils`:

- `buttonId(id: FieldPathId | string, btn: 'add' | 'copy' | 'moveDown' | 'moveUp' | 'remove')`: Generates consistent ids for RJSF buttons
- `getTestIds(): TestIdShape`: Returns an object of test IDs that can only be used in test mode, helpful for writing unit tests for React components
- `hashObject(object: unknown): string`: Stringifies an `object` and returns the hash of the resulting string
- `hashString(string: string): string`: Hashes a string into hex format
- `isFormDataAvailable<T = any>(formData?: T)<T = any>(formData?: T): boolean`: Determines whether the given `formData` represents valid form data, such as a primitive type, an array, or a non-empty object
- `isRootSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(registry: Registry<T, S, F>, schemaToCompare: S): boolean`: Helper to check whether a JSON schema object is the root schema
- `lookupFromFormContext<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(regOrFc: Registry<T, S, F> | Registry<T, S, F>['formContext'], toLookup: string, fallback?: unknown)`: Given a React JSON Schema Form registry or formContext object, return the value associated with `toLookup`
- `optionalControlsId(id: FieldPathId | string, element: 'Add' | 'Msg' | 'Remove')`: Return a consistent `id` for the optional data controls `element`
- `shouldRenderOptionalField<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(registry: Registry<T, S, F>, schema: S, required: boolean, uiSchema?: UiSchema<T, S, F>): boolean`: Determines if this field should be rendered with the Optional Data Controls UI
- `sortedJSONStringify(object: unknown): string`: Stringifies an `object`, sorts object fields in consistent order before stringifying it
- `toFieldPathId(fieldPath: string | number, globalFormOptions: GlobalFormOptions, parentPath?: FieldPathId | FieldPathList, isMultiValue?: boolean)`: Constructs the `FieldPathId` for `fieldPath` and the optional `parentPath`, using `globalFormOptions`
- `useAltDateWidgetProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(props: WidgetProps<T, S, F>): UseAltDateWidgetResult`: which encapsulates the logic needed to render an `AltDateWidget` with optional `time` elements
- `useDeepCompareMemo<T = unknown>(newValue: T): T`: Hook that stores and returns a `T` value. If `newValue` is the same as the stored one, then the stored one is returned, otherwise `newValue` is stored and returned
- `useFileWidgetProps(value: string | string[] | undefined | null, onChange: (value?: string | null | (string | null)[]) => void, multiple?: boolean): UseFileWidgetPropsResult`: Hook which encapsulates the logic needed to read and convert a `value` of `File` or `File[]` into the props needed by a `FileWidget` implementation.

### New validator-based utility functions

Three new validator-based utility functions are available in `@rjsf/utils`:

- `findFieldInSchema<T = undefined, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(validator: ValidatorType<T, S, F>, rootSchema: S, path: string | string[], schema: S, formData?: T, experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>): FoundFieldType<S>`: Finds the field specified by the `path` within the root or recursed `schema`
- `findSelectedOptionInXxxOf<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(validator: ValidatorType<T, S, F>, rootSchema: S, schema: S, fallbackField: string,xxx: 'anyOf' | 'oneOf', formData?: T, experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>): S | undefined`: Finds the option that matches the selector field in the `schema` or undefined if nothing is selected
- `getFromSchema<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any>(validator: ValidatorType<T, S, F>, rootSchema: S, schema: S, path: string | string[], defaultValue: T | S, experimental_customMergeAllOf?: Experimental_CustomMergeAllOf<S>): T | S`: Reads the value at `path` within a schema, additionally retrieving `$ref`s as needed to resolve schemas

### Changes to existing utility functions

- `getDefaultFormState()`: Added an optional `initialDefaultsGenerated` boolean flag that indicates whether or not initial defaults have been generated
- `retrieveSchema()`: Added an optional `resolveAnyOfOrOneOfRefs` boolean flag that causes the internal `resolveAllSchemas()` to resolve `$ref`s inside of the options of `anyOf`/`oneOf` schemas
  - This new optional flag was added to the `SchemaUtilsType` interface's version of `retrieveSchema()` as well.
- `validationDataMerge()`: Added optional `preventDuplicates` boolean flag that causes the `mergeObjects()` call to receive `preventDuplicates` instead of `true`

### initialFormData prop added to Form

A new `initialFormData` prop was added to `Form` to support providing initial values for an **"uncontrolled"** React component.
As a result, a small change was made so that `formData` now causes the `Form` to behave as a **"controlled"** React component.

The programmatic `reset()` will ensure that an **"uncontrolled"** form is reset back to the `initialFormData` values when triggered.

### setFieldValue() added to Form

A new programmatic function, `setFieldValue(fieldPath: string | FieldPathList, newValue?: T): void` was added to the `Form`.
It allows a user to set a value for the provided `fieldPath`, which must be either a dotted path to the field OR a `FieldPathList`.
To set the root element, used either `''` or `[]` for the path. Passing undefined will clear the value in the field.

### liveValidate and liveOmit performance improvement

Because `liveValidate` and `liveOmit` can have serious performance impacts in the `Form`, those flags were updated to add the following new options:

- 'onChange' - Live validate and live omit will happen as part of the `onChange` processing (the same as setting the flag to `true`)
- 'onBlur' - Live validate and live omit will happen as part of the `onBlur` processing, saving the computations until the user is done inputting data. If any changes to the state occur due to this processing, the `onChange()` event will be sent back to the client with the new data.

> NOTE: Due to this new feature, the old `boolean` options on those two flag has been deprecated. In a future major release, you will only be able to pass `onChange`, `onBlur` to activate the feature or `undefined` to disable it

### Optional Data Controls

RJSF 6.x introduces a new feature that allows developers to provide a condensed UI for users who don't care to enter an optional list of array items or set of optional object fields.

See the documentation for [enableOptionalDataFieldForType](../api-reference/uiSchema.md#enableoptionaldatafieldfortype) for more information.

### Dynamic UI Schema for Array Items

RJSF 6.x introduces a new feature that allows dynamic UI schema generation for array items.
The `items` property in a `uiSchema` can now accept a function that returns a UI schema based on the array item's data, index, and form context.

```typescript
const uiSchema: UiSchema = {
  myArrayField: {
    items: (itemData, index, formContext) => {
      // Return different UI schemas based on item data
      if (itemData?.type === 'special') {
        return { 'ui:widget': 'textarea' };
      }
      return { 'ui:widget': 'text' };
    },
  },
};
```

This feature is fully backward compatible - existing forms using object-based `uiSchema.items` will continue to work without changes.
See the [Dynamic UI Schema Examples](../api-reference/dynamic-ui-schema-examples.md) documentation for comprehensive examples and usage patterns.

### Custom field `name` generation

RJSF 6.x adds support for customizing how HTML `name` attributes are generated for form fields via the new [`nameGenerator`](../api-reference/form-props.md#namegenerator) prop. This enables proper form data submission to backend frameworks that expect specific naming conventions like bracket notation (`root[tasks][0][title]`) for PHP/Rails or dot notation (`root.tasks.0.title`) for other frameworks.

The default behavior is unchanged if the prop is not provided.

### Opt-in Fallback UI for unsupported types

RJSF 6.x introduces a new `FallbackField` component that provides a user-friendly UI for unsupported or unrecognized schema types. This new functionality displays a selection box used to choose a JSON primitive type, and a field for the formData that matches the selected type. To use this new feature, which takes the place of the existing `UnsupportedField` component, set the new `useFallbackUiForUnsupportedType` prop to `true` on the `Form` component.

---

--- METRICS ---
- Files Extracted: 71
- Estimated Token Budget: ~125652 tokens
- Canonical Reference: https://codewiki.google/github.com/rjsf-team/react-jsonschema-form
