CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-rjsf--core

A React component that automatically generates interactive web forms from JSON Schema definitions.

Pending
Overview
Eval results
Files

template-components.mddocs/

Template Components

Template components control how form elements are displayed and styled. They provide the layout structure, styling, and presentation logic for fields, errors, arrays, buttons, and other form elements.

Capabilities

Template Component Types

Built-in template components that control form layout and presentation.

interface TemplatesType<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Template for array field descriptions */
  ArrayFieldDescriptionTemplate: ComponentType<ArrayFieldDescriptionProps<T, S, F>>;
  /** Template for individual array items with controls */
  ArrayFieldItemTemplate: ComponentType<ArrayFieldTemplateItemType<T, S, F>>;
  /** Template for entire array fields with add/remove controls */
  ArrayFieldTemplate: ComponentType<ArrayFieldTemplateProps<T, S, F>>;
  /** Template for array field titles and headers */
  ArrayFieldTitleTemplate: ComponentType<ArrayFieldTitleProps<T, S, F>>;
  /** Base template for input widgets with common styling */
  BaseInputTemplate: ComponentType<BaseInputTemplateProps<T, S, F>>;
  /** Template for field descriptions and help text */
  DescriptionFieldTemplate: ComponentType<DescriptionFieldProps<T, S, F>>;
  /** Template for error list display at form level */
  ErrorListTemplate: ComponentType<ErrorListProps<T, S, F>>;
  /** Template for individual form fields with labels and errors */
  FieldTemplate: ComponentType<FieldTemplateProps<T, S, F>>;
  /** Template for field-specific error messages */
  FieldErrorTemplate: ComponentType<FieldErrorProps<T, S, F>>;
  /** Template for field help text display */
  FieldHelpTemplate: ComponentType<FieldHelpProps<T, S, F>>;
  /** Template for object fields with property layout */
  ObjectFieldTemplate: ComponentType<ObjectFieldTemplateProps<T, S, F>>;
  /** Template for field titles and labels */
  TitleFieldTemplate: ComponentType<TitleFieldProps<T, S, F>>;
  /** Template for unsupported field types fallback */
  UnsupportedFieldTemplate: ComponentType<UnsupportedFieldProps<T, S, F>>;
  /** Template for additional properties wrapper */
  WrapIfAdditionalTemplate: ComponentType<WrapIfAdditionalTemplateProps<T, S, F>>;
  /** Collection of button templates for form actions */
  ButtonTemplates: {
    /** Form submit button */
    SubmitButton: ComponentType<SubmitButtonProps<T, S, F>>;
    /** Add array item button */
    AddButton: ComponentType<IconButtonProps<T, S, F>>;
    /** Copy array item button */
    CopyButton: ComponentType<IconButtonProps<T, S, F>>;
    /** Move array item down button */
    MoveDownButton: ComponentType<IconButtonProps<T, S, F>>;
    /** Move array item up button */
    MoveUpButton: ComponentType<IconButtonProps<T, S, F>>;
    /** Remove array item button */
    RemoveButton: ComponentType<IconButtonProps<T, S, F>>;
  };
}

Field Layout Templates

FieldTemplate

Main template for individual form fields, controls layout of labels, inputs, errors, and help text.

/**
 * Main template for individual form fields
 * Handles label, input, error, and help text layout
 */
interface FieldTemplateProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Field ID for accessibility */
  id: string;
  /** CSS class names */
  classNames: string;
  /** Field label text */
  label?: string;
  /** Whether to display the label */
  displayLabel: boolean;
  /** Field description text */
  description?: React.ReactNode;
  /** Raw description from schema */
  rawDescription?: string;
  /** Field help text */
  help?: React.ReactNode;
  /** Raw help text */
  rawHelp?: string;
  /** Field error messages */
  errors?: React.ReactNode;
  /** Raw error messages */
  rawErrors?: string[];
  /** Whether field is required */
  required: boolean;
  /** Whether field is hidden */
  hidden: boolean;
  /** Whether field is readonly */
  readonly: boolean;
  /** Whether field is disabled */
  disabled: boolean;
  /** Form registry */
  registry: Registry<T, S, F>;
  /** Form context */
  formContext: F;
  /** Field children (widget) */
  children: React.ReactNode;
  /** JSON schema */
  schema: S;
  /** UI schema */
  uiSchema: UiSchema<T, S, F>;
  /** Form data */
  formData: T;
}

