Video

<section class="testimonials container scEnabledChrome" data-module="testimonials" sc-part-of="placeholder rendering">
    <header>
        <h2 class="testimonials__heading">
            <span class="scChromeData"></span><span id="fld_77D47B44369D4ACE84D66C17A275811D_1D631840345E4DDEB0539099EA076EEE_en_1_e6929504dae7493c83cb7b24225421d3_292_edit" sc_parameters="prevent-line-break=true" contenteditable="true" class="scWebEditInput scEnabledChrome" scfieldtype="single-line text" scdefaulttext="[No text in field]" sc-part-of="field">Testimonial Carousel</span>
        </h2>
    </header>
    <div class="testimonials__slider">
        <div class="swiper-container swiper-container-initialized swiper-container-horizontal swiper-container-pointer-events">
            <div class="swiper-wrapper">
                <span type="text/sitecore" sc-part-of="placeholder rendering" style="display: none;" class="scEnabledChrome"></span>
                <div class="scEnabledChrome scEmptyPlaceholder" sc-placeholder-id="_Rows_TestimonialCarouselCards__C42E4A27_B288_4A35_82D6_BDF2B96BB2CA__0" sc-part-of="placeholder"></div><code type="text/sitecore" id="scEnclosingTag_" chrometype="placeholder" kind="close" hintname="TestimonialCarouselCards" class="scpm">
            </div>
        </div>
    </div>
</section>
<section class="testimonials container scEnabledChrome" data-module="testimonials" sc-part-of="placeholder rendering">
	<header>
		<h2 class="testimonials__heading">
			<span class="scChromeData"></span><span id="fld_77D47B44369D4ACE84D66C17A275811D_1D631840345E4DDEB0539099EA076EEE_en_1_e6929504dae7493c83cb7b24225421d3_292_edit" sc_parameters="prevent-line-break=true" contenteditable="true" class="scWebEditInput scEnabledChrome" scfieldtype="single-line text" scdefaulttext="[No text in field]" sc-part-of="field">Testimonial Carousel</span>
		</h2>
	</header>
	<div class="testimonials__slider">
		<div class="swiper-container swiper-container-initialized swiper-container-horizontal swiper-container-pointer-events">
			<div class="swiper-wrapper">
				<span type="text/sitecore" sc-part-of="placeholder rendering" style="display: none;" class="scEnabledChrome"></span><div class="scEnabledChrome scEmptyPlaceholder" sc-placeholder-id="_Rows_TestimonialCarouselCards__C42E4A27_B288_4A35_82D6_BDF2B96BB2CA__0" sc-part-of="placeholder"></div><code type="text/sitecore" id="scEnclosingTag_" chrometype="placeholder" kind="close" hintname="TestimonialCarouselCards" class="scpm">
			</div>
		</div>
	</div>
