A comprehensive WordPress-themed UI component library for react-jsonschema-form. This theme replaces Bootstrap components with WordPress components from @wordpress/components, providing a native WordPress admin experience for JSON Schema forms.
- β Complete widget coverage - All standard react-jsonschema-form widgets implemented
- β
WordPress styling - Uses
@wordpress/componentsfor consistent WordPress admin UI - β Full template support - All templates including arrays, objects, and error handling
- β TypeScript support - Fully typed components
- β Comprehensive tests - 100+ unit tests covering all components
- β Kitchen sink demo - Interactive demo showcasing all features
npm install @osahan/wordpress-uiThis package requires the following peer dependencies:
npm install react react-dom @wordpress/components @rjsf/corereact: ^16.8.0 || ^17.0.0 || ^18.0.0react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0@wordpress/components: ^19.0.0 || ^20.0.0@rjsf/core: ^6.1.2
The simplest way to use the WordPress UI theme is to import the default Form component:
import validator from '@rjsf/validator-ajv8';
import Form from '@osahan/wordpress-ui';
function MyForm() {
const schema = {
type: 'object',
required: ['name', 'email'],
properties: {
name: {
type: 'string',
title: 'Name',
},
email: {
type: 'string',
format: 'email',
title: 'Email Address',
},
},
};
return (
<Form
schema={schema}
validator={validator}
onSubmit={({ formData }) => console.log(formData)}
/>
);
}You can also use the generateForm() function to create a Form component (useful for TypeScript generics):
import validator from '@rjsf/validator-ajv8';
import { generateForm } from '@osahan/wordpress-ui';
const Form = generateForm();
function MyForm() {
return (
<Form
schema={schema}
validator={validator}
onSubmit={({ formData }) => console.log(formData)}
/>
);
}For more control, you can use the theme object with withTheme HOC:
import { withTheme } from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';
import { wordpressUITheme } from '@osahan/wordpress-ui';
const ThemedForm = withTheme(wordpressUITheme);
function MyForm() {
return (
<ThemedForm
schema={schema}
validator={validator}
onSubmit={({ formData }) => console.log(formData)}
/>
);
}Or use generateTheme():
import { withTheme } from '@rjsf/core';
import validator from '@rjsf/validator-ajv8';
import { generateTheme } from '@osahan/wordpress-ui';
const ThemedForm = withTheme(generateTheme());
function MyForm() {
return (
<ThemedForm
schema={schema}
validator={validator}
onSubmit={({ formData }) => console.log(formData)}
/>
);
}This package follows the same pattern as @rjsf/react-bootstrap:
- Default export:
Form- Pre-configured Form component with WordPress UI theme generateForm(): Function that returns a Form component (useful for TypeScript generics)generateTheme(): Function that returns the theme objectwordpressUITheme: The theme object (alias forgenerateTheme())
// Default export (most common)
import Form from '@osahan/wordpress-ui';
// Named exports
import { generateForm, generateTheme, wordpressUITheme } from '@osahan/wordpress-ui';The theme provides 17 widgets, all styled with WordPress components:
BaseInput/TextWidget- Standard text input usingTextControlPasswordWidget- Password input usingTextControlwith type="password"EmailWidget- Email input usingTextControlwith type="email"URLWidget- URL input usingTextControlwith type="url"TextareaWidget- Multi-line text input usingTextareaControl
NumberWidget- Number input usingTextControlwith type="number"UpDownWidget- Number input with step controlsRangeWidget- Range slider usingRangeControl
SelectWidget- Dropdown selection usingSelectControlRadioWidget- Radio button group usingRadioControlCheckboxWidget- Single checkbox usingCheckboxControlCheckboxesWidget- Multiple checkboxes for array inputs
DateWidget- Date picker usingTextControlwith type="date"DateTimeWidget- Date and time picker usingTextControlwith type="datetime-local"TimeWidget- Time picker usingTextControlwith type="time"
HiddenWidget- Hidden input field
The theme includes 13 templates for comprehensive form rendering:
FieldTemplate- Wraps individual fields with labels, help text, and errorsFieldErrorTemplate- Displays field-level validation errorsFieldHelpTemplate- Renders help text for fieldsBaseInputTemplate- Base template for text inputs
ObjectFieldTemplate- Renders object/group fields with collapsible panelsArrayFieldTemplate- Handles array fields with add/remove functionalityArrayFieldItemTemplate- Template for individual array itemsGridTemplate- Grid layout support for form fieldsWrapIfAdditionalTemplate- Handles additional properties in objects
ErrorListTemplate- Displays form-level validation errors using WordPressNoticeMultiSchemaFieldTemplate- Supports multiple schema selectionOptionalDataControlsTemplate- Controls for optional additional data
AddButton- Button for adding array itemsSubmitButton- Form submission buttonCopyButton- Copy array item buttonMoveUpButton- Move item up buttonMoveDownButton- Move item down buttonRemoveButton- Remove item button
TitleField- Renders form/section titlesDescriptionField- Renders form/section descriptions
import validator from '@rjsf/validator-ajv8';
import Form from '@osahan/wordpress-ui';
const schema = {
type: 'object',
properties: {
name: { type: 'string', title: 'Name' },
email: { type: 'string', format: 'email', title: 'Email' },
},
};
<Form schema={schema} validator={validator} />import validator from '@rjsf/validator-ajv8';
import Form from '@osahan/wordpress-ui';
const schema = {
type: 'object',
properties: {
bio: { type: 'string', title: 'Biography' },
role: {
type: 'string',
enum: ['admin', 'editor'],
enumNames: ['Administrator', 'Editor'],
},
},
};
const uiSchema = {
bio: {
'ui:widget': 'textarea',
'ui:options': { rows: 5 },
},
role: {
'ui:widget': 'radio',
},
};
<Form schema={schema} uiSchema={uiSchema} validator={validator} />import validator from '@rjsf/validator-ajv8';
import Form from '@osahan/wordpress-ui';
const schema = {
type: 'object',
properties: {
tags: {
type: 'array',
title: 'Tags',
items: { type: 'string' },
},
},
};
const uiSchema = {
tags: {
'ui:options': {
addButtonText: 'Add Tag',
},
},
};
<Form schema={schema} uiSchema={uiSchema} validator={validator} />import validator from '@rjsf/validator-ajv8';
import Form from '@osahan/wordpress-ui';
const schema = {
type: 'object',
properties: {
user: {
type: 'object',
title: 'User Information',
properties: {
name: { type: 'string', title: 'Name' },
email: { type: 'string', format: 'email', title: 'Email' },
},
},
},
};
const uiSchema = {
user: {
'ui:options': {
collapsible: true,
defaultOpen: true,
},
},
};
<Form schema={schema} uiSchema={uiSchema} validator={validator} />When using this theme with controlled components (passing formData prop), make sure to handle onChange correctly:
import { useState } from 'react';
import Form from '@osahan/wordpress-ui';
import validator from '@rjsf/validator-ajv8';
function MyForm() {
const [formData, setFormData] = useState({});
const handleChange = ({ formData }) => {
// Only update if data actually changed to prevent unnecessary re-renders
setFormData(formData);
};
return (
<Form
schema={schema}
formData={formData}
onChange={handleChange}
validator={validator}
/>
);
}Important: This package follows the same pattern as @rjsf/react-bootstrap - it's a simple theme wrapper around RJSF's Form component. If you're experiencing infinite loops, check:
- Are you updating
formDatainonChangewithout checking if it actually changed? - Are you using deep equality checks before updating state?
- Is your
onChangehandler causing unnecessary re-renders?
WordPress component styles are automatically imported when you use the theme. The styles from @wordpress/components ensure all widgets match the WordPress admin interface.
If you need to import styles separately (e.g., for CSS-in-JS setups), you can reference the style field in package.json:
import '@wordpress/components/build-style/style.css';A comprehensive demo showcasing all widgets and templates is available:
π Live Demo: View on GitHub Pages
The demo is also available locally in the demo directory.
From the project root:
npm run demoOr manually:
cd demo
npm install --legacy-peer-deps
npm run devThe demo will open at http://localhost:3000 and includes:
- All 17 widgets
- All templates
- Form validation examples
- Real-time form data display
- Array and object field examples
# Run all tests
npm test
# Run tests in watch mode
npm run test:watch
# Run tests with coverage
npm run test:coveragesrc/
βββ widgets/ # All widget components
βββ templates/ # All template components
β βββ buttons/ # Button templates
βββ fields/ # Field components
βββ index.ts # Main theme export
The package exports both the theme object and a pre-configured Form component:
import Form, { wordpressUITheme } from '@osahan/wordpress-ui';
import { withTheme, type ThemeProps } from '@rjsf/core';
// Use the pre-configured Form component (recommended)
<Form schema={schema} validator={validator} />
// Or use withTheme HOC for advanced usage
const ThemedForm = withTheme(wordpressUITheme);
<ThemedForm schema={schema} validator={validator} />
// Theme structure
const theme: ThemeProps = {
widgets: {
BaseInput,
TextWidget,
InputWidget,
SelectWidget,
CheckboxWidget,
TextareaWidget,
RadioWidget,
CheckboxesWidget,
NumberWidget,
PasswordWidget,
EmailWidget,
URLWidget,
DateWidget,
DateTimeWidget,
TimeWidget,
UpDownWidget,
RangeWidget,
HiddenWidget,
},
templates: {
ArrayFieldItemTemplate,
ArrayFieldTemplate,
BaseInputTemplate,
ButtonTemplates: {
AddButton,
CopyButton,
MoveDownButton,
MoveUpButton,
RemoveButton,
SubmitButton,
},
DescriptionFieldTemplate,
ErrorListTemplate,
FieldErrorTemplate,
FieldHelpTemplate,
FieldTemplate,
GridTemplate,
MultiSchemaFieldTemplate,
ObjectFieldTemplate,
OptionalDataControlsTemplate,
TitleFieldTemplate,
WrapIfAdditionalTemplate,
},
fields: {
TitleField,
DescriptionField,
},
};- react-jsonschema-form: ^6.1.2
- React: ^16.8.0 || ^17.0.0 || ^18.0.0
- @wordpress/components: ^19.0.0 || ^20.0.0
Contributions are welcome! Please ensure all tests pass before submitting a pull request.
MIT
- react-jsonschema-form - The core form library
- @wordpress/components - WordPress component library
- @rjsf/react-bootstrap - Bootstrap theme (inspiration)