Skip to content

Instantly share code, notes, and snippets.

@gpoole
Created January 10, 2023 21:45
Show Gist options
  • Save gpoole/d61be245be4a8c74fe1d63f45d1cf0f8 to your computer and use it in GitHub Desktop.
Save gpoole/d61be245be4a8c74fe1d63f45d1cf0f8 to your computer and use it in GitHub Desktop.
Minimal implementation of @portabletext/react in TypeScript
import { PortableText, PortableTextMarkComponent, PortableTextBlockComponent, PortableTextListComponent, PortableTextListItemComponent } from '@portabletext/react'
import { PortableTextBlock, TypedObject } from '@portabletext/types'
import { FC } from 'react'
interface LinkProps extends TypedObject {
href: string
openInNewTab: boolean
}
const Link: PortableTextMarkComponent<LinkProps> = ({ value, children }) => {
const href: string = (value?.href ?? '')
const target = href.startsWith('http') ? '_blank' : undefined
return (
<a href={href} target={target} rel={target !== '_blank' ? 'noindex nofollow' : undefined}>
{children}
</a>
)
}
const H1: PortableTextBlockComponent = ({ children }) => {
return <h1>{children}</h1>
}
const Em: PortableTextMarkComponent = ({ children }) => {
return <em>{children}</em>
}
const Normal: PortableTextBlockComponent = ({ children }) => {
return <p>{children}</p>
}
const BulletList: PortableTextListComponent = ({ children }) => {
return <ul>{children}</ul>
}
const NumberList: PortableTextListComponent = ({ children }) => {
return <ol>{children}</ol>
}
const ListItem: PortableTextListItemComponent = ({ children }) => {
return <li>{children}</li>
}
const COMPONENTS = {
types: {
},
marks: {
em: Em,
link: Link
},
block: {
h1: H1,
normal: Normal
},
list: {
bullet: BulletList,
number: NumberList
},
listItem: ListItem
}
interface Props {
blocks: PortableTextBlock[]
}
const RichText: FC<Props> = ({ blocks }) => {
return (
<PortableText
value={blocks}
components={COMPONENTS}
/>
)
}
export default RichText
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment