Advertisement
Guest User

Untitled

a guest
Sep 20th, 2019
126
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. import React from 'react'
  2. import PropTypes from 'prop-types'
  3. import { graphql } from 'gatsby'
  4. import classNames from 'classnames'
  5. import { widowFix } from '~utils/string'
  6. import { BLOCKS } from '@contentful/rich-text-types'
  7. import { documentToReactComponents } from '@contentful/rich-text-react-renderer'
  8. import { contentfulResize } from '~utils/url'
  9.  
  10. // components
  11. import Container from '~globals/Container'
  12. import ButtonPrimary from '~elements/ButtonPrimary'
  13. import ButtonSecondary from '~elements/ButtonSecondary'
  14. import VideoEmbed from '~elements/VideoEmbed'
  15. import withIntersectionObserver from '~hocs/withIntersectionObserver'
  16. import Parallax from '~globals/Parallax'
  17.  
  18. // styles
  19. import styles from './style.module.css'
  20. import typography from '~styles/imports/typography.module.css'
  21.  
  22. class SplitContent extends React.Component {
  23.   static propTypes = {
  24.     accentImage: PropTypes.shape({
  25.       description: PropTypes.string,
  26.       file: PropTypes.shape({
  27.         url: PropTypes.string.isRequired,
  28.       }),
  29.     }),
  30.     buttons: PropTypes.arrayOf(PropTypes.object),
  31.     description: PropTypes.shape({
  32.       json: PropTypes.object,
  33.     }),
  34.     enteredOnce: PropTypes.bool.isRequired,
  35.     eyebrow: PropTypes.string,
  36.     hasWideImage: PropTypes.bool,
  37.     isContentLeftAlignedOnMobile: PropTypes.bool,
  38.     isContentRightAligned: PropTypes.bool,
  39.     isHeaderCentered: PropTypes.bool,
  40.     isLongContent: PropTypes.bool,
  41.     offset: PropTypes.bool,
  42.     narrow: PropTypes.bool,
  43.     title: PropTypes.string.isRequired,
  44.     noAppear: PropTypes.bool.isRequired,
  45.     onRef: PropTypes.func.isRequired,
  46.     images: PropTypes.arrayOf(PropTypes.object),
  47.     videoId: PropTypes.string,
  48.     videoPoster: PropTypes.shape({
  49.       url: PropTypes.string,
  50.     }),
  51.   }
  52.  
  53.   static defaultProps = {
  54.     accentImage: null,
  55.     buttons: null,
  56.     description: null,
  57.     eyebrow: null,
  58.     hasWideImage: null,
  59.     images: null,
  60.     isContentLeftAlignedOnMobile: false,
  61.     isContentRightAligned: false,
  62.     isHeaderCentered: false,
  63.     isLongContent: false,
  64.     offset: false,
  65.     narrow: false,
  66.     videoId: null,
  67.     videoPoster: null,
  68.   }
  69.  
  70.   render() {
  71.     const {
  72.       accentImage,
  73.       buttons,
  74.       description,
  75.       enteredOnce,
  76.       eyebrow,
  77.       hasWideImage,
  78.       images,
  79.       isContentLeftAlignedOnMobile,
  80.       isContentRightAligned,
  81.       isHeaderCentered,
  82.       isLongContent,
  83.       narrow,
  84.       noAppear,
  85.       offset,
  86.       onRef,
  87.       title,
  88.       videoId,
  89.       videoPoster,
  90.     } = this.props
  91.  
  92.  
  93.     const wrapperClass = classNames(styles.wrapper, {
  94.       [styles.transitionInverted]: isContentRightAligned,
  95.       [styles.isHeaderCentered]: isHeaderCentered,
  96.       [styles.narrow]: narrow,
  97.       enteredOnce,
  98.       noAppear,
  99.     })
  100.     const flexWrapperClass = classNames(styles.flexWrapper, {
  101.       [styles.narrow]: narrow,
  102.       [styles.offset]: offset,
  103.       [styles.longContent]: isLongContent,
  104.       [styles.inverted]: isContentRightAligned,
  105.       [styles.leftAlignedOnMobile]: isContentLeftAlignedOnMobile,
  106.     })
  107.     const mediaWrapperClass = classNames(styles.mediaWrapper, {
  108.       [styles.hasWideImage]: hasWideImage,
  109.     })
  110.     const titleClass = classNames(styles.title, typography.h1)
  111.     const eyebrowClass = classNames(styles.eyebrow, typography.eyebrow)
  112.     const ContentHeadingClass = classNames(styles.contentHeading, typography.h3)
  113.     const ContentEyebrowClass = classNames(styles.contentEyebrow, typography.eyebrow)
  114.     const ContentParagraphClass = classNames(styles.contentParagraph, typography.body)
  115.  
  116.     const imageWidth = offset ? 1508 : 1276
  117.  
  118.     const ImageSide = (
  119.       <div className={mediaWrapperClass}>
  120.         {images &&
  121.           images.map((image, index) => {
  122.             if (images.length >= 2) {
  123.               const speed = index === 0 ? 30 : 20
  124.               const reverse = index === 0
  125.               return (
  126.                 <Parallax
  127.                   key={image.id}
  128.                   speed={speed}
  129.                   extraClassName={styles.media}
  130.                   reverse={reverse}
  131.                   imageToLoad={image ? contentfulResize(image.file.url, imageWidth) : null}
  132.                 >
  133.                   <img
  134.                     src={image ? contentfulResize(image.file.url, imageWidth) : ''}
  135.                     alt={image.description || ''}
  136.                     key={image.id}
  137.                   />
  138.                 </Parallax>
  139.               )
  140.             }
  141.  
  142.             return (
  143.               <img
  144.                 className={styles.media}
  145.                 src={image ? contentfulResize(image.file.url, imageWidth) : ''}
  146.                 alt={image.description || ''}
  147.                 key={image.id}
  148.               />
  149.             )
  150.           })}
  151.         {videoId && videoPoster && (
  152.           <VideoEmbed videoId={videoId} videoPoster={videoPoster} />
  153.         )}
  154.       </div>
  155.     )
  156.  
  157.     // Allowed styles: plain text, bold text
  158.     const descriptionOptions = {
  159.       renderNode: {
  160.         [BLOCKS.HEADING_3]: (node, children) => <p className={ContentHeadingClass}>{children}</p>,
  161.         [BLOCKS.HEADING_6]: (node, children) => <p className={ContentEyebrowClass}>{children}</p>,
  162.         [BLOCKS.PARAGRAPH]: (node, children) => <p className={ContentParagraphClass}>{children}</p>,
  163.       },
  164.       renderText: text => widowFix(text),
  165.     }
  166.  
  167.     return (
  168.       <Container ref={onRef} extraClassName={wrapperClass}>
  169.         {isHeaderCentered && (
  170.           <div className={styles.headerCentered}>
  171.             {eyebrow && <div className={eyebrowClass}>{eyebrow}</div>}
  172.             <h2 className={titleClass}>{widowFix(title)}</h2>
  173.           </div>
  174.         )}
  175.         <div className={flexWrapperClass}>
  176.           {isContentRightAligned && ImageSide}
  177.           <div className={styles.contentWrapper}>
  178.             {accentImage && (
  179.               <img
  180.                 src={contentfulResize(accentImage.file.url, 928) || ''}
  181.                 alt={accentImage.description || ''}
  182.                 className={styles.accentImage}
  183.               />
  184.             )}
  185.  
  186.             {!isHeaderCentered && (
  187.               <>
  188.                 {eyebrow && <div className={eyebrowClass}>{eyebrow}</div>}
  189.                 <h2 className={titleClass}>{widowFix(title)}</h2>
  190.               </>
  191.             )}
  192.  
  193.             <div className={styles.description}>
  194.               {description && documentToReactComponents(description.json, descriptionOptions)}
  195.             </div>
  196.  
  197.             {buttons && buttons[0] && (
  198.               <div className={styles.buttonWrapper}>
  199.                 {buttons && buttons[0] && (
  200.                   <ButtonPrimary text={buttons[0].text} link={buttons[0].url} extraClassName={styles.primaryButton} />
  201.                 )}
  202.                 {buttons && buttons[1] && (
  203.                   <ButtonSecondary
  204.                     text={buttons[1].text}
  205.                     link={buttons[1].url}
  206.                     extraClassName={styles.secondaryButton}
  207.                   />
  208.                 )}
  209.               </div>
  210.             )}
  211.           </div>
  212.           {!isContentRightAligned && ImageSide}
  213.         </div>
  214.       </Container>
  215.     )
  216.   }
  217. }
  218.  
  219. export const SplitContentFragment = graphql`
  220.   fragment SplitContent on ContentfulSectionSplitContent {
  221.     id
  222.     title
  223.     eyebrow
  224.     description {
  225.       json
  226.     }
  227.     accentImage {
  228.       file {
  229.         url
  230.         fileName
  231.         contentType
  232.       }
  233.     }
  234.     background {
  235.       theme
  236.       color
  237.     }
  238.     images {
  239.       id
  240.       file {
  241.         url
  242.         fileName
  243.         contentType
  244.       }
  245.     }
  246.     narrow
  247.     offset
  248.     buttons {
  249.       text
  250.       url
  251.     }
  252.     isContentRightAligned
  253.     isContentLeftAlignedOnMobile
  254.     isHeaderCentered
  255.     isLongContent
  256.     hasWideImage
  257.   }
  258. `
  259.  
  260. export const SplitContentWithVideoFragment = graphql`
  261.   fragment SplitContentWithVideo on ContentfulSectionSplitContentWithVideo {
  262.     id
  263.     title
  264.     eyebrow
  265.     description {
  266.       json
  267.     }
  268.     accentImage {
  269.       file {
  270.         url
  271.         fileName
  272.         contentType
  273.       }
  274.     }
  275.     videoId
  276.     videoPoster {
  277.       file {
  278.         url
  279.         fileName
  280.         contentType
  281.       }
  282.     }
  283.     offset
  284.     buttons {
  285.       text
  286.       url
  287.     }
  288.     isContentRightAligned
  289.     isContentLeftAlignedOnMobile
  290.     isHeaderCentered
  291.   }
  292. `
  293.  
  294. export default withIntersectionObserver()(SplitContent)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement