@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,221 @@
|
|
|
1
|
+
// SPDX-License-Identifier: AGPL-3.0-or-later
|
|
2
|
+
"use client";
|
|
3
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
4
|
+
/**
|
|
5
|
+
* Wave 3 P5 — Braille layout editor.
|
|
6
|
+
*
|
|
7
|
+
* Pharmaceutical packaging in the EU is required to carry Braille
|
|
8
|
+
* matching the product name (Directive 2001/83/EC Article 56a) per
|
|
9
|
+
* the Marburg Medium dot-geometry standard (EN 15823). This panel
|
|
10
|
+
* lets the user type the source text, configure the dot geometry,
|
|
11
|
+
* and emit an ordered list of {@link BrailleCell}s the host renders
|
|
12
|
+
* as a vector layer.
|
|
13
|
+
*
|
|
14
|
+
* The transliterator covers Grade 1 English uncontracted Braille
|
|
15
|
+
* (letters A–Z, digits 0–9 with the AI 3456 prefix, common
|
|
16
|
+
* punctuation). Multi-language contracted Braille (Grade 2 English,
|
|
17
|
+
* German, French) is out of scope — hosts that need it wire their
|
|
18
|
+
* own translator (e.g. liblouis via a worker) and feed the resulting
|
|
19
|
+
* Unicode Braille string into {@link composeBraille} directly.
|
|
20
|
+
*
|
|
21
|
+
* @public
|
|
22
|
+
*/
|
|
23
|
+
import { useState } from "react";
|
|
24
|
+
/**
|
|
25
|
+
* Marburg Medium dot-geometry defaults (EN 15823). Re-exported so
|
|
26
|
+
* server-side renderers can use the same constants for compliance
|
|
27
|
+
* checks. Values are in millimetres.
|
|
28
|
+
*
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export const MARBURG_MEDIUM = {
|
|
32
|
+
dotHeightMm: 0.2,
|
|
33
|
+
dotBaseDiameterMm: 1.44,
|
|
34
|
+
dotSpacingMm: 2.5,
|
|
35
|
+
cellWidthMm: 6.0,
|
|
36
|
+
charSpacingMm: 5.0,
|
|
37
|
+
lineSpacingMm: 10.0,
|
|
38
|
+
};
|
|
39
|
+
const LETTER_DOTS = {
|
|
40
|
+
a: [true, false, false, false, false, false],
|
|
41
|
+
b: [true, true, false, false, false, false],
|
|
42
|
+
c: [true, false, false, true, false, false],
|
|
43
|
+
d: [true, false, false, true, true, false],
|
|
44
|
+
e: [true, false, false, false, true, false],
|
|
45
|
+
f: [true, true, false, true, false, false],
|
|
46
|
+
g: [true, true, false, true, true, false],
|
|
47
|
+
h: [true, true, false, false, true, false],
|
|
48
|
+
i: [false, true, false, true, false, false],
|
|
49
|
+
j: [false, true, false, true, true, false],
|
|
50
|
+
k: [true, false, true, false, false, false],
|
|
51
|
+
l: [true, true, true, false, false, false],
|
|
52
|
+
m: [true, false, true, true, false, false],
|
|
53
|
+
n: [true, false, true, true, true, false],
|
|
54
|
+
o: [true, false, true, false, true, false],
|
|
55
|
+
p: [true, true, true, true, false, false],
|
|
56
|
+
q: [true, true, true, true, true, false],
|
|
57
|
+
r: [true, true, true, false, true, false],
|
|
58
|
+
s: [false, true, true, true, false, false],
|
|
59
|
+
t: [false, true, true, true, true, false],
|
|
60
|
+
u: [true, false, true, false, false, true],
|
|
61
|
+
v: [true, true, true, false, false, true],
|
|
62
|
+
w: [false, true, false, true, true, true],
|
|
63
|
+
x: [true, false, true, true, false, true],
|
|
64
|
+
y: [true, false, true, true, true, true],
|
|
65
|
+
z: [true, false, true, false, true, true],
|
|
66
|
+
};
|
|
67
|
+
// "Number indicator" prefix (dots 3-4-5-6). When the transliterator
|
|
68
|
+
// emits a digit, it inserts this cell first; digits 0-9 share their
|
|
69
|
+
// dot pattern with letters a-j (per the standard A=1, B=2 ... J=0).
|
|
70
|
+
const NUMBER_PREFIX = [
|
|
71
|
+
false,
|
|
72
|
+
false,
|
|
73
|
+
true,
|
|
74
|
+
true,
|
|
75
|
+
true,
|
|
76
|
+
true,
|
|
77
|
+
];
|
|
78
|
+
const DIGIT_TO_LETTER = {
|
|
79
|
+
"1": "a",
|
|
80
|
+
"2": "b",
|
|
81
|
+
"3": "c",
|
|
82
|
+
"4": "d",
|
|
83
|
+
"5": "e",
|
|
84
|
+
"6": "f",
|
|
85
|
+
"7": "g",
|
|
86
|
+
"8": "h",
|
|
87
|
+
"9": "i",
|
|
88
|
+
"0": "j",
|
|
89
|
+
};
|
|
90
|
+
const PUNCT_DOTS = {
|
|
91
|
+
// Dot indices in the tuple are 1, 2, 3, 4, 5, 6 (left col top→bottom,
|
|
92
|
+
// right col top→bottom). Patterns follow Unified English Braille
|
|
93
|
+
// (UEB) and English Braille American Edition (EBAE), which agree on
|
|
94
|
+
// these punctuation symbols.
|
|
95
|
+
" ": [false, false, false, false, false, false],
|
|
96
|
+
".": [false, true, false, false, true, true], // dots 2-5-6
|
|
97
|
+
",": [false, true, false, false, false, false], // dot 2
|
|
98
|
+
";": [false, true, true, false, false, false], // dots 2-3
|
|
99
|
+
":": [false, true, false, false, true, false], // dots 2-5
|
|
100
|
+
"!": [false, true, true, false, true, false], // dots 2-3-5
|
|
101
|
+
"?": [true, false, false, true, true, true], // dots 1-4-5-6
|
|
102
|
+
"'": [false, false, true, false, false, false], // dot 3
|
|
103
|
+
"-": [false, false, true, false, false, true], // dots 3-6
|
|
104
|
+
};
|
|
105
|
+
function dotsToUnicode(dots) {
|
|
106
|
+
// Unicode Braille pattern codepoint = U+2800 + bitmask where bit 0
|
|
107
|
+
// is dot 1, bit 1 is dot 2, …, bit 5 is dot 6.
|
|
108
|
+
let bits = 0;
|
|
109
|
+
for (let i = 0; i < 6; i++) {
|
|
110
|
+
if (dots[i])
|
|
111
|
+
bits |= 1 << i;
|
|
112
|
+
}
|
|
113
|
+
return String.fromCodePoint(0x2800 + bits);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Transliterate a Grade 1 English string into placed Braille cells.
|
|
117
|
+
* The function only covers letters, digits, and a small set of
|
|
118
|
+
* common punctuation; unsupported characters are dropped and
|
|
119
|
+
* surfaced via `unsupportedChars` so the host can warn the user.
|
|
120
|
+
*
|
|
121
|
+
* Cells are laid out left-to-right at `charSpacingMm` intervals on
|
|
122
|
+
* a single line, all at `y = 0`. Multi-line layout is the host's
|
|
123
|
+
* responsibility (it can chunk the input on `\n` and translate each
|
|
124
|
+
* line separately).
|
|
125
|
+
*
|
|
126
|
+
* Pure function — exported so RSC / Astro-frontmatter callers can
|
|
127
|
+
* pre-compute placement.
|
|
128
|
+
*
|
|
129
|
+
* @public
|
|
130
|
+
*/
|
|
131
|
+
export function composeBraille(input) {
|
|
132
|
+
// Clamp the spacing for direct callers (RSC, host code) the same
|
|
133
|
+
// way the panel does. Zero / negative values produce overlapping
|
|
134
|
+
// or reverse-ordered cells, which is never what a host wants.
|
|
135
|
+
const charSpacing = input.charSpacingMm !== undefined && input.charSpacingMm > 0
|
|
136
|
+
? input.charSpacingMm
|
|
137
|
+
: MARBURG_MEDIUM.charSpacingMm;
|
|
138
|
+
const cells = [];
|
|
139
|
+
const unsupportedChars = [];
|
|
140
|
+
let cursorMm = 0;
|
|
141
|
+
for (const ch of input.text) {
|
|
142
|
+
const lower = ch.toLowerCase();
|
|
143
|
+
const letterDots = LETTER_DOTS[lower];
|
|
144
|
+
if (letterDots) {
|
|
145
|
+
cells.push({
|
|
146
|
+
char: ch,
|
|
147
|
+
xMm: cursorMm,
|
|
148
|
+
yMm: 0,
|
|
149
|
+
dots: letterDots,
|
|
150
|
+
});
|
|
151
|
+
cursorMm += charSpacing;
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const asLetter = DIGIT_TO_LETTER[ch];
|
|
155
|
+
if (asLetter !== undefined) {
|
|
156
|
+
const digitDots = LETTER_DOTS[asLetter];
|
|
157
|
+
if (digitDots) {
|
|
158
|
+
// Emit the number-indicator cell before each digit. A
|
|
159
|
+
// run-aware encoding would only prefix the first digit;
|
|
160
|
+
// per-digit is the conservative form and the standard
|
|
161
|
+
// accepts it.
|
|
162
|
+
cells.push({
|
|
163
|
+
char: "#",
|
|
164
|
+
xMm: cursorMm,
|
|
165
|
+
yMm: 0,
|
|
166
|
+
dots: NUMBER_PREFIX,
|
|
167
|
+
});
|
|
168
|
+
cursorMm += charSpacing;
|
|
169
|
+
cells.push({
|
|
170
|
+
char: ch,
|
|
171
|
+
xMm: cursorMm,
|
|
172
|
+
yMm: 0,
|
|
173
|
+
dots: digitDots,
|
|
174
|
+
});
|
|
175
|
+
cursorMm += charSpacing;
|
|
176
|
+
continue;
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const punctDots = PUNCT_DOTS[ch];
|
|
180
|
+
if (punctDots) {
|
|
181
|
+
cells.push({
|
|
182
|
+
char: ch,
|
|
183
|
+
xMm: cursorMm,
|
|
184
|
+
yMm: 0,
|
|
185
|
+
dots: punctDots,
|
|
186
|
+
});
|
|
187
|
+
cursorMm += charSpacing;
|
|
188
|
+
continue;
|
|
189
|
+
}
|
|
190
|
+
unsupportedChars.push(ch);
|
|
191
|
+
}
|
|
192
|
+
const unicode = cells.map((cell) => dotsToUnicode(cell.dots)).join("");
|
|
193
|
+
return { cells, unicode, unsupportedChars };
|
|
194
|
+
}
|
|
195
|
+
/**
|
|
196
|
+
* Braille layout panel. The user types the source text, optionally
|
|
197
|
+
* tweaks character spacing for non-standard substrates, and clicks
|
|
198
|
+
* **Compose**; the host receives the placed cells.
|
|
199
|
+
*
|
|
200
|
+
* The panel does not render the Braille itself — preview is the
|
|
201
|
+
* host's responsibility because the dot geometry (ellipse vs.
|
|
202
|
+
* spherical dome) and the production process (foil-emboss vs. ink
|
|
203
|
+
* + spot-UV) drive how it should be visualised.
|
|
204
|
+
*
|
|
205
|
+
* @public
|
|
206
|
+
*/
|
|
207
|
+
export function BraillePanel({ onCompose, initialText = "", initialCharSpacingMm = MARBURG_MEDIUM.charSpacingMm, }) {
|
|
208
|
+
const [text, setText] = useState(initialText);
|
|
209
|
+
const [charSpacingMm, setCharSpacingMm] = useState(initialCharSpacingMm);
|
|
210
|
+
const [lastResult, setLastResult] = useState(null);
|
|
211
|
+
function handleCompose() {
|
|
212
|
+
const result = composeBraille({ text, charSpacingMm });
|
|
213
|
+
setLastResult(result);
|
|
214
|
+
onCompose(result);
|
|
215
|
+
}
|
|
216
|
+
return (_jsxs("div", { "data-testid": "braille-panel", style: { padding: "0.5rem", maxWidth: "24em" }, children: [_jsx("h3", { style: { margin: "0 0 0.5rem 0" }, children: "Braille (Marburg Medium)" }), _jsxs("label", { style: { display: "block", marginBottom: "0.5rem" }, children: ["Source text", _jsx("input", { type: "text", value: text, onChange: (e) => setText(e.target.value), "aria-label": "Braille source text", style: { marginLeft: "0.5rem", width: "16em" } })] }), _jsxs("label", { style: { display: "block", marginBottom: "0.5rem" }, children: ["Character spacing (mm)", _jsx("input", { type: "number", min: "0", step: "0.1", value: charSpacingMm, onChange: (e) => {
|
|
217
|
+
const v = Number(e.target.value);
|
|
218
|
+
setCharSpacingMm(Number.isNaN(v) || v <= 0 ? MARBURG_MEDIUM.charSpacingMm : v);
|
|
219
|
+
}, "aria-label": "Character spacing in millimetres", style: { marginLeft: "0.5rem", width: "5em" } })] }), _jsx("button", { type: "button", onClick: handleCompose, style: { padding: "0.4rem 0.8rem" }, children: "Compose" }), lastResult && (_jsxs("div", { style: { marginTop: "0.5rem" }, children: [_jsx("div", { style: { fontFamily: "monospace", fontSize: "1.4em" }, children: lastResult.unicode }), lastResult.unsupportedChars.length > 0 && (_jsxs("div", { role: "alert", style: { marginTop: "0.25rem", color: "#a00", fontSize: "0.8em" }, children: ["Skipped characters: ", lastResult.unsupportedChars.join(" ")] }))] }))] }));
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=BraillePanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BraillePanel.js","sourceRoot":"","sources":["../../src/components/BraillePanel.tsx"],"names":[],"mappings":"AAAA,6CAA6C;AAC7C,YAAY,CAAC;;AAEb;;;;;;;;;;;;;;;;;;GAkBG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEjC;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;IAC5B,WAAW,EAAE,GAAG;IAChB,iBAAiB,EAAE,IAAI;IACvB,YAAY,EAAE,GAAG;IACjB,WAAW,EAAE,GAAG;IAChB,aAAa,EAAE,GAAG;IAClB,aAAa,EAAE,IAAI;CACX,CAAC;AAuCX,MAAM,WAAW,GAA2E;IAC1F,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC5C,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC3C,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC;IAC3C,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;IAC3C,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;IACzC,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;IAC1C,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC;IAC3C,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC3C,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;IACzC,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC;IACzC,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;IACxC,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC;IACzC,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,CAAC;IAC1C,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,CAAC;IACzC,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC;IAC1C,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC;IACzC,CAAC,EAAE,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IACzC,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC;IACzC,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC;IACxC,CAAC,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,I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"}
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 4 B1 — Brand-assets registry panel.
|
|
3
|
+
*
|
|
4
|
+
* Surfaces the document's brand-asset registry
|
|
5
|
+
* (`DocumentV3.brandAssets`) as a browsable list grouped by kind:
|
|
6
|
+
* logo, swatch, typography, graphic-style, other. Hosts get a
|
|
7
|
+
* controlled read-only view; mutation (add / remove / re-hash)
|
|
8
|
+
* happens elsewhere — typically in a host-side asset-cache UI that
|
|
9
|
+
* writes back into the document.
|
|
10
|
+
*
|
|
11
|
+
* Pairs with Wave 4 B2's brand-consistency rule (lint-pdf side): the
|
|
12
|
+
* rule consults this same registry, so what the user sees in the
|
|
13
|
+
* panel is what the rule will check against. The panel is the human
|
|
14
|
+
* surface; B2 is the machine one.
|
|
15
|
+
*
|
|
16
|
+
* @public
|
|
17
|
+
*/
|
|
18
|
+
import type { ReactElement } from "react";
|
|
19
|
+
/**
|
|
20
|
+
* One brand asset. Structurally compatible with `BrandAssetRef` from
|
|
21
|
+
* `@artworkpdf/document-model` — duplicated here so the editor stays
|
|
22
|
+
* consumable without the document-model SDK (same pattern as
|
|
23
|
+
* `ComplianceFinding`, `PreflightFinding`, etc.).
|
|
24
|
+
*
|
|
25
|
+
* `hash` is the content sha256 the host's asset cache uses as its
|
|
26
|
+
* primary key. `sourceUrl` is optional and only set when the asset
|
|
27
|
+
* originally came from an external CDN — local-only assets omit it.
|
|
28
|
+
*
|
|
29
|
+
* @public
|
|
30
|
+
*/
|
|
31
|
+
export type BrandAsset = {
|
|
32
|
+
id: string;
|
|
33
|
+
hash: string;
|
|
34
|
+
name: string;
|
|
35
|
+
kind: BrandAssetKind;
|
|
36
|
+
mimeType?: string;
|
|
37
|
+
sourceUrl?: string;
|
|
38
|
+
};
|
|
39
|
+
/**
|
|
40
|
+
* The discriminator on which the panel groups assets and which the
|
|
41
|
+
* B2 consistency rule pivots on. `"other"` is the escape hatch for
|
|
42
|
+
* tenant-specific kinds that don't map to the four canonical buckets.
|
|
43
|
+
*
|
|
44
|
+
* @public
|
|
45
|
+
*/
|
|
46
|
+
export type BrandAssetKind = "logo" | "swatch" | "typography" | "graphic-style" | "other";
|
|
47
|
+
/**
|
|
48
|
+
* Canonical order brand-asset kinds render in. The order matches the
|
|
49
|
+
* mental hierarchy a brand lead expects: identity (logo), color, type,
|
|
50
|
+
* generic-style, miscellaneous. Hosts that want a different order can
|
|
51
|
+
* read the assets list straight from `DocumentV3.brandAssets` and
|
|
52
|
+
* drive their own renderer over {@link filterBrandAssets}.
|
|
53
|
+
*
|
|
54
|
+
* @public
|
|
55
|
+
*/
|
|
56
|
+
export declare const BRAND_ASSET_KIND_ORDER: readonly BrandAssetKind[];
|
|
57
|
+
/**
|
|
58
|
+
* Result row from {@link groupBrandAssetsByKind}.
|
|
59
|
+
*
|
|
60
|
+
* @public
|
|
61
|
+
*/
|
|
62
|
+
export type BrandAssetGroup = {
|
|
63
|
+
kind: BrandAssetKind;
|
|
64
|
+
assets: readonly BrandAsset[];
|
|
65
|
+
};
|
|
66
|
+
/**
|
|
67
|
+
* Filter spec accepted by {@link filterBrandAssets}.
|
|
68
|
+
*
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
export type BrandAssetFilter = {
|
|
72
|
+
/** Match assets whose `kind` field equals this value. Absent → no
|
|
73
|
+
* kind filter. */
|
|
74
|
+
kind?: BrandAssetKind;
|
|
75
|
+
/** Case-insensitive substring filter on `name`. Whitespace-only
|
|
76
|
+
* strings are treated as absent so a stray space in the search
|
|
77
|
+
* input doesn't blank the list. */
|
|
78
|
+
query?: string;
|
|
79
|
+
};
|
|
80
|
+
/**
|
|
81
|
+
* @public
|
|
82
|
+
*/
|
|
83
|
+
export type BrandAssetsPanelProps = {
|
|
84
|
+
/** The full brand-asset registry. Typically
|
|
85
|
+
* `DocumentV3.brandAssets ?? []`. Empty array → "no assets
|
|
86
|
+
* registered" empty state. */
|
|
87
|
+
assets: readonly BrandAsset[];
|
|
88
|
+
/** Optional kind to pre-filter the panel to. Distinct from the
|
|
89
|
+
* in-panel filter chips — hosts wire this to a deep-link route
|
|
90
|
+
* ("?brand-kind=logo") so reloading the page lands in the same
|
|
91
|
+
* bucket. */
|
|
92
|
+
filterKind?: BrandAssetKind;
|
|
93
|
+
/** Optional callback fired when an asset row is clicked. Hosts
|
|
94
|
+
* typically wire this to a side panel that shows the asset's
|
|
95
|
+
* preview + hash + reference count. */
|
|
96
|
+
onSelect?: (asset: BrandAsset) => void;
|
|
97
|
+
};
|
|
98
|
+
/**
|
|
99
|
+
* Group assets by kind in {@link BRAND_ASSET_KIND_ORDER}. Returns a
|
|
100
|
+
* stable five-bucket shape (one entry per canonical kind, even when
|
|
101
|
+
* empty) so renderers can iterate without worrying about absent keys.
|
|
102
|
+
*
|
|
103
|
+
* Pure function — no React, no DOM.
|
|
104
|
+
*
|
|
105
|
+
* @public
|
|
106
|
+
*/
|
|
107
|
+
export declare function groupBrandAssetsByKind(assets: readonly BrandAsset[]): readonly BrandAssetGroup[];
|
|
108
|
+
/**
|
|
109
|
+
* Filter assets by kind / name substring. Returns a new array;
|
|
110
|
+
* preserves input order. Pure function.
|
|
111
|
+
*
|
|
112
|
+
* @public
|
|
113
|
+
*/
|
|
114
|
+
export declare function filterBrandAssets(assets: readonly BrandAsset[], filter: BrandAssetFilter): readonly BrandAsset[];
|
|
115
|
+
/**
|
|
116
|
+
* Read-only browser for `DocumentV3.brandAssets` grouped by kind.
|
|
117
|
+
*
|
|
118
|
+
* Renders the registry as a count header plus one section per kind in
|
|
119
|
+
* {@link BRAND_ASSET_KIND_ORDER}. When `filterKind` is set, only that
|
|
120
|
+
* bucket's assets are visible; the panel surfaces a distinct
|
|
121
|
+
* "no {kind} assets in this document" message when the filter
|
|
122
|
+
* matches nothing (vs the registry-is-empty message). Hosts opt in
|
|
123
|
+
* to row interaction by passing `onSelect` — otherwise rows render
|
|
124
|
+
* as static content so screen readers don't announce non-functional
|
|
125
|
+
* buttons.
|
|
126
|
+
*
|
|
127
|
+
* @public
|
|
128
|
+
*/
|
|
129
|
+
export declare function BrandAssetsPanel({ assets, filterKind, onSelect, }: BrandAssetsPanelProps): ReactElement;
|
|
130
|
+
//# sourceMappingURL=BrandAssetsPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrandAssetsPanel.d.ts","sourceRoot":"","sources":["../../src/components/BrandAssetsPanel.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAG1C;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,UAAU,GAAG;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,cAAc,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,eAAe,GAAG,OAAO,CAAC;AAE1F;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,EAAE,SAAS,cAAc,EAM3D,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG;IAC5B,IAAI,EAAE,cAAc,CAAC;IACrB,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;CAC/B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,gBAAgB,GAAG;IAC7B;uBACmB;IACnB,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB;;wCAEoC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF;;GAEG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC;;mCAE+B;IAC/B,MAAM,EAAE,SAAS,UAAU,EAAE,CAAC;IAC9B;;;kBAGc;IACd,UAAU,CAAC,EAAE,cAAc,CAAC;IAC5B;;4CAEwC;IACxC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,UAAU,KAAK,IAAI,CAAC;CACxC,CAAC;AAEF;;;;;;;;GAQG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,GAAG,SAAS,eAAe,EAAE,CAchG;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,SAAS,UAAU,EAAE,EAC7B,MAAM,EAAE,gBAAgB,GACvB,SAAS,UAAU,EAAE,CAOvB;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,gBAAgB,CAAC,EAC/B,MAAM,EACN,UAAU,EACV,QAAQ,GACT,EAAE,qBAAqB,GAAG,YAAY,CAyDtC"}
|
|
@@ -0,0 +1,125 @@
|
|
|
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 { useMemo } from "react";
|
|
5
|
+
/**
|
|
6
|
+
* Canonical order brand-asset kinds render in. The order matches the
|
|
7
|
+
* mental hierarchy a brand lead expects: identity (logo), color, type,
|
|
8
|
+
* generic-style, miscellaneous. Hosts that want a different order can
|
|
9
|
+
* read the assets list straight from `DocumentV3.brandAssets` and
|
|
10
|
+
* drive their own renderer over {@link filterBrandAssets}.
|
|
11
|
+
*
|
|
12
|
+
* @public
|
|
13
|
+
*/
|
|
14
|
+
export const BRAND_ASSET_KIND_ORDER = [
|
|
15
|
+
"logo",
|
|
16
|
+
"swatch",
|
|
17
|
+
"typography",
|
|
18
|
+
"graphic-style",
|
|
19
|
+
"other",
|
|
20
|
+
];
|
|
21
|
+
/**
|
|
22
|
+
* Group assets by kind in {@link BRAND_ASSET_KIND_ORDER}. Returns a
|
|
23
|
+
* stable five-bucket shape (one entry per canonical kind, even when
|
|
24
|
+
* empty) so renderers can iterate without worrying about absent keys.
|
|
25
|
+
*
|
|
26
|
+
* Pure function — no React, no DOM.
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export function groupBrandAssetsByKind(assets) {
|
|
31
|
+
const buckets = new Map(BRAND_ASSET_KIND_ORDER.map((k) => [k, []]));
|
|
32
|
+
for (const a of assets) {
|
|
33
|
+
// Defensive: TS makes `kind` a strict union, but runtime data
|
|
34
|
+
// (a JSON load from an external source, a forward-compat extension
|
|
35
|
+
// in the registry) could carry kinds we don't know about. Drop
|
|
36
|
+
// such entries into "other" rather than silently losing them.
|
|
37
|
+
const bucket = buckets.get(a.kind) ?? buckets.get("other");
|
|
38
|
+
bucket?.push(a);
|
|
39
|
+
}
|
|
40
|
+
return BRAND_ASSET_KIND_ORDER.map((kind) => ({
|
|
41
|
+
kind,
|
|
42
|
+
assets: buckets.get(kind) ?? [],
|
|
43
|
+
}));
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Filter assets by kind / name substring. Returns a new array;
|
|
47
|
+
* preserves input order. Pure function.
|
|
48
|
+
*
|
|
49
|
+
* @public
|
|
50
|
+
*/
|
|
51
|
+
export function filterBrandAssets(assets, filter) {
|
|
52
|
+
const trimmedQuery = filter.query?.trim().toLowerCase() ?? "";
|
|
53
|
+
return assets.filter((a) => {
|
|
54
|
+
if (filter.kind && a.kind !== filter.kind)
|
|
55
|
+
return false;
|
|
56
|
+
if (trimmedQuery && !a.name.toLowerCase().includes(trimmedQuery))
|
|
57
|
+
return false;
|
|
58
|
+
return true;
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
const KIND_LABELS = {
|
|
62
|
+
logo: "Logos",
|
|
63
|
+
swatch: "Swatches",
|
|
64
|
+
typography: "Typography",
|
|
65
|
+
"graphic-style": "Graphic styles",
|
|
66
|
+
other: "Other",
|
|
67
|
+
};
|
|
68
|
+
/**
|
|
69
|
+
* Read-only browser for `DocumentV3.brandAssets` grouped by kind.
|
|
70
|
+
*
|
|
71
|
+
* Renders the registry as a count header plus one section per kind in
|
|
72
|
+
* {@link BRAND_ASSET_KIND_ORDER}. When `filterKind` is set, only that
|
|
73
|
+
* bucket's assets are visible; the panel surfaces a distinct
|
|
74
|
+
* "no {kind} assets in this document" message when the filter
|
|
75
|
+
* matches nothing (vs the registry-is-empty message). Hosts opt in
|
|
76
|
+
* to row interaction by passing `onSelect` — otherwise rows render
|
|
77
|
+
* as static content so screen readers don't announce non-functional
|
|
78
|
+
* buttons.
|
|
79
|
+
*
|
|
80
|
+
* @public
|
|
81
|
+
*/
|
|
82
|
+
export function BrandAssetsPanel({ assets, filterKind, onSelect, }) {
|
|
83
|
+
const visibleAssets = useMemo(() => (filterKind ? filterBrandAssets(assets, { kind: filterKind }) : assets), [assets, filterKind]);
|
|
84
|
+
const groups = useMemo(() => groupBrandAssetsByKind(visibleAssets), [visibleAssets]);
|
|
85
|
+
if (assets.length === 0) {
|
|
86
|
+
return (_jsx("div", { "data-testid": "brand-assets-panel", style: { padding: "0.5rem", opacity: 0.6 }, children: "No brand assets registered for this document." }));
|
|
87
|
+
}
|
|
88
|
+
return (_jsxs("div", { "data-testid": "brand-assets-panel", style: { padding: "0.5rem" }, children: [_jsxs("h3", { style: { margin: "0 0 0.5rem 0", fontSize: "0.875rem" }, children: ["Brand assets (", visibleAssets.length, ")"] }), visibleAssets.length === 0 && filterKind && (_jsxs("div", { "data-testid": "brand-assets-panel-empty-filter", style: { opacity: 0.6, fontSize: "0.875rem" }, children: ["No ", filterKind, " assets in this document."] })), groups.map((group) => {
|
|
89
|
+
if (group.assets.length === 0)
|
|
90
|
+
return null;
|
|
91
|
+
return (_jsxs("section", { "data-testid": `brand-assets-group-${group.kind}`, style: { marginBottom: "0.75rem" }, children: [_jsxs("h4", { style: {
|
|
92
|
+
margin: "0 0 0.25rem 0",
|
|
93
|
+
fontSize: "0.75rem",
|
|
94
|
+
color: "#666",
|
|
95
|
+
textTransform: "uppercase",
|
|
96
|
+
letterSpacing: "0.05em",
|
|
97
|
+
}, children: [KIND_LABELS[group.kind], " (", group.assets.length, ")"] }), _jsx("ul", { style: { listStyle: "none", padding: 0, margin: 0 }, children: group.assets.map((asset) => (_jsx(BrandAssetRow, { asset: asset, onSelect: onSelect }, asset.id))) })] }, group.kind));
|
|
98
|
+
})] }));
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Renders one asset row inside a kind section. The row is a `<button>`
|
|
102
|
+
* when the host wired `onSelect` (announces interactivity to screen
|
|
103
|
+
* readers) and a plain `<div>` otherwise so static rows aren't read
|
|
104
|
+
* as clickable controls that do nothing.
|
|
105
|
+
*
|
|
106
|
+
* Intra-package helper — not exported.
|
|
107
|
+
*/
|
|
108
|
+
function BrandAssetRow({ asset, onSelect, }) {
|
|
109
|
+
const rowStyle = {
|
|
110
|
+
display: "flex",
|
|
111
|
+
alignItems: "baseline",
|
|
112
|
+
gap: "0.5rem",
|
|
113
|
+
width: "100%",
|
|
114
|
+
padding: "0.25rem 0.5rem",
|
|
115
|
+
};
|
|
116
|
+
const rowContents = (_jsxs(_Fragment, { children: [_jsx("span", { style: { flex: 1 }, children: asset.name }), _jsx("small", { "data-testid": `brand-asset-hash-${asset.id}`, style: { opacity: 0.6, fontFamily: "monospace" }, title: asset.hash, children: asset.hash.slice(0, 8) })] }));
|
|
117
|
+
return (_jsx("li", { children: onSelect ? (_jsx("button", { type: "button", onClick: () => onSelect(asset), "aria-label": `Brand asset: ${asset.name} (${asset.kind})`, style: {
|
|
118
|
+
...rowStyle,
|
|
119
|
+
background: "transparent",
|
|
120
|
+
border: "none",
|
|
121
|
+
cursor: "pointer",
|
|
122
|
+
textAlign: "left",
|
|
123
|
+
}, children: rowContents })) : (_jsx("div", { style: rowStyle, children: rowContents })) }));
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=BrandAssetsPanel.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrandAssetsPanel.js","sourceRoot":"","sources":["../../src/components/BrandAssetsPanel.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Wave 4 B2 — Brand-consistency findings panel.
|
|
3
|
+
*
|
|
4
|
+
* Companion to the B1 {@link BrandAssetsPanel} (Wave 4 PR-5). The
|
|
5
|
+
* brand-assets panel lists the registry the designer is supposed to
|
|
6
|
+
* pull from; this one surfaces a host-loader-supplied list of
|
|
7
|
+
* violations against that registry — logo placed too small, fill
|
|
8
|
+
* color outside the swatches set, typography pairing off the brand
|
|
9
|
+
* kit, etc.
|
|
10
|
+
*
|
|
11
|
+
* Findings reference a `brandAssetId` so the host can jump to the
|
|
12
|
+
* matching asset in the registry / focus the offending object on the
|
|
13
|
+
* canvas. The loader is the same shape as the rest of the Wave 4
|
|
14
|
+
* panel family: one call per mount resolves the full finding set.
|
|
15
|
+
*
|
|
16
|
+
* Pairs with lint-pdf's brand-consistency profile when one is
|
|
17
|
+
* deployed (cross-repo, deferred); hosts running purely client-side
|
|
18
|
+
* heuristics can wire a local loader in the meantime.
|
|
19
|
+
*
|
|
20
|
+
* @public
|
|
21
|
+
*/
|
|
22
|
+
import type { ReactElement } from "react";
|
|
23
|
+
import type { BrandAssetKind } from "./BrandAssetsPanel";
|
|
24
|
+
/**
|
|
25
|
+
* Severity of a brand-consistency finding. Mirrors lint-pdf's three
|
|
26
|
+
* tiers so the two systems agree on the wire shape.
|
|
27
|
+
*
|
|
28
|
+
* @public
|
|
29
|
+
*/
|
|
30
|
+
export type BrandConsistencySeverity = "error" | "warn" | "info";
|
|
31
|
+
/**
|
|
32
|
+
* One brand-consistency finding. `brandAssetId` is the foreign key
|
|
33
|
+
* into the host's brand-asset registry (the same id surfaced by the
|
|
34
|
+
* B1 {@link BrandAssetsPanel}); `assetKind` is duplicated for fast
|
|
35
|
+
* grouping without a lookup. The optional `objectId` lets the host
|
|
36
|
+
* focus the violating canvas object.
|
|
37
|
+
*
|
|
38
|
+
* @public
|
|
39
|
+
*/
|
|
40
|
+
export type BrandConsistencyFinding = {
|
|
41
|
+
/** Stable identifier — the panel uses it as the React key and
|
|
42
|
+
* exposes it through `onSelect`. */
|
|
43
|
+
id: string;
|
|
44
|
+
/** Foreign key into the host's brand-asset registry. */
|
|
45
|
+
brandAssetId: string;
|
|
46
|
+
/** Duplicated from the asset for fast grouping; saves a registry
|
|
47
|
+
* lookup per row. */
|
|
48
|
+
assetKind: BrandAssetKind;
|
|
49
|
+
severity: BrandConsistencySeverity;
|
|
50
|
+
summary: string;
|
|
51
|
+
description?: string;
|
|
52
|
+
/** Optional id of the canvas object that violates the rule. Hosts
|
|
53
|
+
* wire this to a focus / scroll-into-view affordance. */
|
|
54
|
+
objectId?: string;
|
|
55
|
+
};
|
|
56
|
+
/**
|
|
57
|
+
* Host adapter — resolves the full finding list for the active
|
|
58
|
+
* document. Rejects on transport / validation errors and the panel
|
|
59
|
+
* surfaces the message inline. Hosts should memoize the function
|
|
60
|
+
* with `useCallback` so an unrelated parent re-render doesn't
|
|
61
|
+
* trigger a spurious refetch.
|
|
62
|
+
*
|
|
63
|
+
* @public
|
|
64
|
+
*/
|
|
65
|
+
export type BrandConsistencyLoaderFn = () => Promise<readonly BrandConsistencyFinding[]>;
|
|
66
|
+
/**
|
|
67
|
+
* Filter spec accepted by {@link filterBrandConsistencyFindings}.
|
|
68
|
+
*
|
|
69
|
+
* @public
|
|
70
|
+
*/
|
|
71
|
+
export type BrandConsistencyFilter = {
|
|
72
|
+
/** Pre-filter to a single severity. Absent → all severities. */
|
|
73
|
+
severity?: BrandConsistencySeverity;
|
|
74
|
+
/** Pre-filter to a single asset kind. Absent → all kinds. */
|
|
75
|
+
assetKind?: BrandAssetKind;
|
|
76
|
+
};
|
|
77
|
+
/**
|
|
78
|
+
* Result row from {@link groupBrandConsistencyFindingsBySeverity}.
|
|
79
|
+
*
|
|
80
|
+
* @public
|
|
81
|
+
*/
|
|
82
|
+
export type BrandConsistencyGroup = {
|
|
83
|
+
severity: BrandConsistencySeverity;
|
|
84
|
+
findings: readonly BrandConsistencyFinding[];
|
|
85
|
+
};
|
|
86
|
+
/**
|
|
87
|
+
* Canonical severity order — errors first so press-blocking issues
|
|
88
|
+
* surface at the top.
|
|
89
|
+
*
|
|
90
|
+
* @public
|
|
91
|
+
*/
|
|
92
|
+
export declare const BRAND_CONSISTENCY_SEVERITY_ORDER: readonly BrandConsistencySeverity[];
|
|
93
|
+
/**
|
|
94
|
+
* Pure helper — filters findings by severity / asset kind. Returns a
|
|
95
|
+
* new array; preserves input order. Pure function.
|
|
96
|
+
*
|
|
97
|
+
* @public
|
|
98
|
+
*/
|
|
99
|
+
export declare function filterBrandConsistencyFindings(findings: readonly BrandConsistencyFinding[], filter: BrandConsistencyFilter): readonly BrandConsistencyFinding[];
|
|
100
|
+
/**
|
|
101
|
+
* Pure helper — groups findings by severity in
|
|
102
|
+
* {@link BRAND_CONSISTENCY_SEVERITY_ORDER}. Returns a stable
|
|
103
|
+
* three-bucket shape so renderers iterate without absent-key checks.
|
|
104
|
+
*
|
|
105
|
+
* Pure function.
|
|
106
|
+
*
|
|
107
|
+
* @public
|
|
108
|
+
*/
|
|
109
|
+
export declare function groupBrandConsistencyFindingsBySeverity(findings: readonly BrandConsistencyFinding[]): readonly BrandConsistencyGroup[];
|
|
110
|
+
/**
|
|
111
|
+
* Configuration for the {@link BrandConsistencyPanel}. The host
|
|
112
|
+
* always supplies the {@link BrandConsistencyLoaderFn}; the optional
|
|
113
|
+
* `onSelect` callback lets the host wire a focus affordance (jump to
|
|
114
|
+
* the violating object on the canvas, scroll the brand-assets panel
|
|
115
|
+
* to the matching registry entry, etc.).
|
|
116
|
+
*
|
|
117
|
+
* @public
|
|
118
|
+
*/
|
|
119
|
+
export type BrandConsistencyPanelProps = {
|
|
120
|
+
loader: BrandConsistencyLoaderFn;
|
|
121
|
+
/** Optional severity pre-filter applied before grouping. */
|
|
122
|
+
filterSeverity?: BrandConsistencySeverity;
|
|
123
|
+
/** Optional asset-kind pre-filter applied before grouping. */
|
|
124
|
+
filterAssetKind?: BrandAssetKind;
|
|
125
|
+
/** Id of the currently active finding — the matching row renders
|
|
126
|
+
* in the "active" style. Hosts wire this to whichever surface
|
|
127
|
+
* drives selection. */
|
|
128
|
+
activeFindingId?: string;
|
|
129
|
+
/** Fired when the user clicks a row. */
|
|
130
|
+
onSelect?: (finding: BrandConsistencyFinding) => void;
|
|
131
|
+
};
|
|
132
|
+
/**
|
|
133
|
+
* Stateful panel — loads the finding stream on mount, surfaces the
|
|
134
|
+
* filtered + grouped list, and emits `onSelect` on row click.
|
|
135
|
+
* Handles loading / error / empty states inline.
|
|
136
|
+
*
|
|
137
|
+
* @public
|
|
138
|
+
*/
|
|
139
|
+
export declare function BrandConsistencyPanel({ loader, filterSeverity, filterAssetKind, activeFindingId, onSelect, }: BrandConsistencyPanelProps): ReactElement;
|
|
140
|
+
//# sourceMappingURL=BrandConsistencyPanel.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"BrandConsistencyPanel.d.ts","sourceRoot":"","sources":["../../src/components/BrandConsistencyPanel.tsx"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,OAAO,CAAC;AAE1C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjE;;;;;;;;GAQG;AACH,MAAM,MAAM,uBAAuB,GAAG;IACpC;yCACqC;IACrC,EAAE,EAAE,MAAM,CAAC;IACX,wDAAwD;IACxD,YAAY,EAAE,MAAM,CAAC;IACrB;0BACsB;IACtB,SAAS,EAAE,cAAc,CAAC;IAC1B,QAAQ,EAAE,wBAAwB,CAAC;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;8DAC0D;IAC1D,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF;;;;;;;;GAQG;AACH,MAAM,MAAM,wBAAwB,GAAG,MAAM,OAAO,CAAC,SAAS,uBAAuB,EAAE,CAAC,CAAC;AAEzF;;;;GAIG;AACH,MAAM,MAAM,sBAAsB,GAAG;IACnC,gEAAgE;IAChE,QAAQ,CAAC,EAAE,wBAAwB,CAAC;IACpC,6DAA6D;IAC7D,SAAS,CAAC,EAAE,cAAc,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG;IAClC,QAAQ,EAAE,wBAAwB,CAAC;IACnC,QAAQ,EAAE,SAAS,uBAAuB,EAAE,CAAC;CAC9C,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,gCAAgC,EAAE,SAAS,wBAAwB,EAI/E,CAAC;AAcF;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,SAAS,uBAAuB,EAAE,EAC5C,MAAM,EAAE,sBAAsB,GAC7B,SAAS,uBAAuB,EAAE,CAMpC;AAED;;;;;;;;GAQG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,SAAS,uBAAuB,EAAE,GAC3C,SAAS,qBAAqB,EAAE,CAWlC;AAED;;;;;;;;GAQG;AACH,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,EAAE,wBAAwB,CAAC;IACjC,4DAA4D;IAC5D,cAAc,CAAC,EAAE,wBAAwB,CAAC;IAC1C,8DAA8D;IAC9D,eAAe,CAAC,EAAE,cAAc,CAAC;IACjC;;4BAEwB;IACxB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,wCAAwC;IACxC,QAAQ,CAAC,EAAE,CAAC,OAAO,EAAE,uBAAuB,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,EACpC,MAAM,EACN,cAAc,EACd,eAAe,EACf,eAAe,EACf,QAAQ,GACT,EAAE,0BAA0B,GAAG,YAAY,CA8G3C"}
|