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