@san-siva/blogkit 1.1.35 → 1.1.37

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 (56) hide show
  1. package/dist/assets/collapse.svg +16 -0
  2. package/dist/assets/expand.svg +4 -0
  3. package/dist/assets/reset.svg +4 -0
  4. package/dist/assets/zoom-in.svg +17 -0
  5. package/dist/assets/zoom-out.svg +17 -0
  6. package/dist/cjs/components/MermaidControls.js +17 -0
  7. package/dist/cjs/components/MermaidControls.js.map +1 -0
  8. package/dist/cjs/components/MermaidViewport.js +33 -0
  9. package/dist/cjs/components/MermaidViewport.js.map +1 -0
  10. package/dist/cjs/dynamicComponents/CodeBlockDynamic.js +28 -7
  11. package/dist/cjs/dynamicComponents/CodeBlockDynamic.js.map +1 -1
  12. package/dist/cjs/dynamicComponents/MermaidDynamic.js +52 -75
  13. package/dist/cjs/dynamicComponents/MermaidDynamic.js.map +1 -1
  14. package/dist/cjs/hooks/usePanZoom.js +92 -0
  15. package/dist/cjs/hooks/usePanZoom.js.map +1 -0
  16. package/dist/cjs/index.css +1 -1
  17. package/dist/cjs/index.css.map +1 -1
  18. package/dist/cjs/styles/CodeBlock.module.scss.js +1 -1
  19. package/dist/cjs/styles/Mermaid.module.scss.js +1 -1
  20. package/dist/esm/components/MermaidControls.js +13 -0
  21. package/dist/esm/components/MermaidControls.js.map +1 -0
  22. package/dist/esm/components/MermaidViewport.js +29 -0
  23. package/dist/esm/components/MermaidViewport.js.map +1 -0
  24. package/dist/esm/dynamicComponents/CodeBlockDynamic.js +29 -8
  25. package/dist/esm/dynamicComponents/CodeBlockDynamic.js.map +1 -1
  26. package/dist/esm/dynamicComponents/MermaidDynamic.js +52 -75
  27. package/dist/esm/dynamicComponents/MermaidDynamic.js.map +1 -1
  28. package/dist/esm/hooks/usePanZoom.js +90 -0
  29. package/dist/esm/hooks/usePanZoom.js.map +1 -0
  30. package/dist/esm/index.css +1 -1
  31. package/dist/esm/index.css.map +1 -1
  32. package/dist/esm/styles/CodeBlock.module.scss.js +1 -1
  33. package/dist/esm/styles/Mermaid.module.scss.js +1 -1
  34. package/dist/types/components/MermaidControls.d.ts +11 -0
  35. package/dist/types/components/MermaidControls.d.ts.map +1 -0
  36. package/dist/types/components/MermaidViewport.d.ts +12 -0
  37. package/dist/types/components/MermaidViewport.d.ts.map +1 -0
  38. package/dist/types/dynamicComponents/CodeBlockDynamic.d.ts.map +1 -1
  39. package/dist/types/dynamicComponents/MermaidDynamic.d.ts.map +1 -1
  40. package/dist/types/hooks/usePanZoom.d.ts +24 -0
  41. package/dist/types/hooks/usePanZoom.d.ts.map +1 -0
  42. package/package.json +1 -1
  43. package/src/assets/collapse.svg +16 -0
  44. package/src/assets/expand.svg +4 -0
  45. package/src/assets/reset.svg +4 -0
  46. package/src/assets/zoom-in.svg +17 -0
  47. package/src/assets/zoom-out.svg +17 -0
  48. package/src/components/MermaidControls.tsx +54 -0
  49. package/src/components/MermaidViewport.tsx +61 -0
  50. package/src/dynamicComponents/CodeBlockDynamic.tsx +83 -25
  51. package/src/dynamicComponents/MermaidDynamic.tsx +101 -131
  52. package/src/hooks/usePanZoom.ts +126 -0
  53. package/src/styles/CodeBlock.module.scss +98 -0
  54. package/src/styles/CodeBlock.module.scss.d.ts +6 -0
  55. package/src/styles/Mermaid.module.scss +72 -4
  56. package/src/styles/Mermaid.module.scss.d.ts +10 -0
