npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vega-rjsf

v1.0.0

Published

React JSON Schema Form components integrated with Vega design system

Downloads

6

Readme

vega-rjsf

React JSON Schema Form components integrated with Vega design system.

Installation

npm install vega-rjsf
# or
yarn add vega-rjsf

Peer Dependencies

This package requires the following peer dependencies:

  • react ^19.2.1
  • react-dom ^19.2.1
  • @vega-core (Vega design system components)

Quick Start

import { RJSFForm } from "vega-rjsf";
import type { RJSFSchema, UiSchema } from "@rjsf/utils";

const schema: RJSFSchema = {
  type: "object",
  properties: {
    name: {
      type: "string",
      title: "Name",
    },
    email: {
      type: "string",
      format: "email",
      title: "Email",
    },
  },
  required: ["name", "email"],
};

const uiSchema: UiSchema = {
  email: {
    "ui:widget": "email",
  },
};

function MyForm() {
  const handleSubmit = (data: Record<string, unknown>) => {
    console.log("Form submitted:", data);
  };

  return (
    <RJSFForm
      schema={schema}
      uiSchema={uiSchema}
      onSubmit={handleSubmit}
    />
  );
}

Widget Options Reference

Common Properties (All Widgets)

All widgets support these common UI schema properties:

| Property | Type | Default | Description | |----------|------|---------|-------------| | ui:widget | string | - | Specifies which widget to use (see widget list below) | | ui:label | string | Schema title | Overrides the field label from schema | | ui:placeholder | string | - | Placeholder text for input fields | | ui:help | string | - | Help text displayed below the field | | ui:description | string | Schema description | Description text displayed below the field | | ui:autofocus | boolean | false | Automatically focus the field when form loads | | ui:emptyValue | string | undefined | Value to use when field is empty |

Widget-Specific Options

| Widget | ui:widget Value | ui:options Properties | Schema Type | |--------|-------------------|-------------------------|-------------| | Text | "text" | inputType?: "text" \| "email" \| "password" \| "tel" | string | | Textarea | "textarea" | rows?: number (default: 4) | string | | Number | "number" | None | number | | Select | "select" | enumOptions?: Array<{ label: string; value: string }> | string with enum | | Radio | "radio" | inline?: boolean (default: false)enumOptions?: Array<{ label: string; value: string }> | string with enum | | Radio Cards | "radioCards" | columns?: 2 \| 3 \| 4 (default: 2)enumOptions?: Array<{ label: string; value: string }> | string with enum | | Checkbox | "checkbox" | None | boolean | | Checkboxes | "checkboxes" | columns?: 2 \| 3 \| 4 (default: 2)enumOptions?: Array<{ label: string; value: string }> | array with enum items | | Switch | "switch" | None | boolean | | Segmented Tabs | "segmentedTabs" | enumOptions?: Array<{ label: string; value: string }> | string with enum |

Quick Reference Table

| Property | Text | Textarea | Number | Select | Radio | Radio Cards | Checkbox | Checkboxes | Switch | Segmented Tabs | |----------|:----:|:--------:|:------:|:------:|:----:|:-----------:|:--------:|:----------:|:------:|:--------------:| | ui:label | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | ui:placeholder | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | ui:help | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | ui:description | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | | ui:autofocus | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | ui:emptyValue | ✅ | ✅ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | ui:options.inputType | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | ui:options.rows | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | | ui:options.inline | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ❌ | ❌ | ❌ | ❌ | | ui:options.columns | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ❌ | ✅ | ❌ | ❌ | | ui:options.enumOptions | ❌ | ❌ | ❌ | ✅ | ✅ | ✅ | ❌ | ✅ | ❌ | ✅ |

TypeScript Types

All widget options are available as TypeScript types:

