Plite types custom document models through editor value generics. Define the
element and text shapes for your editor, create a Value from the element
union, then pass that value to createEditor<Value>() or
useEditor<Value>() when React owns the editor lifetime.
import { type ElementOf, type TextOf, type ValueOf } from "plitejs";
import { useEditor, type Editor } from "plitejs/react";
type CustomText = {
import { type ElementOf, type TextOf, type ValueOf } from "plitejs";
import { useEditor, type Editor } from "plitejs/react";
type CustomText = { text: string; bold?: true };
type ParagraphElement = {
type: "paragraph";
children: CustomText[];
};
type HeadingElement = {
type: "heading";
level: number;
children: CustomText[];
};
type CustomValue = (ParagraphElement | HeadingElement)[];
type CustomEditor = Editor<CustomValue>;
const useCustomEditor = () => {
const editor = useEditor<CustomValue>();
type CustomElement = ElementOf<typeof editor>;
type EditorText = TextOf<typeof editor>;
type EditorValue = ValueOf<typeof editor>;
return editor;
};Annotate the editor's initial value with your value type.
import { Editable, EditorRoot, useEditor } from "plitejs/react";
type CustomText = { text: string; bold?: true };
type ParagraphElement = { type: "paragraph"; children: CustomText[] };
type CustomValue = ParagraphElement[];
const initialValue: CustomValue = [
{
type: "paragraph",
children: [{ text: "A line of text in a paragraph." }],
},
];
const App = () => {
const editor = useEditor<CustomValue>({ initialValue });
return (
<EditorRoot editor={editor}>
<Editable />
</EditorRoot>
);
};import { Editable, EditorRoot, useEditor } from "plitejs/react";
type CustomText = { text: string; bold?: true };
type ParagraphElement = { type: "paragraph"; children: CustomText[] };
type CustomValue = ParagraphElement[];
const initialValue: CustomValue = [
{
type: "paragraph",
children: [{ text: "A line of text in a paragraph." }],
},
];
const App = () => {
Use exported helper types to derive the document types from an editor instead of duplicating unions at every call site.
import type { ElementOf, TextOf, ValueOf } from "plitejs";
type CustomElement = ElementOf<typeof editor>;
type CustomText = TextOf<typeof editor>;
type CustomValue = ValueOf<typeof editor>;import type { ElementOf, TextOf, ValueOf } from "plitejs";
type CustomElement = ElementOf<typeof editor>;
type CustomText = TextOf<typeof editor>;
type CustomValue = ValueOf<typeof editor>;When reading a generic Node, narrow it before accessing element-specific
properties.
import { ElementApi, type Node } from "plitejs";
const isParagraph = (node: Node) =>
ElementApi.isElement(node) && node.type === "paragraph";import { ElementApi, type Node } from "plitejs";
const isParagraph = (node: Node) =>
ElementApi.isElement(node) && node.type === "paragraph";Use a different Value type for each editor model.
import { createEditor } from "plitejs";
type ArticleValue = {
type: "paragraph" | "heading";
children: { text: string; bold?: true }[];
}[];
type CommentValue = {
type: "paragraph";
children: { text: string }[];
}[];
const articleEditor = createEditor<ArticleValue>();
const commentEditor = createEditor<CommentValue>();import { createEditor } from "plitejs";
type ArticleValue = {
type: "paragraph" | "heading";
children: { text: string; bold?: true }[];
}[];
type CommentValue = {
type: "paragraph";
children: { text: string }[];
}[];
const articleEditor = createEditor<ArticleValue>();
const commentEditor = createEditor<CommentValue>();Each editor carries its value through ValueOf<typeof editor>,
ElementOf<typeof editor>, and TextOf<typeof editor>.