CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-udecode--plate-image

Image plugin for Plate rich text editor that enables embedding, uploading, and managing images with advanced features like drag-and-drop, resizing, and captions.

Pending
Overview
Eval results
Files

types-interfaces.mddocs/

Types and Interfaces

TypeScript interfaces and types for image elements and plugin configuration.

Capabilities

Image Element Type

The core interface defining the structure of image elements in the Plate editor.

/**
 * Image element interface extending Plate's base element type
 * Represents an image node in the editor's document structure
 */
interface TImageElement extends TElement {
  /** Image URL (can be data URL, blob URL, or remote URL) */
  url: string;
  /** Optional width for image sizing (CSS-compatible value) */
  width?: number;
  /** Optional caption content as descendant nodes */
  caption?: TDescendant[];
}

Usage Examples:

import { TImageElement } from "@udecode/plate-image";

// Create image element data
const imageElement: TImageElement = {
  type: 'img',
  url: 'https://example.com/image.jpg',
  width: 400,
  caption: [{ text: 'Sample image caption' }],
  children: [{ text: '' }] // Required by TElement
};

// Type-safe access to image properties
function processImageElement(element: TImageElement) {
  console.log(`Image URL: ${element.url}`);
  if (element.width) {
    console.log(`Width: ${element.width}px`);
  }
  if (element.caption) {
    console.log(`Has caption with ${element.caption.length} nodes`);
  }
}

Plugin Configuration Interface

Interface defining the configuration options for the image plugin.

/**
 * Configuration interface for the image plugin
 * All properties are optional with sensible defaults
 */
interface ImagePlugin {
  /**
   * Custom image upload function
   * Called when user pastes/drops image files
   * @param dataUrl - Base64 data URL or ArrayBuffer of the image
   * @returns Promise resolving to uploaded image URL or synchronous URL
   */
  uploadImage?: (
    dataUrl: string | ArrayBuffer
  ) => Promise<string | ArrayBuffer> | string | ArrayBuffer;

  /**
   * Disable automatic file upload on paste/drop operations
   * When true, image files won't be processed automatically
   * @default false
   */
  disableUploadInsert?: boolean;

  /**
   * Disable automatic URL embedding when pasting image URLs
   * When true, image URLs will be treated as regular text
   * @default false
   */
  disableEmbedInsert?: boolean;
}

Usage Examples:

import { ImagePlugin } from "@udecode/plate-image";

// Minimal configuration
const basicConfig: ImagePlugin = {};

// Configuration with custom upload
const uploadConfig: ImagePlugin = {
  uploadImage: async (dataUrl) => {
    try {
      const response = await fetch('/api/images', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ imageData: dataUrl })
      });
      const result = await response.json();
      return result.imageUrl;
    } catch (error) {
      console.error('Upload failed:', error);
      throw error;
    }
  }
};

// Configuration with disabled features
const restrictedConfig: ImagePlugin = {
  disableUploadInsert: true,  // No file uploads
  disableEmbedInsert: false,  // Still allow URL embedding
};

// Complete configuration example
const fullConfig: ImagePlugin = {
  async uploadImage(dataUrl) {
    // Handle both string and ArrayBuffer inputs
    const imageData = typeof dataUrl === 'string' ? dataUrl : dataUrl;
    
    // Custom upload logic with error handling
    try {
      const uploadResult = await uploadToCloudinary(imageData);
      return uploadResult.secure_url;
    } catch (error) {
      // Fallback to data URL if upload fails
      return dataUrl;
    }
  },
  disableUploadInsert: false,
  disableEmbedInsert: false,
};

Type Usage Patterns

Working with Image Elements

import { TImageElement, useImageElement } from "@udecode/plate-image";
import { setNodes, findNodePath } from "@udecode/plate-core";

// Hook usage in components
function MyImageComponent() {
  const element = useImageElement(); // Returns TImageElement
  
  // Type-safe property access
  const imageUrl = element.url;
  const imageWidth = element.width || '100%';
  const hasCaption = element.caption && element.caption.length > 0;
  
  return (
    <img 
      src={imageUrl}
      style={{ width: imageWidth }}
      alt={hasCaption ? 'Image with caption' : 'Image'}
    />
  );
}

// Programmatic element manipulation
function updateImageWidth(editor: PlateEditor, newWidth: number) {
  const element = useImageElement();
  const path = findNodePath(editor, element);
  
  if (path) {
    setNodes<TImageElement>(
      editor,
      { width: newWidth },
      { at: path }
    );
  }
}

Plugin Configuration Patterns

import { createImagePlugin, ImagePlugin } from "@udecode/plate-image";

// Factory function for creating configured plugins
function createCustomImagePlugin(uploadEndpoint: string): ImagePlugin {
  return {
    uploadImage: async (dataUrl) => {
      const response = await fetch(uploadEndpoint, {
        method: 'POST',
        body: JSON.stringify({ image: dataUrl }),
        headers: { 'Content-Type': 'application/json' }
      });
      return response.json().then(data => data.url);
    }
  };
}

// Conditional configuration
function createImagePluginForEnvironment(isDevelopment: boolean): ImagePlugin {
  if (isDevelopment) {
    return {
      // In development, just use data URLs
      uploadImage: (dataUrl) => Promise.resolve(dataUrl)
    };
  }
  
  return {
    uploadImage: async (dataUrl) => {
      // Production upload logic
      return await uploadToProduction(dataUrl);
    }
  };
}

Install with Tessl CLI

npx tessl i tessl/npm-udecode--plate-image

docs

editor-enhancements.md

hooks-state.md

index.md

plugin-configuration.md

react-components.md

transforms-utilities.md

types-interfaces.md

tile.json