BlockEditorInput

Use <BlockEditorInput> to edit structured content in a block editor (TipTap) and store it as TipTap JSON. The value is a plain JavaScript object (JSONContent) — not HTML or Markdown.

Installation

pnpm dlx shadcn@latest add @shadmin/block-editor-input

Installation

This is an optional component and is not included in the admin registry block by default. Install it with:

npx shadcn@latest add https://shadmin.turtlesocks.dev/r/block-editor-input.json

Usage

import { Edit, SimpleForm } from "@/components/admin";
import { BlockEditorInput } from "@/components/block-editor";
 
const OrderEdit = () => (
  <Edit>
    <SimpleForm>
      <BlockEditorInput source="notes" />
    </SimpleForm>
  </Edit>
);

Value shape

The stored value is a TipTap JSONContent object, for example:

{
  "type": "doc",
  "content": [
    { "type": "paragraph", "content": [{ "type": "text", "text": "Hello" }] }
  ]
}

Store this column as jsonb in your database. The default value (an empty document) is { type: "doc", content: [{ type: "paragraph" }] }.

Props

PropRequiredTypeDefaultDescription
sourceRequiredstring-Field name in the record
blocksOptionalBlockDefinition[]defaultBlocksBlock types available in the editor
placeholderOptionalstring-Placeholder shown in an empty editor
labelOptionalstring | falseInferred from sourceCustom label, or false to hide it
helperTextOptionalReactNode-Help text displayed below the editor
validateOptionalValidator | Validator[]-Validation rules
disabledOptionalboolean-Disable the editor
readOnlyOptionalboolean-Make the editor read-only (identical to disabled)
classNameOptionalstring-CSS classes applied to the field wrapper

All standard ra-core InputProps (e.g. defaultValue, format, parse, sx) are also accepted.

blocks

Pass a blocks array to control which block types are available in the editor. Omitting blocks uses defaultBlocks, which includes the built-in calloutBlock.

import { BlockEditorInput } from "@/components/block-editor";
import { calloutBlock, referenceRecordBlock } from "@/components/block-editor";
 
<BlockEditorInput
  source="notes"
  blocks={[calloutBlock, referenceRecordBlock]}
/>

See Custom Blocks for how to author your own block types with defineBlock.

placeholder

Text shown in the editor body when the document is empty.

<BlockEditorInput source="notes" placeholder="Add notes…" />

validate

Accepts the same validators as other ra-core inputs.

import { required } from "ra-core";
 
<BlockEditorInput source="notes" validate={required()} />

disabled / readOnly

Both props render the editor in a non-interactive state. Use disabled for form-level control (e.g. during submission), readOnly for a permanently locked field.

<BlockEditorInput source="notes" readOnly />

To render stored content in a Show view without the editor chrome, use <BlockDocField> instead.