@semiont/react-ui 0.5.10 → 0.5.12

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 (81) hide show
  1. package/README.md +1 -1
  2. package/dist/{PdfAnnotationCanvas.client-P37SXBWQ.js → PdfAnnotationCanvas.client-75GY2EDR.js} +15 -6
  3. package/dist/PdfAnnotationCanvas.client-75GY2EDR.js.map +1 -0
  4. package/dist/{chunk-5LFFAVDI.js → chunk-PFUXQPWJ.js} +96 -96
  5. package/dist/{chunk-5LFFAVDI.js.map → chunk-PFUXQPWJ.js.map} +1 -1
  6. package/dist/{chunk-O2MD7TGE.js → chunk-VXASXU4K.js} +10 -2
  7. package/dist/chunk-VXASXU4K.js.map +1 -0
  8. package/dist/index.css +150 -112
  9. package/dist/index.css.map +1 -1
  10. package/dist/index.d.ts +334 -48
  11. package/dist/index.js +2494 -2201
  12. package/dist/index.js.map +1 -1
  13. package/dist/test-utils.d.ts +5 -1
  14. package/dist/test-utils.js +10 -4
  15. package/dist/test-utils.js.map +1 -1
  16. package/package.json +7 -7
  17. package/src/components/ResourceTagsInline.tsx +94 -11
  18. package/src/components/StatusDisplay.css +36 -0
  19. package/src/components/__tests__/ResourceTagsInline.test.tsx +101 -3
  20. package/src/components/annotation/AnnotateToolbar.tsx +53 -28
  21. package/src/components/annotation/__tests__/AnnotateToolbar.display.test.tsx +76 -0
  22. package/src/components/annotation/__tests__/AnnotateToolbar.test.tsx +124 -360
  23. package/src/components/image-annotation/AnnotationOverlay.tsx +6 -6
  24. package/src/components/image-annotation/SvgDrawingCanvas.tsx +17 -5
  25. package/src/components/image-annotation/__tests__/AnnotationOverlay.click.test.tsx +137 -0
  26. package/src/components/image-annotation/__tests__/SvgDrawingCanvas.click.test.tsx +108 -0
  27. package/src/components/pdf-annotation/PdfAnnotationCanvas.tsx +17 -4
  28. package/src/components/pdf-annotation/__tests__/PdfAnnotationCanvas.test.tsx +143 -7
  29. package/src/components/resource/AnnotateView.tsx +59 -38
  30. package/src/components/resource/BrowseView.tsx +172 -138
  31. package/src/components/resource/ResourceViewer.tsx +123 -130
  32. package/src/components/resource/__tests__/AnnotateView.embeddable.test.tsx +55 -0
  33. package/src/components/resource/__tests__/BrowseView.embeddable.test.tsx +49 -0
  34. package/src/components/resource/__tests__/BrowseView.links.test.tsx +60 -0
  35. package/src/components/resource/__tests__/BrowseView.overlay-async.test.tsx +113 -0
  36. package/src/components/resource/__tests__/BrowseView.reference-hover.test.tsx +161 -0
  37. package/src/components/resource/__tests__/BrowseView.registry.test.tsx +43 -0
  38. package/src/components/resource/__tests__/BrowseView.test.tsx +133 -53
  39. package/src/components/resource/__tests__/ResourceViewer.embeddable.test.tsx +102 -0
  40. package/src/components/resource/__tests__/ResourceViewer.mode-switch.test.tsx +12 -7
  41. package/src/components/resource/__tests__/ResourceViewer.toolbar-opt-out.test.tsx +135 -0
  42. package/src/components/resource/__tests__/ResourceViewer.toolbar-prefs.test.tsx +200 -0
  43. package/src/components/resource/__tests__/browse-renderers.dispatch.test.tsx +113 -0
  44. package/src/components/resource/__tests__/browse-renderers.test.tsx +34 -0
  45. package/src/components/resource/__tests__/inline-embedding.test.tsx +81 -0
  46. package/src/components/resource/__tests__/media-completeness.test.tsx +88 -0
  47. package/src/components/resource/browse-renderers.tsx +85 -0
  48. package/src/components/resource/panels/AssessmentEntry.tsx +5 -4
  49. package/src/components/resource/panels/AssessmentPanel.tsx +12 -5
  50. package/src/components/resource/panels/AssistSection.tsx +4 -3
  51. package/src/components/resource/panels/CommentEntry.tsx +5 -4
  52. package/src/components/resource/panels/CommentsPanel.tsx +12 -5
  53. package/src/components/resource/panels/HighlightEntry.tsx +5 -4
  54. package/src/components/resource/panels/HighlightPanel.tsx +12 -5
  55. package/src/components/resource/panels/ReferenceEntry.tsx +9 -10
  56. package/src/components/resource/panels/ReferencesPanel.tsx +15 -6
  57. package/src/components/resource/panels/ResourceInfoPanel.tsx +4 -3
  58. package/src/components/resource/panels/TagEntry.tsx +5 -3
  59. package/src/components/resource/panels/TaggingPanel.tsx +11 -4
  60. package/src/components/resource/panels/UnifiedAnnotationsPanel.tsx +15 -2
  61. package/src/components/resource/panels/__tests__/AssessmentEntry.test.tsx +28 -20
  62. package/src/components/resource/panels/__tests__/AssessmentPanel.test.tsx +39 -28
  63. package/src/components/resource/panels/__tests__/AssistSection.test.tsx +46 -17
  64. package/src/components/resource/panels/__tests__/CommentEntry.test.tsx +65 -57
  65. package/src/components/resource/panels/__tests__/CommentsPanel.test.tsx +54 -24
  66. package/src/components/resource/panels/__tests__/HighlightEntry.test.tsx +27 -17
  67. package/src/components/resource/panels/__tests__/HighlightPanel.annotationProgress.test.tsx +23 -17
  68. package/src/components/resource/panels/__tests__/ReferenceEntry.test.tsx +48 -77
  69. package/src/components/resource/panels/__tests__/ReferencesPanel.headless.test.tsx +87 -0
  70. package/src/components/resource/panels/__tests__/ReferencesPanel.observable-flow.test.tsx +15 -9
  71. package/src/components/resource/panels/__tests__/ReferencesPanel.test.tsx +78 -59
  72. package/src/components/resource/panels/__tests__/ResourceInfoPanel.test.tsx +11 -4
  73. package/src/components/resource/panels/__tests__/TagEntry.test.tsx +33 -19
  74. package/src/components/resource/panels/__tests__/TaggingPanel.test.tsx +16 -7
  75. package/src/components/toolbar/Toolbar.css +14 -0
  76. package/src/features/resource-viewer/__tests__/ResourceViewerPage.test.tsx +7 -17
  77. package/src/features/resource-viewer/components/ResourceViewerPage.tsx +43 -17
  78. package/src/features/resource-viewer/state/resource-viewer-page-state-unit.ts +2 -14
  79. package/src/styles/features/resource-viewer.css +19 -0
  80. package/dist/PdfAnnotationCanvas.client-P37SXBWQ.js.map +0 -1
  81. package/dist/chunk-O2MD7TGE.js.map +0 -1
