1/** 2 * Icon Matrix Slick Slider Implementation 3 * Alternative to custom scroll implementation using Slick Slider 4 */ 5 6// Define timeout constants for better maintainability 7const BREAKPOINT_STYLING_DELAY = 100; 8const REINIT_STYLING_DELAY = 50; 9 10function initializeIconMatrixScrollSlick() { 11 const scrollContainers = document.querySelectorAll('.ss-im-scroll'); 12 13 scrollContainers.forEach(function setupContainerHandler(container) { 14 setupSlickContainer(container); 15 }); 16} 17 18function setupSlickContainer(container) { 19 const iconsList = container.querySelector('.ss-im-icons-list'); 20 const iconsPerRow = parseInt(container.dataset.iconsPerRow, 10) || 6; 21 22 if (!iconsList) return; 23 24 const icons = iconsList.querySelectorAll('.ss-im-icon-wrapper'); 25 const totalIcons = icons.length; 26 27 if (totalIcons <= iconsPerRow) return; 28 29 // Initialize slick slider - each icon wrapper becomes its own slide 30 const $iconsList = $(iconsList); 31 32 // Remove conflicting CSS classes that set widths 33 icons.forEach(function removeFlexClasses(icon) { 34 // Remove the original flex classes that interfere with slick widths 35 icon.classList.remove('ss-flex-1', 'ss-flex-2', 'ss-flex-3', 'ss-flex-4', 'ss-flex-5', 'ss-flex-6'); 36 }); 37 38 // Hide the original pagination dots since slick creates its own 39 const originalDots = container.querySelector('.ss-im-pagination-dots'); 40 if (originalDots) { 41 originalDots.style.display = 'none'; 42 } 43 44 // Add accessibility features 45 if (typeof window.slickSliderA11y === 'function') { 46 window.slickSliderA11y($iconsList, $iconsList.closest('.ss-im-scroll')); 47 } 48 bindCustomDotSync($iconsList); 49 50 // Get mobile responsive settings 51 const mobileSettings = getMobileSlickSettings(container, icons); 52 53 $iconsList.slick({ 54 infinite: false, 55 slidesToShow: iconsPerRow, 56 slidesToScroll: iconsPerRow, 57 adaptiveHeight: false, 58 centerMode: false, 59 arrows: false, 60 dots: true, 61 dotsClass: 'ss-im-slick-dots slick-dots', 62 speed: 500, 63 variableWidth: false, // Let slick handle equal widths 64 responsive: [ 65 { 66 breakpoint: 768, 67 settings: mobileSettings.tablet 68 }, 69 { 70 breakpoint: 640, 71 settings: mobileSettings.mobile 72 } 73 ] 74 }); 75 76 // Monitor breakpoint changes and re-apply custom dot styling 77 $iconsList.on('breakpoint', function handleBreakpointChange(event, slick, breakpoint) { 78 setTimeout(function reapplyDotsAfterBreakpoint() { 79 // Re-apply custom dot styling after breakpoint change 80 customizeSlickDots(container); 81 }, BREAKPOINT_STYLING_DELAY); 82 }); 83 84 // Custom dot styling to match existing design 85 customizeSlickDots(container); 86 87 // Also re-apply dots on any slick reinitialization 88 $iconsList.on('reInit', function handleSlickReInit(event, slick) { 89 setTimeout(function reapplyDotsAfterReInit() { 90 customizeSlickDots(container); 91 }, REINIT_STYLING_DELAY); 92 }); 93} 94 95// Slick will handle slide widths automatically based on slidesToShow 96 97function getMobileSlickSettings(container, icons) { 98 const displayStyle = getDisplayStyle(container); 99 const hasText = icons[0] && icons[0].querySelector('.ss-icon-text'); 100 const iconsPerRow = parseInt(container.dataset.iconsPerRow, 10); 101 102 // Mobile: 2 per row for solid/outline circle/square with title only, 1 for others 103 const iconsPerRowMobile = getMobileIconsPerRow(displayStyle, hasText); 104 105 return { 106 tablet: { 107 slidesToShow: Math.min(4, iconsPerRow), // Don't override desktop value so aggressively 108 slidesToScroll: Math.min(4, iconsPerRow), 109 dots: true 110 }, 111 mobile: { 112 slidesToShow: iconsPerRowMobile, 113 slidesToScroll: iconsPerRowMobile, 114 dots: true 115 } 116 }; 117} 118 119function getDisplayStyle(container) { 120 const iconMatrix = container.closest('.ss-icon-matrix .ss-component-column'); 121 if (!iconMatrix) return 'simple'; 122 123 if (iconMatrix.classList.contains('ss-im-solid-circle')) return 'solid-circle'; 124 if (iconMatrix.classList.contains('ss-im-outline-circle')) return 'outline-circle'; 125 if (iconMatrix.classList.contains('ss-im-solid-square')) return 'solid-square'; 126 if (iconMatrix.classList.contains('ss-im-outline-square')) return 'outline-square'; 127 if (iconMatrix.classList.contains('ss-im-left-aligned')) return 'left-aligned'; 128 if (iconMatrix.classList.contains('ss-im-solid-boxes')) return 'solid-boxes'; 129 if (iconMatrix.classList.contains('ss-im-outline-boxes')) return 'outline-boxes'; 130 if (iconMatrix.classList.contains('ss-im-solid-overlap-boxes')) return 'solid-overlap-boxes'; 131 if (iconMatrix.classList.contains('ss-im-outline-overlap-boxes')) return 'outline-overlap-boxes'; 132 133 return 'simple'; 134} 135 136function getMobileIconsPerRow(displayStyle, hasText) { 137 // For solid/outline circle and square with title only: 2 per row 138 if ((displayStyle === 'solid-circle' || displayStyle === 'outline-circle' || 139 displayStyle === 'solid-square' || displayStyle === 'outline-square' || 140 displayStyle === 'simple') && !hasText) { 141 return 2; 142 } 143 144 // For all other styles or with paragraph text: 1 per row 145 return 1; 146} 147 148function customizeSlickDots(container) { 149 // Replace slick's default dots with our custom styling 150 const slickDots = container.querySelector('.ss-im-slick-dots'); 151 if (slickDots) { 152 // Add our custom classes to make dots look like the original implementation 153 slickDots.className = 'ss-im-pagination-dots ss-im-slick-dots'; 154 155 const dots = slickDots.querySelectorAll('li button');
156 dots.forEach(function setupDotButton(dot, index) { 157 dot.className = 'ss-im-dot'; 158 dot.textContent = ''; // Remove slick's default text 159 dot.setAttribute('aria-label', `Go to slide ${index + 1}`); 160 }); 161 162 // Add active class to first dot 163 if (dots.length > 0) { 164 dots[0].classList.add('active'); 165 } 166 } 167} 168 169// Update custom dot active states on slide change 170function bindCustomDotSync($iconsList) { 171 $iconsList.on('afterChange', function handleDotSync() { 172 const closestScrollContainer = $iconsList.closest('.ss-im-scroll'); 173 if (closestScrollContainer.length === 0) return; 174 175 const container = closestScrollContainer[0]; 176 const dots = container.querySelectorAll('.ss-im-dot'); 177 const activeSlideIndex = $iconsList.slick('slickCurrentSlide'); 178 179 dots.forEach(function updateDotActiveState(dot, index) { 180 dot.classList.toggle('active', index === activeSlideIndex); 181 }); 182 }); 183} 184 185// Icon Matrix Scroll initialization using Slick Slider 186(function initIconMatrixScrollModule() { 187 let iconMatrixScrollInitialized = false; 188 189 // Check if we have any scroll icon matrices on the page and initialize if needed 190 function checkForScrollIconMatrices() { 191 const scrollContainers = document.querySelectorAll('.ss-im-scroll'); 192 if (scrollContainers.length > 0 && !iconMatrixScrollInitialized) { 193 initializeIconMatrixScrollSlick(); 194 iconMatrixScrollInitialized = true; 195 } 196 } 197 198 // Initialize on DOM ready 199 if (document.readyState === 'loading') { 200 document.addEventListener('DOMContentLoaded', checkForScrollIconMatrices); 201 } else { 202 checkForScrollIconMatrices(); 203 } 204 205 // Also check when new content is dynamically added (for AJAX updates) 206 const observer = new MutationObserver(function handleMutations(mutations) { 207 mutations.forEach(function processMutation(mutation) { 208 if (mutation.type === 'childList' && mutation.addedNodes.length > 0) { 209 checkForScrollIconMatrices(); 210 } 211 }); 212 }); 213 214 observer.observe(document.body, { 215 childList: true, 216 subtree: true 217 }); 218 219 // Expose function globally for AJAX re-initialization 220 window.reinitializeIconMatrixScroll = function reinitializeIconMatrixScroll() { 221 iconMatrixScrollInitialized = false; 222 checkForScrollIconMatrices(); 223 }; 224})(); 225 226// Module auto-initializes, no exports needed
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.