Skip to content

Commit ffe2d02

Browse files
committed
feat: add helper files to be used wherever the project is used
1 parent c31a283 commit ffe2d02

2 files changed

Lines changed: 283 additions & 0 deletions

File tree

src/helpers.ts

Lines changed: 274 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,274 @@
1+
/**
2+
* Shared PDF Generation Helpers
3+
*
4+
* Centralized utilities for PDF generation across the app
5+
* Includes color conversion, style injection, and common settings
6+
*/
7+
8+
import { TAILWIND_COLOR_REPLACEMENTS } from './utils';
9+
10+
/**
11+
* Complete OKLCH to RGB color conversion map
12+
* Includes all Tailwind CSS colors used in the app
13+
*/
14+
export const PDF_COLOR_REPLACEMENTS = {
15+
...TAILWIND_COLOR_REPLACEMENTS,
16+
// Add any custom app colors here if needed
17+
};
18+
19+
/**
20+
* Generate comprehensive CSS for PDF rendering
21+
* Handles OKLCH color conversion and ensures proper styling
22+
*/
23+
export function generatePDFColorCSS(): string {
24+
return `
25+
:root, :host, * {
26+
/* Red colors */
27+
--color-red-50: #fef2f2 !important;
28+
--color-red-100: #fee2e2 !important;
29+
--color-red-200: #fecaca !important;
30+
--color-red-300: #fca5a5 !important;
31+
--color-red-400: #f87171 !important;
32+
--color-red-500: #ef4444 !important;
33+
--color-red-600: #dc2626 !important;
34+
--color-red-700: #b91c1c !important;
35+
--color-red-800: #991b1b !important;
36+
--color-red-900: #7f1d1d !important;
37+
38+
/* Orange colors */
39+
--color-orange-50: #fff7ed !important;
40+
--color-orange-100: #ffedd5 !important;
41+
--color-orange-200: #fed7aa !important;
42+
--color-orange-300: #fdba74 !important;
43+
--color-orange-400: #fb923c !important;
44+
--color-orange-500: #f97316 !important;
45+
--color-orange-600: #ea580c !important;
46+
--color-orange-700: #c2410c !important;
47+
--color-orange-800: #9a3412 !important;
48+
--color-orange-900: #7c2d12 !important;
49+
50+
/* Yellow colors */
51+
--color-yellow-50: #fefce8 !important;
52+
--color-yellow-100: #fef9c3 !important;
53+
--color-yellow-200: #fef08a !important;
54+
--color-yellow-300: #fde047 !important;
55+
--color-yellow-400: #facc15 !important;
56+
--color-yellow-500: #eab308 !important;
57+
--color-yellow-600: #ca8a04 !important;
58+
--color-yellow-700: #a16207 !important;
59+
--color-yellow-800: #854d0e !important;
60+
--color-yellow-900: #713f12 !important;
61+
62+
/* Green colors */
63+
--color-green-50: #f0fdf4 !important;
64+
--color-green-100: #dcfce7 !important;
65+
--color-green-200: #bbf7d0 !important;
66+
--color-green-300: #86efac !important;
67+
--color-green-400: #4ade80 !important;
68+
--color-green-500: #22c55e !important;
69+
--color-green-600: #16a34a !important;
70+
--color-green-700: #15803d !important;
71+
--color-green-800: #166534 !important;
72+
--color-green-900: #14532d !important;
73+
74+
/* Blue colors */
75+
--color-blue-50: #eff6ff !important;
76+
--color-blue-100: #dbeafe !important;
77+
--color-blue-200: #bfdbfe !important;
78+
--color-blue-300: #93c5fd !important;
79+
--color-blue-400: #60a5fa !important;
80+
--color-blue-500: #3b82f6 !important;
81+
--color-blue-600: #2563eb !important;
82+
--color-blue-700: #1d4ed8 !important;
83+
--color-blue-800: #1e40af !important;
84+
--color-blue-900: #1e3a8a !important;
85+
86+
/* Purple colors */
87+
--color-purple-50: #faf5ff !important;
88+
--color-purple-100: #f3e8ff !important;
89+
--color-purple-200: #e9d5ff !important;
90+
--color-purple-300: #d8b4fe !important;
91+
--color-purple-400: #c084fc !important;
92+
--color-purple-500: #a855f7 !important;
93+
--color-purple-600: #9333ea !important;
94+
--color-purple-700: #7e22ce !important;
95+
--color-purple-800: #6b21a8 !important;
96+
--color-purple-900: #581c87 !important;
97+
98+
/* Gray colors */
99+
--color-gray-50: #f9fafb !important;
100+
--color-gray-100: #f3f4f6 !important;
101+
--color-gray-200: #e5e7eb !important;
102+
--color-gray-300: #d1d5db !important;
103+
--color-gray-400: #9ca3af !important;
104+
--color-gray-500: #6b7280 !important;
105+
--color-gray-600: #4b5563 !important;
106+
--color-gray-700: #374151 !important;
107+
--color-gray-800: #1f2937 !important;
108+
--color-gray-900: #111827 !important;
109+
110+
/* Basic colors */
111+
--color-black: #000000 !important;
112+
--color-white: #ffffff !important;
113+
}
114+
115+
/* Background color utilities */
116+
.bg-red-50 { background-color: #fef2f2 !important; }
117+
.bg-red-100 { background-color: #fee2e2 !important; }
118+
.bg-red-600 { background-color: #dc2626 !important; }
119+
.bg-red-700 { background-color: #b91c1c !important; }
120+
121+
.bg-orange-50 { background-color: #fff7ed !important; }
122+
.bg-orange-100 { background-color: #ffedd5 !important; }
123+
.bg-orange-600 { background-color: #ea580c !important; }
124+
.bg-orange-700 { background-color: #c2410c !important; }
125+
126+
.bg-yellow-50 { background-color: #fefce8 !important; }
127+
.bg-yellow-100 { background-color: #fef9c3 !important; }
128+
.bg-yellow-200 { background-color: #fef08a !important; }
129+
130+
.bg-green-50 { background-color: #f0fdf4 !important; }
131+
.bg-green-100 { background-color: #dcfce7 !important; }
132+
.bg-green-600 { background-color: #16a34a !important; }
133+
.bg-green-700 { background-color: #15803d !important; }
134+
135+
.bg-blue-50 { background-color: #eff6ff !important; }
136+
.bg-blue-100 { background-color: #dbeafe !important; }
137+
.bg-blue-200 { background-color: #bfdbfe !important; }
138+
.bg-blue-600 { background-color: #2563eb !important; }
139+
.bg-blue-700 { background-color: #1d4ed8 !important; }
140+
141+
.bg-purple-50 { background-color: #faf5ff !important; }
142+
.bg-purple-100 { background-color: #f3e8ff !important; }
143+
.bg-purple-200 { background-color: #e9d5ff !important; }
144+
.bg-purple-600 { background-color: #9333ea !important; }
145+
146+
.bg-gray-50 { background-color: #f9fafb !important; }
147+
.bg-gray-100 { background-color: #f3f4f6 !important; }
148+
.bg-gray-200 { background-color: #e5e7eb !important; }
149+
150+
/* Border color utilities */
151+
.border-red-200 { border-color: #fecaca !important; }
152+
.border-red-300 { border-color: #fca5a5 !important; }
153+
154+
.border-orange-200 { border-color: #fed7aa !important; }
155+
.border-orange-300 { border-color: #fdba74 !important; }
156+
157+
.border-yellow-200 { border-color: #fef08a !important; }
158+
159+
.border-green-200 { border-color: #bbf7d0 !important; }
160+
161+
.border-blue-200 { border-color: #bfdbfe !important; }
162+
.border-blue-300 { border-color: #93c5fd !important; }
163+
.border-blue-400 { border-color: #60a5fa !important; }
164+
165+
.border-purple-200 { border-color: #e9d5ff !important; }
166+
.border-purple-300 { border-color: #d8b4fe !important; }
167+
168+
.border-gray-200 { border-color: #e5e7eb !important; }
169+
.border-gray-300 { border-color: #d1d5db !important; }
170+
.border-gray-400 { border-color: #9ca3af !important; }
171+
172+
/* Text color utilities */
173+
.text-red-600 { color: #dc2626 !important; }
174+
.text-red-700 { color: #b91c1c !important; }
175+
176+
.text-orange-600 { color: #ea580c !important; }
177+
.text-orange-700 { color: #c2410c !important; }
178+
179+
.text-yellow-600 { color: #ca8a04 !important; }
180+
181+
.text-green-600 { color: #16a34a !important; }
182+
.text-green-700 { color: #15803d !important; }
183+
184+
.text-blue-600 { color: #2563eb !important; }
185+
.text-blue-700 { color: #1d4ed8 !important; }
186+
187+
.text-purple-600 { color: #9333ea !important; }
188+
189+
.text-gray-500 { color: #6b7280 !important; }
190+
.text-gray-600 { color: #4b5563 !important; }
191+
.text-gray-700 { color: #374151 !important; }
192+
.text-gray-900 { color: #111827 !important; }
193+
`;
194+
}
195+
196+
/**
197+
* Inject PDF color styles into the document
198+
* Returns cleanup function to remove styles
199+
*/
200+
export function injectPDFStyles(): () => void {
201+
const styleId = 'pdf-color-override';
202+
203+
// Remove existing style if present
204+
const existing = document.getElementById(styleId);
205+
if (existing) {
206+
existing.remove();
207+
}
208+
209+
const style = document.createElement('style');
210+
style.id = styleId;
211+
style.textContent = generatePDFColorCSS();
212+
document.head.appendChild(style);
213+
214+
// Return cleanup function
215+
return () => {
216+
const el = document.getElementById(styleId);
217+
if (el) {
218+
el.remove();
219+
}
220+
};
221+
}
222+
223+
/**
224+
* Default PDF generator options optimized for the app
225+
*/
226+
export const DEFAULT_PDF_OPTIONS = {
227+
format: 'a4' as const,
228+
orientation: 'portrait' as const,
229+
margins: [10, 10, 10, 10] as [number, number, number, number],
230+
compress: true,
231+
showPageNumbers: false,
232+
imageQuality: 0.95,
233+
scale: 3,
234+
colorReplacements: PDF_COLOR_REPLACEMENTS,
235+
};
236+
237+
/**
238+
* High-quality PDF options for detailed documents
239+
*/
240+
export const HIGH_QUALITY_PDF_OPTIONS = {
241+
...DEFAULT_PDF_OPTIONS,
242+
imageQuality: 0.98,
243+
scale: 4,
244+
};
245+
246+
/**
247+
* Fast PDF options for quick generation
248+
*/
249+
export const FAST_PDF_OPTIONS = {
250+
...DEFAULT_PDF_OPTIONS,
251+
imageQuality: 0.85,
252+
scale: 2,
253+
};
254+
255+
/**
256+
* Calculate PDF content width in pixels
257+
* This ensures consistent width across all PDF-rendered components
258+
*
259+
* Formula: (Paper Width - Left Margin - Right Margin) × MM_TO_PX
260+
* For A4 Portrait with 10mm margins: (210 - 10 - 10) × 3.7795 = 718.105px
261+
*/
262+
export function getPDFContentWidth(): number {
263+
const a4WidthMm = 210; // A4 paper width
264+
const [, marginRight, , marginLeft] = DEFAULT_PDF_OPTIONS.margins;
265+
const usableWidthMm = a4WidthMm - marginLeft - marginRight;
266+
const MM_TO_PX = 3.7795275591; // Exact 96 DPI conversion
267+
return Math.round(usableWidthMm * MM_TO_PX); // 718px
268+
}
269+
270+
/**
271+
* PDF content width constant for consistent rendering
272+
* Use this value for all PDF-targeted content widths
273+
*/
274+
export const PDF_CONTENT_WIDTH_PX = getPDFContentWidth();

src/index.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,15 @@ export {
5050
htmlStringToElement,
5151
loadExternalStyles,
5252
} from './utils';
53+
export {
54+
DEFAULT_PDF_OPTIONS,
55+
injectPDFStyles,
56+
HIGH_QUALITY_PDF_OPTIONS,
57+
FAST_PDF_OPTIONS,
58+
generatePDFColorCSS,
59+
getPDFContentWidth,
60+
PDF_CONTENT_WIDTH_PX
61+
} from './helpers';
5362

5463
// Advanced image handling exports
5564
export {

0 commit comments

Comments
 (0)