- Overview
- Anatomy
- Header
- Navigation
- Renderers
The Schema Builder is the JSON Schema editor from the Retab dashboard: recursive
fields, a type picker, enums, optional $defs / references, optional JSON mode,
and live validation. It is a controlled component that edits the json_schema
an extraction runs against and emits standard JSON Schema. The editor normalizes
object properties as required; use nullable field types when a required field may
return null.
"use client";
import * as React from "react";
import { type ExtendedJSONSchema7 } from "@/components/schema-editor/lib/json-schema-types";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import { SchemaBuilder } from "@/components/ui/schema-builder";
const initialSchema: ExtendedJSONSchema7 = {
type: "object",Usage
Give the component your schema state and handle every edit through
onValueChange:
import { useState } from "react";
import {
SchemaBuilder,
type ExtendedJSONSchema7,
} from "@/components/ui/schema-builder";
export function Example() {
const [schema, setSchema] = useState<ExtendedJSONSchema7>({
type: "object",
properties: {},
required: [],
});
return <SchemaBuilder value={schema} onValueChange={setSchema} />;
}Read-only
Pass readOnly to render an existing schema as a static, non-editable summary —
no type pickers, inline inputs, or row actions. Useful for review screens and
run history.
"use client";
import {
SchemaBuilder,
type ExtendedJSONSchema7,
} from "@/components/ui/schema-builder";
const invoiceSchema: ExtendedJSONSchema7 = {
type: "object",
title: "Invoice",Definitions and features
Optional surfaces turn on through features (only definitions is on by
default). definitions lets a schema reuse a shared shape through $defs and
$ref; objectTemplates and importExport add reusable object templates and
import/export actions, and jsonMode adds the Fields ⇄ JSON toggle. This example
enables them all over a schema whose billing_address and shipping_address
reference one address definition.
"use client";
import * as React from "react";
import {
SchemaBuilder,
type ExtendedJSONSchema7,
} from "@/components/ui/schema-builder";
const orderSchema: ExtendedJSONSchema7 = {API Reference
| Prop | Type | Description |
|---|---|---|
value | ExtendedJSONSchema7 | The schema state. |
onValueChange | (schema: ExtendedJSONSchema7) => void | Called with the next schema whenever the user edits it. |
className | string | Optional wrapper class name. |
readOnly | boolean | Renders the current schema without allowing edits. |
view | "fields" | "json" | Controls the active view when JSON mode is enabled. |
onViewChange | (view: "fields" | "json") => void | Called when the user switches between fields and JSON mode. |
features | SchemaBuilderFeatures | Enables optional surfaces: definitions, objectTemplates, jsonMode, and importExport. |
Optional feature defaults are intentionally small: definitions is enabled,
while objectTemplates, jsonMode, and importExport are disabled unless you
turn them on.
Property Form
When you click a field's edit action, the Schema Builder opens an Edit
Property dialog. The body of that dialog is PropertyForm — name, data type,
type-specific options (enum values, array item type, $ref), nullable controls,
and description. It edits a local draft and emits a single validated commit
through onCommitPropertyDraft.
PropertyForm renders just the form (no dialog chrome), so the Schema Builder
drops it into a <DialogContent> while you can reuse the same subcomponent in a
popover or an inline panel.
"use client";
import * as React from "react";
import { type ExtendedJSONSchema7 } from "@/components/schema-editor/lib/json-schema-types";
import { PropertyForm } from "@/components/schema-editor/property-form/property-form";
export function PropertyFormDemo() {
const [property, setProperty] = React.useState<ExtendedJSONSchema7>({
type: "object",Using Property Form standalone
PropertyForm does not own the parent schema. Pass the current property draft
through propertyDraft, parent-local schema context through schemaContext, and
persist changes in onCommitPropertyDraft.
import { useState } from "react";
import type { ExtendedJSONSchema7 } from "@/components/schema-editor/lib/json-schema-types";
import { PropertyForm } from "@/components/schema-editor/property-form/property-form";
export function Example() {
const [property, setProperty] = useState<ExtendedJSONSchema7>({
type: "string",
});
const [name, setName] = useState("currency");
return (
<PropertyForm
propertyDraft={{ name, schemaNode: property }}
schemaContext={{
siblingNames: [],
originalName: name,
schemaDefinitions: {},
}}
submitLabel="Save"
onCommitPropertyDraft={(next) => {
setName(next.name);
setProperty(next.schemaNode);
}}
onCancel={() => {}}
onDelete={() => {}}
/>
);
}Property Form props
| Prop | Type | Description |
|---|---|---|
propertyDraft | { name; schemaNode } | The property draft to edit. |
schemaContext | PropertyFormSchemaContext | Parent-local validation names, original name, $defs, and optional command handler for definitions/templates. |
onCommitPropertyDraft | (next: { name; schemaNode }) => void | Promise<void> | Called only after validation passes. |
onCancel | () => void | Called on Cancel. |
onDelete | () => void | Optional. Shows the Delete Property action. |
submitLabel | string | Submit button label. Defaults to "Save Changes". |
mode | "editable" | "readOnly" | "descriptionOnly" | Defaults to "editable". |
Source
"use client";
export {
SchemaBuilder,
type ExtendedJSONSchema7,
type SchemaBuilderFeatures,
type SchemaBuilderProps,
type SchemaBuilderView,
} from "@/components/schema-editor/schema-builder";