@lucablockltd/ultimate-packaging 1.0.1 → 1.0.2

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.
Files changed (3) hide show
  1. package/LICENSE +8 -0
  2. package/README.md +1 -1019
  3. package/package.json +2 -13
package/LICENSE ADDED
@@ -0,0 +1,8 @@
1
+ Copyright (c) 2026 LUCA BLOCK Ltd. All rights reserved.
2
+
3
+ This software is proprietary and confidential.
4
+ Unauthorized copying, distribution, modification, or use of this software,
5
+ via any medium, is strictly prohibited.
6
+
7
+ This software is licensed, not sold. Use is permitted only under a valid
8
+ license agreement with LUCA BLOCK Ltd.
package/README.md CHANGED
@@ -1,1021 +1,3 @@
1
1
  # @lucablockltd/ultimate-packaging
2
2
 
3
- React library สำหรับสร้าง packaging dieline (แบบแผ่นกล่อง) และจัดวาง auto-layout บนแผ่นกระดาษ ใช้ได้กับ React และ Next.js
4
-
5
- **[Demo](https://PinitS.github.io/ultimate-packaging/)** — ทดลองใช้งานออนไลน์
6
-
7
- ## ติดตั้ง
8
-
9
- ```bash
10
- npm install @lucablockltd/ultimate-packaging
11
- ```
12
-
13
- ต้องมี `react` >= 18.0.0 และ `react-dom` >= 18.0.0 เป็น peer dependency
14
-
15
- ---
16
-
17
- ## สารบัญ
18
-
19
- - [Components](#components)
20
- - [DIE_LINE_LAYOUT](#die_line_layout) — Wrapper component เลือก model อัตโนมัติจาก `modelId` (แนะนำ)
21
- - [MODEL_BECF_1010A](#model_becf_1010a) — Tuck End Box ฝาเสียบด้านเดียว
22
- - [MODEL_BECF_1030A](#model_becf_1030a) — Tuck End Box ฝาเสียบสองด้าน
23
- - [MODEL_BECF_1040A](#model_becf_1040a) — Tuck End Box ฝาเสียบสองด้าน (แบบ B)
24
- - [MODEL_BECF_11D01](#model_becf_11d01) — Standard Box กล่องมาตรฐาน
25
- - [AUTO_LAYOUT](#auto_layout) — จัดวาง dieline บนแผ่นกระดาษอัตโนมัติ
26
- - [Types ทั้งหมด](#types-ทั้งหมด)
27
- - [TuckEndBoxAttributes](#tuckendboxattributes) — ขนาดกล่อง Tuck End
28
- - [StandardBoxAttributes](#standardboxattributes) — ขนาดกล่อง Standard
29
- - [AutoLayoutConfig](#autolayoutconfig) — ตั้งค่า auto-layout
30
- - [AutoLayoutResult](#autolayoutresult) — ผลลัพธ์การจัดวาง
31
- - [AutoLayoutPaperResult](#autolayoutpaperresult) — ผลลัพธ์แต่ละกระดาษ
32
- - [configurePackaging](#configurepackaging) — ตั้งค่า theme กลาง
33
- - [Constants (ค่าคงที่)](#constants-คาคงที)
34
- - [Utilities (ฟังก์ชันช่วย)](#utilities-ฟังก์ชันช่วย)
35
- - [ตัวอย่างการใช้งาน](#ตัวอย่างการใช้งาน)
36
- - [โครงสร้างโปรเจกต์](#โครงสร้างโปรเจกต์)
37
-
38
- ---
39
-
40
- ## Components
41
-
42
- ### `DIE_LINE_LAYOUT`
43
-
44
- Wrapper component ที่เลือก model อัตโนมัติจาก `modelId` ไม่ต้อง switch case เอง — **แนะนำให้ใช้ตัวนี้แทน MODEL_* components โดยตรง**
45
-
46
- ```tsx
47
- import { DIE_LINE_LAYOUT, modelList } from "@lucablockltd/ultimate-packaging";
48
- import type { DieLineLayoutRef } from "@lucablockltd/ultimate-packaging";
49
-
50
- const ref = useRef<DieLineLayoutRef>(null);
51
-
52
- <DIE_LINE_LAYOUT
53
- ref={ref}
54
- modelId="BECF-1010A"
55
- attributes={{ length: 60, width: 25, height: 100, glueArea: 15, dustFlap: 15, tuckFlap: 15 }}
56
- unit="mm"
57
- mode="DIE_LINE"
58
- isShowDimensions={true}
59
- />
60
- ```
61
-
62
- **Props:**
63
-
64
- | Prop | Type | Default | คำอธิบาย |
65
- |------|------|---------|----------|
66
- | `modelId` | `string` | *จำเป็น* | รหัส model เช่น `"BECF-1010A"`, `"BECF-1030A"`, `"BECF-11D01"` |
67
- | `attributes` | `Record<string, number>` | *จำเป็น* | ขนาดกล่อง (ใช้ `modelList` เพื่อดูค่า default แต่ละ model) |
68
- | `unit` | `"mm" \| "cm" \| "in"` | `"mm"` | หน่วยวัด |
69
- | `mode` | `ModelMode` | `"DIE_LINE"` | โหมดการแสดงผล |
70
- | `isShowDimensions` | `boolean` | `false` | แสดงเส้นบอกขนาด |
71
-
72
- **Ref methods (`DieLineLayoutRef`):**
73
-
74
- | Method | Return | คำอธิบาย |
75
- |--------|--------|----------|
76
- | `getAttributes()` | `Record<string, unknown>` | ดึงค่า attributes ปัจจุบัน |
77
- | `exportImage(options?)` | `Promise<Blob>` | Export เป็น PNG |
78
- | `exportDimension()` | `Promise<Blob>` | Export dimension เป็น PDF |
79
-
80
- **รองรับ model:** `BECF-1010A`, `BECF-1030A`, `BECF-1040A`, `BECF-11D01`
81
-
82
- ---
83
-
84
- ### `MODEL_BECF_1010A`
85
-
86
- Component สำหรับแสดง dieline กล่อง Tuck End Box รุ่น BECF-1010A พร้อม canvas ที่ zoom/pan ได้
87
-
88
- ```tsx
89
- import { MODEL_BECF_1010A } from "@lucablockltd/ultimate-packaging";
90
- import type { ModelBecf1010aRef, TuckEndBoxAttributes } from "@lucablockltd/ultimate-packaging";
91
-
92
- const ref = useRef<ModelBecf1010aRef>(null);
93
-
94
- <MODEL_BECF_1010A
95
- ref={ref}
96
- attributes={{
97
- length: 60, // ความยาวกล่อง (mm)
98
- width: 25, // ความกว้างกล่อง (mm)
99
- height: 100, // ความสูงกล่อง (mm)
100
- closurePanel: 25, // แผ่นปิดฝา (mm)
101
- glueArea: 15, // พื้นที่ทากาว (mm)
102
- dustFlap: 15, // ปีกกันฝุ่น (mm)
103
- tuckFlap: 15, // ปีกเสียบ (mm)
104
- }}
105
- unit="mm"
106
- mode="DIE_LINE"
107
- isShowDimensions={true}
108
- />
109
- ```
110
-
111
- **Props:**
112
-
113
- | Prop | Type | Default | คำอธิบาย |
114
- |------|------|---------|----------|
115
- | `attributes` | `TuckEndBoxAttributes` | *จำเป็น* | ขนาดกล่องทั้ง 7 ค่า (ดู [TuckEndBoxAttributes](#tuckendboxattributes)) |
116
- | `unit` | `"mm" \| "cm" \| "in"` | `"mm"` | หน่วยวัดที่แสดงบนเส้นบอกขนาด |
117
- | `mode` | `ModelMode` | `"DIE_LINE"` | โหมดการแสดงผล (`"DIE_LINE"` = แสดงแบบแผ่น, `"AUTO_LAYOUT"` = SVG ตรงๆ ไม่มี canvas) |
118
- | `isShowDimensions` | `boolean` | `false` | แสดงเส้นบอกขนาดหรือไม่ |
119
-
120
- **Ref methods (`ModelBecf1010aRef`):**
121
-
122
- | Method | Return | คำอธิบาย |
123
- |--------|--------|----------|
124
- | `getAttributes()` | `GetAttributesResult` | ดึงข้อมูลขนาดกล่องทั้งหมด รวม `overallWidth` / `overallHeight` ของ dieline |
125
- | `exportImage(options)` | `Promise<Blob>` | Export เป็นรูปภาพ PNG (ส่ง `{ isShowDimension: boolean, originalSize: boolean }`) |
126
- | `exportDimension()` | `Promise<Blob>` | Export เส้นบอกขนาดเป็น PDF |
127
- | `resetView()` | `void` | รีเซ็ต zoom/pan กลับตำแหน่งเริ่มต้น |
128
- | `fitView()` | `void` | ปรับ zoom ให้ dieline พอดีหน้าจอ |
129
-
130
- ---
131
-
132
- ### `MODEL_BECF_1030A`
133
-
134
- Component สำหรับแสดง dieline กล่อง Tuck End Box รุ่น BECF-1030A ใช้งานเหมือน `MODEL_BECF_1010A` ทุกประการ
135
-
136
- ```tsx
137
- import { MODEL_BECF_1030A } from "@lucablockltd/ultimate-packaging";
138
- import type { ModelBecf1030aRef } from "@lucablockltd/ultimate-packaging";
139
-
140
- const ref = useRef<ModelBecf1030aRef>(null);
141
-
142
- <MODEL_BECF_1030A
143
- ref={ref}
144
- attributes={{
145
- length: 105,
146
- width: 50,
147
- height: 155,
148
- closurePanel: 50,
149
- glueArea: 15,
150
- dustFlap: 25,
151
- tuckFlap: 14,
152
- }}
153
- unit="mm"
154
- mode="DIE_LINE"
155
- isShowDimensions={true}
156
- />
157
- ```
158
-
159
- Props และ Ref methods เหมือน [MODEL_BECF_1010A](#model_becf_1010a) ทุกประการ
160
-
161
- ---
162
-
163
- ### `MODEL_BECF_1040A`
164
-
165
- Component สำหรับแสดง dieline กล่อง Tuck End Box รุ่น BECF-1040A ใช้งานเหมือน `MODEL_BECF_1010A` ทุกประการ
166
-
167
- ```tsx
168
- import { MODEL_BECF_1040A } from "@lucablockltd/ultimate-packaging";
169
- import type { ModelBecf1040aRef } from "@lucablockltd/ultimate-packaging";
170
-
171
- const ref = useRef<ModelBecf1040aRef>(null);
172
-
173
- <MODEL_BECF_1040A
174
- ref={ref}
175
- attributes={{
176
- length: 56,
177
- width: 56,
178
- height: 150,
179
- closurePanel: 56,
180
- glueArea: 15,
181
- dustFlap: 30,
182
- tuckFlap: 14,
183
- }}
184
- unit="mm"
185
- mode="DIE_LINE"
186
- isShowDimensions={true}
187
- />
188
- ```
189
-
190
- Props และ Ref methods เหมือน [MODEL_BECF_1010A](#model_becf_1010a) ทุกประการ
191
-
192
- ---
193
-
194
- ### `MODEL_BECF_11D01`
195
-
196
- Component สำหรับแสดง dieline กล่อง Standard Box รุ่น BECF-11D01 (กล่องมาตรฐาน 4 ฝา)
197
-
198
- ```tsx
199
- import { MODEL_BECF_11D01 } from "@lucablockltd/ultimate-packaging";
200
- import type { ModelBecf11d01Ref, StandardBoxAttributes } from "@lucablockltd/ultimate-packaging";
201
-
202
- const ref = useRef<ModelBecf11d01Ref>(null);
203
-
204
- <MODEL_BECF_11D01
205
- ref={ref}
206
- attributes={{
207
- length: 100, // ความยาวกล่อง (mm)
208
- width: 50, // ความกว้างกล่อง (mm)
209
- height: 150, // ความสูงกล่อง (mm)
210
- flapHeight: 50, // ความสูงฝากล่อง (mm)
211
- glueArea: 13, // พื้นที่ทากาว (mm)
212
- }}
213
- unit="mm"
214
- mode="DIE_LINE"
215
- isShowDimensions={true}
216
- />
217
- ```
218
-
219
- **Props:**
220
-
221
- | Prop | Type | Default | คำอธิบาย |
222
- |------|------|---------|----------|
223
- | `attributes` | `StandardBoxAttributes` | *จำเป็น* | ขนาดกล่องทั้ง 5 ค่า (ดู [StandardBoxAttributes](#standardboxattributes)) |
224
- | `unit` | `"mm" \| "cm" \| "in"` | `"mm"` | หน่วยวัดที่แสดงบนเส้นบอกขนาด |
225
- | `mode` | `ModelMode` | `"DIE_LINE"` | โหมดการแสดงผล |
226
- | `isShowDimensions` | `boolean` | `false` | แสดงเส้นบอกขนาดหรือไม่ |
227
-
228
- **Ref methods (`ModelBecf11d01Ref`):**
229
-
230
- | Method | Return | คำอธิบาย |
231
- |--------|--------|----------|
232
- | `getAttributes()` | `GetAttributesResult` | ดึงข้อมูลขนาดกล่องทั้งหมด |
233
- | `exportImage(options)` | `Promise<Blob>` | Export เป็นรูปภาพ PNG |
234
- | `exportDimension()` | `Promise<Blob>` | Export เส้นบอกขนาดเป็น PDF |
235
- | `resetView()` | `void` | รีเซ็ต zoom/pan กลับตำแหน่งเริ่มต้น |
236
- | `fitView()` | `void` | ปรับ zoom ให้ dieline พอดีหน้าจอ |
237
-
238
- ---
239
-
240
- ### `AUTO_LAYOUT`
241
-
242
- Component สำหรับจัดวาง dieline บนแผ่นกระดาษอัตโนมัติ รองรับหลายขนาดกระดาษ หลาย model คำนวณการจัดวางที่ประหยัดกระดาษที่สุด พร้อม export เป็น PNG หรือ PDF
243
-
244
- ```tsx
245
- import { AUTO_LAYOUT } from "@lucablockltd/ultimate-packaging";
246
- import type { AutoLayoutRef, AutoLayoutConfig } from "@lucablockltd/ultimate-packaging";
247
-
248
- const layoutRef = useRef<AutoLayoutRef>(null);
249
- const [config, setConfig] = useState<AutoLayoutConfig | null>(null);
250
- const [result, setResult] = useState<AutoLayoutResult | null>(null);
251
-
252
- <AUTO_LAYOUT
253
- ref={layoutRef}
254
- config={config}
255
- onResult={setResult}
256
- />
257
- ```
258
-
259
- **Props:**
260
-
261
- | Prop | Type | Default | คำอธิบาย |
262
- |------|------|---------|----------|
263
- | `config` | `AutoLayoutConfig \| null` | *จำเป็น* | การตั้งค่าทั้งหมด (กระดาษ, model, จำนวน, spacing ฯลฯ) — เมื่อเปลี่ยนค่า component จะคำนวณใหม่อัตโนมัติ |
264
- | `onResult` | `(result: AutoLayoutResult \| null) => void` | - | callback ที่ถูกเรียกเมื่อคำนวณเสร็จ ส่ง result กลับให้ parent |
265
- | `onModifiedPapers` | `(papers: AutoLayoutPaperResult[]) => void` | - | callback ที่ถูกเรียกเมื่อ user submit layout ที่แก้ไขด้วยมือ ส่ง modified papers กลับให้ parent |
266
-
267
- **Ref methods (`AutoLayoutRef`):**
268
-
269
- | Method | Return | คำอธิบาย |
270
- |--------|--------|----------|
271
- | `getResult()` | `AutoLayoutResult \| null` | ดึงผลลัพธ์การคำนวณล่าสุด |
272
- | `exportImage(paperIndex)` | `Promise<Blob>` | Export กระดาษตาม index เป็น PNG (ได้ Blob กลับมา ส่งไป API ได้) |
273
- | `exportPdf(paperIndex)` | `Promise<Blob>` | Export กระดาษตาม index เป็น PDF (ได้ Blob กลับมา ส่งไป API ได้) |
274
-
275
- **Modify Layout (จัดวางด้วยมือ):**
276
-
277
- - ลาก-วาง dieline ไปตำแหน่งที่ต้องการ
278
- - หมุน 0° / 90° / 270°
279
- - เพิ่ม/ลบชิ้นงาน
280
- - ตรวจจับการชนแบบ real-time — ชิ้นที่ชนแสดงสีแดง
281
- - กด Submit → สร้างหน้ากระดาษใหม่ `modify-[ชื่อกระดาษ]`
282
-
283
- ---
284
-
285
- ## Types ทั้งหมด
286
-
287
- ### `TuckEndBoxAttributes`
288
-
289
- ขนาดกล่อง Tuck End Box ทุก model (BECF-1010A, BECF-1030A, BECF-1040A) ใช้ type เดียวกัน หน่วยเป็น mm
290
-
291
- ```tsx
292
- import type { TuckEndBoxAttributes } from "@lucablockltd/ultimate-packaging";
293
- ```
294
-
295
- | ตัวแปร | Type | คำอธิบาย |
296
- |--------|------|----------|
297
- | `length` | `number` | ความยาวกล่อง (ด้านยาวของฐานกล่อง) |
298
- | `width` | `number` | ความกว้างกล่อง (ด้านสั้นของฐานกล่อง) |
299
- | `height` | `number` | ความสูงกล่อง (จากฐานถึงฝา) |
300
- | `closurePanel` | `number` | ความยาวแผ่นปิดฝา (ส่วนที่พับลงมาปิดฝากล่อง) |
301
- | `glueArea` | `number` | ความกว้างพื้นที่ทากาว (ขอบสำหรับติดกาว) |
302
- | `dustFlap` | `number` | ความยาวปีกกันฝุ่น (ปีกข้างที่พับเข้าด้านใน) |
303
- | `tuckFlap` | `number` | ความยาวปีกเสียบ (ปีกที่เสียบเข้าไปในกล่องเพื่อล็อคฝา) |
304
-
305
- ---
306
-
307
- ### `StandardBoxAttributes`
308
-
309
- ขนาดกล่อง Standard Box (BECF-11D01) หน่วยเป็น mm
310
-
311
- ```tsx
312
- import type { StandardBoxAttributes } from "@lucablockltd/ultimate-packaging";
313
- ```
314
-
315
- | ตัวแปร | Type | คำอธิบาย |
316
- |--------|------|----------|
317
- | `length` | `number` | ความยาวกล่อง |
318
- | `width` | `number` | ความกว้างกล่อง |
319
- | `height` | `number` | ความสูงกล่อง |
320
- | `flapHeight` | `number` | ความสูงฝากล่อง |
321
- | `glueArea` | `number` | ความกว้างพื้นที่ทากาว |
322
-
323
- ---
324
-
325
- ### `AutoLayoutConfig`
326
-
327
- การตั้งค่าทั้งหมดสำหรับ `AUTO_LAYOUT` component
328
-
329
- ```tsx
330
- import type { AutoLayoutConfig } from "@lucablockltd/ultimate-packaging";
331
- ```
332
-
333
- | ตัวแปร | Type | คำอธิบาย |
334
- |--------|------|----------|
335
- | `papers` | `AutoLayoutPaper[]` | รายการกระดาษที่ต้องการเปรียบเทียบ (ส่งได้หลายขนาด) |
336
- | `model` | `AutoLayoutModel` | model กล่องที่จะจัดวาง (ระบุ modelId + attributes) |
337
- | `quantity` | `number` | จำนวนกล่องที่ต้องการผลิต |
338
- | `layoutDistance` | `number` | ระยะห่างระหว่าง dieline แต่ละชิ้น (mm) |
339
- | `spacing` | `number` | ระยะห่างขอบกระดาษซ้าย-ขวา (mm) |
340
- | `griper` | `number` | ความกว้าง gripper — พื้นที่ที่แท่นพิมพ์จับกระดาษ (mm) |
341
- | `colorbarHeight` | `number` | ความสูง colorbar — แถบสีสำหรับตรวจสอบคุณภาพการพิมพ์ (mm) |
342
- | `isShowColorbar` | `boolean` | แสดง colorbar หรือไม่ |
343
-
344
- ---
345
-
346
- ### `AutoLayoutPaper`
347
-
348
- ข้อมูลกระดาษแต่ละแผ่นที่ส่งเข้า config
349
-
350
- ```tsx
351
- import type { AutoLayoutPaper } from "@lucablockltd/ultimate-packaging";
352
- ```
353
-
354
- | ตัวแปร | Type | คำอธิบาย |
355
- |--------|------|----------|
356
- | `paperId` | `string` | ID ของกระดาษ (ใช้สำหรับ key ต้องไม่ซ้ำ) |
357
- | `paperName` | `string` | ชื่อกระดาษ เช่น `"A3"`, `"A4"` |
358
- | `paperWidth` | `number` | ความกว้างกระดาษ (mm) |
359
- | `paperHeight` | `number` | ความสูงกระดาษ (mm) |
360
-
361
- ---
362
-
363
- ### `AutoLayoutModel`
364
-
365
- ระบุ model กล่องที่จะจัดวาง
366
-
367
- ```tsx
368
- import type { AutoLayoutModel } from "@lucablockltd/ultimate-packaging";
369
- ```
370
-
371
- | ตัวแปร | Type | คำอธิบาย |
372
- |--------|------|----------|
373
- | `modelId` | `string` | ID ของ model เช่น `"BECF-1010A"`, `"BECF-11D01"` |
374
- | `attributes` | `Record<string, number>` | ขนาดกล่อง |
375
-
376
- ---
377
-
378
- ### `AutoLayoutResult`
379
-
380
- ผลลัพธ์รวมจากการคำนวณ auto-layout
381
-
382
- ```tsx
383
- import type { AutoLayoutResult } from "@lucablockltd/ultimate-packaging";
384
- ```
385
-
386
- | ตัวแปร | Type | คำอธิบาย |
387
- |--------|------|----------|
388
- | `papers` | `AutoLayoutPaperResult[]` | ผลลัพธ์แต่ละกระดาษ (เรียงจากประหยัดที่สุดไปน้อยสุด) |
389
- | `totalProduced` | `number` | จำนวนกล่องที่ผลิตได้ทั้งหมด |
390
- | `totalSheets` | `number` | จำนวนแผ่นกระดาษที่ต้องใช้ทั้งหมด |
391
- | `remainingNeeded` | `number` | จำนวนกล่องที่ยังขาดอยู่ |
392
- | `recommendedPaperId` | `string \| null` | paperId ของกระดาษที่แนะนำ (ประหยัดที่สุด) |
393
-
394
- ---
395
-
396
- ### `AutoLayoutPaperResult`
397
-
398
- ผลลัพธ์การจัดวางบนกระดาษแต่ละแผ่น
399
-
400
- ```tsx
401
- import type { AutoLayoutPaperResult } from "@lucablockltd/ultimate-packaging";
402
- ```
403
-
404
- | ตัวแปร | Type | คำอธิบาย |
405
- |--------|------|----------|
406
- | `paperId` | `string` | ID ของกระดาษ |
407
- | `paperName` | `string` | ชื่อกระดาษ |
408
- | `paperWidth` | `number` | ความกว้างกระดาษ (mm) |
409
- | `paperHeight` | `number` | ความสูงกระดาษ (mm) |
410
- | `perSheet` | `number` | จำนวนกล่องที่วางได้ต่อแผ่น |
411
- | `totalSheets` | `number` | จำนวนแผ่นที่ต้องใช้ |
412
- | `totalProduced` | `number` | จำนวนกล่องที่ผลิตได้ทั้งหมด |
413
- | `excessCount` | `number` | จำนวนกล่องที่เกิน (ผลิตเกินจากที่สั่ง) |
414
- | `wastePercent` | `number` | เปอร์เซ็นต์เศษกระดาษเหลือทิ้ง |
415
- | `independentSheets` | `number` | จำนวนแผ่นที่ต้องใช้ (คำนวณแยกเฉพาะกระดาษขนาดนี้) |
416
- | `independentTotalArea` | `number` | พื้นที่กระดาษทั้งหมดที่ใช้ (mm²) |
417
- | `placements` | `AutoLayoutPlacement[]` | ตำแหน่งวาง dieline แต่ละชิ้นบนกระดาษ |
418
- | `gripperSide` | `GripperSide` | ด้านที่ gripper จับ |
419
-
420
- ---
421
-
422
- ### `AutoLayoutPlacement`
423
-
424
- ตำแหน่งวาง dieline ชิ้นหนึ่งบนกระดาษ
425
-
426
- ```tsx
427
- import type { AutoLayoutPlacement } from "@lucablockltd/ultimate-packaging";
428
- ```
429
-
430
- | ตัวแปร | Type | คำอธิบาย |
431
- |--------|------|----------|
432
- | `x` | `number` | ตำแหน่ง x บนกระดาษ (mm) |
433
- | `y` | `number` | ตำแหน่ง y บนกระดาษ (mm) |
434
- | `rotation` | `number` | องศาหมุน (0, 90, 180, 270) |
435
-
436
- ---
437
-
438
- ### `GetAttributesResult`
439
-
440
- ผลลัพธ์จาก `ref.getAttributes()` ของ MODEL component
441
-
442
- ```tsx
443
- import type { GetAttributesResult } from "@lucablockltd/ultimate-packaging";
444
- ```
445
-
446
- | ตัวแปร | Type | คำอธิบาย |
447
- |--------|------|----------|
448
- | `modelId` | `string` | ID ของ model |
449
- | `overallWidth` | `number` | ความกว้างรวมของ dieline ทั้งแผ่น (mm) |
450
- | `overallHeight` | `number` | ความสูงรวมของ dieline ทั้งแผ่น (mm) |
451
- | `...attributes` | `number` | ค่า attributes ทั้งหมดของ model นั้นๆ |
452
-
453
- ---
454
-
455
- ### `ExportImageOptions`
456
-
457
- ตัวเลือกสำหรับ export รูปภาพจาก MODEL component
458
-
459
- ```tsx
460
- import type { ExportImageOptions } from "@lucablockltd/ultimate-packaging";
461
- ```
462
-
463
- | ตัวแปร | Type | คำอธิบาย |
464
- |--------|------|----------|
465
- | `isShowDimension` | `boolean` | แสดงเส้นบอกขนาดในรูปที่ export หรือไม่ |
466
- | `originalSize` | `boolean` | export ขนาดจริง (true) หรือขนาดตามหน้าจอ (false) |
467
-
468
- ---
469
-
470
- ### `ModelThemeConfig`
471
-
472
- ปรับแต่งสี dieline สำหรับ MODEL component
473
-
474
- ```tsx
475
- import type { ModelThemeConfig } from "@lucablockltd/ultimate-packaging";
476
- ```
477
-
478
- | ตัวแปร | Type | ค่าเริ่มต้น | คำอธิบาย |
479
- |--------|------|-------------|----------|
480
- | `colorBackground` | `string` | `"#FAFAFA"` | สีพื้นหลัง canvas |
481
- | `colorDieLine` | `string` | `"#FF0000"` | สีเส้นตัด (cut line) |
482
- | `colorFoldLine` | `string` | `"#00FF00"` | สีเส้นพับ (crease line) |
483
-
484
- ---
485
-
486
- ### `AutoLayoutThemeConfig`
487
-
488
- ปรับแต่งสีสำหรับ AUTO_LAYOUT component
489
-
490
- ```tsx
491
- import type { AutoLayoutThemeConfig } from "@lucablockltd/ultimate-packaging";
492
- ```
493
-
494
- | ตัวแปร | Type | ค่าเริ่มต้น | คำอธิบาย |
495
- |--------|------|-------------|----------|
496
- | `colorBackground` | `string` | `"#F5F5F5"` | สีพื้นหลัง canvas |
497
- | `colorPaperFill` | `string` | `"#FFFFFF"` | สีพื้นกระดาษ |
498
- | `colorPaperStroke` | `string` | `"#999999"` | สีขอบกระดาษ |
499
- | `colorGriper` | `string` | `"#228B22"` | สีพื้นที่ gripper |
500
- | `colorSpacing` | `string` | `"#f54278"` | สีพื้นที่ spacing ซ้าย-ขวา |
501
- | `colorDistanceLine` | `string` | `"#0088FF"` | สีเส้นระยะห่างระหว่าง dieline |
502
- | `colorDieLine` | `string` | `"#FF0000"` | สีเส้นตัด |
503
- | `colorFoldLine` | `string` | `"#00FF00"` | สีเส้นพับ |
504
- | `colorLabel` | `string` | `"#333333"` | สีข้อความ label |
505
-
506
- ---
507
-
508
- ### `ModelMode`
509
-
510
- โหมดการแสดงผลของ MODEL component
511
-
512
- | ค่า | คำอธิบาย |
513
- |-----|----------|
514
- | `"DIE_LINE"` | แสดง dieline แบบมี canvas (zoom/pan ได้) |
515
- | `"3D"` | แสดงแบบ 3 มิติ (ยังไม่พร้อมใช้งาน) |
516
- | `"AUTO_LAYOUT"` | แสดง dieline แบบ SVG ตรงๆ ไม่มี canvas |
517
-
518
- ---
519
-
520
- ### `GripperSide`
521
-
522
- ด้านที่ gripper จับกระดาษ
523
-
524
- | ค่า | คำอธิบาย |
525
- |-----|----------|
526
- | `"top"` | ด้านบน |
527
- | `"bottom"` | ด้านล่าง |
528
- | `"left"` | ด้านซ้าย |
529
- | `"right"` | ด้านขวา |
530
-
531
- ---
532
-
533
- ### `PackagingModel`
534
-
535
- ข้อมูล model กล่องจาก `modelList`
536
-
537
- | ตัวแปร | Type | คำอธิบาย |
538
- |--------|------|----------|
539
- | `id` | `string` | ID ของ model เช่น `"BECF-1010A"` |
540
- | `name` | `string` | ชื่อ model เช่น `"Tuck End Box BECF-1010A"` |
541
- | `dimension` | `ModelMode[]` | โหมดที่ model รองรับ |
542
- | `attributes` | `Record<string, number>` | ค่าเริ่มต้นของขนาดกล่อง |
543
-
544
- ---
545
-
546
- ## `configurePackaging`
547
-
548
- ตั้งค่า theme กลางที่เดียว ทุก component จะใช้ค่าจากที่นี่โดยอัตโนมัติ
549
-
550
- ```tsx
551
- import { configurePackaging } from "@lucablockltd/ultimate-packaging";
552
-
553
- configurePackaging({
554
- modelTheme: {
555
- colorBackground: "#FFFFFF",
556
- colorDieLine: "#0000FF",
557
- colorFoldLine: "#00AA00",
558
- },
559
- autoLayoutTheme: {
560
- colorBackground: "#EEEEEE",
561
- colorPaperFill: "#FFFFFF",
562
- colorGriper: "#336633",
563
- },
564
- });
565
- ```
566
-
567
- - เรียกครั้งเดียวตอน app เริ่มต้น (เช่นใน `App.tsx` หรือ `layout.tsx`)
568
- - ใส่แค่บาง property ก็ได้ — property ที่ไม่ใส่จะใช้ค่าเริ่มต้น
569
- - ไม่เรียก `configurePackaging()` เลยก็ได้ — ทุกอย่างใช้ค่าเริ่มต้น
570
- - รองรับ Next.js (ไม่ใช้ DOM/browser API)
571
-
572
- ---
573
-
574
- ## Constants (ค่าคงที่)
575
-
576
- ### `modelList`
577
-
578
- รายการ model ทั้งหมดที่ library รองรับ
579
-
580
- ```tsx
581
- import { modelList } from "@lucablockltd/ultimate-packaging";
582
-
583
- // [
584
- // { id: "BECF-1010A", name: "Tuck End Box BECF-1010A", ... },
585
- // { id: "BECF-1030A", name: "Tuck End Box BECF-1030A", ... },
586
- // { id: "BECF-1040A", name: "Tuck End Box BECF-1040A", ... },
587
- // { id: "BECF-11D01", name: "Standard Box BECF-11D01", ... },
588
- // ]
589
- ```
590
-
591
- ### `BECF_1010A_DEFAULT_ATTRIBUTES`
592
-
593
- ```tsx
594
- import { BECF_1010A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
595
- // { length: 60, width: 25, height: 100, closurePanel: 25, glueArea: 15, dustFlap: 15, tuckFlap: 15 }
596
- ```
597
-
598
- ### `BECF_1030A_DEFAULT_ATTRIBUTES`
599
-
600
- ```tsx
601
- import { BECF_1030A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
602
- // { length: 105, width: 50, height: 155, closurePanel: 50, glueArea: 15, dustFlap: 25, tuckFlap: 14 }
603
- ```
604
-
605
- ### `BECF_1040A_DEFAULT_ATTRIBUTES`
606
-
607
- ```tsx
608
- import { BECF_1040A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
609
- // { length: 56, width: 56, height: 150, closurePanel: 56, glueArea: 15, dustFlap: 30, tuckFlap: 14 }
610
- ```
611
-
612
- ### `BECF_11D01_DEFAULT_ATTRIBUTES`
613
-
614
- ```tsx
615
- import { BECF_11D01_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
616
- // { length: 100, width: 50, height: 150, flapHeight: 50, glueArea: 13 }
617
- ```
618
-
619
- ### `MODEL_THEME_CONFIG`
620
-
621
- ```tsx
622
- import { MODEL_THEME_CONFIG } from "@lucablockltd/ultimate-packaging";
623
- // { colorBackground: "#FAFAFA", colorDieLine: "#FF0000", colorFoldLine: "#00FF00" }
624
- ```
625
-
626
- ### `AUTO_LAYOUT_THEME_CONFIG`
627
-
628
- ```tsx
629
- import { AUTO_LAYOUT_THEME_CONFIG } from "@lucablockltd/ultimate-packaging";
630
- // { colorBackground: "#F5F5F5", colorPaperFill: "#FFFFFF", colorPaperStroke: "#999999", ... }
631
- ```
632
-
633
- ---
634
-
635
- ## Utilities (ฟังก์ชันช่วย)
636
-
637
- ### `calculateAutoLayout`
638
-
639
- คำนวณการจัดวาง dieline บนกระดาษ — เป็น pure function เรียกใช้ได้โดยไม่ต้องมี component
640
-
641
- ```tsx
642
- import { calculateAutoLayout } from "@lucablockltd/ultimate-packaging";
643
- import type { AutoLayoutConfig, AutoLayoutResult } from "@lucablockltd/ultimate-packaging";
644
-
645
- const config: AutoLayoutConfig = {
646
- papers: [
647
- { paperId: "1", paperName: "A3", paperWidth: 420, paperHeight: 297 },
648
- ],
649
- model: {
650
- modelId: "BECF-1010A",
651
- attributes: { length: 60, width: 25, height: 100, closurePanel: 25, glueArea: 15, dustFlap: 15, tuckFlap: 15 },
652
- },
653
- quantity: 100,
654
- layoutDistance: 3,
655
- spacing: 5,
656
- griper: 10,
657
- colorbarHeight: 5,
658
- isShowColorbar: false,
659
- };
660
-
661
- const result: AutoLayoutResult = calculateAutoLayout(config);
662
- console.log(result.papers[0].perSheet); // จำนวนต่อแผ่น
663
- console.log(result.papers[0].independentSheets); // จำนวนแผ่นที่ต้องใช้
664
- console.log(result.papers[0].wastePercent); // เปอร์เซ็นต์เศษเหลือ
665
- ```
666
-
667
- ---
668
-
669
- ## ตัวอย่างการใช้งาน
670
-
671
- ### ตัวอย่าง 1: แสดง Dieline อย่างเดียว
672
-
673
- ```tsx
674
- import { useRef, useState } from "react";
675
- import { MODEL_BECF_1010A, BECF_1010A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
676
- import type { ModelBecf1010aRef, TuckEndBoxAttributes } from "@lucablockltd/ultimate-packaging";
677
-
678
- function DielinePage() {
679
- const modelRef = useRef<ModelBecf1010aRef>(null);
680
- const [attributes, setAttributes] = useState<TuckEndBoxAttributes>({
681
- ...BECF_1010A_DEFAULT_ATTRIBUTES,
682
- });
683
-
684
- const handleExport = async () => {
685
- if (!modelRef.current) return;
686
- const blob = await modelRef.current.exportImage({
687
- isShowDimension: true,
688
- originalSize: true,
689
- });
690
- const url = URL.createObjectURL(blob);
691
- window.open(url);
692
- };
693
-
694
- return (
695
- <div>
696
- <MODEL_BECF_1010A
697
- ref={modelRef}
698
- attributes={attributes}
699
- unit="mm"
700
- mode="DIE_LINE"
701
- isShowDimensions={true}
702
- />
703
- <button onClick={handleExport}>Export รูป</button>
704
- <button onClick={() => modelRef.current?.fitView()}>Fit View</button>
705
- </div>
706
- );
707
- }
708
- ```
709
-
710
- ### ตัวอย่าง 2: Standard Box
711
-
712
- ```tsx
713
- import { useRef } from "react";
714
- import { MODEL_BECF_11D01, BECF_11D01_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
715
- import type { ModelBecf11d01Ref } from "@lucablockltd/ultimate-packaging";
716
-
717
- function StandardBoxPage() {
718
- const modelRef = useRef<ModelBecf11d01Ref>(null);
719
-
720
- return (
721
- <MODEL_BECF_11D01
722
- ref={modelRef}
723
- attributes={{ ...BECF_11D01_DEFAULT_ATTRIBUTES }}
724
- unit="mm"
725
- mode="DIE_LINE"
726
- isShowDimensions={true}
727
- />
728
- );
729
- }
730
- ```
731
-
732
- ### ตัวอย่าง 3: Auto Layout จัดวางบนกระดาษ
733
-
734
- ```tsx
735
- import { useRef, useState } from "react";
736
- import { AUTO_LAYOUT, BECF_1010A_DEFAULT_ATTRIBUTES } from "@lucablockltd/ultimate-packaging";
737
- import type { AutoLayoutRef, AutoLayoutConfig, AutoLayoutResult, AutoLayoutPaperResult } from "@lucablockltd/ultimate-packaging";
738
-
739
- function AutoLayoutPage() {
740
- const layoutRef = useRef<AutoLayoutRef>(null);
741
- const [config, setConfig] = useState<AutoLayoutConfig | null>(null);
742
- const [result, setResult] = useState<AutoLayoutResult | null>(null);
743
- const [modifiedPapers, setModifiedPapers] = useState<AutoLayoutPaperResult[]>([]);
744
-
745
- const handleCalculate = () => {
746
- setConfig({
747
- papers: [
748
- { paperId: "a3", paperName: "A3", paperWidth: 420, paperHeight: 297 },
749
- { paperId: "a4", paperName: "A4", paperWidth: 210, paperHeight: 297 },
750
- ],
751
- model: {
752
- modelId: "BECF-1010A",
753
- attributes: { ...BECF_1010A_DEFAULT_ATTRIBUTES },
754
- },
755
- quantity: 100,
756
- layoutDistance: 3,
757
- spacing: 5,
758
- griper: 10,
759
- colorbarHeight: 5,
760
- isShowColorbar: false,
761
- });
762
- };
763
-
764
- return (
765
- <div>
766
- <button onClick={handleCalculate}>คำนวณ</button>
767
-
768
- {result && result.papers.map((paper) => (
769
- <div key={paper.paperId}>
770
- <strong>{paper.paperName}</strong>
771
- <span>{paper.perSheet} ชิ้น/แผ่น · {paper.independentSheets} แผ่น · เศษ {paper.wastePercent}%</span>
772
- </div>
773
- ))}
774
-
775
- <AUTO_LAYOUT
776
- ref={layoutRef}
777
- config={config}
778
- onResult={setResult}
779
- onModifiedPapers={setModifiedPapers}
780
- />
781
- </div>
782
- );
783
- }
784
- ```
785
-
786
- ---
787
-
788
- ## โครงสร้างโปรเจกต์
789
-
790
- ```
791
- ultimate-packaging/
792
- ├── src/ # Source code (library)
793
- │ ├── components/ # React components
794
- │ │ ├── dieline/ # Dieline rendering (pure SVG generation + React)
795
- │ │ │ ├── tuck-end-boxes/ # BECF-1010A, 1030A, 1040A
796
- │ │ │ └── standard-boxes/ # BECF-11D01
797
- │ │ ├── model/ # Model wrappers (mode switching)
798
- │ │ ├── auto-layout/ # Auto-layout per model
799
- │ │ └── shared/ # Shared components (auto-layout engine, colorbar, gripper)
800
- │ ├── statics/ # Default attributes, model list, theme configs
801
- │ ├── types/ # TypeScript type definitions
802
- │ ├── utils/ # Utility functions (calculateAutoLayout, exportDimension)
803
- │ └── index.ts # Main export
804
- ├── demo/ # Demo app (Vite + React) — ไม่รวมใน lib
805
- ├── references/ # Reference files (SVG/PDF/DXF templates, inspector images) — ไม่รวมใน lib
806
- ├── tools/ # Standalone tools
807
- │ └── playwright-inspector/ # Playwright-based dieline inspector (แยก dependencies)
808
- ├── dist/ # Built output (auto-generated)
809
- ├── package.json
810
- ├── tsconfig.json
811
- └── tsup.config.ts
812
- ```
813
-
814
- ---
815
-
816
- ## Model ที่รองรับ
817
-
818
- | Model ID | ชื่อ | ประเภท | คำอธิบาย |
819
- |----------|------|--------|----------|
820
- | `BECF-1010A` | Tuck End Box BECF-1010A | Tuck End | กล่อง tuck end box มาตรฐาน ฝาเสียบด้านเดียว |
821
- | `BECF-1030A` | Tuck End Box BECF-1030A | Tuck End | กล่อง tuck end box ฝาเสียบทั้งสองด้าน |
822
- | `BECF-1040A` | Tuck End Box BECF-1040A | Tuck End | กล่อง tuck end box ฝาเสียบทั้งสองด้าน (แบบ B) |
823
- | `BECF-11D01` | Standard Box BECF-11D01 | Standard | กล่องมาตรฐาน 4 ฝา |
824
-
825
- ---
826
-
827
- ## สำหรับนักพัฒนา (Developer Guide)
828
-
829
- ### Prerequisites
830
-
831
- - Node.js >= 18
832
- - npm >= 9
833
-
834
- ### เริ่มต้นพัฒนา
835
-
836
- ```bash
837
- # 1. Clone repo
838
- git clone https://github.com/Omadar/ULTIMATE-PACKAGING.git
839
- cd ULTIMATE-PACKAGING
840
-
841
- # 2. ติดตั้ง dependencies
842
- npm install
843
-
844
- # 3. Build library
845
- npm run build
846
-
847
- # 4. รัน demo app (Vite + React)
848
- cd demo && npm install && cd ..
849
- npm run demo
850
- ```
851
-
852
- Demo app จะเปิดที่ `http://localhost:5173` — import ตรงจาก `src/` ผ่าน Vite alias ไม่ต้อง build ใหม่ทุกครั้ง
853
-
854
- ### Scripts ที่มี
855
-
856
- | Script | คำอธิบาย |
857
- |--------|----------|
858
- | `npm run build` | Build library ด้วย tsup → output ไปที่ `dist/` |
859
- | `npm run dev` | Build แบบ watch mode (rebuild อัตโนมัติเมื่อแก้ไฟล์) |
860
- | `npm run demo` | รัน demo app (Vite dev server) |
861
- | `npm run typecheck` | ตรวจสอบ TypeScript ไม่ build |
862
- | `npm run lint` | ตรวจสอบ code style ด้วย ESLint |
863
- | `npm run clean` | ลบ `dist/` folder |
864
-
865
- ### Architecture Pattern
866
-
867
- ทุก model กล่องใช้โครงสร้างเดียวกัน แบ่งเป็น 4 layers:
868
-
869
- ```
870
- src/
871
- ├── components/dieline/<box-type>/<model-id>/
872
- │ ├── generate.ts ← Pure TypeScript (ไม่มี React)
873
- │ │ คำนวณ SVG path, contour, dimensions ทั้งหมด
874
- │ └── index.tsx ← React component
875
- │ Render SVG, จัดการ ref methods, theme
876
- ├── components/model/<box-type>/<model-id>/
877
- │ └── index.tsx ← Model wrapper (thin layer)
878
- │ สลับ mode: DIE_LINE / 3D / AUTO_LAYOUT
879
- └── statics/<box-type>/<model-id>/
880
- └── DEFAULT_ATTRIBUTES.ts ← ค่าเริ่มต้นของขนาดกล่อง
881
- ```
882
-
883
- **หลักการสำคัญ:**
884
-
885
- - `generate.ts` = Pure function ไม่พึ่ง React → ทดสอบง่าย, reuse ได้ใน auto-layout
886
- - `index.tsx` (dieline) = React component ที่ render SVG + จัดการ ref methods (`getAttributes`, `exportImage`, `exportDimension`)
887
- - `index.tsx` (model) = Thin wrapper ทำหน้าที่สลับ mode เท่านั้น
888
- - เส้นตัด (cut) = สีแดง `#FF0000`, เส้นทึบ
889
- - เส้นพับ (crease) = สีเขียว `#00FF00`, เส้นประ
890
- - เส้นบอกขนาด (dimension) = สีดำ, พร้อมข้อความ
891
-
892
- ### วิธีเพิ่ม Model ใหม่
893
-
894
- #### ใช้ Claude Code Skills (แนะนำ)
895
-
896
- โปรเจกต์นี้มี Claude Code Skills สำหรับสร้าง model ใหม่โดยอัตโนมัติ:
897
-
898
- | Skill | คำอธิบาย |
899
- |-------|----------|
900
- | `/create-tuck-end-box-packaging` | สร้างกล่อง Tuck End Box ใหม่ — ระบุ model ID และ dimensions |
901
- | `/create-standard-box-packaging` | สร้างกล่อง Standard Box ใหม่ |
902
- | `/create-auto-layout` | เพิ่ม auto-layout สำหรับ model ที่มีอยู่ |
903
- | `/inspect-packaging` | ตรวจสอบ packaging ที่มีอยู่ — route ไปสกิลที่ถูกต้อง |
904
- | `/playwright-inspector-boxes` | Inspect dieline จาก URL ด้วย Playwright แล้วสร้างสกิลใหม่อัตโนมัติ |
905
-
906
- **ตัวอย่าง:** พิมพ์ `/create-tuck-end-box-packaging` ใน Claude Code แล้วระบุ model ID กับค่า default → สร้างไฟล์ทั้งหมดให้อัตโนมัติ
907
-
908
- #### เพิ่มเอง (Manual)
909
-
910
- 1. **สร้างไฟล์ตาม pattern:**
911
-
912
- ```
913
- src/components/dieline/<box-type>/<model-id>/generate.ts
914
- src/components/dieline/<box-type>/<model-id>/index.tsx
915
- src/components/model/<box-type>/<model-id>/index.tsx
916
- src/statics/<box-type>/<model-id>/DEFAULT_ATTRIBUTES.ts
917
- ```
918
-
919
- 2. **Export จาก `src/components/index.ts`:**
920
-
921
- ```tsx
922
- export { MODEL_<MODEL_ID> } from "./model/<box-type>/<model-id>";
923
- export type { Model<ModelId>Ref, Model<ModelId>Props } from "./model/<box-type>/<model-id>";
924
- ```
925
-
926
- 3. **Export default attributes จาก `src/index.ts`:**
927
-
928
- ```tsx
929
- export { <MODEL_ID>_DEFAULT_ATTRIBUTES } from "./statics/<box-type>/<model-id>/DEFAULT_ATTRIBUTES";
930
- ```
931
-
932
- 4. **เพิ่มใน `src/statics/modelList.ts`:**
933
-
934
- ```tsx
935
- {
936
- id: "<MODEL-ID>",
937
- name: "<Box Type> <MODEL-ID>",
938
- dimension: ["DIE_LINE"],
939
- attributes: { ...<MODEL_ID>_DEFAULT_ATTRIBUTES },
940
- }
941
- ```
942
-
943
- 5. **(ถ้าต้องการ auto-layout)** สร้างไฟล์ใน `src/components/auto-layout/<box-type>/<model-id>/` แล้ว export เพิ่ม
944
-
945
- ### Playwright Inspector (เครื่องมือ inspect dieline)
946
-
947
- ใช้ Playwright เปิดเว็บที่มี dieline แล้วดึงข้อมูล SVG มาวิเคราะห์ — แยก dependencies ออกจาก lib
948
-
949
- ```bash
950
- # ติดตั้ง (ครั้งแรกเท่านั้น)
951
- cd tools/playwright-inspector
952
- npm install
953
-
954
- # ใช้งานผ่าน Claude Code skill
955
- # พิมพ์ /playwright-inspector-boxes แล้วระบุ URL
956
- ```
957
-
958
- **Output:** ไฟล์ทั้งหมดจะอยู่ใน `tools/playwright-inspector/output/` — screenshots, JSON data, scripts
959
-
960
- ### การ Build และ Publish
961
-
962
- Library build ด้วย [tsup](https://tsup.egoist.dev/) — output ทั้ง CommonJS (`.cjs`) และ ESM (`.mjs`) พร้อม TypeScript declarations
963
-
964
- ```bash
965
- npm run build
966
- ```
967
-
968
- **Output ใน `dist/`:**
969
-
970
- | ไฟล์ | Format | คำอธิบาย |
971
- |------|--------|----------|
972
- | `index.cjs` | CommonJS | สำหรับ `require()` |
973
- | `index.mjs` | ESM | สำหรับ `import` |
974
- | `index.d.ts` | Types (CJS) | TypeScript definitions |
975
- | `index.d.mts` | Types (ESM) | TypeScript definitions |
976
- | `*.map` | Source maps | สำหรับ debugging |
977
-
978
- **External dependencies** (ไม่ bundle เข้า lib):
979
- - `react`, `react-dom` — peer dependency
980
- - `jspdf` — runtime dependency
981
-
982
- ### ติดตั้ง lib จาก GitHub
983
-
984
- ผู้ใช้ lib ติดตั้งด้วย:
985
-
986
- ```bash
987
- npm install @lucablockltd/ultimate-packaging
988
- ```
989
-
990
- `prepare` script จะรัน `tsup` อัตโนมัติหลัง install เพื่อ build `dist/`
991
-
992
- > **หมายเหตุ:** ฝั่งผู้ใช้ต้องมี devDependencies ของ tsup ในเครื่อง หรือ commit `dist/` ขึ้น git เพื่อให้ใช้ได้โดยไม่ต้อง build — ดูหัวข้อถัดไป
993
-
994
- ### ทางเลือก: Commit dist/ ขึ้น git
995
-
996
- ถ้าไม่ต้องการให้ฝั่งผู้ใช้ build เอง สามารถ commit `dist/` ขึ้น git ได้:
997
-
998
- ```bash
999
- # ลบ dist ออกจาก .gitignore (ถ้ามี)
1000
- # แล้ว commit dist/
1001
- git add dist/
1002
- git commit -m "chore: include built dist for GitHub install"
1003
- ```
1004
-
1005
- จากนั้นลบ `prepare` script ออกจาก package.json เพื่อไม่ให้ build ซ้ำ
1006
-
1007
- ### โฟลเดอร์ที่ไม่รวมใน lib
1008
-
1009
- | โฟลเดอร์ | คำอธิบาย |
1010
- |-----------|----------|
1011
- | `demo/` | Demo app สำหรับทดสอบ component ตอน dev |
1012
- | `references/diecut-templates/` | ไฟล์ SVG/PDF/DXF ต้นแบบสำหรับอ้างอิง |
1013
- | `references/inspector/` | รูปภาพ reference สำหรับ inspector |
1014
- | `tools/playwright-inspector/` | Playwright tool แยก dependencies |
1015
- | `.claude/skills/` | Claude Code skills สำหรับ automation |
1016
-
1017
- ---
1018
-
1019
- ## License
1020
-
1021
- MIT
3
+ Proprietary software. All rights reserved.
package/package.json CHANGED
@@ -1,7 +1,6 @@
1
1
  {
2
2
  "name": "@lucablockltd/ultimate-packaging",
3
- "version": "1.0.1",
4
- "description": "Ultimate packaging library for React and Next.js",
3
+ "version": "1.0.2",
5
4
  "main": "./dist/index.cjs",
6
5
  "module": "./dist/index.mjs",
7
6
  "types": "./dist/index.d.ts",
@@ -24,10 +23,6 @@
24
23
  "publishConfig": {
25
24
  "access": "public"
26
25
  },
27
- "repository": {
28
- "type": "git",
29
- "url": "git+https://github.com/Omadar/ULTIMATE-PACKAGING.git"
30
- },
31
26
  "scripts": {
32
27
  "build": "tsup",
33
28
  "dev": "tsup --watch",
@@ -51,13 +46,7 @@
51
46
  "typescript": "^5.7.0"
52
47
  },
53
48
  "sideEffects": false,
54
- "license": "MIT",
55
- "keywords": [
56
- "react",
57
- "nextjs",
58
- "typescript",
59
- "components"
60
- ],
49
+ "license": "SEE LICENSE IN LICENSE",
61
50
  "dependencies": {
62
51
  "jspdf": "^4.2.1"
63
52
  }