const FieldTemplate: ComponentType<FieldTemplateProps<T, S, F>>;

Usage Examples:

// Custom field template with Bootstrap styling
const BootstrapFieldTemplate = (props: FieldTemplateProps) => {
  const {
    id,
    classNames,
    label,
    children,
    errors,
    help,
    description,
    hidden,
    required,
    displayLabel,
  } = props;

  if (hidden) {
    return <div className="hidden">{children}</div>;
  }

  return (
    <div className={`form-group ${classNames}`}>
      {displayLabel && label && (
        <label htmlFor={id} className="control-label">
          {label}
          {required && <span className="text-danger"> *</span>}
        </label>
      )}
      {description && (
        <div className="field-description text-muted">{description}</div>
      )}
      {children}
      {errors && <div className="text-danger">{errors}</div>}
      {help && <small className="form-text text-muted">{help}</small>}
    </div>
  );
};

ObjectFieldTemplate

Template for object fields that contain multiple properties.

/**
 * Template for object fields with multiple properties
 * Handles property layout and additional properties
 */
interface ObjectFieldTemplateProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Object field ID */
  id: string;
  /** CSS class names */
  classNames: string;
  /** Object field title */
  title?: string;
  /** Object field description */
  description?: React.ReactNode;
  /** Whether title should be displayed */
  displayTitle: boolean;
  /** Array of property elements */
  properties: ObjectFieldTemplatePropertyType[];
  /** Whether object is required */
  required: boolean;
  /** Whether object is readonly */
  readonly: boolean;
  /** Whether object is disabled */
  disabled: boolean;
  /** Form registry */
  registry: Registry<T, S, F>;
  /** Form context */
  formContext: F;
  /** JSON schema */
  schema: S;
  /** UI schema */
  uiSchema: UiSchema<T, S, F>;
  /** Form data */
  formData: T;
}

interface ObjectFieldTemplatePropertyType {
  content: React.ReactElement;
  name: string;
  readonly: boolean;
  disabled: boolean;
  required: boolean;
}

const ObjectFieldTemplate: ComponentType<ObjectFieldTemplateProps<T, S, F>>;

Custom Implementation:

const CustomObjectFieldTemplate = (props: ObjectFieldTemplateProps) => {
  const { title, properties, description, displayTitle } = props;
  
  return (
    <fieldset className="object-field">
      {displayTitle && title && <legend>{title}</legend>}
      {description && <div className="object-description">{description}</div>}
      <div className="object-properties">
        {properties.map((prop, index) => (
          <div key={index} className={`property ${prop.name}`}>
            {prop.content}
          </div>
        ))}
      </div>
    </fieldset>
  );
};

BaseInputTemplate

Base template for input widgets with common styling and structure.

/**
 * Base template for input widgets
 * Provides common structure for form inputs
 */
interface BaseInputTemplateProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Input ID */
  id: string;
  /** Input value */
  value: any;
  /** Input label */
  label: string;
  /** Input type */
  type: string;
  /** Placeholder text */
  placeholder?: string;
  /** Whether input is required */
  required: boolean;
  /** Whether input is disabled */
  disabled: boolean;
  /** Whether input is readonly */
  readonly: boolean;
  /** Whether input should autofocus */
  autofocus: boolean;
  /** Change handler */
  onChange: (value: any) => void;
  /** Blur handler */
  onBlur: (id: string, value: any) => void;
  /** Focus handler */
  onFocus: (id: string, value: any) => void;
  /** Additional options */
  options: any;
  /** JSON schema */
  schema: S;
  /** UI schema */
  uiSchema: UiSchema<T, S, F>;
  /** Form context */
  formContext: F;
  /** Form registry */
  registry: Registry<T, S, F>;
  /** Raw validation errors */
  rawErrors?: string[];
}

const BaseInputTemplate: ComponentType<BaseInputTemplateProps<T, S, F>>;

Array Templates

ArrayFieldTemplate

Main template for array fields with item management controls.

/**
 * Template for array fields with add/remove/reorder controls
 * Manages array items and provides action buttons
 */
