@printwithsynergy/artwork-pdf-editor 0.2.0 → 0.4.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/StreamingRenderProgress.d.ts +60 -0
- package/dist/components/StreamingRenderProgress.d.ts.map +1 -0
- package/dist/components/StreamingRenderProgress.js +99 -0
- package/dist/components/StreamingRenderProgress.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 +51 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +51 -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 +390 -0
- package/dist/lib/editor-config.d.ts.map +1 -1
- package/dist/lib/editor-config.js +90 -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 +50 -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/streaming-render.d.ts +100 -0
- package/dist/lib/streaming-render.d.ts.map +1 -0
- package/dist/lib/streaming-render.js +132 -0
- package/dist/lib/streaming-render.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,159 @@
|
|
|
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, useMemo, useState } from "react";
|
|
5
|
+
/**
|
|
6
|
+
* Pure helper — sorts a `SpotMatch` list ascending on `deltaE`
|
|
7
|
+
* (best-first). Stable on ties: input order preserved. Returns a
|
|
8
|
+
* new array.
|
|
9
|
+
*
|
|
10
|
+
* @public
|
|
11
|
+
*/
|
|
12
|
+
export function sortMatchesByDeltaE(matches) {
|
|
13
|
+
return [...matches]
|
|
14
|
+
.map((m, i) => ({ m, i }))
|
|
15
|
+
.sort((a, b) => a.m.deltaE - b.m.deltaE || a.i - b.i)
|
|
16
|
+
.map((x) => x.m);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Pure helper — maps a ΔE distance to a {@link DeltaEQuality} band
|
|
20
|
+
* using the CIE-1994 perceptual cut points (under 1 is
|
|
21
|
+
* imperceptible, 1–3 is noticeable, 3–5 is fair, ≥5 is poor). Used
|
|
22
|
+
* by the panel for the per-row severity chip; exported so hosts can
|
|
23
|
+
* surface the same banding outside the panel (e.g. in a print-proof
|
|
24
|
+
* audit). Returns `"poor"` for non-finite or negative inputs by
|
|
25
|
+
* threshold ordering — callers should pre-validate if they care.
|
|
26
|
+
*
|
|
27
|
+
* @public
|
|
28
|
+
*/
|
|
29
|
+
export function deltaEQuality(deltaE) {
|
|
30
|
+
if (!Number.isFinite(deltaE) || deltaE < 0)
|
|
31
|
+
return "poor";
|
|
32
|
+
if (deltaE < 1)
|
|
33
|
+
return "imperceptible";
|
|
34
|
+
if (deltaE < 3)
|
|
35
|
+
return "noticeable";
|
|
36
|
+
if (deltaE < 5)
|
|
37
|
+
return "fair";
|
|
38
|
+
return "poor";
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Pure helper — formats ΔE for chip / row display (e.g. `"ΔE 1.2"`).
|
|
42
|
+
* Two-decimal precision matches what most ΔE engines emit and what
|
|
43
|
+
* print shops quote.
|
|
44
|
+
*
|
|
45
|
+
* @public
|
|
46
|
+
*/
|
|
47
|
+
export function formatDeltaE(deltaE) {
|
|
48
|
+
return `ΔE ${deltaE.toFixed(2)}`;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Pure helper — quickly checks whether a query has at least one
|
|
52
|
+
* color-space populated. Exported so hosts that drive the loader
|
|
53
|
+
* from outside the panel can gate their fetch on the same predicate.
|
|
54
|
+
*
|
|
55
|
+
* @public
|
|
56
|
+
*/
|
|
57
|
+
export function isQueryReady(query) {
|
|
58
|
+
return Boolean(query.cmyk || query.lab || query.hex?.trim());
|
|
59
|
+
}
|
|
60
|
+
const DELTA_E_COLORS = {
|
|
61
|
+
imperceptible: "#080",
|
|
62
|
+
noticeable: "#0a8",
|
|
63
|
+
fair: "#a60",
|
|
64
|
+
poor: "#a00",
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Stateful panel — accepts a CMYK or hex input, calls the host
|
|
68
|
+
* loader, and surfaces ranked matches with ΔE chips. Hosts wire
|
|
69
|
+
* `onSelect` to push the picked spot into the active object's fill
|
|
70
|
+
* / stroke or into the separations registry.
|
|
71
|
+
*
|
|
72
|
+
* @public
|
|
73
|
+
*/
|
|
74
|
+
export function SmartSpotMatchPanel({ loader, initialQuery, limit, onSelect, }) {
|
|
75
|
+
const [hex, setHex] = useState(initialQuery?.hex ?? "");
|
|
76
|
+
const [matches, setMatches] = useState(null);
|
|
77
|
+
const [error, setError] = useState(null);
|
|
78
|
+
const [loading, setLoading] = useState(false);
|
|
79
|
+
// Keep the hex input in lockstep with `initialQuery.hex` when the
|
|
80
|
+
// host swaps the active selection — without this, a panel reused
|
|
81
|
+
// for a different object would mix new cmyk / lab with the old
|
|
82
|
+
// hex value in the input.
|
|
83
|
+
useEffect(() => {
|
|
84
|
+
setHex(initialQuery?.hex ?? "");
|
|
85
|
+
}, [initialQuery?.hex]);
|
|
86
|
+
// Stable query object — re-derived only when content changes, not
|
|
87
|
+
// when a parent re-render hands back a referentially-different
|
|
88
|
+
// but content-identical `initialQuery`. The join'd keys identity-
|
|
89
|
+
// compare on content; the raw refs are read inside but excluded
|
|
90
|
+
// from the dep list intentionally.
|
|
91
|
+
const cmykKey = initialQuery?.cmyk?.join(",") ?? "";
|
|
92
|
+
const labKey = initialQuery?.lab?.join(",") ?? "";
|
|
93
|
+
// biome-ignore lint/correctness/useExhaustiveDependencies: cmyk / lab are content-keyed via cmykKey / labKey
|
|
94
|
+
const query = useMemo(() => ({
|
|
95
|
+
...(hex.trim() && { hex: hex.trim() }),
|
|
96
|
+
...(initialQuery?.cmyk && { cmyk: initialQuery.cmyk }),
|
|
97
|
+
...(initialQuery?.lab && { lab: initialQuery.lab }),
|
|
98
|
+
...(limit !== undefined && { limit }),
|
|
99
|
+
}), [hex, cmykKey, labKey, limit]);
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (!isQueryReady(query)) {
|
|
102
|
+
setMatches(null);
|
|
103
|
+
setError(null);
|
|
104
|
+
setLoading(false);
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
let disposed = false;
|
|
108
|
+
setLoading(true);
|
|
109
|
+
setError(null);
|
|
110
|
+
// Drop the previous result eagerly so stale rows can't be
|
|
111
|
+
// selected for a query that's no longer current.
|
|
112
|
+
setMatches(null);
|
|
113
|
+
void (async () => {
|
|
114
|
+
try {
|
|
115
|
+
const next = await loader(query);
|
|
116
|
+
if (disposed)
|
|
117
|
+
return;
|
|
118
|
+
setMatches(sortMatchesByDeltaE(next));
|
|
119
|
+
}
|
|
120
|
+
catch (err) {
|
|
121
|
+
if (disposed)
|
|
122
|
+
return;
|
|
123
|
+
setMatches(null);
|
|
124
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
125
|
+
}
|
|
126
|
+
finally {
|
|
127
|
+
if (!disposed)
|
|
128
|
+
setLoading(false);
|
|
129
|
+
}
|
|
130
|
+
})();
|
|
131
|
+
return () => {
|
|
132
|
+
disposed = true;
|
|
133
|
+
};
|
|
134
|
+
}, [loader, query]);
|
|
135
|
+
return (_jsxs("div", { "data-testid": "smart-spot-match-panel", style: { padding: "0.5rem" }, children: [_jsx("header", { style: { marginBottom: "0.5rem" }, children: _jsx("h3", { style: { margin: 0, fontSize: "0.875rem" }, children: "Find PANTONE match" }) }), _jsxs("label", { style: { display: "block", fontSize: "0.75rem", marginBottom: "0.5rem" }, children: ["sRGB hex", _jsx("input", { type: "text", "aria-label": "sRGB hex", placeholder: "#ff5102", value: hex, onChange: (e) => setHex(e.target.value), style: { display: "block", marginTop: "0.125rem", width: "100%" } })] }), loading && _jsx("div", { style: { opacity: 0.6, fontSize: "0.75rem" }, children: "Searching\u2026" }), error && (_jsxs("div", { role: "alert", style: { color: "#a00", fontSize: "0.75rem" }, children: ["Couldn't fetch matches: ", error] })), matches && matches.length === 0 && !loading && !error && (_jsx("div", { style: { opacity: 0.6, fontSize: "0.75rem" }, children: "No matches." })), matches && matches.length > 0 && (_jsx("ul", { style: { listStyle: "none", padding: 0, margin: 0 }, children: matches.map((match) => (_jsx(SmartSpotMatchRow, { match: match, onSelect: onSelect }, `${match.spot.library ?? "-"}|${match.spot.name}`))) }))] }));
|
|
136
|
+
}
|
|
137
|
+
function SmartSpotMatchRow({ match, onSelect, }) {
|
|
138
|
+
const quality = deltaEQuality(match.deltaE);
|
|
139
|
+
const chipColor = DELTA_E_COLORS[quality];
|
|
140
|
+
const rowContents = (_jsxs(_Fragment, { children: [_jsx("span", { style: { flex: 1, fontSize: "0.8125rem" }, children: match.spot.name }), _jsx("span", { "aria-label": `${formatDeltaE(match.deltaE)} — ${quality}`, style: {
|
|
141
|
+
fontSize: "0.6875rem",
|
|
142
|
+
padding: "0.0625rem 0.375rem",
|
|
143
|
+
borderRadius: 999,
|
|
144
|
+
background: chipColor,
|
|
145
|
+
color: "#fff",
|
|
146
|
+
}, children: formatDeltaE(match.deltaE) })] }));
|
|
147
|
+
const rowStyle = {
|
|
148
|
+
display: "flex",
|
|
149
|
+
alignItems: "center",
|
|
150
|
+
gap: "0.5rem",
|
|
151
|
+
width: "100%",
|
|
152
|
+
padding: "0.25rem 0.5rem",
|
|
153
|
+
border: "1px solid transparent",
|
|
154
|
+
borderRadius: 4,
|
|
155
|
+
textAlign: "left",
|
|
156
|
+
};
|
|
157
|
+
return (_jsx("li", { children: onSelect ? (_jsx("button", { type: "button", onClick: () => onSelect(match), style: { ...rowStyle, cursor: "pointer", background: "transparent" }, "aria-label": match.spot.name, children: rowContents })) : (_jsx("div", { style: rowStyle, children: rowContents })) }));
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=SmartSpotMatchPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SmartSpotMatchPanel.js","sourceRoot":"","sources":["../../src/components/SmartSpotMatchPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 3 O3 — Streaming render progress panel.
|
|
3
|
+
*
|
|
4
|
+
* Shows live per-page progress for a long render that returns
|
|
5
|
+
* `text/event-stream` via `POST /v1/compose/stream`. The host wires
|
|
6
|
+
* a {@link StreamingRenderConnectFn} adapter (typically backed by an
|
|
7
|
+
* `EventSource` or a stubbed `AsyncIterable` for tests); the panel
|
|
8
|
+
* owns the event accumulator and renders the summary returned by
|
|
9
|
+
* {@link summarizeStreamingProgress}.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
import type { ReactElement } from "react";
|
|
14
|
+
import { type StreamingRenderEvent } from "../lib/streaming-render";
|
|
15
|
+
/**
|
|
16
|
+
* Host adapter — opens a stream and returns an async iterable of
|
|
17
|
+
* events plus a `close()` to abort. The shape lets a host wire an
|
|
18
|
+
* `EventSource` over `/v1/compose/stream`, a `fetch()` with
|
|
19
|
+
* `ReadableStream`, or a test mock interchangeably.
|
|
20
|
+
*
|
|
21
|
+
* The panel iterates events until the stream ends; on unmount it
|
|
22
|
+
* calls `close()` to abort.
|
|
23
|
+
*
|
|
24
|
+
* @public
|
|
25
|
+
*/
|
|
26
|
+
export type StreamingRenderConnectFn = () => {
|
|
27
|
+
events: AsyncIterable<StreamingRenderEvent>;
|
|
28
|
+
close: () => void;
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* Configuration for the {@link StreamingRenderProgress}.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export type StreamingRenderProgressProps = {
|
|
36
|
+
/** Connect adapter. When absent the panel renders in
|
|
37
|
+
* "ready to connect" mode and never opens a stream. */
|
|
38
|
+
connect?: StreamingRenderConnectFn;
|
|
39
|
+
/** Fires when the stream's `done` event lands — typically used
|
|
40
|
+
* to redirect to the rendered PDF or refresh the job list. */
|
|
41
|
+
onDone?: (info: {
|
|
42
|
+
pdfSha256: string;
|
|
43
|
+
cacheKey: string;
|
|
44
|
+
}) => void;
|
|
45
|
+
/** Fires when the stream emits an error event — typically used
|
|
46
|
+
* for telemetry / fallback to non-streaming render. */
|
|
47
|
+
onError?: (info: {
|
|
48
|
+
message: string;
|
|
49
|
+
code: string;
|
|
50
|
+
}) => void;
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* Stateful streaming-progress panel. Connects on mount when
|
|
54
|
+
* `connect` is supplied, accumulates events, surfaces summary +
|
|
55
|
+
* per-page badge list, and calls `onDone` / `onError` once.
|
|
56
|
+
*
|
|
57
|
+
* @public
|
|
58
|
+
*/
|
|
59
|
+
export declare function StreamingRenderProgress({ connect, onDone, onError, }: StreamingRenderProgressProps): ReactElement;
|
|
60
|
+
//# sourceMappingURL=StreamingRenderProgress.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamingRenderProgress.d.ts","sourceRoot":"","sources":["../../src/components/StreamingRenderProgress.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,EAEL,KAAK,oBAAoB,EAE1B,MAAM,yBAAyB,CAAC;AAEjC;;;;;;;;;;GAUG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM;IAC3C,MAAM,EAAE,aAAa,CAAC,oBAAoB,CAAC,CAAC;IAC5C,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;4DACwD;IACxD,OAAO,CAAC,EAAE,wBAAwB,CAAC;IACnC;mEAC+D;IAC/D,MAAM,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;IACjE;4DACwD;IACxD,OAAO,CAAC,EAAE,CAAC,IAAI,EAAE;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CAC7D,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,OAAO,EACP,MAAM,EACN,OAAO,GACR,EAAE,4BAA4B,GAAG,YAAY,CAwI7C"}
|
|
@@ -0,0 +1,99 @@
|
|
|
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 { useEffect, useRef, useState } from "react";
|
|
5
|
+
import { summarizeStreamingProgress, } from "../lib/streaming-render";
|
|
6
|
+
/**
|
|
7
|
+
* Stateful streaming-progress panel. Connects on mount when
|
|
8
|
+
* `connect` is supplied, accumulates events, surfaces summary +
|
|
9
|
+
* per-page badge list, and calls `onDone` / `onError` once.
|
|
10
|
+
*
|
|
11
|
+
* @public
|
|
12
|
+
*/
|
|
13
|
+
export function StreamingRenderProgress({ connect, onDone, onError, }) {
|
|
14
|
+
const [events, setEvents] = useState([]);
|
|
15
|
+
const handlersRef = useRef({ onDone, onError });
|
|
16
|
+
handlersRef.current = { onDone, onError };
|
|
17
|
+
useEffect(() => {
|
|
18
|
+
if (!connect)
|
|
19
|
+
return;
|
|
20
|
+
const handle = connect();
|
|
21
|
+
let disposed = false;
|
|
22
|
+
void (async () => {
|
|
23
|
+
try {
|
|
24
|
+
for await (const ev of handle.events) {
|
|
25
|
+
if (disposed)
|
|
26
|
+
return;
|
|
27
|
+
setEvents((prev) => [...prev, ev]);
|
|
28
|
+
if (ev.kind === "done") {
|
|
29
|
+
handlersRef.current.onDone?.({
|
|
30
|
+
pdfSha256: ev.pdfSha256,
|
|
31
|
+
cacheKey: ev.cacheKey,
|
|
32
|
+
});
|
|
33
|
+
}
|
|
34
|
+
else if (ev.kind === "error") {
|
|
35
|
+
handlersRef.current.onError?.({ message: ev.message, code: ev.code });
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
// Stream tear-down — surface as a synthetic error event so
|
|
41
|
+
// the summarizer flips to "error" status without the
|
|
42
|
+
// consumer having to special-case missing events.
|
|
43
|
+
if (!disposed) {
|
|
44
|
+
setEvents((prev) => [
|
|
45
|
+
...prev,
|
|
46
|
+
{ kind: "error", message: "Stream closed unexpectedly.", code: "E_STREAM_ABORTED" },
|
|
47
|
+
]);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
})();
|
|
51
|
+
return () => {
|
|
52
|
+
disposed = true;
|
|
53
|
+
handle.close();
|
|
54
|
+
};
|
|
55
|
+
}, [connect]);
|
|
56
|
+
const summary = summarizeStreamingProgress(events);
|
|
57
|
+
return (_jsxs("div", { "data-testid": "streaming-render-progress", style: { padding: "0.5rem" }, children: [_jsxs("header", { style: {
|
|
58
|
+
display: "flex",
|
|
59
|
+
justifyContent: "space-between",
|
|
60
|
+
alignItems: "baseline",
|
|
61
|
+
marginBottom: "0.375rem",
|
|
62
|
+
}, children: [_jsx("h3", { style: { margin: 0, fontSize: "0.875rem" }, children: "Render progress" }), _jsxs("span", { style: { fontSize: "0.75rem", color: "#595959" }, children: [summary.percent, "% \u00B7 ", summary.completedPages, "/", summary.totalPages || "?"] })] }), _jsx("div", { "aria-label": "Render progress", role: "progressbar", "aria-valuenow": summary.percent, "aria-valuemin": 0, "aria-valuemax": 100, style: {
|
|
63
|
+
background: "#eee",
|
|
64
|
+
height: 6,
|
|
65
|
+
borderRadius: 3,
|
|
66
|
+
overflow: "hidden",
|
|
67
|
+
marginBottom: "0.5rem",
|
|
68
|
+
}, children: _jsx("div", { style: {
|
|
69
|
+
width: `${summary.percent}%`,
|
|
70
|
+
height: "100%",
|
|
71
|
+
background: summary.status === "error"
|
|
72
|
+
? "#a00"
|
|
73
|
+
: summary.status === "done"
|
|
74
|
+
? "#080"
|
|
75
|
+
: "#06a",
|
|
76
|
+
transition: "width 200ms linear",
|
|
77
|
+
} }) }), summary.status === "error" && summary.errorMessage && (_jsx("div", { role: "alert", style: { fontSize: "0.75rem", color: "#a00", marginBottom: "0.375rem" }, children: summary.errorMessage })), summary.status !== "error" && summary.totalPages > 0 && (_jsx("ul", { "aria-label": "Per-page status", style: {
|
|
78
|
+
display: "flex",
|
|
79
|
+
flexWrap: "wrap",
|
|
80
|
+
gap: "0.25rem",
|
|
81
|
+
listStyle: "none",
|
|
82
|
+
padding: 0,
|
|
83
|
+
margin: 0,
|
|
84
|
+
}, children: Array.from({ length: summary.totalPages }, (_, i) => {
|
|
85
|
+
// O(1) lookup against the pre-computed Set so we don't
|
|
86
|
+
// re-scan the raw events array on every badge.
|
|
87
|
+
const done = summary.completedPageIndices.has(i);
|
|
88
|
+
const active = summary.currentPage === i;
|
|
89
|
+
const bg = done ? "#080" : active ? "#06a" : "#ccc";
|
|
90
|
+
return (_jsx("li", { title: `Page ${i + 1}: ${done ? "done" : active ? "rendering" : "pending"}`, style: {
|
|
91
|
+
width: 16,
|
|
92
|
+
height: 16,
|
|
93
|
+
borderRadius: 2,
|
|
94
|
+
background: bg,
|
|
95
|
+
border: "1px solid #999",
|
|
96
|
+
} }, i));
|
|
97
|
+
}) })), summary.receivedBytes > 0 && (_jsxs("div", { style: { fontSize: "0.6875rem", color: "#595959", marginTop: "0.375rem" }, children: [(summary.receivedBytes / 1024).toFixed(1), " KB received"] })), !connect && (_jsx("div", { style: { fontSize: "0.75rem", color: "#595959" }, children: "Streaming adapter not wired." }))] }));
|
|
98
|
+
}
|
|
99
|
+
//# sourceMappingURL=StreamingRenderProgress.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"StreamingRenderProgress.js","sourceRoot":"","sources":["../../src/components/StreamingRenderProgress.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One PANTONE catalogue entry from compile-pdf's `/v1/spots/*`
|
|
3
|
+
* endpoints. Mirrors `SpotEntry` on the apps/service
|
|
4
|
+
* `CompilePdfClient`, kept structural here so editor-app stays
|
|
5
|
+
* apps/service-dep-free.
|
|
6
|
+
*
|
|
7
|
+
* @public
|
|
8
|
+
*/
|
|
9
|
+
export type Spot = {
|
|
10
|
+
name: string;
|
|
11
|
+
library?: string | null;
|
|
12
|
+
lab?: [number, number, number] | null;
|
|
13
|
+
cmyk_bridge?: [number, number, number, number] | null;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Search adapter — the editor passes in a function that fronts
|
|
17
|
+
* `CompilePdfClient.spotSearch()`. Threading the search via a prop
|
|
18
|
+
* (rather than calling fetch directly) keeps SwatchesPicker
|
|
19
|
+
* decoupled from the network — tests pass a stub, the demo can
|
|
20
|
+
* preload an in-memory fixture, etc.
|
|
21
|
+
*
|
|
22
|
+
* @public
|
|
23
|
+
*/
|
|
24
|
+
export type SpotSearchFn = (opts: {
|
|
25
|
+
q?: string;
|
|
26
|
+
library?: string;
|
|
27
|
+
limit?: number;
|
|
28
|
+
}) => Promise<{
|
|
29
|
+
results: Spot[];
|
|
30
|
+
total: number;
|
|
31
|
+
limit: number;
|
|
32
|
+
}>;
|
|
33
|
+
/**
|
|
34
|
+
* Library descriptor — matches the wire shape of one entry in
|
|
35
|
+
* `/v1/spots/libraries`.
|
|
36
|
+
*
|
|
37
|
+
* @public
|
|
38
|
+
*/
|
|
39
|
+
export type SpotLibrary = {
|
|
40
|
+
id: string;
|
|
41
|
+
count: number;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* Props for the C3 SwatchesPicker palette.
|
|
45
|
+
*
|
|
46
|
+
* `search` is the only required prop; library filter + initial
|
|
47
|
+
* query are optional. `onSelect` fires when the user clicks a
|
|
48
|
+
* swatch — typically wired to AI4's `registerSpot` in the host.
|
|
49
|
+
*
|
|
50
|
+
* `enable_palettes: false` collapses the entire palette system off;
|
|
51
|
+
* hosts mount this component only when `isPanelVisible(config,
|
|
52
|
+
* "swatches")` returns true.
|
|
53
|
+
*
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
export type SwatchesPickerProps = {
|
|
57
|
+
search: SpotSearchFn;
|
|
58
|
+
/** Initial libraries-filter dropdown values. Hosts that already
|
|
59
|
+
* fetched `spotLibraries()` thread the result here. */
|
|
60
|
+
libraries?: SpotLibrary[];
|
|
61
|
+
/** Optional initial query. */
|
|
62
|
+
initialQuery?: string;
|
|
63
|
+
/** Click callback. Receives the full Spot row. */
|
|
64
|
+
onSelect: (spot: Spot) => void;
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Right-rail palette for browsing compile-pdf's PANTONE catalogue
|
|
68
|
+
* (codex-pdf's public-domain reference set).
|
|
69
|
+
*
|
|
70
|
+
* UX:
|
|
71
|
+
* - Search input → debounced (250 ms) call to `search()`.
|
|
72
|
+
* - Optional library dropdown (when `libraries` is supplied).
|
|
73
|
+
* - Result list as colored chips with the canonical name; click
|
|
74
|
+
* fires `onSelect`.
|
|
75
|
+
* - Footer disclaimer ("public-domain reference, not licensed
|
|
76
|
+
* PANTONE data") — present per the trademark stance.
|
|
77
|
+
*
|
|
78
|
+
* @returns An `<aside>` element with search input, library filter,
|
|
79
|
+
* results list, and the trademark disclaimer footer.
|
|
80
|
+
* @public
|
|
81
|
+
*/
|
|
82
|
+
export declare function SwatchesPicker({ search, libraries, initialQuery, onSelect, }: SwatchesPickerProps): import("react/jsx-runtime").JSX.Element;
|
|
83
|
+
//# sourceMappingURL=SwatchesPicker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwatchesPicker.d.ts","sourceRoot":"","sources":["../../src/components/SwatchesPicker.tsx"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,MAAM,MAAM,IAAI,GAAG;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;CACvD,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,YAAY,GAAG,CAAC,IAAI,EAAE;IAChC,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,KAAK,OAAO,CAAC;IAAE,OAAO,EAAE,IAAI,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEjE;;;;;GAKG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,mBAAmB,GAAG;IAChC,MAAM,EAAE,YAAY,CAAC;IACrB;4DACwD;IACxD,SAAS,CAAC,EAAE,WAAW,EAAE,CAAC;IAC1B,8BAA8B;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,kDAAkD;IAClD,QAAQ,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;CAChC,CAAC;AAoBF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,cAAc,CAAC,EAC7B,MAAM,EACN,SAAS,EACT,YAAiB,EACjB,QAAQ,GACT,EAAE,mBAAmB,2CAuKrB"}
|
|
@@ -0,0 +1,151 @@
|
|
|
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 { useEffect, useRef, useState } from "react";
|
|
5
|
+
const PANEL_BG = "#1a0f08";
|
|
6
|
+
const BORDER = "#3d1a00";
|
|
7
|
+
const BRAND = "#fc5102";
|
|
8
|
+
const TEXT = "#f4ece6";
|
|
9
|
+
const MUTED = "#888";
|
|
10
|
+
const DEBOUNCE_MS = 250;
|
|
11
|
+
const inputStyle = {
|
|
12
|
+
flex: 1,
|
|
13
|
+
padding: "0.4rem 0.6rem",
|
|
14
|
+
background: "#0f0a05",
|
|
15
|
+
border: `1px solid ${BORDER}`,
|
|
16
|
+
borderRadius: 4,
|
|
17
|
+
color: TEXT,
|
|
18
|
+
fontSize: "0.8rem",
|
|
19
|
+
fontFamily: "inherit",
|
|
20
|
+
};
|
|
21
|
+
/**
|
|
22
|
+
* Right-rail palette for browsing compile-pdf's PANTONE catalogue
|
|
23
|
+
* (codex-pdf's public-domain reference set).
|
|
24
|
+
*
|
|
25
|
+
* UX:
|
|
26
|
+
* - Search input → debounced (250 ms) call to `search()`.
|
|
27
|
+
* - Optional library dropdown (when `libraries` is supplied).
|
|
28
|
+
* - Result list as colored chips with the canonical name; click
|
|
29
|
+
* fires `onSelect`.
|
|
30
|
+
* - Footer disclaimer ("public-domain reference, not licensed
|
|
31
|
+
* PANTONE data") — present per the trademark stance.
|
|
32
|
+
*
|
|
33
|
+
* @returns An `<aside>` element with search input, library filter,
|
|
34
|
+
* results list, and the trademark disclaimer footer.
|
|
35
|
+
* @public
|
|
36
|
+
*/
|
|
37
|
+
export function SwatchesPicker({ search, libraries, initialQuery = "", onSelect, }) {
|
|
38
|
+
const [query, setQuery] = useState(initialQuery);
|
|
39
|
+
const [library, setLibrary] = useState("");
|
|
40
|
+
const [results, setResults] = useState([]);
|
|
41
|
+
const [loading, setLoading] = useState(false);
|
|
42
|
+
const [error, setError] = useState(null);
|
|
43
|
+
const reqIdRef = useRef(0);
|
|
44
|
+
useEffect(() => {
|
|
45
|
+
// Debounce — bump the request id and only commit results from
|
|
46
|
+
// the latest call. Prevents stale results overriding fresh ones
|
|
47
|
+
// when the user types quickly.
|
|
48
|
+
const id = ++reqIdRef.current;
|
|
49
|
+
const handle = setTimeout(() => {
|
|
50
|
+
setLoading(true);
|
|
51
|
+
setError(null);
|
|
52
|
+
const opts = { limit: 50 };
|
|
53
|
+
if (query)
|
|
54
|
+
opts.q = query;
|
|
55
|
+
if (library)
|
|
56
|
+
opts.library = library;
|
|
57
|
+
search(opts)
|
|
58
|
+
.then((res) => {
|
|
59
|
+
if (id !== reqIdRef.current)
|
|
60
|
+
return; // stale
|
|
61
|
+
setResults(res.results);
|
|
62
|
+
setLoading(false);
|
|
63
|
+
})
|
|
64
|
+
.catch((err) => {
|
|
65
|
+
if (id !== reqIdRef.current)
|
|
66
|
+
return;
|
|
67
|
+
const msg = err instanceof Error ? err.message : "spots search failed";
|
|
68
|
+
setError(msg);
|
|
69
|
+
setLoading(false);
|
|
70
|
+
});
|
|
71
|
+
}, DEBOUNCE_MS);
|
|
72
|
+
return () => clearTimeout(handle);
|
|
73
|
+
}, [query, library, search]);
|
|
74
|
+
return (_jsxs("aside", { style: {
|
|
75
|
+
width: 240,
|
|
76
|
+
background: PANEL_BG,
|
|
77
|
+
borderLeft: `1px solid ${BORDER}`,
|
|
78
|
+
color: TEXT,
|
|
79
|
+
display: "flex",
|
|
80
|
+
flexDirection: "column",
|
|
81
|
+
overflow: "hidden",
|
|
82
|
+
flexShrink: 0,
|
|
83
|
+
}, children: [_jsx("div", { style: {
|
|
84
|
+
fontSize: "0.7rem",
|
|
85
|
+
letterSpacing: "0.08em",
|
|
86
|
+
textTransform: "uppercase",
|
|
87
|
+
color: MUTED,
|
|
88
|
+
padding: "0.55rem 0.85rem",
|
|
89
|
+
borderBottom: `1px solid ${BORDER}`,
|
|
90
|
+
}, children: "Swatches" }), _jsx("div", { style: { padding: "0.55rem 0.65rem", display: "flex", gap: "0.4rem" }, children: _jsx("input", { value: query, onChange: (e) => setQuery(e.target.value), placeholder: "Search PANTONE\u2026", "aria-label": "Search PANTONE catalogue", style: inputStyle }) }), libraries && libraries.length > 0 && (_jsx("div", { style: { padding: "0 0.65rem 0.55rem" }, children: _jsxs("select", { value: library, onChange: (e) => setLibrary(e.target.value), "aria-label": "Filter by library", style: { ...inputStyle, width: "100%" }, children: [_jsx("option", { value: "", children: "All libraries" }), libraries.map((lib) => (_jsxs("option", { value: lib.id, children: [lib.id, " (", lib.count, ")"] }, lib.id)))] }) })), _jsxs("div", { style: { flex: 1, overflow: "auto" }, children: [loading && (_jsx("div", { style: { padding: "0.55rem 0.85rem", color: MUTED, fontSize: "0.78rem" }, children: "Loading\u2026" })), error && !loading && (_jsx("div", { role: "alert", style: { padding: "0.55rem 0.85rem", color: "#ef4444", fontSize: "0.78rem" }, children: error })), !loading && !error && results.length === 0 && (_jsx("div", { style: { padding: "0.55rem 0.85rem", color: MUTED, fontSize: "0.78rem" }, children: "No matches." })), !loading &&
|
|
91
|
+
!error &&
|
|
92
|
+
results.map((spot) => {
|
|
93
|
+
const swatchColor = labToCssApprox(spot.lab) ?? "#666";
|
|
94
|
+
return (_jsxs("button", { type: "button", onClick: () => onSelect(spot), style: {
|
|
95
|
+
display: "flex",
|
|
96
|
+
alignItems: "center",
|
|
97
|
+
gap: "0.55rem",
|
|
98
|
+
width: "100%",
|
|
99
|
+
padding: "0.35rem 0.85rem",
|
|
100
|
+
background: "transparent",
|
|
101
|
+
border: "none",
|
|
102
|
+
borderLeft: "2px solid transparent",
|
|
103
|
+
cursor: "pointer",
|
|
104
|
+
color: TEXT,
|
|
105
|
+
fontSize: "0.78rem",
|
|
106
|
+
fontFamily: "inherit",
|
|
107
|
+
textAlign: "left",
|
|
108
|
+
}, onMouseEnter: (e) => {
|
|
109
|
+
e.currentTarget.style.borderLeftColor = BRAND;
|
|
110
|
+
}, onMouseLeave: (e) => {
|
|
111
|
+
e.currentTarget.style.borderLeftColor = "transparent";
|
|
112
|
+
}, children: [_jsx("span", { style: {
|
|
113
|
+
display: "inline-block",
|
|
114
|
+
width: 16,
|
|
115
|
+
height: 16,
|
|
116
|
+
borderRadius: 3,
|
|
117
|
+
background: swatchColor,
|
|
118
|
+
border: `1px solid ${BORDER}`,
|
|
119
|
+
flexShrink: 0,
|
|
120
|
+
} }), _jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis" }, children: spot.name })] }, spot.name));
|
|
121
|
+
})] }), _jsx("div", { style: {
|
|
122
|
+
padding: "0.45rem 0.85rem",
|
|
123
|
+
borderTop: `1px solid ${BORDER}`,
|
|
124
|
+
color: MUTED,
|
|
125
|
+
fontSize: "0.65rem",
|
|
126
|
+
lineHeight: 1.35,
|
|
127
|
+
}, children: "Public-domain colour-science reference. Not licensed PANTONE data." })] }));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Crude Lab → CSS-color approximation for the swatch chips. Not a
|
|
131
|
+
* colorimetric conversion — just enough to give each row a
|
|
132
|
+
* recognizable tint in the picker. Returns `undefined` for entries
|
|
133
|
+
* without a Lab triplet (the chip falls back to a neutral grey).
|
|
134
|
+
*
|
|
135
|
+
* Lab L is 0-100 (perceptual lightness); we map directly to sRGB
|
|
136
|
+
* grey then shift slightly toward a/b axes. Future: replace with a
|
|
137
|
+
* proper Lab→sRGB conversion via culori or chroma-js if perceptual
|
|
138
|
+
* accuracy matters for the picker.
|
|
139
|
+
*/
|
|
140
|
+
function labToCssApprox(lab) {
|
|
141
|
+
if (!lab)
|
|
142
|
+
return undefined;
|
|
143
|
+
const [L, a, b] = lab;
|
|
144
|
+
// Very rough — clamps to a tinted grey based on a/b sign.
|
|
145
|
+
const lum = Math.max(0, Math.min(255, Math.round((L / 100) * 255)));
|
|
146
|
+
const r = Math.max(0, Math.min(255, lum + Math.round(a * 1.5)));
|
|
147
|
+
const g = Math.max(0, Math.min(255, lum - Math.round(Math.abs(a) * 0.5)));
|
|
148
|
+
const bl = Math.max(0, Math.min(255, lum - Math.round(b * 1.5)));
|
|
149
|
+
return `rgb(${r}, ${g}, ${bl})`;
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=SwatchesPicker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SwatchesPicker.js","sourceRoot":"","sources":["../../src/components/SwatchesPicker.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import type Konva from "konva";
|
|
2
|
+
/**
|
|
3
|
+
* C4 live total-area-coverage overlay.
|
|
4
|
+
*
|
|
5
|
+
* Sits as an absolutely-positioned `<canvas>` on top of the Konva
|
|
6
|
+
* Stage, debouncing a rasterize-and-sample pass on every change to
|
|
7
|
+
* the watched objects array. Paints pixels whose TAC exceeds the
|
|
8
|
+
* configured threshold (default 300%) in translucent red — a "where
|
|
9
|
+
* the ink is going to pool" hint — and shows a `max / avg` chip in
|
|
10
|
+
* the bottom-left.
|
|
11
|
+
*
|
|
12
|
+
* Browser-side sanity check, not a colorimetric proof: the same
|
|
13
|
+
* caveats as {@link import("../lib/rasterize").sampleTACFromImageData}
|
|
14
|
+
* apply (subtractive sRGB → CMYK with K-extraction, alpha composited
|
|
15
|
+
* onto an opaque white background). Production TAC enforcement lives
|
|
16
|
+
* server-side in compile-pdf's `total_ink_coverage` preflight rule.
|
|
17
|
+
*
|
|
18
|
+
* @public
|
|
19
|
+
*/
|
|
20
|
+
export type TacOverlayProps = {
|
|
21
|
+
/** Live Konva Stage. The overlay no-ops while this is `null` (the
|
|
22
|
+
* ref starts null on first render). */
|
|
23
|
+
stage: Konva.Stage | null;
|
|
24
|
+
/** Container width/height in CSS pixels — the overlay canvas
|
|
25
|
+
* matches these so it lines up with the Stage. */
|
|
26
|
+
width: number;
|
|
27
|
+
height: number;
|
|
28
|
+
/** Re-sample trigger. Any change to this value (by reference for
|
|
29
|
+
* arrays, by equality for primitives) debounces a new rasterize
|
|
30
|
+
* pass. The value itself isn't read — it just lets React's effect
|
|
31
|
+
* diffing detect editor changes. Pass `objects` (the canvas
|
|
32
|
+
* contents array) so every commit re-samples. */
|
|
33
|
+
trigger: unknown;
|
|
34
|
+
/** TAC threshold in percent (0-400). Pixels at or above the
|
|
35
|
+
* threshold are painted; pixels below are transparent. Defaults to
|
|
36
|
+
* 300% — the standard coated-stock preflight ceiling. */
|
|
37
|
+
thresholdPct?: number;
|
|
38
|
+
/** Debounce window in milliseconds before a new sample fires.
|
|
39
|
+
* Defaults to 250 ms — fast enough to feel live, slow enough that
|
|
40
|
+
* click-drag operations don't thrash the rasterizer. */
|
|
41
|
+
debounceMs?: number;
|
|
42
|
+
};
|
|
43
|
+
/**
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export declare function TacOverlay({ stage, width, height, trigger, thresholdPct, debounceMs, }: TacOverlayProps): import("react/jsx-runtime").JSX.Element;
|
|
47
|
+
//# sourceMappingURL=TacOverlay.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TacOverlay.d.ts","sourceRoot":"","sources":["../../src/components/TacOverlay.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B;4CACwC;IACxC,KAAK,EAAE,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC;IAC1B;uDACmD;IACnD,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf;;;;sDAIkD;IAClD,OAAO,EAAE,OAAO,CAAC;IACjB;;8DAE0D;IAC1D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;6DAEyD;IACzD,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;GAEG;AACH,wBAAgB,UAAU,CAAC,EACzB,KAAK,EACL,KAAK,EACL,MAAM,EACN,OAAO,EACP,YAAkB,EAClB,UAAgB,GACjB,EAAE,eAAe,2CA0HjB"}
|