Dojo NG is being built in the open, one section at a time — follow along on Heptapod.

API REFERENCE · RICH TEXT PLUGINS

@dojo-ng/rich-text-image

Images for <dj-rich-text>, inserted from a file or a URL, with required alt text.

Try it in the playground

@dojo-ng/rich-text-image · v0.1.1 · A plugin for <dj-rich-text>, not a custom element

npm install @dojo-ng/rich-text-image

Compose the image plugin with the default set. Pass createImagePlugin({ upload }) to host files instead of embedding data URLs.

<dj-rich-text id="editor" label="Article"></dj-rich-text>
<script type="module">
  import "@dojo-ng/rich-text";
  import { defaultPlugins } from "@dojo-ng/rich-text";
  import { createImagePlugin } from "@dojo-ng/rich-text-image";
  const imagePlugin = createImagePlugin({ upload: async (file) => (await myUploader(file)).url });
  document.getElementById("editor").plugins = [...defaultPlugins, imagePlugin];
</script>

Inserting

  • The toolbar button opens a dialog with a dj-file-input and a URL field. The source used most recently wins.
  • Alt text is required: the Insert button stays disabled until it is filled in, because an image must have an accessible name.
  • Click an image to select it; Backspace or Delete then removes it.

Setup

  • Exports imagePlugin, createImagePlugin({ upload, maxSize }), ImageNode, $createImageNode, $isImageNode, and INSERT_IMAGE_COMMAND.
  • The default upload turns the file into a data URL, which makes the HTML value large. In production, pass your own upload(file) => Promise<string> that stores the file and returns its URL.
  • There is no size limit by default. maxSize (bytes) limits the file input.
  • Setting plugins replaces the default set, so spread ...defaultPlugins to keep bold, italic, underline, undo, and redo.

Pasting

  • Paste cleaning removes <img> tags, so images come in through the dialog or value, not by pasting.

Not built

  • Resizing and cropping, captions, inserting by drag or paste, and alignment.

Need one of these? Make a request on Discord or add an issue (work item) on Heptapod.

Functions

createImagePlugin

function createImagePlugin(options?: ImagePluginOptions): RichTextPlugin;

Classes

ImageNode

class ImageNode extends DecoratorNode<HTMLElement> {
  __src: string;
  __alt: string;
  __width?: number;
  __height?: number;
  static getType(): string;
  static clone(node: ImageNode): ImageNode;
  static importJSON(serialized: SerializedImageNode): ImageNode;
  static importDOM(): DOMConversionMap | null;
  constructor(payload: ImagePayload);
  exportJSON(): SerializedImageNode;
  createDOM(_config: EditorConfig): HTMLElement;
  updateDOM(): boolean;
  exportDOM(): DOMExportOutput;
  decorate(editor: LexicalEditor): HTMLElement;
  getSrc(): string;
  getAlt(): string;
}

Values

imagePlugin

const imagePlugin: RichTextPlugin;

INSERT_IMAGE_COMMAND

const INSERT_IMAGE_COMMAND: LexicalCommand<ImagePayload>;

Types

ImagePayload

interface ImagePayload {
  src: string;
  alt: string;
  width?: number;
  height?: number;
  key?: NodeKey;
}

ImagePluginOptions

interface ImagePluginOptions {
  upload?: (file: File) => Promise<string>;
  maxSize?: number;
}

SerializedImageNode

type SerializedImageNode = Spread<{
  src: string;
  alt: string;
  width?: number;
  height?: number;
}, SerializedLexicalNode>;