SHARE
TWEET

Untitled

a guest Sep 20th, 2019 87 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)
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
Not a member of Pastebin yet?
Sign Up, it unlocks many cool features!
 
Top