@@ -1,9 +1,13 @@
1
1
  'use client';
2
2
 
3
3
  import { useCallback, useEffect, useRef, useState } from 'react';
4
+ import { createPortal } from 'react-dom';
4
5
 
5
6
  import mermaid from 'mermaid';
6
7
 
8
+ import MermaidControls from '../components/MermaidControls';
9
+ import MermaidViewport from '../components/MermaidViewport';
10
+ import { usePanZoom } from '../hooks/usePanZoom';
7
11
  import CalloutStatic from '../staticComponents/CalloutStatic';
8
12
  import styles from '../styles/Mermaid.module.scss';
9
13
 
@@ -31,10 +35,6 @@ mermaid.initialize({
31
35
  },
32
36
  });
33
37
 
34
- const MIN_SCALE = 0.5;
35
- const MAX_SCALE = 4;
36
- const ZOOM_STEP = 0.15;
37
-
38
38
  const Mermaid = ({
39
39
  code = '',
40
40
  id = '',
@@ -43,109 +43,69 @@ const Mermaid = ({
43
43
  }: MermaidProperties) => {
44
44
  const [enabled, setEnabled] = useState(false);
45
45
  const [error, setError] = useState<string | null>(null);
46
- const [transform, setTransform] = useState({ scale: 1, x: 0, y: 0 });
47
- const [isDragging, setIsDragging] = useState(false);
46
+ const [isExpanded, setIsExpanded] = useState(false);
48
47
 
49
48
  const mermaidReference = useRef<HTMLDivElement>(null);
50
- const viewportRef = useRef<HTMLDivElement>(null);
49
+ const modalMermaidReference = useRef<HTMLDivElement>(null);
51
50
  const renderCount = useRef(0);
52
- const transformRef = useRef({ scale: 1, x: 0, y: 0 });
53
- const isDraggingRef = useRef(false);
54
- const dragStart = useRef({
55
- mouseX: 0,
56
- mouseY: 0,
57
- transformX: 0,
58
- transformY: 0,
59
- });
60
51
 
61
- const applyTransform = useCallback(
62
- (
63
- updater: (
64
- prev: typeof transformRef.current
65
- ) => typeof transformRef.current
66
- ) => {
67
- const next = updater(transformRef.current);
68
- transformRef.current = next;
69
- setTransform(next);
52
+ const inline = usePanZoom();
53
+ const modal = usePanZoom();
54
+
55
+ const renderInto = useCallback(
56
+ async (target: HTMLDivElement | null, prefix: string) => {
57
+ if (!target || !code) return false;
58
+ const renderId = `${prefix}-${id}-${++renderCount.current}`;
59
+ try {
60
+ const { svg, bindFunctions } = await mermaid.render(renderId, code);
61
+ if (!svg) return false;
62
+ target.innerHTML = svg;
63
+ bindFunctions?.(target);
64
+ return true;
65
+ } catch (err) {
66
+ const message =
67
+ err instanceof Error ? err.message : 'Failed to render diagram';
68
+ setError(message);
69
+ return false;
70
+ }
70
71
  },
71
- []
72
+ [code, id]
72
73
  );
73
74
 
74
- const initializeMermaid = useCallback(async () => {
75
- if (!mermaidReference.current || !code) return;
76
- const renderId = `mermaid-diagram-${id}-${++renderCount.current}`;
77
- document.getElementById(renderId)?.remove();
78
- try {
79
- const { svg, bindFunctions } = await mermaid.render(renderId, code);
80
- if (!mermaidReference.current || !svg) return;
81
- mermaidReference.current.innerHTML = svg;
82
- bindFunctions?.(mermaidReference.current);
83
- setEnabled(true);
84
- } catch (err) {
85
- const message =
86
- err instanceof Error ? err.message : 'Failed to render diagram';
87
- setError(message);
88
- }
89
- }, [code, id]);
90
-
91
75
  useEffect(() => {
92
76
  if (!code) return;
93
77
  setError(null);
94
- applyTransform(() => ({ scale: 1, x: 0, y: 0 }));
95
- const timer = setTimeout(initializeMermaid, 100);
78
+ inline.reset();
79
+ const timer = setTimeout(() => {
80
+ renderInto(mermaidReference.current, 'mermaid-diagram').then(ok => {
81
+ if (ok) setEnabled(true);
82
+ });
83
+ }, 100);
96
84
  return () => clearTimeout(timer);
97
- }, [code, initializeMermaid, applyTransform]);
98
-
85
+ }, [code, renderInto, inline.reset]);
99
86
 
87
+ useEffect(() => {
88
+ if (!isExpanded) return;
89
+ modal.reset();
90
+ const timer = setTimeout(() => {
91
+ renderInto(modalMermaidReference.current, 'mermaid-modal');
92
+ }, 0);
93
+ return () => clearTimeout(timer);
94
+ }, [isExpanded, renderInto, modal.reset]);
100
95
 
101
- const handleMouseDown = useCallback((e: React.MouseEvent) => {
102
- e.preventDefault();
103
- isDraggingRef.current = true;
104
- setIsDragging(true);
105
- dragStart.current = {
106
- mouseX: e.clientX,
107
- mouseY: e.clientY,
108
- transformX: transformRef.current.x,
109
- transformY: transformRef.current.y,
96
+ useEffect(() => {
97
+ if (!isExpanded) return;
98
+ const onKey = (e: KeyboardEvent) => {
99
+ if (e.key === 'Escape') setIsExpanded(false);
110
100
  };
111
- }, []);
112
-
113
- const handleMouseMove = useCallback(
114
- (e: React.MouseEvent) => {
115
- if (!isDraggingRef.current) return;
116
- applyTransform(prev => ({
117
- ...prev,
118
- x:
119
- dragStart.current.transformX + (e.clientX - dragStart.current.mouseX),
120
- y:
121
- dragStart.current.transformY + (e.clientY - dragStart.current.mouseY),
122
- }));
123
- },
124
- [applyTransform]
125
- );
126
-
127
- const handleMouseUp = useCallback(() => {
128
- isDraggingRef.current = false;
129
- setIsDragging(false);
130
- }, []);
131
-
132
- const zoomIn = useCallback(() => {
133
- applyTransform(prev => ({
134
- ...prev,
135
- scale: Math.min(prev.scale * (1 + ZOOM_STEP), MAX_SCALE),
136
- }));
137
- }, [applyTransform]);
138
-
139
- const zoomOut = useCallback(() => {
140
- applyTransform(prev => ({
141
- ...prev,
142
- scale: Math.max(prev.scale * (1 - ZOOM_STEP), MIN_SCALE),
143
- }));
144
- }, [applyTransform]);
145
-
146
- const resetView = useCallback(() => {
147
- applyTransform(() => ({ scale: 1, x: 0, y: 0 }));
148
- }, [applyTransform]);
101
+ const previousOverflow = document.body.style.overflow;
102
+ document.body.style.overflow = 'hidden';
103
+ window.addEventListener('keydown', onKey);
104
+ return () => {
105
+ document.body.style.overflow = previousOverflow;
106
+ window.removeEventListener('keydown', onKey);
107
+ };
108
+ }, [isExpanded]);
149
109
 
150
110
  return (
151
111
  <div
@@ -164,45 +124,55 @@ const Mermaid = ({
164
124
  <p>Rendering diagram...</p>
165
125
  </CalloutStatic>
166
126
  ) : (
167
- <div className={styles['mermaid__controls']}>
168
- <button className={styles['mermaid__controls__btn']} onClick={zoomIn}>
169
- +
170
- </button>
171
- <button
172
- className={styles['mermaid__controls__btn']}
173
- onClick={zoomOut}
174
- >
175
-
176
- </button>
177
- <button
178
- className={styles['mermaid__controls__btn']}
179
- onClick={resetView}
180
- >
181
- Reset
182
- </button>
183
- </div>
127
+ <MermaidControls
128
+ className={styles['mermaid__controls']}
129
+ isExpanded={false}
130
+ onZoomIn={inline.zoomIn}
131
+ onZoomOut={inline.zoomOut}
132
+ onReset={inline.reset}
133
+ onToggleExpand={() => setIsExpanded(true)}
134
+ />
184
135
  )}
185
- <div
186
- ref={viewportRef}
187
- className={`${styles['mermaid__viewport']} ${
188
- isDragging ? styles['mermaid__viewport--dragging'] : ''
189
- }`}
190
- style={enabled ? undefined : { display: 'none' }}
191
- onMouseDown={handleMouseDown}
192
- onMouseMove={handleMouseMove}
193
- onMouseUp={handleMouseUp}
194
- onMouseLeave={handleMouseUp}
195
- >
196
- <div
197
- style={{
198
- transform: `translate(${transform.x}px, ${transform.y}px) scale(${transform.scale})`,
199
- transformOrigin: '0 0',
200
- transition: isDragging ? 'none' : 'transform 0.1s ease',
201
- }}
202
- >
203
- <div ref={mermaidReference} id={id} />
204
- </div>
205
- </div>
136
+ <MermaidViewport
137
+ className={styles['mermaid__viewport']}
138
+ draggingClassName={styles['mermaid__viewport--dragging']}
139
+ pan={inline}
140
+ contentRef={mermaidReference}
141
+ contentId={id}
142
+ hidden={!enabled}
143
+ />
144
+
145
+ {isExpanded &&
146
+ typeof document !== 'undefined' &&
147
+ createPortal(
148
+ <div
149
+ className={styles['mermaid__modal']}
150
+ onClick={() => setIsExpanded(false)}
151
+ role="dialog"
152
+ aria-modal="true"
153
+ >
154
+ <div
155
+ className={styles['mermaid__modal__content']}
156
+ onClick={e => e.stopPropagation()}
157
+ >
158
+ <MermaidControls
159
+ className={styles['mermaid__modal__controls']}
160
+ isExpanded={true}
161
+ onZoomIn={modal.zoomIn}
162
+ onZoomOut={modal.zoomOut}
163
+ onReset={modal.reset}
164
+ onToggleExpand={() => setIsExpanded(false)}
165
+ />
166
+ <MermaidViewport
167
+ className={styles['mermaid__modal__viewport']}
168
+ draggingClassName={styles['mermaid__modal__viewport--dragging']}
169
+ pan={modal}
170
+ contentRef={modalMermaidReference}
171
+ />
172
+ </div>
173
+ </div>,
174
+ document.body
175
+ )}
206
176
  </div>
207
177
  );
208
178
  };
@@ -0,0 +1,126 @@
1
+ import { useCallback, useRef, useState } from 'react';
2
+
3
+ export interface Transform {
4
+ scale: number;
5
+ x: number;
6
+ y: number;
7
+ }
8
+
9
+ export interface UsePanZoomOptions {
10
+ initialTransform?: Transform;
11
+ minScale?: number;
12
+ maxScale?: number;
13
+ zoomStep?: number;
14
+ }
15
+
16
+ const DEFAULT_INITIAL_TRANSFORM: Transform = { scale: 1, x: 0, y: 0 };
17
+ const DEFAULT_MIN_SCALE = 0.5;
18
+ const DEFAULT_MAX_SCALE = 4;
19
+ const DEFAULT_ZOOM_STEP = 0.15;
20
+
21
+ export const usePanZoom = ({
22
+ initialTransform = DEFAULT_INITIAL_TRANSFORM,
23
+ minScale = DEFAULT_MIN_SCALE,
24
+ maxScale = DEFAULT_MAX_SCALE,
25
+ zoomStep = DEFAULT_ZOOM_STEP,
26
+ }: UsePanZoomOptions = {}) => {
27
+ const [transform, setTransform] = useState<Transform>(initialTransform);
28
+ const [isDragging, setIsDragging] = useState(false);
29
+ const transformRef = useRef<Transform>(initialTransform);
30
+ const isDraggingRef = useRef(false);
31
+ const dragStart = useRef({
32
+ mouseX: 0,
33
+ mouseY: 0,
34
+ transformX: 0,
35
+ transformY: 0,
36
+ });
37
+
38
+ const apply = useCallback((updater: (prev: Transform) => Transform) => {
39
+ const next = updater(transformRef.current);
40
+ transformRef.current = next;
41
+ setTransform(next);
42
+ }, []);
43
+
44
+ const onMouseDown = useCallback((e: React.MouseEvent) => {
45
+ e.preventDefault();
46
+ isDraggingRef.current = true;
47
+ setIsDragging(true);
48
+ dragStart.current = {
49
+ mouseX: e.clientX,
50
+ mouseY: e.clientY,
51
+ transformX: transformRef.current.x,
52
+ transformY: transformRef.current.y,
53
+ };
54
+ }, []);
55
+
56
+ const onMouseMove = useCallback(
57
+ (e: React.MouseEvent) => {
58
+ if (!isDraggingRef.current) return;
59
+ apply(prev => ({
60
+ ...prev,
61
+ x:
62
+ dragStart.current.transformX + (e.clientX - dragStart.current.mouseX),
63
+ y:
64
+ dragStart.current.transformY + (e.clientY - dragStart.current.mouseY),
65
+ }));
66
+ },
67
+ [apply]
68
+ );
69
+
70
+ const onMouseUp = useCallback(() => {
71
+ isDraggingRef.current = false;
72
+ setIsDragging(false);
73
+ }, []);
74
+
75
+ const zoomIn = useCallback(() => {
76
+ apply(prev => ({
77
+ ...prev,
78
+ scale: Math.min(prev.scale * (1 + zoomStep), maxScale),
79
+ }));
80
+ }, [apply, zoomStep, maxScale]);
81
+
82
+ const zoomOut = useCallback(() => {
83
+ apply(prev => ({
84
+ ...prev,
85
+ scale: Math.max(prev.scale * (1 - zoomStep), minScale),
86
+ }));
87
+ }, [apply, zoomStep, minScale]);
88
+
89
+ const zoomAtPoint = useCallback(
90
+ (deltaY: number, pointX: number, pointY: number) => {
91
+ apply(prev => {
92
+ const factor = deltaY < 0 ? 1 + zoomStep : 1 - zoomStep;
93
+ const newScale = Math.max(
94
+ minScale,
95
+ Math.min(maxScale, prev.scale * factor)
96
+ );
97
+ if (newScale === prev.scale) return prev;
98
+ const ratio = newScale / prev.scale;
99
+ return {
100
+ scale: newScale,
101
+ x: pointX - (pointX - prev.x) * ratio,
102
+ y: pointY - (pointY - prev.y) * ratio,
103
+ };
104
+ });
105
+ },
106
+ [apply, zoomStep, minScale, maxScale]
107
+ );
108
+
109
+ const reset = useCallback(() => {
110
+ apply(() => initialTransform);
111
+ }, [apply, initialTransform]);
112
+
113
+ return {
114
+ transform,
115
+ isDragging,
116
+ onMouseDown,
117
+ onMouseMove,
118
+ onMouseUp,
119
+ zoomIn,
120
+ zoomOut,
121
+ zoomAtPoint,
122
+ reset,
123
+ };
124
+ };
125
+
126
+ export type PanZoom = ReturnType<typeof usePanZoom>;
@@ -85,6 +85,41 @@ $code-block-background-color: #282a36;
85
85
  color: stylekit.$color--code;
86
86
  }
87
87
 
88
+ &__actions {
89
+ display: flex;
90
+ flex-direction: row;
91
+ align-items: center;
92
+ gap: stylekit.rem(4);
93
+ }
94
+
95
+ &__expand {
96
+ position: relative;
97
+ height: stylekit.rem(32);
98
+ width: stylekit.rem(32);
99
+ cursor: pointer;
100
+ transition: all 0.2s ease-in-out;
101
+
102
+ &::before {
103
+ content: '';
104
+ position: absolute;
105
+ inset: 0;
106
+ background-image: url('../assets/expand.svg');
107
+ background-size: stylekit.rem(14) stylekit.rem(14);
108
+ background-position: center;
109
+ background-repeat: no-repeat;
110
+ filter: invert(1);
111
+ }
112
+
113
+ &:hover {
114
+ background-color: stylekit.$color--grey-dark;
115
+ border-radius: 100%;
116
+ }
117
+
118
+ &--collapse::before {
119
+ background-image: url('../assets/collapse.svg');
120
+ }
121
+ }
122
+
88
123
  &__copy {
89
124
  height: stylekit.rem(32);
90
125
  width: stylekit.rem(32);
@@ -106,6 +141,69 @@ $code-block-background-color: #282a36;
106
141
  }
107
142
  }
108
143
  }