import type {
  CommonWidgetOptions,
  TextWidgetOptions,
  TextareaWidgetOptions,
  NumberWidgetOptions,
  SelectWidgetOptions,
  RadioWidgetOptions,
  RadioCardsWidgetOptions,
  CheckboxWidgetOptions,
  CheckboxesWidgetOptions,
  SwitchWidgetOptions,
  SegmentedTabsWidgetOptions,
  WidgetOptions,
  SubmitButtonOptions,
} from "vega-rjsf";

Example

const uiSchema: UiSchema = {
  myField: {
    "ui:label": "Custom Label",
    "ui:placeholder": "Enter value",
    "ui:help": "This is helpful information",
    "ui:description": "This is a description",
    "ui:autofocus": true,
    "ui:emptyValue": "",
    "ui:widget": "text",
    "ui:options": {
      inputType: "email",
    },
  },
};

Widgets

Text Widget (text)

Default widget for string fields. Supports various input types based on schema format or explicit configuration.

Schema:

{
  "type": "string",
  "title": "Text Field"
}

UI Schema Options:

{
  "ui:widget": "text",
  "ui:options": {
    "inputType": "text" | "email" | "password" | "tel" // Optional, auto-detected from format
  }
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    username: {
      type: "string",
      title: "Username",
    },
    email: {
      type: "string",
      format: "email",
      title: "Email",
    },
    password: {
      type: "string",
      title: "Password",
    },
  },
};

const uiSchema: UiSchema = {
  password: {
    "ui:widget": "text",
    "ui:options": {
      inputType: "password",
    },
  },
};

Textarea Widget (textarea)

Multi-line text input for longer text content.

Schema:

{
  "type": "string",
  "title": "Description"
}

UI Schema Options:

{
  "ui:widget": "textarea",
  "ui:options": {
    "rows": number // Number of rows (default: 4)
  }
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    description: {
      type: "string",
      title: "Description",
    },
  },
};

const uiSchema: UiSchema = {
  description: {
    "ui:widget": "textarea",
    "ui:placeholder": "Enter a detailed description",
    "ui:options": {
      rows: 6,
    },
  },
};

Number Widget (number)

Numeric input with proper number formatting and validation.

Schema:

{
  "type": "number",
  "title": "Amount"
}

UI Schema Options:

{
  "ui:widget": "number"
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    amount: {
      type: "number",
      title: "Amount",
      minimum: 0,
    },
  },
};

const uiSchema: UiSchema = {
  amount: {
    "ui:widget": "number",
    "ui:placeholder": "0.00",
  },
};

Select Widget (select)

Dropdown select for single value selection from a list of options.

Schema:

{
  "type": "string",
  "title": "Country",
  "enum": ["US", "UK", "CA"],
  "enumNames": ["United States", "United Kingdom", "Canada"]
}

UI Schema Options:

{
  "ui:widget": "select",
  "ui:options": {
    "enumOptions": Array<{ label: string; value: string }> // Override enum/enumNames
  }
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    country: {
      type: "string",
      title: "Country",
      enum: ["US", "UK", "CA"],
      enumNames: ["United States", "United Kingdom", "Canada"],
    },
  },
};

const uiSchema: UiSchema = {
  country: {
    "ui:widget": "select",
    "ui:placeholder": "Select a country",
    // Optional: override enum options
    "ui:options": {
      enumOptions: [
        { label: "United States", value: "US" },
        { label: "United Kingdom", value: "UK" },
        { label: "Canada", value: "CA" },
      ],
    },
  },
};

Radio Widget (radio)

Radio button group for single selection.

Schema:

{
  "type": "string",
  "title": "Option",
  "enum": ["option1", "option2", "option3"],
  "enumNames": ["Option 1", "Option 2", "Option 3"]
}

UI Schema Options:

{
  "ui:widget": "radio",
  "ui:options": {
    "inline": boolean, // Display horizontally (default: false)
    "enumOptions": Array<{ label: string; value: string }> // Override enum/enumNames
  }
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    plan: {
      type: "string",
      title: "Select Plan",
      enum: ["basic", "premium", "enterprise"],
      enumNames: ["Basic", "Premium", "Enterprise"],
    },
  },
};

