CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-udecode--plate-media

Comprehensive media handling capabilities for the Plate rich text editor framework, supporting images, videos, audio files, and embeddable content

Pending
Overview
Eval results
Files

image.mddocs/

Image Management

Complete image management system providing upload capabilities, automatic embed detection, preview functionality, zoom controls, and URL validation. Supports both programmatic insertion and user interactions like drag & drop and paste operations.

Capabilities

Image Insertion

Core functions for inserting images into the editor.

Insert Image

/**
 * Inserts an image element at the current selection
 * @param editor - Slate editor instance
 * @param url - Image URL or ArrayBuffer data
 * @param options - Optional insertion configuration
 */
function insertImage(
  editor: SlateEditor, 
  url: ArrayBuffer | string, 
  options?: InsertNodesOptions
): void;

Usage Example:

import { insertImage } from "@udecode/plate-media";

// Insert image from URL
insertImage(editor, "https://example.com/image.jpg");

// Insert image from file data
const fileData = await file.arrayBuffer();
insertImage(editor, fileData, { 
  at: [0, 0] // Specific insertion point
});

Insert Images from Files

/**
 * Processes FileList and inserts images after upload processing
 * Handles multiple files and integrates with upload configuration
 * @param editor - Slate editor instance
 * @param files - FileList from input or drag & drop
 * @param options - Optional insertion configuration
 */
function insertImageFromFiles(
  editor: SlateEditor, 
  files: FileList, 
  options?: InsertNodesOptions
): void;

Usage Example:

import { insertImageFromFiles } from "@udecode/plate-media";

// Handle file input change
const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => {
  if (event.target.files) {
    insertImageFromFiles(editor, event.target.files);
  }
};

// Handle drag & drop
const handleDrop = (event: DragEvent) => {
  event.preventDefault();
  if (event.dataTransfer?.files) {
    insertImageFromFiles(editor, event.dataTransfer.files);
  }
};

URL Validation

Utility for detecting image URLs based on file extensions.

/**
 * Validates if a URL points to an image based on file extension
 * Supports comprehensive list of image formats
 * @param url - URL string to validate
 * @returns Boolean indicating if URL is likely an image
 */
function isImageUrl(url: string): boolean;

Supported Extensions:

  • Common formats: jpg, jpeg, png, gif, svg, webp, bmp, tiff, tif, ico
  • RAW formats: cr2, raw
  • Professional formats: psd, ai, eps, dxf, xcf
  • Legacy formats: pcx, tga, xbm, xpm
  • And many more: Complete list includes 100+ image formats and extensions

Usage Example:

import { isImageUrl } from "@udecode/plate-media";

const checkUrl = (url: string) => {
  if (isImageUrl(url)) {
    // Handle as image
    insertImage(editor, url);
  } else {
    // Handle as regular link
    insertLink(editor, url);
  }
};

checkUrl("https://example.com/photo.jpg"); // true
checkUrl("https://example.com/document.pdf"); // false

React Integration

React-specific image functionality including components, hooks, and state management.

Image Preview System

Advanced image preview functionality with zoom, navigation, and keyboard controls.

Image Preview Store

/**
 * Zustand store managing image preview state across the application
 */
interface ImagePreviewStore {
  // State
  currentPreview: PreviewItem | null;
  previewList: PreviewItem[];
  openEditorId: string | null;
  scale: number;
  translate: { x: number; y: number };
  isEditingScale: boolean;
  boundingClientRect: DOMRect | null;
  
  // Actions
  close(): void;
  
  // Selectors
  isOpen(editorId: string): boolean;
}

interface PreviewItem {
  id: string;
  url: string;
  element: TMediaElement;
}

Open Image Preview

/**
 * Opens image preview overlay for the specified image element
 * @param editor - Slate editor instance
 * @param element - Media element to preview
 */
function openImagePreview(editor: SlateEditor, element: TMediaElement): void;

Image Preview Hook

/**
 * Complete image preview functionality with controls and keyboard shortcuts
 * @param options - Configuration options
 * @returns Complete preview control props and handlers
 */
function useImagePreview(options: { 
  scrollSpeed: number 
}): ImagePreviewControls;

interface ImagePreviewControls {
  // Navigation
  canGoNext: boolean;
  canGoPrevious: boolean;
  goNext: () => void;
  goPrevious: () => void;
  
  // Zoom controls
  canZoomIn: boolean;
  canZoomOut: boolean;
  zoomIn: () => void;
  zoomOut: () => void;
  
  // Pan controls
  onMouseDown: (event: MouseEvent) => void;
  onWheel: (event: WheelEvent) => void;
  
  // Keyboard shortcuts
  onKeyDown: (event: KeyboardEvent) => void;
  
  // State
  scale: number;
  translate: { x: number; y: number };
}

Usage Example:

import { useImagePreview, openImagePreview } from "@udecode/plate-media/react";

const ImagePreviewComponent = () => {
  const controls = useImagePreview({ scrollSpeed: 0.1 });
  
  return (
    <div 
      onKeyDown={controls.onKeyDown}
      onWheel={controls.onWheel}
      onMouseDown={controls.onMouseDown}
      tabIndex={0}
    >
      <div>
        <button 
          onClick={controls.zoomIn} 
          disabled={!controls.canZoomIn}
        >
          Zoom In
        </button>
        <button 
          onClick={controls.zoomOut} 
          disabled={!controls.canZoomOut}
        >
          Zoom Out  
        </button>
      </div>
      
      <div>
        <button 
          onClick={controls.goPrevious} 
          disabled={!controls.canGoPrevious}
        >
          Previous
        </button>
        <button 
          onClick={controls.goNext} 
          disabled={!controls.canGoNext}
        >
          Next
        </button>
      </div>
      
      <div 
        style={{
          transform: `scale(${controls.scale}) translate(${controls.translate.x}px, ${controls.translate.y}px)`
        }}
      >
        {/* Image content */}
      </div>
    </div>
  );
};

Zoom Functionality

Dedicated zoom controls for image preview.

/**
 * Provides zoom in/out functionality with predefined zoom levels
 * @returns Zoom control functions
 */
function useZoom(): {
  zoomIn: () => void;
  zoomOut: () => void;
};

Zoom Levels: 0, 0.5, 1, 1.5, 2

Image Components

React primitive components for image rendering and interaction.

Image Component

/**
 * Primitive image component with drag and preview functionality
 * Provides double-click to open preview and draggable behavior
 */
const Image: React.ComponentType;

/**
 * Hook providing image component props and handlers
 * @returns Props for image element including drag and preview handlers
 */
function useImage(): {
  onDoubleClick: () => void;
  draggable: boolean;
  onDragStart: (event: DragEvent) => void;
};

Preview Image Component

/**
 * Primitive component for preview overlay image
 * Handles click-to-zoom and transform styles
 */
const PreviewImage: React.ComponentType;

/**
 * Hook providing preview image props with zoom and transform functionality
 * @returns Props for preview image including click handlers and styles
 */
function usePreviewImage(): {
  onClick: () => void;
  style: CSSProperties;
  cursor: string;
};

Scale Input Hook

/**
 * Hook for scale input management in preview mode
 * Provides auto-focus, validation, and keyboard handling
 * @returns Input props for scale editing
 */
function useScaleInput(): {
  value: string;
  onChange: (event: ChangeEvent<HTMLInputElement>) => void;
  onKeyDown: (event: KeyboardEvent) => void;
  onBlur: () => void;
  autoFocus: boolean;
};

Configuration

Image-Specific Configuration

Extended configuration options specific to image handling.

interface ImageConfig extends MediaPluginOptions {
  /** Disable automatic image insertion when pasting URLs */
  disableEmbedInsert?: boolean;
  /** Disable image upload functionality */
  disableUploadInsert?: boolean;
  /** Upload function for handling image files */
  uploadImage?: (dataUrl: ArrayBuffer | string) => Promise<string> | string;
}

Usage Example:

import { BaseImagePlugin } from "@udecode/plate-media";

const imageConfig: ImageConfig = {
  disableEmbedInsert: false,
  disableUploadInsert: false,
  uploadImage: async (file) => {
    const formData = new FormData();
    formData.append('image', file);
    
    const response = await fetch('/api/upload-image', {
      method: 'POST',
      body: formData
    });
    
    const result = await response.json();
    return result.url;
  },
  isUrl: (text) => /^https?:\/\/.+\.(jpg|jpeg|png|gif|webp)$/i.test(text),
  transformUrl: (url) => `${url}?width=800&quality=85`
};

const editor = createSlateEditor({
  plugins: [
    BaseImagePlugin.configure({
      options: imageConfig
    })
  ]
});

Install with Tessl CLI

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

docs

base-plugins.md

image.md

index.md

media-embeds.md

react-components.md

upload-system.md

tile.json