@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.
Files changed (236) hide show
  1. package/LICENSE +62 -0
  2. package/dist/components/AccessibilityHintsPanel.d.ts +142 -0
  3. package/dist/components/AccessibilityHintsPanel.d.ts.map +1 -0
  4. package/dist/components/AccessibilityHintsPanel.js +158 -0
  5. package/dist/components/AccessibilityHintsPanel.js.map +1 -0
  6. package/dist/components/AnnotationOverlay.d.ts +142 -0
  7. package/dist/components/AnnotationOverlay.d.ts.map +1 -0
  8. package/dist/components/AnnotationOverlay.js +141 -0
  9. package/dist/components/AnnotationOverlay.js.map +1 -0
  10. package/dist/components/AnnotationsSidebar.d.ts +98 -0
  11. package/dist/components/AnnotationsSidebar.d.ts.map +1 -0
  12. package/dist/components/AnnotationsSidebar.js +100 -0
  13. package/dist/components/AnnotationsSidebar.js.map +1 -0
  14. package/dist/components/BarcodeGeneratorPanel.d.ts +58 -0
  15. package/dist/components/BarcodeGeneratorPanel.d.ts.map +1 -0
  16. package/dist/components/BarcodeGeneratorPanel.js +91 -0
  17. package/dist/components/BarcodeGeneratorPanel.js.map +1 -0
  18. package/dist/components/BraillePanel.d.ts +99 -0
  19. package/dist/components/BraillePanel.d.ts.map +1 -0
  20. package/dist/components/BraillePanel.js +221 -0
  21. package/dist/components/BraillePanel.js.map +1 -0
  22. package/dist/components/BrandAssetsPanel.d.ts +130 -0
  23. package/dist/components/BrandAssetsPanel.d.ts.map +1 -0
  24. package/dist/components/BrandAssetsPanel.js +125 -0
  25. package/dist/components/BrandAssetsPanel.js.map +1 -0
  26. package/dist/components/BrandConsistencyPanel.d.ts +140 -0
  27. package/dist/components/BrandConsistencyPanel.d.ts.map +1 -0
  28. package/dist/components/BrandConsistencyPanel.js +158 -0
  29. package/dist/components/BrandConsistencyPanel.js.map +1 -0
  30. package/dist/components/ComplianceFindingsPanel.d.ts +62 -0
  31. package/dist/components/ComplianceFindingsPanel.d.ts.map +1 -0
  32. package/dist/components/ComplianceFindingsPanel.js +118 -0
  33. package/dist/components/ComplianceFindingsPanel.js.map +1 -0
  34. package/dist/components/DesignSuggestionsPanel.d.ts +148 -0
  35. package/dist/components/DesignSuggestionsPanel.d.ts.map +1 -0
  36. package/dist/components/DesignSuggestionsPanel.js +154 -0
  37. package/dist/components/DesignSuggestionsPanel.js.map +1 -0
  38. package/dist/components/DielineParametersPanel.d.ts +62 -0
  39. package/dist/components/DielineParametersPanel.d.ts.map +1 -0
  40. package/dist/components/DielineParametersPanel.js +170 -0
  41. package/dist/components/DielineParametersPanel.js.map +1 -0
  42. package/dist/components/DielinePreview.d.ts +150 -0
  43. package/dist/components/DielinePreview.d.ts.map +1 -0
  44. package/dist/components/DielinePreview.js +146 -0
  45. package/dist/components/DielinePreview.js.map +1 -0
  46. package/dist/components/EditorApp.d.ts +18 -3
  47. package/dist/components/EditorApp.d.ts.map +1 -1
  48. package/dist/components/EditorApp.js +42 -7
  49. package/dist/components/EditorApp.js.map +1 -1
  50. package/dist/components/EditorCanvas.d.ts +31 -2
  51. package/dist/components/EditorCanvas.d.ts.map +1 -1
  52. package/dist/components/EditorCanvas.js +97 -16
  53. package/dist/components/EditorCanvas.js.map +1 -1
  54. package/dist/components/EmailNotifyPanel.d.ts +165 -0
  55. package/dist/components/EmailNotifyPanel.d.ts.map +1 -0
  56. package/dist/components/EmailNotifyPanel.js +211 -0
  57. package/dist/components/EmailNotifyPanel.js.map +1 -0
  58. package/dist/components/FileDropZone.d.ts +9 -1
  59. package/dist/components/FileDropZone.d.ts.map +1 -1
  60. package/dist/components/FileDropZone.js +53 -5
  61. package/dist/components/FileDropZone.js.map +1 -1
  62. package/dist/components/FoldEditorPanel.d.ts +68 -0
  63. package/dist/components/FoldEditorPanel.d.ts.map +1 -0
  64. package/dist/components/FoldEditorPanel.js +65 -0
  65. package/dist/components/FoldEditorPanel.js.map +1 -0
  66. package/dist/components/FoldPreviewOverlay.d.ts +48 -0
  67. package/dist/components/FoldPreviewOverlay.d.ts.map +1 -0
  68. package/dist/components/FoldPreviewOverlay.js +182 -0
  69. package/dist/components/FoldPreviewOverlay.js.map +1 -0
  70. package/dist/components/Gs1DigitalLinkPanel.d.ts +103 -0
  71. package/dist/components/Gs1DigitalLinkPanel.d.ts.map +1 -0
  72. package/dist/components/Gs1DigitalLinkPanel.js +199 -0
  73. package/dist/components/Gs1DigitalLinkPanel.js.map +1 -0
  74. package/dist/components/HistoryPanel.d.ts +39 -0
  75. package/dist/components/HistoryPanel.d.ts.map +1 -0
  76. package/dist/components/HistoryPanel.js +72 -0
  77. package/dist/components/HistoryPanel.js.map +1 -0
  78. package/dist/components/IccSoftProofOverlay.d.ts +67 -0
  79. package/dist/components/IccSoftProofOverlay.d.ts.map +1 -0
  80. package/dist/components/IccSoftProofOverlay.js +119 -0
  81. package/dist/components/IccSoftProofOverlay.js.map +1 -0
  82. package/dist/components/ImposePanel.d.ts +71 -0
  83. package/dist/components/ImposePanel.d.ts.map +1 -0
  84. package/dist/components/ImposePanel.js +127 -0
  85. package/dist/components/ImposePanel.js.map +1 -0
  86. package/dist/components/InksPanel.d.ts +61 -0
  87. package/dist/components/InksPanel.d.ts.map +1 -0
  88. package/dist/components/InksPanel.js +84 -0
  89. package/dist/components/InksPanel.js.map +1 -0
  90. package/dist/components/JobSetupPanel.d.ts +118 -0
  91. package/dist/components/JobSetupPanel.d.ts.map +1 -0
  92. package/dist/components/JobSetupPanel.js +169 -0
  93. package/dist/components/JobSetupPanel.js.map +1 -0
  94. package/dist/components/LayersPanel.d.ts.map +1 -1
  95. package/dist/components/LayersPanel.js +1 -0
  96. package/dist/components/LayersPanel.js.map +1 -1
  97. package/dist/components/MarkLibraryPanel.d.ts +131 -0
  98. package/dist/components/MarkLibraryPanel.d.ts.map +1 -0
  99. package/dist/components/MarkLibraryPanel.js +184 -0
  100. package/dist/components/MarkLibraryPanel.js.map +1 -0
  101. package/dist/components/MisEstimateButton.d.ts +73 -0
  102. package/dist/components/MisEstimateButton.d.ts.map +1 -0
  103. package/dist/components/MisEstimateButton.js +57 -0
  104. package/dist/components/MisEstimateButton.js.map +1 -0
  105. package/dist/components/NutritionPanel.d.ts +118 -0
  106. package/dist/components/NutritionPanel.d.ts.map +1 -0
  107. package/dist/components/NutritionPanel.js +169 -0
  108. package/dist/components/NutritionPanel.js.map +1 -0
  109. package/dist/components/PageNavigator.d.ts.map +1 -1
  110. package/dist/components/PageNavigator.js +6 -1
  111. package/dist/components/PageNavigator.js.map +1 -1
  112. package/dist/components/PaletteManager.d.ts +32 -0
  113. package/dist/components/PaletteManager.d.ts.map +1 -0
  114. package/dist/components/PaletteManager.js +89 -0
  115. package/dist/components/PaletteManager.js.map +1 -0
  116. package/dist/components/PaletteToSpotPanel.d.ts +122 -0
  117. package/dist/components/PaletteToSpotPanel.d.ts.map +1 -0
  118. package/dist/components/PaletteToSpotPanel.js +160 -0
  119. package/dist/components/PaletteToSpotPanel.js.map +1 -0
  120. package/dist/components/PreflightAutoFixPanel.d.ts +110 -0
  121. package/dist/components/PreflightAutoFixPanel.d.ts.map +1 -0
  122. package/dist/components/PreflightAutoFixPanel.js +119 -0
  123. package/dist/components/PreflightAutoFixPanel.js.map +1 -0
  124. package/dist/components/PreflightDiffPanel.d.ts +127 -0
  125. package/dist/components/PreflightDiffPanel.d.ts.map +1 -0
  126. package/dist/components/PreflightDiffPanel.js +0 -0
  127. package/dist/components/PreflightDiffPanel.js.map +1 -0
  128. package/dist/components/ProcessRulesPanel.d.ts +81 -0
  129. package/dist/components/ProcessRulesPanel.d.ts.map +1 -0
  130. package/dist/components/ProcessRulesPanel.js +143 -0
  131. package/dist/components/ProcessRulesPanel.js.map +1 -0
  132. package/dist/components/SlackNotifyPanel.d.ts +139 -0
  133. package/dist/components/SlackNotifyPanel.d.ts.map +1 -0
  134. package/dist/components/SlackNotifyPanel.js +133 -0
  135. package/dist/components/SlackNotifyPanel.js.map +1 -0
  136. package/dist/components/SmartSpotMatchPanel.d.ts +143 -0
  137. package/dist/components/SmartSpotMatchPanel.d.ts.map +1 -0
  138. package/dist/components/SmartSpotMatchPanel.js +159 -0
  139. package/dist/components/SmartSpotMatchPanel.js.map +1 -0
  140. package/dist/components/SwatchesPicker.d.ts +83 -0
  141. package/dist/components/SwatchesPicker.d.ts.map +1 -0
  142. package/dist/components/SwatchesPicker.js +151 -0
  143. package/dist/components/SwatchesPicker.js.map +1 -0
  144. package/dist/components/TacOverlay.d.ts +47 -0
  145. package/dist/components/TacOverlay.d.ts.map +1 -0
  146. package/dist/components/TacOverlay.js +116 -0
  147. package/dist/components/TacOverlay.js.map +1 -0
  148. package/dist/components/TrapEditorPanel.d.ts +52 -0
  149. package/dist/components/TrapEditorPanel.d.ts.map +1 -0
  150. package/dist/components/TrapEditorPanel.js +64 -0
  151. package/dist/components/TrapEditorPanel.js.map +1 -0
  152. package/dist/components/TrapPreviewOverlay.d.ts +64 -0
  153. package/dist/components/TrapPreviewOverlay.d.ts.map +1 -0
  154. package/dist/components/TrapPreviewOverlay.js +120 -0
  155. package/dist/components/TrapPreviewOverlay.js.map +1 -0
  156. package/dist/components/VariantMatrixPanel.d.ts +61 -0
  157. package/dist/components/VariantMatrixPanel.d.ts.map +1 -0
  158. package/dist/components/VariantMatrixPanel.js +97 -0
  159. package/dist/components/VariantMatrixPanel.js.map +1 -0
  160. package/dist/components/VariantMatrixVersionPanel.d.ts +122 -0
  161. package/dist/components/VariantMatrixVersionPanel.d.ts.map +1 -0
  162. package/dist/components/VariantMatrixVersionPanel.js +162 -0
  163. package/dist/components/VariantMatrixVersionPanel.js.map +1 -0
  164. package/dist/components/WebhookNotifyPanel.d.ts +160 -0
  165. package/dist/components/WebhookNotifyPanel.d.ts.map +1 -0
  166. package/dist/components/WebhookNotifyPanel.js +100 -0
  167. package/dist/components/WebhookNotifyPanel.js.map +1 -0
  168. package/dist/components/WhiteUnderbasePanel.d.ts +107 -0
  169. package/dist/components/WhiteUnderbasePanel.d.ts.map +1 -0
  170. package/dist/components/WhiteUnderbasePanel.js +104 -0
  171. package/dist/components/WhiteUnderbasePanel.js.map +1 -0
  172. package/dist/hooks/useEditorMode.d.ts +25 -5
  173. package/dist/hooks/useEditorMode.d.ts.map +1 -1
  174. package/dist/hooks/useEditorMode.js +18 -5
  175. package/dist/hooks/useEditorMode.js.map +1 -1
  176. package/dist/index.d.ts +49 -2
  177. package/dist/index.d.ts.map +1 -1
  178. package/dist/index.js +49 -2
  179. package/dist/index.js.map +1 -1
  180. package/dist/lens/preflight-findings.d.ts.map +1 -1
  181. package/dist/lens/preflight-findings.js.map +1 -1
  182. package/dist/lib/barcode-scan.d.ts +154 -0
  183. package/dist/lib/barcode-scan.d.ts.map +1 -0
  184. package/dist/lib/barcode-scan.js +152 -0
  185. package/dist/lib/barcode-scan.js.map +1 -0
  186. package/dist/lib/color-math.d.ts +76 -0
  187. package/dist/lib/color-math.d.ts.map +1 -0
  188. package/dist/lib/color-math.js +96 -0
  189. package/dist/lib/color-math.js.map +1 -0
  190. package/dist/lib/dieline-template.d.ts +87 -0
  191. package/dist/lib/dieline-template.d.ts.map +1 -1
  192. package/dist/lib/dieline-template.js +163 -0
  193. package/dist/lib/dieline-template.js.map +1 -1
  194. package/dist/lib/editor-config.d.ts +384 -0
  195. package/dist/lib/editor-config.d.ts.map +1 -1
  196. package/dist/lib/editor-config.js +89 -0
  197. package/dist/lib/editor-config.js.map +1 -1
  198. package/dist/lib/fold-geometry.d.ts +144 -0
  199. package/dist/lib/fold-geometry.d.ts.map +1 -0
  200. package/dist/lib/fold-geometry.js +138 -0
  201. package/dist/lib/fold-geometry.js.map +1 -0
  202. package/dist/lib/merge-tokens.d.ts +81 -0
  203. package/dist/lib/merge-tokens.d.ts.map +1 -0
  204. package/dist/lib/merge-tokens.js +88 -0
  205. package/dist/lib/merge-tokens.js.map +1 -0
  206. package/dist/lib/palette-registry.d.ts +40 -0
  207. package/dist/lib/palette-registry.d.ts.map +1 -0
  208. package/dist/lib/palette-registry.js +49 -0
  209. package/dist/lib/palette-registry.js.map +1 -0
  210. package/dist/lib/panel-anchor.d.ts +101 -0
  211. package/dist/lib/panel-anchor.d.ts.map +1 -0
  212. package/dist/lib/panel-anchor.js +68 -0
  213. package/dist/lib/panel-anchor.js.map +1 -0
  214. package/dist/lib/preflight/checks.d.ts.map +1 -1
  215. package/dist/lib/preflight/checks.js +71 -0
  216. package/dist/lib/preflight/checks.js.map +1 -1
  217. package/dist/lib/preflight/types.d.ts.map +1 -1
  218. package/dist/lib/preflight/types.js +11 -0
  219. package/dist/lib/preflight/types.js.map +1 -1
  220. package/dist/lib/rasterize.d.ts +93 -0
  221. package/dist/lib/rasterize.d.ts.map +1 -0
  222. package/dist/lib/rasterize.js +117 -0
  223. package/dist/lib/rasterize.js.map +1 -0
  224. package/dist/lib/separations-registry.d.ts +99 -0
  225. package/dist/lib/separations-registry.d.ts.map +1 -0
  226. package/dist/lib/separations-registry.js +59 -0
  227. package/dist/lib/separations-registry.js.map +1 -0
  228. package/dist/lib/unwired.d.ts +29 -0
  229. package/dist/lib/unwired.d.ts.map +1 -0
  230. package/dist/lib/unwired.js +58 -0
  231. package/dist/lib/unwired.js.map +1 -0
  232. package/package.json +20 -11
  233. package/dist/components/SeparationsPanel.d.ts +0 -9
  234. package/dist/components/SeparationsPanel.d.ts.map +0 -1
  235. package/dist/components/SeparationsPanel.js +0 -168
  236. 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"}