<section class="column-row" data-module="column-row" data-breakpoint=767 aria-labelledby="columnRowHeading">
<header>
<h2 class="column-row__heading" id="columnRowHeading">4 columns row</h2>
<div class="column-row__copy rtf">Praesent dui elit, porttitor sed vulputate id, mollis sed nibh. Morbi molestie scelerisque diam, at efficitur erat auctor vitae. Proin vehicula volutpat consequat. Donec sit amet magna sed urna egestas feugiat in et nisi. Suspendisse risus dolor, maximus sit amet pharetra sed, convallis sed orci. Nulla sit amet nisi cursus, blandit ipsum vel, feugiat nisl.</div>
</header>
<div class="swiper-container">
<!-- additional required wrapper -->
<div class="swiper-wrapper swiper-wrapper--">
<!-- slides -->
<aside class="swiper-slide">
<article class="content-card content-card--no-image ">
<!-- Display this div if image exists-->
<picture class="content-card__image">
<source media="(max-width: 767px)" srcset="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=767&h=430">
<source media="(max-width: 1279px)" srcset="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=1280&h=717">
<img src="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=790&h=444" alt="Image Description" loading="lazy">
</picture>
<div class="content-card__wrapper">
<h6 class="content-card__heading">Default</h6>
<div class="content-card__copy">Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Maecenas faucibus mollis interdum.</div>
<div class="content-card__actions">
<a href=# class="btn btn--primary btn--small">
Action
</a>
</div>
</div>
</article>
</aside>
<aside class="swiper-slide">
<article class="content-card content-card--no-image ">
<!-- Display this div if image exists-->
<picture class="content-card__image">
<source media="(max-width: 767px)" srcset="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=767&h=430">
<source media="(max-width: 1279px)" srcset="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=1280&h=717">
<img src="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=790&h=444" alt="Image Description" loading="lazy">
</picture>
<div class="content-card__wrapper">
<h6 class="content-card__heading">Default</h6>
<div class="content-card__copy">Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Maecenas faucibus mollis interdum.</div>
<div class="content-card__actions">
<a href=# class="btn btn--primary btn--small">
Action
</a>
</div>
</div>
</article>
</aside>
<aside class="swiper-slide">
<article class="content-card content-card--no-image ">
<!-- Display this div if image exists-->
<picture class="content-card__image">
<source media="(max-width: 767px)" srcset="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=767&h=430">
<source media="(max-width: 1279px)" srcset="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=1280&h=717">
<img src="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=790&h=444" alt="Image Description" loading="lazy">
</picture>
<div class="content-card__wrapper">
<h6 class="content-card__heading">Default</h6>
<div class="content-card__copy">Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Maecenas faucibus mollis interdum.</div>
<div class="content-card__actions">
<a href=# class="btn btn--primary btn--small">
Action
</a>
</div>
</div>
</article>
</aside>
<aside class="swiper-slide">
<article class="content-card content-card--no-image ">
<!-- Display this div if image exists-->
<picture class="content-card__image">
<source media="(max-width: 767px)" srcset="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=767&h=430">
<source media="(max-width: 1279px)" srcset="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=1280&h=717">
<img src="https://verndale-image-tools.herokuapp.com/random/mountains?seed=1&w=790&h=444" alt="Image Description" loading="lazy">
</picture>
<div class="content-card__wrapper">
<h6 class="content-card__heading">Default</h6>
<div class="content-card__copy">Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Maecenas faucibus mollis interdum.</div>
<div class="content-card__actions">
<a href=# class="btn btn--primary btn--small">
Action
</a>
</div>
</div>
</article>
</aside>
</div>
<!-- pagination -->
<div class="column-row__pagination">
<div class="swiper-button-prev"></div>
<div class="swiper-pagination"></div>
<div class="swiper-button-next"></div>
</div>
</div>
<div class="column-row__copy rtf">Praesent dui elit, porttitor sed vulputate id, mollis sed nibh. Morbi molestie scelerisque diam, at efficitur erat auctor vitae. Proin vehicula volutpat consequat. Donec sit amet magna sed urna egestas feugiat in et nisi. Suspendisse risus dolor, maximus sit amet pharetra sed, convallis sed orci. Nulla sit amet nisi cursus, blandit ipsum vel, feugiat nisl.</div>
</section>
<section class="column-row" data-module="column-row" data-breakpoint=767 aria-labelledby="columnRowHeading">
<header>
<h2 class="column-row__heading" id="columnRowHeading">{{heading}}</h2>
<div class="column-row__copy rtf">{{copy_intro}}</div>
</header>
<div class="swiper-container">
<!-- additional required wrapper -->
<div class="swiper-wrapper swiper-wrapper--{{type}}">
<!-- slides -->
{{#json items}}
{{#each this}}
<aside class="swiper-slide">
{{>@content-card
heading= "Default"
copy= "Integer posuere erat a ante venenatis dapibus posuere velit aliquet. Maecenas faucibus mollis interdum."
ctaLabel= "Action"
cta= "#"
icon= "chevron-right"
}}
</aside>
{{/each}}
{{/json}}
</div>
<!-- pagination -->
<div class="column-row__pagination">
<div class="swiper-button-prev"></div>
<div class="swiper-pagination"></div>
<div class="swiper-button-next"></div>
</div>
</div>
<div class="column-row__copy rtf">{{copy_outro}}</div>
</section>
{
"heading": "4 columns row",
"copy_intro": "Praesent dui elit, porttitor sed vulputate id, mollis sed nibh. Morbi molestie scelerisque diam, at efficitur erat auctor vitae. Proin vehicula volutpat consequat. Donec sit amet magna sed urna egestas feugiat in et nisi. Suspendisse risus dolor, maximus sit amet pharetra sed, convallis sed orci. Nulla sit amet nisi cursus, blandit ipsum vel, feugiat nisl.",
"copy_outro": "Praesent dui elit, porttitor sed vulputate id, mollis sed nibh. Morbi molestie scelerisque diam, at efficitur erat auctor vitae. Proin vehicula volutpat consequat. Donec sit amet magna sed urna egestas feugiat in et nisi. Suspendisse risus dolor, maximus sit amet pharetra sed, convallis sed orci. Nulla sit amet nisi cursus, blandit ipsum vel, feugiat nisl.",
"items": [
{
"title": "Card for iteration only"
},
{
"title": "Card for iteration only"
},
{
"title": "Card for iteration only"
},
{
"title": "Card for iteration only"
}
]
}
@import '../theme', 'variables';
.column-row__heading {
font-family: $column-row-title-font;
font-size: 30px;
font-weight: 700;
line-height: 1.13;
margin: 0 0 10px;
}
.column-row .swiper-wrapper {
margin: 20px 0;
display: flex;
@include mq(tablet) {
display: grid;
row-gap: $gap;
column-gap: $gap;
grid-template-columns: repeat(2, 1fr);
}
&--three {
@include mq(tablet-landscape) {
grid-template-columns: repeat(3, 1fr);
}
}
&--four {
@include mq(tablet-landscape) {
grid-template-columns: repeat(4, 1fr);
}
}
}
.swiper-slide {
width: 100%;
& > div {
width: 100%;
}
// @include mq(tablet) {
// width: 24%;
// }
}
.column-row__copy {
margin-top: 15px;
}
.column-row__pagination {
align-items: center;
display: flex;
gap: 8px;
justify-content: center;
margin-top: 20px;
.swiper-pagination-bullet {
background-color: $swiper-pagination-bullet;
border-radius: 0;
height: 4px;
opacity: 1;
transition: width 300ms linear;
width: 12px;
}
.swiper-pagination-bullet + .swiper-pagination-bullet {
margin-left: 4px;
}
.swiper-pagination-bullet-active {
background-color: $swiper-pagination-bullet-active;
width: 15px;
}
.swiper-pagination {
display: flex;
gap: 4px;
height: 4px;
position: static;
}
.swiper-button-prev,
.swiper-button-next {
align-items: center;
border-radius: 999px;
display: flex;
height: $swiper-button-size;
justify-content: center;
margin-top: 0;
position: static;
width: $swiper-button-size;
&:hover {
background-color: $swiper-pagination-bullet;
}
&::after {
color: $swiper-pagination-bullet-active;
font-size: 24px;
transform: translate(1px, -3px);
}
}
.swiper-button-prev {
&::after {
content: '‹';
}
}
.swiper-button-next {
&::after {
content: '›';
}
}
@include mq(tablet) {
display: none;
}
}
$column-row-title-font: $primary-font !default;
$gap: 15px;
$swiper-pagination-bullet: map-get(
$theme-colors,
'primary-light-gray'
) !default;
$swiper-pagination-bullet-active: map-get(
$theme-colors,
'primary-gray'
) !default;
$swiper-button-size: 40px;
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
Allow content authors to create cards that can be displayed in the a 3 or up layout. (sample included 3 and 4 columns)
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/alert/styles';
Copy and paste to your project any of the markup in the alert variations - you can find the markup in the HTML tab.
The component will already have a default style/theme set, so it will work out of the box. The alert 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
// Font for title
$column-row-title-font
// Gap between cards right and bottom
$gap
// Swiper styles fro slider mobile
$swiper-pagination-bullet
$swiper-pagination-bullet-active
$swiper-button-size
$gap: 15px;
@import '../../node_modules/@verndale/front-end-components/lib/colum-row/styles';