Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import React from 'react'
- import PropTypes from 'prop-types'
- import { graphql } from 'gatsby'
- import classNames from 'classnames'
- import { widowFix } from '~utils/string'
- import { BLOCKS } from '@contentful/rich-text-types'
- import { documentToReactComponents } from '@contentful/rich-text-react-renderer'
- import { contentfulResize } from '~utils/url'
- // components
- import Container from '~globals/Container'
- import ButtonPrimary from '~elements/ButtonPrimary'
- import ButtonSecondary from '~elements/ButtonSecondary'
- import VideoEmbed from '~elements/VideoEmbed'
- import withIntersectionObserver from '~hocs/withIntersectionObserver'
- import Parallax from '~globals/Parallax'
- // styles
- import styles from './style.module.css'
- import typography from '~styles/imports/typography.module.css'
- class SplitContent extends React.Component {
- static propTypes = {
- accentImage: PropTypes.shape({
- description: PropTypes.string,
- file: PropTypes.shape({
- url: PropTypes.string.isRequired,
- }),
- }),
- buttons: PropTypes.arrayOf(PropTypes.object),
- description: PropTypes.shape({
- json: PropTypes.object,
- }),
- enteredOnce: PropTypes.bool.isRequired,
- eyebrow: PropTypes.string,
- hasWideImage: PropTypes.bool,
- isContentLeftAlignedOnMobile: PropTypes.bool,
- isContentRightAligned: PropTypes.bool,
- isHeaderCentered: PropTypes.bool,
- isLongContent: PropTypes.bool,
- offset: PropTypes.bool,
- narrow: PropTypes.bool,
- title: PropTypes.string.isRequired,
- noAppear: PropTypes.bool.isRequired,
- onRef: PropTypes.func.isRequired,
- images: PropTypes.arrayOf(PropTypes.object),
- videoId: PropTypes.string,
- videoPoster: PropTypes.shape({
- url: PropTypes.string,
- }),
- }
- static defaultProps = {
- accentImage: null,
- buttons: null,
- description: null,
- eyebrow: null,
- hasWideImage: null,
- images: null,
- isContentLeftAlignedOnMobile: false,
- isContentRightAligned: false,
- isHeaderCentered: false,
- isLongContent: false,
- offset: false,
- narrow: false,
- videoId: null,
- videoPoster: null,
- }
- render() {
- const {
- accentImage,
- buttons,
- description,
- enteredOnce,
- eyebrow,
- hasWideImage,
- images,
- isContentLeftAlignedOnMobile,
- isContentRightAligned,
- isHeaderCentered,
- isLongContent,
- narrow,
- noAppear,
- offset,
- onRef,
- title,
- videoId,
- videoPoster,
- } = this.props
- const wrapperClass = classNames(styles.wrapper, {
- [styles.transitionInverted]: isContentRightAligned,
- [styles.isHeaderCentered]: isHeaderCentered,
- [styles.narrow]: narrow,
- enteredOnce,
- noAppear,
- })
- const flexWrapperClass = classNames(styles.flexWrapper, {
- [styles.narrow]: narrow,
- [styles.offset]: offset,
- [styles.longContent]: isLongContent,
- [styles.inverted]: isContentRightAligned,
- [styles.leftAlignedOnMobile]: isContentLeftAlignedOnMobile,
- })
- const mediaWrapperClass = classNames(styles.mediaWrapper, {
- [styles.hasWideImage]: hasWideImage,
- })
- const titleClass = classNames(styles.title, typography.h1)
- const eyebrowClass = classNames(styles.eyebrow, typography.eyebrow)
- const ContentHeadingClass = classNames(styles.contentHeading, typography.h3)
- const ContentEyebrowClass = classNames(styles.contentEyebrow, typography.eyebrow)
- const ContentParagraphClass = classNames(styles.contentParagraph, typography.body)
- const imageWidth = offset ? 1508 : 1276
- const ImageSide = (
- <div className={mediaWrapperClass}>
- {images &&
- images.map((image, index) => {
- if (images.length >= 2) {
- const speed = index === 0 ? 30 : 20
- const reverse = index === 0
- return (
- <Parallax
- key={image.id}
- speed={speed}
- extraClassName={styles.media}
- reverse={reverse}
- imageToLoad={image ? contentfulResize(image.file.url, imageWidth) : null}
- >
- <img
- src={image ? contentfulResize(image.file.url, imageWidth) : ''}
- alt={image.description || ''}
- key={image.id}
- />
- </Parallax>
- )
- }
- return (
- <img
- className={styles.media}
- src={image ? contentfulResize(image.file.url, imageWidth) : ''}
- alt={image.description || ''}
- key={image.id}
- />
- )
- })}
- {videoId && videoPoster && (
- <VideoEmbed videoId={videoId} videoPoster={videoPoster} />
- )}
- </div>
- )
- // Allowed styles: plain text, bold text
- const descriptionOptions = {
- renderNode: {
- [BLOCKS.HEADING_3]: (node, children) => <p className={ContentHeadingClass}>{children}</p>,
- [BLOCKS.HEADING_6]: (node, children) => <p className={ContentEyebrowClass}>{children}</p>,
- [BLOCKS.PARAGRAPH]: (node, children) => <p className={ContentParagraphClass}>{children}</p>,
- },
- renderText: text => widowFix(text),
- }
- return (
- <Container ref={onRef} extraClassName={wrapperClass}>
- {isHeaderCentered && (
- <div className={styles.headerCentered}>
- {eyebrow && <div className={eyebrowClass}>{eyebrow}</div>}
- <h2 className={titleClass}>{widowFix(title)}</h2>
- </div>
- )}
- <div className={flexWrapperClass}>
- {isContentRightAligned && ImageSide}
- <div className={styles.contentWrapper}>
- {accentImage && (
- <img
- src={contentfulResize(accentImage.file.url, 928) || ''}
- alt={accentImage.description || ''}
- className={styles.accentImage}
- />
- )}
- {!isHeaderCentered && (
- <>
- {eyebrow && <div className={eyebrowClass}>{eyebrow}</div>}
- <h2 className={titleClass}>{widowFix(title)}</h2>
- </>
- )}
- <div className={styles.description}>
- {description && documentToReactComponents(description.json, descriptionOptions)}
- </div>
- {buttons && buttons[0] && (
- <div className={styles.buttonWrapper}>
- {buttons && buttons[0] && (
- <ButtonPrimary text={buttons[0].text} link={buttons[0].url} extraClassName={styles.primaryButton} />
- )}
- {buttons && buttons[1] && (
- <ButtonSecondary
- text={buttons[1].text}
- link={buttons[1].url}
- extraClassName={styles.secondaryButton}
- />
- )}
- </div>
- )}
- </div>
- {!isContentRightAligned && ImageSide}
- </div>
- </Container>
- )
- }
- }
- export const SplitContentFragment = graphql`
- fragment SplitContent on ContentfulSectionSplitContent {
- id
- title
- eyebrow
- description {
- json
- }
- accentImage {
- file {
- url
- fileName
- contentType
- }
- }
- background {
- theme
- color
- }
- images {
- id
- file {
- url
- fileName
- contentType
- }
- }
- narrow
- offset
- buttons {
- text
- url
- }
- isContentRightAligned
- isContentLeftAlignedOnMobile
- isHeaderCentered
- isLongContent
- hasWideImage
- }
- `
- export const SplitContentWithVideoFragment = graphql`
- fragment SplitContentWithVideo on ContentfulSectionSplitContentWithVideo {
- id
- title
- eyebrow
- description {
- json
- }
- accentImage {
- file {
- url
- fileName
- contentType
- }
- }
- videoId
- videoPoster {
- file {
- url
- fileName
- contentType
- }
- }
- offset
- buttons {
- text
- url
- }
- isContentRightAligned
- isContentLeftAlignedOnMobile
- isHeaderCentered
- }
- `
- export default withIntersectionObserver()(SplitContent)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement