@printwithsynergy/artwork-pdf-editor 0.1.5 → 0.2.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/README.md +63 -2
- package/dist/components/EditorApp.d.ts +23 -4
- package/dist/components/EditorApp.d.ts.map +1 -1
- package/dist/components/EditorApp.js +72 -2
- package/dist/components/EditorApp.js.map +1 -1
- package/dist/components/EditorCanvas.d.ts +21 -1
- package/dist/components/EditorCanvas.d.ts.map +1 -1
- package/dist/components/EditorCanvas.js +23 -52
- package/dist/components/EditorCanvas.js.map +1 -1
- package/dist/components/PageNavigator.d.ts +26 -0
- package/dist/components/PageNavigator.d.ts.map +1 -0
- package/dist/components/PageNavigator.js +91 -0
- package/dist/components/PageNavigator.js.map +1 -0
- package/dist/data/dielines.json +35 -0
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lens/dieline-overlay.d.ts +25 -0
- package/dist/lens/dieline-overlay.d.ts.map +1 -0
- package/dist/lens/dieline-overlay.js +50 -0
- package/dist/lens/dieline-overlay.js.map +1 -0
- package/dist/lens/index.d.ts +27 -0
- package/dist/lens/index.d.ts.map +1 -0
- package/dist/lens/index.js +28 -0
- package/dist/lens/index.js.map +1 -0
- package/dist/lens/preflight-findings.d.ts +21 -0
- package/dist/lens/preflight-findings.d.ts.map +1 -0
- package/dist/lens/preflight-findings.js +82 -0
- package/dist/lens/preflight-findings.js.map +1 -0
- package/dist/lib/dieline-template.d.ts +82 -0
- package/dist/lib/dieline-template.d.ts.map +1 -1
- package/dist/lib/dieline-template.js +66 -1
- package/dist/lib/dieline-template.js.map +1 -1
- package/dist/lib/editor-config.d.ts +0 -1
- package/dist/lib/editor-config.d.ts.map +1 -1
- package/dist/lib/editor-config.js +0 -2
- package/dist/lib/editor-config.js.map +1 -1
- package/package.json +11 -2
package/README.md
CHANGED
|
@@ -70,7 +70,6 @@ Defaults to everything enabled.
|
|
|
70
70
|
```tsx
|
|
71
71
|
<EditorApp
|
|
72
72
|
config={{
|
|
73
|
-
enable_separations_panel: false,
|
|
74
73
|
enable_layers_panel: false,
|
|
75
74
|
enable_source_link: false,
|
|
76
75
|
}}
|
|
@@ -109,7 +108,69 @@ import { getTemplateById } from "@printwithsynergy/artwork-pdf-editor";
|
|
|
109
108
|
const tpl = getTemplateById("standup-pouch-4x6");
|
|
110
109
|
```
|
|
111
110
|
|
|
112
|
-
Hosted routes can deep-link with `?dieline=<id>`.
|
|
111
|
+
Hosted routes can deep-link with `?dieline=<id>`. The demo route also
|
|
112
|
+
accepts:
|
|
113
|
+
|
|
114
|
+
- A bundled multi-page set id (`?dieline=carton-6x4x2-set`) — see
|
|
115
|
+
`TEMPLATE_SETS`.
|
|
116
|
+
- A comma-separated list of template ids
|
|
117
|
+
(`?dieline=carton-6x4x2,carton-6x4x2`).
|
|
118
|
+
|
|
119
|
+
Unknown ids silently fall back to the default template.
|
|
120
|
+
|
|
121
|
+
## Multi-page documents
|
|
122
|
+
|
|
123
|
+
Each page in a multi-page artwork carries its own `objects`, `pageSize`,
|
|
124
|
+
`bleedMm`, and optional `templateId` + `name`. Seed via `initialPages`:
|
|
125
|
+
|
|
126
|
+
```tsx
|
|
127
|
+
import {
|
|
128
|
+
EditorApp,
|
|
129
|
+
getTemplateSetById,
|
|
130
|
+
templateSetToPages,
|
|
131
|
+
} from "@printwithsynergy/artwork-pdf-editor";
|
|
132
|
+
|
|
133
|
+
const set = getTemplateSetById("carton-6x4x2-set");
|
|
134
|
+
const pages = templateSetToPages(set!, 3.175); // 0.125 in bleed
|
|
135
|
+
|
|
136
|
+
<EditorApp demo initialPhase="editor" initialPages={pages} />
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Helpers:
|
|
140
|
+
|
|
141
|
+
- `templateToPage(template, bleedMm?, name?)` — single template → Page.
|
|
142
|
+
- `templatesToPages([{ template, name }], bleedMm?)` — ordered ad-hoc
|
|
143
|
+
set → Page[].
|
|
144
|
+
- `templateSetToPages(set, bleedMm?)` — bundled set → Page[].
|
|
145
|
+
|
|
146
|
+
A `PageNavigator` strip renders above the canvas on desktop and a
|
|
147
|
+
"Pages" section appears in the mobile drawer. Users can switch
|
|
148
|
+
between pages, add (duplicate) pages, and delete pages. Per-page state
|
|
149
|
+
is preserved across switches; each page has its own undo history.
|
|
150
|
+
|
|
151
|
+
## Lens plugins (`/lens` subpath)
|
|
152
|
+
|
|
153
|
+
Hosts that mount [`@printwithsynergy/lens-pdf`](https://www.npmjs.com/package/@printwithsynergy/lens-pdf)
|
|
154
|
+
to display rendered output can register artwork-aware overlays:
|
|
155
|
+
|
|
156
|
+
```tsx
|
|
157
|
+
import { LensPDF } from "@printwithsynergy/lens-pdf";
|
|
158
|
+
import {
|
|
159
|
+
dielineOverlayPlugin,
|
|
160
|
+
preflightFindingsPlugin,
|
|
161
|
+
} from "@printwithsynergy/artwork-pdf-editor/lens";
|
|
162
|
+
|
|
163
|
+
<LensPDF
|
|
164
|
+
pdfUrl={blobUrl}
|
|
165
|
+
plugins={[
|
|
166
|
+
dielineOverlayPlugin({ pages: { 1: { template: tpl, bleedMm: 3.175 } } }),
|
|
167
|
+
preflightFindingsPlugin({ report }),
|
|
168
|
+
]}
|
|
169
|
+
/>
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`@printwithsynergy/lens-pdf` is an **optional** peer dep — only required
|
|
173
|
+
when you import from the `/lens` subpath.
|
|
113
174
|
|
|
114
175
|
## License
|
|
115
176
|
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type EditorMode } from "../hooks/useEditorMode";
|
|
2
|
+
import type { Page } from "../lib/dieline-template";
|
|
2
3
|
import { type EditorConfig } from "../lib/editor-config";
|
|
3
4
|
import { type CanvasObj } from "./EditorCanvas";
|
|
4
5
|
import { type TopBarProps } from "./TopBar";
|
|
@@ -16,22 +17,40 @@ export type EditorAppProps = {
|
|
|
16
17
|
demo?: boolean;
|
|
17
18
|
/** Starting phase. Set `"editor"` to skip the upload step. */
|
|
18
19
|
initialPhase?: Phase;
|
|
19
|
-
/** Seed objects for the canvas — typically from `templateToInitialState`.
|
|
20
|
+
/** Seed objects for the canvas — typically from `templateToInitialState`.
|
|
21
|
+
* Single-page convenience; for multi-page documents pass `initialPages`. */
|
|
20
22
|
initialObjects?: CanvasObj[];
|
|
21
|
-
/** Seed page size for the canvas — typically from `templateToInitialState`.
|
|
23
|
+
/** Seed page size for the canvas — typically from `templateToInitialState`.
|
|
24
|
+
* Single-page convenience; for multi-page documents pass `initialPages`. */
|
|
22
25
|
initialPageSize?: {
|
|
23
26
|
width: number;
|
|
24
27
|
height: number;
|
|
25
28
|
};
|
|
29
|
+
/**
|
|
30
|
+
* Multi-page seed. Each entry is a {@link Page} with its own
|
|
31
|
+
* `objects`, `pageSize`, and `bleedMm`. Takes precedence over the
|
|
32
|
+
* single-page `initialObjects` / `initialPageSize` props when supplied.
|
|
33
|
+
*
|
|
34
|
+
* A `PageNavigator` strip renders above the canvas on desktop and a
|
|
35
|
+
* "Pages" section appears in the mobile drawer; users can switch
|
|
36
|
+
* between pages, add (duplicate) pages, and delete pages. Per-page
|
|
37
|
+
* state (objects, pageSize, bleedMm) is preserved across switches.
|
|
38
|
+
* Each page has its own undo history.
|
|
39
|
+
*
|
|
40
|
+
* Pair with `templatesToPages` / `templateSetToPages` helpers to seed
|
|
41
|
+
* known multi-page documents (e.g. carton front + back).
|
|
42
|
+
*/
|
|
43
|
+
initialPages?: Page[];
|
|
26
44
|
/** Initial mode preference. `"auto"` resolves by viewport. */
|
|
27
45
|
preferMode?: EditorMode | "auto";
|
|
28
46
|
/** Per-instance flag overrides. Merged into mode + global defaults. */
|
|
29
47
|
config?: Partial<EditorConfig>;
|
|
30
|
-
/** Bleed margin in millimetres. Defaults to {@link DEFAULT_BLEED_MM} (0.125 in).
|
|
48
|
+
/** Bleed margin in millimetres. Defaults to {@link DEFAULT_BLEED_MM} (0.125 in).
|
|
49
|
+
* Ignored when `initialPages` is supplied (each page carries its own bleed). */
|
|
31
50
|
bleedMm?: number;
|
|
32
51
|
/** Host-supplied top bar configuration (logo, extra CTAs, etc.). */
|
|
33
52
|
topBar?: Partial<TopBarProps>;
|
|
34
53
|
};
|
|
35
|
-
export declare function EditorApp({ demo, initialPhase, initialObjects, initialPageSize, preferMode, config: configOverrides, bleedMm, topBar, }: EditorAppProps): import("react/jsx-runtime").JSX.Element;
|
|
54
|
+
export declare function EditorApp({ demo, initialPhase, initialObjects, initialPageSize, initialPages, preferMode, config: configOverrides, bleedMm, topBar, }: EditorAppProps): import("react/jsx-runtime").JSX.Element;
|
|
36
55
|
export {};
|
|
37
56
|
//# sourceMappingURL=EditorApp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorApp.d.ts","sourceRoot":"","sources":["../../src/components/EditorApp.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,wBAAwB,CAAC;AAIxE,OAAO,EAAE,KAAK,YAAY,EAAiB,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorApp.d.ts","sourceRoot":"","sources":["../../src/components/EditorApp.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,UAAU,EAAiB,MAAM,wBAAwB,CAAC;AAIxE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,KAAK,YAAY,EAAiB,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,KAAK,SAAS,EAAgB,MAAM,gBAAgB,CAAC;AAI9D,OAAO,EAAU,KAAK,WAAW,EAAE,MAAM,UAAU,CAAC;AAEpD,KAAK,KAAK,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,QAAQ,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;6DACyD;IACzD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,8DAA8D;IAC9D,YAAY,CAAC,EAAE,KAAK,CAAC;IACrB;iFAC6E;IAC7E,cAAc,CAAC,EAAE,SAAS,EAAE,CAAC;IAC7B;iFAC6E;IAC7E,eAAe,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD;;;;;;;;;;;;;OAaG;IACH,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC;IACtB,8DAA8D;IAC9D,UAAU,CAAC,EAAE,UAAU,GAAG,MAAM,CAAC;IACjC,uEAAuE;IACvE,MAAM,CAAC,EAAE,OAAO,CAAC,YAAY,CAAC,CAAC;IAC/B;qFACiF;IACjF,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,oEAAoE;IACpE,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;CAC/B,CAAC;AAEF,wBAAgB,SAAS,CAAC,EACxB,IAAY,EACZ,YAAuB,EACvB,cAAc,EACd,eAAe,EACf,YAAY,EACZ,UAAmB,EACnB,MAAM,EAAE,eAAe,EACvB,OAA0B,EAC1B,MAAM,GACP,EAAE,cAAc,2CA6PhB"}
|
|
@@ -8,10 +8,67 @@ import { usePreflight } from "../hooks/usePreflight";
|
|
|
8
8
|
import { DEFAULT_BLEED_MM } from "../lib/bleed";
|
|
9
9
|
import { resolveConfig } from "../lib/editor-config";
|
|
10
10
|
import { EditorCanvas } from "./EditorCanvas";
|
|
11
|
+
import { PageNavigator } from "./PageNavigator";
|
|
11
12
|
import { FileDropZone } from "./FileDropZone";
|
|
12
13
|
import { PreflightPanel } from "./PreflightPanel";
|
|
13
14
|
import { TopBar } from "./TopBar";
|
|
14
|
-
export function EditorApp({ demo = false, initialPhase = "upload", initialObjects, initialPageSize, preferMode = "auto", config: configOverrides, bleedMm = DEFAULT_BLEED_MM, topBar, }) {
|
|
15
|
+
export function EditorApp({ demo = false, initialPhase = "upload", initialObjects, initialPageSize, initialPages, preferMode = "auto", config: configOverrides, bleedMm = DEFAULT_BLEED_MM, topBar, }) {
|
|
16
|
+
// Multi-page seed wins over the single-page convenience props. We
|
|
17
|
+
// wrap legacy `initialObjects` / `initialPageSize` into a single-page
|
|
18
|
+
// array so the rest of EditorApp can treat everything as multi-page.
|
|
19
|
+
const seededPages = (() => {
|
|
20
|
+
if (initialPages && initialPages.length > 0)
|
|
21
|
+
return initialPages;
|
|
22
|
+
return [
|
|
23
|
+
{
|
|
24
|
+
id: "page-1",
|
|
25
|
+
objects: initialObjects ?? [],
|
|
26
|
+
pageSize: initialPageSize ?? { width: 595, height: 842 },
|
|
27
|
+
bleedMm,
|
|
28
|
+
},
|
|
29
|
+
];
|
|
30
|
+
})();
|
|
31
|
+
const [pages, setPages] = useState(seededPages);
|
|
32
|
+
const [currentPageIndex, setCurrentPageIndex] = useState(0);
|
|
33
|
+
const clampedPageIndex = Math.min(Math.max(currentPageIndex, 0), pages.length - 1);
|
|
34
|
+
// `pages` is seeded with at least one entry and `handleDeletePage`
|
|
35
|
+
// refuses to drop the last one, so `pages[clampedPageIndex]` is always
|
|
36
|
+
// defined. The non-null assertion makes the invariant explicit; a
|
|
37
|
+
// misuse would crash here instead of silently swapping back to the
|
|
38
|
+
// seeded default.
|
|
39
|
+
// biome-ignore lint/style/noNonNullAssertion: pages is non-empty by construction
|
|
40
|
+
const activePage = pages[clampedPageIndex];
|
|
41
|
+
function updateActivePage(patch) {
|
|
42
|
+
setPages((prev) => prev.map((p, i) => (i === clampedPageIndex ? { ...p, ...patch } : p)));
|
|
43
|
+
}
|
|
44
|
+
function handleAddPage() {
|
|
45
|
+
// Duplicate the active page; user can edit / pick a new dieline from there.
|
|
46
|
+
setPages((prev) => {
|
|
47
|
+
const src = prev[clampedPageIndex];
|
|
48
|
+
if (!src)
|
|
49
|
+
return prev;
|
|
50
|
+
const dup = {
|
|
51
|
+
...src,
|
|
52
|
+
id: `page-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`,
|
|
53
|
+
objects: src.objects.map((o) => ({ ...o })),
|
|
54
|
+
};
|
|
55
|
+
const next = [...prev];
|
|
56
|
+
next.splice(clampedPageIndex + 1, 0, dup);
|
|
57
|
+
return next;
|
|
58
|
+
});
|
|
59
|
+
setCurrentPageIndex((i) => i + 1);
|
|
60
|
+
}
|
|
61
|
+
function handleDeletePage() {
|
|
62
|
+
// Deleting the current page should keep the user on the *next* page
|
|
63
|
+
// (now at the same index in the shorter array). Only fall back to the
|
|
64
|
+
// previous page when the deleted one was the last in the list.
|
|
65
|
+
if (pages.length <= 1)
|
|
66
|
+
return;
|
|
67
|
+
const deletedIdx = clampedPageIndex;
|
|
68
|
+
const nextPages = pages.filter((_, i) => i !== deletedIdx);
|
|
69
|
+
setPages(nextPages);
|
|
70
|
+
setCurrentPageIndex(Math.min(deletedIdx, nextPages.length - 1));
|
|
71
|
+
}
|
|
15
72
|
const { mode, setMode } = useEditorMode(preferMode);
|
|
16
73
|
const [phase, setPhase] = useState(initialPhase);
|
|
17
74
|
const [file, setFile] = useState(null);
|
|
@@ -53,7 +110,20 @@ export function EditorApp({ demo = false, initialPhase = "upload", initialObject
|
|
|
53
110
|
fontWeight: 600,
|
|
54
111
|
textDecoration: "none",
|
|
55
112
|
opacity: 0.85,
|
|
56
|
-
}, children: "Try the demo editor (no file needed) \u2192" }))] })), phase === "checking" && (_jsx("p", { style: { color: "#995b30" }, children: "Running preflight checks\u2026" })), phase === "preflight" && report && config.enable_preflight_banner && (_jsx(PreflightPanel, { report: report, onProceed: () => setPhase("editor"), onSendToLint: handleSendToLint })), phase === "preflight" && report && !config.enable_preflight_banner && (_jsx(AutoAdvance, { onContinue: () => setPhase("editor") })), phase === "editor" &&
|
|
113
|
+
}, children: "Try the demo editor (no file needed) \u2192" }))] })), phase === "checking" && (_jsx("p", { style: { color: "#995b30" }, children: "Running preflight checks\u2026" })), phase === "preflight" && report && config.enable_preflight_banner && (_jsx(PreflightPanel, { report: report, onProceed: () => setPhase("editor"), onSendToLint: handleSendToLint })), phase === "preflight" && report && !config.enable_preflight_banner && (_jsx(AutoAdvance, { onContinue: () => setPhase("editor") })), phase === "editor" && activePage && (_jsxs("div", { style: {
|
|
114
|
+
display: "flex",
|
|
115
|
+
flexDirection: "column",
|
|
116
|
+
width: "100%",
|
|
117
|
+
height: "100%",
|
|
118
|
+
}, children: [pages.length > 1 && !isMobile && (_jsx(PageNavigator, { pages: pages, currentPageIndex: currentPageIndex, onSelect: setCurrentPageIndex, onAddPage: handleAddPage, ...(pages.length > 1 ? { onDeletePage: handleDeletePage } : {}), variant: "strip" })), _jsx(EditorCanvas, { file: file, report: report, demo: demo, mode: mode, onModeChange: setMode, config: config, bleedMm: activePage.bleedMm, isMobile: isMobile, menuOpen: menuOpen, onMenuOpenChange: setMenuOpen, initialObjects: activePage.objects, initialPageSize: activePage.pageSize, onObjectsChange: (objects) => updateActivePage({ objects }), onPageSizeChange: (pageSize) => updateActivePage({ pageSize }), onBleedMmChange: (bleedMmValue) => updateActivePage({ bleedMm: bleedMmValue }), prependDrawerSections: pages.length > 1 || isMobile
|
|
119
|
+
? [
|
|
120
|
+
{
|
|
121
|
+
title: "Pages",
|
|
122
|
+
defaultOpen: true,
|
|
123
|
+
content: (_jsx(PageNavigator, { pages: pages, currentPageIndex: currentPageIndex, onSelect: setCurrentPageIndex, onAddPage: handleAddPage, ...(pages.length > 1 ? { onDeletePage: handleDeletePage } : {}), variant: "stack" })),
|
|
124
|
+
},
|
|
125
|
+
]
|
|
126
|
+
: [] }, activePage.id)] }))] }), demo && phase !== "editor" && (_jsx("footer", { style: {
|
|
57
127
|
background: "#1a0f08",
|
|
58
128
|
borderTop: "1px solid #3d1a00",
|
|
59
129
|
padding: "0.5rem 1.25rem",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorApp.js","sourceRoot":"","sources":["../../src/components/EditorApp.tsx"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,YAAY,CAAC;;AAEb,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAC5C,OAAO,EAAmB,aAAa,EAAE,MAAM,wBAAwB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AACnD,OAAO,EAAE,YAAY,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorApp.js","sourceRoot":"","sources":["../../src/components/EditorApp.tsx"],"names":[],"mappings":"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"}
|
|
@@ -42,7 +42,27 @@ type Props = {
|
|
|
42
42
|
isMobile?: boolean;
|
|
43
43
|
menuOpen?: boolean;
|
|
44
44
|
onMenuOpenChange?: (open: boolean) => void;
|
|
45
|
+
/** Fired whenever the canvas's objects change (drawing, drag, transform,
|
|
46
|
+
* delete, undo/redo, applyDieline). Used by the multi-page wrapper to
|
|
47
|
+
* keep the parent's `pages` array in sync. */
|
|
48
|
+
onObjectsChange?: (objects: CanvasObj[]) => void;
|
|
49
|
+
/** Fired whenever the page size changes (template apply, bleed override,
|
|
50
|
+
* uploaded-PDF parse). */
|
|
51
|
+
onPageSizeChange?: (pageSize: {
|
|
52
|
+
width: number;
|
|
53
|
+
height: number;
|
|
54
|
+
}) => void;
|
|
55
|
+
/** Fired whenever the bleed value changes (drawer input or URL prop sync). */
|
|
56
|
+
onBleedMmChange?: (bleedMm: number) => void;
|
|
57
|
+
/** Extra collapsible sections added to the *top* of the mobile drawer
|
|
58
|
+
* (used by `EditorApp` to insert the `PageNavigator` stack when the
|
|
59
|
+
* document is multi-page). */
|
|
60
|
+
prependDrawerSections?: Array<{
|
|
61
|
+
title: string;
|
|
62
|
+
content: import("react").ReactNode;
|
|
63
|
+
defaultOpen?: boolean;
|
|
64
|
+
}>;
|
|
45
65
|
};
|
|
46
|
-
export declare function EditorCanvas({ file, report, demo, initialObjects, initialPageSize, mode, onModeChange, config, bleedMm: bleedMmProp, isMobile, menuOpen, onMenuOpenChange, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
66
|
+
export declare function EditorCanvas({ file, report, demo, initialObjects, initialPageSize, mode, onModeChange, config, bleedMm: bleedMmProp, isMobile, menuOpen, onMenuOpenChange, onObjectsChange, onPageSizeChange, onBleedMmChange, prependDrawerSections, }: Props): import("react/jsx-runtime").JSX.Element;
|
|
47
67
|
export {};
|
|
48
68
|
//# sourceMappingURL=EditorCanvas.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EditorCanvas.d.ts","sourceRoot":"","sources":["../../src/components/EditorCanvas.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"EditorCanvas.d.ts","sourceRoot":"","sources":["../../src/components/EditorCanvas.tsx"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACzD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AA+B9D,KAAK,OAAO,GAAG,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,OAAO,CAAC;AAErD,MAAM,MAAM,SAAS,GAAG;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B;iEAC6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;oEAEgE;IAChE,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB,CAAC;AAMF,KAAK,KAAK,GAAG;IACX,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,MAAM,CAAC,EAAE,eAAe,GAAG,IAAI,CAAC;IAChC,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,cAAc,CAAC,EAAE,SAAS,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACpD,IAAI,CAAC,EAAE,OAAO,GAAG,KAAK,CAAC;IACvB,YAAY,CAAC,EAAE,CAAC,CAAC,EAAE,OAAO,GAAG,KAAK,KAAK,IAAI,CAAC;IAC5C,MAAM,EAAE,YAAY,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C;;mDAE+C;IAC/C,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,KAAK,IAAI,CAAC;IACjD;+BAC2B;IAC3B,gBAAgB,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACzE,8EAA8E;IAC9E,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC5C;;mCAE+B;IAC/B,qBAAqB,CAAC,EAAE,KAAK,CAAC;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,OAAO,OAAO,EAAE,SAAS,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAA;KAAE,CAAC,CAAC;CAC7G,CAAC;AA2IF,wBAAgB,YAAY,CAAC,EAC3B,IAAI,EACJ,MAAM,EACN,IAAY,EACZ,cAAc,EACd,eAAe,EACf,IAAc,EACd,YAAY,EACZ,MAAM,EACN,OAAO,EAAE,WAA8B,EACvC,QAAgB,EAChB,QAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,qBAA0B,GAC3B,EAAE,KAAK,2CAmnCP"}
|
|
@@ -9,7 +9,6 @@ import { templateToInitialState } from "../lib/dieline-template";
|
|
|
9
9
|
import { DielineLibraryModal } from "./DielineLibraryModal";
|
|
10
10
|
import { LayersPanel } from "./LayersPanel";
|
|
11
11
|
import { MobileToolDrawer } from "./MobileToolDrawer";
|
|
12
|
-
import { SeparationsPanel } from "./SeparationsPanel";
|
|
13
12
|
// ── constants ─────────────────────────────────────────────────────────────────
|
|
14
13
|
const SERVICE_URL = (process.env.NEXT_PUBLIC_SERVICE_URL ?? "http://localhost:3001").replace(/\/$/, "");
|
|
15
14
|
const BRAND = "#fc5102";
|
|
@@ -77,7 +76,7 @@ function ObjNode({ obj, selected, onSelect, onDragEnd, onTransformEnd, onDblClic
|
|
|
77
76
|
return null;
|
|
78
77
|
}
|
|
79
78
|
// ── main component ─────────────────────────────────────────────────────────────
|
|
80
|
-
export function EditorCanvas({ file, report, demo = false, initialObjects, initialPageSize, mode = "basic", onModeChange, config, bleedMm: bleedMmProp = DEFAULT_BLEED_MM, isMobile = false, menuOpen = false, onMenuOpenChange, }) {
|
|
79
|
+
export function EditorCanvas({ file, report, demo = false, initialObjects, initialPageSize, mode = "basic", onModeChange, config, bleedMm: bleedMmProp = DEFAULT_BLEED_MM, isMobile = false, menuOpen = false, onMenuOpenChange, onObjectsChange, onPageSizeChange, onBleedMmChange, prependDrawerSections = [], }) {
|
|
81
80
|
const containerRef = useRef(null);
|
|
82
81
|
const stageRef = useRef(null);
|
|
83
82
|
const trRef = useRef(null);
|
|
@@ -102,11 +101,25 @@ export function EditorCanvas({ file, report, demo = false, initialObjects, initi
|
|
|
102
101
|
const imageInputRef = useRef(null);
|
|
103
102
|
// Pro mode state — dieline modal + per-ink visibility filter for separations.
|
|
104
103
|
const [dielineOpen, setDielineOpen] = useState(false);
|
|
105
|
-
const [hiddenInks, setHiddenInks] = useState(new Set());
|
|
106
104
|
// ── sync bleed from prop ────────────────────────────────────────────────────
|
|
107
105
|
useEffect(() => {
|
|
108
106
|
setBleedMm(bleedMmProp);
|
|
109
107
|
}, [bleedMmProp]);
|
|
108
|
+
// ── notify parent of document-state changes ─────────────────────────────────
|
|
109
|
+
// Used by the multi-page wrapper in EditorApp to mirror the active page
|
|
110
|
+
// back into its `pages` array; no-op when the host doesn't pass callbacks.
|
|
111
|
+
useEffect(() => {
|
|
112
|
+
onObjectsChange?.(objects);
|
|
113
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: fire on objects only
|
|
114
|
+
}, [objects]);
|
|
115
|
+
useEffect(() => {
|
|
116
|
+
onPageSizeChange?.(pageSize);
|
|
117
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: fire on pageSize only
|
|
118
|
+
}, [pageSize]);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
onBleedMmChange?.(bleedMm);
|
|
121
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: fire on bleedMm only
|
|
122
|
+
}, [bleedMm]);
|
|
110
123
|
// ── recompute page + dieline when bleed changes ────────────────────────────
|
|
111
124
|
useEffect(() => {
|
|
112
125
|
if (!currentTemplate)
|
|
@@ -597,28 +610,10 @@ export function EditorCanvas({ file, report, demo = false, initialObjects, initi
|
|
|
597
610
|
commit(next);
|
|
598
611
|
setSelectedId(null);
|
|
599
612
|
}
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
next.delete(color);
|
|
605
|
-
else
|
|
606
|
-
next.add(color);
|
|
607
|
-
return next;
|
|
608
|
-
});
|
|
609
|
-
}
|
|
610
|
-
// Objects whose fill/stroke match a hidden ink are rendered with opacity 0
|
|
611
|
-
// for the preview. We don't mutate the actual object — separations preview
|
|
612
|
-
// is non-destructive.
|
|
613
|
-
const visibleObjects = config.enable_separations_panel && hiddenInks.size > 0
|
|
614
|
-
? objects.map((o) => {
|
|
615
|
-
const fillHidden = hiddenInks.has(o.fill.toLowerCase());
|
|
616
|
-
const strokeHidden = hiddenInks.has(o.stroke.toLowerCase());
|
|
617
|
-
if (fillHidden && strokeHidden)
|
|
618
|
-
return { ...o, opacity: 0 };
|
|
619
|
-
return o;
|
|
620
|
-
})
|
|
621
|
-
: objects;
|
|
613
|
+
// Real post-render separations live in the lens-pdf viewer
|
|
614
|
+
// (`SeparationCanvas`, codex-backed). The pre-render RGB approximation
|
|
615
|
+
// we used to do here was misleading and is no longer rendered.
|
|
616
|
+
const visibleObjects = objects;
|
|
622
617
|
// ── render ──────────────────────────────────────────────────────────────────
|
|
623
618
|
const cursor = tool === "select" ? "default" : tool === "image" ? "cell" : "crosshair";
|
|
624
619
|
const exportLabel = exportStatus === "sending"
|
|
@@ -707,24 +702,7 @@ export function EditorCanvas({ file, report, demo = false, initialObjects, initi
|
|
|
707
702
|
fontWeight: 600,
|
|
708
703
|
cursor: exportStatus === "sending" || exportStatus === "polling" ? "wait" : "pointer",
|
|
709
704
|
opacity: exportStatus === "sending" || exportStatus === "polling" ? 0.7 : 1,
|
|
710
|
-
}, children: exportLabel }))] })),
|
|
711
|
-
display: "flex",
|
|
712
|
-
justifyContent: "flex-end",
|
|
713
|
-
padding: "0.4rem 0.75rem",
|
|
714
|
-
background: PANEL_BG,
|
|
715
|
-
borderBottom: `1px solid ${BORDER}`,
|
|
716
|
-
flexShrink: 0,
|
|
717
|
-
}, children: _jsx("button", { type: "button", onClick: handleExport, disabled: exportStatus === "sending" || exportStatus === "polling", style: {
|
|
718
|
-
background: exportStatus === "done" ? "#2e7d32" : exportStatus === "error" ? "#b71c1c" : BRAND,
|
|
719
|
-
color: "#fff",
|
|
720
|
-
border: "none",
|
|
721
|
-
borderRadius: 4,
|
|
722
|
-
padding: "0.35rem 0.95rem",
|
|
723
|
-
fontSize: "0.85rem",
|
|
724
|
-
fontWeight: 600,
|
|
725
|
-
cursor: exportStatus === "sending" || exportStatus === "polling" ? "wait" : "pointer",
|
|
726
|
-
opacity: exportStatus === "sending" || exportStatus === "polling" ? 0.7 : 1,
|
|
727
|
-
}, children: exportLabel }) })), _jsxs("div", { style: { display: "flex", flex: 1, overflow: "hidden" }, children: [config.enable_layers_panel && !isMobile && (_jsx(LayersPanel, { objects: objects, selectedId: selectedId, onSelect: (id) => setSelectedId(id), onReorder: reorderObject, onDelete: (id) => {
|
|
705
|
+
}, children: exportLabel }))] })), _jsxs("div", { style: { display: "flex", flex: 1, overflow: "hidden" }, children: [config.enable_layers_panel && !isMobile && (_jsx(LayersPanel, { objects: objects, selectedId: selectedId, onSelect: (id) => setSelectedId(id), onReorder: reorderObject, onDelete: (id) => {
|
|
728
706
|
commit(objects.filter((o) => o.id !== id));
|
|
729
707
|
if (id === selectedId)
|
|
730
708
|
setSelectedId(null);
|
|
@@ -738,7 +716,7 @@ export function EditorCanvas({ file, report, demo = false, initialObjects, initi
|
|
|
738
716
|
alignItems: "center",
|
|
739
717
|
justifyContent: "center",
|
|
740
718
|
pointerEvents: "none",
|
|
741
|
-
}, children: _jsx("span", { style: { fontSize: "0.8rem", color: "#94a3b8" }, children: "Use the toolbar to draw shapes, add text, or import an image" }) }))] })
|
|
719
|
+
}, children: _jsx("span", { style: { fontSize: "0.8rem", color: "#94a3b8" }, children: "Use the toolbar to draw shapes, add text, or import an image" }) }))] })] }), selected && (_jsxs("div", { style: {
|
|
742
720
|
display: "flex",
|
|
743
721
|
alignItems: "center",
|
|
744
722
|
gap: "1rem",
|
|
@@ -804,6 +782,7 @@ export function EditorCanvas({ file, report, demo = false, initialObjects, initi
|
|
|
804
782
|
if (selected)
|
|
805
783
|
updateSelected({ stroke: hex });
|
|
806
784
|
}, bleedMm: bleedMm, onBleedMmChange: setBleedMm, mode: mode, onModeChange: (m) => onModeChange?.(m), onExport: handleExport, exportLabel: exportLabel, exportBusy: exportStatus === "sending" || exportStatus === "polling", extraSections: [
|
|
785
|
+
...prependDrawerSections,
|
|
807
786
|
...(config.enable_layers_panel
|
|
808
787
|
? [
|
|
809
788
|
{
|
|
@@ -816,14 +795,6 @@ export function EditorCanvas({ file, report, demo = false, initialObjects, initi
|
|
|
816
795
|
},
|
|
817
796
|
]
|
|
818
797
|
: []),
|
|
819
|
-
...(config.enable_separations_panel
|
|
820
|
-
? [
|
|
821
|
-
{
|
|
822
|
-
title: "Separations",
|
|
823
|
-
content: (_jsx(SeparationsPanel, { objects: objects, hidden: hiddenInks, onToggle: toggleInk })),
|
|
824
|
-
},
|
|
825
|
-
]
|
|
826
|
-
: []),
|
|
827
798
|
] }))] }));
|
|
828
799
|
}
|
|
829
800
|
// ── grid overlay ──────────────────────────────────────────────────────────────
|