</section>
{
  "image": {
    "srcset": {
      "767": "https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=767&h=430",
      "1279": "https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=1280&h=717"
    },
    "src": "https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=790&h=444",
    "description": "Image Description"
  },
  "autoplay": false,
  "videoId": "DSLgAsrcpGQ",
  "videoPlayer": "youtube",
  "background": true
}
  • Content:
    @import 'variables';
    
    .video {
      cursor: pointer;
      height: 0;
      overflow: hidden;
      padding-bottom: 56.25%;
      position: relative;
      width: 100%;
    
      &:hover {
        svg {
          fill: $primary-color;
        }
      }
    
      video,
      iframe {
        height: 100%;
        left: 0;
        object-fit: cover;
        position: absolute;
        top: 0;
        width: 100%;
      }
    
      svg {
        bottom: 20px;
        fill: $svg-color;
        height: 30px;
        position: absolute;
        right: 20px;
        transition: fill 0.2s ease-in-out;
        width: 30px;
        z-index: 1;
    
        @include mq(desktop) {
          bottom: 30px;
          right: 30px;
        }
      }
    
      &.video--playing {
        svg {
          display: none;
        }
      }
    }
    
    .video__background {
      left: 0;
      padding-bottom: 56.25%;
      position: absolute;
      top: 50%;
      transform: translateY(-50%);
      width: 100%;
    }
    
    .full-background-video {
      iframe {
        pointer-events: none;
      }
    }
    
    .video__poster {
      picture,
      img {
        height: 100%;
        left: 0;
        object-fit: cover;
        position: absolute;
        top: 0;
        width: 100%;
      }
    }
    
  • URL: /components/raw/video/_styles.scss
  • Filesystem Path: src/components/video/_styles.scss
  • Size: 1 KB
  • Content:
    import { Component } from '@verndale/core'
    
    class Module extends Component {
      setupDefaults() {
        this.dom = {
          poster: this.el.querySelector('.video__poster'),
          backgroundVideo: this.el.querySelector('.video__background'),
          icon: this.el.querySelector('svg'),
          videoPoster: this.el.parentNode.querySelector(
            'picture:not(.video__poster)'
          ),
          video: this.el.querySelector('video')
        }
    
        this.initialized = false
        this.videoId = this.el.dataset.videoId
        this.videoPlayer = this.el.dataset.videoPlayer
        this.videoBackgroundImage = this.el.dataset.videoBackgroundImage
        this.vimeoPlayer = 'vimeo'
        this.youtubePlayer = 'youtube'
        this.localVideo = 'video'
        this.vimeoScript = 'https://player.vimeo.com/api/player.js'
      }
    
      addListeners() {
        if (this.videoBackgroundImage === 'false') {
          this.removeCover()
          this.getCurrentPlayer(false)
          return
        }
    
        if (!this.el.dataset.videoAutoPlay !== true) {
          this.el.addEventListener('click', this.getCurrentPlayer.bind(this, true))
        }
    
        if (this.el.dataset.videoAutoPlay === 'true') {
          this.removeCover()
          this.el.classList.add('full-background-video')
          if (this.vimeoPlayer === this.el.dataset.videoPlayer) {
            return this.dom.backgroundVideo.appendChild(this.getVimeoIframe(true))
          }
          if (this.youtubePlayer === this.el.dataset.videoPlayer) {
            return this.dom.backgroundVideo.appendChild(
              this.getYoutubeIframe(true, 1)
            )
          }
          if (this.localVideo === this.el.dataset.videoPlayer) {
            this.dom.backgroundVideo.appendChild(this.getLocalVideo(true))
            return
          }
          return
        }
      }
    
      getCurrentPlayer(autoplay) {
        if (this.initialized) return
        if (this.vimeoPlayer === this.el.dataset.videoPlayer) {
          return this.handleInitVideos(
            this.el.dataset.videoPlayer,
            this.getVimeoIframe(autoplay)
          )
        }
    
        if (this.youtubePlayer === this.el.dataset.videoPlayer) {
          return this.handleInitVideos(
            this.el.dataset.videoPlayer,
            this.getYoutubeIframe(false, autoplay)
          )
        }
    
        if (this.localVideo === this.el.dataset.videoPlayer) {
          this.handleInitVideos(
            this.el.dataset.videoPlayer,
            this.getLocalVideo(autoplay)
          )
          this.addVideoListeners()
        }
    
        return null
      }
    
      addVideoListeners() {
        this.video = this.el.querySelector('video')
        if (!this.initialized) {
          this.definePlayingObject()
          return
        }
    
        this.video.addEventListener('click', this.handleVideoClick.bind(this))
        this.video.addEventListener('play', this.handleVideoPlay.bind(this))
        this.video.addEventListener('pause', this.handleVideoPause.bind(this))
        this.video.addEventListener('ended', this.handleVideoEnd.bind(this))
        return
      }
    
      definePlayingObject() {
        Object.defineProperty(this.video, 'playing', {
          // eslint-disable-next-line object-shorthand
          get: function() {
            return !!(
              this.currentTime > 0 &&
              !this.paused &&
              !this.ended &&
              this.readyState > 2
            )
          }
        })
      }
    
      getYoutubeIframe(controls = false, autoplay) {
        const iframe = document.createElement('iframe')
    
        iframe.setAttribute('width', 640)
        iframe.setAttribute('height', 360)
        iframe.setAttribute('frameborder', 0)
        iframe.setAttribute(
          'src',
          `https://www.youtube.com/embed/${
            this.videoId
          }?modestbranding=1&rel=0&showinfo=0&autohide=1&autoplay=${autoplay}&mute=1${
            controls ? '&controls=0' : ''
          }`
        )
        return iframe
      }
    
      getVimeoIframe(autoplay) {
        const iframe = document.createElement('iframe')
        iframe.setAttribute('width', 640)
        iframe.setAttribute('height', 360)
        iframe.setAttribute('frameborder', 0)
        iframe.setAttribute('webkitallowfullscreen', 'webkitallowfullscreen')
        iframe.setAttribute('mozallowfullscreen', 'mozallowfullscreen')
        iframe.setAttribute('allowfullscreen', 'allowfullscreen')
        iframe.setAttribute('allow', 'autoplay')
        iframe.setAttribute(
          'src',
          `https://player.vimeo.com/video/${this.videoId}?title=false&autoplay=${autoplay}&muted=1`
        )
        return iframe
      }
    
      getLocalVideo(autoplay) {
        const video = document.createElement('video')
        const source = document.createElement('source')
    
        source.src = this.el.dataset.videoId
        video.autoplay = autoplay
        video.poster = this.el.dataset.videoPoster
        video.appendChild(source)
        return video
      }
    
      removeCover() {
        if (this.dom.poster) this.dom.poster.remove()
        if (this.dom.icon) this.dom.icon.remove()
      }
    
      addVimeoScript() {
        const script = document.createElement('script')
        script.setAttribute('src', this.vimeoScript)
        document.body.prepend(script)
      }
    
      handleInitVideos(videoType, iframe) {
        if (videoType === this.vimeoPlayer) {
          this.addVimeoScript()
        }
    
        if (videoType === this.localVideo) {
          this.removeCover()
        }
    
        if (!this.initialized) {
          iframe.onload = () => {
            this.removeCover()
          }
          this.dom.backgroundVideo.appendChild(iframe)
          this.initialized = true
        }
      }
    
      handleVideoClick() {
        if (!this.video.playing) {
          this.video.play()
        }
      }
    
      handleVideoPlay() {
        this.video.classList.add('video--playing')
        this.video.setAttribute('controls', 'controls')
      }
    
      handleVideoPause() {
        this.video.classList.remove('video--playing')
        this.video.removeAttribute('controls')
      }
    
      handleVideoEnd() {
        this.video.classList.remove('video--playing')
        this.video.removeAttribute('controls')
        this.video.currentTime = 0
        this.video.load()
      }
    }
    
    export default Module
    
  • URL: /components/raw/video/video.js
  • Filesystem Path: src/components/video/video.js
  • Size: 5.7 KB

