@portabletext/to-html
Version:
Render Portable Text to HTML
43 lines (36 loc) • 1.44 kB
text/typescript
import type {PortableTextComponents, PortableTextHtmlComponents} from '../types'
export function mergeComponents(
parent: PortableTextHtmlComponents,
overrides: PortableTextComponents,
): PortableTextHtmlComponents {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const {block, list, listItem, marks, types, ...rest} = overrides
// @todo figure out how to not `as ...` these
return {
...parent,
block: mergeDeeply(parent, overrides, 'block') as PortableTextHtmlComponents['block'],
list: mergeDeeply(parent, overrides, 'list') as PortableTextHtmlComponents['list'],
listItem: mergeDeeply(parent, overrides, 'listItem') as PortableTextHtmlComponents['listItem'],
marks: mergeDeeply(parent, overrides, 'marks') as PortableTextHtmlComponents['marks'],
types: mergeDeeply(parent, overrides, 'types') as PortableTextHtmlComponents['types'],
...rest,
}
}
function mergeDeeply(
parent: PortableTextHtmlComponents,
overrides: PortableTextComponents,
key: 'block' | 'list' | 'listItem' | 'marks' | 'types',
): PortableTextHtmlComponents[typeof key] {
const override = overrides[key]
const parentVal = parent[key]
if (typeof override === 'function') {
return override
}
if (override && typeof parentVal === 'function') {
return override
}
if (override) {
return {...parentVal, ...override} as PortableTextHtmlComponents[typeof key]
}
return parentVal
}