@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,158 @@
|
|
|
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
|
+
* Canonical severity order — errors first so press-blocking issues
|
|
7
|
+
* surface at the top.
|
|
8
|
+
*
|
|
9
|
+
* @public
|
|
10
|
+
*/
|
|
11
|
+
export const BRAND_CONSISTENCY_SEVERITY_ORDER = [
|
|
12
|
+
"error",
|
|
13
|
+
"warn",
|
|
14
|
+
"info",
|
|
15
|
+
];
|
|
16
|
+
const SEVERITY_LABELS = {
|
|
17
|
+
error: "Errors",
|
|
18
|
+
warn: "Warnings",
|
|
19
|
+
info: "Info",
|
|
20
|
+
};
|
|
21
|
+
const SEVERITY_COLORS = {
|
|
22
|
+
error: "#a00",
|
|
23
|
+
warn: "#a60",
|
|
24
|
+
info: "#06a",
|
|
25
|
+
};
|
|
26
|
+
/**
|
|
27
|
+
* Pure helper — filters findings by severity / asset kind. Returns a
|
|
28
|
+
* new array; preserves input order. Pure function.
|
|
29
|
+
*
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export function filterBrandConsistencyFindings(findings, filter) {
|
|
33
|
+
return findings.filter((f) => {
|
|
34
|
+
if (filter.severity && f.severity !== filter.severity)
|
|
35
|
+
return false;
|
|
36
|
+
if (filter.assetKind && f.assetKind !== filter.assetKind)
|
|
37
|
+
return false;
|
|
38
|
+
return true;
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Pure helper — groups findings by severity in
|
|
43
|
+
* {@link BRAND_CONSISTENCY_SEVERITY_ORDER}. Returns a stable
|
|
44
|
+
* three-bucket shape so renderers iterate without absent-key checks.
|
|
45
|
+
*
|
|
46
|
+
* Pure function.
|
|
47
|
+
*
|
|
48
|
+
* @public
|
|
49
|
+
*/
|
|
50
|
+
export function groupBrandConsistencyFindingsBySeverity(findings) {
|
|
51
|
+
const buckets = new Map(BRAND_CONSISTENCY_SEVERITY_ORDER.map((s) => [s, []]));
|
|
52
|
+
for (const f of findings) {
|
|
53
|
+
buckets.get(f.severity)?.push(f);
|
|
54
|
+
}
|
|
55
|
+
return BRAND_CONSISTENCY_SEVERITY_ORDER.map((severity) => ({
|
|
56
|
+
severity,
|
|
57
|
+
findings: buckets.get(severity) ?? [],
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Stateful panel — loads the finding stream on mount, surfaces the
|
|
62
|
+
* filtered + grouped list, and emits `onSelect` on row click.
|
|
63
|
+
* Handles loading / error / empty states inline.
|
|
64
|
+
*
|
|
65
|
+
* @public
|
|
66
|
+
*/
|
|
67
|
+
export function BrandConsistencyPanel({ loader, filterSeverity, filterAssetKind, activeFindingId, onSelect, }) {
|
|
68
|
+
const [findings, setFindings] = useState(null);
|
|
69
|
+
const [error, setError] = useState(null);
|
|
70
|
+
const [loading, setLoading] = useState(true);
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
let disposed = false;
|
|
73
|
+
setLoading(true);
|
|
74
|
+
setError(null);
|
|
75
|
+
setFindings(null);
|
|
76
|
+
void (async () => {
|
|
77
|
+
try {
|
|
78
|
+
const next = await loader();
|
|
79
|
+
if (disposed)
|
|
80
|
+
return;
|
|
81
|
+
setFindings(next);
|
|
82
|
+
}
|
|
83
|
+
catch (err) {
|
|
84
|
+
if (disposed)
|
|
85
|
+
return;
|
|
86
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
87
|
+
}
|
|
88
|
+
finally {
|
|
89
|
+
if (!disposed)
|
|
90
|
+
setLoading(false);
|
|
91
|
+
}
|
|
92
|
+
})();
|
|
93
|
+
return () => {
|
|
94
|
+
disposed = true;
|
|
95
|
+
};
|
|
96
|
+
}, [loader]);
|
|
97
|
+
const visibleGroups = useMemo(() => {
|
|
98
|
+
if (!findings)
|
|
99
|
+
return null;
|
|
100
|
+
const filtered = filterBrandConsistencyFindings(findings, {
|
|
101
|
+
...(filterSeverity && { severity: filterSeverity }),
|
|
102
|
+
...(filterAssetKind && { assetKind: filterAssetKind }),
|
|
103
|
+
});
|
|
104
|
+
return groupBrandConsistencyFindingsBySeverity(filtered);
|
|
105
|
+
}, [findings, filterSeverity, filterAssetKind]);
|
|
106
|
+
if (loading) {
|
|
107
|
+
return (_jsx("output", { "data-testid": "brand-consistency-panel", "aria-live": "polite", style: { display: "block", padding: "0.5rem", opacity: 0.6 }, children: "Loading brand findings\u2026" }));
|
|
108
|
+
}
|
|
109
|
+
if (error) {
|
|
110
|
+
return (_jsxs("div", { "data-testid": "brand-consistency-panel", role: "alert", style: { padding: "0.5rem", color: "#a00" }, children: ["Couldn't load brand findings: ", error] }));
|
|
111
|
+
}
|
|
112
|
+
if (!visibleGroups)
|
|
113
|
+
return _jsx("div", { "data-testid": "brand-consistency-panel" });
|
|
114
|
+
const totalVisible = visibleGroups.reduce((s, g) => s + g.findings.length, 0);
|
|
115
|
+
return (_jsxs("div", { "data-testid": "brand-consistency-panel", style: { padding: "0.5rem" }, children: [_jsx("header", { style: { marginBottom: "0.5rem" }, children: _jsxs("h3", { style: { margin: 0, fontSize: "0.875rem" }, children: ["Brand consistency (", totalVisible, ")"] }) }), totalVisible === 0 && (_jsx("div", { "data-testid": "brand-consistency-panel-empty", style: { opacity: 0.6, fontSize: "0.875rem" }, children: findings && findings.length > 0
|
|
116
|
+
? "No findings match the current filter."
|
|
117
|
+
: "On-brand — no findings." })), visibleGroups.map((group) => {
|
|
118
|
+
if (group.findings.length === 0)
|
|
119
|
+
return null;
|
|
120
|
+
return (_jsxs("section", { "data-testid": `brand-consistency-group-${group.severity}`, style: { marginBottom: "0.75rem" }, children: [_jsxs("h4", { style: {
|
|
121
|
+
margin: "0 0 0.25rem 0",
|
|
122
|
+
fontSize: "0.75rem",
|
|
123
|
+
color: SEVERITY_COLORS[group.severity],
|
|
124
|
+
textTransform: "uppercase",
|
|
125
|
+
letterSpacing: "0.05em",
|
|
126
|
+
}, children: [SEVERITY_LABELS[group.severity], " (", group.findings.length, ")"] }), _jsx("ul", { style: { listStyle: "none", padding: 0, margin: 0 }, children: group.findings.map((finding) => (_jsx(BrandConsistencyRow, { finding: finding, isActive: finding.id === activeFindingId, onSelect: onSelect }, finding.id))) })] }, group.severity));
|
|
127
|
+
})] }));
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Renders one finding row. Intra-package helper — the row's surface
|
|
131
|
+
* (asset-kind chip, summary, optional description, optional jump
|
|
132
|
+
* affordance) is intentionally minimal so {@link BrandConsistencyPanel}
|
|
133
|
+
* can swap it without downstream consumers depending on the shape.
|
|
134
|
+
*/
|
|
135
|
+
function BrandConsistencyRow({ finding, isActive, onSelect, }) {
|
|
136
|
+
const rowStyle = {
|
|
137
|
+
display: "block",
|
|
138
|
+
width: "100%",
|
|
139
|
+
padding: "0.375rem 0.5rem",
|
|
140
|
+
background: isActive ? "#e0ecff" : "transparent",
|
|
141
|
+
border: isActive ? "1px solid #2563eb" : "1px solid #ddd",
|
|
142
|
+
borderRadius: 4,
|
|
143
|
+
marginBottom: "0.25rem",
|
|
144
|
+
textAlign: "left",
|
|
145
|
+
cursor: onSelect ? "pointer" : "default",
|
|
146
|
+
};
|
|
147
|
+
const contents = (_jsxs(_Fragment, { children: [_jsxs("div", { style: { fontSize: "0.8125rem", fontWeight: 500 }, children: [_jsx("span", { style: {
|
|
148
|
+
display: "inline-block",
|
|
149
|
+
fontSize: "0.625rem",
|
|
150
|
+
padding: "0.0625rem 0.375rem",
|
|
151
|
+
borderRadius: 999,
|
|
152
|
+
background: "#eee",
|
|
153
|
+
color: "#595959",
|
|
154
|
+
marginRight: "0.375rem",
|
|
155
|
+
}, children: finding.assetKind }), finding.summary] }), finding.description && (_jsx("div", { style: { fontSize: "0.75rem", color: "#595959", marginTop: "0.125rem" }, children: finding.description }))] }));
|
|
156
|
+
return (_jsx("li", { children: onSelect ? (_jsx("button", { type: "button", onClick: () => onSelect(finding), style: rowStyle, children: contents })) : (_jsx("div", { style: rowStyle, children: contents })) }));
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=BrandConsistencyPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrandConsistencyPanel.js","sourceRoot":"","sources":["../../src/components/BrandConsistencyPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One compliance finding — mirrors lint-pdf's `Finding` wire shape
|
|
3
|
+
* but is duplicated here so the editor stays consumable without the
|
|
4
|
+
* lint-pdf SDK (same pattern as `EditorSeparation`).
|
|
5
|
+
*
|
|
6
|
+
* @public
|
|
7
|
+
*/
|
|
8
|
+
export type ComplianceFinding = {
|
|
9
|
+
ruleId: string;
|
|
10
|
+
severity: "error" | "warn" | "info";
|
|
11
|
+
message: string;
|
|
12
|
+
/** 0-indexed page reference, if the finding is scoped to one. */
|
|
13
|
+
pageIndex?: number;
|
|
14
|
+
/** Optional id of the offending object on `pageIndex`. */
|
|
15
|
+
objectId?: string;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Host-supplied adapter. Receives the document + the process /
|
|
19
|
+
* substrate context the host has collected (typically from the
|
|
20
|
+
* Job-Setup panel) and returns the compliance findings. Rejects on
|
|
21
|
+
* transport errors; the panel surfaces the message inline.
|
|
22
|
+
*
|
|
23
|
+
* `documentB64` is required — the panel never invokes the loader
|
|
24
|
+
* without a rendered PDF in hand, so hosts shouldn't have to handle
|
|
25
|
+
* a `undefined`-input case.
|
|
26
|
+
*
|
|
27
|
+
* **Identity matters.** The panel re-fetches whenever the `loader`
|
|
28
|
+
* reference changes (the standard React-effect dependency rule);
|
|
29
|
+
* hosts that build the adapter inline should memoize it with
|
|
30
|
+
* `useCallback` so an unrelated parent re-render doesn't trigger a
|
|
31
|
+
* spurious `POST /v1/preflight/process` round-trip.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
34
|
+
*/
|
|
35
|
+
export type ComplianceLoaderFn = (input: {
|
|
36
|
+
documentB64: string;
|
|
37
|
+
process: string;
|
|
38
|
+
substrate: string;
|
|
39
|
+
}) => Promise<readonly ComplianceFinding[]>;
|
|
40
|
+
/**
|
|
41
|
+
* @public
|
|
42
|
+
*/
|
|
43
|
+
export type ComplianceFindingsPanelProps = {
|
|
44
|
+
/** Latest rendered document — base64 PDF or `undefined` for an
|
|
45
|
+
* "export first" affordance. */
|
|
46
|
+
documentB64: string | undefined;
|
|
47
|
+
/** Process class from `PrintContext.process` — drives the
|
|
48
|
+
* process_is matcher in lint-pdf's conditional rule engine. */
|
|
49
|
+
process: string | undefined;
|
|
50
|
+
/** Substrate class — drives the substrate_is matcher. */
|
|
51
|
+
substrate: string | undefined;
|
|
52
|
+
/** Adapter that resolves to the compliance findings. */
|
|
53
|
+
loader: ComplianceLoaderFn;
|
|
54
|
+
/** Optional callback fired when a finding row is clicked — hosts
|
|
55
|
+
* wire this to highlight the offending object on canvas. */
|
|
56
|
+
onSelect?: (finding: ComplianceFinding) => void;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* @public
|
|
60
|
+
*/
|
|
61
|
+
export declare function ComplianceFindingsPanel({ documentB64, process, substrate, loader, onSelect, }: ComplianceFindingsPanelProps): import("react/jsx-runtime").JSX.Element;
|
|
62
|
+
//# sourceMappingURL=ComplianceFindingsPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComplianceFindingsPanel.d.ts","sourceRoot":"","sources":["../../src/components/ComplianceFindingsPanel.tsx"],"names":[],"mappings":"AAwBA;;;;;;GAMG;AACH,MAAM,MAAM,iBAAiB,GAAG;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,iEAAiE;IACjE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,MAAM,kBAAkB,GAAG,CAAC,KAAK,EAAE;IACvC,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB,KAAK,OAAO,CAAC,SAAS,iBAAiB,EAAE,CAAC,CAAC;AAE5C;;GAEG;AACH,MAAM,MAAM,4BAA4B,GAAG;IACzC;qCACiC;IACjC,WAAW,EAAE,MAAM,GAAG,SAAS,CAAC;IAChC;oEACgE;IAChE,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,yDAAyD;IACzD,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,wDAAwD;IACxD,MAAM,EAAE,kBAAkB,CAAC;IAC3B;iEAC6D;IAC7D,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,iBAAiB,KAAK,IAAI,CAAC;CACjD,CAAC;AAQF;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,EACtC,WAAW,EACX,OAAO,EACP,SAAS,EACT,MAAM,EACN,QAAQ,GACT,EAAE,4BAA4B,2CA0I9B"}
|
|
@@ -0,0 +1,118 @@
|
|
|
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
|
+
/**
|
|
5
|
+
* Wave 2 P3 — Compliance findings panel.
|
|
6
|
+
*
|
|
7
|
+
* Surfaces the substrate / market / regulation findings produced by
|
|
8
|
+
* lint-pdf's `P3_compliance_v1` profile (PR-D) separately from the
|
|
9
|
+
* existing generic preflight panel. Generic preflight stays for "does
|
|
10
|
+
* this PDF render" findings; this panel is for "is this artwork *
|
|
11
|
+
* allowed* on the chosen substrate / market". The split keeps the two
|
|
12
|
+
* audiences scannable: a press operator only wants to see render
|
|
13
|
+
* blockers, a brand compliance lead only wants to see substrate /
|
|
14
|
+
* regulation issues.
|
|
15
|
+
*
|
|
16
|
+
* Adapter pattern: hosts wire an async function that POSTs the
|
|
17
|
+
* document + process / substrate to lint-pdf's
|
|
18
|
+
* `/v1/preflight/process` endpoint (PR-E). This keeps the editor
|
|
19
|
+
* package free of a runtime dep on lint-pdf's HTTP client.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
import { useEffect, useState } from "react";
|
|
24
|
+
const SEVERITY_COLORS = {
|
|
25
|
+
error: "#a00",
|
|
26
|
+
warn: "#a60",
|
|
27
|
+
info: "#06a",
|
|
28
|
+
};
|
|
29
|
+
/**
|
|
30
|
+
* @public
|
|
31
|
+
*/
|
|
32
|
+
export function ComplianceFindingsPanel({ documentB64, process, substrate, loader, onSelect, }) {
|
|
33
|
+
const [findings, setFindings] = useState(null);
|
|
34
|
+
const [error, setError] = useState(null);
|
|
35
|
+
const [loading, setLoading] = useState(false);
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!documentB64 || !process || !substrate) {
|
|
38
|
+
setFindings(null);
|
|
39
|
+
setError(null);
|
|
40
|
+
return;
|
|
41
|
+
}
|
|
42
|
+
let disposed = false;
|
|
43
|
+
setLoading(true);
|
|
44
|
+
setError(null);
|
|
45
|
+
// Wrap the loader call in an async IIFE so a *synchronous*
|
|
46
|
+
// throw from the adapter (e.g. a host that validates inputs
|
|
47
|
+
// before constructing the fetch Promise) flows through the
|
|
48
|
+
// same `setError` path as a rejected Promise — otherwise the
|
|
49
|
+
// throw would escape the effect and leave the panel stuck on
|
|
50
|
+
// "Checking compliance…".
|
|
51
|
+
void (async () => {
|
|
52
|
+
try {
|
|
53
|
+
const next = await loader({ documentB64, process, substrate });
|
|
54
|
+
if (disposed)
|
|
55
|
+
return;
|
|
56
|
+
setFindings(next);
|
|
57
|
+
}
|
|
58
|
+
catch (err) {
|
|
59
|
+
if (disposed)
|
|
60
|
+
return;
|
|
61
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
62
|
+
}
|
|
63
|
+
finally {
|
|
64
|
+
if (!disposed)
|
|
65
|
+
setLoading(false);
|
|
66
|
+
}
|
|
67
|
+
})();
|
|
68
|
+
return () => {
|
|
69
|
+
disposed = true;
|
|
70
|
+
};
|
|
71
|
+
}, [documentB64, process, substrate, loader]);
|
|
72
|
+
if (!documentB64 || !process || !substrate) {
|
|
73
|
+
return (_jsx("div", { "data-testid": "compliance-findings-panel", style: { padding: "0.5rem", opacity: 0.6 }, children: "Set process + substrate in Job Setup, then export to see compliance findings." }));
|
|
74
|
+
}
|
|
75
|
+
if (loading) {
|
|
76
|
+
return (_jsx("div", { "data-testid": "compliance-findings-panel", style: { padding: "0.5rem", opacity: 0.6 }, children: "Checking compliance\u2026" }));
|
|
77
|
+
}
|
|
78
|
+
if (error) {
|
|
79
|
+
return (_jsxs("div", { "data-testid": "compliance-findings-panel", role: "alert", style: { padding: "0.5rem", color: "#a00" }, children: ["Couldn't load compliance findings: ", error] }));
|
|
80
|
+
}
|
|
81
|
+
if (!findings || findings.length === 0) {
|
|
82
|
+
return (_jsxs("div", { "data-testid": "compliance-findings-panel", style: { padding: "0.5rem", opacity: 0.6 }, children: ["No compliance issues for ", process, " on ", substrate, "."] }));
|
|
83
|
+
}
|
|
84
|
+
return (_jsxs("div", { "data-testid": "compliance-findings-panel", style: { padding: "0.5rem" }, children: [_jsxs("h3", { style: { margin: "0 0 0.5rem 0" }, children: ["Compliance (", findings.length, ")"] }), _jsx("ul", { style: { listStyle: "none", padding: 0, margin: 0 }, children: findings.map((f, i) => {
|
|
85
|
+
// Append the array index so duplicate (ruleId, pageIndex,
|
|
86
|
+
// objectId) tuples — which the lint-pdf wire format allows
|
|
87
|
+
// when the same rule fires twice on the same target with
|
|
88
|
+
// different messages — still get unique React keys.
|
|
89
|
+
const key = `${f.ruleId}-${f.pageIndex ?? "doc"}-${f.objectId ?? ""}-${i}`;
|
|
90
|
+
const rowContents = (_jsxs(_Fragment, { children: [_jsx("span", { "aria-hidden": "true", style: {
|
|
91
|
+
display: "inline-block",
|
|
92
|
+
width: "0.5rem",
|
|
93
|
+
height: "0.5rem",
|
|
94
|
+
borderRadius: "50%",
|
|
95
|
+
background: SEVERITY_COLORS[f.severity],
|
|
96
|
+
flexShrink: 0,
|
|
97
|
+
} }), _jsx("span", { style: { flex: 1 }, children: f.message }), _jsxs("small", { style: { opacity: 0.6, fontFamily: "monospace" }, children: [f.ruleId, f.pageIndex !== undefined ? ` · p${f.pageIndex + 1}` : ""] })] }));
|
|
98
|
+
const rowStyle = {
|
|
99
|
+
display: "flex",
|
|
100
|
+
alignItems: "baseline",
|
|
101
|
+
gap: "0.5rem",
|
|
102
|
+
width: "100%",
|
|
103
|
+
padding: "0.25rem 0.5rem",
|
|
104
|
+
};
|
|
105
|
+
// When the host wires no `onSelect`, rendering a `<button>`
|
|
106
|
+
// would announce an interactive control to screen-reader
|
|
107
|
+
// users that does nothing on activation — render a plain
|
|
108
|
+
// div instead so the finding is read as static content.
|
|
109
|
+
return (_jsx("li", { children: onSelect ? (_jsx("button", { type: "button", onClick: () => onSelect(f), "aria-label": `Compliance finding: ${f.message} (${f.ruleId}${f.pageIndex !== undefined ? `, page ${f.pageIndex + 1}` : ""})`, style: {
|
|
110
|
+
...rowStyle,
|
|
111
|
+
background: "transparent",
|
|
112
|
+
border: "none",
|
|
113
|
+
cursor: "pointer",
|
|
114
|
+
textAlign: "left",
|
|
115
|
+
}, children: rowContents })) : (_jsx("div", { style: rowStyle, children: rowContents })) }, key));
|
|
116
|
+
}) })] }));
|
|
117
|
+
}
|
|
118
|
+
//# sourceMappingURL=ComplianceFindingsPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComplianceFindingsPanel.js","sourceRoot":"","sources":["../../src/components/ComplianceFindingsPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 4 AI1 — AI design-suggestions panel.
|
|
3
|
+
*
|
|
4
|
+
* Surfaces a host-loader-supplied stream of AI-generated design
|
|
5
|
+
* suggestions for the active document — typography hierarchy hints,
|
|
6
|
+
* contrast warnings, layout balance critiques, color-harmony nudges,
|
|
7
|
+
* etc. Typical suggestion sources: a synergy `design.suggest`
|
|
8
|
+
* workflow node, a tenant-trained model behind the host's auth, or a
|
|
9
|
+
* heuristics engine that walks the document for canned advice.
|
|
10
|
+
*
|
|
11
|
+
* Each suggestion carries an opaque `applyHint` bag the host knows
|
|
12
|
+
* how to interpret + apply — the editor stays runtime-free of the
|
|
13
|
+
* suggestion logic and only handles UI plumbing (loading, filtering
|
|
14
|
+
* by category, click-to-focus, apply / dismiss).
|
|
15
|
+
*
|
|
16
|
+
* Sibling of {@link PreflightAutoFixPanel} (Wave 4 AI3): that one
|
|
17
|
+
* remediates rule violations, this one offers proactive aesthetic
|
|
18
|
+
* advice. Both follow the same loader-adapter pattern.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
import type { ReactElement } from "react";
|
|
23
|
+
/**
|
|
24
|
+
* Discriminator on which the panel groups its suggestions and which
|
|
25
|
+
* downstream renderers (mini-dashboard, "Top 3 fixes" badge, …) can
|
|
26
|
+
* pivot. `"other"` is the escape hatch for tenant-specific
|
|
27
|
+
* categories that don't map to the five canonical buckets.
|
|
28
|
+
*
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export type DesignSuggestionCategory = "typography" | "color" | "layout" | "contrast" | "imagery" | "other";
|
|
32
|
+
/**
|
|
33
|
+
* One AI-supplied design suggestion. The shape is intentionally
|
|
34
|
+
* minimal: a stable id, a category for grouping, a one-line summary,
|
|
35
|
+
* an optional long-form rationale, an opaque `applyHint` the host
|
|
36
|
+
* applies, and an optional `confidence` ([0,1]) for sorting / chip
|
|
37
|
+
* decoration.
|
|
38
|
+
*
|
|
39
|
+
* `applyHint` is forwarded to `onApply` verbatim — its shape is a
|
|
40
|
+
* contract between the host's loader and its `onApply` handler. The
|
|
41
|
+
* panel never inspects it.
|
|
42
|
+
*
|
|
43
|
+
* @public
|
|
44
|
+
*/
|
|
45
|
+
export type DesignSuggestion = {
|
|
46
|
+
id: string;
|
|
47
|
+
category: DesignSuggestionCategory;
|
|
48
|
+
summary: string;
|
|
49
|
+
description?: string;
|
|
50
|
+
applyHint?: Record<string, unknown>;
|
|
51
|
+
/** Loader-supplied confidence in `[0, 1]`. Optional — when absent
|
|
52
|
+
* the panel doesn't surface a confidence chip. Suggestions are
|
|
53
|
+
* grouped by category in {@link DESIGN_SUGGESTION_CATEGORY_ORDER}
|
|
54
|
+
* and keep loader-supplied order within each bucket; the panel
|
|
55
|
+
* does not re-sort by confidence or id. */
|
|
56
|
+
confidence?: number;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* Host adapter — resolves a stream of suggestions for the active
|
|
60
|
+
* document context. Resolves with a fresh list each call; rejects on
|
|
61
|
+
* transport / validation errors and the panel surfaces the message
|
|
62
|
+
* inline. Hosts should memoize the function with `useCallback` so an
|
|
63
|
+
* unrelated parent re-render doesn't trigger a spurious refetch.
|
|
64
|
+
*
|
|
65
|
+
* @public
|
|
66
|
+
*/
|
|
67
|
+
export type DesignSuggestionLoaderFn = () => Promise<readonly DesignSuggestion[]>;
|
|
68
|
+
/**
|
|
69
|
+
* Filter spec accepted by {@link filterDesignSuggestions}.
|
|
70
|
+
*
|
|
71
|
+
* @public
|
|
72
|
+
*/
|
|
73
|
+
export type DesignSuggestionFilter = {
|
|
74
|
+
category?: DesignSuggestionCategory;
|
|
75
|
+
/** Minimum confidence in `[0, 1]`. Suggestions without a
|
|
76
|
+
* `confidence` field are kept when `minConfidence` is absent or
|
|
77
|
+
* zero, and excluded when `minConfidence > 0` (no signal = drop). */
|
|
78
|
+
minConfidence?: number;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* Result row from {@link groupDesignSuggestionsByCategory}.
|
|
82
|
+
*
|
|
83
|
+
* @public
|
|
84
|
+
*/
|
|
85
|
+
export type DesignSuggestionGroup = {
|
|
86
|
+
category: DesignSuggestionCategory;
|
|
87
|
+
suggestions: readonly DesignSuggestion[];
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Canonical category order — typography is the first thing a human
|
|
91
|
+
* eye lands on; "other" is the escape hatch at the tail.
|
|
92
|
+
*
|
|
93
|
+
* @public
|
|
94
|
+
*/
|
|
95
|
+
export declare const DESIGN_SUGGESTION_CATEGORY_ORDER: readonly DesignSuggestionCategory[];
|
|
96
|
+
/**
|
|
97
|
+
* Pure helper — filters suggestions by category / minConfidence.
|
|
98
|
+
* Returns a new array; preserves input order. Pure function.
|
|
99
|
+
*
|
|
100
|
+
* @public
|
|
101
|
+
*/
|
|
102
|
+
export declare function filterDesignSuggestions(suggestions: readonly DesignSuggestion[], filter: DesignSuggestionFilter): readonly DesignSuggestion[];
|
|
103
|
+
/**
|
|
104
|
+
* Pure helper — groups suggestions by category in
|
|
105
|
+
* {@link DESIGN_SUGGESTION_CATEGORY_ORDER}. Returns a stable
|
|
106
|
+
* six-bucket shape so renderers iterate without absent-key checks.
|
|
107
|
+
* Unknown runtime categories fall into "other" rather than being
|
|
108
|
+
* dropped (defensive against forward-compat catalogue extensions).
|
|
109
|
+
*
|
|
110
|
+
* Pure function.
|
|
111
|
+
*
|
|
112
|
+
* @public
|
|
113
|
+
*/
|
|
114
|
+
export declare function groupDesignSuggestionsByCategory(suggestions: readonly DesignSuggestion[]): readonly DesignSuggestionGroup[];
|
|
115
|
+
/**
|
|
116
|
+
* Configuration for the {@link DesignSuggestionsPanel}. The host
|
|
117
|
+
* always supplies the {@link DesignSuggestionLoaderFn}; the other
|
|
118
|
+
* three props are optional and shape the panel's initial filter
|
|
119
|
+
* floor and apply / dismiss wiring. Hosts that ship a high-recall
|
|
120
|
+
* model can tighten the surface up-front via `defaultMinConfidence`.
|
|
121
|
+
*
|
|
122
|
+
* @public
|
|
123
|
+
*/
|
|
124
|
+
export type DesignSuggestionsPanelProps = {
|
|
125
|
+
/** Host adapter, see {@link DesignSuggestionLoaderFn}. The panel
|
|
126
|
+
* calls it on mount and whenever the function reference changes. */
|
|
127
|
+
loader: DesignSuggestionLoaderFn;
|
|
128
|
+
/** Optional minimum-confidence floor for the in-panel filter
|
|
129
|
+
* (`[0, 1]`). Hosts that ship a high-recall model can default the
|
|
130
|
+
* panel to `0.5` or higher to keep the surface focused. */
|
|
131
|
+
defaultMinConfidence?: number;
|
|
132
|
+
/** Fired when the user clicks "Apply" on a suggestion. The host
|
|
133
|
+
* inspects `suggestion.applyHint` and mutates the document. */
|
|
134
|
+
onApply?: (suggestion: DesignSuggestion) => void;
|
|
135
|
+
/** Fired when the user clicks "Dismiss" on a suggestion. The host
|
|
136
|
+
* typically writes the id into a per-document dismissed set so
|
|
137
|
+
* the suggestion doesn't reappear on the next load. */
|
|
138
|
+
onDismiss?: (suggestion: DesignSuggestion) => void;
|
|
139
|
+
};
|
|
140
|
+
/**
|
|
141
|
+
* Stateful panel — loads the suggestion stream on mount, exposes a
|
|
142
|
+
* category filter + min-confidence slider, and emits `onApply` /
|
|
143
|
+
* `onDismiss`. Handles loading / error / empty states inline.
|
|
144
|
+
*
|
|
145
|
+
* @public
|
|
146
|
+
*/
|
|
147
|
+
export declare function DesignSuggestionsPanel({ loader, defaultMinConfidence, onApply, onDismiss, }: DesignSuggestionsPanelProps): ReactElement;
|
|
148
|
+
//# sourceMappingURL=DesignSuggestionsPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DesignSuggestionsPanel.d.ts","sourceRoot":"","sources":["../../src/components/DesignSuggestionsPanel.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C;;;;;;;GAOG;AACH,MAAM,MAAM,wBAAwB,GAChC,YAAY,GACZ,OAAO,GACP,QAAQ,GACR,UAAU,GACV,SAAS,GACT,OAAO,CAAC;AAEZ;;;;;;;;;;;;GAYG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,wBAAwB,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACpC;;;;gDAI4C;IAC5C,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,CAAC,SAAS,gBAAgB,EAAE,CAAC,CAAC;AAElF;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,QAAQ,CAAC,EAAE,wBAAwB,CAAC;IACpC;;0EAEsE;IACtE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,wBAAwB,CAAC;IACnC,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAC;CAC1C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,EAAE,SAAS,wBAAwB,EAO/E,CAAC;AAWF;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,WAAW,EAAE,SAAS,gBAAgB,EAAE,EACxC,MAAM,EAAE,sBAAsB,GAC7B,SAAS,gBAAgB,EAAE,CAS7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,SAAS,gBAAgB,EAAE,GACvC,SAAS,qBAAqB,EAAE,CAYlC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,2BAA2B,GAAG;IACxC;yEACqE;IACrE,MAAM,EAAE,wBAAwB,CAAC;IACjC;;gEAE4D;IAC5D,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B;oEACgE;IAChE,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;IACjD;;4DAEwD;IACxD,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,gBAAgB,KAAK,IAAI,CAAC;CACpD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,EACrC,MAAM,EACN,oBAAoB,EACpB,OAAO,EACP,SAAS,GACV,EAAE,2BAA2B,GAAG,YAAY,CAyI5C"}
|