<section class="related-articles" aria-labelledby="related-articles" data-module="relatedArticles">
    <h2 id="related-articles" class="related-articles__title">Related Articles</h2>
    <div class="related-articles__cards">
        <article class="article-card">
            <a class="article-card__link" href="#">
                <h3 class="article-card__title" style="overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 3;">
                    Card Title 1
                </h3>
                <p class="article-card__date">
                    Month DD, YYYY
                </p>
                <p class="article-card__description">
                    Lorem ipsum dolor sit amet
                </p>
            </a>
        </article>
        <article class="article-card">
            <a class="article-card__link" href="#">
                <h3 class="article-card__title" style="overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 3;">
                    Card Title 2
                </h3>
                <p class="article-card__date">
                    Month DD, YYYY
                </p>
                <p class="article-card__description">
                    Lorem ipsum dolor sit amet
                </p>
            </a>
        </article>
        <article class="article-card">
            <a class="article-card__link" href="#">
                <h3 class="article-card__title" style="overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 3;">
                    Card Title 3
                </h3>
                <p class="article-card__description">
                    Lorem ipsum dolor sit amet
                </p>
            </a>
        </article>
        <article class="article-card">
            <a class="article-card__link" href="#">
                <h3 class="article-card__title" style="overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 3;">
                    Card Title 4
                </h3>
                <p class="article-card__date">
                    Month DD, YYYY
                </p>
            </a>
        </article>
    </div>
