Skip to content

Commit 8412032

Browse files
Add zoom controls to Mermaid charts (#10586)
1 parent 8976087 commit 8412032

File tree

3 files changed

+49
-32
lines changed

3 files changed

+49
-32
lines changed

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,7 @@
139139
"react-textarea-autosize": "^8.4.0",
140140
"react-transition-group": "^4.4.5",
141141
"react-tsparticles": "^2.11.0",
142+
"react-zoom-pan-pinch": "^3.7.0",
142143
"reactflow": "^11.11.4",
143144
"redoc": "^2.0.0-rc.62",
144145
"redux": "^4.0.5",

src/components/Mermaid/index.tsx

+40-4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,36 @@
11
import React, { useEffect, useRef, useState } from 'react'
22
import mermaid from 'mermaid'
3+
import { TransformWrapper, TransformComponent, useControls } from 'react-zoom-pan-pinch'
4+
import { IconMinus, IconPlus, IconRefresh } from '@posthog/icons'
5+
6+
const ControlButton = ({ children, onClick }: { children: React.ReactNode; onClick: () => void }) => {
7+
return (
8+
<button
9+
onClick={onClick}
10+
className="p-2 border border-light dark:border-dark rounded-md bg-accent dark:bg-accent-dark"
11+
>
12+
{children}
13+
</button>
14+
)
15+
}
16+
17+
const Controls = () => {
18+
const { zoomIn, zoomOut, resetTransform } = useControls()
19+
20+
return (
21+
<div className="opacity-0 group-hover:opacity-100 transition-opacity space-x-1 absolute bottom-0 right-0 z-10">
22+
<ControlButton onClick={() => zoomIn()}>
23+
<IconPlus className="w-4" />
24+
</ControlButton>
25+
<ControlButton onClick={() => zoomOut()}>
26+
<IconMinus className="w-4" />
27+
</ControlButton>
28+
<ControlButton onClick={() => resetTransform()}>
29+
<IconRefresh className="w-4" />
30+
</ControlButton>
31+
</div>
32+
)
33+
}
334

435
export default function Mermaid({ children }: { children: string }): JSX.Element {
536
const [loading, setLoading] = useState(true)
@@ -17,13 +48,18 @@ export default function Mermaid({ children }: { children: string }): JSX.Element
1748
}
1849
}, [])
1950
return (
20-
<div className="relative">
51+
<div className="relative group">
2152
{loading && (
2253
<div className="bg-accent dark:bg-accent-dark flex items-center justify-center size-full rounded-md animate-pulse absolute inset-0" />
2354
)}
24-
<div ref={mermaidRef} className={`${loading ? 'invisible' : ''} mermaid-container`}>
25-
{children}
26-
</div>
55+
<TransformWrapper>
56+
<Controls />
57+
<TransformComponent contentStyle={{ width: '100%' }} wrapperStyle={{ width: '100%' }}>
58+
<div ref={mermaidRef} className={`${loading ? 'invisible' : ''} mermaid-container w-full`}>
59+
{children}
60+
</div>
61+
</TransformComponent>
62+
</TransformWrapper>
2763
</div>
2864
)
2965
}

yarn.lock

+8-28
Original file line numberDiff line numberDiff line change
@@ -21665,6 +21665,11 @@ react-tsparticles@^2.11.0:
2166521665
dependencies:
2166621666
tsparticles-engine "^2.12.0"
2166721667

21668+
react-zoom-pan-pinch@^3.7.0:
21669+
version "3.7.0"
21670+
resolved "https://registry.yarnpkg.com/react-zoom-pan-pinch/-/react-zoom-pan-pinch-3.7.0.tgz#7db4d2ec49c316eb20f71c56e9012eeb3ef4b504"
21671+
integrity sha512-UmReVZ0TxlKzxSbYiAj+LeGRW8s8LraAFTXRAxzMYnNRgGPsxCudwZKVkjvGmjtx7SW/hZamt69NUmGf4xrkXA==
21672+
2166821673
react@^16.13.1:
2166921674
version "16.14.0"
2167021675
resolved "https://registry.yarnpkg.com/react/-/react-16.14.0.tgz#94d776ddd0aaa37da3eda8fc5b6b18a4c9a3114d"
@@ -23700,16 +23705,7 @@ string-similarity@^1.2.2:
2370023705
lodash.map "^4.6.0"
2370123706
lodash.maxby "^4.6.0"
2370223707

23703-
"string-width-cjs@npm:string-width@^4.2.0":
23704-
version "4.2.3"
23705-
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
23706-
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
23707-
dependencies:
23708-
emoji-regex "^8.0.0"
23709-
is-fullwidth-code-point "^3.0.0"
23710-
strip-ansi "^6.0.1"
23711-
23712-
"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
23708+
"string-width-cjs@npm:string-width@^4.2.0", "string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3:
2371323709
version "4.2.3"
2371423710
resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010"
2371523711
integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==
@@ -23843,7 +23839,7 @@ stringify-object@^3.3.0:
2384323839
is-obj "^1.0.1"
2384423840
is-regexp "^1.0.0"
2384523841

23846-
"strip-ansi-cjs@npm:strip-ansi@^6.0.1":
23842+
"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1:
2384723843
version "6.0.1"
2384823844
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
2384923845
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
@@ -23871,13 +23867,6 @@ strip-ansi@^5.2.0:
2387123867
dependencies:
2387223868
ansi-regex "^4.1.0"
2387323869

23874-
strip-ansi@^6.0.0, strip-ansi@^6.0.1:
23875-
version "6.0.1"
23876-
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9"
23877-
integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==
23878-
dependencies:
23879-
ansi-regex "^5.0.1"
23880-
2388123870
strip-ansi@^7.0.1:
2388223871
version "7.1.0"
2388323872
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45"
@@ -26366,7 +26355,7 @@ worker-rpc@^0.1.0:
2636626355
dependencies:
2636726356
microevent.ts "~0.1.1"
2636826357

26369-
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0":
26358+
"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0:
2637026359
version "7.0.0"
2637126360
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
2637226361
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
@@ -26384,15 +26373,6 @@ wrap-ansi@^6.2.0:
2638426373
string-width "^4.1.0"
2638526374
strip-ansi "^6.0.0"
2638626375

26387-
wrap-ansi@^7.0.0:
26388-
version "7.0.0"
26389-
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43"
26390-
integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==
26391-
dependencies:
26392-
ansi-styles "^4.0.0"
26393-
string-width "^4.1.0"
26394-
strip-ansi "^6.0.0"
26395-
2639626376
wrap-ansi@^8.1.0:
2639726377
version "8.1.0"
2639826378
resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"

0 commit comments

Comments
 (0)