mirror of
https://github.com/hedgedoc/hedgedoc.git
synced 2025-05-22 03:05:19 -04:00

* Add 'yarn lint' command and run it in GH actions * Move linting to own workflow * Remove linting from build-workflow * Solve linting warnings Signed-off-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de> Co-authored-by: Tilman Vatteroth <tilman.vatteroth@tu-dortmund.de>
62 lines
1.7 KiB
TypeScript
62 lines
1.7 KiB
TypeScript
import React, { Fragment, ReactElement, useMemo } from 'react'
|
|
import { TocAst } from '../../../external-types/markdown-it-toc-done-right/interface'
|
|
import { ShowIf } from '../../common/show-if/show-if'
|
|
import './table-of-contents.scss'
|
|
|
|
export interface TableOfContentsProps {
|
|
ast: TocAst
|
|
maxDepth?: number
|
|
className?: string
|
|
}
|
|
|
|
export const slugify = (content:string): string => {
|
|
return encodeURIComponent(String(content).trim().toLowerCase().replace(/\s+/g, '-'))
|
|
}
|
|
|
|
const convertLevel = (toc: TocAst, levelsToShowUnderThis: number, headerCounts: Map<string, number>, wrapInListItem: boolean): ReactElement | null => {
|
|
if (levelsToShowUnderThis < 0) {
|
|
return null
|
|
}
|
|
|
|
const rawName = toc.n.trim()
|
|
const nameCount = (headerCounts.get(rawName) ?? 0) + 1
|
|
const slug = `#${slugify(rawName)}${nameCount > 1 ? `-${nameCount}` : ''}`
|
|
|
|
headerCounts.set(rawName, nameCount)
|
|
|
|
const content = (
|
|
<Fragment>
|
|
<ShowIf condition={toc.l > 0}>
|
|
<a href={slug}>{rawName}</a>
|
|
</ShowIf>
|
|
<ShowIf condition={toc.c.length > 0}>
|
|
<ul>
|
|
{
|
|
toc.c.map(child =>
|
|
(convertLevel(child, levelsToShowUnderThis - 1, headerCounts, true)))
|
|
}
|
|
</ul>
|
|
</ShowIf>
|
|
</Fragment>
|
|
)
|
|
|
|
if (wrapInListItem) {
|
|
return (
|
|
<li key={slug}>
|
|
{content}
|
|
</li>
|
|
)
|
|
} else {
|
|
return content
|
|
}
|
|
}
|
|
|
|
export const TableOfContents: React.FC<TableOfContentsProps> = ({ ast, maxDepth = 3, className }) => {
|
|
const tocTree = useMemo(() => convertLevel(ast, maxDepth, new Map<string, number>(), false), [ast, maxDepth])
|
|
|
|
return (
|
|
<div className={`markdown-toc ${className ?? ''}`}>
|
|
{tocTree}
|
|
</div>
|
|
)
|
|
}
|