const uiSchema: UiSchema = {
  plan: {
    "ui:widget": "radio",
    "ui:options": {
      inline: true, // Display horizontally
    },
  },
};

Radio Cards Widget (radioCards)

Card-based radio selection with visual cards for each option.

Schema:

{
  "type": "string",
  "title": "Payment Method",
  "enum": ["credit", "debit", "paypal"],
  "enumNames": ["Credit Card", "Debit Card", "PayPal"]
}

UI Schema Options:

{
  "ui:widget": "radioCards",
  "ui:options": {
    "columns": number, // Grid columns: 2, 3, or 4 (default: 2)
    "enumOptions": Array<{ label: string; value: string }> // Override enum/enumNames
  }
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    paymentMethod: {
      type: "string",
      title: "Payment Method",
      enum: ["credit", "debit", "paypal"],
      enumNames: ["Credit Card", "Debit Card", "PayPal"],
    },
  },
};

const uiSchema: UiSchema = {
  paymentMethod: {
    "ui:widget": "radioCards",
    "ui:options": {
      columns: 3, // Display in 3 columns
    },
  },
};

Checkbox Widget (checkbox)

Single checkbox for boolean values.

Schema:

{
  "type": "boolean",
  "title": "I agree to the terms"
}

UI Schema Options:

{
  "ui:widget": "checkbox"
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    agreeToTerms: {
      type: "boolean",
      title: "I agree to the terms and conditions",
    },
  },
};

const uiSchema: UiSchema = {
  agreeToTerms: {
    "ui:widget": "checkbox",
    "ui:help": "You must agree to continue",
  },
};

Checkboxes Widget (checkboxes)

Multiple checkboxes for array of selected values.

Schema:

{
  "type": "array",
  "title": "Interests",
  "items": {
    "type": "string",
    "enum": ["sports", "music", "travel"],
    "enumNames": ["Sports", "Music", "Travel"]
  }
}

UI Schema Options:

{
  "ui:widget": "checkboxes",
  "ui:options": {
    "columns": number, // Grid columns: 2, 3, or 4 (default: 2)
    "enumOptions": Array<{ label: string; value: string }> // Override enum/enumNames
  }
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    interests: {
      type: "array",
      title: "Select Your Interests",
      items: {
        type: "string",
        enum: ["sports", "music", "travel", "reading"],
        enumNames: ["Sports", "Music", "Travel", "Reading"],
      },
      uniqueItems: true,
    },
  },
};

const uiSchema: UiSchema = {
  interests: {
    "ui:widget": "checkboxes",
    "ui:options": {
      columns: 2, // Display in 2 columns
    },
  },
};

Switch Widget (switch)

Toggle switch for boolean values.

Schema:

{
  "type": "boolean",
  "title": "Enable notifications"
}

UI Schema Options:

{
  "ui:widget": "switch"
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    notifications: {
      type: "boolean",
      title: "Enable Email Notifications",
    },
  },
};

const uiSchema: UiSchema = {
  notifications: {
    "ui:widget": "switch",
    "ui:help": "Receive email updates about your account",
  },
};

Segmented Tabs Widget (segmentedTabs)

Segmented tab selection for single value selection.

Schema:

{
  "type": "string",
  "title": "View Mode",
  "enum": ["list", "grid", "card"],
  "enumNames": ["List", "Grid", "Card"]
}

UI Schema Options:

{
  "ui:widget": "segmentedTabs",
  "ui:options": {
    "enumOptions": Array<{ label: string; value: string }> // Override enum/enumNames
  }
}

Example:

const schema: RJSFSchema = {
  type: "object",
  properties: {
    viewMode: {
      type: "string",
      title: "View Mode",
      enum: ["list", "grid", "card"],
      enumNames: ["List", "Grid", "Card"],
    },
  },
};

const uiSchema: UiSchema = {
  viewMode: {
    "ui:widget": "segmentedTabs",
  },
};

Submit Button Customization

Customize the submit button text via the root-level UI schema:

const uiSchema: UiSchema = {
  "ui:submitButtonOptions": {
    submitText: "Save Changes", // Custom button text
  },
  // ... field-specific UI schemas
};

Backend Validation Errors

The form supports backend validation errors in RJSF's ErrorSchema format. Backend should send errors directly in this format:

import type { ErrorSchema } from "@rjsf/utils";

const backendErrors: ErrorSchema = {
  name: {
    __errors: ["Name is required"],
  },
  email: {
    __errors: ["Invalid email format", "Email must be unique"],
  },
  amount: {
    __errors: ["Amount exceeds maximum allowed"],
  },
};

<RJSFForm
  schema={schema}
  uiSchema={uiSchema}
  extraErrors={backendErrors}
  onSubmit={handleSubmit}
/>

Error Schema Format

type ErrorSchema = {
  [fieldName: string]: {
    __errors: string[];
  } & ErrorSchema; // Recursive for nested fields
};

Example with nested fields:

const nestedErrors: ErrorSchema = {
  address: {
    street: {
      __errors: ["Street is required"],
    },
    city: {
      __errors: ["City is required"],
    },
  },
};

Complete Example

import { RJSFForm } from "vega-rjsf";
import type { ErrorSchema, RJSFSchema, UiSchema } from "@rjsf/utils";
import { useState } from "react";

const schema: RJSFSchema = {
  type: "object",
  properties: {
    name: {
      type: "string",
      title: "Full Name",
    },
    email: {
      type: "string",
      format: "email",
      title: "Email Address",
    },
    country: {
      type: "string",
      title: "Country",
      enum: ["US", "UK", "CA"],
      enumNames: ["United States", "United Kingdom", "Canada"],
    },
    interests: {
      type: "array",
      title: "Interests",
      items: {
        type: "string",
        enum: ["sports", "music", "travel"],
        enumNames: ["Sports", "Music", "Travel"],
      },
      uniqueItems: true,
    },
    notifications: {
      type: "boolean",
      title: "Enable Notifications",
    },
  },
  required: ["name", "email"],
};

const uiSchema: UiSchema = {
  "ui:submitButtonOptions": {
    submitText: "Create Account",
  },
  email: {
    "ui:placeholder": "[email protected]",
    "ui:help": "We'll never share your email",
  },
  country: {
    "ui:widget": "select",
  },
  interests: {
    "ui:widget": "checkboxes",
    "ui:options": {
      columns: 3,
    },
  },
  notifications: {
    "ui:widget": "switch",
  },
};

function MyForm() {
  const [errors, setErrors] = useState<ErrorSchema | undefined>();

  const handleSubmit = async (data: Record<string, unknown>) => {
    // Simulate API call
    try {
      const response = await fetch("/api/submit", {
        method: "POST",
        body: JSON.stringify(data),
      });

      if (!response.ok) {
        const errorData = await response.json();
        // Backend should return ErrorSchema format
        setErrors(errorData.errors);
        return;
      }

      console.log("Success:", data);
      setErrors(undefined);
    } catch (error) {
      console.error("Error:", error);
    }
  };

  return (
    <RJSFForm
      schema={schema}
      uiSchema={uiSchema}
      extraErrors={errors}
      onSubmit={handleSubmit}
    />
  );
}

TypeScript Support

All types are exported from the package:

import type {
  RJSFFormProps,
  ErrorSchema,
  // Widget option types
  CommonWidgetOptions,
  TextWidgetOptions,
  TextareaWidgetOptions,
  NumberWidgetOptions,
  SelectWidgetOptions,
  RadioWidgetOptions,
  RadioCardsWidgetOptions,
  CheckboxWidgetOptions,
  CheckboxesWidgetOptions,
  SwitchWidgetOptions,
  SegmentedTabsWidgetOptions,
  WidgetOptions,
  SubmitButtonOptions,
} from "vega-rjsf";
import type { RJSFSchema, UiSchema } from "@rjsf/utils";

License

UNLICENSED