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

Element API

PreviousNext

Element node API for schema behavior, void rendering, and element checks.

Element objects are a type of Node in a Plite document that contain other Element nodes or Text nodes.

Interface

interface Element {
  children: Node[];
}
interface Element {
  children
EditorNodeEntry API

On This Page

InterfaceOn This PageElement Behavior TypesBlock vs. InlineVoid vs Not VoidVoids That Support MarksRendering Void ElementsStatic methodsRetrieval methodsElementApi.matches(element: Element, props: Partial<Element>) => booleanCheck methodsElementApi.isAncestor(value: unknown) => value is AncestorElementApi.isElement(value: unknown) => value is ElementElementApi.isElementList(value: unknown) => value is Element[]ElementApi.isElementProps(props: unknown) => props is Partial<Element>ElementApi.isElementType<T extends Element>(value: unknown, elementVal: string, elementKey: string = 'type'): value is T
Build your editor
Production-ready AI template and reusable components.
Get all-access
:
Node
[];
}

On This Page

  • Behavior Types
    • Block vs. Inline
    • Void vs Not Void
      • Rendering Void Elements
  • Static methods
    • Retrieval methods
    • Check methods

Element Behavior Types

Element nodes behave differently depending on the Plite editor's schema. An element can be:

  • "block" or "inline" as defined by state.schema.isInline(element)
  • either "void" or "not void" as defined by state.schema.isVoid(element)

Block vs. Inline

A "block" element can only be siblings with other "block" elements. An "inline" node can be siblings with Text nodes or other "inline" elements.

Void vs Not Void

In a not "void" element, Plite handles the rendering of its children (e.g. in a paragraph where the Text and Inline children are rendered by Plite). In a "void" element, Plite owns the DOM shell and selection anchor while app code renders only the visible content.

Voids That Support Marks

Some void elements are effectively stand-ins for text, such as with the mentions example, where the mention element renders the character's name. Users might want to format Void elements like this with bold, or set their font and size, so state.schema.isMarkableVoid(element) tells Plite whether or not to apply Marks to the text children of void elements.

Rendering Void Elements

Void elements still contain a text child in the Plite document model so selection and marks have a stable model location. The React runtime renders the hidden anchor and browser shell for you. App renderers should use Editable's renderVoid prop and return visible content only.

Typical rendering code will resemble this image element:

import type { RenderVoidProps } from "@platejs/plite-react";
 
type ImageElement = {
  type: "image";
  url: string;
  children: [{ text: "" }];
};
 
const Image = ({ element }: RenderVoidProps<ImageElement>) => {
  return <img alt="" src={element.url} />;
};
 
<Editable
  renderVoid={(props) => {
    switch (props.element.type) {
      case "image":
        return <Image {...props} />;
      default:
        return null;
    }
  }}
/>;
import type { RenderVoidProps } from "@platejs/plite-react";
 
type ImageElement = {
  type: "image";
  url: string;
  children: [{ text: "" }];
};
 
const Image = ({ element }: RenderVoidProps<ImageElement>) => {
  return <img alt="" src={element.url} />;
};
 
<Editable
  renderVoid={(props) => {







For a "markable" void such as a mention element, marks on the text child can still be used to determine how the visible content is rendered. Selection UI is an opt-in target subscription:

import { useElementSelected, type RenderVoidProps } from "@platejs/plite-react";
 
type MentionElement = {
  type: "mention";
  character: string;
  children: [{ bold?: true; italic?: true; text: "" }];
};
 
const Mention = ({ element }: RenderVoidProps<MentionElement>) => {
  const selected = useElementSelected();
  const text = element.children[0] ?? {};
  const style = {
    padding: "3px 3px 2px",
    margin: "0 1px",
    verticalAlign: "baseline",
    display: "inline-block",
    borderRadius: "4px",
    backgroundColor: "#eee",
    fontSize: "0.9em",
    boxShadow: selected ? "0 0 0 2px #B4D5FF" : "none",
  };
  if (text.bold) {
    style.fontWeight = "bold";
  }
  if (text.italic) {
    style.fontStyle = "italic";
  }
  return (
    <span
      data-cy={`mention-${element.character.replace(" ", "-")}`}
      style={style}
    >
      @{element.character}
    </span>
  );
};
import { useElementSelected, type RenderVoidProps } from "@platejs/plite-react";
 
type MentionElement = {
  type: "mention";
  character: string;
  children: [{ bold?: true; italic?: true; text: "" }];
};
 
const Mention = ({ element }: RenderVoidProps<MentionElement>) => {
  const selected = useElementSelected();
  const text = element.children[0] ?? {};
























Static methods

Retrieval methods

ElementApi.matches(element: Element, props: Partial<Element>) => boolean

Check if an element matches a set of props. Note: This checks custom properties, but it does not ensure that any children are equivalent.

Check methods

ElementApi.isAncestor(value: unknown) => value is Ancestor

Check if a value implements the 'Ancestor' interface.

ElementApi.isElement(value: unknown) => value is Element

Check if a value implements the Element interface.

ElementApi.isElementList(value: unknown) => value is Element[]

Check if a value is an array of Element objects.

ElementApi.isElementProps(props: unknown) => props is Partial<Element>

Check if a value is an object that can be used as partial Element props.

ElementApi.isElementType<T extends Element>(value: unknown, elementVal: string, elementKey: string = 'type'): value is T

Check if a value implements the Element interface and has elementKey with the selected value. The default key is type.

switch
(props.element.type) {
case "image":
return <Image {...props} />;
default:
return null;
}
}}
/>;
const style = {
padding: "3px 3px 2px",
margin: "0 1px",
verticalAlign: "baseline",
display: "inline-block",
borderRadius: "4px",
backgroundColor: "#eee",
fontSize: "0.9em",
boxShadow: selected ? "0 0 0 2px #B4D5FF" : "none",
};
if (text.bold) {
style.fontWeight = "bold";
}
if (text.italic) {
style.fontStyle = "italic";
}
return (
<span
data-cy={`mention-${element.character.replace(" ", "-")}`}
style={style}
>
@{element.character}
</span>
);
};