144
+
145
+ &__modal {
146
+ position: fixed;
147
+ inset: 0;
148
+ z-index: 9999;
149
+ background-color: rgba(0, 0, 0, 0.7);
150
+ display: flex;
151
+ align-items: stretch;
152
+ justify-content: stretch;
153
+
154
+ &__content {
155
+ background-color: $code-block-background-color;
156
+ width: 100%;
157
+ height: 100%;
158
+ display: flex;
159
+ flex-direction: column;
160
+ position: relative;
161
+ }
162
+
163
+ &__wrapper {
164
+ flex: 1;
165
+ font-family: stylekit.$font-family--code;
166
+ overflow: auto;
167
+
168
+ scrollbar-width: thin;
169
+ scrollbar-color: stylekit.$color--grey-dark $code-block-background-color;
170
+
171
+ &::-webkit-scrollbar {
172
+ height: 8px;
173
+ width: 8px;
174
+ }
175
+
176
+ &::-webkit-scrollbar-track {
177
+ background: $code-block-background-color;
178
+ }
179
+
180
+ &::-webkit-scrollbar-thumb {
181
+ background-color: stylekit.$color--grey-dark;
182
+ border-radius: 4px;
183
+ }
184
+
185
+ padding: stylekit.rem(18);
186
+ tab-size: 2;
187
+
188
+ > pre {
189
+ margin: 0;
190
+ padding: 0 !important;
191
+ width: max-content;
192
+ min-width: 100%;
193
+
194
+ > code,
195
+ > code > * {
196
+ font-family: stylekit.$font-family--code;
197
+ font-size: stylekit.$font-size--small;
198
+ font-weight: unset;
199
+ font-style: unset;
200
+ line-height: stylekit.$line-height--normal;
201
+ color: unset;
202
+ text-align: left !important;
203
+ }
204
+ }
205
+ }
206
+ }
109
207
  }
