Skip to content

Commit

Permalink
fix: Improved the widget/field customization docs (#4302)
Browse files Browse the repository at this point in the history
* fix Improved the widget/field customization docs
Updated the widget and field customization docs to add examples of wrapping a widget/field to adjust props

* Apply suggestions from code review

- Responded to reviewer feedback

Co-authored-by: Nick Grosenbacher <nickgrosenbacher@gmail.com>

---------

Co-authored-by: Nick Grosenbacher <nickgrosenbacher@gmail.com>
  • Loading branch information
heath-freenome and nickgros authored Sep 14, 2024
1 parent f0eb734 commit 9d1ff6d
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 0 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,12 @@ should change the heading of the (upcoming) version to include a major version b
-->

# 5.21.2

## Dev / docs / playground

- Updated the `custom-widgets-fields.md` to add examples of wrapping a widget/field

# 5.21.1

## @rjsf/utils
Expand Down
62 changes: 62 additions & 0 deletions packages/docs/docs/advanced-customization/custom-widgets-fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -279,6 +279,34 @@ render(<Form schema={schema} uiSchema={uiSchema} validator={validator} />, docum

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.
Expand Down Expand Up @@ -475,3 +503,37 @@ const schema: RJSFSchema = {

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, es?: ErrorSchema<T>, id?: string) => {
let data = newFormData;
let error = es;
if (checkBadData(newFormData)) {
// Format the `error` and fix the `data` here
}
onChange(data, error, id);
},
[onChange]
);
return <ObjectField {...props} onChange={onChangeHandler} />;
}
```

0 comments on commit 9d1ff6d

Please sign in to comment.