Skip to content

Commit

Permalink
Career testimonials: create testimonials carousel block (#71)
Browse files Browse the repository at this point in the history
* Career testimonials: create testimonials carousel block

Fixes #17
  • Loading branch information
bosschaert authored Sep 29, 2023
1 parent 6dcd4c4 commit ef9becf
Show file tree
Hide file tree
Showing 6 changed files with 532 additions and 1 deletion.
148 changes: 148 additions & 0 deletions blocks/career-carousel/career-carousel.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
.career-carousel {
--card-width: 16rem;
}

.career-slider {
display: flex;
flex-direction: column;
margin-left: -1rem;
width: calc((var(--card-width) + 3rem) * 4);
overflow: hidden;
}

.career-slides {
display: flex;
overflow-x: scroll;
scroll-behavior: smooth;

/* We want to hide the scroll bar */
-ms-overflow-style: none; /* for Internet Explorer, Edge */
scrollbar-width: none; /* for Firefox */
}

/* Hide the scroll bar */
.career-slides::-webkit-scrollbar {
/* for Chrome, Safari and Opera */
display: none;
}

.career-carousel .career-card {
flex-shrink: 0;
box-shadow: #3c465040 0 2px 12px 0;
margin: 0.5rem;
padding: 1rem;
width: var(--card-width);
transition: all 0.15s ease-in-out;
}

.career-carousel .career-card:hover {
box-shadow: #3c465066 0 4px 16px 0;
}

.career-carousel .career-card a {
display: inline-flex;
flex-direction: column;
text-decoration: none;
}

.career-carousel .career-card picture {
align-self: center;
width: 14.375rem;
margin: 0 0 1.375rem;
}

.career-carousel .career-card picture img {
height: 16rem;
width: 14.375rem;
}

.career-carousel .career-card blockquote {
color: var(--primary);
font-size: var(--body-font-size-l);
font-style: normal;
line-height: 29px;
margin: 0 0 19px;
max-height: 9.375rem;
overflow: hidden;
text-indent: 0;

/* Show ellipsis on multiline text */
display: -webkit-box;
-webkit-line-clamp: 5; /* number of lines to show */
-webkit-box-orient: vertical;
}

.career-carousel .career-card .career-card-bqc {
height: 9.375rem;
margin-bottom: 0.75rem;
}

.career-carousel .career-card h6 {
color: var(--light-black);
font-size: var( --heading-font-size-mxs);
text-transform: none;
margin-bottom: 6px;
}

.career-carousel .career-card p {
color: var(--light-black);
font-size: var(--body-font-size-s);
height: 2.5rem;
line-height: 21.6px;
margin-bottom: 0.75rem;
overflow: hidden;
text-overflow: ellipsis;
}

.career-carousel .career-card button {
background-color: unset;
color: var(--secondary);
font-family: var(--body-font-family);
font-size: var(--body-font-size-m);
font-weight: var(--font-weight-medium);
justify-content: left;
height: auto;
padding: 0;
margin-block: 1rem;
}

.career-carousel .career-card button:hover {
text-decoration: underline;
}

.career-carousel .career-card button .icon-angle-right-blue {
height: 14px;
width: 10px;
margin-left: 6px;
margin-top: 2px;
}

.career-carousel .career-slides-navbar {
display: flex;
}

.career-carousel .career-slides-nav {
display: inline-flex;
align-items: center;
margin-top: 3.125rem;
margin-bottom: 2.5rem;
margin-inline: auto;
}

.career-carousel .career-slides-nav span {
width: 6px;
height: 6px;
margin: 0 3px;
border-radius: 50%;
background: #0003;
}

.career-carousel .career-slides-nav span.active-nav {
background: var(--link-color);
}

.career-carousel .career-slides-nav .btn-angle {
height: 1.5rem;
width: 1rem;
margin-inline: 0.5rem;
}
144 changes: 144 additions & 0 deletions blocks/career-carousel/career-carousel.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
import { createOptimizedPicture } from '../../scripts/lib-franklin.js';
import { fetchIndex } from '../../scripts/scripts.js';

export function filterIncompleteEntries(json) {
return json.data.filter((e) => e.image !== '' && e['career-quote'] !== '0' && e['career-jobtitle'] !== '0');
}

export function scrollToCard(idx, card, precedingCard, slides, span, doc) {
const rect = card.getBoundingClientRect();

// set the style on the active button
const buttons = doc.querySelectorAll('.career-slides-nav span.active-nav');
buttons.forEach((b) => b.classList.remove('active-nav'));
span.classList.add('active-nav');

// Compute the gap to add to the location
let gap = 0;
if (precedingCard) {
const prevRect = precedingCard.getBoundingClientRect();
gap = rect.x - (prevRect.x + prevRect.width);
}

slides.scrollTo(idx * (rect.width + gap), slides.scrollHeight);
}

export function scrollToAdjacent(spans, slideDivs, slides, next, doc) {
const curActive = spans.findIndex((s) => s.classList.contains('active-nav'));
if (curActive === -1) {
return;
}

// compute the next active element, wrapping around on over- or underflow.
const newActive = (curActive + (next ? 1 : -1) + spans.length) % spans.length;
if (slideDivs.length <= newActive) {
return;
}

scrollToCard(
newActive,
slideDivs[newActive],
newActive > 0 ? slideDivs[newActive - 1] : null,
slides,
spans[newActive],
doc,
);
}

export default async function decorate(block) {
const json = await fetchIndex('query-index', 'career-testimonials');
const data = filterIncompleteEntries(json);

const careerSlider = document.createElement('div');
careerSlider.classList.add('career-slider');

const careerSlides = document.createElement('div');
careerSlides.classList.add('career-slides');

const slideDivs = [];
for (let i = 0; i < data.length; i += 1) {
const div = document.createElement('div');
div.classList.add('career-card');
const a = document.createElement('a');
a.href = data[i].path;
const pic = createOptimizedPicture(data[i].image, data[i].pagename);
a.append(pic);

const bqc = document.createElement('div');
bqc.classList.add('career-card-bqc');
const bq = document.createElement('blockquote');
bq.textContent = data[i]['career-quote'];
bqc.append(bq);
a.append(bqc);

const nm = document.createElement('h6');
nm.textContent = data[i].pagename;
a.append(nm);

const role = document.createElement('p');
role.textContent = data[i]['career-jobtitle'];
a.append(role);

const link = document.createElement('button');
link.textContent = 'Read More '; // TODO
const arrow = document.createElement('img');
arrow.src = '/icons/angle-right-blue.svg';
arrow.alt = 'Go to testimonial';
arrow.classList.add('icon-angle-right-blue');
link.append(arrow);
a.append(link);
div.append(a);

careerSlides.append(div);
slideDivs.push(div);
}
careerSlider.append(careerSlides);

const navBar = document.createElement('div');
navBar.classList.add('career-slides-navbar');
const navButtons = document.createElement('div');
navButtons.classList.add('career-slides-nav');

const buttons = [];
for (let i = 0; i < data.length; i += 1) {
const prevDiv = i > 0 ? slideDivs[i - 1] : null;

const s = document.createElement('span');
s.classList.toggle('active-nav', i === 0);
s.tabIndex = '-1';
s.onclick = () => scrollToCard(i, slideDivs[i], prevDiv, careerSlides, s, document);
navButtons.append(s);

buttons.push(s);
}
const la = document.createElement('img');
la.src = '/icons/angle-left-blue.svg';
la.alt = 'Previous person card';
la.classList.add('btn-angle');
la.onclick = () => scrollToAdjacent(buttons, slideDivs, careerSlides, false, document);
navButtons.prepend(la);

const ra = document.createElement('img');
ra.src = '/icons/angle-right-blue.svg';
ra.alt = 'Next person card';
ra.classList.add('btn-angle');
ra.onclick = () => scrollToAdjacent(buttons, slideDivs, careerSlides, true, document);
navButtons.append(ra);
navBar.append(navButtons);

block.append(careerSlider);
block.append(navBar);

document.onkeydown = (e) => {
switch (e.keyCode) {
case 37:
la.onclick();
break;
case 39:
ra.onclick();
break;
default:
// do nothing
}
};
}
1 change: 1 addition & 0 deletions icons/angle-left-blue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion icons/angle-right-blue.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions test/blocks/career-carousel/career-carousel.plain.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<div>
<div class="breadcrumb"></div>
</div>
<div>
<div class="career-carousel"></div>
</div>
Loading

0 comments on commit ef9becf

Please sign in to comment.