@printwithsynergy/artwork-pdf-editor 0.1.6 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +62 -0
- package/README.md +63 -2
- package/dist/components/AccessibilityHintsPanel.d.ts +142 -0
- package/dist/components/AccessibilityHintsPanel.d.ts.map +1 -0
- package/dist/components/AccessibilityHintsPanel.js +158 -0
- package/dist/components/AccessibilityHintsPanel.js.map +1 -0
- package/dist/components/AnnotationOverlay.d.ts +142 -0
- package/dist/components/AnnotationOverlay.d.ts.map +1 -0
- package/dist/components/AnnotationOverlay.js +141 -0
- package/dist/components/AnnotationOverlay.js.map +1 -0
- package/dist/components/AnnotationsSidebar.d.ts +98 -0
- package/dist/components/AnnotationsSidebar.d.ts.map +1 -0
- package/dist/components/AnnotationsSidebar.js +100 -0
- package/dist/components/AnnotationsSidebar.js.map +1 -0
- package/dist/components/BarcodeGeneratorPanel.d.ts +58 -0
- package/dist/components/BarcodeGeneratorPanel.d.ts.map +1 -0
- package/dist/components/BarcodeGeneratorPanel.js +91 -0
- package/dist/components/BarcodeGeneratorPanel.js.map +1 -0
- package/dist/components/BraillePanel.d.ts +99 -0
- package/dist/components/BraillePanel.d.ts.map +1 -0
- package/dist/components/BraillePanel.js +221 -0
- package/dist/components/BraillePanel.js.map +1 -0
- package/dist/components/BrandAssetsPanel.d.ts +130 -0
- package/dist/components/BrandAssetsPanel.d.ts.map +1 -0
- package/dist/components/BrandAssetsPanel.js +125 -0
- package/dist/components/BrandAssetsPanel.js.map +1 -0
- package/dist/components/BrandConsistencyPanel.d.ts +140 -0
- package/dist/components/BrandConsistencyPanel.d.ts.map +1 -0
- package/dist/components/BrandConsistencyPanel.js +158 -0
- package/dist/components/BrandConsistencyPanel.js.map +1 -0
- package/dist/components/ComplianceFindingsPanel.d.ts +62 -0
- package/dist/components/ComplianceFindingsPanel.d.ts.map +1 -0
- package/dist/components/ComplianceFindingsPanel.js +118 -0
- package/dist/components/ComplianceFindingsPanel.js.map +1 -0
- package/dist/components/DesignSuggestionsPanel.d.ts +148 -0
- package/dist/components/DesignSuggestionsPanel.d.ts.map +1 -0
- package/dist/components/DesignSuggestionsPanel.js +154 -0
- package/dist/components/DesignSuggestionsPanel.js.map +1 -0
- package/dist/components/DielineParametersPanel.d.ts +62 -0
- package/dist/components/DielineParametersPanel.d.ts.map +1 -0
- package/dist/components/DielineParametersPanel.js +170 -0
- package/dist/components/DielineParametersPanel.js.map +1 -0
- package/dist/components/DielinePreview.d.ts +150 -0
- package/dist/components/DielinePreview.d.ts.map +1 -0
- package/dist/components/DielinePreview.js +146 -0
- package/dist/components/DielinePreview.js.map +1 -0
- package/dist/components/EditorApp.d.ts +39 -5
- package/dist/components/EditorApp.d.ts.map +1 -1
- package/dist/components/EditorApp.js +110 -5
- package/dist/components/EditorApp.js.map +1 -1
- package/dist/components/EditorCanvas.d.ts +51 -2
- package/dist/components/EditorCanvas.d.ts.map +1 -1
- package/dist/components/EditorCanvas.js +117 -48
- package/dist/components/EditorCanvas.js.map +1 -1
- package/dist/components/EmailNotifyPanel.d.ts +165 -0
- package/dist/components/EmailNotifyPanel.d.ts.map +1 -0
- package/dist/components/EmailNotifyPanel.js +211 -0
- package/dist/components/EmailNotifyPanel.js.map +1 -0
- package/dist/components/FileDropZone.d.ts +9 -1
- package/dist/components/FileDropZone.d.ts.map +1 -1
- package/dist/components/FileDropZone.js +53 -5
- package/dist/components/FileDropZone.js.map +1 -1
- package/dist/components/FoldEditorPanel.d.ts +68 -0
- package/dist/components/FoldEditorPanel.d.ts.map +1 -0
- package/dist/components/FoldEditorPanel.js +65 -0
- package/dist/components/FoldEditorPanel.js.map +1 -0
- package/dist/components/FoldPreviewOverlay.d.ts +48 -0
- package/dist/components/FoldPreviewOverlay.d.ts.map +1 -0
- package/dist/components/FoldPreviewOverlay.js +182 -0
- package/dist/components/FoldPreviewOverlay.js.map +1 -0
- package/dist/components/Gs1DigitalLinkPanel.d.ts +103 -0
- package/dist/components/Gs1DigitalLinkPanel.d.ts.map +1 -0
- package/dist/components/Gs1DigitalLinkPanel.js +199 -0
- package/dist/components/Gs1DigitalLinkPanel.js.map +1 -0
- package/dist/components/HistoryPanel.d.ts +39 -0
- package/dist/components/HistoryPanel.d.ts.map +1 -0
- package/dist/components/HistoryPanel.js +72 -0
- package/dist/components/HistoryPanel.js.map +1 -0
- package/dist/components/IccSoftProofOverlay.d.ts +67 -0
- package/dist/components/IccSoftProofOverlay.d.ts.map +1 -0
- package/dist/components/IccSoftProofOverlay.js +119 -0
- package/dist/components/IccSoftProofOverlay.js.map +1 -0
- package/dist/components/ImposePanel.d.ts +71 -0
- package/dist/components/ImposePanel.d.ts.map +1 -0
- package/dist/components/ImposePanel.js +127 -0
- package/dist/components/ImposePanel.js.map +1 -0
- package/dist/components/InksPanel.d.ts +61 -0
- package/dist/components/InksPanel.d.ts.map +1 -0
- package/dist/components/InksPanel.js +84 -0
- package/dist/components/InksPanel.js.map +1 -0
- package/dist/components/JobSetupPanel.d.ts +118 -0
- package/dist/components/JobSetupPanel.d.ts.map +1 -0
- package/dist/components/JobSetupPanel.js +169 -0
- package/dist/components/JobSetupPanel.js.map +1 -0
- package/dist/components/LayersPanel.d.ts.map +1 -1
- package/dist/components/LayersPanel.js +1 -0
- package/dist/components/LayersPanel.js.map +1 -1
- package/dist/components/MarkLibraryPanel.d.ts +131 -0
- package/dist/components/MarkLibraryPanel.d.ts.map +1 -0
- package/dist/components/MarkLibraryPanel.js +184 -0
- package/dist/components/MarkLibraryPanel.js.map +1 -0
- package/dist/components/MisEstimateButton.d.ts +73 -0
- package/dist/components/MisEstimateButton.d.ts.map +1 -0
- package/dist/components/MisEstimateButton.js +57 -0
- package/dist/components/MisEstimateButton.js.map +1 -0
- package/dist/components/NutritionPanel.d.ts +118 -0
- package/dist/components/NutritionPanel.d.ts.map +1 -0
- package/dist/components/NutritionPanel.js +169 -0
- package/dist/components/NutritionPanel.js.map +1 -0
- package/dist/components/PageNavigator.d.ts +26 -0
- package/dist/components/PageNavigator.d.ts.map +1 -0
- package/dist/components/PageNavigator.js +96 -0
- package/dist/components/PageNavigator.js.map +1 -0
- package/dist/components/PaletteManager.d.ts +32 -0
- package/dist/components/PaletteManager.d.ts.map +1 -0
- package/dist/components/PaletteManager.js +89 -0
- package/dist/components/PaletteManager.js.map +1 -0
- package/dist/components/PaletteToSpotPanel.d.ts +122 -0
- package/dist/components/PaletteToSpotPanel.d.ts.map +1 -0
- package/dist/components/PaletteToSpotPanel.js +160 -0
- package/dist/components/PaletteToSpotPanel.js.map +1 -0
- package/dist/components/PreflightAutoFixPanel.d.ts +110 -0
- package/dist/components/PreflightAutoFixPanel.d.ts.map +1 -0
- package/dist/components/PreflightAutoFixPanel.js +119 -0
- package/dist/components/PreflightAutoFixPanel.js.map +1 -0
- package/dist/components/PreflightDiffPanel.d.ts +127 -0
- package/dist/components/PreflightDiffPanel.d.ts.map +1 -0
- package/dist/components/PreflightDiffPanel.js +0 -0
- package/dist/components/PreflightDiffPanel.js.map +1 -0
- package/dist/components/ProcessRulesPanel.d.ts +81 -0
- package/dist/components/ProcessRulesPanel.d.ts.map +1 -0
- package/dist/components/ProcessRulesPanel.js +143 -0
- package/dist/components/ProcessRulesPanel.js.map +1 -0
- package/dist/components/SlackNotifyPanel.d.ts +139 -0
- package/dist/components/SlackNotifyPanel.d.ts.map +1 -0
- package/dist/components/SlackNotifyPanel.js +133 -0
- package/dist/components/SlackNotifyPanel.js.map +1 -0
- package/dist/components/SmartSpotMatchPanel.d.ts +143 -0
- package/dist/components/SmartSpotMatchPanel.d.ts.map +1 -0
- package/dist/components/SmartSpotMatchPanel.js +159 -0
- package/dist/components/SmartSpotMatchPanel.js.map +1 -0
- package/dist/components/SwatchesPicker.d.ts +83 -0
- package/dist/components/SwatchesPicker.d.ts.map +1 -0
- package/dist/components/SwatchesPicker.js +151 -0
- package/dist/components/SwatchesPicker.js.map +1 -0
- package/dist/components/TacOverlay.d.ts +47 -0
- package/dist/components/TacOverlay.d.ts.map +1 -0
- package/dist/components/TacOverlay.js +116 -0
- package/dist/components/TacOverlay.js.map +1 -0
- package/dist/components/TrapEditorPanel.d.ts +52 -0
- package/dist/components/TrapEditorPanel.d.ts.map +1 -0
- package/dist/components/TrapEditorPanel.js +64 -0
- package/dist/components/TrapEditorPanel.js.map +1 -0
- package/dist/components/TrapPreviewOverlay.d.ts +64 -0
- package/dist/components/TrapPreviewOverlay.d.ts.map +1 -0
- package/dist/components/TrapPreviewOverlay.js +120 -0
- package/dist/components/TrapPreviewOverlay.js.map +1 -0
- package/dist/components/VariantMatrixPanel.d.ts +61 -0
- package/dist/components/VariantMatrixPanel.d.ts.map +1 -0
- package/dist/components/VariantMatrixPanel.js +97 -0
- package/dist/components/VariantMatrixPanel.js.map +1 -0
- package/dist/components/VariantMatrixVersionPanel.d.ts +122 -0
- package/dist/components/VariantMatrixVersionPanel.d.ts.map +1 -0
- package/dist/components/VariantMatrixVersionPanel.js +162 -0
- package/dist/components/VariantMatrixVersionPanel.js.map +1 -0
- package/dist/components/WebhookNotifyPanel.d.ts +160 -0
- package/dist/components/WebhookNotifyPanel.d.ts.map +1 -0
- package/dist/components/WebhookNotifyPanel.js +100 -0
- package/dist/components/WebhookNotifyPanel.js.map +1 -0
- package/dist/components/WhiteUnderbasePanel.d.ts +107 -0
- package/dist/components/WhiteUnderbasePanel.d.ts.map +1 -0
- package/dist/components/WhiteUnderbasePanel.js +104 -0
- package/dist/components/WhiteUnderbasePanel.js.map +1 -0
- package/dist/data/dielines.json +35 -0
- package/dist/hooks/useEditorMode.d.ts +25 -5
- package/dist/hooks/useEditorMode.d.ts.map +1 -1
- package/dist/hooks/useEditorMode.js +18 -5
- package/dist/hooks/useEditorMode.js.map +1 -1
- package/dist/index.d.ts +49 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +49 -2
- 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/barcode-scan.d.ts +154 -0
- package/dist/lib/barcode-scan.d.ts.map +1 -0
- package/dist/lib/barcode-scan.js +152 -0
- package/dist/lib/barcode-scan.js.map +1 -0
- package/dist/lib/color-math.d.ts +76 -0
- package/dist/lib/color-math.d.ts.map +1 -0
- package/dist/lib/color-math.js +96 -0
- package/dist/lib/color-math.js.map +1 -0
- package/dist/lib/dieline-template.d.ts +169 -0
- package/dist/lib/dieline-template.d.ts.map +1 -1
- package/dist/lib/dieline-template.js +229 -1
- package/dist/lib/dieline-template.js.map +1 -1
- package/dist/lib/editor-config.d.ts +384 -1
- package/dist/lib/editor-config.d.ts.map +1 -1
- package/dist/lib/editor-config.js +89 -2
- package/dist/lib/editor-config.js.map +1 -1
- package/dist/lib/fold-geometry.d.ts +144 -0
- package/dist/lib/fold-geometry.d.ts.map +1 -0
- package/dist/lib/fold-geometry.js +138 -0
- package/dist/lib/fold-geometry.js.map +1 -0
- package/dist/lib/merge-tokens.d.ts +81 -0
- package/dist/lib/merge-tokens.d.ts.map +1 -0
- package/dist/lib/merge-tokens.js +88 -0
- package/dist/lib/merge-tokens.js.map +1 -0
- package/dist/lib/palette-registry.d.ts +40 -0
- package/dist/lib/palette-registry.d.ts.map +1 -0
- package/dist/lib/palette-registry.js +49 -0
- package/dist/lib/palette-registry.js.map +1 -0
- package/dist/lib/panel-anchor.d.ts +101 -0
- package/dist/lib/panel-anchor.d.ts.map +1 -0
- package/dist/lib/panel-anchor.js +68 -0
- package/dist/lib/panel-anchor.js.map +1 -0
- package/dist/lib/preflight/checks.d.ts.map +1 -1
- package/dist/lib/preflight/checks.js +71 -0
- package/dist/lib/preflight/checks.js.map +1 -1
- package/dist/lib/preflight/types.d.ts.map +1 -1
- package/dist/lib/preflight/types.js +11 -0
- package/dist/lib/preflight/types.js.map +1 -1
- package/dist/lib/rasterize.d.ts +93 -0
- package/dist/lib/rasterize.d.ts.map +1 -0
- package/dist/lib/rasterize.js +117 -0
- package/dist/lib/rasterize.js.map +1 -0
- package/dist/lib/separations-registry.d.ts +99 -0
- package/dist/lib/separations-registry.d.ts.map +1 -0
- package/dist/lib/separations-registry.js +59 -0
- package/dist/lib/separations-registry.js.map +1 -0
- package/dist/lib/unwired.d.ts +29 -0
- package/dist/lib/unwired.d.ts.map +1 -0
- package/dist/lib/unwired.js +58 -0
- package/dist/lib/unwired.js.map +1 -0
- package/package.json +29 -11
- package/dist/components/SeparationsPanel.d.ts +0 -9
- package/dist/components/SeparationsPanel.d.ts.map +0 -1
- package/dist/components/SeparationsPanel.js +0 -168
- package/dist/components/SeparationsPanel.js.map +0 -1
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Props for the X2 history-scrubber panel.
|
|
3
|
+
*
|
|
4
|
+
* The panel is purely presentational — EditorCanvas owns the
|
|
5
|
+
* snapshot stack + the active cursor and threads them in via these
|
|
6
|
+
* props. `onSelect(idx)` seeks the canvas to the chosen snapshot;
|
|
7
|
+
* stack depth is derived from `objectCounts.length` (single source
|
|
8
|
+
* of truth — no separate `entries` prop to keep in sync).
|
|
9
|
+
*
|
|
10
|
+
* `cursor` is 0-indexed; row 0 is the initial canvas state, row N
|
|
11
|
+
* is the most recent commit.
|
|
12
|
+
*
|
|
13
|
+
* @public
|
|
14
|
+
*/
|
|
15
|
+
export type HistoryPanelProps = {
|
|
16
|
+
/** 0-indexed position of the active snapshot. */
|
|
17
|
+
cursor: number;
|
|
18
|
+
/** Per-snapshot object count, in stack order. Length defines the
|
|
19
|
+
* number of rows; the array itself drives the per-row count chip. */
|
|
20
|
+
objectCounts: number[];
|
|
21
|
+
/** Click handler — seek the canvas to the given snapshot index. */
|
|
22
|
+
onSelect: (idx: number) => void;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Vertical list of history snapshots. The newest entry sits at the
|
|
26
|
+
* top; the active cursor is highlighted with the brand color.
|
|
27
|
+
*
|
|
28
|
+
* Stack-size cap is enforced upstream in `EditorCanvas` (see the
|
|
29
|
+
* 100-snapshot ceiling in `commit()`); rendering the entire list
|
|
30
|
+
* here is cheap because the cap keeps the row count bounded.
|
|
31
|
+
*
|
|
32
|
+
* @returns An `<aside>` element containing the history header and
|
|
33
|
+
* one `<button>` per snapshot. Each button is keyed by its
|
|
34
|
+
* snapshot index and reports `aria-current="step"` when it is the
|
|
35
|
+
* active cursor.
|
|
36
|
+
* @public
|
|
37
|
+
*/
|
|
38
|
+
export declare function HistoryPanel({ cursor, objectCounts, onSelect }: HistoryPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
39
|
+
//# sourceMappingURL=HistoryPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HistoryPanel.d.ts","sourceRoot":"","sources":["../../src/components/HistoryPanel.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;GAaG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,iDAAiD;IACjD,MAAM,EAAE,MAAM,CAAC;IACf;0EACsE;IACtE,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,mEAAmE;IACnE,QAAQ,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;CACjC,CAAC;AAgCF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,EAAE,iBAAiB,2CA6CjF"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
"use client";
|
|
3
|
+
import { jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
+
const PANEL_BG = "#1a0f08";
|
|
5
|
+
const BORDER = "#3d1a00";
|
|
6
|
+
const BRAND = "#fc5102";
|
|
7
|
+
const TEXT = "#f4ece6";
|
|
8
|
+
const MUTED = "#888";
|
|
9
|
+
const headerStyle = {
|
|
10
|
+
fontSize: "0.7rem",
|
|
11
|
+
letterSpacing: "0.08em",
|
|
12
|
+
textTransform: "uppercase",
|
|
13
|
+
color: MUTED,
|
|
14
|
+
padding: "0.55rem 0.85rem",
|
|
15
|
+
borderBottom: `1px solid ${BORDER}`,
|
|
16
|
+
fontFamily: "inherit",
|
|
17
|
+
};
|
|
18
|
+
const rowBaseStyle = {
|
|
19
|
+
display: "flex",
|
|
20
|
+
alignItems: "center",
|
|
21
|
+
justifyContent: "space-between",
|
|
22
|
+
width: "100%",
|
|
23
|
+
padding: "0.4rem 0.85rem",
|
|
24
|
+
background: "transparent",
|
|
25
|
+
border: "none",
|
|
26
|
+
cursor: "pointer",
|
|
27
|
+
fontFamily: "inherit",
|
|
28
|
+
fontSize: "0.78rem",
|
|
29
|
+
textAlign: "left",
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Vertical list of history snapshots. The newest entry sits at the
|
|
33
|
+
* top; the active cursor is highlighted with the brand color.
|
|
34
|
+
*
|
|
35
|
+
* Stack-size cap is enforced upstream in `EditorCanvas` (see the
|
|
36
|
+
* 100-snapshot ceiling in `commit()`); rendering the entire list
|
|
37
|
+
* here is cheap because the cap keeps the row count bounded.
|
|
38
|
+
*
|
|
39
|
+
* @returns An `<aside>` element containing the history header and
|
|
40
|
+
* one `<button>` per snapshot. Each button is keyed by its
|
|
41
|
+
* snapshot index and reports `aria-current="step"` when it is the
|
|
42
|
+
* active cursor.
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export function HistoryPanel({ cursor, objectCounts, onSelect }) {
|
|
46
|
+
// Render newest → oldest so the most-recent action is at the top
|
|
47
|
+
// (mirrors the canvas's "future-of-undo is at the top of the
|
|
48
|
+
// stack" mental model). Stack depth comes from objectCounts.length
|
|
49
|
+
// — single source of truth.
|
|
50
|
+
const entries = objectCounts.length;
|
|
51
|
+
const indices = Array.from({ length: entries }, (_, i) => entries - 1 - i);
|
|
52
|
+
return (_jsxs("aside", { style: {
|
|
53
|
+
width: 200,
|
|
54
|
+
background: PANEL_BG,
|
|
55
|
+
borderLeft: `1px solid ${BORDER}`,
|
|
56
|
+
color: TEXT,
|
|
57
|
+
display: "flex",
|
|
58
|
+
flexDirection: "column",
|
|
59
|
+
overflow: "auto",
|
|
60
|
+
flexShrink: 0,
|
|
61
|
+
}, children: [_jsxs("div", { style: headerStyle, children: ["History \u00B7 ", entries, " steps"] }), indices.map((idx) => {
|
|
62
|
+
const active = idx === cursor;
|
|
63
|
+
const count = objectCounts[idx] ?? 0;
|
|
64
|
+
return (_jsxs("button", { type: "button", onClick: () => onSelect(idx), "aria-current": active ? "step" : undefined, style: {
|
|
65
|
+
...rowBaseStyle,
|
|
66
|
+
background: active ? "#241308" : "transparent",
|
|
67
|
+
color: active ? BRAND : TEXT,
|
|
68
|
+
borderLeft: active ? `2px solid ${BRAND}` : "2px solid transparent",
|
|
69
|
+
}, children: [_jsxs("span", { children: ["Step ", idx] }), _jsxs("span", { style: { color: MUTED, fontSize: "0.72rem" }, children: [count, " obj"] })] }, idx));
|
|
70
|
+
})] }));
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=HistoryPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"HistoryPanel.js","sourceRoot":"","sources":["../../src/components/HistoryPanel.tsx"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,YAAY,CAAC;;AA4Bb,MAAM,QAAQ,GAAG,SAAS,CAAC;AAC3B,MAAM,MAAM,GAAG,SAAS,CAAC;AACzB,MAAM,KAAK,GAAG,SAAS,CAAC;AACxB,MAAM,IAAI,GAAG,SAAS,CAAC;AACvB,MAAM,KAAK,GAAG,MAAM,CAAC;AAErB,MAAM,WAAW,GAAkB;IACjC,QAAQ,EAAE,QAAQ;IAClB,aAAa,EAAE,QAAQ;IACvB,aAAa,EAAE,WAAW;IAC1B,KAAK,EAAE,KAAK;IACZ,OAAO,EAAE,iBAAiB;IAC1B,YAAY,EAAE,aAAa,MAAM,EAAE;IACnC,UAAU,EAAE,SAAS;CACtB,CAAC;AAEF,MAAM,YAAY,GAAkB;IAClC,OAAO,EAAE,MAAM;IACf,UAAU,EAAE,QAAQ;IACpB,cAAc,EAAE,eAAe;IAC/B,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,gBAAgB;IACzB,UAAU,EAAE,aAAa;IACzB,MAAM,EAAE,MAAM;IACd,MAAM,EAAE,SAAS;IACjB,UAAU,EAAE,SAAS;IACrB,QAAQ,EAAE,SAAS;IACnB,SAAS,EAAE,MAAM;CAClB,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,YAAY,CAAC,EAAE,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAqB;IAChF,iEAAiE;IACjE,6DAA6D;IAC7D,mEAAmE;IACnE,4BAA4B;IAC5B,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC;IACpC,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,OAAO,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IAE3E,OAAO,CACL,iBACE,KAAK,EAAE;YACL,KAAK,EAAE,GAAG;YACV,UAAU,EAAE,QAAQ;YACpB,UAAU,EAAE,aAAa,MAAM,EAAE;YACjC,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,MAAM;YACf,aAAa,EAAE,QAAQ;YACvB,QAAQ,EAAE,MAAM;YAChB,UAAU,EAAE,CAAC;SACd,aAED,eAAK,KAAK,EAAE,WAAW,gCAAa,OAAO,cAAa,EACvD,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;gBACnB,MAAM,MAAM,GAAG,GAAG,KAAK,MAAM,CAAC;gBAC9B,MAAM,KAAK,GAAG,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;gBACrC,OAAO,CACL,kBAEE,IAAI,EAAC,QAAQ,EACb,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,CAAC,GAAG,CAAC,kBACd,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EACzC,KAAK,EAAE;wBACL,GAAG,YAAY;wBACf,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,aAAa;wBAC9C,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI;wBAC5B,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa,KAAK,EAAE,CAAC,CAAC,CAAC,uBAAuB;qBACpE,aAED,oCAAY,GAAG,IAAQ,EACvB,gBAAM,KAAK,EAAE,EAAE,KAAK,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,aAAG,KAAK,YAAY,KAZjE,GAAG,CAaD,CACV,CAAC;YACJ,CAAC,CAAC,IACI,CACT,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ICC rendering intent — mirrors the four ICC v4 intents that
|
|
3
|
+
* compile-pdf's soft-proof producer accepts.
|
|
4
|
+
*
|
|
5
|
+
* @public
|
|
6
|
+
*/
|
|
7
|
+
export type SoftProofIntent = "perceptual" | "relative-colorimetric" | "saturation" | "absolute-colorimetric";
|
|
8
|
+
/**
|
|
9
|
+
* Result shape returned by an {@link IccSoftProofLoaderFn}. `deltaE`
|
|
10
|
+
* is a per-pixel ImageData (R = clamped deltaE * 4, G/B = 0, A = 255)
|
|
11
|
+
* the overlay paints over the canvas; `max` / `avg` drive the footer
|
|
12
|
+
* chip. Keeping max/avg outside the ImageData lets the host compute
|
|
13
|
+
* them server-side without re-walking the buffer on the client.
|
|
14
|
+
*
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export type IccSoftProofResult = {
|
|
18
|
+
deltaE: ImageData;
|
|
19
|
+
max: number;
|
|
20
|
+
avg: number;
|
|
21
|
+
};
|
|
22
|
+
/**
|
|
23
|
+
* Host-supplied adapter. Receives the rasterized document + source /
|
|
24
|
+
* destination ICC profiles + rendering intent; returns the delta-E
|
|
25
|
+
* heatmap. Rejects on transport errors; the overlay surfaces the
|
|
26
|
+
* message inline.
|
|
27
|
+
*
|
|
28
|
+
* **Identity matters.** The overlay re-fetches whenever the `loader`
|
|
29
|
+
* reference changes; hosts that build the adapter inline should
|
|
30
|
+
* memoize it with `useCallback` so an unrelated parent re-render
|
|
31
|
+
* doesn't trigger a spurious `POST /v1/soft-proof/apply` round-trip.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export type IccSoftProofLoaderFn = (input: {
|
|
36
|
+
documentB64: string;
|
|
37
|
+
sourceProfile: string;
|
|
38
|
+
destinationProfile: string;
|
|
39
|
+
intent: SoftProofIntent;
|
|
40
|
+
}) => Promise<IccSoftProofResult>;
|
|
41
|
+
/**
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export type IccSoftProofOverlayProps = {
|
|
45
|
+
/** Latest rendered document (base64 PDF) or `undefined` while
|
|
46
|
+
* the host has nothing to soft-proof. */
|
|
47
|
+
documentB64: string | undefined;
|
|
48
|
+
/** Source ICC profile name (e.g. `"ISOcoated_v2_eci"`). */
|
|
49
|
+
sourceProfile: string | undefined;
|
|
50
|
+
/** Destination ICC profile name (e.g. `"USWebUncoated"`). */
|
|
51
|
+
destinationProfile: string | undefined;
|
|
52
|
+
/** Rendering intent. Defaults to `"relative-colorimetric"` when
|
|
53
|
+
* the host doesn't supply one. */
|
|
54
|
+
intent?: SoftProofIntent;
|
|
55
|
+
/** Adapter that resolves to the delta-E result. */
|
|
56
|
+
loader: IccSoftProofLoaderFn;
|
|
57
|
+
/** Pixel width of the overlay (= the rasterized canvas width).
|
|
58
|
+
* The overlay draws the deltaE ImageData 1:1. */
|
|
59
|
+
width: number;
|
|
60
|
+
/** Pixel height of the overlay. */
|
|
61
|
+
height: number;
|
|
62
|
+
};
|
|
63
|
+
/**
|
|
64
|
+
* @public
|
|
65
|
+
*/
|
|
66
|
+
export declare function IccSoftProofOverlay({ documentB64, sourceProfile, destinationProfile, intent, loader, width, height, }: IccSoftProofOverlayProps): import("react/jsx-runtime").JSX.Element | null;
|
|
67
|
+
//# sourceMappingURL=IccSoftProofOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IccSoftProofOverlay.d.ts","sourceRoot":"","sources":["../../src/components/IccSoftProofOverlay.tsx"],"names":[],"mappings":"AA0BA;;;;;GAKG;AACH,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,uBAAuB,GACvB,YAAY,GACZ,uBAAuB,CAAC;AAE5B;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,MAAM,EAAE,SAAS,CAAC;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,oBAAoB,GAAG,CAAC,KAAK,EAAE;IACzC,WAAW,EAAE,MAAM,CAAC;IACpB,aAAa,EAAE,MAAM,CAAC;IACtB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,MAAM,EAAE,eAAe,CAAC;CACzB,KAAK,OAAO,CAAC,kBAAkB,CAAC,CAAC;AAElC;;GAEG;AACH,MAAM,MAAM,wBAAwB,GAAG;IACrC;8CAC0C;IAC1C,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC,2DAA2D;IAC3D,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,6DAA6D;IAC7D,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC;uCACmC;IACnC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,mDAAmD;IACnD,MAAM,EAAE,oBAAoB,CAAC;IAC7B;sDACkD;IAClD,KAAK,EAAE,MAAM,CAAC;IACd,mCAAmC;IACnC,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAKF;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,EAClC,WAAW,EACX,aAAa,EACb,kBAAkB,EAClB,MAAgC,EAChC,MAAM,EACN,KAAK,EACL,MAAM,GACP,EAAE,wBAAwB,kDAmG1B"}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
"use client";
|
|
3
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
+
/**
|
|
5
|
+
* Wave 2 PR-6 (C5) — ICC soft-proof overlay.
|
|
6
|
+
*
|
|
7
|
+
* Surfaces compile-pdf's per-pixel delta-E map (source ICC →
|
|
8
|
+
* destination ICC, simulated through the selected rendering intent)
|
|
9
|
+
* as a heat overlay on top of the canvas, plus a footer chip showing
|
|
10
|
+
* `max / avg deltaE`. Workflow:
|
|
11
|
+
*
|
|
12
|
+
* 1. Host rasterizes the active page + collects the source +
|
|
13
|
+
* destination ICC profiles + intent.
|
|
14
|
+
* 2. Host hands the `loader` adapter to the overlay; the adapter
|
|
15
|
+
* POSTs to compile-pdf's `/v1/soft-proof/apply` (Wave 2 PR-G).
|
|
16
|
+
* 3. The overlay paints the returned delta-E ImageData on a
|
|
17
|
+
* positioned canvas, recomputing every time the inputs change.
|
|
18
|
+
*
|
|
19
|
+
* Adapter pattern (matches {@link ComplianceFindingsPanel}): hosts
|
|
20
|
+
* wire the HTTP client themselves so this package stays free of a
|
|
21
|
+
* compile-pdf runtime dep.
|
|
22
|
+
*
|
|
23
|
+
* @public
|
|
24
|
+
*/
|
|
25
|
+
import { useEffect, useRef, useState } from "react";
|
|
26
|
+
const FOOTER_BG = "rgba(0,0,0,0.65)";
|
|
27
|
+
const FOOTER_TEXT = "#f4ece6";
|
|
28
|
+
/**
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export function IccSoftProofOverlay({ documentB64, sourceProfile, destinationProfile, intent = "relative-colorimetric", loader, width, height, }) {
|
|
32
|
+
const canvasRef = useRef(null);
|
|
33
|
+
const [error, setError] = useState(null);
|
|
34
|
+
const [loading, setLoading] = useState(false);
|
|
35
|
+
const [stats, setStats] = useState(null);
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!documentB64 || !sourceProfile || !destinationProfile) {
|
|
38
|
+
setStats(null);
|
|
39
|
+
setError(null);
|
|
40
|
+
// Also clear the in-flight loading state — a request started
|
|
41
|
+
// before the inputs were cleared would otherwise leave the
|
|
42
|
+
// footer chip stuck on "soft-proofing…".
|
|
43
|
+
setLoading(false);
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
let disposed = false;
|
|
47
|
+
// Reset stats + the canvas up front so a slow fetch doesn't
|
|
48
|
+
// leave the previous run's heatmap visible under the
|
|
49
|
+
// "soft-proofing…" footer.
|
|
50
|
+
setStats(null);
|
|
51
|
+
const ctx = canvasRef.current?.getContext("2d");
|
|
52
|
+
if (ctx)
|
|
53
|
+
ctx.clearRect(0, 0, canvasRef.current?.width ?? 0, canvasRef.current?.height ?? 0);
|
|
54
|
+
setLoading(true);
|
|
55
|
+
setError(null);
|
|
56
|
+
// Wrap the loader call in an async IIFE so synchronous throws
|
|
57
|
+
// from the adapter (e.g. host-side input validation) flow into
|
|
58
|
+
// the same `setError` path as a rejected Promise — otherwise
|
|
59
|
+
// the throw would escape the effect and leave the overlay stuck.
|
|
60
|
+
void (async () => {
|
|
61
|
+
try {
|
|
62
|
+
const result = await loader({
|
|
63
|
+
documentB64,
|
|
64
|
+
sourceProfile,
|
|
65
|
+
destinationProfile,
|
|
66
|
+
intent,
|
|
67
|
+
});
|
|
68
|
+
if (disposed)
|
|
69
|
+
return;
|
|
70
|
+
const ctx = canvasRef.current?.getContext("2d");
|
|
71
|
+
if (ctx)
|
|
72
|
+
ctx.putImageData(result.deltaE, 0, 0);
|
|
73
|
+
setStats({ max: result.max, avg: result.avg });
|
|
74
|
+
}
|
|
75
|
+
catch (err) {
|
|
76
|
+
if (disposed)
|
|
77
|
+
return;
|
|
78
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
79
|
+
}
|
|
80
|
+
finally {
|
|
81
|
+
if (!disposed)
|
|
82
|
+
setLoading(false);
|
|
83
|
+
}
|
|
84
|
+
})();
|
|
85
|
+
return () => {
|
|
86
|
+
disposed = true;
|
|
87
|
+
};
|
|
88
|
+
}, [documentB64, sourceProfile, destinationProfile, intent, loader]);
|
|
89
|
+
if (!documentB64 || !sourceProfile || !destinationProfile)
|
|
90
|
+
return null;
|
|
91
|
+
return (_jsxs("div", { "data-testid": "icc-soft-proof-overlay", style: { position: "relative", width, height, pointerEvents: "none" }, children: [_jsx("canvas", { ref: canvasRef, width: width, height: height, style: {
|
|
92
|
+
position: "absolute",
|
|
93
|
+
inset: 0,
|
|
94
|
+
width: "100%",
|
|
95
|
+
height: "100%",
|
|
96
|
+
// Multiply blend so the heatmap reads as a tint over the
|
|
97
|
+
// canvas rather than replacing it — matches how the C4 TAC
|
|
98
|
+
// overlay composites.
|
|
99
|
+
mixBlendMode: "multiply",
|
|
100
|
+
opacity: 0.7,
|
|
101
|
+
} }), _jsx("output", { style: {
|
|
102
|
+
position: "absolute",
|
|
103
|
+
right: 8,
|
|
104
|
+
bottom: 8,
|
|
105
|
+
padding: "2px 8px",
|
|
106
|
+
background: FOOTER_BG,
|
|
107
|
+
color: FOOTER_TEXT,
|
|
108
|
+
borderRadius: 4,
|
|
109
|
+
fontSize: "0.7rem",
|
|
110
|
+
fontFamily: "monospace",
|
|
111
|
+
}, children: loading
|
|
112
|
+
? "soft-proofing…"
|
|
113
|
+
: error
|
|
114
|
+
? `soft-proof failed: ${error}`
|
|
115
|
+
: stats
|
|
116
|
+
? `ΔE max ${stats.max.toFixed(1)} · avg ${stats.avg.toFixed(1)}`
|
|
117
|
+
: null })] }));
|
|
118
|
+
}
|
|
119
|
+
//# sourceMappingURL=IccSoftProofOverlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IccSoftProofOverlay.js","sourceRoot":"","sources":["../../src/components/IccSoftProofOverlay.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wire-shape mirror of `apps/service`'s `ImposeTemplate`. Kept inline
|
|
3
|
+
* here so the published editor package has no runtime dep on
|
|
4
|
+
* `apps/service`; the structural duplication is intentional — a
|
|
5
|
+
* future refactor may centralize this in `@artworkpdf/document-model`.
|
|
6
|
+
*
|
|
7
|
+
* Sheet size is in PDF points (1 pt = 1/72 in) to match the wire
|
|
8
|
+
* boundary; the panel renders human-friendly mm read-outs but stores
|
|
9
|
+
* points so the value can be POSTed to compile-pdf unchanged.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export type ImposePanelValue = {
|
|
14
|
+
sheetWidthPt: number;
|
|
15
|
+
sheetHeightPt: number;
|
|
16
|
+
rows: number;
|
|
17
|
+
cols: number;
|
|
18
|
+
pageMapping?: "sequential" | "repeat";
|
|
19
|
+
gutterMm?: number;
|
|
20
|
+
marginMm?: number;
|
|
21
|
+
registrationMarks?: boolean;
|
|
22
|
+
cropMarks?: boolean;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Pre-populated sheet presets. PDF-points dimensions match standard
|
|
26
|
+
* commercial press sheet sizes used by the dieline library and
|
|
27
|
+
* impose policies. Hosts can add custom presets via the `presets`
|
|
28
|
+
* prop without losing the defaults.
|
|
29
|
+
*
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export type ImposePanelPreset = {
|
|
33
|
+
/** Stable id, used as the `<option>` value. */
|
|
34
|
+
id: string;
|
|
35
|
+
/** Human label rendered in the dropdown. */
|
|
36
|
+
label: string;
|
|
37
|
+
widthPt: number;
|
|
38
|
+
heightPt: number;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export type ImposePanelProps = {
|
|
44
|
+
/** Current template. `undefined` means "no impose configured" —
|
|
45
|
+
* the panel renders preset defaults the user can fill in. */
|
|
46
|
+
value: ImposePanelValue | undefined;
|
|
47
|
+
/** Fires on every change to any field (sheet picker, spinner,
|
|
48
|
+
* toggle, radio). Hosts wire this to the job's `imposeTemplate`
|
|
49
|
+
* field on submission. */
|
|
50
|
+
onChange: (next: ImposePanelValue) => void;
|
|
51
|
+
/** Override the default sheet-size dropdown. The first preset is
|
|
52
|
+
* used as the initial value when `value` is `undefined`. */
|
|
53
|
+
presets?: readonly ImposePanelPreset[];
|
|
54
|
+
};
|
|
55
|
+
/**
|
|
56
|
+
* O1 sheet-imposition builder.
|
|
57
|
+
*
|
|
58
|
+
* Controlled component: surfaces sheet size, rows × cols, gutter /
|
|
59
|
+
* margin in mm, and registration / crop-mark toggles. Renders no
|
|
60
|
+
* chrome of its own — hosts wrap it in a modal, drawer, or
|
|
61
|
+
* right-rail container (matches the `JobSetupPanel` / `TrapEditorPanel`
|
|
62
|
+
* convention).
|
|
63
|
+
*
|
|
64
|
+
* Wire shape uses PDF points everywhere; the panel converts to mm
|
|
65
|
+
* for display so values can be POSTed to compile-pdf's
|
|
66
|
+
* `/v1/impose/apply` endpoint without rescaling.
|
|
67
|
+
*
|
|
68
|
+
* @public
|
|
69
|
+
*/
|
|
70
|
+
export declare function ImposePanel({ value, onChange, presets }: ImposePanelProps): import("react/jsx-runtime").JSX.Element;
|
|
71
|
+
//# sourceMappingURL=ImposePanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImposePanel.d.ts","sourceRoot":"","sources":["../../src/components/ImposePanel.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,CAAC,EAAE,YAAY,GAAG,QAAQ,CAAC;IACtC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF;;;;;;;GAOG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC;AAaF;;GAEG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;kEAC8D;IAC9D,KAAK,EAAE,gBAAgB,GAAG,SAAS,CAAC;IACpC;;+BAE2B;IAC3B,QAAQ,EAAE,CAAC,IAAI,EAAE,gBAAgB,KAAK,IAAI,CAAC;IAC3C;iEAC6D;IAC7D,OAAO,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CACxC,CAAC;AA0CF;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAyB,EAAE,EAAE,gBAAgB,2CA8M3F"}
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
"use client";
|
|
3
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
+
import { useId } from "react";
|
|
5
|
+
const DEFAULT_PRESETS = [
|
|
6
|
+
// Letter (8.5 × 11 in) — 612 × 792 pt
|
|
7
|
+
{ id: "letter", label: "Letter (8.5 × 11 in)", widthPt: 612, heightPt: 792 },
|
|
8
|
+
// Tabloid (11 × 17 in) — 792 × 1224 pt
|
|
9
|
+
{ id: "tabloid", label: "Tabloid (11 × 17 in)", widthPt: 792, heightPt: 1224 },
|
|
10
|
+
// SRA3 (320 × 450 mm) — commercial digital press standard
|
|
11
|
+
{ id: "sra3", label: "SRA3 (320 × 450 mm)", widthPt: 907.09, heightPt: 1275.59 },
|
|
12
|
+
// 28 × 40 in offset sheet
|
|
13
|
+
{ id: "offset-28x40", label: "Offset sheet (28 × 40 in)", widthPt: 2016, heightPt: 2880 },
|
|
14
|
+
];
|
|
15
|
+
const MM_PER_PT = 25.4 / 72;
|
|
16
|
+
/** Convert a PDF-points dimension to millimeters for human-readable
|
|
17
|
+
* display. Storage stays in points so the value can be POSTed to
|
|
18
|
+
* compile-pdf without rescaling. */
|
|
19
|
+
function ptToMm(pt) {
|
|
20
|
+
return pt * MM_PER_PT;
|
|
21
|
+
}
|
|
22
|
+
/** Tolerance for matching a preset by sheet dimensions. PDF-points
|
|
23
|
+
* fractions arise easily — SRA3 is 907.09 / 1275.59 pt — so strict
|
|
24
|
+
* equality breaks against hosts that compute from mm. 0.5 pt is
|
|
25
|
+
* smaller than half a hairline rule, well below user-visible. */
|
|
26
|
+
const PRESET_MATCH_TOLERANCE_PT = 0.5;
|
|
27
|
+
/** Parse a numeric input safely. Returns `fallback` for empty,
|
|
28
|
+
* whitespace-only, or non-finite input (e.g. when the user has
|
|
29
|
+
* typed only `-` mid-edit). Without this guard `Number.parseInt`
|
|
30
|
+
* would surface `NaN` and `Math.max` would propagate it, leaving
|
|
31
|
+
* the panel stuck in an unrecoverable state. */
|
|
32
|
+
function parseIntOr(value, fallback) {
|
|
33
|
+
const n = Number.parseInt(value, 10);
|
|
34
|
+
return Number.isFinite(n) ? n : fallback;
|
|
35
|
+
}
|
|
36
|
+
/** Same NaN-safe contract as {@link parseIntOr} but for floats —
|
|
37
|
+
* used by the gutter / margin spinners which accept 0.1 mm steps. */
|
|
38
|
+
function parseFloatOr(value, fallback) {
|
|
39
|
+
const n = Number.parseFloat(value);
|
|
40
|
+
return Number.isFinite(n) ? n : fallback;
|
|
41
|
+
}
|
|
42
|
+
/** Two-sided clamp: ensure `value` is in `[min, max]`. Used to keep
|
|
43
|
+
* the input handlers honest — the `<input min/max>` attributes only
|
|
44
|
+
* guide the spinner; users can still type out-of-range values
|
|
45
|
+
* directly, and we don't want those to propagate to the wire. */
|
|
46
|
+
function clamp(value, min, max) {
|
|
47
|
+
return Math.min(max, Math.max(min, value));
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* O1 sheet-imposition builder.
|
|
51
|
+
*
|
|
52
|
+
* Controlled component: surfaces sheet size, rows × cols, gutter /
|
|
53
|
+
* margin in mm, and registration / crop-mark toggles. Renders no
|
|
54
|
+
* chrome of its own — hosts wrap it in a modal, drawer, or
|
|
55
|
+
* right-rail container (matches the `JobSetupPanel` / `TrapEditorPanel`
|
|
56
|
+
* convention).
|
|
57
|
+
*
|
|
58
|
+
* Wire shape uses PDF points everywhere; the panel converts to mm
|
|
59
|
+
* for display so values can be POSTed to compile-pdf's
|
|
60
|
+
* `/v1/impose/apply` endpoint without rescaling.
|
|
61
|
+
*
|
|
62
|
+
* @public
|
|
63
|
+
*/
|
|
64
|
+
export function ImposePanel({ value, onChange, presets = DEFAULT_PRESETS }) {
|
|
65
|
+
const sheetId = useId();
|
|
66
|
+
const rowsId = useId();
|
|
67
|
+
const colsId = useId();
|
|
68
|
+
const gutterId = useId();
|
|
69
|
+
const marginId = useId();
|
|
70
|
+
const mappingName = useId();
|
|
71
|
+
const firstPreset = presets[0] ?? DEFAULT_PRESETS[0];
|
|
72
|
+
if (!firstPreset) {
|
|
73
|
+
// Should be unreachable: DEFAULT_PRESETS is non-empty. Defensive
|
|
74
|
+
// fallback keeps TypeScript happy without a non-null assertion.
|
|
75
|
+
throw new Error("ImposePanel: presets must contain at least one entry");
|
|
76
|
+
}
|
|
77
|
+
const current = value ?? {
|
|
78
|
+
sheetWidthPt: firstPreset.widthPt,
|
|
79
|
+
sheetHeightPt: firstPreset.heightPt,
|
|
80
|
+
rows: 2,
|
|
81
|
+
cols: 2,
|
|
82
|
+
pageMapping: "sequential",
|
|
83
|
+
};
|
|
84
|
+
const update = (patch) => onChange({ ...current, ...patch });
|
|
85
|
+
// Match the currently-selected preset by tolerance — hosts that
|
|
86
|
+
// round-trip through mm can produce sub-point fractional drift
|
|
87
|
+
// that strict equality would reject, dropping the dropdown into
|
|
88
|
+
// the "custom" fallback even though the user picked SRA3.
|
|
89
|
+
const selectedPresetId = presets.find((p) => Math.abs(p.widthPt - current.sheetWidthPt) <= PRESET_MATCH_TOLERANCE_PT &&
|
|
90
|
+
Math.abs(p.heightPt - current.sheetHeightPt) <= PRESET_MATCH_TOLERANCE_PT)?.id ?? "custom";
|
|
91
|
+
return (_jsxs("div", { style: {
|
|
92
|
+
display: "flex",
|
|
93
|
+
flexDirection: "column",
|
|
94
|
+
gap: "0.75rem",
|
|
95
|
+
padding: "0.75rem",
|
|
96
|
+
fontSize: "0.85rem",
|
|
97
|
+
color: "#1f2937",
|
|
98
|
+
background: "#ffffff",
|
|
99
|
+
border: "1px solid #e5e7eb",
|
|
100
|
+
borderRadius: 6,
|
|
101
|
+
minWidth: 280,
|
|
102
|
+
}, children: [_jsxs("label", { htmlFor: sheetId, style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [_jsx("span", { style: { fontWeight: 600 }, children: "Sheet size" }), _jsxs("select", { id: sheetId, value: selectedPresetId, onChange: (e) => {
|
|
103
|
+
const next = presets.find((p) => p.id === e.target.value);
|
|
104
|
+
if (next)
|
|
105
|
+
update({ sheetWidthPt: next.widthPt, sheetHeightPt: next.heightPt });
|
|
106
|
+
}, style: selectStyle, children: [presets.map((p) => (_jsx("option", { value: p.id, children: p.label }, p.id))), selectedPresetId === "custom" && (_jsxs("option", { value: "custom", children: ["Custom (", ptToMm(current.sheetWidthPt).toFixed(0), " \u00D7", " ", ptToMm(current.sheetHeightPt).toFixed(0), " mm)"] }))] })] }), _jsxs("div", { style: { display: "flex", gap: "0.5rem" }, children: [_jsxs("label", { htmlFor: rowsId, style: { display: "flex", flexDirection: "column", gap: "0.25rem", flex: 1 }, children: [_jsx("span", { style: { fontWeight: 600 }, children: "Rows" }), _jsx("input", { id: rowsId, type: "number", min: 1, max: 32, step: 1, value: current.rows, onChange: (e) => update({ rows: clamp(parseIntOr(e.target.value, current.rows), 1, 32) }), style: numberStyle })] }), _jsxs("label", { htmlFor: colsId, style: { display: "flex", flexDirection: "column", gap: "0.25rem", flex: 1 }, children: [_jsx("span", { style: { fontWeight: 600 }, children: "Columns" }), _jsx("input", { id: colsId, type: "number", min: 1, max: 32, step: 1, value: current.cols, onChange: (e) => update({ cols: clamp(parseIntOr(e.target.value, current.cols), 1, 32) }), style: numberStyle })] })] }), _jsxs("div", { style: { display: "flex", gap: "0.5rem" }, children: [_jsxs("label", { htmlFor: gutterId, style: { display: "flex", flexDirection: "column", gap: "0.25rem", flex: 1 }, children: [_jsx("span", { style: { fontWeight: 600 }, children: "Gutter (mm)" }), _jsx("input", { id: gutterId, type: "number", min: 0, max: 100, step: 0.1, value: current.gutterMm ?? 0, onChange: (e) => update({
|
|
107
|
+
gutterMm: clamp(parseFloatOr(e.target.value, current.gutterMm ?? 0), 0, 100),
|
|
108
|
+
}), style: numberStyle })] }), _jsxs("label", { htmlFor: marginId, style: { display: "flex", flexDirection: "column", gap: "0.25rem", flex: 1 }, children: [_jsx("span", { style: { fontWeight: 600 }, children: "Margin (mm)" }), _jsx("input", { id: marginId, type: "number", min: 0, max: 100, step: 0.1, value: current.marginMm ?? 0, onChange: (e) => update({
|
|
109
|
+
marginMm: clamp(parseFloatOr(e.target.value, current.marginMm ?? 0), 0, 100),
|
|
110
|
+
}), style: numberStyle })] })] }), _jsxs("fieldset", { style: { border: "none", padding: 0, margin: 0 }, children: [_jsx("legend", { style: { fontWeight: 600, padding: 0, marginBottom: "0.25rem" }, children: "Page mapping" }), _jsxs("div", { style: { display: "flex", gap: "1rem" }, children: [_jsxs("label", { style: { display: "flex", alignItems: "center", gap: "0.35rem" }, children: [_jsx("input", { type: "radio", name: mappingName, value: "sequential", checked: (current.pageMapping ?? "sequential") === "sequential", onChange: () => update({ pageMapping: "sequential" }) }), "Sequential"] }), _jsxs("label", { style: { display: "flex", alignItems: "center", gap: "0.35rem" }, children: [_jsx("input", { type: "radio", name: mappingName, value: "repeat", checked: current.pageMapping === "repeat", onChange: () => update({ pageMapping: "repeat" }) }), "Repeat page 0"] })] })] }), _jsxs("div", { style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [_jsxs("label", { style: { display: "flex", alignItems: "center", gap: "0.35rem" }, children: [_jsx("input", { type: "checkbox", checked: current.registrationMarks ?? false, onChange: (e) => update({ registrationMarks: e.target.checked }) }), "Registration marks"] }), _jsxs("label", { style: { display: "flex", alignItems: "center", gap: "0.35rem" }, children: [_jsx("input", { type: "checkbox", checked: current.cropMarks ?? false, onChange: (e) => update({ cropMarks: e.target.checked }) }), "Crop marks"] })] })] }));
|
|
111
|
+
}
|
|
112
|
+
const selectStyle = {
|
|
113
|
+
padding: "0.25rem 0.5rem",
|
|
114
|
+
fontSize: "0.8rem",
|
|
115
|
+
border: "1px solid #d1d5db",
|
|
116
|
+
borderRadius: 4,
|
|
117
|
+
background: "#ffffff",
|
|
118
|
+
};
|
|
119
|
+
const numberStyle = {
|
|
120
|
+
padding: "0.25rem 0.5rem",
|
|
121
|
+
fontSize: "0.8rem",
|
|
122
|
+
border: "1px solid #d1d5db",
|
|
123
|
+
borderRadius: 4,
|
|
124
|
+
background: "#ffffff",
|
|
125
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
126
|
+
};
|
|
127
|
+
//# sourceMappingURL=ImposePanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ImposePanel.js","sourceRoot":"","sources":["../../src/components/ImposePanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 2 C1 — inks palette.
|
|
3
|
+
*
|
|
4
|
+
* Surfaces the live separations registered in the document plus the
|
|
5
|
+
* named inks discovered in the active rendered PDF (via the new
|
|
6
|
+
* compile-pdf `POST /v1/separations/list` endpoint, PR-F). Splits
|
|
7
|
+
* cleanly from the existing swatches palette which still handles
|
|
8
|
+
* PANTONE search:
|
|
9
|
+
*
|
|
10
|
+
* - **swatches** (PR-7 / C3): catalogue search, "register as spot"
|
|
11
|
+
* - **inks** (this panel, C1): the live ink list — what plates
|
|
12
|
+
* will the compiler actually produce?
|
|
13
|
+
*
|
|
14
|
+
* Adapter pattern: hosts wire an async function that returns the
|
|
15
|
+
* separations list. This keeps the editor package free of any
|
|
16
|
+
* runtime dep on `apps/service`'s `CompilePdfClient`. The host
|
|
17
|
+
* typically passes
|
|
18
|
+
* `(pdfB64) => client.separationsList(pdfB64).then((r) => r.separations)`.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export type Ink = {
|
|
23
|
+
/** Display name (e.g. "PANTONE 185 C", "Silver", "Cyan"). */
|
|
24
|
+
name: string;
|
|
25
|
+
/** "Separation" or "DeviceN" — mirrors the wire shape. */
|
|
26
|
+
color_space: "Separation" | "DeviceN";
|
|
27
|
+
/** 0-indexed page numbers on which this ink appears. */
|
|
28
|
+
occurs_on_pages: number[];
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Host-supplied adapter. Returns the inks for `pdfB64` (typically by
|
|
32
|
+
* proxying to `CompilePdfClient.separationsList`). Rejects on
|
|
33
|
+
* transport errors; the panel renders the error inline.
|
|
34
|
+
*
|
|
35
|
+
* **Identity matters.** The panel re-fetches whenever the `loader`
|
|
36
|
+
* reference changes (the standard React-effect dependency rule);
|
|
37
|
+
* hosts that build the adapter inline should memoize it with
|
|
38
|
+
* `useCallback` so an unrelated parent re-render doesn't trigger a
|
|
39
|
+
* spurious `POST /v1/separations/list` round-trip.
|
|
40
|
+
*
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export type InksLoaderFn = (pdfB64: string) => Promise<readonly Ink[]>;
|
|
44
|
+
/**
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
export type InksPanelProps = {
|
|
48
|
+
/** Latest rendered PDF — base64, no `data:` prefix. When
|
|
49
|
+
* `undefined` the panel shows an "export first" affordance. */
|
|
50
|
+
pdfB64: string | undefined;
|
|
51
|
+
/** Adapter that resolves to the inks list. */
|
|
52
|
+
loader: InksLoaderFn;
|
|
53
|
+
/** Optional callback fired when the user clicks an ink row;
|
|
54
|
+
* hosts wire this to highlight occurrences on the canvas. */
|
|
55
|
+
onSelect?: (ink: Ink) => void;
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
export declare function InksPanel({ pdfB64, loader, onSelect }: InksPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
61
|
+
//# sourceMappingURL=InksPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InksPanel.d.ts","sourceRoot":"","sources":["../../src/components/InksPanel.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,MAAM,MAAM,GAAG,GAAG;IAChB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;IACb,0DAA0D;IAC1D,WAAW,EAAE,YAAY,GAAG,SAAS,CAAC;IACtC,wDAAwD;IACxD,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,SAAS,GAAG,EAAE,CAAC,CAAC;AAEvE;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;oEACgE;IAChE,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,8CAA8C;IAC9C,MAAM,EAAE,YAAY,CAAC;IACrB;kEAC8D;IAC9D,QAAQ,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,KAAK,IAAI,CAAC;CAC/B,CAAC;AAEF;;GAEG;AACH,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,cAAc,2CA2FrE"}
|