55 lines
1.8 KiB
TypeScript
55 lines
1.8 KiB
TypeScript
import { type RichTextItemResponse } from '@notionhq/client/build/src/api-endpoints'
|
|
import clsx from 'clsx'
|
|
import dynamic from 'next/dynamic'
|
|
import { type FC, Fragment, Suspense } from 'react'
|
|
|
|
import HybridLink from './HybridLink'
|
|
|
|
const TeX = dynamic(() => import('@matejmazur/react-katex'))
|
|
|
|
const RichText: FC<{ richText: RichTextItemResponse[] }> = ({ richText }) => {
|
|
return (
|
|
<>
|
|
{richText.map((text, index) => {
|
|
if (text.type === 'mention') return null // TODO
|
|
else if (text.type === 'text') {
|
|
const className = clsx({
|
|
italic: text.annotations.italic,
|
|
'font-bold': text.annotations.bold,
|
|
underline: text.annotations.underline,
|
|
'dark:bg-neutral-800 border-1 dark:border-neutral-500 font-mono dark:text-red-400 p-1 rounded':
|
|
text.annotations.code,
|
|
strikethrough: text.annotations.strikethrough,
|
|
})
|
|
|
|
if (text.href)
|
|
return (
|
|
<HybridLink
|
|
key={index}
|
|
href={text.href}
|
|
className={clsx(
|
|
'underline transition-colors hover:text-teal-500',
|
|
className,
|
|
)}
|
|
>
|
|
{/* The above "hack" is so that we don't get empty `class`es all over the HTML */}
|
|
{text.plain_text}
|
|
</HybridLink>
|
|
)
|
|
else
|
|
return className ? (
|
|
<span key={index} className={className}>
|
|
{text.plain_text}
|
|
</span>
|
|
) : (
|
|
<Fragment key={index}>{text.plain_text}</Fragment>
|
|
)
|
|
} else if (text.type === 'equation')
|
|
return <TeX>{text.equation.expression}</TeX>
|
|
})}
|
|
</>
|
|
)
|
|
}
|
|
|
|
export default RichText
|