(function (global) { "use strict"; function pad(n) { return String(n).padStart(2, "0"); } /* Attach interactive behavior to a pre-rendered .slider-section element. Reads captions/credits from data-caption/data-credit on each .slider-slide. Reads data-loop="false" on the section to disable looping (default: loops). */ function wire(section) { var slideEls = Array.prototype.slice.call( section.querySelectorAll(".slider-slide"), ); var total = slideEls.length; if (total < 2) return; var current = 0; for (var i = 0; i < total; i++) { if (slideEls[i].classList.contains("active")) { current = i; break; } } var prevBtn = section.querySelector('.slider-arrow[data-dir="prev"]'); var nextBtn = section.querySelector('.slider-arrow[data-dir="next"]'); var currentNumEl = section.querySelector(".slider-counter .current"); var captionEl = section.querySelector(".slider-caption"); var creditEl = section.querySelector(".slider-credit"); var captionCard = section.querySelector(".caption-card"); var loop = section.getAttribute("data-loop") !== "false"; function updateCaption() { var slide = slideEls[current]; var caption = slide.getAttribute("data-caption") || ""; var credit = slide.getAttribute("data-credit") || ""; if (captionEl) { captionEl.textContent = caption; captionEl.hidden = !caption; } if (creditEl) { creditEl.textContent = credit; creditEl.hidden = !credit; } if (captionCard) { captionCard.hidden = !caption && !credit; } } function refreshButtons() { if (!loop) { if (prevBtn) prevBtn.disabled = current === 0; if (nextBtn) nextBtn.disabled = current === total - 1; } } function goTo(n) { var next = loop ? ((n % total) + total) % total : Math.max(0, Math.min(total - 1, n)); if (next === current) return; slideEls[current].classList.remove("active"); slideEls[current].setAttribute("aria-hidden", "true"); slideEls[next].classList.add("active"); slideEls[next].setAttribute("aria-hidden", "false"); current = next; if (currentNumEl) currentNumEl.textContent = pad(current + 1); updateCaption(); refreshButtons(); } if (prevBtn) { prevBtn.addEventListener("click", function () { goTo(current - 1); }); } if (nextBtn) { nextBtn.addEventListener("click", function () { goTo(current + 1); }); } section.addEventListener("keydown", function (e) { if (e.key === "ArrowLeft") { e.preventDefault(); goTo(current - 1); } if (e.key === "ArrowRight") { e.preventDefault(); goTo(current + 1); } }); refreshButtons(); } /* Auto-init: wire every .slider-section already in the DOM. */ function autoInit() { Array.prototype.forEach.call( document.querySelectorAll(".slider-section"), wire, ); } if (document.readyState === "loading") { document.addEventListener("DOMContentLoaded", autoInit); } else { autoInit(); } /* ---- Legacy programmatic API (for pages that still call LinfieldSlider.init) ---- */ function chevron(direction) { var ns = "http://www.w3.org/2000/svg"; var svg = document.createElementNS(ns, "svg"); svg.setAttribute("viewBox", "0 0 24 24"); svg.setAttribute("width", "22"); svg.setAttribute("height", "22"); svg.setAttribute("fill", "none"); svg.setAttribute("stroke", "currentColor"); svg.setAttribute("stroke-width", "1.75"); svg.setAttribute("stroke-linecap", "round"); svg.setAttribute("stroke-linejoin", "round"); svg.setAttribute("aria-hidden", "true"); var poly = document.createElementNS(ns, "polyline"); poly.setAttribute( "points", direction === "prev" ? "15 6 9 12 15 18" : "9 6 15 12 9 18", ); svg.appendChild(poly); return svg; } function make(tag, attrs) { var node = document.createElement(tag); if (attrs) { Object.keys(attrs).forEach(function (k) { var v = attrs[k]; if (k === "className") { node.className = v; } else if (k === "textContent") { node.textContent = v; } else { node.setAttribute(k, v); } }); } return node; } function init(container, options) { var opts = options || {}; var slides = opts.slides || []; var eyebrow = opts.eyebrow; var title = opts.title; var body = opts.body; var showHeader = opts.showHeader !== false; var theme = opts.theme || "dark"; var bgColor = opts.bgColor; var arrowShape = opts.arrowShape || "pill"; var counterStyle = opts.counterStyle || "serif"; var showTopBar = opts.showTopBar !== undefined ? opts.showTopBar : theme === "dark"; var showAccent = opts.showLinfieldAccent !== false; var loop = opts.loop !== false; var total = slides.length; var section = make("section", { className: "slider-section theme-" + theme, role: "region", "aria-roledescription": "carousel", "aria-label": title || "Image slider", tabindex: "0", "data-loop": String(loop), }); if (bgColor) { section.style.setProperty("--bg-color", bgColor); } if (showTopBar) { section.appendChild( make("div", { className: "top-bar", "aria-hidden": "true" }), ); } if (showAccent) { var accent = make("div", { className: "linfield-accent", "aria-hidden": "true", }); accent.innerHTML = "LINFIELDLINFIELD"; section.appendChild(accent); } var wrap = make("div", { className: "slider-container wide" }); section.appendChild(wrap); if (showHeader && (eyebrow || title || body)) { var header = make("header", { className: "slider-header" }); if (eyebrow) { header.appendChild( make("p", { className: "slider-eyebrow", textContent: eyebrow }), ); } if (title) { header.appendChild( make("h2", { className: "slider-title text-h1", textContent: title }), ); } if (body) { header.appendChild( make("p", { className: "slider-body text-body", textContent: body }), ); } wrap.appendChild(header); } var splitStage = make("div", { className: "split-stage" }); wrap.appendChild(splitStage); var stage = make("div", { className: "slider-stage", "aria-live": "polite" }); splitStage.appendChild(stage); var track = make("div", { className: "slider-track" }); stage.appendChild(track); slides.forEach(function (s, i) { var slide = make("div", { className: "slider-slide" + (i === 0 ? " active" : ""), "aria-hidden": String(i !== 0), "data-caption": s.caption || "", "data-credit": s.credit || "", }); var img = make("img", { src: s.src, alt: s.alt || s.caption || "Slide " + (i + 1), loading: i === 0 ? "eager" : "lazy", }); slide.appendChild(img); track.appendChild(slide); }); var captionCard = make("div", { className: "caption-card" }); splitStage.appendChild(captionCard); var captionRow = make("div", { className: "slider-caption-row" }); captionCard.appendChild(captionRow); captionRow.appendChild(make("p", { className: "slider-caption" })); captionRow.appendChild(make("span", { className: "slider-credit" })); if (total > 1) { var controls = make("div", { className: "slider-controls", role: "group", "aria-label": "Slider navigation", }); wrap.appendChild(controls); var prevBtn = make("button", { type: "button", className: "slider-arrow " + arrowShape, "aria-label": "Previous slide", "data-dir": "prev", }); prevBtn.appendChild(chevron("prev")); controls.appendChild(prevBtn); var counterClass = counterStyle === "default" ? "slider-counter" : "slider-counter " + counterStyle; var counter = make("div", { className: counterClass, "aria-live": "polite", "aria-atomic": "true", }); counter.appendChild(make("span", { className: "current", textContent: pad(1) })); counter.appendChild(make("span", { className: "sep", textContent: "/", "aria-hidden": "true" })); counter.appendChild(make("span", { className: "total", textContent: pad(total) })); controls.appendChild(counter); var nextBtn = make("button", { type: "button", className: "slider-arrow " + arrowShape, "aria-label": "Next slide", "data-dir": "next", }); nextBtn.appendChild(chevron("next")); controls.appendChild(nextBtn); } container.innerHTML = ""; container.appendChild(section); wire(section); return section; } global.LinfieldSlider = { init: init }; })(window);