Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions e2e/no-raw-mermaid.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { expect, test } from '@playwright/test'
import { readdirSync, readFileSync, statSync } from 'node:fs'
import { dirname, join } from 'node:path'
import { fileURLToPath } from 'node:url'

const __dirname = dirname(fileURLToPath(import.meta.url))

function findMdxFiles(dir: string): string[] {
const results: string[] = []
for (const entry of readdirSync(dir, { withFileTypes: true })) {
const full = join(dir, entry.name)
if (entry.isDirectory() && entry.name !== 'node_modules') {
results.push(...findMdxFiles(full))
} else if (entry.name.endsWith('.mdx')) {
results.push(full)
}
}
return results
}

test('no raw ```mermaid code blocks in MDX files', () => {
const pagesDir = join(__dirname, '..', 'src', 'pages')
const mdxFiles = findMdxFiles(pagesDir)

const violations: string[] = []
for (const file of mdxFiles) {
const content = readFileSync(file, 'utf-8')
if (/^```mermaid\s*$/m.test(content)) {
const relative = file.replace(join(__dirname, '..') + '/', '')
violations.push(relative)
}
}

expect(violations, [
'Found raw ```mermaid code blocks. Use <StaticMermaidDiagram> instead:',
...violations.map((f) => ` - ${f}`),
].join('\n')).toHaveLength(0)
})
113 changes: 113 additions & 0 deletions src/components/StaticMermaidDiagram.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
'use client'

import { useEffect, useRef, useState } from 'react'
import { THEMES } from './MermaidDiagram'

const FONT_FAMILY =
'ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji"'

let idCounter = 0

export function StaticMermaidDiagram({ chart }: { chart: string }) {
const containerRef = useRef<HTMLDivElement>(null)
const [isDark, setIsDark] = useState(false)

useEffect(() => {
const check = () =>
setIsDark(
document.documentElement.style.colorScheme === 'dark' ||
document.documentElement.classList.contains('dark'),
)
check()
const obs = new MutationObserver(check)
obs.observe(document.documentElement, {
attributes: true,
attributeFilter: ['class', 'style'],
})
return () => obs.disconnect()
}, [])

useEffect(() => {
const el = containerRef.current
if (!el) return

let cancelled = false

async function renderChart() {
const { default: mermaid } = await import('mermaid')
if (cancelled) return

const th = isDark ? THEMES.dark : THEMES.light

const nodeBg = isDark ? '#27272a' : th.actorFill
const nodeBorder = isDark ? '#52525b' : th.actorStroke
const clusterBg = isDark ? '#3f3f46' : th.blockHeaderBg
const clusterBorder = isDark ? '#52525b' : th.blockStroke

mermaid.initialize({
startOnLoad: false,
theme: 'base',
themeVariables: {
fontFamily: FONT_FAMILY,
fontSize: '14px',
primaryColor: clusterBg,
primaryTextColor: th.text,
primaryBorderColor: clusterBorder,
lineColor: th.line,
secondaryColor: nodeBg,
tertiaryColor: clusterBg,
mainBkg: nodeBg,
nodeBorder,
clusterBkg: clusterBg,
clusterBorder,
titleColor: th.text,
edgeLabelBackground: nodeBg,
},
flowchart: {
htmlLabels: true,
curve: 'basis',
padding: 12,
nodeSpacing: 40,
rankSpacing: 40,
},
})

const id = `static-mermaid-${++idCounter}`
try {
const { svg } = await mermaid.render(id, chart.trim())
if (cancelled || !el) return
el.innerHTML = svg
const svgEl = el.querySelector('svg')
if (svgEl) {
svgEl.style.maxWidth = '100%'
svgEl.style.height = 'auto'
svgEl.style.display = 'block'
svgEl.style.margin = '0 auto'
}
} catch (err) {
console.error('StaticMermaidDiagram:', err)
}
}

renderChart()
return () => {
cancelled = true
}
}, [chart, isDark])

return (
<div
className="mermaid-diagram"
style={{
margin: '1.5rem 0',
padding: '1rem 0.5rem',
borderRadius: '12px',
overflow: 'hidden',
overflowX: 'auto',
position: 'relative',
}}
>
<div ref={containerRef} style={{ maxWidth: '540px', margin: '0 auto' }} />
</div>
)
}
6 changes: 3 additions & 3 deletions src/pages/accounts/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { Cards, Card } from 'vocs'
import * as Demo from '../../components/guides/Demo.tsx'
import * as Step from '../../components/guides/steps'
import IconGitHub from '~icons/simple-icons/github'
import { StaticMermaidDiagram } from '../../components/StaticMermaidDiagram'

# Getting Started

Expand Down Expand Up @@ -47,8 +48,7 @@ Your application interacts with the SDK through standard JSON-RPC methods (via [

An example of a high-level flow of an Application requesting for a user to perform an action with their Tempo Wallet is shown below:

```mermaid
sequenceDiagram
<StaticMermaidDiagram chart={`sequenceDiagram
participant A as Application
participant S as Accounts SDK
participant W as wallet.tempo.xyz or Other
Expand All @@ -58,7 +58,7 @@ sequenceDiagram
note over W: User approves with Passkey
W-->>S: result
S-->>A: result
```
`} />

## Install

Expand Down
7 changes: 4 additions & 3 deletions src/pages/guide/node/validator-config-v2.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ title: ValidatorConfig V2
description: Manage your validator with ValidatorConfig V2. Self-service key rotation, IP updates, and ownership transfer.
---

import { StaticMermaidDiagram } from '../../../components/StaticMermaidDiagram'

# ValidatorConfig V2

ValidatorConfig V2 ([TIP-1017](/protocol/tips/tip-1017)) is the precompile that manages consensus participants. This config was [activated on mainnet](https://explore.mainnet.tempo.xyz/receipt/0x4716147e3c2bf5c8d014b8c27d6e2af0042d5a5f29bdead256d6f33038702d64) after the T2 hardfork.
Expand All @@ -11,12 +13,11 @@ ValidatorConfig V2 ([TIP-1017](/protocol/tips/tip-1017)) is the precompile that

Once added, a validator immediately becomes a player in the next epoch.

```mermaid
flowchart TD
<StaticMermaidDiagram chart={`flowchart TD
A[Inactive] -->|epoch ends| B["Player<br/>Receives signing shares"]
B -->|"+1 epoch, receives share"| C["Player<br/>Dealer"]
C -->|"once fully synced"| D["Voter ↔ Proposer"]
```
`} />
## What changes for operators

Validators can perform several operations themselves without coordinating with the Tempo team:
Expand Down
Loading