@barzhsieh/nuxt-content-mermaid 2.2.3 → 3.0.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.
Files changed (62) hide show
  1. package/README.md +47 -502
  2. package/README.zh-TW.md +46 -509
  3. package/dist/module.d.mts +39 -53
  4. package/dist/module.json +3 -3
  5. package/dist/module.mjs +600 -155
  6. package/dist/runtime/built-in-renderer/BuiltInRenderer.d.vue.ts +0 -0
  7. package/dist/runtime/built-in-renderer/BuiltInRenderer.vue +597 -0
  8. package/dist/runtime/built-in-renderer/BuiltInRenderer.vue.d.ts +0 -0
  9. package/dist/runtime/component-configuration-error.d.ts +3 -0
  10. package/dist/runtime/component-configuration-error.js +7 -0
  11. package/dist/runtime/component-configuration.d.ts +23 -0
  12. package/dist/runtime/component-configuration.js +78 -0
  13. package/dist/runtime/components/ContentMermaidTransport.d.vue.ts +10 -0
  14. package/dist/runtime/components/ContentMermaidTransport.vue +21 -0
  15. package/dist/runtime/components/ContentMermaidTransport.vue.d.ts +10 -0
  16. package/dist/runtime/components/Mermaid.d.vue.ts +0 -31
  17. package/dist/runtime/components/Mermaid.vue +136 -743
  18. package/dist/runtime/components/Mermaid.vue.d.ts +0 -31
  19. package/dist/runtime/components/MermaidExpandOverlay.d.vue.ts +13 -16
  20. package/dist/runtime/components/MermaidExpandOverlay.vue +61 -53
  21. package/dist/runtime/components/MermaidExpandOverlay.vue.d.ts +13 -16
  22. package/dist/runtime/components/MermaidFullscreenPresentation.d.vue.ts +18 -0
  23. package/dist/runtime/components/MermaidFullscreenPresentation.vue +56 -0
  24. package/dist/runtime/components/MermaidFullscreenPresentation.vue.d.ts +18 -0
  25. package/dist/runtime/composables/useMermaidExpand.d.ts +16 -32
  26. package/dist/runtime/composables/useMermaidExpand.js +232 -75
  27. package/dist/runtime/composables/useMermaidFullscreen.d.ts +18 -0
  28. package/dist/runtime/composables/useMermaidFullscreen.js +242 -0
  29. package/dist/runtime/composables/useMermaidZoom.d.ts +5 -1
  30. package/dist/runtime/composables/useMermaidZoom.js +54 -28
  31. package/dist/runtime/configuration/core.d.ts +27 -0
  32. package/dist/runtime/configuration/core.js +340 -0
  33. package/dist/runtime/configuration/module.d.ts +17 -0
  34. package/dist/runtime/configuration/module.js +233 -0
  35. package/dist/runtime/configuration/runtime-options.d.ts +4 -0
  36. package/dist/runtime/configuration/runtime-options.js +57 -0
  37. package/dist/runtime/constants.d.ts +24 -0
  38. package/dist/runtime/constants.js +60 -2
  39. package/dist/runtime/direct-mermaid-config.d.ts +5 -0
  40. package/dist/runtime/direct-mermaid-config.js +216 -0
  41. package/dist/runtime/mermaid-config.d.ts +9 -5
  42. package/dist/runtime/mermaid-config.js +30 -19
  43. package/dist/runtime/mermaid-rendering.d.ts +28 -0
  44. package/dist/runtime/mermaid-rendering.js +140 -0
  45. package/dist/runtime/plugins/content-mermaid-transport.d.ts +2 -0
  46. package/dist/runtime/plugins/content-mermaid-transport.js +5 -0
  47. package/dist/runtime/plugins/mermaid.client.d.ts +0 -3
  48. package/dist/runtime/plugins/mermaid.client.js +14 -32
  49. package/dist/runtime/plugins/runtime-config.d.ts +2 -0
  50. package/dist/runtime/plugins/runtime-config.js +9 -0
  51. package/dist/runtime/rendererSelection.d.ts +43 -0
  52. package/dist/runtime/rendererSelection.js +36 -0
  53. package/dist/runtime/rendererSelectionOrchestration.d.ts +12 -0
  54. package/dist/runtime/rendererSelectionOrchestration.js +13 -0
  55. package/dist/runtime/runtime-snapshot.d.ts +3 -0
  56. package/dist/runtime/runtime-snapshot.js +26 -0
  57. package/dist/runtime/utils/index.d.ts +0 -4
  58. package/dist/runtime/utils/index.js +0 -37
  59. package/dist/types.d.mts +2 -2
  60. package/package.json +38 -32
  61. package/dist/runtime/utils/mermaid-transform.d.ts +0 -18
  62. package/dist/runtime/utils/mermaid-transform.js +0 -345
