@snakeroads-soft/pdf-editor
Framework-agnostic visual PDF report designer and jsPDF compiler in pure TypeScript with Angular, React, Vue, and Vanilla JS support.
2,033
| Install | |
|---|---|
npm install @snakeroads-soft/pdf-editor@1.0.0 |
|
| Latest Version: | 1.0.0 |
| License: | MIT |
| Last Updated: | Oct 12, 2026 |
| Links: | npm |
Maintainer: eliasdominguez
@snakeroads-soft/pdf-editor 🚀
Framework-Agnostic, High-Performance PDF Studio & Editor for TypeScript, Angular, React, Vue, Svelte, and Vanilla JS.
A modern, glassmorphism-styled, plug-and-play PDF designer and compilation engine built with 100% pure TypeScript and jsPDF.
✨ Features
- 🌐 Framework-Agnostic: Zero framework lock-in. Works as a Web Component
<pdf-studio>, a JavaScript classnew PdfStudio(), or an Angular component/service. - 📄 Multi-Format & Multi-Orientation: Native A4, Letter, Legal, A3, A5 with portrait and landscape modes.
- 📊 Decoupled Dynamic Data Tables & Lists:
- Pass runtime JSON arrays (
datasets: { estudiantes: [...], productos: [...] }) from code without modifying template design. - One-click auto-mapping (
🪄 Auto-Mapear Columnas) of object keys to table columns with balanced 100% widths. #indexvirtual field support for automatic 1-based row numbering.- Interactive table column
% widthdrag-resizing and inspector sliders. - Column visibility toggles and alignment controls.
- Pass runtime JSON arrays (
- 🌊 Smart Dynamic Flow & Multi-Page Interference Engine:
- Automatically shifts elements positioned below multi-page tables or long markdown blocks down to avoid overlaps.
- Multi-column spatial interference detection (only displaces elements sharing horizontal X-coordinate boundaries).
- 📝 Multi-Page Markdown Auto-Breaking:
- Full GitHub-flavored markdown with bold, headers, lists, code, and tables.
- Auto-Split Across Pages: Automatically splits long markdown text across multiple PDF pages when it exceeds page boundaries.
- 🧩 Dynamic Variable Engine:
- Auto-discovery of
{{variable_name}}and{{dataset.length}}tokens across text, tables, and lists. - Variable chip injector in toolbox & inspector.
- Live preview and batch compilation with dynamic runtime data.
- Auto-discovery of
- 📐 Millimeter Precision Workspace:
- Real-time horizontal and vertical mm rulers.
- 8-direction resize handles and 360° rotation handle.
- Grid snap system with configurable millimeter step.
- Backspace-protected deletion (only
Deletekey deletes elements to prevent accidental removal while typing).
- ☁️ Storage & Cloud Ready: Local Storage, REST API, Azure Blob Storage, and AWS S3 integration.
- 🎨 Built-in Business Templates: Modern Invoices, Achievement Certificates, Reports, and Shipping Labels.
📦 Installation
npm install @snakeroads-soft/pdf-editor jspdf jspdf-autotable marked dompurify
🅰️ Angular Integration
1. In Standalone Components (Angular 14+)
import { Component, ElementRef, ViewChild, AfterViewInit, OnDestroy } from '@angular/core';
import { PdfStudio, DocumentSchema } from '@snakeroads-soft/pdf-editor';
import '@snakeroads-soft/pdf-editor/style.css';
@Component({
selector: 'app-pdf-designer',
standalone: true,
template: `
<div class="editor-container" #editorContainer style="width: 100%; height: 90vh;"></div>
`
})
export class PdfDesignerComponent implements AfterViewInit, OnDestroy {
@ViewChild('editorContainer', { static: true }) editorContainer!: ElementRef<HTMLElement>;
private studio!: PdfStudio;
ngAfterViewInit(): void {
this.studio = new PdfStudio({
container: this.editorContainer.nativeElement,
variables: {
company_name: 'Acme Corp',
invoice_total: '$1,450.00'
},
onChange: (schema: DocumentSchema) => {
console.log('Schema updated:', schema);
},
onSave: (schema: DocumentSchema) => {
console.log('Document saved:', schema);
}
});
}
exportPdf(): void {
this.studio.downloadPdf('my-document.pdf');
}
ngOnDestroy(): void {
this.studio?.destroy();
}
}
2. Using the Web Component <pdf-studio> in Angular
Add CUSTOM_ELEMENTS_SCHEMA to your component or module:
import { Component, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
import '@snakeroads-soft/pdf-editor';
import '@snakeroads-soft/pdf-editor/style.css';
@Component({
selector: 'app-pdf-page',
standalone: true,
schemas: [CUSTOM_ELEMENTS_SCHEMA],
template: `
<pdf-studio
style="width: 100%; height: 100vh; display: block;"
(schemaChange)="onSchemaChange($event)"
(save)="onSave($event)"
></pdf-studio>
`
})
export class PdfPageComponent {
onSchemaChange(event: any) {
console.log('Schema:', event.detail);
}
onSave(event: any) {
console.log('Save:', event.detail);
}
}
3. Headless PDF Generation in Angular (Without UI)
Use SnakeroadsPdfService or JsPdfEngine directly to render PDFs in background services:
import { Injectable } from '@angular/core';
import { SnakeroadsPdfService, DocumentSchema } from '@snakeroads-soft/pdf-editor';
@Injectable({ providedIn: 'root' })
export class InvoiceService {
private pdfService = new SnakeroadsPdfService();
async downloadInvoice(schema: DocumentSchema, invoiceData: any) {
await this.pdfService.downloadPdf(schema, invoiceData, 'invoice.pdf');
}
async getInvoiceBlob(schema: DocumentSchema, invoiceData: any): Promise<Blob> {
return await this.pdfService.generatePdf(schema, invoiceData);
}
}
⚛️ React Integration
import React, { useEffect, useRef } from 'react';
import { PdfStudio } from '@snakeroads-soft/pdf-editor';
import '@snakeroads-soft/pdf-editor/style.css';
export const PdfEditor: React.FC = () => {
const containerRef = useRef<HTMLDivElement>(null);
const studioRef = useRef<PdfStudio | null>(null);
useEffect(() => {
if (containerRef.current) {
studioRef.current = new PdfStudio({
container: containerRef.current,
onChange: (schema) => console.log('Schema:', schema),
});
}
return () => {
studioRef.current?.destroy();
};
}, []);
return <div ref={containerRef} style={{ width: '100%', height: '100vh' }} />;
};
🟢 Vue 3 Integration
<template>
<div ref="editorContainer" style="width: 100%; height: 100vh;"></div>
</template>
<script setup lang="ts">
import { ref, onMounted, onUnmounted } from 'vue';
import { PdfStudio } from '@snakeroads-soft/pdf-editor';
import '@snakeroads-soft/pdf-editor/style.css';
const editorContainer = ref<HTMLElement | null>(null);
let studio: PdfStudio | null = null;
onMounted(() => {
if (editorContainer.value) {
studio = new PdfStudio({
container: editorContainer.value,
onChange: (schema) => console.log('Schema:', schema),
});
}
});
onUnmounted(() => {
studio?.destroy();
});
</script>
🍦 Vanilla TypeScript / JavaScript
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="stylesheet" href="node_modules/@snakeroads-soft/pdf-editor/dist/style.css" />
</head>
<body>
<div id="pdf-editor" style="width: 100vw; height: 100vh;"></div>
<script type="module">
import { PdfStudio } from './node_modules/@snakeroads-soft/pdf-editor/dist/index.mjs';
const studio = new PdfStudio({
container: '#pdf-editor',
variables: {
user_name: 'Arturo Schloss',
project: 'Cloud Infrastructure'
}
});
</script>
</body>
</html>
🛠️ API Reference
new PdfStudio(options)
| Option | Type | Description |
|---|---|---|
container |
HTMLElement | string |
DOM element or CSS selector to mount the studio into. |
schema |
DocumentSchema (optional) |
Initial document schema to load. |
variables |
Record<string, any> (optional) |
Key-value dictionary for {{variable}} interpolation. |
datasets |
Record<string, any[]> (optional) |
Named collections of dynamic JSON objects for tables and lists. |
storageConfig |
StorageConfig (optional) |
Storage provider config (local, rest, azure-blob, s3). |
onChange |
(schema: DocumentSchema) => void |
Triggered on every element change or layout modification. |
onSave |
(schema: DocumentSchema) => void |
Triggered when user clicks Save. |
onPdfGenerated |
(blob: Blob) => void |
Triggered when a PDF is compiled. |
Instance Methods
studio.getSchema(): DocumentSchemastudio.loadSchema(schema: DocumentSchema): voidstudio.setVariables(vars: Record<string, string>): voidstudio.getVariables(): Record<string, string>studio.setDatasets(datasets: Record<string, any[]>): voidstudio.setDataset(name: string, data: any[]): voidstudio.getDatasets(): Record<string, any[]>studio.exportPdfBlob(options?: GeneratePdfOptions): Promise<Blob>studio.downloadPdf(filename?: string, options?: GeneratePdfOptions): Promise<void>studio.save(): Promise<{ id: string; success: boolean }>studio.undo(): booleanstudio.redo(): booleanstudio.destroy(): void
Headless Engine (JspdfEngine)
import { JspdfEngine } from '@snakeroads-soft/pdf-editor';
const result = JspdfEngine.generatePdf(schema, {
variables: { empresa: 'Snakeroads' },
datasets: { estudiantes: dataArray }
});
console.log(result.blobUrl);
📄 License
MIT © Snakeroads Technologies
Related Packages
@mecorelabs/free-pdf-sdk
Free PDF SDK: an embeddable, white-label PDF viewer, annotator and editor for th...
207
0
Version History
| Version | Released | License |
|---|---|---|
| 1.0.0 | MIT |
Pre-releases (18)
| Version | Released | License |
|---|---|---|
| 1.0.0-beta.19 | MIT | |
| 1.0.0-beta.18 | MIT | |
| 1.0.0-beta.17 | MIT | |
| 1.0.0-beta.16 | MIT | |
| 1.0.0-beta.15 | MIT | |
| 1.0.0-beta.14 | MIT | |
| 1.0.0-beta.12 | MIT | |
| 1.0.0-beta.11 | MIT | |
| 1.0.0-beta.10 | MIT | |
| 1.0.0-beta.9 | MIT | |
| 1.0.0-beta.8 | MIT | |
| 1.0.0-beta.7 | MIT | |
| 1.0.0-beta.6 | MIT | |
| 1.0.0-beta.5 | MIT | |
| 1.0.0-beta.4 | MIT | |
| 1.0.0-beta.3 | MIT | |
| 1.0.0-beta.2 | MIT | |
| 1.0.0-beta.1 | MIT |