@@ -34,9 +34,17 @@ async function renderPdfPageToDataUrl(page, scale = 1) {
34
34
  };
35
35
  }
36
36
 
37
+ // src/lib/anchor-rect.ts
38
+ function toViewportAnchorRect(origin, x, y, width, height) {
39
+ const left = origin.left + x;
40
+ const top = origin.top + y;
41
+ return { x: left, y: top, width, height, top, right: left + width, bottom: top + height, left };
42
+ }
43
+
37
44
  export {
38
45
  setPdfWorkerSrc,
39
46
  loadPdfDocument,
40
- renderPdfPageToDataUrl
47
+ renderPdfPageToDataUrl,
48
+ toViewportAnchorRect
41
49
  };
42
- //# sourceMappingURL=chunk-O2MD7TGE.js.map
50
+ //# sourceMappingURL=chunk-VXASXU4K.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/lib/browser-pdfjs.ts","../src/lib/anchor-rect.ts"],"sourcesContent":["/**\n * Browser PDF.js — bundled from the npm `pdfjs-dist` (v6) package, loaded\n * lazily.\n *\n * pdf.js (the ~300 kB display layer) is pulled in via a dynamic `import()` the\n * first time a PDF is actually opened, so it is code-split out of the main app\n * bundle — restoring the lazy-load behaviour the old CDN loader had. Only the\n * pdf.js *types* are imported statically (erased at build time, zero runtime\n * cost).\n *\n * The worker can't be resolved inside this tsup-built library (Vite's `?url`\n * lives in the app), so the host hands us the worker URL via `setPdfWorkerSrc`\n * once at startup; it is applied to `GlobalWorkerOptions` when pdf.js loads.\n * See `apps/frontend/src/main.tsx`.\n */\nimport type { PDFDocumentProxy, PDFPageProxy } from 'pdfjs-dist';\n\nexport type { PDFDocumentProxy };\n\nlet workerSrc: string | undefined;\n\n/**\n * Supply the (Vite-resolved) pdf.js worker URL. Call once at app startup,\n * before any PDF is opened.\n */\nexport function setPdfWorkerSrc(src: string): void {\n workerSrc = src;\n}\n\nlet pdfjsPromise: Promise<typeof import('pdfjs-dist')> | undefined;\n\n/** Lazy-load pdf.js once, applying the worker URL on first load. */\nasync function getPdfjs(): Promise<typeof import('pdfjs-dist')> {\n if (!pdfjsPromise) {\n pdfjsPromise = import('pdfjs-dist').then((pdfjsLib) => {\n if (workerSrc) {\n pdfjsLib.GlobalWorkerOptions.workerSrc = workerSrc;\n }\n return pdfjsLib;\n });\n }\n return pdfjsPromise;\n}\n\n/**\n * Load a PDF document from a URL. The URL must carry auth (e.g. `?token=…`);\n * pdf.js streams the document directly.\n */\nexport async function loadPdfDocument(url: string): Promise<PDFDocumentProxy> {\n const pdfjsLib = await getPdfjs();\n return pdfjsLib.getDocument({ url }).promise;\n}\n\n/**\n * Render a PDF page to a PNG data URL. The `page` is already loaded (its owning\n * document came from `loadPdfDocument`), so no pdf.js import is needed here.\n */\nexport async function renderPdfPageToDataUrl(\n page: PDFPageProxy,\n scale = 1.0,\n): Promise<{ dataUrl: string; width: number; height: number }> {\n const viewport = page.getViewport({ scale });\n\n const canvas = document.createElement('canvas');\n canvas.width = viewport.width;\n canvas.height = viewport.height;\n\n // pdf.js 6 requires the `canvas` parameter; `canvasContext` is deprecated.\n await page.render({ canvas, viewport }).promise;\n\n return {\n dataUrl: canvas.toDataURL('image/png'),\n width: viewport.width,\n height: viewport.height,\n };\n}\n","import type { AnchorRect } from '@semiont/core';\n\n/**\n * Convert a rect in element-local display coordinates to a viewport-space\n * AnchorRect, offset by the element's own viewport position. Used by the\n * canvas hit-tests (image / PDF), whose annotation geometry lives in display\n * coordinates rather than on a DOM element.\n */\nexport function toViewportAnchorRect(\n origin: { left: number; top: number },\n x: number,\n y: number,\n width: number,\n height: number,\n): AnchorRect {\n const left = origin.left + x;\n const top = origin.top + y;\n return { x: left, y: top, width, height, top, right: left + width, bottom: top + height, left };\n}\n"],"mappings":";;;AAmBA,IAAI;AAMG,SAAS,gBAAgB,KAAmB;AACjD,cAAY;AACd;AAEA,IAAI;AAGJ,eAAe,WAAiD;AAC9D,MAAI,CAAC,cAAc;AACjB,mBAAe,OAAO,YAAY,EAAE,KAAK,CAAC,aAAa;AACrD,UAAI,WAAW;AACb,iBAAS,oBAAoB,YAAY;AAAA,MAC3C;AACA,aAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAMA,eAAsB,gBAAgB,KAAwC;AAC5E,QAAM,WAAW,MAAM,SAAS;AAChC,SAAO,SAAS,YAAY,EAAE,IAAI,CAAC,EAAE;AACvC;AAMA,eAAsB,uBACpB,MACA,QAAQ,GACqD;AAC7D,QAAM,WAAW,KAAK,YAAY,EAAE,MAAM,CAAC;AAE3C,QAAM,SAAS,SAAS,cAAc,QAAQ;AAC9C,SAAO,QAAQ,SAAS;AACxB,SAAO,SAAS,SAAS;AAGzB,QAAM,KAAK,OAAO,EAAE,QAAQ,SAAS,CAAC,EAAE;AAExC,SAAO;AAAA,IACL,SAAS,OAAO,UAAU,WAAW;AAAA,IACrC,OAAO,SAAS;AAAA,IAChB,QAAQ,SAAS;AAAA,EACnB;AACF;;;ACnEO,SAAS,qBACd,QACA,GACA,GACA,OACA,QACY;AACZ,QAAM,OAAO,OAAO,OAAO;AAC3B,QAAM,MAAM,OAAO,MAAM;AACzB,SAAO,EAAE,GAAG,MAAM,GAAG,KAAK,OAAO,QAAQ,KAAK,OAAO,OAAO,OAAO,QAAQ,MAAM,QAAQ,KAAK;AAChG;","names":[]}
package/dist/index.css CHANGED
@@ -1,115 +1,3 @@
1
- /* src/components/Toast.css */
2
- .semiont-toast-container {
3
- position: fixed;
4
- top: 1rem;
5
- right: 1rem;
6
- z-index: 50;
7
- display: flex;
8
- flex-direction: column;
9
- gap: 0.5rem;
10
- max-width: 24rem;
11
- }
12
- .semiont-toast {
13
- display: flex;
14
- align-items: center;
15
- gap: 0.75rem;
16
- padding: 0.75rem 1rem;
17
- border-radius: var(--semiont-radius-lg);
18
- border: 1px solid;
19
- box-shadow: var(--semiont-shadow-lg);
20
- transition: all var(--semiont-duration-base) var(--semiont-ease);
21
- transform: translateX(0);
22
- animation: slideIn var(--semiont-duration-base) var(--semiont-ease);
23
- }
24
- [data-theme=dark] .semiont-toast {
25
- box-shadow: var(--semiont-shadow-lg);
26
- }
27
- @keyframes slideIn {
28
- from {
29
- transform: translateX(100%);
30
- opacity: 0;
31
- }
32
- to {
33
- transform: translateX(0);
34
- opacity: 1;
35
- }
36
- }
37
- .semiont-toast-icon-wrapper {
38
- flex-shrink: 0;
39
- display: flex;
40
- align-items: center;
41
- justify-content: center;
42
- }
43
- .semiont-toast-icon {
44
- width: 1.25rem;
45
- height: 1.25rem;
46
- }
47
- .semiont-toast-message {
48
- flex: 1;
49
- font-size: var(--semiont-text-sm);
50
- font-weight: var(--semiont-font-medium);
51
- }
52
- .semiont-toast-close {
53
- margin-left: auto;
54
- flex-shrink: 0;
55
- display: flex;
56
- align-items: center;
57
- justify-content: center;
58
- background: transparent;
59
- border: none;
60
- cursor: pointer;
61
- padding: 0.25rem;
62
- border-radius: var(--semiont-radius-base);
63
- transition: opacity var(--semiont-duration-fast) var(--semiont-ease);
64
- }
65
- .semiont-toast-close:hover {
66
- opacity: 0.7;
67
- }
68
- .semiont-toast-close-icon {
69
- width: 1rem;
70
- height: 1rem;
71
- }
72
- .semiont-toast[data-variant=success] {
73
- background-color: var(--semiont-color-green-100);
74
- border-color: var(--semiont-color-green-300);
75
- color: var(--semiont-color-green-800);
76
- }
77
- .semiont-toast[data-variant=error] {
78
- background-color: var(--semiont-color-red-100);
79
- border-color: var(--semiont-color-red-300);
80
- color: var(--semiont-color-red-800);
81
- }
82
- .semiont-toast[data-variant=warning] {
83
- background-color: var(--semiont-color-yellow-100);
84
- border-color: var(--semiont-color-yellow-300);
85
- color: var(--semiont-color-yellow-900);
86
- }
87
- .semiont-toast[data-variant=info] {
88
- background-color: var(--semiont-color-blue-100);
89
- border-color: var(--semiont-color-blue-300);
90
- color: var(--semiont-color-blue-800);
91
- }
92
- [data-theme=dark] .semiont-toast[data-variant=success] {
93
- background-color: rgba(34, 197, 94, 0.1);
94
- border-color: var(--semiont-color-green-600);
95
- color: var(--semiont-color-green-300);
96
- }
97
- [data-theme=dark] .semiont-toast[data-variant=error] {
98
- background-color: rgba(239, 68, 68, 0.1);
99
- border-color: var(--semiont-color-red-600);
100
- color: var(--semiont-color-red-300);
101
- }
102
- [data-theme=dark] .semiont-toast[data-variant=warning] {
103
- background-color: rgba(245, 158, 11, 0.1);
104
- border-color: var(--semiont-color-amber-600);
105
- color: var(--semiont-color-yellow-300);
106
- }
107
- [data-theme=dark] .semiont-toast[data-variant=info] {
108
- background-color: rgba(59, 130, 246, 0.1);
109
- border-color: var(--semiont-color-blue-600);
110
- color: var(--semiont-color-blue-300);
111
- }
112
-
113
1
  /* src/components/ProtectedErrorBoundary.css */
