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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@molecule/app-image-crop-cropperjs

v1.0.1

Published

Cropper.js provider for @molecule/app-image-crop

Downloads

244

Readme

@molecule/app-image-crop-cropperjs

Auto-generated, AI-first package reference for the molecule.dev ecosystem. It is written to be read by coding agents as much as by people, and is generated from this package's source — edit src/index.ts JSDoc, not this file.

Cropper.js image-crop provider for @molecule/app-image-crop — a REAL implementation backed by cropperjs v1. createCropper({ src }) mounts a live Cropper on an image element and every instance method delegates to the corresponding cropperjs call, so getCroppedCanvas() returns the actual cropped <canvas> (call .toBlob() / .toDataURL() on it to export) — not a placeholder object.

Quick Start

import { provider } from '@molecule/app-image-crop-cropperjs'
import { setProvider, requireProvider } from '@molecule/app-image-crop'

setProvider(provider) // once, at app startup (bonds.ts)

const cropper = requireProvider().createCropper({ src: '/avatar.jpg', aspectRatio: 1 })
const canvas = cropper.getCroppedCanvas({ width: 200, height: 200 })
canvas.toBlob((blob) => uploadAvatar(blob), 'image/png')

Type

provider

Installation

npm install @molecule/app-image-crop-cropperjs @molecule/app-image-crop cropperjs
npm install -D @types/cropperjs

API

Interfaces

CropperjsConfig

Provider-level defaults applied to every cropper created by the provider.

These map onto cropperjs constructor options. Per-cropper CropperOptions (e.g. guides) take precedence over the matching field here.

interface CropperjsConfig {
  /**
   * Whether to show the dashed crop guide lines by default. Overridden per-cropper
   * by `CropperOptions.guides`. Defaults to `true`.
   */
  guides?: boolean

  /** Whether to render the checkerboard background behind the image. Defaults to `true`. */
  background?: boolean

  /**
   * cropperjs view mode (0-3) constraining the crop box relative to the canvas /
   * container. `1` restricts the crop box within the canvas. Defaults to `1`.
   */
  viewMode?: 0 | 1 | 2 | 3
}

Functions

createProvider(config)

Creates a Cropper.js-based image crop provider.

function createProvider(config?: CropperjsConfig): ImageCropProvider
  • config — Optional provider-level defaults (guides, background, viewMode).

Returns: A configured ImageCropProvider backed by real cropperjs instances.

Constants

provider

Default Cropper.js provider instance.

const provider: ImageCropProvider

Namespaces

Cropper

Core Interface

Implements @molecule/app-image-crop interface.

Bond Wiring

Setup function to register this provider with the core interface:

import { setProvider } from '@molecule/app-image-crop'
import { provider } from '@molecule/app-image-crop-cropperjs'

export function setupImageCropCropperjs(): void {
  setProvider(provider)
}

Injection Notes

Requirements

Peer dependencies:

  • @molecule/app-image-crop ^1.0.1

Runtime Dependencies

  • @molecule/app-image-crop

  • cropperjs

  • Import cropperjs's stylesheet yourself — this package does NOT: import 'cropperjs/dist/cropper.css'. Without it the crop box, handles, and drag guides render unstyled (an invisible/broken cropper), the same way Quill needs its theme CSS.

  • Browser-only. createCropper() calls document.createElement('img') and new Cropper(...); construct it in a client-only effect under SSR.

  • cropperjs initializes on the image's load event. Reading getCropData() or getCroppedCanvas() before the source has loaded returns empty/degenerate data — drive them after load, or set the region explicitly with setCropData() in natural-image coordinates first.

  • circular is a UI concern, not a pixel op. cropperjs has no circular pixel output; for a round avatar, style the crop box round in CSS (.cropper-view-box, .cropper-face { border-radius: 50% }) and draw the returned canvas into a rounded canvas before upload.

  • OutputOptions.quality applies at encode time, not to canvas generation — pass it to canvas.toBlob(cb, 'image/jpeg', quality) / toDataURL(type, quality).

  • Provider defaults (guides, background, viewMode) come from createProvider(config); per-cropper CropperOptions.guides wins over the config default. maxWidth/maxHeight are enforced on output (cropperjs has no max-crop-box constructor option).

  • Wire it with setProvider() from @molecule/app-image-crop or bond('image-crop', provider) from @molecule/app-bond — both route through the shared registry; requireProvider() throws until one has run.

E2E Tests

Integration checklist — drive the real UI (live preview, no mocks), adapt each item to this app's actual crop screen (avatar/photo upload, etc.), and check every box off one by one. A box you can't check is an integration bug to fix — not a skip. The cropper is headless, so verify the UI YOU rendered:

  • [ ] Opening the crop screen loads the source image (createCropper({ src })) and renders it with a visible crop-box overlay + drag handles drawn from getCropData() — not a blank or full-bleed image with no selection.
  • [ ] Dragging/resizing the crop box feeds the gesture into setCropData(), getCropData() reflects the new x/y/width/height, and the on-page preview (the getCroppedCanvas() output drawn into the page) updates to show ONLY the selected area, not the whole image.
  • [ ] With an aspect-ratio lock (e.g. aspectRatio: 1 for an avatar) the crop box stays that ratio while you resize — getCropData() width == height for 1:1 — and circular: true clips the preview to a circle.
  • [ ] rotate() / zoom() transform the source and the crop overlay follows: getCropData().rotate / scaleX change and the preview re-renders the transformed region — the selection isn't stranded on the old orientation.
  • [ ] Applying the crop OUTPUTS the cropped image: getCroppedCanvas() pixels match the selected region (not the full source), and downstream the SAVED file is the cropped Blob (canvas.toBlob → upload) — re-fetch and render the stored image and confirm it shows the crop, never the original.
  • [ ] Min/max crop size is enforced — you cannot drag the box smaller than minWidth/minHeight or larger than maxWidth/maxHeight.
  • [ ] Cancel/close discards without mutating the source: the original image is unchanged and no cropped result is saved.