interface ArrayFieldTemplateProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Array field ID */
  id: string;
  /** CSS class names */
  classNames: string;
  /** Array field title */
  title?: string;
  /** Array field description */
  description?: React.ReactNode;
  /** Array items */
  items: ArrayFieldTemplateItemType<T, S, F>[];
  /** Whether items can be added */
  canAdd: boolean;
  /** Add item handler */
  onAddClick: (event: React.MouseEvent) => void;
  /** Whether array is disabled */
  disabled: boolean;
  /** Whether array is readonly */
  readonly: boolean;
  /** Form registry */
  registry: Registry<T, S, F>;
  /** Form context */
  formContext: F;
  /** JSON schema */
  schema: S;
  /** UI schema */
  uiSchema: UiSchema<T, S, F>;
  /** Form data */
  formData: T[];
}

interface ArrayFieldTemplateItemType<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Item content */
  children: React.ReactElement;
  /** Item index */
  index: number;
  /** Whether item can be removed */
  hasRemove: boolean;
  /** Whether item can be moved up */
  hasMoveUp: boolean;
  /** Whether item can be moved down */
  hasMoveDown: boolean;
  /** Whether item can be copied */
  hasCopy: boolean;
  /** Remove item handler */
  onDropIndexClick: (index: number) => (event: React.MouseEvent) => void;
  /** Move up handler */
  onReorderClick: (index: number, newIndex: number) => (event: React.MouseEvent) => void;
  /** Copy item handler */
  onCopyIndexClick: (index: number) => (event: React.MouseEvent) => void;
  /** Whether item is readonly */
  readonly: boolean;
  /** Whether item is disabled */
  disabled: boolean;
}

const ArrayFieldTemplate: ComponentType<ArrayFieldTemplateProps<T, S, F>>;

Custom Array Template:

const CustomArrayFieldTemplate = (props: ArrayFieldTemplateProps) => {
  const {
    items,
    canAdd,
    onAddClick,
    title,
    description,
    registry
  } = props;
  
  const { AddButton } = registry.templates.ButtonTemplates;
  
  return (
    <div className="array-field">
      {title && <h3>{title}</h3>}
      {description && <div className="array-description">{description}</div>}
      
      <div className="array-items">
        {items.map((item, index) => (
          <div key={index} className="array-item">
            <div className="item-content">{item.children}</div>
            <div className="item-controls">
              {item.hasRemove && (
                <button onClick={item.onDropIndexClick(item.index)}>
                  Remove
                </button>
              )}
              {item.hasMoveUp && (
                <button onClick={item.onReorderClick(item.index, item.index - 1)}>
                  Move Up
                </button>
              )}
              {item.hasMoveDown && (
                <button onClick={item.onReorderClick(item.index, item.index + 1)}>
                  Move Down
                </button>
              )}
            </div>
          </div>
        ))}
      </div>
      
      {canAdd && (
        <div className="array-add">
          <AddButton onClick={onAddClick} />
        </div>
      )}
    </div>
  );
};

ArrayFieldItemTemplate

Template for individual array items with controls.

/**
 * Template for individual array items
 * Wraps item content with controls
 */
const ArrayFieldItemTemplate: ComponentType<ArrayFieldTemplateItemType<T, S, F>>;

Error and Help Templates

ErrorListTemplate

Template for displaying form-level errors.

/**
 * Template for form-level error list display
 * Shows validation errors at top or bottom of form
 */
interface ErrorListProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Array of validation errors */
  errors: RJSFValidationError[];
  /** Form registry */
  registry: Registry<T, S, F>;
  /** Form context */
  formContext: F;
  /** JSON schema */
  schema: S;
  /** UI schema */
  uiSchema: UiSchema<T, S, F>;
}

const ErrorListTemplate: ComponentType<ErrorListProps<T, S, F>>;

FieldErrorTemplate

Template for field-specific error messages.

/**
 * Template for field-specific error messages
 * Displays errors inline with fields
 */
interface FieldErrorProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Array of error messages */
  errors: string[];
  /** Field ID */
  idSchema: IdSchema<T>;
  /** JSON schema */
  schema: S;
  /** UI schema */
  uiSchema: UiSchema<T, S, F>;
  /** Form registry */
  registry: Registry<T, S, F>;
}

const FieldErrorTemplate: ComponentType<FieldErrorProps<T, S, F>>;

FieldHelpTemplate

Template for field help text display.

/**
 * Template for field help text display
 * Shows guidance and instructions for fields
 */
