Skip to content

Instantly share code, notes, and snippets.

@brianbancroft
Last active April 2, 2019 14:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save brianbancroft/464c5f06253315ecbc542fced5d99ba3 to your computer and use it in GitHub Desktop.
Save brianbancroft/464c5f06253315ecbc542fced5d99ba3 to your computer and use it in GitHub Desktop.
Deciphering Contentful Rich Text Blocks in React. The second file is an example of the graphql output that would go into this.
import React from 'react'
const classList = marks => marks.map(i => i.type).join(' ')
const elementMap = {
paragraph: 'p',
'heading-1': 'h1',
'heading-2': 'h2',
'heading-3': 'h3',
'heading-4': 'h4',
'heading-5': 'h5',
'heading-6': 'h6',
'ordered-list': 'ol',
'unordered-list': 'il',
'list-item': 'li',
blockquote: 'blockquote',
}
const richText = content =>
content.map(({ content, data, nodeType, marks, value } = {}) => {
switch (nodeType) {
case 'text':
return <span className={classList(marks)}>{value}</span>
case 'paragraph':
case 'heading-1':
case 'heading-2':
case 'heading-3':
case 'heading-4':
case 'heading-5':
case 'heading-6':
case 'paragraph':
case 'ordered-list':
case 'unordered-list':
case 'list-item':
case 'blockquote':
let El = elementMap[nodeType]
return <El>{richText(content)}</El>
// SPECIAL CASES
case 'hr':
return <hr />
// Will contain either a codeblock or an image
case 'embedded-asset-block':
console.log('TODO')
return <span>0</span>
case 'hyperlink':
console.log('TODO')
return <span>0</span>
default:
console.error('Error. Unknown node type -> ', nodeType)
}
})
export default richText
{
"data": {
"post": {
"article": {
"json": {
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "Header 1",
"nodeType": "text"
}
],
"nodeType": "heading-1"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "Header 2",
"nodeType": "text"
}
],
"nodeType": "heading-2"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "Header 3",
"nodeType": "text"
}
],
"nodeType": "heading-3"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "Header 4",
"nodeType": "text"
}
],
"nodeType": "heading-4"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "Header 5",
"nodeType": "text"
}
],
"nodeType": "heading-5"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "Header 6",
"nodeType": "text"
}
],
"nodeType": "heading-6"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "Normal Text",
"nodeType": "text"
}
],
"nodeType": "paragraph"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "bold"
}
],
"value": "Bold Text",
"nodeType": "text"
}
],
"nodeType": "paragraph"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "italic"
}
],
"value": "Italic Text",
"nodeType": "text"
}
],
"nodeType": "paragraph"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "underline"
}
],
"value": "Underline Text",
"nodeType": "text"
}
],
"nodeType": "paragraph"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "Monospace Code Block",
"nodeType": "text"
}
],
"nodeType": "paragraph"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "",
"nodeType": "text"
},
{
"data": {
"uri": "https://google.ca"
},
"content": [
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "Link to Google",
"nodeType": "text"
}
],
"nodeType": "hyperlink"
},
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "",
"nodeType": "text"
}
],
"nodeType": "paragraph"
},
{
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "UL Item 1",
"nodeType": "text"
}
],
"nodeType": "paragraph"
}
],
"nodeType": "list-item"
},
{
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "UL Item 2",
"nodeType": "text"
}
],
"nodeType": "paragraph"
}
],
"nodeType": "list-item"
},
{
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "UL Item 3",
"nodeType": "text"
}
],
"nodeType": "paragraph"
}
],
"nodeType": "list-item"
}
],
"nodeType": "unordered-list"
},
{
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "OL Item 1",
"nodeType": "text"
}
],
"nodeType": "paragraph"
}
],
"nodeType": "list-item"
},
{
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "OL Item 2",
"nodeType": "text"
}
],
"nodeType": "paragraph"
}
],
"nodeType": "list-item"
},
{
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "OL Item 3",
"nodeType": "text"
}
],
"nodeType": "paragraph"
}
],
"nodeType": "list-item"
}
],
"nodeType": "ordered-list"
},
{
"data": {},
"content": [
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "This is a blockquote of something profound",
"nodeType": "text"
}
],
"nodeType": "paragraph"
}
],
"nodeType": "blockquote"
},
{
"data": {},
"content": [],
"nodeType": "hr"
},
{
"data": {
"target": {
"sys": {
"id": "W4AsE6tspZ8iacOahSryN",
"type": "Link",
"linkType": "Asset"
}
}
},
"content": [],
"nodeType": "embedded-asset-block"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "",
"nodeType": "text"
}
],
"nodeType": "paragraph"
},
{
"data": {},
"content": [
{
"data": {},
"marks": [],
"value": "Copy: The ",
"nodeType": "text"
},
{
"data": {},
"marks": [
{
"type": "bold"
}
],
"value": "quick",
"nodeType": "text"
},
{
"data": {},
"marks": [],
"value": " ",
"nodeType": "text"
},
{
"data": {},
"marks": [
{
"type": "italic"
}
],
"value": "brown",
"nodeType": "text"
},
{
"data": {},
"marks": [],
"value": " ",
"nodeType": "text"
},
{
"data": {},
"marks": [
{
"type": "underline"
},
{
"type": "italic"
}
],
"value": "fox",
"nodeType": "text"
},
{
"data": {},
"marks": [],
"value": " ",
"nodeType": "text"
},
{
"data": {},
"marks": [
{
"type": "code"
}
],
"value": "jumps",
"nodeType": "text"
},
{
"data": {},
"marks": [],
"value": " over the lazy dog",
"nodeType": "text"
}
],
"nodeType": "paragraph"
}
],
"nodeType": "document"
}
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment