Skip to content

osahan/wordpress-ui

Repository files navigation

@osahan/wordpress-ui

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.

Features

  • βœ… Complete widget coverage - All standard react-jsonschema-form widgets implemented
  • βœ… WordPress styling - Uses @wordpress/components for 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

Installation

npm install @osahan/wordpress-ui

Peer Dependencies

This package requires the following peer dependencies:

npm install react react-dom @wordpress/components @rjsf/core
  • react: ^16.8.0 || ^17.0.0 || ^18.0.0
  • react-dom: ^16.8.0 || ^17.0.0 || ^18.0.0
  • @wordpress/components: ^19.0.0 || ^20.0.0
  • @rjsf/core: ^6.1.2

Quick Start

Basic Usage (Default Export)

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)}
    />
  );
}

Using generateForm() Function

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)}
    />
  );
}

Advanced: Using withTheme directly

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)}
    />
  );
}

API Exports

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 object
  • wordpressUITheme: The theme object (alias for generateTheme())
// Default export (most common)
import Form from '@osahan/wordpress-ui';

// Named exports
import { generateForm, generateTheme, wordpressUITheme } from '@osahan/wordpress-ui';

Available Widgets

The theme provides 17 widgets, all styled with WordPress components:

Text Inputs

  • BaseInput / TextWidget - Standard text input using TextControl
  • PasswordWidget - Password input using TextControl with type="password"
  • EmailWidget - Email input using TextControl with type="email"
  • URLWidget - URL input using TextControl with type="url"
  • TextareaWidget - Multi-line text input using TextareaControl

Number Inputs

  • NumberWidget - Number input using TextControl with type="number"
  • UpDownWidget - Number input with step controls
  • RangeWidget - Range slider using RangeControl

Selection Widgets

  • SelectWidget - Dropdown selection using SelectControl
  • RadioWidget - Radio button group using RadioControl
  • CheckboxWidget - Single checkbox using CheckboxControl
  • CheckboxesWidget - Multiple checkboxes for array inputs

Date/Time Widgets

  • DateWidget - Date picker using TextControl with type="date"
  • DateTimeWidget - Date and time picker using TextControl with type="datetime-local"
  • TimeWidget - Time picker using TextControl with type="time"

Special Widgets

  • HiddenWidget - Hidden input field

Available Templates

The theme includes 13 templates for comprehensive form rendering:

Field Templates

  • FieldTemplate - Wraps individual fields with labels, help text, and errors
  • FieldErrorTemplate - Displays field-level validation errors
  • FieldHelpTemplate - Renders help text for fields
  • BaseInputTemplate - Base template for text inputs

Structure Templates

  • ObjectFieldTemplate - Renders object/group fields with collapsible panels
  • ArrayFieldTemplate - Handles array fields with add/remove functionality
  • ArrayFieldItemTemplate - Template for individual array items
  • GridTemplate - Grid layout support for form fields
  • WrapIfAdditionalTemplate - Handles additional properties in objects

Special Templates

  • ErrorListTemplate - Displays form-level validation errors using WordPress Notice
  • MultiSchemaFieldTemplate - Supports multiple schema selection
  • OptionalDataControlsTemplate - Controls for optional additional data

Button Templates

  • AddButton - Button for adding array items
  • SubmitButton - Form submission button
  • CopyButton - Copy array item button
  • MoveUpButton - Move item up button
  • MoveDownButton - Move item down button
  • RemoveButton - Remove item button

Available Fields

  • TitleField - Renders form/section titles
  • DescriptionField - Renders form/section descriptions

Usage Examples

Basic Form

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} />

Using Widgets

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} />

Array Fields

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} />

Nested Objects

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} />

Controlled Components

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:

  1. Are you updating formData in onChange without checking if it actually changed?
  2. Are you using deep equality checks before updating state?
  3. Is your onChange handler causing unnecessary re-renders?

Styling

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';

Demo / Kitchen Sink

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.

Running the Demo

From the project root:

npm run demo

Or manually:

cd demo
npm install --legacy-peer-deps
npm run dev

The 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

Development

Running Tests

# Run all tests
npm test

# Run tests in watch mode
npm run test:watch

# Run tests with coverage
npm run test:coverage

Project Structure

src/
β”œβ”€β”€ widgets/          # All widget components
β”œβ”€β”€ templates/        # All template components
β”‚   └── buttons/      # Button templates
β”œβ”€β”€ fields/           # Field components
└── index.ts          # Main theme export

API Reference

Theme Object and Themed Form

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,
  },
};

Compatibility

  • react-jsonschema-form: ^6.1.2
  • React: ^16.8.0 || ^17.0.0 || ^18.0.0
  • @wordpress/components: ^19.0.0 || ^20.0.0

Contributing

Contributions are welcome! Please ensure all tests pass before submitting a pull request.

License

MIT

Related Projects

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published