Skip to content

Commit

Permalink
feat!: allow specifying custom component for block-like types
Browse files Browse the repository at this point in the history
BREAKING CHANGE: Components defined in `components.types` will now be used even
if the data shape appears to be a portable text block. In past versions, data
shapes that appeared to be portable text blocks would always be rendered using
the default block renderer, with no way of overriding how they would be
rendered.
  • Loading branch information
rexxars authored and snorrees committed Apr 26, 2023
1 parent 120892b commit 6407839
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 10 deletions.
32 changes: 23 additions & 9 deletions src/react-portable-text.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,15 +88,23 @@ const getNodeRenderer = (
return renderSpan(node, index, key)
}

if (node._type === 'block' && isPortableTextBlock(node)) {
if (hasCustomComponentForNode(node)) {
return renderCustomBlock(node, index, key, isInline)
}

if (isPortableTextBlock(node)) {
return renderBlock(node, index, key, isInline)
}

if (isPortableTextToolkitTextNode(node)) {
return renderText(node, key)
}

return renderCustomBlock(node, index, key, isInline)
return renderUnknownType(node, index, key, isInline)
}

function hasCustomComponentForNode(node: TypedObject): boolean {
return node._type in components.types
}

/* eslint-disable react/jsx-no-bind */
Expand Down Expand Up @@ -209,25 +217,31 @@ const getNodeRenderer = (
return node.text
}

function renderCustomBlock(node: TypedObject, index: number, key: string, isInline: boolean) {
const Node = components.types[node._type]

function renderUnknownType(node: TypedObject, index: number, key: string, isInline: boolean) {
const nodeOptions = {
value: node,
isInline,
index,
renderNode,
}

if (Node) {
return <Node key={key} {...nodeOptions} />
}

handleMissingComponent(unknownTypeWarning(node._type), {nodeType: 'block', type: node._type})

const UnknownType = components.unknownType
return <UnknownType key={key} {...nodeOptions} />
}

function renderCustomBlock(node: TypedObject, index: number, key: string, isInline: boolean) {
const nodeOptions = {
value: node,
isInline,
index,
renderNode,
}

const Node = components.types[node._type]
return Node ? <Node key={key} {...nodeOptions} /> : null
}
/* eslint-enable react/jsx-no-bind */

return renderNode
Expand Down
2 changes: 1 addition & 1 deletion test/fixtures/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,11 @@ import inlineBlockWithText from './026-inline-block-with-text'
import styledListItems from './027-styled-list-items'
import customListItemType from './028-custom-list-item-type'
import customBlockType from './050-custom-block-type'
import customBlockTypeWithChildren from './062-custom-block-type-with-children'
import customMarks from './052-custom-marks'
import overrideDefaultMarks from './053-override-default-marks'
import listIssue from './060-list-issue'
import missingMarkComponent from './061-missing-mark-component'
import customBlockTypeWithChildren from './062-custom-block-type-with-children'

export {
emptyBlock,
Expand Down

0 comments on commit 6407839

Please sign in to comment.