npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@skchawala/extended-editorjs-image

v1.0.2

Published

EditorJS Image tool that handles Google Docs / text/html clipboard image pastes and uploads them like the Image tool.

Readme

Extended EditorJS Image Tool

🖼️ An EditorJS block tool for pasting and uploading images — handles Google Docs clipboard images, supports file uploads, and provides a clean paste-only input interface.

📌 Note: This tool is specifically designed for pasting images from the internet and Google Docs. Both uploadByFile and uploadByUrl are supported. Additional features (like direct file selection, etc.) will be added in future releases.

Features

  • 📋 Paste-only input — Clean interface that only accepts paste events
  • 🖼️ Image preview — Shows uploaded images with proper styling
  • ☁️ File upload support — Upload images via uploadByFile method
  • 🔗 URL upload support — Upload images by URL via uploadByUrl method
  • 📎 Google Docs support — Specifically handles images pasted from Google Docs and internet
  • Upload status — Visual feedback during upload process
  • 🎨 Configurable — Customize uploaders, placeholders, and more
  • 🪶 Lightweight — No extra dependencies

Installation

Install via npm or yarn:

npm install @skchawala/extended-editorjs-image

or

yarn add @skchawala/extended-editorjs-image

🚀 Usage

Basic Usage

import EditorJS from "@editorjs/editorjs";
import ExtendedEditorJsImage from "@skchawala/extended-editorjs-image";

const editor = new EditorJS({
  holder: "editorjs",
  tools: {
    extendedImage: {
      class: ExtendedEditorJsImage,
      config: {
        placeholder: "Paste image here...",
      },
    },
  },
});

With Custom Uploader

You need to provide an Uploader object with uploadByFile and/or uploadByUrl methods:

import EditorJS from "@editorjs/editorjs";
import ExtendedEditorJsImage from "@skchawala/extended-editorjs-image";

const customUploader = {
  uploadByFile: async (file) => {
    const formData = new FormData();
    formData.append("image", file);

    const response = await fetch("https://api.example.com/upload", {
      method: "POST",
      headers: {
        Authorization: "Bearer your-token",
      },
      body: formData,
    });

    const data = await response.json();

    return {
      success: response.ok ? 1 : 0,
      file: data.url ? { url: data.url } : undefined,
      error: response.ok ? undefined : "Upload failed",
    };
  },
  // uploadByUrl is optional - recommended for handling pasted image URLs
  uploadByUrl: async (url) => {
    const response = await fetch("https://api.example.com/upload-url", {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: "Bearer your-token",
      },
      body: JSON.stringify({ url }),
    });

    const data = await response.json();

    return {
      success: response.ok ? 1 : 0,
      file: data.url ? { url: data.url } : undefined,
      error: response.ok ? undefined : "Upload failed",
    };
  },
};

const editor = new EditorJS({
  holder: "editorjs",
  tools: {
    image: {
      class: ExtendedEditorJsImage,
      config: {
        uploader: customUploader,
        placeholder: "Paste image here...",
      },
    },
  },
});

⚙️ Configuration Options

| Option | Type | Default | Description | | -------------------- | --------------------------------------------------------------- | ----------------------- | ---------------------------------------------------------------- | | toolboxTitle | string | "Paste Image" | Title displayed in the EditorJS toolbox | | placeholder | string | "Paste image here..." | Placeholder text for the input box | | uploader | Uploader | undefined | Uploader object with uploadByFile and/or uploadByUrl methods | | captionPlaceholder | string | "Caption" | Placeholder for caption input (if caption feature is enabled) | | buttonContent | string | undefined | HTML content to override the "Select file" button | | actions | Array<Action> | undefined | Custom actions to show in the tool's settings menu | | features | { border?: boolean, background?: boolean, caption?: boolean } | undefined | Enable/disable additional features | | maxSizeBytes | number | undefined | Maximum file size in bytes |

Uploader Interface

You must provide an Uploader object that implements the following interface:

type Uploader = {
  uploadByFile?: (file: File) => Promise<UploadResult>;
  uploadByUrl?: (url: string) => Promise<UploadResult>;
};

type UploadResult = {
  success: 1 | 0;
  file?: { url: string };
  error?: string;
};

Important Notes:

  • uploadByFile is required for file uploads (handles pasted image files)
  • uploadByUrl is optional but recommended for URL-based uploads (handles pasted image URLs)
  • Both methods should return a UploadResult object
  • The success field should be 1 for success or 0 for failure
  • The file.url should contain the uploaded image URL on success
  • You can provide both methods or just uploadByFile depending on your needs

Action Interface

type Action = {
  name: string;
  icon: string;
  title: string;
  action: () => void;
};

🛠️ Output Data

The tool saves data in the following format:

{
  "type": "extendedImage",
  "data": {
    "file": {
      "url": "https://example.com/uploaded-image.jpg"
    },
    "caption": ""
  }
}

📝 Supported Paste Formats

The tool handles various paste formats:

  • Image files — Direct image files from clipboard
  • Data URLs — Base64 encoded images (data:image/...)
  • HTML images — Images embedded in HTML (e.g., from Google Docs)
  • Image URLs — Plain text URLs pointing to images

🎯 Features

Paste-Only Input

The input box is read-only and only accepts paste events. Users can paste images using:

  • Ctrl+V / Cmd+V
  • Shift+Insert

Upload Status

Visual feedback is shown during upload:

  • Loading spinner in the input box
  • Upload status overlay on image preview
  • Empty image block state during upload

Image Preview

Once an image is uploaded and file.url is available, the tool displays a preview with:

  • Responsive width (100%)
  • Auto height to maintain aspect ratio
  • Clean, modern styling

📜 Changelog

You can find the full list of changes in the CHANGELOG.md.


🤝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.


📄 License

MIT © Satish Kumar


🔗 Links