dbf-mirador 4.3.1 → 4.3.2

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dbf-mirador",
3
- "version": "4.3.1",
3
+ "version": "4.3.2",
4
4
  "description": "An open-source, web-based 'multi-up' viewer that supports zoom-pan-rotate functionality, ability to display/compare simple images, and images with annotations.",
5
5
  "type": "module",
6
6
  "main": "./dist/mirador.min.js",
@@ -85,6 +85,7 @@
85
85
  "uuid": "^8.1.0 || ^9.0.0 || ^10.0.0 || ^11.0.0"
86
86
  },
87
87
  "devDependencies": {
88
+ "@ckeditor/ckeditor5-react": "~11.0.1",
88
89
  "@emotion/react": "^11.10.6",
89
90
  "@emotion/styled": "^11.10.6",
90
91
  "@eslint/compat": "^2.0.3",
@@ -100,6 +101,8 @@
100
101
  "@vitest/coverage-v8": "^4.1.2",
101
102
  "@vitest/ui": "^4.1.2",
102
103
  "chalk": "^5.3.0",
104
+ "ckeditor5": "~47.6.1",
105
+ "dbf-mirador": "file:.",
103
106
  "eslint": "^10.0.0",
104
107
  "eslint-config-prettier": "^10.1.8",
105
108
  "eslint-plugin-import": "^2.32.0",
@@ -125,7 +128,8 @@
125
128
  "vitest-fetch-mock": "^0.4.2"
126
129
  },
127
130
  "overrides": {
128
- "brace-expansion@1": "^1.1.16"
131
+ "brace-expansion@1": "^1.1.16",
132
+ "dbf-mirador": "file:."
129
133
  },
130
134
  "peerDependencies": {
131
135
  "@emotion/react": "^11.10.6",
@@ -0,0 +1,2 @@
1
+ <?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
2
+ <svg width="800px" height="800px" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--gis" preserveAspectRatio="xMidYMid meet"><path d="M50.002 0C30.763 0 15 15.718 15 34.902c0 7.432 2.374 14.34 6.392 20.019L45.73 96.994c3.409 4.453 5.675 3.607 8.51-.235l26.843-45.683c.542-.981.967-2.026 1.338-3.092A34.446 34.446 0 0 0 85 34.902C85 15.718 69.24 0 50.002 0zm0 16.354c10.359 0 18.597 8.218 18.597 18.548c0 10.33-8.238 18.544-18.597 18.544c-10.36 0-18.601-8.215-18.601-18.544c0-10.33 8.241-18.548 18.6-18.548z" fill="#000000"></path></svg>
@@ -0,0 +1,80 @@
1
+ import { useEffect, useId, useRef } from 'react';
2
+ import PropTypes from 'prop-types';
3
+ import { viewer } from '../init';
4
+ import { poiPreviewPlugins } from '../plugins/poiPreviewPlugin.tsx';
5
+
6
+ // Hides Mirador's generic multi-window IIIF-viewer chrome (top bar, workspace controls,
7
+ // canvas panel) so a manifest reads as a single interactive map rather than a document
8
+ // viewer, and opens straight onto the annotation sidebar since that's where a map's
9
+ // POIs/journeys live. Exported so callers who need Mirador's raw `viewer()`/`Mirador.viewer()`
10
+ // API (e.g. the integration demo config) can build on the same preset instead of copying it.
11
+ export const defaultMapViewerConfig = {
12
+ theme: {
13
+ components: {
14
+ WindowTopBar: {
15
+ styleOverrides: {
16
+ root: {
17
+ display: 'none',
18
+ },
19
+ },
20
+ },
21
+ },
22
+ },
23
+ window: {
24
+ defaultSideBarPanel: 'annotations',
25
+ // Closed by default (issue #410): the left sidebar (annotation list, table of
26
+ // contents, etc.) is Mirador's own document-viewer chrome, not part of the map UI -
27
+ // POIs/journeys are opened through the canvas or the poiPreview companion window
28
+ // instead. `highlightAllAnnotations` still draws markers on the canvas regardless.
29
+ sideBarOpenByDefault: false,
30
+ highlightAllAnnotations: true,
31
+ panels: {
32
+ canvas: false,
33
+ },
34
+ },
35
+ workspaceControlPanel: {
36
+ enabled: false,
37
+ },
38
+ };
39
+
40
+ /**
41
+ * Drop-in map renderer: give it a IIIF manifest URL, get Mirador pre-configured to look
42
+ * and behave like a map instead of a generic multi-window viewer. Wraps `viewer()` so
43
+ * callers don't need to know Mirador's own instantiation/config API.
44
+ */
45
+ export function MapViewer({ manifestId }) {
46
+ const baseId = useId().replace(/:/g, '');
47
+ const wrapperRef = useRef(null);
48
+
49
+ useEffect(() => {
50
+ const wrapper = wrapperRef.current;
51
+ if (!wrapper) return undefined;
52
+
53
+ const container = document.createElement('div');
54
+ container.id = `mirador-map-viewer-${baseId}`;
55
+ container.style.position = 'absolute';
56
+ container.style.inset = 0;
57
+ wrapper.appendChild(container);
58
+
59
+ const instance = viewer(
60
+ {
61
+ ...defaultMapViewerConfig,
62
+ id: container.id,
63
+ windows: [{ manifestId }],
64
+ },
65
+ poiPreviewPlugins,
66
+ );
67
+
68
+ return () => {
69
+ instance.unmount();
70
+ container.remove();
71
+ };
72
+ }, [baseId, manifestId]);
73
+
74
+ return <div ref={wrapperRef} style={{ height: '100%', position: 'relative', width: '100%' }} />;
75
+ }
76
+
77
+ MapViewer.propTypes = {
78
+ /** URL of the IIIF manifest to render as a map. */
79
+ manifestId: PropTypes.string.isRequired,
80
+ };
@@ -41,6 +41,7 @@ export * from './ManifestInfo';
41
41
  export * from './ManifestListItem';
42
42
  export * from './ManifestListItemError';
43
43
  export * from './ManifestRelatedLinks';
44
+ export * from './MapViewer';
44
45
  export * from './MinimalWindow';
45
46
  export * from './MiradorMenuButton';
46
47
  export * from './MosaicRenderPreview';
@@ -1 +1,2 @@
1
1
  export * from './OSDReferences';
2
+ export * from './poiPreviewPlugin.tsx';
@@ -1,4 +1,6 @@
1
1
  import { useState, type ComponentType } from 'react';
2
+ import useMediaQuery from '@mui/material/useMediaQuery';
3
+ import { useTheme } from '@mui/material/styles';
2
4
  import {
3
5
  ConnectedCompanionWindow as CompanionWindow,
4
6
  addCompanionWindow,
@@ -7,7 +9,11 @@ import {
7
9
  getCompanionWindows,
8
10
  getVisibleCanvases,
9
11
  updateCompanionWindow,
10
- } from 'dbf-mirador';
12
+ // Relative, not `from 'dbf-mirador'`: this file lives inside the dbf-mirador package
13
+ // itself (unlike its copy in the Strapi maps plugin, a real external consumer), and
14
+ // there's no self-referencing node_modules link or dist build for the package name to
15
+ // resolve against during local dev.
16
+ } from '../index';
11
17
 
12
18
  // A "dumb" way to preview a POI/journey (issue #375): a Mirador companion window plugin,
13
19
  // registered alongside dbf-mirador-annotation-editor's own (see MiradorMaeViewer.tsx) via
@@ -264,9 +270,10 @@ const poiPreviewCompanionWindowPlugin = {
264
270
  };
265
271
 
266
272
  // A canvas annotation resource, as AnnotationsOverlay's own `annotations`/`searchAnnotations`
267
- // props carry it (see AnnotationItem#pointSelector) - a POI marker is any resource with a
268
- // pointSelector, exactly the condition CanvasAnnotationDisplay#pointContext draws on.
269
- type AnnotationResourceLike = { id: string; pointSelector?: unknown };
273
+ // props carry it (see AnnotationItem#pointSelector/#svgSelector) - a POI marker is any resource
274
+ // with a pointSelector (CanvasAnnotationDisplay#pointContext), a Journey's own canvas target is
275
+ // one with an svgSelector (AnnotationsOverlay#isAnnotationAtPoint's own svgSelector branch).
276
+ type AnnotationResourceLike = { id: string; pointSelector?: unknown; svgSelector?: unknown };
270
277
  type AnnotationListItem = { resources?: AnnotationResourceLike[] };
271
278
 
272
279
  interface AnnotationsOverlayTargetProps {
@@ -287,9 +294,10 @@ interface AnnotationsOverlayPoiClickWrapperProps {
287
294
 
288
295
  // Wraps AnnotationsOverlay (the component that owns the OSD canvas-click handler and the
289
296
  // select/deselect-annotation dispatch, see AnnotationsOverlay#toggleAnnotation) so that
290
- // clicking a POI marker on the canvas - not just a row in a list somewhere - opens this same
291
- // preview companion window a "Preview" button would (issue #375's own follow-up: pins on the
292
- // map itself). Re-uses an already-open preview window instead of stacking a new one per click.
297
+ // clicking a POI marker OR a Journey's own path on the canvas - not just a row in a list
298
+ // somewhere - opens this same preview companion window a "Preview" button would (issue #375's
299
+ // own follow-up: pins on the map itself; issue #378 extends this to journeys). Re-uses an
300
+ // already-open preview window instead of stacking a new one per click.
293
301
  const AnnotationsOverlayPoiClickWrapper = ({
294
302
  TargetComponent,
295
303
  targetProps,
@@ -299,6 +307,12 @@ const AnnotationsOverlayPoiClickWrapper = ({
299
307
  }: AnnotationsOverlayPoiClickWrapperProps) => {
300
308
  const { annotations = [], searchAnnotations = [], selectAnnotation } = targetProps;
301
309
 
310
+ const theme = useTheme();
311
+ // Issue #410: on a phone-width viewport there's no room for a right-hand rail next to
312
+ // the map, so the POI/journey preview opens as a bottom sheet instead.
313
+ const isMobile = useMediaQuery(theme.breakpoints.down('sm'));
314
+ const previewPosition = isMobile ? 'bottom' : 'right';
315
+
302
316
  const selectAnnotationAndMaybePreview = (clickedWindowId: string, annotationId: string) => {
303
317
  selectAnnotation?.(clickedWindowId, annotationId);
304
318
 
@@ -306,17 +320,20 @@ const AnnotationsOverlayPoiClickWrapper = ({
306
320
  .flatMap((item) => item.resources ?? [])
307
321
  .find((item) => item.id === annotationId);
308
322
 
309
- if (!resource?.pointSelector) return;
323
+ // pointSelector => POI pin, svgSelector => a Journey's own canvas target (its path/stops
324
+ // line) - anything else (e.g. a fragmentSelector) has no preview content, skip it.
325
+ if (!resource?.pointSelector && !resource?.svgSelector) return;
310
326
 
311
327
  if (existingPreviewCompanionWindowId) {
312
328
  dispatchUpdateCompanionWindow(clickedWindowId, existingPreviewCompanionWindowId, {
313
329
  annotationid: annotationId,
330
+ position: previewPosition,
314
331
  });
315
332
  } else {
316
333
  dispatchAddCompanionWindow(clickedWindowId, {
317
334
  annotationid: annotationId,
318
335
  content: POI_PREVIEW_CONTENT_ID,
319
- position: 'right',
336
+ position: previewPosition,
320
337
  });
321
338
  }
322
339
  };