@@ -6,6 +6,10 @@ const swipeToCloseThreshold = 10;
6
6
  export function useMermaidExpand(options) {
7
7
  const isClient = typeof import.meta.client === "boolean" ? import.meta.client : typeof window !== "undefined" && typeof document !== "undefined";
8
8
  const expandTargetWrap = ref(null);
9
+ const expandModal = ref(null);
10
+ const setExpandModal = (el) => {
11
+ expandModal.value = el && "nodeType" in el ? el : null;
12
+ };
9
13
  const setExpandTargetWrap = (el) => {
10
14
  if (el && "nodeType" in el) {
11
15
  expandTargetWrap.value = el;
@@ -26,26 +30,43 @@ export function useMermaidExpand(options) {
26
30
  minScale: 0.1,
27
31
  maxScale: 10
28
32
  });
29
- const isVisible = computed(() => expandState.value === "open");
30
- const allowTargetClick = options.invokeOpenOn?.diagramClick !== false;
31
- const allowCloseByEsc = options.invokeCloseOn?.esc !== false;
32
- const allowCloseByWheel = options.invokeCloseOn?.wheel !== false;
33
- const allowCloseBySwipe = options.invokeCloseOn?.swipe !== false;
33
+ const isVisible = computed(() => isExpanded.value);
34
+ const allowTargetClick = options.expandOptions.invokeOpenOn?.diagramClick !== false;
35
+ const allowCloseByEsc = options.expandOptions.invokeCloseOn?.esc !== false;
36
+ const allowCloseByWheel = options.expandOptions.invokeCloseOn?.wheel !== false;
37
+ const allowCloseBySwipe = options.expandOptions.invokeCloseOn?.swipe !== false;
38
+ const allowOverlayClose = options.expandOptions.invokeCloseOn?.overlayClick !== false;
39
+ const allowCloseButton = options.expandOptions.invokeCloseOn?.closeButtonClick !== false;
40
+ const shouldDisableTransition = computed(() => shouldRefreshExpand.value || zoom.isPointerDown.value);
41
+ const expandClipStyle = computed(() => {
42
+ const metrics = expandMetrics.value;
43
+ if (!metrics) return {};
44
+ const rect = isExpanded.value ? metrics.expandedClip : metrics.sourceClip;
45
+ return {
46
+ top: `${metrics.coordinatePlane.top}px`,
47
+ left: `${metrics.coordinatePlane.left}px`,
48
+ width: `${metrics.coordinatePlane.width}px`,
49
+ height: `${metrics.coordinatePlane.height}px`,
50
+ clipPath: toClipPath(rect, metrics.coordinatePlane),
51
+ transitionDuration: shouldDisableTransition.value ? "0ms" : void 0
52
+ };
53
+ });
34
54
  const expandTargetStyle = computed(() => {
35
55
  const metrics = expandMetrics.value;
36
56
  if (!metrics) return {};
37
57
  const { transform } = zoom.transformStyle.value;
38
58
  return {
39
- top: `${metrics.top}px`,
40
- left: `${metrics.left}px`,
41
- width: `${metrics.width}px`,
42
- height: `${metrics.height}px`,
59
+ top: `${metrics.sourceDiagram.top}px`,
60
+ left: `${metrics.sourceDiagram.left}px`,
61
+ width: `${metrics.sourceDiagram.width}px`,
62
+ height: `${metrics.sourceDiagram.height}px`,
43
63
  transform: isExpanded.value ? transform : "translate(0px, 0px) scale(1)",
44
- transitionDuration: shouldRefreshExpand.value || zoom.isPointerDown.value ? "0ms" : void 0
64
+ transitionDuration: shouldDisableTransition.value ? "0ms" : void 0
45
65
  };
46
66
  });
47
67
  let expandTransitionTimeout;
48
68
  let expandResizeTimeout;
69
+ let openingRaf;
49
70
  const resizeDoubleRaf = {
50
71
  raf1: void 0,
51
72
  raf2: void 0,
@@ -68,46 +89,67 @@ export function useMermaidExpand(options) {
68
89
  }
69
90
  };
70
91
  let expandRefreshRaf;
92
+ let hasDeferredResize = false;
71
93
  const resizeRefreshDelay = 180;
72
94
  const scrollState = {
73
95
  bodyOverflow: "",
74
96
  bodyWidth: "",
75
97
  htmlOverflow: "",
76
98
  htmlWidth: "",
77
- lockedWidth: false
99
+ scrollbarGutter: 0,
100
+ layoutWidth: 0,
101
+ lockedWidth: false,
102
+ locked: false
78
103
  };
79
104
  const touchState = {
80
105
  isScaling: false
81
106
  };
82
107
  let expandInstanceId = 0;
83
108
  function resolveExpandMargin() {
84
- const margin = options.expandMargin;
109
+ const margin = options.expandOptions.margin;
85
110
  if (typeof margin !== "number" || Number.isNaN(margin)) return 0;
86
111
  return Math.max(0, margin);
87
112
  }
88
- function getLayoutViewportSize() {
89
- const viewport = window.visualViewport;
90
- const scale = viewport?.scale ?? 1;
113
+ function getExpandCoordinateViewportSize() {
91
114
  return {
92
- width: (viewport?.width ?? window.innerWidth) * scale,
93
- height: (viewport?.height ?? window.innerHeight) * scale
115
+ width: scrollState.locked && scrollState.layoutWidth > 0 ? scrollState.layoutWidth : document.documentElement.clientWidth || window.innerWidth,
116
+ height: window.innerHeight
94
117
  };
95
118
  }
119
+ function intersectRects(...rects) {
120
+ const left = Math.max(...rects.map((rect) => rect.left));
121
+ const top = Math.max(...rects.map((rect) => rect.top));
122
+ const right = Math.min(...rects.map((rect) => rect.left + rect.width));
123
+ const bottom = Math.min(...rects.map((rect) => rect.top + rect.height));
124
+ if (right <= left || bottom <= top) return null;
125
+ return {
126
+ top,
127
+ left,
128
+ width: right - left,
129
+ height: bottom - top
130
+ };
131
+ }
132
+ function toClipPath(rect, plane) {
133
+ const top = Math.max(0, rect.top - plane.top);
134
+ const left = Math.max(0, rect.left - plane.left);
135
+ const right = Math.max(0, plane.width - left - rect.width);
136
+ const bottom = Math.max(0, plane.height - top - rect.height);
137
+ return `inset(${top}px ${right}px ${bottom}px ${left}px)`;
138
+ }
96
139
  function getLockedViewportWidth() {
97
140
  const width = document.documentElement.clientWidth || window.innerWidth;
98
141
  return Math.max(1, Math.round(width));
99
142
  }
100
- function shouldLockWidth() {
101
- return window.innerWidth - document.documentElement.clientWidth > 0;
102
- }
103
143
  function updateLockedWidth() {
104
144
  if (!scrollState.lockedWidth || document.body.style.overflow !== "hidden") return;
105
- document.documentElement.style.width = "";
106
- document.body.style.width = "";
107
- void document.body.offsetHeight;
108
- const clientWidth = getLockedViewportWidth();
109
- document.documentElement.style.width = `${clientWidth}px`;
110
- document.body.style.width = `${clientWidth}px`;
145
+ const width = window.innerWidth;
146
+ const height = window.innerHeight;
147
+ const needsVerticalScrollbar = document.documentElement.scrollHeight > height;
148
+ const gutter = needsVerticalScrollbar ? scrollState.scrollbarGutter : 0;
149
+ const layoutWidth = Math.max(1, Math.round(width - gutter));
150
+ scrollState.layoutWidth = layoutWidth;
151
+ document.documentElement.style.width = `${layoutWidth}px`;
152
+ document.body.style.width = `${layoutWidth}px`;
111
153
  }
112
154
  function clearResizeTimers() {
113
155
  clearTimeout(expandResizeTimeout);
@@ -118,24 +160,73 @@ export function useMermaidExpand(options) {
118
160
  if (expandRefreshRaf != null) cancelAnimationFrame(expandRefreshRaf);
119
161
  expandRefreshRaf = void 0;
120
162
  }
163
+ function clearOpeningRaf() {
164
+ if (openingRaf != null) cancelAnimationFrame(openingRaf);
165
+ openingRaf = void 0;
166
+ }
167
+ function resetSwipeState() {
168
+ touchState.isScaling = false;
169
+ touchState.start = void 0;
170
+ touchState.end = void 0;
171
+ }
172
+ function cancelPendingWork() {
173
+ clearTimeout(expandTransitionTimeout);
174
+ clearTimeout(hintTimeout);
175
+ expandTransitionTimeout = void 0;
176
+ hintTimeout = void 0;
177
+ clearResizeTimers();
178
+ clearRefreshRaf();
179
+ clearOpeningRaf();
180
+ showZoomHint.value = false;
181
+ resetSwipeState();
182
+ zoom.cancelInteraction();
183
+ }
121
184
  function calculateExpandMetrics(target) {
122
- const rect = target.getBoundingClientRect();
123
- if (!rect.width || !rect.height) return null;
185
+ const sourceRect = target.getBoundingClientRect();
186
+ if (!sourceRect.width || !sourceRect.height) return null;
187
+ const viewport = options.getExpandViewport();
188
+ if (!viewport) return null;
189
+ const viewportRect = viewport.getBoundingClientRect();
124
190
  const margin = resolveExpandMargin();
125
- const { width, height } = getLayoutViewportSize();
191
+ const { width, height } = getExpandCoordinateViewportSize();
192
+ const coordinatePlane = { top: 0, left: 0, width, height };
126
193
  const viewportWidth = Math.max(1, width - margin * 2);
127
194
  const viewportHeight = Math.max(1, height - margin * 2);
128
- const scaleX = viewportWidth / rect.width;
129
- const scaleY = viewportHeight / rect.height;
195
+ const sourceDiagram = {
196
+ top: sourceRect.top,
197
+ left: sourceRect.left,
198
+ width: sourceRect.width,
199
+ height: sourceRect.height
200
+ };
201
+ const sourceViewport = {
202
+ top: viewportRect.top + viewport.clientTop,
203
+ left: viewportRect.left + viewport.clientLeft,
204
+ width: viewport.clientWidth,
205
+ height: viewport.clientHeight
206
+ };
207
+ const sourceClip = intersectRects(
208
+ sourceDiagram,
209
+ sourceViewport,
210
+ coordinatePlane
211
+ );
212
+ if (!sourceClip) return null;
213
+ const expandedClip = {
214
+ top: margin,
215
+ left: margin,
216
+ width: viewportWidth,
217
+ height: viewportHeight
218
+ };
219
+ const scaleX = viewportWidth / sourceRect.width;
220
+ const scaleY = viewportHeight / sourceRect.height;
130
221
  const scale = Number.isFinite(scaleX) && Number.isFinite(scaleY) ? Math.min(scaleX, scaleY) : 1;
131
222
  const safeScale = scale > 0 ? scale : 1;
132
223
  return {
133
- top: rect.top,
134
- left: rect.left,
135
- width: rect.width,
136
- height: rect.height,
137
- translateX: width / 2 - (rect.left + rect.width * safeScale / 2),
138
- translateY: height / 2 - (rect.top + rect.height * safeScale / 2),
224
+ coordinatePlane,
225
+ sourceDiagram,
226
+ sourceClip,
227
+ expandedClip,
228
+ translateX: expandedClip.left + (expandedClip.width - sourceRect.width * safeScale) / 2 - sourceDiagram.left,
229
+ translateY: expandedClip.top + (expandedClip.height - sourceRect.height * safeScale) / 2 - sourceDiagram.top,
139
230
  scale: safeScale
140
231
  };
141
232
  }
@@ -200,14 +291,12 @@ export function useMermaidExpand(options) {
200
291
  }
201
292
  function resetExpand() {
202
293
  if (!isClient) return;
203
- clearTimeout(expandTransitionTimeout);
204
- clearTimeout(hintTimeout);
205
- clearResizeTimers();
206
- clearRefreshRaf();
294
+ cancelPendingWork();
207
295
  clearExpandSvg();
208
296
  expandState.value = "idle";
209
297
  isExpanded.value = false;
210
298
  shouldRefreshExpand.value = false;
299
+ hasDeferredResize = false;
211
300
  showZoomHint.value = false;
212
301
  expandMetrics.value = null;
213
302
  enableBodyScroll();
@@ -225,8 +314,8 @@ export function useMermaidExpand(options) {
225
314
  scale: metrics.scale,
226
315
  translateX: metrics.translateX,
227
316
  translateY: metrics.translateY,
228
- top: metrics.top,
229
- left: metrics.left
317
+ top: metrics.sourceDiagram.top,
318
+ left: metrics.sourceDiagram.left
230
319
  });
231
320
  expandState.value = "opening";
232
321
  isExpanded.value = false;
@@ -237,10 +326,17 @@ export function useMermaidExpand(options) {
237
326
  resetExpand();
238
327
  return;
239
328
  }
240
- requestAnimationFrame(() => {
241
- if (expandState.value !== "opening") return;
242
- isExpanded.value = true;
243
- expandState.value = "open";
329
+ openingRaf = requestAnimationFrame(() => {
330
+ if (expandState.value !== "opening") {
331
+ openingRaf = void 0;
332
+ return;
333
+ }
334
+ openingRaf = requestAnimationFrame(() => {
335
+ openingRaf = void 0;
336
+ if (expandState.value !== "opening") return;
337
+ isExpanded.value = true;
338
+ ensureExpandTransitionEnd();
339
+ });
244
340
  });
245
341
  });
246
342
  }
@@ -250,6 +346,8 @@ export function useMermaidExpand(options) {
250
346
  resetExpand();
251
347
  return;
252
348
  }
349
+ cancelPendingWork();
350
+ hasDeferredResize = false;
253
351
  expandState.value = "closing";
254
352
  isExpanded.value = false;
255
353
  ensureExpandTransitionEnd();
@@ -263,18 +361,30 @@ export function useMermaidExpand(options) {
263
361
  }
264
362
  function handleExpandTransitionEnd(event) {
265
363
  if (event.propertyName !== "transform") return;
266
- if (expandState.value === "closing") {
267
- resetExpand();
268
- }
364
+ if (expandState.value === "opening") finishOpening();
365
+ else if (expandState.value === "closing") resetExpand();
366
+ }
367
+ function finishOpening() {
368
+ if (expandState.value !== "opening") return;
369
+ clearTimeout(expandTransitionTimeout);
370
+ expandTransitionTimeout = void 0;
371
+ expandState.value = "open";
372
+ if (!hasDeferredResize) return;
373
+ hasDeferredResize = false;
374
+ scheduleExpandRefresh();
269
375
  }
270
376
  function ensureExpandTransitionEnd() {
271
377
  if (!expandTargetWrap.value) return;
272
378
  const duration = window.getComputedStyle(expandTargetWrap.value).transitionDuration;
273
379
  const durationMs = Number.parseFloat(duration) * (duration.endsWith("ms") ? 1 : 1e3);
274
- if (!durationMs) return;
380
+ if (!durationMs) {
381
+ if (expandState.value === "opening") finishOpening();
382
+ return;
383
+ }
275
384
  clearTimeout(expandTransitionTimeout);
276
385
  expandTransitionTimeout = setTimeout(() => {
277
- if (expandState.value === "closing") resetExpand();
386
+ if (expandState.value === "opening") finishOpening();
387
+ else if (expandState.value === "closing") resetExpand();
278
388
  }, durationMs + 50);
279
389
  }
280
390
  function handleExpandKeyDown(event) {
@@ -370,34 +480,41 @@ export function useMermaidExpand(options) {
370
480
  }
371
481
  function handleExpandTouchEnd() {
372
482
  if (!allowCloseBySwipe) return;
373
- touchState.isScaling = false;
374
- touchState.start = void 0;
375
- touchState.end = void 0;
483
+ resetSwipeState();
376
484
  }
377
485
  function handleExpandTouchCancel() {
378
486
  if (!allowCloseBySwipe) return;
379
- touchState.isScaling = false;
380
- touchState.start = void 0;
381
- touchState.end = void 0;
487
+ resetSwipeState();
382
488
  }
383
489
  function handleExpandResize() {
384
- if (!isExpandActive.value) return;
490
+ if (expandState.value === "opening") {
491
+ hasDeferredResize = true;
492
+ return;
493
+ }
494
+ if (expandState.value !== "open") return;
385
495
  scheduleExpandRefresh();
386
496
  }
497
+ function hasSameRect(left, right) {
498
+ return left.top === right.top && left.left === right.left && left.width === right.width && left.height === right.height;
499
+ }
500
+ function hasSameExpandMetrics(left, right) {
501
+ return hasSameRect(left.coordinatePlane, right.coordinatePlane) && hasSameRect(left.sourceDiagram, right.sourceDiagram) && hasSameRect(left.sourceClip, right.sourceClip) && hasSameRect(left.expandedClip, right.expandedClip) && left.translateX === right.translateX && left.translateY === right.translateY && left.scale === right.scale;
502
+ }
387
503
  function refreshExpandMetrics() {
388
- if (!isExpandActive.value) return;
504
+ if (expandState.value !== "open") return;
389
505
  updateLockedWidth();
390
506
  const svg = options.getExpandTarget();
391
507
  if (!svg) return;
392
508
  const metrics = calculateExpandMetrics(svg);
393
509
  if (!metrics) return;
510
+ if (expandMetrics.value && hasSameExpandMetrics(expandMetrics.value, metrics)) return;
394
511
  expandMetrics.value = metrics;
395
512
  zoom.init({
396
513
  scale: metrics.scale,
397
514
  translateX: metrics.translateX,
398
515
  translateY: metrics.translateY,
399
- top: metrics.top,
400
- left: metrics.left
516
+ top: metrics.sourceDiagram.top,
517
+ left: metrics.sourceDiagram.left
401
518
  });
402
519
  shouldRefreshExpand.value = true;
403
520
  clearRefreshRaf();
@@ -417,6 +534,8 @@ export function useMermaidExpand(options) {
417
534
  const activeWindow = computed(() => isExpandActive.value ? window : null);
418
535
  const activeDocument = computed(() => isExpandActive.value ? document : null);
419
536
  const activeVisualViewport = computed(() => isExpandActive.value ? window.visualViewport : null);
537
+ const activeModal = computed(() => isExpandActive.value ? expandModal.value : null);
538
+ const activeTarget = computed(() => isExpandActive.value ? expandTargetWrap.value : null);
420
539
  useEventListener(activeWindow, "resize", handleExpandResize, { passive: true });
421
540
  useEventListener(activeWindow, "orientationchange", handleExpandResize, { passive: true });
422
541
  useEventListener(activeVisualViewport, "resize", handleExpandResize, { passive: true });
@@ -426,22 +545,35 @@ export function useMermaidExpand(options) {
426
545
  useEventListener(activeWindow, "touchend", handleExpandTouchEnd, { passive: true });
427
546
  useEventListener(activeWindow, "touchcancel", handleExpandTouchCancel, { passive: true });
428
547
  useEventListener(activeDocument, "keydown", handleExpandKeyDown, true);
548
+ useEventListener(activeModal, "click", handleModalClick);
549
+ useEventListener(activeModal, "mousedown", zoom.handleDragStart);
550
+ useEventListener(activeModal, "mousemove", zoom.handleDragMove);
551
+ useEventListener(activeModal, "touchstart", zoom.handleDragStart);
552
+ useEventListener(activeModal, "touchmove", zoom.handleDragMove);
553
+ useEventListener(activeModal, "touchend", zoom.handleDragEnd);
554
+ useEventListener(activeTarget, "transitionend", handleExpandTransitionEnd);
429
555
  }
430
556
  function disableBodyScroll() {
557
+ if (scrollState.locked) return;
431
558
  scrollState.bodyOverflow = document.body.style.overflow;
432
559
  scrollState.bodyWidth = document.body.style.width;
433
560
  scrollState.htmlOverflow = document.documentElement.style.overflow;
434
561
  scrollState.htmlWidth = document.documentElement.style.width;
435
- scrollState.lockedWidth = shouldLockWidth();
436
- document.documentElement.style.overflow = "hidden";
437
- document.body.style.overflow = "hidden";
562
+ const layoutWidth = getLockedViewportWidth();
563
+ const viewportWidth = window.innerWidth;
564
+ scrollState.layoutWidth = layoutWidth;
565
+ scrollState.scrollbarGutter = Math.max(0, Math.round(viewportWidth - layoutWidth));
566
+ scrollState.lockedWidth = scrollState.scrollbarGutter > 0;
567
+ scrollState.locked = true;
438
568
  if (scrollState.lockedWidth) {
439
- const clientWidth = getLockedViewportWidth();
440
- document.documentElement.style.width = `${clientWidth}px`;
441
- document.body.style.width = `${clientWidth}px`;
569
+ document.documentElement.style.width = `${layoutWidth}px`;
570
+ document.body.style.width = `${layoutWidth}px`;
442
571
  }
572
+ document.documentElement.style.overflow = "hidden";
573
+ document.body.style.overflow = "hidden";
443
574
  }
444
575
  function enableBodyScroll() {
576
+ if (!scrollState.locked) return;
445
577
  document.documentElement.style.width = scrollState.htmlWidth;
446
578
  document.documentElement.style.overflow = scrollState.htmlOverflow;
447
579
  scrollState.htmlOverflow = "";
@@ -450,7 +582,10 @@ export function useMermaidExpand(options) {
450
582
  document.body.style.overflow = scrollState.bodyOverflow;
451
583
  scrollState.bodyOverflow = "";
452
584
  scrollState.bodyWidth = "";
585
+ scrollState.scrollbarGutter = 0;
586
+ scrollState.layoutWidth = 0;
453
587
  scrollState.lockedWidth = false;
588
+ scrollState.locked = false;
454
589
  }
455
590
  function handleMermaidClick(event) {
456
591
  if (!allowTargetClick) return;
@@ -460,21 +595,43 @@ export function useMermaidExpand(options) {
460
595
  if (!svg.contains(event.target)) return;
461
596
  openExpand(event);
462
597
  }
598
+ function handleModalClick(event) {
599
+ if (zoom.isSpacePressed.value) return;
600
+ if (zoom.wasLastInteractionDrag.value) {
601
+ event.stopPropagation();
602
+ return;
603
+ }
604
+ const target = event.target;
605
+ if (!target.classList?.contains("ncm-expand-overlay") && !target.classList?.contains("ncm-expand-modal")) return;
606
+ if (allowOverlayClose) closeExpand(event);
607
+ }
608
+ function closeFromButton(event) {
609
+ if (allowCloseButton) closeExpand(event);
610
+ }
611
+ function endForDiagramReplacement() {
612
+ if (isExpandActive.value) resetExpand();
613
+ }
463
614
  tryOnScopeDispose(() => {
464
615
  if (isClient) resetExpand();
465
616
  });
466
617
  return {
618
+ setExpandModal,
467
619
  setExpandTargetWrap,
620
+ expandClipStyle,
468
621
  expandTargetStyle,
469
622
  isExpandActive,
470
623
  isVisible,
471
- openExpand,
472
- closeExpand,
473
- toggleExpand,
474
- handleExpandTransitionEnd,
475
- handleMermaidClick,
476
- resetExpand,
477
- zoom,
624
+ toggle: toggleExpand,
625
+ openFromDiagram: handleMermaidClick,
626
+ endForDiagramReplacement,
627
+ closeFromButton,
628
+ zoomIn: zoom.zoomIn,
629
+ zoomOut: zoom.zoomOut,
630
+ resetZoom: zoom.reset,
631
+ cursor: computed(() => zoom.cursor.value),
632
+ isDragging: computed(() => zoom.isDragging.value),
633
+ scale: computed(() => zoom.scale.value),
634
+ isOverlayClosable: computed(() => allowOverlayClose && !zoom.isSpacePressed.value),
478
635
  showZoomHint
479
636
  };
480
637
  }
@@ -0,0 +1,18 @@
1
+ import type { ConfigurableDocument, ConfigurableWindow } from './_configurable.js';
2
+ interface UseMermaidFullscreenOptions extends ConfigurableDocument, ConfigurableWindow {
3
+ getFullscreenTarget: () => HTMLElement | null;
4
+ getViewportTarget: () => HTMLElement | null;
5
+ getRenderTarget: () => HTMLElement | null;
6
+ }
7
+ export declare function useMermaidFullscreen(options: UseMermaidFullscreenOptions): {
8
+ isSupported: import("vue").ComputedRef<boolean>;
9
+ isActive: import("vue").ShallowRef<boolean, boolean>;
10
+ scale: import("vue").ComputedRef<number>;
11
+ showZoomHint: import("vue").Ref<boolean, boolean>;
12
+ toggle: () => Promise<void>;
13
+ endForDiagramReplacement: () => Promise<void>;
14
+ zoomIn: () => void;
15
+ zoomOut: () => void;
16
+ resetZoom: () => void;
17
+ };
18
+ export {};