interface FieldHelpProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Help text content */
  help: React.ReactNode;
  /** Field ID */
  idSchema: IdSchema<T>;
  /** JSON schema */
  schema: S;
  /** UI schema */
  uiSchema: UiSchema<T, S, F>;
  /** Form registry */
  registry: Registry<T, S, F>;
}

const FieldHelpTemplate: ComponentType<FieldHelpProps<T, S, F>>;

Button Templates

Button Template Types

Collection of button templates for form actions.

interface ButtonTemplates<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Form submit button */
  SubmitButton: ComponentType<SubmitButtonProps<T, S, F>>;
  /** Add array item button */
  AddButton: ComponentType<IconButtonProps<T, S, F>>;
  /** Copy array item button */
  CopyButton: ComponentType<IconButtonProps<T, S, F>>;
  /** Move array item down button */
  MoveDownButton: ComponentType<IconButtonProps<T, S, F>>;
  /** Move array item up button */
  MoveUpButton: ComponentType<IconButtonProps<T, S, F>>;
  /** Remove array item button */
  RemoveButton: ComponentType<IconButtonProps<T, S, F>>;
}

SubmitButton

Template for form submit button.

/**
 * Template for form submit button
 * Handles form submission trigger
 */
interface SubmitButtonProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** UI schema submit button options */
  uiSchema: UiSchema<T, S, F>;
  /** Form registry */
  registry: Registry<T, S, F>;
  /** Form context */
  formContext: F;
  /** Whether form is disabled */
  disabled: boolean;
  /** Whether form is readonly */
  readonly: boolean;
}

const SubmitButton: ComponentType<SubmitButtonProps<T, S, F>>;

Icon Button Props

Common props for array action buttons.

interface IconButtonProps<T = any, S extends StrictRJSFSchema = RJSFSchema, F extends FormContextType = any> {
  /** Button icon name or element */
  icon?: string | React.ReactElement;
  /** Button color scheme */
  color?: string;
  /** Button title/tooltip */
  title?: string;
  /** CSS class names */
  className?: string;
  /** Tab index */
  tabIndex?: number;
  /** Whether button is disabled */
  disabled?: boolean;
  /** Click handler */
  onClick?: (event: React.MouseEvent) => void;
  /** UI schema */
  uiSchema?: UiSchema<T, S, F>;
  /** Form registry */
  registry?: Registry<T, S, F>;
}

Custom Template Implementation

Custom Field Template

const MaterialFieldTemplate = (props: FieldTemplateProps) => {
  const {
    id,
    label,
    children,
    errors,
    help,
    description,
    required,
    displayLabel,
    hidden
  } = props;

  if (hidden) {
    return <div style={{ display: 'none' }}>{children}</div>;
  }

  return (
    <div className="material-field">
      {displayLabel && label && (
        <label htmlFor={id} className="material-label">
          {label}
          {required && <span className="required">*</span>}
        </label>
      )}
      
      <div className="material-input-container">
        {children}
      </div>
      
      {description && (
        <div className="material-description">{description}</div>
      )}
      
      {errors && (
        <div className="material-errors">{errors}</div>
      )}
      
      {help && (
        <div className="material-help">{help}</div>
      )}
    </div>
  );
};

Custom Button Templates

const CustomButtonTemplates = {
  SubmitButton: (props: SubmitButtonProps) => (
    <button type="submit" className="btn btn-primary">
      Submit Form
    </button>
  ),
  
  AddButton: (props: IconButtonProps) => (
    <button
      type="button"
      className="btn btn-success btn-sm"
      onClick={props.onClick}
      disabled={props.disabled}
      title="Add Item"
    >
      + Add
    </button>
  ),
  
  RemoveButton: (props: IconButtonProps) => (
    <button
      type="button"
      className="btn btn-danger btn-sm"
      onClick={props.onClick}
      disabled={props.disabled}
      title="Remove Item"
    >
      × Remove
    </button>
  )
};

// Use custom templates
const customTemplates = {
  FieldTemplate: MaterialFieldTemplate,
  ButtonTemplates: CustomButtonTemplates
};

<Form
  schema={schema}
  validator={validator}
  templates={customTemplates}
/>

Install with Tessl CLI

npx tessl i tessl/npm-rjsf--core

docs

field-components.md

form-component.md

index.md

registry-system.md

template-components.md

theme-system.md

widget-components.md

tile.json