Skip to content
Snippets Groups Projects
PortableTextBlock.js 4.18 KiB
Newer Older
Tarje Lavik's avatar
Tarje Lavik committed
import React from 'react'
import NextLink from 'next/link'
Tarje Lavik's avatar
Tarje Lavik committed
import {Heading, Link, Text} from '@chakra-ui/react'
import { BigText, Hero, Iframe, InstagramPost, PageHeader,Quote, MiradorGallery, SectionText, SingleLevelChart, SingleObject, Social, SubStory, TimelineSection, TwoColumn, Video, IllustrationWithCaption, ExhibitionElement } from './Sections'
Sanity.io's avatar
Sanity.io committed

const BlockContent = require('@sanity/block-content-to-react')

export default function PortableTextBlock(props) {
  if (!props.blocks || !Array.isArray(props.blocks) || !props.blocks.length) {
Sanity.io's avatar
Sanity.io committed
    return null
  }

    fontSize = {base: 'lg', sm: 'xl', md: 'xl', xl: 'xl'}, 
    lineHeight=['1.25', '1.3'], 
    fontWeight = 'normal',
Sanity.io's avatar
Sanity.io committed

Tarje Lavik's avatar
Tarje Lavik committed
  const getFontSize = (level) => {
    switch(level) {
    case 'h2' :
      return {base: 'lg', sm: '2xl', md: '3xl', xl: '4xl'}
    case 'h3' :
      return {base: 'md', sm: 'xl', md: '2xl', xl: '3xl'}
    default : return null
Sanity.io's avatar
Sanity.io committed
  const BlockRenderer = (props) => {
    if(!props) {return null}
Sanity.io's avatar
Sanity.io committed
    const {style = 'normal'} = props.node

    if (/^h\d/.test(style)) {
Tarje Lavik's avatar
Tarje Lavik committed
      const level = style
      return (
        <Heading 
          maxWidth={['xl', null, 'xl', null ]}
          margin="auto"
          as={level} 
          fontSize={getFontSize(level)}
        >
          {props.children}
        </Heading>)
Sanity.io's avatar
Sanity.io committed
    }

    if (style === 'blockquote') {
      return <blockquote>- {props.children}</blockquote>
    }

    return (
        maxWidth={['xl', null, 'xl', null ]}
        fontSize={fontSize} 
        lineHeight={lineHeight} 
        fontWeight={fontWeight} 
        fontFamily={fontFamily} 
        mx={mx ?? 'auto'}
Sanity.io's avatar
Sanity.io committed
        {props.children}
      </Text>
    )
    // Fall back to default handling
    // return BlockContent.defaultSerializers.types.block(props)
  }

  const serializers = {
    marks: {
      internalLink: ({mark, children}) => {
        const {reference} = mark
        const href = `/id/${reference._ref}`
        const text = children.length ? children[0] : children
Sanity.io's avatar
Sanity.io committed
        return (
          <Link as={NextLink} href={href}>
Sanity.io's avatar
Sanity.io committed
          </Link>
        )
      },
      link: ({mark, children}) => {
Tarje.Lavik's avatar
Tarje.Lavik committed
        // console.log(children)
Sanity.io's avatar
Sanity.io committed
        // Read https://css-tricks.com/use-target_blank/
        const {blank, href} = mark
        const text = children.length ? children[0] : children
Sanity.io's avatar
Sanity.io committed
        return blank ? (
          <Link href={href} isExternal>
Sanity.io's avatar
Sanity.io committed
          </Link>
        ) : (
          <Link href={href}>
Sanity.io's avatar
Sanity.io committed
          </Link>
        )
      },
    },
    types: {
      code: (props) => (
        <pre data-language={props.node.language}>
          <code>{props.node.code}</code>
        </pre>
      ),
      block: BlockRenderer,
Tarje Lavik's avatar
Tarje Lavik committed
      BigText: (props) => (<BigText {...props.node} />),
      ExhibitionElement: (props) => (<ExhibitionElement {...props.node} />),
Tarje Lavik's avatar
Tarje Lavik committed
      Hero: (props) => (<Hero {...props.node} />),
      Iframe: (props) => (<Iframe {...props.node} />),
      IllustrationWithCaption: (props) => (<IllustrationWithCaption {...props.node} />),
Tarje Lavik's avatar
Tarje Lavik committed
      InstagramPost: (props) => (<InstagramPost {...props.node} />),
      MiradorGallery: (props) => (<MiradorGallery {...props.node} />),
      PageHeader: (props) => (<PageHeader {...props.node} />),
      Quote: (props) => (<Quote {...props.node} />),
      SectionText: (props) => (<SectionText {...props.node} />),
Tarje Lavik's avatar
Tarje Lavik committed
      SingleLevelChart: (props) => (<SingleLevelChart {...props.node} />),
Tarje Lavik's avatar
Tarje Lavik committed
      SingleObject: (props) => (<SingleObject {...props.node} />),
      Social: (props) => (<Social {...props.node} />),
      SubStory: (props) => (<SubStory {...props.node} />),
Tarje Lavik's avatar
Tarje Lavik committed
      TimelineSection: (props) => (<TimelineSection {...props.node} />),
      TwoColumn: (props) => (<TwoColumn {...props.node} />),
      Video: (props) => (<Video {...props.node} />),
      Place: (props) => (
Sanity.io's avatar
Sanity.io committed
        <div>
          <h2>Demo: referanse til dokument i en Portable Text blokk</h2>
          <p>
            <Link as={NextLink} href={`/id/${props.node._id}`}>{props.node.label.no}</Link>
Sanity.io's avatar
Sanity.io committed
          </p>
        </div>
      )
    },
  }

  return <BlockContent blocks={blocks} serializers={serializers} />
Sanity.io's avatar
Sanity.io committed
}