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

@droplinked-dev/dmdm

v1.1.0

Published

A React component for creating designs on merchandise

Readme

@droplinked-dev/dmdm

A powerful, customizable merchandise design tool that allows users to create and personalize product designs with text and images. This React component provides a complete design experience with multiple view angles, layer management, and design export capabilities.

Features

  • 🎨 Interactive design canvas with intuitive controls
  • 📝 Add and edit text with font customization
  • 🖼️ Upload and position images
  • 👕 Support for multiple product views (front, back, etc.)
  • 📋 Layer management with z-index control
  • 📲 Responsive design (mobile and desktop friendly)
  • 📦 Export designs as PNG (with or without background)
  • 🔄 Context-based state management for efficient updates
  • 📏 Precise positioning of design elements
  • 🧩 TypeScript support with comprehensive type definitions

Installation

# npm
npm install @droplinked-dev/dmdm

# yarn
yarn add @droplinked-dev/dmdm

# pnpm
pnpm add @droplinked-dev/dmdm

Quick Start

import React, { useState } from 'react';
import { DMDM } from '@droplinked-dev/dmdm';
import '@droplinked-dev/dmdm/dist/index.css';

function App() {
  const [isOpen, setIsOpen] = useState(false);
  
  return (
    <div>
      <button onClick={() => setIsOpen(true)}>
        Customize Product
      </button>
      
      <DMDM 
        id="product-123" 
        isOpen={isOpen} 
        onClose={() => setIsOpen(false)} 
      />
    </div>
  );
}

API Reference

DMDM Component

The main component that wraps the design tool with the necessary context providers.

Props

| Prop | Type | Required | Description | |------|------|----------|-------------| | id | string | Yes | Unique identifier for the merchandise item to be designed | | isOpen | boolean | Yes | Controls whether the design modal is visible | | onClose | () => void | Yes | Callback function called when the user closes the design tool |

Required Backend API

For the design tool to function properly, you need to implement a backend API that provides merchandise data. The main function required is:

getMerchById(id: string): Promise<MerchItem>

This function should fetch merchandise information from your backend based on the provided ID. You should implement this in your application to match the expected return type.

Example implementation:

// lib/api.ts
import type { MerchItem } from '@droplinked-dev/dmdm';

export async function getMerchById(id: string): Promise<MerchItem> {
  const response = await fetch(`/api/merchandise/${id}`);
  
  if (!response.ok) {
    throw new Error('Failed to fetch merchandise');
  }
  
  return await response.json();
}

Type Definitions

The package exports the following TypeScript types:

Design Elements

// Base element with common properties
interface BaseDesignElement {
  id: string;
  type: string;
  x: number;
  y: number;
  width: number;
  height: number;
  rotation: number;
  selected?: boolean;
}

// Text element with specific text properties
interface TextElement extends BaseDesignElement {
  type: "text";
  content: string;
  fontSize: number;
  fontFamily: string;
}

// Image element
interface ImageElement extends BaseDesignElement {
  type: "image";
  content: string; // URL or base64 string
}

// Union type for all design elements
type DesignElement = TextElement | ImageElement;

Merchandise Types

// View angle constants
type ViewAngle = "front" | "back" | "left" | "right" | string;

// Supported merchandise types
type MerchType = "tshirt" | "hoodie" | "mug" | "hat" | string;

// Currency options
type Currency = "USD" | "EUR" | "GBP" | string;

// Defines the printable area on a merchandise view
interface PrintableArea {
  x: number;
  y: number;
  width: number;
  height: number;
}

// Configuration for each merchandise view
interface ViewConfig {
  angle: ViewAngle;
  imageUrl: string;
  printableArea: PrintableArea;
}

// Complete merchandise item definition
interface MerchItem {
  id: string;
  name: string;
  type: MerchType;
  price?: number;
  currency?: Currency;
  views: ViewConfig[];
}

Required Data Format

Your backend API should return merchandise data in the following format:

{
  "id": "tshirt-001",
  "name": "Classic T-Shirt",
  "type": "tshirt",
  "price": 24.99,
  "currency": "USD",
  "views": [
    {
      "angle": "front",
      "imageUrl": "/images/tshirt-front.png",
      "printableArea": {
        "x": 180,
        "y": 100,
        "width": 200,
        "height": 300
      }
    },
    {
      "angle": "back",
      "imageUrl": "/images/tshirt-back.png",
      "printableArea": {
        "x": 180,
        "y": 100,
        "width": 200,
        "height": 300
      }
    }
  ]
}

Implementation Examples

Basic Implementation

import React, { useState } from 'react';
import { DMDM } from '@droplinked-dev/dmdm';
import '@droplinked-dev/dmdm/dist/index.css';

function ProductPage() {
  const [isDesignOpen, setIsDesignOpen] = useState(false);
  
  return (
    <div className="product-page">
      <h1>Custom T-Shirt</h1>
      <button 
        onClick={() => setIsDesignOpen(true)}
        className="customize-button"
      >
        Customize Design
      </button>
      
      <DMDM 
        id="tshirt-001" 
        isOpen={isDesignOpen} 
        onClose={() => setIsDesignOpen(false)} 
      />
    </div>
  );
}

E-commerce Integration

import React, { useState } from 'react';
import { DMDM } from '@droplinked-dev/dmdm';
import { addToCart } from './cart-service';

function ProductWithCart() {
  const [isDesignOpen, setIsDesignOpen] = useState(false);
  const [currentDesign, setCurrentDesign] = useState(null);
  
  const handleAddToCart = () => {
    // Add the product with design data to cart
    addToCart({
      productId: 'tshirt-001',
      designData: currentDesign,
      quantity: 1
    });
  };
  
  return (
    <div>
      <button onClick={() => setIsDesignOpen(true)}>
        Customize
      </button>
      
      <button onClick={handleAddToCart} disabled={!currentDesign}>
        Add to Cart
      </button>
      
      <DMDM 
        id="tshirt-001" 
        isOpen={isDesignOpen} 
        onClose={() => {
          // Get current design data before closing
          // This would require extending the component
          setIsDesignOpen(false);
        }} 
      />
    </div>
  );
}

User Interface Overview

The design tool provides a comprehensive UI with the following sections:

  1. Top Bar: Contains the title and close button
  2. Side Panel: Includes tabs for:
    • Views: Select different angles of the merchandise
    • Add: Add text or upload images
    • Layers: Manage and reorder design elements
  3. Canvas: The interactive design area showing the merchandise and editable elements
  4. Bottom Bar: Contains actions like "Clear View" and "Export Design"

Export Functionality

The design tool can export designs in two formats:

  1. Design Only: Transparent PNG containing just the design elements
  2. Full Design: PNG with the design elements on the merchandise background

All exports are packaged into a ZIP file with organized filenames based on the merchandise name and view angles.

Mobile Responsiveness

The design tool is fully responsive:

  • On desktop, it shows a side panel alongside the canvas
  • On mobile, the side panel collapses to maximize the canvas area
  • A toggle button allows users to show/hide the side panel on mobile

Performance Considerations

  • The tool uses React Context for efficient state management
  • Components use memoization to prevent unnecessary re-renders
  • Large images are properly scaled for optimal performance
  • Element selection updates are optimized to only affect relevant state

Browser Compatibility

The design tool has been tested and works on:

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

Dependencies

The design tool has minimal external dependencies:

  • React 16.8+ (for Hooks support)
  • html-to-image (for exporting designs)
  • JSZip (for creating design export packages)

License

MIT License

Support

For issues, feature requests, or questions, please open an issue on the repository or contact [email protected].


Made with ❤️ by droplinked