@lucablockltd/ultimate-packaging 1.0.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.
@@ -0,0 +1,472 @@
1
+ # ultimate-packaging — AI Agent Reference
2
+
3
+ > React library for packaging dieline rendering and auto-layout on paper sheets.
4
+ > This document is optimized for AI agents to understand and use the library correctly.
5
+
6
+ ## Quick Start
7
+
8
+ ```bash
9
+ npm install PinitS/ultimate-packaging
10
+ ```
11
+
12
+ Requires `react >= 18.0.0` and `react-dom >= 18.0.0`.
13
+
14
+ ---
15
+
16
+ ## 1. Show a Dieline (Simplest Usage)
17
+
18
+ Use `DIE_LINE_LAYOUT` — one component for ALL models. No switch-case needed.
19
+
20
+ ```tsx
21
+ import { DIE_LINE_LAYOUT, modelList } from "ultimate-packaging";
22
+ import type { DieLineLayoutRef } from "ultimate-packaging";
23
+
24
+ const ref = useRef<DieLineLayoutRef>(null);
25
+
26
+ // Get default attributes for any model
27
+ const model = modelList.find(m => m.id === "BECF-1010A")!;
28
+
29
+ <DIE_LINE_LAYOUT
30
+ ref={ref}
31
+ modelId="BECF-1010A"
32
+ attributes={model.attributes}
33
+ unit="mm"
34
+ mode="DIE_LINE"
35
+ isShowDimensions={true}
36
+ />
37
+ ```
38
+
39
+ ### DIE_LINE_LAYOUT Props
40
+
41
+ | Prop | Type | Required | Default | Description |
42
+ |------|------|----------|---------|-------------|
43
+ | `modelId` | `string` | YES | — | One of: `"BECF-1010A"`, `"BECF-1030A"`, `"BECF-1040A"`, `"BECF-11D01"` |
44
+ | `attributes` | `object` | YES | — | Box dimensions (see Model Attributes below) |
45
+ | `unit` | `"mm" \| "cm" \| "in"` | no | `"mm"` | Display unit for dimension labels |
46
+ | `mode` | `ModelMode` | no | `"DIE_LINE"` | `"DIE_LINE"` = interactive canvas, `"AUTO_LAYOUT"` = raw SVG |
47
+ | `isShowDimensions` | `boolean` | no | `false` | Show dimension annotation lines |
48
+
49
+ ### DIE_LINE_LAYOUT Ref Methods
50
+
51
+ ```tsx
52
+ const ref = useRef<DieLineLayoutRef>(null);
53
+
54
+ // Get current attributes
55
+ ref.current.getAttributes(); // → { length: 60, width: 25, ... }
56
+
57
+ // Export as PNG image
58
+ const blob = await ref.current.exportImage({ isShowDimension: true, originalSize: true });
59
+
60
+ // Export dimensions as PDF
61
+ const pdf = await ref.current.exportDimension();
62
+ ```
63
+
64
+ ---
65
+
66
+ ## 2. Auto-Layout (Pack Dielines on Paper)
67
+
68
+ Use `AUTO_LAYOUT` to automatically arrange dieline pieces on paper sheets.
69
+
70
+ ```tsx
71
+ import { AUTO_LAYOUT, calculateAutoLayout } from "ultimate-packaging";
72
+ import type { AutoLayoutRef, AutoLayoutConfig, AutoLayoutResult } from "ultimate-packaging";
73
+
74
+ const ref = useRef<AutoLayoutRef>(null);
75
+ const [result, setResult] = useState<AutoLayoutResult | null>(null);
76
+
77
+ const config: AutoLayoutConfig = {
78
+ papers: [
79
+ { paperId: "1", paperName: "20x28\"", paperWidth: 508, paperHeight: 711.2 },
80
+ { paperId: "2", paperName: "25x36\"", paperWidth: 635, paperHeight: 914.4 },
81
+ ],
82
+ model: {
83
+ modelId: "BECF-1010A",
84
+ attributes: { length: 60, width: 25, height: 100, glueArea: 15, dustFlap: 15, tuckFlap: 15 },
85
+ },
86
+ quantity: 1000,
87
+ layoutDistance: 3, // mm gap between pieces (offset contour)
88
+ spacing: 5, // mm margin on sides
89
+ griper: 10, // mm machine gripper zone
90
+ colorbarHeight: 5, // mm colorbar strip height
91
+ isShowColorbar: true,
92
+ };
93
+
94
+ <AUTO_LAYOUT ref={ref} config={config} onResult={setResult} />
95
+ ```
96
+
97
+ ### AUTO_LAYOUT Props
98
+
99
+ | Prop | Type | Required | Description |
100
+ |------|------|----------|-------------|
101
+ | `config` | `AutoLayoutConfig \| null` | YES | Layout configuration (null = no render) |
102
+ | `onResult` | `(result: AutoLayoutResult \| null) => void` | no | Called when layout is calculated |
103
+ | `onModifiedPapers` | `(papers: AutoLayoutPaperResult[]) => void` | no | Called when user modifies layout manually |
104
+
105
+ ### AUTO_LAYOUT Ref Methods
106
+
107
+ ```tsx
108
+ // Get calculation result
109
+ ref.current.getResult(); // → AutoLayoutResult
110
+
111
+ // Export layout image (PNG) for specific paper
112
+ const png = await ref.current.exportImage(0); // paper index 0
113
+
114
+ // Export layout as PDF
115
+ const pdf = await ref.current.exportPdf(0);
116
+
117
+ // Get packed result with dieline + layout image files
118
+ const packed = await ref.current.getPackedResult(0);
119
+ // → { ...paperResult, quantity, dielineFile: File, layoutFile: File }
120
+ ```
121
+
122
+ ### Programmatic Calculation (No UI)
123
+
124
+ ```tsx
125
+ import { calculateAutoLayout } from "ultimate-packaging";
126
+
127
+ const result = calculateAutoLayout(config);
128
+ // → AutoLayoutResult { papers, quantity, totalProduced, totalSheets, remainingNeeded, recommendedPaperId }
129
+ ```
130
+
131
+ ---
132
+
133
+ ## 3. Available Models & Attributes
134
+
135
+ ### Get All Models
136
+
137
+ ```tsx
138
+ import { modelList } from "ultimate-packaging";
139
+
140
+ modelList.forEach(model => {
141
+ console.log(model.id); // "BECF-1010A"
142
+ console.log(model.name); // "Tuck End Box BECF-1010A"
143
+ console.log(model.dimension); // ["DIE_LINE"]
144
+ console.log(model.attributes); // { length: 60, width: 25, ... }
145
+ });
146
+ ```
147
+
148
+ ### Model Attribute Schemas
149
+
150
+ #### Tuck End Boxes (BECF-1010A, BECF-1030A, BECF-1040A)
151
+
152
+ ```typescript
153
+ interface TuckEndBoxAttributes {
154
+ length: number; // box length (mm)
155
+ width: number; // box width (mm)
156
+ height: number; // box height (mm)
157
+ glueArea: number; // glue flap width (mm)
158
+ dustFlap: number; // dust flap extension (mm)
159
+ tuckFlap: number; // tuck flap height (mm)
160
+ }
161
+ ```
162
+
163
+ | Model | length | width | height | glueArea | dustFlap | tuckFlap |
164
+ |-------|--------|-------|--------|----------|----------|----------|
165
+ | BECF-1010A | 60 | 25 | 100 | 15 | 15 | 15 |
166
+ | BECF-1030A | 105 | 50 | 155 | 15 | 25 | 14 |
167
+ | BECF-1040A | 56 | 56 | 150 | 15 | 30 | 14 |
168
+
169
+ #### Standard Box (BECF-11D01)
170
+
171
+ ```typescript
172
+ interface StandardBoxAttributes {
173
+ length: number; // box length (mm)
174
+ width: number; // box width (mm)
175
+ height: number; // box height (mm)
176
+ flapHeight: number; // top/bottom flap height (mm)
177
+ glueArea: number; // glue flap width (mm)
178
+ }
179
+ ```
180
+
181
+ | Model | length | width | height | flapHeight | glueArea |
182
+ |-------|--------|-------|--------|------------|----------|
183
+ | BECF-11D01 | 100 | 50 | 150 | 50 | 13 |
184
+
185
+ ### Default Attribute Constants
186
+
187
+ ```tsx
188
+ import {
189
+ BECF_1010A_DEFAULT_ATTRIBUTES,
190
+ BECF_1030A_DEFAULT_ATTRIBUTES,
191
+ BECF_1040A_DEFAULT_ATTRIBUTES,
192
+ BECF_11D01_DEFAULT_ATTRIBUTES,
193
+ } from "ultimate-packaging";
194
+ ```
195
+
196
+ ---
197
+
198
+ ## 4. Type Reference
199
+
200
+ ### AutoLayoutConfig
201
+
202
+ ```typescript
203
+ interface AutoLayoutConfig {
204
+ papers: AutoLayoutPaper[]; // paper sizes to try
205
+ model: AutoLayoutModel; // { modelId, attributes }
206
+ quantity: number; // total pieces needed
207
+ layoutDistance: number; // mm between piece cut-lines
208
+ spacing: number; // mm margin on paper sides
209
+ griper: number; // mm machine gripper zone
210
+ colorbarHeight: number; // mm colorbar strip
211
+ isShowColorbar: boolean; // show colorbar on layout
212
+ }
213
+
214
+ interface AutoLayoutPaper {
215
+ paperId: string;
216
+ paperName: string;
217
+ paperWidth: number; // mm
218
+ paperHeight: number; // mm
219
+ }
220
+ ```
221
+
222
+ ### AutoLayoutResult
223
+
224
+ ```typescript
225
+ interface AutoLayoutResult {
226
+ papers: AutoLayoutPaperResult[]; // results per paper size
227
+ quantity: number;
228
+ totalProduced: number;
229
+ totalSheets: number;
230
+ remainingNeeded: number;
231
+ recommendedPaperId: string | null; // most efficient paper
232
+ }
233
+
234
+ interface AutoLayoutPaperResult {
235
+ paperId: string;
236
+ paperName: string;
237
+ paperWidth: number;
238
+ paperHeight: number;
239
+ producedPerSheet: number; // pieces per sheet
240
+ totalSheets: number;
241
+ totalProduced: number;
242
+ excessCount: number; // overproduction
243
+ wastePercent: number; // paper waste %
244
+ independentSheets: number; // sheets if using only this paper
245
+ independentTotalArea: number; // total paper area (mm²)
246
+ placements: AutoLayoutPlacement[];
247
+ gripperSide: GripperSide; // "top" | "bottom" | "left" | "right"
248
+ }
249
+
250
+ interface AutoLayoutPlacement {
251
+ x: number; // mm from paper left
252
+ y: number; // mm from paper top
253
+ rotation: number; // 0 | 90 | 180 | 270
254
+ }
255
+ ```
256
+
257
+ ### AutoLayoutPackedResult
258
+
259
+ ```typescript
260
+ interface AutoLayoutPackedResult extends AutoLayoutPaperResult {
261
+ quantity: number;
262
+ dielineFile: File; // dieline pattern image
263
+ layoutFile: File; // layout arrangement image
264
+ }
265
+ ```
266
+
267
+ ### ModelMode
268
+
269
+ ```typescript
270
+ type ModelMode = "DIE_LINE" | "3D" | "AUTO_LAYOUT";
271
+ ```
272
+
273
+ ---
274
+
275
+ ## 5. Theme Configuration
276
+
277
+ ```tsx
278
+ import { configurePackaging } from "ultimate-packaging";
279
+
280
+ // Call ONCE at app startup, BEFORE rendering any components
281
+ configurePackaging({
282
+ modelTheme: {
283
+ colorBackground: "#FAFAFA",
284
+ colorDieLine: "#FF0000", // cut lines
285
+ colorFoldLine: "#00FF00", // crease lines
286
+ },
287
+ autoLayoutTheme: {
288
+ colorBackground: "#F5F5F5",
289
+ colorPaperFill: "#FFFFFF",
290
+ colorPaperStroke: "#999999",
291
+ colorGriper: "#228B22",
292
+ colorSpacing: "#f54278",
293
+ colorDistanceLine: "#0088FF", // blue offset contour
294
+ colorDieLine: "#FF0000",
295
+ colorFoldLine: "#00FF00",
296
+ colorLabel: "#333333",
297
+ },
298
+ });
299
+ ```
300
+
301
+ ---
302
+
303
+ ## 6. Complete Imports Cheat Sheet
304
+
305
+ ```tsx
306
+ // Components
307
+ import {
308
+ DIE_LINE_LAYOUT, // Recommended: auto-switches by modelId
309
+ AUTO_LAYOUT, // Auto-layout packing on paper
310
+ MODEL_BECF_1010A, // Direct model components (if needed)
311
+ MODEL_BECF_1030A,
312
+ MODEL_BECF_1040A,
313
+ MODEL_BECF_11D01,
314
+ Colorbar, // Sub-components for custom rendering
315
+ Gripper,
316
+ } from "ultimate-packaging";
317
+
318
+ // Types
319
+ import type {
320
+ DieLineLayoutRef,
321
+ DieLineLayoutProps,
322
+ AutoLayoutRef,
323
+ AutoLayoutProps,
324
+ AutoLayoutConfig,
325
+ AutoLayoutResult,
326
+ AutoLayoutPaperResult,
327
+ AutoLayoutPackedResult,
328
+ AutoLayoutPlacement,
329
+ AutoLayoutPaper,
330
+ AutoLayoutModel,
331
+ TuckEndBoxAttributes,
332
+ StandardBoxAttributes,
333
+ ModelMode,
334
+ PackagingModel,
335
+ GripperSide,
336
+ ModifyPlacement,
337
+ ModelThemeConfig,
338
+ AutoLayoutThemeConfig,
339
+ UltimatePackagingConfig,
340
+ } from "ultimate-packaging";
341
+
342
+ // Data & Constants
343
+ import {
344
+ modelList, // PackagingModel[] — all models with defaults
345
+ BECF_1010A_DEFAULT_ATTRIBUTES,
346
+ BECF_1030A_DEFAULT_ATTRIBUTES,
347
+ BECF_1040A_DEFAULT_ATTRIBUTES,
348
+ BECF_11D01_DEFAULT_ATTRIBUTES,
349
+ MODEL_THEME_CONFIG,
350
+ AUTO_LAYOUT_THEME_CONFIG,
351
+ } from "ultimate-packaging";
352
+
353
+ // Functions
354
+ import {
355
+ configurePackaging, // Set global theme
356
+ calculateAutoLayout, // Compute layout without UI
357
+ } from "ultimate-packaging";
358
+ ```
359
+
360
+ ---
361
+
362
+ ## 7. Common Patterns
363
+
364
+ ### Pattern A: Display a Dieline with Controls
365
+
366
+ ```tsx
367
+ import { DIE_LINE_LAYOUT, modelList } from "ultimate-packaging";
368
+ import type { DieLineLayoutRef } from "ultimate-packaging";
369
+
370
+ function DielineEditor() {
371
+ const ref = useRef<DieLineLayoutRef>(null);
372
+ const [modelId, setModelId] = useState("BECF-1010A");
373
+ const [attrs, setAttrs] = useState(modelList[0].attributes);
374
+
375
+ const handleModelChange = (id: string) => {
376
+ setModelId(id);
377
+ setAttrs(modelList.find(m => m.id === id)!.attributes);
378
+ };
379
+
380
+ return (
381
+ <>
382
+ <select value={modelId} onChange={e => handleModelChange(e.target.value)}>
383
+ {modelList.map(m => <option key={m.id} value={m.id}>{m.name}</option>)}
384
+ </select>
385
+ <DIE_LINE_LAYOUT ref={ref} modelId={modelId} attributes={attrs} />
386
+ </>
387
+ );
388
+ }
389
+ ```
390
+
391
+ ### Pattern B: Auto-Layout with Export
392
+
393
+ ```tsx
394
+ import { AUTO_LAYOUT } from "ultimate-packaging";
395
+ import type { AutoLayoutRef, AutoLayoutConfig, AutoLayoutResult } from "ultimate-packaging";
396
+
397
+ function LayoutPlanner() {
398
+ const ref = useRef<AutoLayoutRef>(null);
399
+ const [result, setResult] = useState<AutoLayoutResult | null>(null);
400
+
401
+ const config: AutoLayoutConfig = {
402
+ papers: [{ paperId: "1", paperName: "20x28\"", paperWidth: 508, paperHeight: 711.2 }],
403
+ model: { modelId: "BECF-1010A", attributes: { length: 60, width: 25, height: 100, glueArea: 15, dustFlap: 15, tuckFlap: 15 } },
404
+ quantity: 500,
405
+ layoutDistance: 3,
406
+ spacing: 5,
407
+ griper: 10,
408
+ colorbarHeight: 5,
409
+ isShowColorbar: true,
410
+ };
411
+
412
+ const handleExport = async () => {
413
+ const packed = await ref.current!.getPackedResult(0);
414
+ // packed.dielineFile → File (dieline image)
415
+ // packed.layoutFile → File (layout image)
416
+ // packed.producedPerSheet → number
417
+ };
418
+
419
+ return (
420
+ <>
421
+ <AUTO_LAYOUT ref={ref} config={config} onResult={setResult} />
422
+ {result && <p>Best: {result.recommendedPaperId} — {result.papers[0].producedPerSheet} pcs/sheet</p>}
423
+ <button onClick={handleExport}>Export</button>
424
+ </>
425
+ );
426
+ }
427
+ ```
428
+
429
+ ### Pattern C: Headless Calculation (No React)
430
+
431
+ ```tsx
432
+ import { calculateAutoLayout } from "ultimate-packaging";
433
+
434
+ const result = calculateAutoLayout({
435
+ papers: [
436
+ { paperId: "A", paperName: "20x28\"", paperWidth: 508, paperHeight: 711.2 },
437
+ { paperId: "B", paperName: "25x36\"", paperWidth: 635, paperHeight: 914.4 },
438
+ ],
439
+ model: { modelId: "BECF-1030A", attributes: { length: 105, width: 50, height: 155, glueArea: 15, dustFlap: 25, tuckFlap: 14 } },
440
+ quantity: 1000,
441
+ layoutDistance: 3,
442
+ spacing: 5,
443
+ griper: 10,
444
+ colorbarHeight: 5,
445
+ isShowColorbar: true,
446
+ });
447
+
448
+ console.log(result.recommendedPaperId); // "B"
449
+ result.papers.forEach(p => {
450
+ console.log(`${p.paperName}: ${p.producedPerSheet} pcs/sheet, ${p.wastePercent}% waste`);
451
+ });
452
+ ```
453
+
454
+ ---
455
+
456
+ ## 8. Important Rules
457
+
458
+ 1. **Units are always millimeters** — all attributes, paper sizes, layout distances are in mm internally. The `unit` prop only affects display labels.
459
+
460
+ 2. **`configurePackaging()` must be called before rendering** — call once at app startup to set theme colors.
461
+
462
+ 3. **`modelList` contains all models with defaults** — use it to populate dropdowns and get default attributes. Never hardcode model lists.
463
+
464
+ 4. **`DIE_LINE_LAYOUT` is the recommended component** — it handles model switching internally. Only use `MODEL_*` components directly if you need model-specific type safety.
465
+
466
+ 5. **Paper dimensions for auto-layout are in mm** — convert inches to mm: `inches * 25.4`. Common sizes: 20x28" = 508x711.2mm, 25x36" = 635x914.4mm.
467
+
468
+ 6. **`layoutDistance` is the gap between cut-lines** — internally divided by 2 to create the offset contour on each side. Set to 0 for pieces touching.
469
+
470
+ 7. **`ref` methods are async for exports** — `exportImage()`, `exportDimension()`, `exportPdf()`, `getPackedResult()` all return `Promise<Blob>` or `Promise<File>`.
471
+
472
+ 8. **`rotation` in placements is degrees** — always one of: 0, 90, 180, 270.