114
2
  .semiont-protected-error-boundary-container {
115
3
  min-height: 400px;
@@ -291,6 +179,118 @@
291
179
  outline: none;
292
180
  }
293
181
 
182
+ /* src/components/Toast.css */
183
+ .semiont-toast-container {
184
+ position: fixed;
185
+ top: 1rem;
186
+ right: 1rem;
187
+ z-index: 50;
188
+ display: flex;
189
+ flex-direction: column;
190
+ gap: 0.5rem;
191
+ max-width: 24rem;
192
+ }
193
+ .semiont-toast {
194
+ display: flex;
195
+ align-items: center;
196
+ gap: 0.75rem;
197
+ padding: 0.75rem 1rem;
198
+ border-radius: var(--semiont-radius-lg);
199
+ border: 1px solid;
200
+ box-shadow: var(--semiont-shadow-lg);
201
+ transition: all var(--semiont-duration-base) var(--semiont-ease);
202
+ transform: translateX(0);
203
+ animation: slideIn var(--semiont-duration-base) var(--semiont-ease);
204
+ }
205
+ [data-theme=dark] .semiont-toast {
206
+ box-shadow: var(--semiont-shadow-lg);
207
+ }
208
+ @keyframes slideIn {
209
+ from {
210
+ transform: translateX(100%);
211
+ opacity: 0;
212
+ }
213
+ to {
214
+ transform: translateX(0);
215
+ opacity: 1;
216
+ }
217
+ }
218
+ .semiont-toast-icon-wrapper {
219
+ flex-shrink: 0;
220
+ display: flex;
221
+ align-items: center;
222
+ justify-content: center;
223
+ }
224
+ .semiont-toast-icon {
225
+ width: 1.25rem;
226
+ height: 1.25rem;
227
+ }
228
+ .semiont-toast-message {
229
+ flex: 1;
230
+ font-size: var(--semiont-text-sm);
231
+ font-weight: var(--semiont-font-medium);
232
+ }
233
+ .semiont-toast-close {
234
+ margin-left: auto;
235
+ flex-shrink: 0;
236
+ display: flex;
237
+ align-items: center;
238
+ justify-content: center;
239
+ background: transparent;
240
+ border: none;
241
+ cursor: pointer;
242
+ padding: 0.25rem;
243
+ border-radius: var(--semiont-radius-base);
244
+ transition: opacity var(--semiont-duration-fast) var(--semiont-ease);
245
+ }
246
+ .semiont-toast-close:hover {
247
+ opacity: 0.7;
248
+ }
249
+ .semiont-toast-close-icon {
250
+ width: 1rem;
251
+ height: 1rem;
252
+ }
253
+ .semiont-toast[data-variant=success] {
254
+ background-color: var(--semiont-color-green-100);
255
+ border-color: var(--semiont-color-green-300);
256
+ color: var(--semiont-color-green-800);
257
+ }
258
+ .semiont-toast[data-variant=error] {
259
+ background-color: var(--semiont-color-red-100);
260
+ border-color: var(--semiont-color-red-300);
261
+ color: var(--semiont-color-red-800);
262
+ }
263
+ .semiont-toast[data-variant=warning] {
264
+ background-color: var(--semiont-color-yellow-100);
265
+ border-color: var(--semiont-color-yellow-300);
266
+ color: var(--semiont-color-yellow-900);
267
+ }
268
+ .semiont-toast[data-variant=info] {
269
+ background-color: var(--semiont-color-blue-100);
270
+ border-color: var(--semiont-color-blue-300);
271
+ color: var(--semiont-color-blue-800);
272
+ }
273
+ [data-theme=dark] .semiont-toast[data-variant=success] {
274
+ background-color: rgba(34, 197, 94, 0.1);
275
+ border-color: var(--semiont-color-green-600);
276
+ color: var(--semiont-color-green-300);
277
+ }
278
+ [data-theme=dark] .semiont-toast[data-variant=error] {
279
+ background-color: rgba(239, 68, 68, 0.1);
280
+ border-color: var(--semiont-color-red-600);
281
+ color: var(--semiont-color-red-300);
282
+ }
283
+ [data-theme=dark] .semiont-toast[data-variant=warning] {
284
+ background-color: rgba(245, 158, 11, 0.1);
285
+ border-color: var(--semiont-color-amber-600);
286
+ color: var(--semiont-color-yellow-300);
287
+ }
288
+ [data-theme=dark] .semiont-toast[data-variant=info] {
289
+ background-color: rgba(59, 130, 246, 0.1);
290
+ border-color: var(--semiont-color-blue-600);
291
+ color: var(--semiont-color-blue-300);
292
+ }
293
+
294
294
  /* src/components/toolbar/Toolbar.css */
295
295
  .semiont-annotate-toolbar {
296
296
  display: flex;
@@ -469,6 +469,15 @@
469
469
  .semiont-toolbar-menu-label {
470
470
  font-size: 0.875rem;
471
471
  }
472
+ .semiont-annotate-toolbar--compact {
473
+ gap: 0.375rem;
474
+ padding: 0.25rem 0;
475
+ background: transparent;
476
+ border-bottom: none;
477
+ }
478
+ .semiont-annotate-toolbar--compact .semiont-dropdown-label {
479
+ display: none;
480
+ }
472
481
 
473
482
  /* src/components/settings/SettingsPanel.css */
474
483
  .semiont-settings-panel {
@@ -4248,6 +4257,35 @@
4248
4257
  border-radius: var(--semiont-radius-base);
4249
4258
  font-size: var(--semiont-font-size-xs);
4250
4259
  }
4260
+ .semiont-resource-tag__remove {
4261
+ display: inline-flex;
4262
+ align-items: center;
4263
+ padding: 0;
4264
+ border: none;
4265
+ background: none;
4266
+ color: inherit;
4267
+ font-size: var(--semiont-font-size-xs);
4268
+ cursor: pointer;
4269
+ opacity: 0.7;
4270
+ }
4271
+ .semiont-resource-tag__remove:hover:not(:disabled) {
4272
+ opacity: 1;
4273
+ }
4274
+ .semiont-resource-tag__remove:disabled {
4275
+ cursor: default;
4276
+ opacity: 0.4;
4277
+ }
4278
+ .semiont-resource-tag--add {
4279
+ cursor: pointer;
4280
+ background: none;
4281
+ }
4282
+ .semiont-resource-tag--add:disabled {
4283
+ cursor: default;
4284
+ opacity: 0.4;
4285
+ }
4286
+ .semiont-resource-tags-inline--editing .semiont-form__entity-type-buttons {
4287
+ margin-top: var(--semiont-spacing-xs);
4288
+ }
4251
4289
  [data-theme=dark] .semiont-resource-tags-inline {
4252
4290
  border-top-color: var(--semiont-color-neutral-700);
4253
4291
  }