From 69627224d0200036040e9535584e7caabd9c35a7 Mon Sep 17 00:00:00 2001 From: Martin Leblanc <m26lebla@uwaterloo.ca> Date: Thu, 20 Feb 2025 10:32:58 -0500 Subject: [PATCH] ISTWCMS-5650: Attach the current functionality to the flickity carousel, remove all mention of Owl. --- .../03-layouts/carousel/carousel.twig | 9 +- .../04-components/banners/_banners.scss | 165 ++++++++++-------- src/patterns/04-components/banners/banners.js | 153 +++++++++------- .../04-components/banners/banners.twig | 2 +- .../card/card--banner/_card--banner.scss | 8 +- 5 files changed, 190 insertions(+), 147 deletions(-) diff --git a/src/patterns/03-layouts/carousel/carousel.twig b/src/patterns/03-layouts/carousel/carousel.twig index e0e56481..40a81bf2 100644 --- a/src/patterns/03-layouts/carousel/carousel.twig +++ b/src/patterns/03-layouts/carousel/carousel.twig @@ -8,7 +8,7 @@ {% else %} <div class="uw-carousel"> {% endif %} - <div class="carousel"> + <div class="carousel" > {% block content %} <div class="item">Item #1</div> <div class="item">Item #2</div> @@ -16,17 +16,16 @@ <div class="item">Item #4</div> <div class="item">Item #5</div> {% endblock %} - </div> {% if carousel_type == 'banner' %} - <div class="uw-owl-nav__banner-control-wrap"> - <button href="#uw-pause" id="uw-play" class="uw-owl-nav__banner-control uw-play" title="play"> + <div class="uw-nav__banner-control-wrap"> + <button href="#uw-pause" id="uw-play" class="uw-nav__banner-control uw-play" title="play"> <span class="element-invisible off-screen">Play banner slideshow</span> {% include '@components/icon/icon.twig' with { 'name': 'banner_play', } %} </button> - <button href="#uw-play" id="uw-pause" class="uw-owl-nav__banner-control uw-pause" title="pause"> + <button href="#uw-play" id="uw-pause" class="uw-nav__banner-control uw-pause" title="pause"> <span class="element-invisible off-screen">Pause banner slideshow</span> {% include '@components/icon/icon.twig' with { 'name': 'banner_pause', diff --git a/src/patterns/04-components/banners/_banners.scss b/src/patterns/04-components/banners/_banners.scss index dfddec1b..b28009d1 100644 --- a/src/patterns/04-components/banners/_banners.scss +++ b/src/patterns/04-components/banners/_banners.scss @@ -4,58 +4,59 @@ --banner-transition-speed: 400ms; } -//.uw-carousel { -// &__banner { -// .animated { -// animation-duration: var(--banner-transition-speed) !important; -// } -// -// // Used to control the display of the play-pause. -// &[data-autoplay="1"] { -// .uw-owl-nav__banner-control-wrap { -// display: block; -// } -// -// &.banner-single { -// .uw-owl-nav__banner-control-wrap { -// display: none; -// } -// } -// } -// -// &[data-autoplay="0"] { -// .uw-owl-nav__banner-control-wrap { -// display: none; -// } -// } -// -// .uw-owl-nav__banner-control-wrap { -// bottom: var(--size-5); -// display: none; -// font-size: var(--font-size-3); -// left: var(--size-1); -// order: 4; -// position: absolute; -// z-index: var(--layer-content); -// .uw-owl-nav__banner-control { -// @include button-reset(); -// box-sizing: border-box; -// display: block; -// height: var(--size-4); -// overflow: hidden; -// position: relative; -// width: var(--size-4); -// &.uw-play{ -// display: none; -// } -// -// .uw-icon{ -// display: block; -// height: var(--size-4); -// width: var(--size-4); -// } -// } -// } +.uw-carousel { + position: relative; + &__banner { + .animated { + animation-duration: var(--banner-transition-speed) !important; + } + + // Used to control the display of the play-pause. + &[data-autoplay="1"] { + .uw-nav__banner-control-wrap { + display: block !important; + } + + &.banner-single { + .uw-nav__banner-control-wrap { + display: none; + } + } + } + + &[data-autoplay="0"] { + .uw-nav__banner-control-wrap { + display: none; + } + } + + .uw-nav__banner-control-wrap { + bottom: var(--size-2); + display: none; + font-size: var(--font-size-3); + left: var(--size-1); + order: 4; + position: absolute; + z-index: var(--layer-content); + .uw-nav__banner-control { + @include button-reset(); + box-sizing: border-box; + display: block; + height: var(--size-4); + overflow: hidden; + position: relative; + width: var(--size-4); + &.uw-play{ + display: none; + } + + .uw-icon{ + display: block; + height: var(--size-4); + width: var(--size-4); + } + } + } // // .owl-stage-outer { // margin-bottom: 0; @@ -146,8 +147,8 @@ // } // } // } -// } -//} + } +} //.no-js { // .uw-carousel { @@ -227,8 +228,10 @@ .carousel { background: #FAFAFA; opacity: 0; - -webkit-transition: opacity 0.4s; - transition: opacity 0.4s; + transition: all 0.4s; + position: relative; + margin-bottom: 1.5rem; + } .carousel.is-hidden { @@ -239,52 +242,64 @@ opacity: 1; } + .flickity-button { - background: transparent !important; + background: transparent; } /* big previous & next buttons */ .flickity-prev-next-button { - width: 100px !important; - height: 100px !important; + top: 40%; + width: 5rem; + height: 5rem; } /* icon color */ .flickity-button-icon { - fill: var(--uw-gold) !important; + fill: var(--uw-black); } /* hide disabled button */ .flickity-button:disabled { - display: none !important; + display: none; } /* position dots up a bit */ .flickity-page-dots { - bottom: -2.125rem !important; + bottom: -1.5rem; + display: flex; } /* dots are lines */ .flickity-page-dots .dot { - height: 2rem !important; - min-width: 2rem !important; - @media(min-width: $screen-md) { - min-width: 5rem !important; + height: 1.5rem; + width: 100%; + margin: 0; + background: var(--gray-2); + border-radius: 0; + border-left: 1px; + border-bottom: 1px; + border-color: var(--gray-5); + border-style: solid; + opacity:1; + &:first-child { + border-left: 0; } - @media(min-width: $screen-lg) { - min-width: 10rem !important; + &.is-selected { + background:var(--uw-black); + } + &:hover, + &:focus{ + background: var(--gray-5); } - width: 100%; - margin: 0 !important; - border-radius: 0 !important; } .flickity-enabled:focus .flickity-viewport { - outline: thin dotted !important; - outline: 5px auto -webkit-focus-ring-color !important; + outline: thin dotted; + outline: 5px auto -webkit-focus-ring-color; } .flickity-button:focus { outline: none; - box-shadow: 0 0 0 5px var(--uw-black) !important; + box-shadow: 0 0 0 5px var(--uw-black); .flickity-button-icon { - fill: var(--uw-black) !important; + fill: var(--uw-black); } } diff --git a/src/patterns/04-components/banners/banners.js b/src/patterns/04-components/banners/banners.js index 3afee57d..537b4035 100644 --- a/src/patterns/04-components/banners/banners.js +++ b/src/patterns/04-components/banners/banners.js @@ -4,79 +4,108 @@ * Ensures autoplay, navigation, and pause/play functionality. */ -(function (Drupal) { +(function ($, Drupal, Flickity) { 'use strict'; Drupal.behaviors.bannersFlickity = { attach: function () { - document.querySelectorAll('.uw-carousel__banner').forEach(function (banner) { - var selector = 'div[data-uuid="' + banner.getAttribute('data-uuid') + '"] .carousel'; - var elem = document.querySelector(selector); - if (!elem) { - return; - } - - // Get the slide speed and autoplay settings. - var bannerSlideSpeed = parseInt(banner.getAttribute('data-slide-speed'), 10) || 3000; - var bannerAutoplay = banner.getAttribute('data-autoplay') !== '0' && !document.querySelector('.layout-builder'); - - // Add a class if there's only one slide. - if (elem.children.length <= 1) { - banner.classList.add('banner-single'); - } - - // Check if dots and navigation should be enabled. - var bannerDots = elem.children.length > 1; - - // Ensure Flickity is defined before initializing. - if (typeof Flickity === 'undefined') { - console.error('Flickity is not defined. Ensure the library is loaded.'); - return; - } - - // Initialize Flickity carousel. - var flkty = new Flickity(elem, { - autoPlay: bannerAutoplay ? bannerSlideSpeed : false, - cellAlign: 'left', - contain: true, - draggable: true, - fullscreen: true, - cellSelector: '.card__banner', - pageDots: bannerDots - }); + $(document).ready(function () { - // Get play and pause buttons. - var bannerPlay = banner.querySelector('.uw-play'); - var bannerPause = banner.querySelector('.uw-pause'); + document.querySelectorAll('.uw-carousel__banner').forEach(function (banner) { + var selector = 'div[data-uuid="' + banner.getAttribute('data-uuid') + '"] .carousel'; + var elem = document.querySelector(selector); + if (!elem) { + return; + } - // Attach event listeners for play and pause. - if (bannerPlay && bannerPause) { - bannerPlay.addEventListener('click', function () { - flkty.playPlayer(); - bannerPlay.style.display = 'none'; - bannerPause.style.display = 'block'; - }); + // Get the slide speed and autoplay settings. + var bannerSlideSpeed = parseInt(banner.getAttribute('data-slide-speed'), 10) || 3000; + var bannerAutoplay = banner.getAttribute('data-autoplay') !== '0' && !document.querySelector('.layout-builder'); + + // Add a class if there's only one slide. + if (elem.children.length <= 1) { + banner.classList.add('banner-single'); + } + + // Check if dots and navigation should be enabled. + var bannerDots = elem.children.length > 1; + + // Ensure Flickity is defined before initializing. + if (typeof Flickity === 'undefined') { + console.error('Flickity is not defined. Ensure the library is loaded.'); + return; + } + + var flkty = new Flickity(elem, { + autoPlay: bannerAutoplay ? bannerSlideSpeed : false, + draggable: true, + fade: true, + cellSelector: '.card__banner', + pageDots: bannerDots, + on: { + ready: function() { + var dots = document.querySelectorAll('.flickity-page-dots .dot'); + + if (!dots.length) { + return; + } - bannerPause.addEventListener('click', function () { - flkty.stopPlayer(); - bannerPause.style.display = 'none'; - bannerPlay.style.display = 'block'; + dots.forEach(function(dot) { + // Make dots focusable + dot.setAttribute('tabindex', '0'); + + dot.addEventListener('keydown', function(event) { + if (event.key === 'Enter' || event.keyCode === 13) { + var label = dot.getAttribute('aria-label'); + // Get "Page dot # // Extract the number" + var match = label.match(/\d+/); + if (!match) { + return; + } + + // Convert to zero-based index + var targetIndex = parseInt(match[0], 10) - 1; + + flkty.select(targetIndex); // Move to the slide + } + }); + }); + } + } }); - } - }); + // Get play and pause buttons. + var bannerPlay = banner.querySelector('.uw-play'); + var bannerPause = banner.querySelector('.uw-pause'); - // Pause carousel when clicking pagination dots. - document.addEventListener('click', function (event) { - if (event.target.matches('.flickity-page-dot')) { - var banner = event.target.closest('.uw-carousel__banner'); - if (banner) { - var pauseButton = banner.querySelector('.uw-pause'); - if (pauseButton) { - pauseButton.click(); + // Attach event listeners for play and pause. + if (bannerPlay && bannerPause) { + bannerPlay.addEventListener('click', function () { + flkty.playPlayer(); + bannerPlay.style.display = 'none'; + bannerPause.style.display = 'block'; + }); + + bannerPause.addEventListener('click', function () { + flkty.stopPlayer(); + bannerPause.style.display = 'none'; + bannerPlay.style.display = 'block'; + }); + } + }); + + // Pause carousel when clicking pagination dots. + document.addEventListener('click', function (event) { + if (event.target.matches('.flickity-page-dots')) { + var banner = event.target.closest('.uw-carousel__banner'); + if (banner) { + var pauseButton = banner.querySelector('.uw-pause'); + if (pauseButton) { + pauseButton.click(); + } } } - } + }); }); } }; -}(Drupal)); +})(jQuery,Drupal, Flickity); diff --git a/src/patterns/04-components/banners/banners.twig b/src/patterns/04-components/banners/banners.twig index 5c54d1d8..3fd70767 100644 --- a/src/patterns/04-components/banners/banners.twig +++ b/src/patterns/04-components/banners/banners.twig @@ -17,7 +17,7 @@ {% endembed %} <noscript> - <div class="uw-owl-nav__dots-js"> + <div class="uw-nav__dots-js"> {% for image in banners.images %} <a href="#banner{{ loop.index }}-{{ banners.uuid }}" role="button" class="owl-dot"></a> {% endfor %} diff --git a/src/patterns/04-components/card/card--banner/_card--banner.scss b/src/patterns/04-components/card/card--banner/_card--banner.scss index 27e00d97..e62a1f99 100644 --- a/src/patterns/04-components/card/card--banner/_card--banner.scss +++ b/src/patterns/04-components/card/card--banner/_card--banner.scss @@ -18,7 +18,7 @@ } } } - .uw-owl-nav__banner-control { + .uw-nav__banner-control { background: var(--uw-black) !important; border: var(size-xs) solid var(--uw-gold) !important; .uw-play-svg { @@ -187,7 +187,7 @@ } } } - .uw-owl-nav__banner-control, + .uw-nav__banner-control, .banner-video-control{ color: var(--#{$colour}-primary) !important; background: var(--uw-white) !important; @@ -314,7 +314,7 @@ } } - .uw-owl-nav__banner-control, + .uw-nav__banner-control, .banner-video-control { background: var(--uw-white) !important; border: var(--size-xs) solid var(--#{$colour}-primary) !important; @@ -684,7 +684,7 @@ display: none; } -.uw-owl-nav__banner-control, +.uw-nav__banner-control, .banner-video-control { .uw-icon { svg { -- GitLab