Button

This component can be both a <button> and a link (<a>) that looks like a button. There are two different themes to this button. One is a light button (primary) that will be used on darker backgrounds, and a lighter button (secondary) that will be used on darker background.

Usage

Add the front-end-copmonent library to your project

yarn add @verndale/front-end-components

Import the style to your main style file in your project

@import "../../node_modules/@verndale/front-end-components/lib/button/styles";

Copy and paste to your project any of the markup in the button variations - you can find the markup in the HTML tab.


Styling

The component will already have a default style/theme set, so it will work out of the box. The button has a set of variables that may be overriden, or you may choose to just override the actual styles in your project. It is recommended to use the overrides if you can as it will be less code in your project.

Below is the list of variables you can override. You may also find these in the Assets tab under _variables.scss

// Primary button
$btn-primary-background
$btn-primary-focus-background
$btn-primary-text-color
$btn-primary-outline-border
$btn-primary-outline-text-color
$btn-primary-outline-focus-background
$btn-primary-outline-focus-border
$btn-primary-outline-focus-text-color
$btn-primary-disabled-background
$btn-primary-disabled-text-color

// Secondary button
$btn-secondary-background
$btn-secondary-focus-background
$btn-secondary-focus-text-color
$btn-secondary-text-color
$btn-secondary-outline-border
$btn-secondary-outline-text-color
$btn-secondary-outline-focus-background
$btn-secondary-outline-focus-text-color
$btn-secondary-disabled-border
$btn-secondary-disabled-text-color

You always need to set your overrides before the import of you component - for example:

$btn-primary-background: #808080;
$btn-primary-focus-background: #101010;

@import "../../node_modules/@verndale/front-end-components/lib/button/styles";