Skip to content

Commit dc14a6d

Browse files
authored
refactor(docs): guides toc headers (supabase#30955)
Remove the dangerouslySetInnerHTML which is prone to breakage
1 parent 822cf92 commit dc14a6d

File tree

1 file changed

+31
-17
lines changed

1 file changed

+31
-17
lines changed

apps/docs/components/GuidesTableOfContents.tsx

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use client'
22

33
import { usePathname } from 'next/navigation'
4-
import { useEffect, useState } from 'react'
4+
import { Fragment, useEffect, useState } from 'react'
55
import { cn } from 'ui'
66
import { ExpandableVideo } from 'ui-patterns/ExpandableVideo'
77
import { proxy, useSnapshot } from 'valtio'
@@ -20,27 +20,32 @@ const formatSlug = (slug: string) => {
2020
return slug
2121
}
2222

23-
const formatTOCHeader = (content: string) => {
24-
let begin = false
25-
const res: Array<string> = []
23+
function formatTOCHeader(content: string) {
24+
let insideInlineCode = false
25+
const res: Array<{ type: 'text'; value: string } | { type: 'code'; value: string }> = []
26+
2627
for (const x of content) {
2728
if (x === '`') {
28-
if (!begin) {
29-
begin = true
30-
res.push(`<code class="text-xs border rounded bg-muted">`)
29+
if (!insideInlineCode) {
30+
insideInlineCode = true
31+
res.push({ type: 'code', value: '' })
3132
} else {
32-
begin = false
33-
res.push(`</code>`)
33+
insideInlineCode = false
3434
}
35-
} else if (x === '<') {
36-
res.push('&lt')
37-
} else if (x === '>') {
38-
res.push('&gt')
3935
} else {
40-
res.push(x)
36+
if (insideInlineCode) {
37+
res[res.length - 1].value += x
38+
} else {
39+
if (res.length === 0 || res[res.length - 1].type === 'code') {
40+
res.push({ type: 'text', value: x })
41+
} else {
42+
res[res.length - 1].value += x
43+
}
44+
}
4145
}
4246
}
43-
return res.join('')
47+
48+
return res
4449
}
4550

4651
const tocRenderSwitch = proxy({
@@ -144,8 +149,17 @@ const GuidesTableOfContents = ({
144149
<a
145150
href={`#${formatSlug(item.link)}`}
146151
className="text-foreground-lighter hover:text-brand-link transition-colors"
147-
dangerouslySetInnerHTML={{ __html: formatTOCHeader(removeAnchor(item.text)) }}
148-
/>
152+
>
153+
{formatTOCHeader(removeAnchor(item.text)).map((x, index) => (
154+
<Fragment key={index}>
155+
{x.type === 'code' ? (
156+
<code className="text-xs border rounded bg-muted">{x.value}</code>
157+
) : (
158+
x.value
159+
)}
160+
</Fragment>
161+
))}
162+
</a>
149163
</li>
150164
))}
151165
</ul>

0 commit comments

Comments
 (0)