1/** 2 * Horizontal card/tab centring (the "our approach" cards + the logo tab strip). 3 * 4 * These live in reusable sections (templates/sections/our-approach-section.php, 5 * tab-logo.php), so they are guarded by markup presence rather than a page 6 * template â they activate wherever their section is rendered. 7 * 8 * - Center-active card: on mobile (<= 576px), as `#approach-cards` scrolls 9 * horizontally, marks the card nearest the viewport centre `.active`. 10 * - Logo-tab: on load, scrolls the active `.logo-tab .nav-link` into the centre. 11 * 12 * @module ui/interactive-cards 13 */ 14import { rafThrottle } from "../core/raf.js"; 15import { onResize } from "./events.js"; 16 17const $ = window.jQuery; 18const $window = $(window); 19const NS = ".tmCards"; 20const CENTER_CARD_MAX_WIDTH = 576; 21 22/** Cached center-card state (module singleton). */ 23const centerCards = { $container: $(), $boxes: $() }; 24 25function updateCenterActiveBox() { 26 const { $container, $boxes } = centerCards; 27 if ( 28 !$container.length || 29 !$boxes.length || 30 window.innerWidth > CENTER_CARD_MAX_WIDTH 31 ) { 32 return; 33 } 34 35 const center = $window.width() / 2; 36 let $closest = $(); 37 let closestDistance = Infinity; 38 39 $boxes.each(function () { 40 const rect = this.getBoundingClientRect(); 41 const boxCenter = rect.left + rect.width / 2; 42 const distance = Math.abs(center - boxCenter); 43 if (distance < closestDistance) { 44 closestDistance = distance; 45 $closest = $(this); 46 } 47 }); 48 49 $boxes.removeClass("active"); 50 $closest.addClass("active"); 51} 52 53function initCenterActiveCard() { 54 const $container = $("#approach-cards"); 55 const $boxes = $container.find(".theme-box"); 56 if (!$container.length || !$boxes.length) return; 57 58 centerCards.$container = $container; 59 centerCards.$boxes = $boxes; 60 61 $container 62 .off(`scroll${NS}`) 63 .on(`scroll${NS}`, rafThrottle(updateCenterActiveBox)); 64 onResize(updateCenterActiveBox); 65 updateCenterActiveBox(); 66} 67 68function initLogoTabCentering() { 69 const $activeTab = $(".logo-tab .nav-link.active");
70 const $scrollContainer = $(".logo-tab"); 71 if (!$activeTab.length || !$scrollContainer.length) return; 72 73 $scrollContainer[0].scrollTo({ 74 left: 75 $activeTab[0].offsetLeft - 76 $scrollContainer.width() / 2 + 77 $activeTab.outerWidth() / 2, 78 behavior: "smooth", 79 }); 80} 81 82/** @type {import("../core/registry.js").Component} */ 83export default { 84 name: "interactive-cards", 85 init() { 86 initCenterActiveCard(); 87 initLogoTabCentering(); 88 }, 89};
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.