</section>
{{#*inline "related-article-card"}}
  <article class="article-card">
    <a class="article-card__link" href="#">
      <h3 class="article-card__title" style="overflow: hidden; text-overflow: ellipsis; -webkit-box-orient: vertical; display: -webkit-box; -webkit-line-clamp: 3;">
        {{title}}
      </h3>
      {{#if date}}
      <p class="article-card__date">
        {{date}}
      </p>
      {{/if}}
      {{#if summary}}
      <p class="article-card__description">
        {{summary}}
      </p>
      {{/if}}
    </a>
  </article>
{{/inline}}

<section class="related-articles" aria-labelledby="related-articles" data-module="relatedArticles">
  <h2 id="related-articles" class="related-articles__title">{{heading}}</h2>
  <div class="related-articles__cards">
    {{#json items}}
      {{#each this}}
        {{> related-article-card}}
      {{/each}}
    {{/json}}
  </div>
</section>
{
  "heading": "Related Articles",
  "items": [
    {
      "title": "Card Title 1",
      "date": "Month DD, YYYY",
      "summary": "Lorem ipsum dolor sit amet"
    },
    {
      "title": "Card Title 2",
      "date": "Month DD, YYYY",
      "summary": "Lorem ipsum dolor sit amet"
    },
    {
      "title": "Card Title 3",
      "summary": "Lorem ipsum dolor sit amet"
    },
    {
      "title": "Card Title 4",
      "date": "Month DD, YYYY"
    }
  ]
}
  • Content:
    @import '../theme', 'variables';
    
    .related-articles {
      margin-bottom: 0;
      padding-bottom: 60px;
      padding-top: 60px;
    
      @include mq($until: desktop) {
        margin-top: 0;
      }
    
      @include mq(desktop) {
        padding-bottom: 100px;
      }
    }
    
    .related-articles__title {
      font-size: 30px;
      font-weight: 500;
      line-height: 1.2;
      margin: 0 0 40px;
      color: $article-card-headline;
    
      @include mq(desktop) {
        font-size: 48px;
        line-height: 1.13;
      }
    }
    
    .related-articles__cards {
      & > * {
        & + * {
          margin-top: 24px;
        }
      }
    
      @include mq($from: tablet, $until: desktop) {
        display: flex;
        flex-wrap: wrap;
    
        & > * {
          margin-top: 0;
          width: calc(50% - 12px);
    
          &:nth-child(even) {
            margin-left: 24px;
          }
    
          &:nth-child(n+3) {
            margin-top: 24px;
          }
        }
      }
    
      @include mq(desktop) {
        display: flex;
        flex-wrap: wrap;
    
        & > * {
          margin-left: 23px;
          margin-top: 0;
          width: calc(25% - 18px);
    
          &:nth-child(4n-3) {
            margin-left: 0;
          }
    
          &:nth-child(n+5) {
            margin-top: 24px;
          }
        }
      }
    }
    
    .article-card {
      background-color: $article-card-bg;
      border: 1px solid $article-card-border;
      border-radius: 2px;
      overflow: hidden;
      position: relative;
      transition: box-shadow 0.3s ease-in-out, transform 0.3s ease-in-out;
    
      &:hover {
        @include mq(desktop) {
          box-shadow: 0 20px 15px 0 rgba(0, 0, 0, 0.15);
          transform: translateY(-10px);
        }
      }
    
      a {
        text-decoration: none;
      }
    
      @include mq(desktop) {
        width: calc(25% - 18px);
      }
    }
    
    .article-card__title {
      color: $article-card-title;
      font-size: 24px;
      font-weight: 500;
      margin: 0 0 12px;
    }
    
    .article-card__date,
    .article-card__description {
      color: $article-card-text;
      font-size: 14px;
      margin: 0 0 8px;
    }
    
    .article-card__link {
      display: block;
      height: 100%;
      padding: 20px 30px 28px;
    }
    
  • URL: /components/raw/c-grd-2-related-content-row/_styles.scss
  • Filesystem Path: src/components/C-GRD-2-related-content-row/_styles.scss
  • Size: 1.9 KB
  • Content:
    $article-card-bg: #fff !default;
    $article-card-border: map-get($theme-colors, 'primary-light-gray') !default;
    $article-card-title: map-get($theme-colors, 'primary-dark') !default;
    $article-card-text: map-get($theme-colors, 'primary') !default;
    $article-card-headline: map-get($theme-colors, 'primary') !default;
    
  • URL: /components/raw/c-grd-2-related-content-row/_variables.scss
  • Filesystem Path: src/components/C-GRD-2-related-content-row/_variables.scss
  • Size: 312 Bytes
  • Content:
    import { Component } from '@verndale/core'
    import Swiper, { Pagination, Navigation } from 'swiper'
    
    Swiper.use([Pagination, Navigation])
    
    class Module extends Component {
      setupDefaults() {
        this.dom = {
          container: this.el.querySelector('.swiper-container'),
          pagination: this.el.querySelector('.swiper-pagination'),
          next: this.el.querySelector('.swiper-button-next'),
          prev: this.el.querySelector('.swiper-button-prev'),
          breakpoint: this.el.dataset.breakpoint
        }
        this.slider = null
    
        if (!this.dom.breakpoint) {
          this.dom.breakpoint = 320
        }
        this.isMobile = window.matchMedia(`(max-width:${this.dom.breakpoint}px)`)
    
        if (this.isMobile.matches) {
          this.initSlider()
        }
      }
    
      addListeners() {
        window.addEventListener(
          'resize',
          this.debounce((e) => {
            // if is not mobile and there is a slider, destroy swiper slider func
            if (!this.isMobile.matches && this.slider) {
              this.slider.destroy(true, true)
            } else {
              if (this.isMobile.matches) {
                this.initSlider()
              }
            }
          })
        )
      }
    
      debounce(func, timeParam) {
        const time = timeParam || 1000 // 100 by default if no param
        let timer
        // eslint-disable-next-line space-before-function-paren
        return function (event) {
          if (timer) clearTimeout(timer)
          timer = setTimeout(func, time, event)
        }
      }
    
      initSlider() {
        this.slider = new Swiper(this.dom.container, {
          centeredSlides: true,
          spaceBetween: 25,
          pagination: {
            el: this.dom.pagination
          },
          navigation: {
            nextEl: this.dom.next,
            prevEl: this.dom.prev
          }
        })
      }
    }
    
    export default Module
    
  • URL: /components/raw/c-grd-2-related-content-row/related-articles.js
  • Filesystem Path: src/components/C-GRD-2-related-content-row/related-articles.js
  • Size: 1.7 KB
  • Handle: @c-grd-2-related-content-row
  • Preview:
  • Filesystem Path: src/components/C-GRD-2-related-content-row/C-GRD-2-related-content-row.hbs

Related Articles

Displays up to four Article Cards

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/related-articles/styles';

Copy and paste to your project any of the markup - 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 module 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

// Colors
$article-card-bg
$article-card-border
$article-card-title
$article-card-text
$gap: 15px;

@import '../../node_modules/@verndale/front-end-components/lib/related-articles/styles';