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

react-components.mddocs/

React Components

Complete set of React components for rendering images with captions, resizing handles, and interactive features.

Capabilities

Image Component Namespace

Main component namespace containing all image-related React components.

/**
 * Image component namespace containing all image-related components
 * Provides a structured way to access different image rendering components
 */
const Image: {
  /** Root image element component */
  Root: React.ComponentType<any>;
  /** Image caption component */
  Caption: React.ComponentType<ImageCaptionProps>;
  /** Image display component */
  Img: React.ComponentType<any>;
  /** Resizable image wrapper component */
  Resizable: React.ComponentType<ImageResizableProps>;
  /** Caption textarea component */
  CaptionTextarea: React.ComponentType<ImageCaptionTextareaProps>;
};

Usage Examples:

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

// Complete image component with all features
function MyImageRenderer() {
  return (
    <Image.Root>
      <Image.Resizable align="center">
        <Image.Img />
      </Image.Resizable>
      <Image.Caption>
        <Image.CaptionTextarea />
      </Image.Caption>
    </Image.Root>
  );
}

// Minimal image component
function SimpleImageRenderer() {
  return (
    <Image.Root>
      <Image.Img />
    </Image.Root>
  );
}

Image Root Component

Base root component for image elements created using Plate's element component factory.

/**
 * Root image element component created via createPlateElementComponent
 * Serves as the container for all image-related content and components
 */
const ImageRoot: React.ComponentType<any>;

Image Caption Component

Conditionally rendered caption component that displays when caption content exists or when the image is selected in edit mode.

/**
 * Image caption component that conditionally renders based on content and editor state
 * Automatically hides when no caption exists and image is not selected in read-only mode
 */
const ImageCaption: React.ComponentType<ImageCaptionProps>;

interface ImageCaptionProps extends HTMLPropsAs<'figcaption'> {
  /** Override read-only state (inherits from editor if not specified) */
  readOnly?: boolean;
}

Caption Display Logic:

  • Shows when caption has content
  • Shows when image is selected in edit mode (even without content)
  • Hides when no content and in read-only mode or image not selected

Usage Examples:

import { Image, ImageCaptionProps } from "@udecode/plate-image";

// Basic caption
function BasicCaption() {
  return <Image.Caption />;
}

// Caption with custom styling
function StyledCaption() {
  return (
    <Image.Caption 
      className="custom-caption"
      style={{ fontStyle: 'italic', textAlign: 'center' }}
    />
  );
}

// Read-only caption
function ReadOnlyCaption() {
  return <Image.Caption readOnly={true} />;
}

Image Display Component

Component that renders the actual image element with proper source and accessibility attributes.

/**
 * Image display component that renders the actual img element
 * Automatically sets src from element URL and alt from caption
 */
const ImageImg: React.ComponentType<any>;

Automatic Behavior:

  • Sets src attribute from image element's url property
  • Sets alt attribute from caption text content
  • Enables dragging with draggable={true}
  • Accepts additional HTML img attributes as props

Usage Examples:

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

// Basic image
function BasicImage() {
  return <Image.Img />;
}

// Image with custom attributes
function CustomImage() {
  return (
    <Image.Img 
      className="custom-image"
      loading="lazy"
      onLoad={() => console.log('Image loaded')}
    />
  );
}

Resizable Image Component

Wrapper component providing image resizing functionality using the re-resizable library.

/**
 * Resizable image wrapper component with alignment and interaction controls
 * Provides drag handles for resizing images while maintaining aspect ratio
 */
const ImageResizable: React.ComponentType<ImageResizableProps>;

interface ImageResizableProps extends Omit<ResizableProps, 'as'>, AsProps<'div'> {
  /** Image alignment affecting resize handle placement */
  align?: 'left' | 'center' | 'right';
  /** Override read-only state (disables resizing when true) */
  readOnly?: boolean;
}

Resizing Behavior:

  • Left alignment: Resize handle on right side only
  • Center alignment: Resize handles on both sides (default)
  • Right alignment: Resize handle on left side only
  • Aspect ratio: Automatically maintained during resize
  • Minimum width: 92 pixels
  • Maximum width: 100% of container

Usage Examples:

import { Image, ImageResizableProps } from "@udecode/plate-image";

// Center-aligned resizable image (default)
function CenterResizableImage() {
  return (
    <Image.Resizable>
      <Image.Img />
    </Image.Resizable>
  );
}

// Left-aligned resizable image
function LeftResizableImage() {
  return (
    <Image.Resizable align="left">
      <Image.Img />
    </Image.Resizable>
  );
}

// Read-only image (no resize handles)
function ReadOnlyImage() {
  return (
    <Image.Resizable readOnly={true}>
      <Image.Img />
    </Image.Resizable>
  );
}

// Custom resize constraints
function CustomResizableImage() {
  return (
    <Image.Resizable
      minWidth={200}
      maxWidth={800}
      onResize={(e, direction, ref) => {
        console.log('Resizing to:', ref.offsetWidth);
      }}
    >
      <Image.Img />
    </Image.Resizable>
  );
}

Caption Textarea Component

Auto-resizing textarea component for editing image captions with keyboard navigation support.

/**
 * Auto-resizing textarea component for caption editing
 * Handles keyboard navigation and integrates with image focus management
 */
const ImageCaptionTextarea: React.ComponentType<ImageCaptionTextareaProps>;

interface ImageCaptionTextareaProps 
  extends TextareaAutosizeProps,
    RefAttributes<HTMLTextAreaElement>,
    AsProps<'textarea'> {}

Features:

  • Auto-resizes height based on content
  • Keyboard navigation (up/down arrows)
  • Focus management integration
  • Real-time caption updates
  • Read-only state inheritance

Keyboard Behavior:

  • Up arrow: Focus the image element above
  • Down arrow: Move to next block after image

Usage Examples:

import { Image, ImageCaptionTextareaProps } from "@udecode/plate-image";

// Basic caption textarea
function BasicCaptionTextarea() {
  return <Image.CaptionTextarea />;
}

// Styled caption textarea
function StyledCaptionTextarea() {
  return (
    <Image.CaptionTextarea 
      placeholder="Enter image caption..."
      className="caption-input"
      style={{ 
        fontFamily: 'serif',
        fontSize: '14px',
        textAlign: 'center'
      }}
    />
  );
}

// Caption with event handlers
function InteractiveCaptionTextarea() {
  return (
    <Image.CaptionTextarea 
      onFocus={() => console.log('Caption focused')}
      onBlur={() => console.log('Caption blurred')}
      onChange={(e) => console.log('Caption changed:', e.target.value)}
    />
  );
}

Auto-resize Textarea Base Component

Base textarea component with auto-resize functionality, used internally by the caption textarea.

/**
 * Auto-sizing textarea component wrapper around react-textarea-autosize
 * Handles re-rendering issues and provides consistent auto-resize behavior
 */
const TextareaAutosize: React.ComponentType<TextareaAutosizeProps>;

Internal Implementation Note:

  • Addresses re-rendering issues with react-textarea-autosize
  • Uses useLayoutEffect to ensure proper rendering timing
  • Can be used independently for other auto-resize textarea needs

Component Hook Functions

Advanced hook functions for customizing component behavior and accessing internal component state.

/**
 * Image caption hook providing style properties and behavior configuration
 * @param props - ImageCaptionProps configuration
 * @returns HTMLPropsAs<'figcaption'> with computed properties including width styling
 */
function useImageCaption(props?: ImageCaptionProps): HTMLPropsAs<'figcaption'>;

/**
 * Image caption state hook providing caption content and interaction state
 * @param props - ImageCaptionProps configuration
 * @returns Object containing captionString, selected state, and readOnly state
 */
function useImageCaptionState(props: ImageCaptionProps): {
  captionString: string;
  selected: boolean;
  readOnly: boolean;
};

/**
 * Image resizable hook providing resizable configuration and behavior
 * @param props - ImageResizableProps with alignment and resizing options
 * @returns ResizableProps configured for the image element with proper constraints
 */
function useImageResizable(props?: ImageResizableProps): ResizableProps;

Hook Usage Examples:

import { 
  useImageCaption, 
  useImageCaptionState, 
  useImageResizable,
  ImageCaptionProps,
  ImageResizableProps 
} from "@udecode/plate-image";

// Custom caption component using hooks
function CustomImageCaption(props: ImageCaptionProps) {
  const htmlProps = useImageCaption(props);
  const { captionString, selected, readOnly } = useImageCaptionState(props);
  
  // Custom rendering logic
  if (!captionString.length && (readOnly || !selected)) {
    return null;
  }
  
  return <figcaption {...htmlProps}>Custom caption: {captionString}</figcaption>;
}

// Custom resizable component using hooks
function CustomImageResizable(props: ImageResizableProps) {
  const resizableProps = useImageResizable({
    align: 'center',
    minWidth: 150,
    ...props
  });
  
  return <Resizable {...resizableProps} />;
}

Component Composition Patterns

Complete Image with All Features

function FullFeaturedImage() {
  return (
    <Image.Root>
      <Image.Resizable align="center">
        <Image.Img />
      </Image.Resizable>
      <Image.Caption>
        <Image.CaptionTextarea placeholder="Add a caption..." />
      </Image.Caption>
    </Image.Root>
  );
}

Read-Only Image Display

function ReadOnlyImageDisplay() {
  return (
    <Image.Root>
      <Image.Resizable readOnly={true}>
        <Image.Img />
      </Image.Resizable>
      <Image.Caption readOnly={true} />
    </Image.Root>
  );
}

Minimal Image Component

function MinimalImage() {
  return (
    <Image.Root>
      <Image.Img />
    </Image.Root>
  );
}

Integration with Plate Editor

These components are designed to be used with Plate's rendering system:

import { createPlateEditor } from "@udecode/plate-core";
import { createImagePlugin, Image, ELEMENT_IMAGE } from "@udecode/plate-image";

const editor = createPlateEditor({
  plugins: [
    createImagePlugin()
  ],
  components: {
    [ELEMENT_IMAGE]: FullFeaturedImage, // Use your composed component
  }
});

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