UNPKG

@splidejs/splide-extension-grid

Version:

The extension of Splide for creating grid inside slides.

673 lines (552 loc) 16.9 kB
/*! * @splidejs/splide-extension-grid * Version : 0.4.1 * License : MIT * Copyright: 2022 Naotoshi Fujita */ (function (factory) { typeof define === 'function' && define.amd ? define(factory) : factory(); })(function () { 'use strict'; function empty$1(array) { array.length = 0; } function slice$1(arrayLike, start, end) { return Array.prototype.slice.call(arrayLike, start, end); } function apply$1(func) { return func.bind.apply(func, [null].concat(slice$1(arguments, 1))); } function typeOf$1(type, subject) { return typeof subject === type; } var isArray$1 = Array.isArray; apply$1(typeOf$1, "function"); apply$1(typeOf$1, "string"); apply$1(typeOf$1, "undefined"); function toArray$1(value) { return isArray$1(value) ? value : [value]; } function forEach$1(values, iteratee) { toArray$1(values).forEach(iteratee); } var ownKeys$1 = Object.keys; function forOwn$1(object, iteratee, right) { if (object) { var keys = ownKeys$1(object); keys = right ? keys.reverse() : keys; for (var i = 0; i < keys.length; i++) { var key = keys[i]; if (key !== "__proto__") { if (iteratee(object[key], key) === false) { break; } } } } return object; } function assign$1(object) { slice$1(arguments, 1).forEach(function (source) { forOwn$1(source, function (value, key) { object[key] = source[key]; }); }); return object; } var PROJECT_CODE$1 = "splide"; function EventBinder() { var listeners = []; function bind(targets, events, callback, options) { forEachEvent(targets, events, function (target, event, namespace) { var isEventTarget = ("addEventListener" in target); var remover = isEventTarget ? target.removeEventListener.bind(target, event, callback, options) : target["removeListener"].bind(target, callback); isEventTarget ? target.addEventListener(event, callback, options) : target["addListener"](callback); listeners.push([target, event, namespace, callback, remover]); }); } function unbind(targets, events, callback) { forEachEvent(targets, events, function (target, event, namespace) { listeners = listeners.filter(function (listener) { if (listener[0] === target && listener[1] === event && listener[2] === namespace && (!callback || listener[3] === callback)) { listener[4](); return false; } return true; }); }); } function dispatch(target, type, detail) { var e; var bubbles = true; if (typeof CustomEvent === "function") { e = new CustomEvent(type, { bubbles: bubbles, detail: detail }); } else { e = document.createEvent("CustomEvent"); e.initCustomEvent(type, bubbles, false, detail); } target.dispatchEvent(e); return e; } function forEachEvent(targets, events, iteratee) { forEach$1(targets, function (target) { target && forEach$1(events, function (events2) { events2.split(" ").forEach(function (eventNS) { var fragment = eventNS.split("."); iteratee(target, fragment[0], fragment[1]); }); }); }); } function destroy() { listeners.forEach(function (data) { data[4](); }); empty$1(listeners); } return { bind: bind, unbind: unbind, dispatch: dispatch, destroy: destroy }; } var EVENT_VISIBLE = "visible"; var EVENT_HIDDEN = "hidden"; var EVENT_REFRESH = "refresh"; var EVENT_UPDATED = "updated"; var EVENT_DESTROY = "destroy"; function EventInterface(Splide2) { var bus = Splide2 ? Splide2.event.bus : document.createDocumentFragment(); var binder = EventBinder(); function on(events, callback) { binder.bind(bus, toArray$1(events).join(" "), function (e) { callback.apply(callback, isArray$1(e.detail) ? e.detail : []); }); } function emit(event) { binder.dispatch(bus, event, slice$1(arguments, 1)); } if (Splide2) { Splide2.event.on(EVENT_DESTROY, binder.destroy); } return assign$1(binder, { bus: bus, on: on, off: apply$1(binder.unbind, bus), emit: emit }); } var CLASS_ROOT = PROJECT_CODE$1; var CLASS_SLIDE = PROJECT_CODE$1 + "__slide"; var CLASS_CONTAINER = CLASS_SLIDE + "__container"; function empty(array) { array.length = 0; } function slice(arrayLike, start, end) { return Array.prototype.slice.call(arrayLike, start, end); } function apply(func) { return func.bind.apply(func, [null].concat(slice(arguments, 1))); } function typeOf(type, subject) { return typeof subject === type; } function isObject(subject) { return !isNull(subject) && typeOf("object", subject); } var isArray = Array.isArray; apply(typeOf, "function"); var isString = apply(typeOf, "string"); var isUndefined = apply(typeOf, "undefined"); function isNull(subject) { return subject === null; } function isHTMLElement(subject) { return subject instanceof HTMLElement; } function toArray(value) { return isArray(value) ? value : [value]; } function forEach(values, iteratee) { toArray(values).forEach(iteratee); } function push(array, items) { array.push.apply(array, toArray(items)); return array; } function toggleClass(elm, classes, add) { if (elm) { forEach(classes, function (name) { if (name) { elm.classList[add ? "add" : "remove"](name); } }); } } function addClass(elm, classes) { toggleClass(elm, isString(classes) ? classes.split(" ") : classes, true); } function append(parent, children) { forEach(children, parent.appendChild.bind(parent)); } function matches(elm, selector) { return isHTMLElement(elm) && (elm["msMatchesSelector"] || elm.matches).call(elm, selector); } function children(parent, selector) { var children2 = parent ? slice(parent.children) : []; return selector ? children2.filter(function (child) { return matches(child, selector); }) : children2; } function child(parent, selector) { return selector ? children(parent, selector)[0] : parent.firstElementChild; } var ownKeys = Object.keys; function forOwn(object, iteratee, right) { if (object) { var keys = ownKeys(object); keys = right ? keys.reverse() : keys; for (var i = 0; i < keys.length; i++) { var key = keys[i]; if (key !== "__proto__") { if (iteratee(object[key], key) === false) { break; } } } } return object; } function assign(object) { slice(arguments, 1).forEach(function (source) { forOwn(source, function (value, key) { object[key] = source[key]; }); }); return object; } function omit(object, keys) { toArray(keys || ownKeys(object)).forEach(function (key) { delete object[key]; }); } function removeAttribute(elms, attrs) { forEach(elms, function (elm) { forEach(attrs, function (attr) { elm && elm.removeAttribute(attr); }); }); } function setAttribute(elms, attrs, value) { if (isObject(attrs)) { forOwn(attrs, function (value2, name) { setAttribute(elms, name, value2); }); } else { forEach(elms, function (elm) { isNull(value) || value === "" ? removeAttribute(elm, attrs) : elm.setAttribute(attrs, String(value)); }); } } function create(tag, attrs, parent) { var elm = document.createElement(tag); if (attrs) { isString(attrs) ? addClass(elm, attrs) : setAttribute(elm, attrs); } parent && append(parent, elm); return elm; } function style(elm, prop, value) { if (isUndefined(value)) { return getComputedStyle(elm)[prop]; } if (!isNull(value)) { elm.style[prop] = "" + value; } } function hasClass(elm, className) { return elm && elm.classList.contains(className); } function remove(nodes) { forEach(nodes, function (node) { if (node && node.parentNode) { node.parentNode.removeChild(node); } }); } function queryAll(parent, selector) { return selector ? slice(parent.querySelectorAll(selector)) : []; } function removeClass(elm, classes) { toggleClass(elm, classes, false); } function unit(value) { return isString(value) ? value : value ? value + "px" : ""; } var PROJECT_CODE = "splide"; function assert(condition, message) { if (!condition) { throw new Error("[" + PROJECT_CODE + "] " + (message || "")); } } var min = Math.min, max = Math.max, floor = Math.floor, ceil = Math.ceil, abs = Math.abs; function pad(number) { return number < 10 ? "0" + number : "" + number; } var CLASS_SLIDE_ROW = CLASS_SLIDE + "__row"; var CLASS_SLIDE_COL = CLASS_SLIDE + "--col"; var DEFAULTS = { rows: 1, cols: 1, dimensions: [], gap: {} }; function Dimension(options) { function normalize() { var rows = options.rows, cols = options.cols, dimensions = options.dimensions; return isArray(dimensions) && dimensions.length ? dimensions : [[rows, cols]]; } function get(index) { var dimensions = normalize(); return dimensions[min(index, dimensions.length - 1)]; } function getAt(index) { var dimensions = normalize(); var rows, cols, aggregator = 0; for (var i = 0; i < dimensions.length; i++) { var dimension = dimensions[i]; rows = dimension[0] || 1; cols = dimension[1] || 1; aggregator += rows * cols; if (index < aggregator) { break; } } assert(rows && cols, "Invalid dimension"); return [rows, cols]; } return { get: get, getAt: getAt }; } function Layout(Splide2, gridOptions, Dimension) { var _EventInterface = EventInterface(Splide2), on = _EventInterface.on, destroyEvent = _EventInterface.destroy; var Components = Splide2.Components, options = Splide2.options; var resolve = Components.Direction.resolve; var forEach = Components.Slides.forEach; function mount() { layout(); if (options.slideFocus) { on(EVENT_VISIBLE, onVisible); on(EVENT_HIDDEN, onHidden); } } function destroy() { forEach(function (Slide) { var slide = Slide.slide; toggleTabIndex(slide, false); getRowsIn(slide).forEach(function (cell) { removeAttribute(cell, "style"); }); getColsIn(slide).forEach(function (colSlide) { cover(colSlide, true); removeAttribute(colSlide, "style"); }); }); destroyEvent(); } function layout() { forEach(function (Slide) { var slide = Slide.slide; var _Dimension$get = Dimension.get(Slide.isClone ? Slide.slideIndex : Slide.index), rows = _Dimension$get[0], cols = _Dimension$get[1]; layoutRow(rows, slide); layoutCol(cols, slide); getColsIn(Slide.slide).forEach(function (colSlide, index) { colSlide.id = Slide.slide.id + "-col" + pad(index + 1); if (Splide2.options.cover) { cover(colSlide); } }); }); } function layoutRow(rows, slide) { var rowGap = gridOptions.gap.row; var height = "calc(" + 100 / rows + "%" + (rowGap ? " - " + unit(rowGap) + " * " + (rows - 1) / rows : "") + ")"; getRowsIn(slide).forEach(function (rowElm, index, rowElms) { style(rowElm, "height", height); style(rowElm, "display", "flex"); style(rowElm, "margin", "0 0 " + unit(rowGap) + " 0"); style(rowElm, "padding", 0); if (index === rowElms.length - 1) { style(rowElm, "marginBottom", 0); } }); } function layoutCol(cols, slide) { var colGap = gridOptions.gap.col; var width = "calc(" + 100 / cols + "%" + (colGap ? " - " + unit(colGap) + " * " + (cols - 1) / cols : "") + ")"; getColsIn(slide).forEach(function (colElm, index, colElms) { style(colElm, "width", width); if (index !== colElms.length - 1) { style(colElm, resolve("marginRight"), unit(colGap)); } }); } function cover(colSlide, uncover) { var container = child(colSlide, "." + CLASS_CONTAINER); var img = child(container || colSlide, "img"); if (img && img.src) { style(container || colSlide, "background", uncover ? "" : "center/cover no-repeat url(\"" + img.src + "\")"); style(img, "display", uncover ? "" : "none"); } } function getRowsIn(slide) { return queryAll(slide, "." + CLASS_SLIDE_ROW); } function getColsIn(slide) { return queryAll(slide, "." + CLASS_SLIDE_COL); } function toggleTabIndex(slide, add) { getColsIn(slide).forEach(function (colSlide) { setAttribute(colSlide, "tabindex", add ? 0 : null); }); } function onVisible(Slide) { toggleTabIndex(Slide.slide, true); } function onHidden(Slide) { toggleTabIndex(Slide.slide, false); } return { mount: mount, destroy: destroy }; } function Grid(Splide2, Components2, options) { var _EventInterface2 = EventInterface(Splide2), on = _EventInterface2.on, off = _EventInterface2.off; var Elements = Components2.Elements; var gridOptions = {}; var Dimension$1 = Dimension(gridOptions); var Layout$1 = Layout(Splide2, gridOptions, Dimension$1); var modifier = CLASS_ROOT + "--grid"; var originalSlides = []; function mount() { init(); on(EVENT_UPDATED, init); } function init() { omit(gridOptions); assign(gridOptions, DEFAULTS, options.grid || {}); if (shouldBuild()) { destroy(); push(originalSlides, Elements.slides); addClass(Splide2.root, modifier); append(Elements.list, build()); off(EVENT_REFRESH); on(EVENT_REFRESH, layout); refresh(); } else if (isActive()) { destroy(); refresh(); } } function destroy() { if (isActive()) { var slides = Elements.slides; Layout$1.destroy(); originalSlides.forEach(function (slide) { removeClass(slide, CLASS_SLIDE_COL); append(Elements.list, slide); }); remove(slides); removeClass(Splide2.root, modifier); empty(slides); push(slides, originalSlides); empty(originalSlides); off(EVENT_REFRESH); } } function refresh() { Splide2.refresh(); } function layout() { if (isActive()) { Layout$1.mount(); } } function build() { var outerSlides = []; var row = 0, col = 0; var outerSlide, rowSlide; originalSlides.forEach(function (slide, index) { var _Dimension$1$getAt = Dimension$1.getAt(index), rows = _Dimension$1$getAt[0], cols = _Dimension$1$getAt[1]; if (!col) { if (!row) { outerSlide = create(slide.tagName, CLASS_SLIDE); outerSlides.push(outerSlide); } rowSlide = buildRow(rows, slide, outerSlide); } buildCol(cols, slide, rowSlide); if (++col >= cols) { col = 0; row = ++row >= rows ? 0 : row; } }); return outerSlides; } function buildRow(rows, slide, outerSlide) { var tag = slide.tagName.toLowerCase() === "li" ? "ul" : "div"; return create(tag, CLASS_SLIDE_ROW, outerSlide); } function buildCol(cols, slide, rowSlide) { addClass(slide, CLASS_SLIDE_COL); append(rowSlide, slide); return slide; } function shouldBuild() { if (options.grid) { var rows = gridOptions.rows, cols = gridOptions.cols, dimensions = gridOptions.dimensions; return rows > 1 || cols > 1 || isArray(dimensions) && dimensions.length > 0; } return false; } function isActive() { return hasClass(Splide2.root, modifier); } return { mount: mount, destroy: destroy }; } if (typeof window !== "undefined") { window.splide = window.splide || {}; window.splide.Extensions = window.splide.Extensions || {}; window.splide.Extensions.Grid = Grid; } });