@framv/docs 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +1 -0
- package/dist/bundle.esm.js +260 -0
- package/dist/bundle.iife.js +44048 -0
- package/dist/cdn.d.ts +5 -0
- package/dist/cdn.d.ts.map +1 -0
- package/dist/cdn.js +5 -0
- package/dist/cdn.js.map +1 -0
- package/dist/doc.d.ts +12 -0
- package/dist/doc.d.ts.map +1 -0
- package/dist/doc.js +15 -0
- package/dist/doc.js.map +1 -0
- package/dist/element.d.ts +28 -0
- package/dist/element.d.ts.map +1 -0
- package/dist/element.js +233 -0
- package/dist/element.js.map +1 -0
- package/dist/export.d.ts +2 -0
- package/dist/export.d.ts.map +1 -0
- package/dist/export.js +34 -0
- package/dist/export.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/package.json +40 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Mens Reversa
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
# DOCS\n\nPart of the Framv framework.\n
|
|
@@ -0,0 +1,260 @@
|
|
|
1
|
+
// src/export.ts
|
|
2
|
+
import { registerExporter } from "@framv/core";
|
|
3
|
+
registerExporter("pdf", async (element, settings, { freezer, renderer }) => {
|
|
4
|
+
const { jsPDF } = await import("jspdf");
|
|
5
|
+
const w = settings.width ?? (element instanceof SVGElement ? 800 : element.clientWidth || 800);
|
|
6
|
+
const h = settings.height ?? (element instanceof SVGElement ? 600 : element.clientHeight || 600);
|
|
7
|
+
const orientation = w > h ? "l" : "p";
|
|
8
|
+
const pdf = new jsPDF({
|
|
9
|
+
orientation,
|
|
10
|
+
unit: "px",
|
|
11
|
+
format: [w, h]
|
|
12
|
+
});
|
|
13
|
+
if (!(element instanceof SVGElement)) {
|
|
14
|
+
await pdf.html(element, {
|
|
15
|
+
x: 0,
|
|
16
|
+
y: 0,
|
|
17
|
+
width: w,
|
|
18
|
+
windowWidth: w
|
|
19
|
+
});
|
|
20
|
+
} else {
|
|
21
|
+
const frozen = await freezer.freezeAll(element);
|
|
22
|
+
const canvas = await renderer.renderToCanvas(frozen, settings.width, settings.height);
|
|
23
|
+
const blob = await canvas.convertToBlob({ type: "image/jpeg", quality: settings.quality ?? 0.95 });
|
|
24
|
+
const imgData = await new Promise((resolve) => {
|
|
25
|
+
const reader = new FileReader();
|
|
26
|
+
reader.onloadend = () => resolve(reader.result);
|
|
27
|
+
reader.readAsDataURL(blob);
|
|
28
|
+
});
|
|
29
|
+
pdf.addImage(imgData, "JPEG", 0, 0, canvas.width, canvas.height);
|
|
30
|
+
}
|
|
31
|
+
return pdf.output("blob");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// src/doc.ts
|
|
35
|
+
var FramvDoc = class {
|
|
36
|
+
options;
|
|
37
|
+
constructor(options) {
|
|
38
|
+
this.options = options;
|
|
39
|
+
}
|
|
40
|
+
render() {
|
|
41
|
+
const el = document.createElement("framv-docs");
|
|
42
|
+
el.setAttribute("page-size", this.options.pageSize ?? "A4");
|
|
43
|
+
el.setAttribute("orientation", this.options.orientation ?? "portrait");
|
|
44
|
+
el.setAttribute("margin", String(this.options.margin ?? 20));
|
|
45
|
+
el.innerHTML = this.options.content;
|
|
46
|
+
return el;
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
// src/element.ts
|
|
51
|
+
import { exportElement } from "@framv/core";
|
|
52
|
+
var PAGE_SIZES = {
|
|
53
|
+
A4: { w: 210, h: 297 },
|
|
54
|
+
A3: { w: 297, h: 420 },
|
|
55
|
+
A5: { w: 148, h: 210 },
|
|
56
|
+
letter: { w: 216, h: 279 },
|
|
57
|
+
legal: { w: 216, h: 356 }
|
|
58
|
+
};
|
|
59
|
+
var STYLES = `
|
|
60
|
+
:host {
|
|
61
|
+
display: block;
|
|
62
|
+
background: #e8e8e8;
|
|
63
|
+
min-height: 100%;
|
|
64
|
+
padding: 24px 0;
|
|
65
|
+
}
|
|
66
|
+
.framv-docs-inner {
|
|
67
|
+
display: flex;
|
|
68
|
+
flex-direction: column;
|
|
69
|
+
align-items: center;
|
|
70
|
+
gap: 24px;
|
|
71
|
+
}
|
|
72
|
+
.framv-page {
|
|
73
|
+
background: white;
|
|
74
|
+
box-shadow: 0 2px 16px rgba(0,0,0,0.12);
|
|
75
|
+
box-sizing: border-box;
|
|
76
|
+
overflow: hidden;
|
|
77
|
+
position: relative;
|
|
78
|
+
}
|
|
79
|
+
.framv-page::after {
|
|
80
|
+
content: attr(data-page);
|
|
81
|
+
position: absolute;
|
|
82
|
+
bottom: 8px;
|
|
83
|
+
left: 0; right: 0;
|
|
84
|
+
text-align: center;
|
|
85
|
+
font: 10px system-ui;
|
|
86
|
+
color: #999;
|
|
87
|
+
}
|
|
88
|
+
.framv-page-break {
|
|
89
|
+
page-break-before: always;
|
|
90
|
+
break-before: page;
|
|
91
|
+
}
|
|
92
|
+
.framv-toolbar {
|
|
93
|
+
display: flex; align-items: center; justify-content: center; gap: 8px;
|
|
94
|
+
padding: 8px 16px;
|
|
95
|
+
background: rgba(0,0,0,0.7); backdrop-filter: blur(6px);
|
|
96
|
+
color: #fff; font: 12px system-ui;
|
|
97
|
+
position: sticky; top: 0; z-index: 10;
|
|
98
|
+
border-radius: 0 0 8px 8px;
|
|
99
|
+
width: fit-content; margin: 0 auto 16px auto;
|
|
100
|
+
}
|
|
101
|
+
.framv-toolbar button {
|
|
102
|
+
background: none; border: 1px solid rgba(255,255,255,0.2);
|
|
103
|
+
color: inherit; cursor: pointer;
|
|
104
|
+
padding: 4px 10px; font: inherit; border-radius: 4px;
|
|
105
|
+
}
|
|
106
|
+
.framv-toolbar button:hover { background: rgba(255,255,255,0.15); }
|
|
107
|
+
.framv-toolbar .btn-pdf { border-color: #50fa7b; color: #50fa7b; }
|
|
108
|
+
.framv-toolbar .btn-print { border-color: #8be9fd; color: #8be9fd; }
|
|
109
|
+
.framv-info {
|
|
110
|
+
color: rgba(255,255,255,0.6); font-size: 11px;
|
|
111
|
+
}
|
|
112
|
+
@media print {
|
|
113
|
+
:host { background: white; padding: 0; }
|
|
114
|
+
.framv-toolbar { display: none !important; }
|
|
115
|
+
.framv-page { box-shadow: none; break-inside: avoid; margin: 0; }
|
|
116
|
+
}
|
|
117
|
+
`;
|
|
118
|
+
var FramvDocsElement = class extends HTMLElement {
|
|
119
|
+
static observedAttributes = ["page-size", "orientation", "margin"];
|
|
120
|
+
_inner;
|
|
121
|
+
_toolbar;
|
|
122
|
+
_pdfBtn;
|
|
123
|
+
// Saved original content for re-pagination on attribute change
|
|
124
|
+
_savedContent = null;
|
|
125
|
+
_initialized = false;
|
|
126
|
+
get pageSize() {
|
|
127
|
+
return this.getAttribute("page-size") ?? "A4";
|
|
128
|
+
}
|
|
129
|
+
get orientation() {
|
|
130
|
+
return this.getAttribute("orientation") ?? "portrait";
|
|
131
|
+
}
|
|
132
|
+
get margin() {
|
|
133
|
+
return parseInt(this.getAttribute("margin") ?? "20");
|
|
134
|
+
}
|
|
135
|
+
get format() {
|
|
136
|
+
return this.getAttribute("format") ?? "pdf";
|
|
137
|
+
}
|
|
138
|
+
connectedCallback() {
|
|
139
|
+
if (this._initialized) return;
|
|
140
|
+
this._initialized = true;
|
|
141
|
+
const originalNodes = Array.from(this.childNodes);
|
|
142
|
+
this._savedContent = [];
|
|
143
|
+
for (const node of originalNodes) {
|
|
144
|
+
if (node instanceof HTMLElement && node.classList.contains("framv-page-break")) {
|
|
145
|
+
this._savedContent.push("BREAK");
|
|
146
|
+
} else {
|
|
147
|
+
this._savedContent.push(node.cloneNode(true));
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
this.innerHTML = `
|
|
151
|
+
<style>${STYLES}</style>
|
|
152
|
+
<div class="framv-toolbar">
|
|
153
|
+
<span class="framv-info"></span>
|
|
154
|
+
<button class="btn-pdf">\u2B07 Export PDF</button>
|
|
155
|
+
<button class="btn-print">\u{1F5A8} Print</button>
|
|
156
|
+
</div>
|
|
157
|
+
<div class="framv-docs-inner"></div>
|
|
158
|
+
`;
|
|
159
|
+
this._toolbar = this.querySelector(".framv-toolbar");
|
|
160
|
+
this._pdfBtn = this._toolbar.querySelector(".btn-pdf");
|
|
161
|
+
this._inner = this.querySelector(".framv-docs-inner");
|
|
162
|
+
this._paginate();
|
|
163
|
+
this._pdfBtn.addEventListener("click", () => this._export());
|
|
164
|
+
this._toolbar.querySelector(".btn-print").addEventListener("click", () => window.print());
|
|
165
|
+
}
|
|
166
|
+
attributeChangedCallback() {
|
|
167
|
+
if (this.isConnected && this._initialized) {
|
|
168
|
+
this._paginate();
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
_paginate() {
|
|
172
|
+
const size = PAGE_SIZES[this.pageSize] ?? PAGE_SIZES.A4;
|
|
173
|
+
const isPortrait = this.orientation !== "landscape";
|
|
174
|
+
const pageW = isPortrait ? size.w : size.h;
|
|
175
|
+
const pageH = isPortrait ? size.h : size.w;
|
|
176
|
+
const margin = this.margin;
|
|
177
|
+
const content = this._savedContent ?? [];
|
|
178
|
+
const pages = [];
|
|
179
|
+
let current = [];
|
|
180
|
+
for (const item of content) {
|
|
181
|
+
if (item === "BREAK") {
|
|
182
|
+
if (current.length > 0) pages.push(current);
|
|
183
|
+
current = [];
|
|
184
|
+
} else {
|
|
185
|
+
current.push(item.cloneNode(true));
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
if (current.length > 0) pages.push(current);
|
|
189
|
+
this._inner.innerHTML = "";
|
|
190
|
+
const contentW = pageW - margin * 2;
|
|
191
|
+
const contentH = pageH - margin * 2;
|
|
192
|
+
pages.forEach((nodes, i) => {
|
|
193
|
+
const page = document.createElement("div");
|
|
194
|
+
page.className = "framv-page";
|
|
195
|
+
page.dataset.page = String(i + 1);
|
|
196
|
+
page.style.width = `${pageW}mm`;
|
|
197
|
+
page.style.minHeight = `${pageH}mm`;
|
|
198
|
+
page.style.padding = `${margin}mm`;
|
|
199
|
+
const contentDiv = document.createElement("div");
|
|
200
|
+
contentDiv.className = "framv-page-content";
|
|
201
|
+
contentDiv.style.minHeight = `${contentH}mm`;
|
|
202
|
+
nodes.forEach((n) => contentDiv.appendChild(n));
|
|
203
|
+
page.appendChild(contentDiv);
|
|
204
|
+
this._inner.appendChild(page);
|
|
205
|
+
});
|
|
206
|
+
const info = this._toolbar.querySelector(".framv-info");
|
|
207
|
+
if (info) info.textContent = `${this.pageSize.toUpperCase()} ${this.orientation} \xB7 ${pages.length} pages`;
|
|
208
|
+
this._pdfBtn.textContent = `\u2B07 Export ${this.format.toUpperCase()}`;
|
|
209
|
+
}
|
|
210
|
+
async _export() {
|
|
211
|
+
const size = PAGE_SIZES[this.pageSize] ?? PAGE_SIZES.A4;
|
|
212
|
+
const isPortrait = this.orientation !== "landscape";
|
|
213
|
+
const pageW = isPortrait ? size.w : size.h;
|
|
214
|
+
const pageH = isPortrait ? size.h : size.w;
|
|
215
|
+
const margin = this.margin;
|
|
216
|
+
const mmToPx = 3.7795275591;
|
|
217
|
+
const pages = this._inner.querySelectorAll(".framv-page");
|
|
218
|
+
try {
|
|
219
|
+
const { jsPDF } = await import("jspdf");
|
|
220
|
+
const pdf = new jsPDF({
|
|
221
|
+
orientation: pageW > pageH ? "l" : "p",
|
|
222
|
+
unit: "mm",
|
|
223
|
+
format: [pageW, pageH]
|
|
224
|
+
});
|
|
225
|
+
for (let i = 0; i < pages.length; i++) {
|
|
226
|
+
if (i > 0) pdf.addPage();
|
|
227
|
+
const page = pages[i];
|
|
228
|
+
const pageContent = page.querySelector(".framv-page-content");
|
|
229
|
+
if (!pageContent) continue;
|
|
230
|
+
await pdf.html(pageContent, {
|
|
231
|
+
x: margin,
|
|
232
|
+
y: margin,
|
|
233
|
+
width: pageW - margin * 2,
|
|
234
|
+
windowWidth: pageW * mmToPx
|
|
235
|
+
});
|
|
236
|
+
}
|
|
237
|
+
pdf.save("framv-document.pdf");
|
|
238
|
+
} catch (err) {
|
|
239
|
+
console.error("PDF export failed, falling back to core:", err);
|
|
240
|
+
const firstPage = this._inner.querySelector(".framv-page-content");
|
|
241
|
+
const blob = await exportElement({
|
|
242
|
+
element: firstPage ?? this._inner,
|
|
243
|
+
settings: { format: "pdf", width: pageW * mmToPx, height: pageH * mmToPx }
|
|
244
|
+
});
|
|
245
|
+
const url = URL.createObjectURL(blob);
|
|
246
|
+
const a = document.createElement("a");
|
|
247
|
+
a.href = url;
|
|
248
|
+
a.download = "framv-document.pdf";
|
|
249
|
+
a.click();
|
|
250
|
+
URL.revokeObjectURL(url);
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
};
|
|
254
|
+
if (!customElements.get("framv-docs")) {
|
|
255
|
+
customElements.define("framv-docs", FramvDocsElement);
|
|
256
|
+
}
|
|
257
|
+
export {
|
|
258
|
+
FramvDoc,
|
|
259
|
+
FramvDocsElement
|
|
260
|
+
};
|