@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/dmdmQuick 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:
- Top Bar: Contains the title and close button
- Side Panel: Includes tabs for:
- Views: Select different angles of the merchandise
- Add: Add text or upload images
- Layers: Manage and reorder design elements
- Canvas: The interactive design area showing the merchandise and editable elements
- Bottom Bar: Contains actions like "Clear View" and "Export Design"
Export Functionality
The design tool can export designs in two formats:
- Design Only: Transparent PNG containing just the design elements
- 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