110
208
 
111
209
  .margin-top--1 {
@@ -5,8 +5,14 @@ declare const styles: {
5
5
  readonly 'code-block__wrapper': string;
6
6
  readonly 'code-block__header': string;
7
7
  readonly 'code-block__header__title': string;
8
+ readonly 'code-block__header__actions': string;
9
+ readonly 'code-block__header__expand': string;
10
+ readonly 'code-block__header__expand--collapse': string;
8
11
  readonly 'code-block__header__copy': string;
9
12
  readonly 'code-block__header__copy--active': string;
13
+ readonly 'code-block__modal': string;
14
+ readonly 'code-block__modal__content': string;
15
+ readonly 'code-block__modal__wrapper': string;
10
16
  readonly 'code-block--static': string;
11
17
  readonly 'margin-top--1': string;
12
18
  readonly 'margin-bottom--2': string;
@@ -16,19 +16,45 @@
16
16
  opacity: 0;
17
17
 
18
18
  &__btn {
19
+ align-items: center;
19
20
  background: none;
21
+ background-position: center;
22
+ background-repeat: no-repeat;
23
+ background-size: styles.rem(14) styles.rem(14);
20
24
  border: 1px solid styles.$color--grey-medium;
25
+ border-radius: styles.rem(2);
21
26
  color: styles.$color--dark;
22
27
  cursor: pointer;
23
- font-size: styles.$font-size--very-small;
24
- font-weight: styles.$font-weight--500;
28
+ display: inline-flex;
29
+ height: styles.rem(28);
30
+ justify-content: center;
25
31
  line-height: 1;
26
- padding: styles.rem(4) styles.rem(8);
27
- border-radius: styles.rem(2);
32
+ padding: 0;
33
+ width: styles.rem(28);
28
34
 
29
35
  &:hover {
30
36
  background-color: rgba(0, 0, 0, 0.05);
31
37
  }
38
+
39
+ &--zoom-in {
40
+ background-image: url('../assets/zoom-in.svg');
41
+ }
42
+
43
+ &--zoom-out {
44
+ background-image: url('../assets/zoom-out.svg');
45
+ }
46
+
47
+ &--reset {
48
+ background-image: url('../assets/reset.svg');
49
+ }
50
+
51
+ &--expand {
52
+ background-image: url('../assets/expand.svg');
53
+ }
54
+
55
+ &--collapse {
56
+ background-image: url('../assets/collapse.svg');
57
+ }
32
58
  }
33
59
  }
34
60
 
@@ -43,6 +69,48 @@
43
69
  }
