From zbeyens. The source code is available on GitHub.

Plate
PlatePliteEditorsTemplates
GitHub16kGitHub
DiscordDiscord
UNPUBLISHED
  • Overview
  • Why This Fork
  • Examples
Walkthroughs
  • Installing Plite
  • Adding Event Handlers
  • Defining Custom Elements
  • Applying Custom Formatting
  • Executing Commands
  • Saving to a Database
  • Canonical Change Substrate
  • Improving Performance
Concepts
  • Interfaces
  • Nodes
  • Locations
  • Transforms
  • Document Changes
  • Commands
  • Editor
  • Extensions
  • Rendering
  • Serializing
  • Normalizing
  • Using TypeScript
  • Roots
  • Document State
  • Editing Behavior
  • Selection And DOM
  • Clipboard And Paste
  • Projection And Overlays
  • Schema
API
  • Anchor API
  • Location API
  • Path API
  • PointEntry API
  • Point API
  • Range API
  • Selection API
  • Location Types APIs
  • Span API
  • Editor
  • Element API
  • NodeEntry API
  • Node API
  • Node Types APIs
  • Text API
  • Debug Value Scrubbing
  • Transforms API
Libraries
  • Plite DOM
  • History Editor API
  • History Extension Setup
  • History
  • Plite History
  • Plite Hyperscript
  • Plite Layout
  • Annotations
  • DOM Coverage Boundaries
  • Editable Component
  • Plite React Event Handling
  • Virtualized Rendering
  • Plite React Hooks
  • React Editor Setup
  • React Editor
  • Plite React
  • Plite Component
  • Plite Yjs
  • Plite
General
  • Migration
  • Contributing
  • Docs Proof Map
  • FAQ
  • Resources

Using TypeScript

PreviousNext

Type custom Plite values, elements, text nodes, and React editors with value generics.

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 usePliteEditor<Value>() when React owns the editor lifetime.

Defining Element And Text Types

import { type ElementOf, type TextOf, type ValueOf } from "@platejs/plite";
import { usePliteEditor, type ReactEditor } from "@platejs/plite-react";
 
type CustomText = { text: string























NormalizingRoots

On This Page

Defining Element And Text TypesAnnotating Initial ValuesWorking With NodesMultiple Document Models
Build your editor
Production-ready AI template and reusable components.
Get all-access
;
bold
?:
true
};
type ParagraphElement = {
type: "paragraph";
children: CustomText[];
};
type HeadingElement = {
type: "heading";
level: number;
children: CustomText[];
};
type CustomValue = (ParagraphElement | HeadingElement)[];
type CustomEditor = ReactEditor<CustomValue>;
const useCustomEditor = () => {
const editor = usePliteEditor<CustomValue>();
type CustomElement = ElementOf<typeof editor>;
type EditorText = TextOf<typeof editor>;
type EditorValue = ValueOf<typeof editor>;
return editor;
};
import { type ElementOf, type TextOf, type ValueOf } from "@platejs/plite";
import { usePliteEditor, type ReactEditor } from "@platejs/plite-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 = ReactEditor<CustomValue>;
 
const useCustomEditor = () => {
  const editor = usePliteEditor<CustomValue>();
 
  type CustomElement = ElementOf<typeof editor>;
  type EditorText = TextOf<typeof editor>;
  type EditorValue = ValueOf<typeof editor>;
 
  return editor;
};

Annotating Initial Values

Annotate the editor's initial value with your value type.

import { Editable, Plite, usePliteEditor } from "@platejs/plite-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 = usePliteEditor<CustomValue>({ initialValue });
 
  return (
    <Plite editor={editor}>
      <Editable />
    </Plite>
  );
};
import { Editable, Plite, usePliteEditor } from "@platejs/plite-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 = () => {







Working With Nodes

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 "@platejs/plite";
 
type CustomElement = ElementOf<typeof editor>;
type CustomText = TextOf<typeof editor>;
type CustomValue = ValueOf<typeof editor>;
import type { ElementOf, TextOf, ValueOf } from "@platejs/plite";
 
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 "@platejs/plite";
 
const isParagraph = (node: Node) =>
  ElementApi.isElement(node) && node.type === "paragraph";
import { ElementApi, type Node } from "@platejs/plite";
 
const isParagraph = (node: Node) =>
  ElementApi.isElement(node) && node.type === "paragraph";

Multiple Document Models

Use a different Value type for each editor model.

const articleEditor = createEditor<ArticleValue>();
const commentEditor = createEditor<CommentValue>();
const articleEditor = createEditor<ArticleValue>();
const commentEditor = createEditor<CommentValue>();

Each editor carries its value through ValueOf<typeof editor>, ElementOf<typeof editor>, and TextOf<typeof editor>.

const
editor
=
usePliteEditor
<
CustomValue
>({ initialValue });
return (
<Plite editor={editor}>
<Editable />
</Plite>
);
};