@printwithsynergy/artwork-pdf-editor 0.2.0 → 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/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 +18 -3
- package/dist/components/EditorApp.d.ts.map +1 -1
- package/dist/components/EditorApp.js +42 -7
- package/dist/components/EditorApp.js.map +1 -1
- package/dist/components/EditorCanvas.d.ts +31 -2
- package/dist/components/EditorCanvas.d.ts.map +1 -1
- package/dist/components/EditorCanvas.js +97 -16
- 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.map +1 -1
- package/dist/components/PageNavigator.js +6 -1
- package/dist/components/PageNavigator.js.map +1 -1
- 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/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/preflight-findings.d.ts.map +1 -1
- package/dist/lens/preflight-findings.js.map +1 -1
- 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 +87 -0
- package/dist/lib/dieline-template.d.ts.map +1 -1
- package/dist/lib/dieline-template.js +163 -0
- package/dist/lib/dieline-template.js.map +1 -1
- package/dist/lib/editor-config.d.ts +384 -0
- package/dist/lib/editor-config.d.ts.map +1 -1
- package/dist/lib/editor-config.js +89 -0
- 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 +20 -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,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Controlled trap-policy shape consumed by the editor. Mirrors
|
|
3
|
+
* `@artworkpdf/document-model`'s `TrapPolicy` minus the runtime dep
|
|
4
|
+
* (the published editor package can't pull in document-model). Keep
|
|
5
|
+
* these in sync; the future structural-dedup follow-up will move both
|
|
6
|
+
* into a shared types module.
|
|
7
|
+
*
|
|
8
|
+
* @public
|
|
9
|
+
*/
|
|
10
|
+
export type TrapEditorValue = {
|
|
11
|
+
widthMm: number;
|
|
12
|
+
mode?: "auto" | "spread" | "choke";
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* @public
|
|
16
|
+
*/
|
|
17
|
+
export type TrapEditorPanelProps = {
|
|
18
|
+
/** Current policy. `undefined` means "no trap policy set" — the
|
|
19
|
+
* panel renders empty defaults the user can fill in. */
|
|
20
|
+
value: TrapEditorValue | undefined;
|
|
21
|
+
/** Fires on every committed change (slider release, select change).
|
|
22
|
+
* Hosts wire this to `document.pages[activeIdx].trapConfig` so the
|
|
23
|
+
* D1 preview overlay (PR-12) updates live as the user adjusts. */
|
|
24
|
+
onChange: (next: TrapEditorValue) => void;
|
|
25
|
+
/** Min width in mm. Defaults to 0 (no trap). */
|
|
26
|
+
minMm?: number;
|
|
27
|
+
/** Max width in mm. Defaults to 1.0 — typical maximum for press
|
|
28
|
+
* trapping. Hosts can raise for specialty work. */
|
|
29
|
+
maxMm?: number;
|
|
30
|
+
/** Step in mm. Defaults to 0.01 mm (one hundredth-millimeter) so
|
|
31
|
+
* fine-grain edits feel natural. */
|
|
32
|
+
stepMm?: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* D2 interactive trap-policy editor.
|
|
36
|
+
*
|
|
37
|
+
* Controlled component: takes the current `TrapEditorValue` and emits
|
|
38
|
+
* the next one on every committed change. Surfaces the two fields the
|
|
39
|
+
* Wave 1 `TrapPolicy` shape supports today — `widthMm` (0–1 mm) and
|
|
40
|
+
* `mode` (`auto` / `spread` / `choke`). Per-edge (top/right/bottom/
|
|
41
|
+
* left) and per-color-pair tables are wired in a follow-up once the
|
|
42
|
+
* compile-pdf trap producer exposes them; the panel layout reserves
|
|
43
|
+
* space for those without committing to their final shape.
|
|
44
|
+
*
|
|
45
|
+
* Renders no chrome of its own — hosts wrap it in whatever modal /
|
|
46
|
+
* drawer / right-rail container fits their layout (matches
|
|
47
|
+
* `JobSetupPanel`'s embedding convention).
|
|
48
|
+
*
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export declare function TrapEditorPanel({ value, onChange, minMm, maxMm, stepMm, }: TrapEditorPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
52
|
+
//# sourceMappingURL=TrapEditorPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrapEditorPanel.d.ts","sourceRoot":"","sources":["../../src/components/TrapEditorPanel.tsx"],"names":[],"mappings":"AAKA;;;;;;;;GAQG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,GAAG,QAAQ,GAAG,OAAO,CAAC;CACpC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;6DACyD;IACzD,KAAK,EAAE,eAAe,GAAG,SAAS,CAAC;IACnC;;uEAEmE;IACnE,QAAQ,EAAE,CAAC,IAAI,EAAE,eAAe,KAAK,IAAI,CAAC;IAC1C,gDAAgD;IAChD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;wDACoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;yCACqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB,CAAC;AAEF;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,eAAe,CAAC,EAC9B,KAAK,EACL,QAAQ,EACR,KAAS,EACT,KAAS,EACT,MAAa,GACd,EAAE,oBAAoB,2CA0FtB"}
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
/**
|
|
6
|
+
* D2 interactive trap-policy editor.
|
|
7
|
+
*
|
|
8
|
+
* Controlled component: takes the current `TrapEditorValue` and emits
|
|
9
|
+
* the next one on every committed change. Surfaces the two fields the
|
|
10
|
+
* Wave 1 `TrapPolicy` shape supports today — `widthMm` (0–1 mm) and
|
|
11
|
+
* `mode` (`auto` / `spread` / `choke`). Per-edge (top/right/bottom/
|
|
12
|
+
* left) and per-color-pair tables are wired in a follow-up once the
|
|
13
|
+
* compile-pdf trap producer exposes them; the panel layout reserves
|
|
14
|
+
* space for those without committing to their final shape.
|
|
15
|
+
*
|
|
16
|
+
* Renders no chrome of its own — hosts wrap it in whatever modal /
|
|
17
|
+
* drawer / right-rail container fits their layout (matches
|
|
18
|
+
* `JobSetupPanel`'s embedding convention).
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
export function TrapEditorPanel({ value, onChange, minMm = 0, maxMm = 1, stepMm = 0.01, }) {
|
|
23
|
+
const widthId = useId();
|
|
24
|
+
const modeId = useId();
|
|
25
|
+
const current = value ?? { widthMm: 0.144, mode: "auto" };
|
|
26
|
+
const updateWidth = (next) => {
|
|
27
|
+
// Clamp to the configured range so a stray pointer-up at the
|
|
28
|
+
// slider edges doesn't propagate an out-of-range value.
|
|
29
|
+
const clamped = Math.max(minMm, Math.min(maxMm, next));
|
|
30
|
+
onChange({ ...current, widthMm: clamped });
|
|
31
|
+
};
|
|
32
|
+
const updateMode = (next) => {
|
|
33
|
+
onChange({ ...current, mode: next });
|
|
34
|
+
};
|
|
35
|
+
return (_jsxs("div", { style: {
|
|
36
|
+
display: "flex",
|
|
37
|
+
flexDirection: "column",
|
|
38
|
+
gap: "0.75rem",
|
|
39
|
+
padding: "0.75rem",
|
|
40
|
+
fontSize: "0.85rem",
|
|
41
|
+
color: "#1f2937",
|
|
42
|
+
background: "#ffffff",
|
|
43
|
+
border: "1px solid #e5e7eb",
|
|
44
|
+
borderRadius: 6,
|
|
45
|
+
minWidth: 240,
|
|
46
|
+
}, children: [_jsxs("label", { htmlFor: widthId, style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [_jsx("span", { style: { fontWeight: 600 }, children: "Trap width" }), _jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5rem" }, children: [_jsx("input", { id: widthId, type: "range", min: minMm, max: maxMm, step: stepMm, value: current.widthMm, onChange: (e) => updateWidth(Number.parseFloat(e.target.value)), style: { flex: 1 } }), _jsxs("span", { style: {
|
|
47
|
+
minWidth: "3.5rem",
|
|
48
|
+
textAlign: "right",
|
|
49
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
50
|
+
fontSize: "0.75rem",
|
|
51
|
+
}, children: [current.widthMm.toFixed(3), " mm"] })] })] }), _jsxs("label", { htmlFor: modeId, style: { display: "flex", flexDirection: "column", gap: "0.25rem" }, children: [_jsx("span", { style: { fontWeight: 600 }, children: "Mode" }), _jsxs("select", { id: modeId, value: current.mode ?? "auto", onChange: (e) => updateMode(e.target.value), style: {
|
|
52
|
+
padding: "0.25rem 0.5rem",
|
|
53
|
+
fontSize: "0.8rem",
|
|
54
|
+
border: "1px solid #d1d5db",
|
|
55
|
+
borderRadius: 4,
|
|
56
|
+
background: "#ffffff",
|
|
57
|
+
}, children: [_jsx("option", { value: "auto", children: "Auto (density-based)" }), _jsx("option", { value: "spread", children: "Spread (lighter into darker)" }), _jsx("option", { value: "choke", children: "Choke (darker into lighter)" })] })] }), _jsx("p", { style: {
|
|
58
|
+
margin: 0,
|
|
59
|
+
fontSize: "0.7rem",
|
|
60
|
+
color: "#6b7280",
|
|
61
|
+
lineHeight: 1.4,
|
|
62
|
+
}, children: "Per-edge and per-color-pair overrides land in a future revision once the compile-pdf trap producer exposes them." })] }));
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=TrapEditorPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrapEditorPanel.js","sourceRoot":"","sources":["../../src/components/TrapEditorPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One trap operation as predicted by the D1 preview pass. Pixel-space
|
|
3
|
+
* rectangle in PDF points (1 pt = 1/72 in) plus the source/destination
|
|
4
|
+
* ink names.
|
|
5
|
+
*
|
|
6
|
+
* Mirrors compile-pdf's `trap_diff.operations[i]` shape (see
|
|
7
|
+
* `apps/service/src/compile-pdf-client.ts`'s `TrapOperation`). Kept
|
|
8
|
+
* inline here so the published editor package has no runtime dep on
|
|
9
|
+
* apps/service — a future refactor may centralize this shape in
|
|
10
|
+
* `@artworkpdf/document-model` to remove the structural duplication.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export type TrapPreviewOperation = {
|
|
15
|
+
/** Server-side page index — **0-indexed**, matching compile-pdf's
|
|
16
|
+
* `TrapZone.page_index: NonNegativeInt`. Note the distinct
|
|
17
|
+
* convention from the overlay's prop, which uses **1-indexed**
|
|
18
|
+
* `pageIndex` to match PDF user-facing page numbers; the overlay
|
|
19
|
+
* converts internally. */
|
|
20
|
+
page_index: number;
|
|
21
|
+
rect_pt: [number, number, number, number];
|
|
22
|
+
from_ink: string;
|
|
23
|
+
to_ink: string;
|
|
24
|
+
width_pt?: number;
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Pluggable preview fetcher. Hosts inject this so the editor never
|
|
28
|
+
* imports `CompilePdfClient` directly — matches the
|
|
29
|
+
* {@link import("./SwatchesPicker").SpotSearchFn} adapter pattern.
|
|
30
|
+
*
|
|
31
|
+
* @public
|
|
32
|
+
*/
|
|
33
|
+
export type TrapPreviewFn = () => Promise<{
|
|
34
|
+
operations: TrapPreviewOperation[];
|
|
35
|
+
}>;
|
|
36
|
+
/**
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export type TrapPreviewOverlayProps = {
|
|
40
|
+
/** Container width / height in CSS pixels — the overlay canvas
|
|
41
|
+
* matches these so it aligns with the Konva Stage underneath. */
|
|
42
|
+
width: number;
|
|
43
|
+
height: number;
|
|
44
|
+
/** 1-indexed page number to render. The trap-diff payload may carry
|
|
45
|
+
* operations for many pages; the overlay only draws this page. */
|
|
46
|
+
pageIndex: number;
|
|
47
|
+
/** Stage scale × DPR-equivalent factor: how many CSS pixels one PDF
|
|
48
|
+
* point occupies. The component multiplies `rect_pt` by this to
|
|
49
|
+
* position each trap rectangle on the overlay. */
|
|
50
|
+
pointsToPx: number;
|
|
51
|
+
/** Re-fetch trigger — change this value to debounce a new preview
|
|
52
|
+
* pass. The value itself isn't read. Pass the editor's `objects`
|
|
53
|
+
* array or a policy-version counter. */
|
|
54
|
+
trigger: unknown;
|
|
55
|
+
/** Async fetcher returning the trap operations for the current
|
|
56
|
+
* document + policy. Hosts wire this to
|
|
57
|
+
* `CompilePdfClient.trapPreview()` and a serialized canvas PDF. */
|
|
58
|
+
previewFn: TrapPreviewFn | null;
|
|
59
|
+
/** Debounce window in milliseconds. Defaults to 500 — slower than
|
|
60
|
+
* C4's 250 ms because the trap preview is a server round trip. */
|
|
61
|
+
debounceMs?: number;
|
|
62
|
+
};
|
|
63
|
+
export declare function TrapPreviewOverlay({ width, height, pageIndex, pointsToPx, trigger, previewFn, debounceMs, }: TrapPreviewOverlayProps): import("react/jsx-runtime").JSX.Element;
|
|
64
|
+
//# sourceMappingURL=TrapPreviewOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrapPreviewOverlay.d.ts","sourceRoot":"","sources":["../../src/components/TrapPreviewOverlay.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,oBAAoB,GAAG;IACjC;;;;+BAI2B;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,aAAa,GAAG,MAAM,OAAO,CAAC;IACxC,UAAU,EAAE,oBAAoB,EAAE,CAAC;CACpC,CAAC,CAAC;AAEH;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;sEACkE;IAClE,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;uEACmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB;;uDAEmD;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB;;6CAEyC;IACzC,OAAO,EAAE,OAAO,CAAC;IACjB;;wEAEoE;IACpE,SAAS,EAAE,aAAa,GAAG,IAAI,CAAC;IAChC;uEACmE;IACnE,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AA8BF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,MAAM,EACN,SAAS,EACT,UAAU,EACV,OAAO,EACP,SAAS,EACT,UAAgB,GACjB,EAAE,uBAAuB,2CAoGzB"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
"use client";
|
|
3
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
4
|
+
import { useEffect, useRef, useState } from "react";
|
|
5
|
+
/**
|
|
6
|
+
* D1 background trap-preview overlay.
|
|
7
|
+
*
|
|
8
|
+
* Sits as an absolutely-positioned `<canvas>` on top of the Konva
|
|
9
|
+
* Stage, debouncing calls to a host-supplied
|
|
10
|
+
* {@link TrapPreviewFn} on every change to the `trigger` prop. Paints
|
|
11
|
+
* a translucent cyan band over each predicted trap region from the
|
|
12
|
+
* server's trap-diff so users see where ink spreading / choking will
|
|
13
|
+
* happen before submitting a full render.
|
|
14
|
+
*
|
|
15
|
+
* Approximate preview — uses the metadata-only `/v1/trap/preview`
|
|
16
|
+
* endpoint (compile-pdf PR #38) which runs the same trap analysis as
|
|
17
|
+
* `/trap/apply` but skips the PDF write. Users wanting bit-exact
|
|
18
|
+
* preview must still run a full job.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
/** Wipes any previously drawn trap rectangles. Called from every
|
|
23
|
+
* "no overlay should be visible right now" branch so the canvas
|
|
24
|
+
* doesn't keep stale visuals after the user disables the feature
|
|
25
|
+
* or the preview request fails. */
|
|
26
|
+
function clearOverlayCanvas(canvas) {
|
|
27
|
+
if (!canvas)
|
|
28
|
+
return;
|
|
29
|
+
const ctx = canvas.getContext("2d");
|
|
30
|
+
if (!ctx)
|
|
31
|
+
return;
|
|
32
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
33
|
+
}
|
|
34
|
+
export function TrapPreviewOverlay({ width, height, pageIndex, pointsToPx, trigger, previewFn, debounceMs = 500, }) {
|
|
35
|
+
const canvasRef = useRef(null);
|
|
36
|
+
const [opsCount, setOpsCount] = useState(null);
|
|
37
|
+
const reqIdRef = useRef(0);
|
|
38
|
+
useEffect(() => {
|
|
39
|
+
// `trigger` is intentionally read here (no-op `void` cast) so the
|
|
40
|
+
// exhaustive-deps lint sees it as used; the actual value is never
|
|
41
|
+
// consumed — only its identity change is meaningful.
|
|
42
|
+
void trigger;
|
|
43
|
+
if (!previewFn || width <= 0 || height <= 0) {
|
|
44
|
+
// Reset BOTH state and canvas — otherwise the previously drawn
|
|
45
|
+
// trap bands stay visible after the user disables the feature
|
|
46
|
+
// via `enable_trap_preview` or the container collapses to 0×0.
|
|
47
|
+
setOpsCount(null);
|
|
48
|
+
clearOverlayCanvas(canvasRef.current);
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
reqIdRef.current += 1;
|
|
52
|
+
const myReqId = reqIdRef.current;
|
|
53
|
+
const handle = setTimeout(async () => {
|
|
54
|
+
let result;
|
|
55
|
+
try {
|
|
56
|
+
result = await previewFn();
|
|
57
|
+
}
|
|
58
|
+
catch {
|
|
59
|
+
// Network / server failure — clear the overlay and stop. We
|
|
60
|
+
// don't surface the error because trap preview is advisory;
|
|
61
|
+
// failures shouldn't block editing.
|
|
62
|
+
if (myReqId === reqIdRef.current) {
|
|
63
|
+
setOpsCount(null);
|
|
64
|
+
clearOverlayCanvas(canvasRef.current);
|
|
65
|
+
}
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
// Stale-response guard: a newer request fired while this one
|
|
69
|
+
// was in-flight; drop the result.
|
|
70
|
+
if (myReqId !== reqIdRef.current)
|
|
71
|
+
return;
|
|
72
|
+
// The server emits 0-indexed `page_index` (compile-pdf's
|
|
73
|
+
// `TrapZone.page_index: NonNegativeInt`); our prop is 1-indexed
|
|
74
|
+
// to match PDF user-facing page numbers. Convert at the boundary.
|
|
75
|
+
const pageOps = result.operations.filter((o) => o.page_index === pageIndex - 1);
|
|
76
|
+
setOpsCount(pageOps.length);
|
|
77
|
+
const canvas = canvasRef.current;
|
|
78
|
+
if (!canvas)
|
|
79
|
+
return;
|
|
80
|
+
canvas.width = Math.round(width);
|
|
81
|
+
canvas.height = Math.round(height);
|
|
82
|
+
const ctx = canvas.getContext("2d");
|
|
83
|
+
if (!ctx)
|
|
84
|
+
return;
|
|
85
|
+
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
86
|
+
ctx.fillStyle = "rgba(14, 165, 233, 0.45)";
|
|
87
|
+
for (const op of pageOps) {
|
|
88
|
+
const [llx, lly, urx, ury] = op.rect_pt;
|
|
89
|
+
const x = llx * pointsToPx;
|
|
90
|
+
// PDF coords are y-up from bottom; canvas coords are y-down
|
|
91
|
+
// from top. Mirror against the container height so traps land
|
|
92
|
+
// where the user sees them on screen.
|
|
93
|
+
const y = canvas.height - ury * pointsToPx;
|
|
94
|
+
const w = (urx - llx) * pointsToPx;
|
|
95
|
+
const h = (ury - lly) * pointsToPx;
|
|
96
|
+
ctx.fillRect(x, y, w, h);
|
|
97
|
+
}
|
|
98
|
+
}, debounceMs);
|
|
99
|
+
return () => clearTimeout(handle);
|
|
100
|
+
}, [width, height, pageIndex, pointsToPx, trigger, previewFn, debounceMs]);
|
|
101
|
+
return (_jsxs(_Fragment, { children: [_jsx("canvas", { ref: canvasRef, style: {
|
|
102
|
+
position: "absolute",
|
|
103
|
+
inset: 0,
|
|
104
|
+
width: `${width}px`,
|
|
105
|
+
height: `${height}px`,
|
|
106
|
+
pointerEvents: "none",
|
|
107
|
+
} }), opsCount !== null && opsCount > 0 && (_jsxs("output", { "aria-label": "Trap preview operations", style: {
|
|
108
|
+
position: "absolute",
|
|
109
|
+
bottom: 8,
|
|
110
|
+
right: 8,
|
|
111
|
+
padding: "0.25rem 0.5rem",
|
|
112
|
+
background: "rgba(14, 116, 144, 0.85)",
|
|
113
|
+
color: "#f0f9ff",
|
|
114
|
+
fontSize: "0.7rem",
|
|
115
|
+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
|
|
116
|
+
borderRadius: 4,
|
|
117
|
+
pointerEvents: "none",
|
|
118
|
+
}, children: [opsCount, " trap", opsCount === 1 ? "" : "s"] }))] }));
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=TrapPreviewOverlay.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrapPreviewOverlay.js","sourceRoot":"","sources":["../../src/components/TrapPreviewOverlay.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 2 V2 — variant matrix UI for variable-data overrides.
|
|
3
|
+
*
|
|
4
|
+
* One row per {@link Variant}; one editable column per token in
|
|
5
|
+
* `tokenKeys`. The token columns mirror the document-level
|
|
6
|
+
* `variableData` token keys; each `Variant.overrides` maps a subset
|
|
7
|
+
* of those keys to variant-specific values. Absent keys inherit the
|
|
8
|
+
* document's defaults at merge time (Wave 3 V1).
|
|
9
|
+
*
|
|
10
|
+
* Structurally mirrors `@artworkpdf/document-model`'s `VariantMatrix`
|
|
11
|
+
* — inlined here so the editor stays consumable without
|
|
12
|
+
* document-model (same pattern as `EditorSeparation`,
|
|
13
|
+
* `FoldGeometryPanelMetadata`).
|
|
14
|
+
*
|
|
15
|
+
* Controlled component: pass `value` + `onChange`, panel reflects
|
|
16
|
+
* mutations back to the host on every keystroke. Hosts that need
|
|
17
|
+
* batched commits should debounce externally.
|
|
18
|
+
*
|
|
19
|
+
* @public
|
|
20
|
+
*/
|
|
21
|
+
/**
|
|
22
|
+
* One row of a {@link VariantMatrixPanelValue}.
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export type VariantMatrixPanelVariant = {
|
|
27
|
+
id: string;
|
|
28
|
+
name: string;
|
|
29
|
+
overrides: Record<string, string>;
|
|
30
|
+
};
|
|
31
|
+
/**
|
|
32
|
+
* Controlled value for the panel — the cross-product of variants
|
|
33
|
+
* (rows) × token keys (columns).
|
|
34
|
+
*
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export type VariantMatrixPanelValue = {
|
|
38
|
+
tokenKeys: string[];
|
|
39
|
+
variants: VariantMatrixPanelVariant[];
|
|
40
|
+
};
|
|
41
|
+
/**
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export type VariantMatrixPanelProps = {
|
|
45
|
+
/** Current matrix. `undefined` means "no variants configured" —
|
|
46
|
+
* the panel offers an empty matrix with the document's token
|
|
47
|
+
* keys as columns. */
|
|
48
|
+
value: VariantMatrixPanelValue | undefined;
|
|
49
|
+
/** Fires on every change to a variant row, a token cell, or a
|
|
50
|
+
* token key. Hosts thread this into `document.variants`. */
|
|
51
|
+
onChange: (next: VariantMatrixPanelValue) => void;
|
|
52
|
+
/** Optional initial token keys to surface when `value` is
|
|
53
|
+
* `undefined` — typically the document-level `variableData`
|
|
54
|
+
* keys, so the matrix immediately reflects the merge surface. */
|
|
55
|
+
initialTokenKeys?: readonly string[];
|
|
56
|
+
};
|
|
57
|
+
/**
|
|
58
|
+
* @public
|
|
59
|
+
*/
|
|
60
|
+
export declare function VariantMatrixPanel({ value, onChange, initialTokenKeys }: VariantMatrixPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
61
|
+
//# sourceMappingURL=VariantMatrixPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariantMatrixPanel.d.ts","sourceRoot":"","sources":["../../src/components/VariantMatrixPanel.tsx"],"names":[],"mappings":"AAKA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH;;;;GAIG;AACH,MAAM,MAAM,yBAAyB,GAAG;IACtC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CACnC,CAAC;AAEF;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,QAAQ,EAAE,yBAAyB,EAAE,CAAC;CACvC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;;2BAEuB;IACvB,KAAK,EAAE,uBAAuB,GAAG,SAAS,CAAC;IAC3C;iEAC6D;IAC7D,QAAQ,EAAE,CAAC,IAAI,EAAE,uBAAuB,KAAK,IAAI,CAAC;IAClD;;sEAEkE;IAClE,gBAAgB,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACtC,CAAC;AAEF;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,EAAE,KAAK,EAAE,QAAQ,EAAE,gBAAgB,EAAE,EAAE,uBAAuB,2CAsJhG"}
|
|
@@ -0,0 +1,97 @@
|
|
|
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 { useMemo, useRef } from "react";
|
|
5
|
+
/**
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export function VariantMatrixPanel({ value, onChange, initialTokenKeys }) {
|
|
9
|
+
const effective = useMemo(() => {
|
|
10
|
+
if (value)
|
|
11
|
+
return value;
|
|
12
|
+
return {
|
|
13
|
+
tokenKeys: initialTokenKeys ? [...initialTokenKeys] : [],
|
|
14
|
+
variants: [],
|
|
15
|
+
};
|
|
16
|
+
}, [value, initialTokenKeys]);
|
|
17
|
+
// Monotonic counter to keep variant IDs stable across delete-then-add
|
|
18
|
+
// cycles. Length-derived ids (`v-${length + 1}`) collide whenever a
|
|
19
|
+
// middle row is removed and a new one added, which produces duplicate
|
|
20
|
+
// React keys and mis-targets row-level updates.
|
|
21
|
+
const nextVariantSuffix = useRef(1);
|
|
22
|
+
const addVariant = () => {
|
|
23
|
+
const used = new Set(effective.variants.map((v) => v.id));
|
|
24
|
+
let n = nextVariantSuffix.current;
|
|
25
|
+
let id = `v-${n}`;
|
|
26
|
+
while (used.has(id)) {
|
|
27
|
+
n += 1;
|
|
28
|
+
id = `v-${n}`;
|
|
29
|
+
}
|
|
30
|
+
nextVariantSuffix.current = n + 1;
|
|
31
|
+
onChange({
|
|
32
|
+
...effective,
|
|
33
|
+
variants: [...effective.variants, { id, name: `Variant ${n}`, overrides: {} }],
|
|
34
|
+
});
|
|
35
|
+
};
|
|
36
|
+
const removeVariant = (id) => {
|
|
37
|
+
onChange({
|
|
38
|
+
...effective,
|
|
39
|
+
variants: effective.variants.filter((v) => v.id !== id),
|
|
40
|
+
});
|
|
41
|
+
};
|
|
42
|
+
const renameVariant = (id, name) => {
|
|
43
|
+
onChange({
|
|
44
|
+
...effective,
|
|
45
|
+
variants: effective.variants.map((v) => (v.id === id ? { ...v, name } : v)),
|
|
46
|
+
});
|
|
47
|
+
};
|
|
48
|
+
const setOverride = (id, key, val) => {
|
|
49
|
+
onChange({
|
|
50
|
+
...effective,
|
|
51
|
+
variants: effective.variants.map((v) => {
|
|
52
|
+
if (v.id !== id)
|
|
53
|
+
return v;
|
|
54
|
+
// Empty string means "clear the override" — drop the key so the
|
|
55
|
+
// variant falls back to the document-level default at merge
|
|
56
|
+
// time. Storing `""` would pin the override to an empty string,
|
|
57
|
+
// which is a different (and surprising) semantic.
|
|
58
|
+
if (val === "") {
|
|
59
|
+
const { [key]: _removed, ...rest } = v.overrides;
|
|
60
|
+
return { ...v, overrides: rest };
|
|
61
|
+
}
|
|
62
|
+
return { ...v, overrides: { ...v.overrides, [key]: val } };
|
|
63
|
+
}),
|
|
64
|
+
});
|
|
65
|
+
};
|
|
66
|
+
const addTokenKey = (key) => {
|
|
67
|
+
const trimmed = key.trim();
|
|
68
|
+
if (!trimmed || effective.tokenKeys.includes(trimmed))
|
|
69
|
+
return;
|
|
70
|
+
onChange({ ...effective, tokenKeys: [...effective.tokenKeys, trimmed] });
|
|
71
|
+
};
|
|
72
|
+
const removeTokenKey = (key) => {
|
|
73
|
+
onChange({
|
|
74
|
+
...effective,
|
|
75
|
+
tokenKeys: effective.tokenKeys.filter((k) => k !== key),
|
|
76
|
+
variants: effective.variants.map((v) => {
|
|
77
|
+
if (!(key in v.overrides))
|
|
78
|
+
return v;
|
|
79
|
+
const { [key]: _removed, ...rest } = v.overrides;
|
|
80
|
+
return { ...v, overrides: rest };
|
|
81
|
+
}),
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
return (_jsxs("div", { "data-testid": "variant-matrix-panel", style: { padding: "0.5rem" }, children: [_jsxs("header", { style: { display: "flex", gap: "0.5rem", alignItems: "baseline" }, children: [_jsx("h3", { style: { margin: 0 }, children: "Variants" }), _jsx("button", { type: "button", onClick: addVariant, "aria-label": "Add variant", children: "+ variant" }), _jsx(TokenKeyAdder, { onAdd: addTokenKey })] }), effective.variants.length === 0 ? (_jsxs("p", { style: { opacity: 0.6 }, children: ["No variants yet. Click ", _jsx("strong", { children: "+ variant" }), " to add the first row."] })) : (_jsxs("table", { style: { borderCollapse: "collapse", marginTop: "0.5rem" }, children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: "Name" }), effective.tokenKeys.map((k) => (_jsxs("th", { children: [k, " ", _jsx("button", { type: "button", onClick: () => removeTokenKey(k), "aria-label": `Remove token ${k}`, title: `Remove token ${k}`, children: "\u00D7" })] }, k))), _jsx("th", {})] }) }), _jsx("tbody", { children: effective.variants.map((v) => (_jsxs("tr", { children: [_jsx("td", { children: _jsx("input", { value: v.name, onChange: (e) => renameVariant(v.id, e.target.value), "aria-label": `Variant name for ${v.id}` }) }), effective.tokenKeys.map((k) => (_jsx("td", { children: _jsx("input", { value: v.overrides[k] ?? "", onChange: (e) => setOverride(v.id, k, e.target.value), "aria-label": `${v.name} override for ${k}`, placeholder: "\u2014" }) }, k))), _jsx("td", { children: _jsx("button", { type: "button", onClick: () => removeVariant(v.id), "aria-label": `Remove variant ${v.name}`, children: "\u00D7" }) })] }, v.id))) })] }))] }));
|
|
85
|
+
}
|
|
86
|
+
function TokenKeyAdder({ onAdd }) {
|
|
87
|
+
return (_jsxs("form", { style: { display: "inline-flex", gap: "0.25rem" }, onSubmit: (e) => {
|
|
88
|
+
e.preventDefault();
|
|
89
|
+
const form = e.currentTarget;
|
|
90
|
+
const input = form.elements.namedItem("token");
|
|
91
|
+
if (input?.value) {
|
|
92
|
+
onAdd(input.value);
|
|
93
|
+
input.value = "";
|
|
94
|
+
}
|
|
95
|
+
}, children: [_jsx("input", { name: "token", placeholder: "+ token key", "aria-label": "New token key" }), _jsx("button", { type: "submit", children: "add" })] }));
|
|
96
|
+
}
|
|
97
|
+
//# sourceMappingURL=VariantMatrixPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariantMatrixPanel.js","sourceRoot":"","sources":["../../src/components/VariantMatrixPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 4 V3 — versioned variant matrix viewer.
|
|
3
|
+
*
|
|
4
|
+
* Reads a list of historical {@link VariantMatrixSnapshot}s (typically
|
|
5
|
+
* derived from `DocumentV3.variants.version` paired with snapshots
|
|
6
|
+
* the host persists) and surfaces a "v1.2.0 vs v1.3.0" diff. Hosts
|
|
7
|
+
* that ship variant-aware versioning land this in their MIS chrome
|
|
8
|
+
* so a designer can answer "which row did the brand team add in the
|
|
9
|
+
* last revision?" without a full table re-read.
|
|
10
|
+
*
|
|
11
|
+
* Pure controlled component — host owns history, baselineVersion,
|
|
12
|
+
* and currentVersion. The diff helper {@link diffVariantMatrices}
|
|
13
|
+
* is exported so hosts can drive custom rendering (sparkline,
|
|
14
|
+
* change log, MIS audit row) over the same algorithm.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
import type { ReactElement } from "react";
|
|
19
|
+
import type { VariantMatrixPanelValue, VariantMatrixPanelVariant } from "./VariantMatrixPanel";
|
|
20
|
+
/**
|
|
21
|
+
* One historical variant-matrix snapshot. Structurally compatible
|
|
22
|
+
* with `{ version, ...VariantMatrix }` from
|
|
23
|
+
* `@artworkpdf/document-model` — hosts that carry their own
|
|
24
|
+
* version-history list construct snapshots by stamping each
|
|
25
|
+
* persisted `variants` payload with the matrix-level `version`.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export type VariantMatrixSnapshot = {
|
|
30
|
+
version: string;
|
|
31
|
+
matrix: VariantMatrixPanelValue;
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Per-variant modification record produced by
|
|
35
|
+
* {@link diffVariantMatrices}.
|
|
36
|
+
*
|
|
37
|
+
* `changedTokens` is the list of token keys whose value differs
|
|
38
|
+
* between baseline and current; `nameChanged` is true when the
|
|
39
|
+
* variant's human-readable `name` changed (with the `id` still
|
|
40
|
+
* matching). Either being non-empty makes the variant "modified".
|
|
41
|
+
*
|
|
42
|
+
* @public
|
|
43
|
+
*/
|
|
44
|
+
export type VariantMatrixModifiedVariant = {
|
|
45
|
+
id: string;
|
|
46
|
+
name: string;
|
|
47
|
+
changedTokens: readonly string[];
|
|
48
|
+
nameChanged: boolean;
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Result of {@link diffVariantMatrices}.
|
|
52
|
+
*
|
|
53
|
+
* - `addedVariants` — present in `current` but not `baseline`.
|
|
54
|
+
* - `removedVariants` — present in `baseline` but not `current`.
|
|
55
|
+
* - `modifiedVariants` — present in both with at least one token
|
|
56
|
+
* override change or a name change.
|
|
57
|
+
* - `addedTokenKeys` / `removedTokenKeys` — the diff of the column
|
|
58
|
+
* set (`matrix.tokenKeys`).
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
export type VariantMatrixDiffResult = {
|
|
63
|
+
addedVariants: readonly VariantMatrixPanelVariant[];
|
|
64
|
+
removedVariants: readonly VariantMatrixPanelVariant[];
|
|
65
|
+
modifiedVariants: readonly VariantMatrixModifiedVariant[];
|
|
66
|
+
addedTokenKeys: readonly string[];
|
|
67
|
+
removedTokenKeys: readonly string[];
|
|
68
|
+
};
|
|
69
|
+
/**
|
|
70
|
+
* @public
|
|
71
|
+
*/
|
|
72
|
+
export type VariantMatrixVersionPanelProps = {
|
|
73
|
+
/** Ordered version history, oldest → newest. Typically the host's
|
|
74
|
+
* matrix-snapshot ring buffer. Empty array surfaces a "no
|
|
75
|
+
* history yet" hint. */
|
|
76
|
+
history: readonly VariantMatrixSnapshot[];
|
|
77
|
+
/** Version to compare against. Absent → the second-to-latest
|
|
78
|
+
* snapshot when `history.length >= 2`, else the only snapshot. */
|
|
79
|
+
baselineVersion?: string;
|
|
80
|
+
/** Version to compare as "current". Absent → the most-recent
|
|
81
|
+
* snapshot. */
|
|
82
|
+
currentVersion?: string;
|
|
83
|
+
/** Fires when the user picks a different baseline from the panel's
|
|
84
|
+
* dropdown. */
|
|
85
|
+
onBaselineChange?: (version: string) => void;
|
|
86
|
+
/** Fires when the user picks a different current version. */
|
|
87
|
+
onCurrentChange?: (version: string) => void;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Resolve which snapshot the panel should pull from `history`.
|
|
91
|
+
*
|
|
92
|
+
* Behaviour matches `PreflightDiffPanel.resolveBaselineSnapshot`:
|
|
93
|
+
* an explicit version wins when found, else falls back to the
|
|
94
|
+
* most-recent snapshot. Returns `undefined` only when `history` is
|
|
95
|
+
* empty. Falling back keeps the panel useful after a host trims
|
|
96
|
+
* history below the user's saved selection.
|
|
97
|
+
*
|
|
98
|
+
* Pure function; exposed for hosts that mirror the panel's
|
|
99
|
+
* selection in their own chrome.
|
|
100
|
+
*
|
|
101
|
+
* @public
|
|
102
|
+
*/
|
|
103
|
+
export declare function resolveSnapshot(history: readonly VariantMatrixSnapshot[], version: string | undefined): VariantMatrixSnapshot | undefined;
|
|
104
|
+
/**
|
|
105
|
+
* Compute the variant-row + token-column diff between two matrices.
|
|
106
|
+
*
|
|
107
|
+
* Variants are matched by `id`; the human-readable `name` and token
|
|
108
|
+
* `overrides` are compared per-id. Token keys are diffed as sets
|
|
109
|
+
* (order-insensitive). Pure function — no React, no DOM.
|
|
110
|
+
*
|
|
111
|
+
* @public
|
|
112
|
+
*/
|
|
113
|
+
export declare function diffVariantMatrices(baseline: VariantMatrixPanelValue, current: VariantMatrixPanelValue): VariantMatrixDiffResult;
|
|
114
|
+
/**
|
|
115
|
+
* Read-only viewer for a versioned variant matrix history. Picks
|
|
116
|
+
* a baseline + current version (dropdowns) and renders a per-row
|
|
117
|
+
* diff plus a token-column diff.
|
|
118
|
+
*
|
|
119
|
+
* @public
|
|
120
|
+
*/
|
|
121
|
+
export declare function VariantMatrixVersionPanel({ history, baselineVersion, currentVersion, onBaselineChange, onCurrentChange, }: VariantMatrixVersionPanelProps): ReactElement;
|
|
122
|
+
//# sourceMappingURL=VariantMatrixVersionPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"VariantMatrixVersionPanel.d.ts","sourceRoot":"","sources":["../../src/components/VariantMatrixVersionPanel.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,uBAAuB,EAAE,yBAAyB,EAAE,MAAM,sBAAsB,CAAC;AAE/F;;;;;;;;GAQG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,uBAAuB,CAAC;CACjC,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,WAAW,EAAE,OAAO,CAAC;CACtB,CAAC;AAEF;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC,aAAa,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACpD,eAAe,EAAE,SAAS,yBAAyB,EAAE,CAAC;IACtD,gBAAgB,EAAE,SAAS,4BAA4B,EAAE,CAAC;IAC1D,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,gBAAgB,EAAE,SAAS,MAAM,EAAE,CAAC;CACrC,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,8BAA8B,GAAG;IAC3C;;6BAEyB;IACzB,OAAO,EAAE,SAAS,qBAAqB,EAAE,CAAC;IAC1C;uEACmE;IACnE,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB;oBACgB;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;oBACgB;IAChB,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7C,6DAA6D;IAC7D,eAAe,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC7C,CAAC;AAEF;;;;;;;;;;;;;GAaG;AACH,wBAAgB,eAAe,CAC7B,OAAO,EAAE,SAAS,qBAAqB,EAAE,EACzC,OAAO,EAAE,MAAM,GAAG,SAAS,GAC1B,qBAAqB,GAAG,SAAS,CAOnC;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,uBAAuB,EACjC,OAAO,EAAE,uBAAuB,GAC/B,uBAAuB,CAmCzB;AA+BD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,OAAO,EACP,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,eAAe,GAChB,EAAE,8BAA8B,GAAG,YAAY,CA6F/C"}
|