44
70
  }
45
71
 
72
+ &__modal {
73
+ position: fixed;
74
+ inset: 0;
75
+ z-index: 9999;
76
+ background-color: rgba(0, 0, 0, 0.7);
77
+ display: flex;
78
+ align-items: stretch;
79
+ justify-content: stretch;
80
+
81
+ &__content {
82
+ background-color: styles.$color--base;
83
+ width: 100%;
84
+ height: 100%;
85
+ display: flex;
86
+ flex-direction: column;
87
+ position: relative;
88
+ }
89
+
90
+ &__controls {
91
+ display: flex;
92
+ flex-direction: row;
93
+ gap: styles.rem(8);
94
+ justify-content: flex-end;
95
+ padding: styles.rem(12) styles.rem(16);
96
+ border-bottom: 1px solid styles.$color--grey-light;
97
+ flex-shrink: 0;
98
+ }
99
+
100
+ &__viewport {
101
+ flex: 1;
102
+ overflow: hidden;
103
+ cursor: grab;
104
+ user-select: none;
105
+ -webkit-user-select: none;
106
+ padding: styles.rem(16);
107
+
108
+ &--dragging {
109
+ cursor: grabbing;
110
+ }
111
+ }
112
+ }
113
+
46
114
  &:hover {
47
115
  .mermaid__controls {
48
116
  opacity: 1;
@@ -2,8 +2,18 @@ declare const styles: {
2
2
  readonly mermaid: string;
3
3
  readonly 'mermaid__controls': string;
4
4
  readonly 'mermaid__controls__btn': string;
5
+ readonly 'mermaid__controls__btn--zoom-in': string;
6
+ readonly 'mermaid__controls__btn--zoom-out': string;
7
+ readonly 'mermaid__controls__btn--reset': string;
8
+ readonly 'mermaid__controls__btn--expand': string;
9
+ readonly 'mermaid__controls__btn--collapse': string;
5
10
  readonly 'mermaid__viewport': string;
6
11
  readonly 'mermaid__viewport--dragging': string;
12
+ readonly 'mermaid__modal': string;
13
+ readonly 'mermaid__modal__content': string;
14
+ readonly 'mermaid__modal__controls': string;
15
+ readonly 'mermaid__modal__viewport': string;
16
+ readonly 'mermaid__modal__viewport--dragging': string;
7
17
  readonly 'margin-top--1': string;
8
18
  readonly 'margin-bottom--2': string;
9
19
  };