UNPKG

buefy

Version:

Lightweight UI components for Vue.js (v3) based on Bulma

1,492 lines (1,476 loc) 51.3 kB
/*! Buefy v3.0.0 | MIT License | github.com/buefy/buefy */ (function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vue')) : typeof define === 'function' && define.amd ? define(['exports', 'vue'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.Carousel = {}, global.Vue)); })(this, (function (exports, vue) { 'use strict'; let config = { defaultIconPack: "mdi", defaultIconComponent: null, defaultIconPrev: "chevron-left", defaultIconNext: "chevron-right", defaultCarouselInterval: 3500, defaultImageWebpFallback: null, defaultImageLazy: true, defaultImageResponsive: true, defaultImageRatio: null}; function signPoly(value) { if (value < 0) return -1; return value > 0 ? 1 : 0; } const sign = Math.sign || signPoly; function hasFlag(val, flag) { return (val & flag) === flag; } function mod(n, mod2) { return (n % mod2 + mod2) % mod2; } function bound(val, min, max) { return Math.max(min, Math.min(max, val)); } function isWebpSupported() { return new Promise((resolve) => { const image = new Image(); image.onerror = () => resolve(false); image.onload = () => resolve(image.width === 1); image.src = "data:image/webp;base64,UklGRiQAAABXRUJQVlA4IBgAAAAwAQCdASoBAAEAAwA0JaQAA3AA/vuUAAA="; }).catch(() => false); } const mdiIcons = { sizes: { default: "mdi-24px", "is-small": null, "is-medium": "mdi-36px", "is-large": "mdi-48px" }, iconPrefix: "mdi-" }; const faIcons = () => { const faIconPrefix = "fa-"; return { sizes: { default: null, "is-small": null, "is-medium": faIconPrefix + "lg", "is-large": faIconPrefix + "2x" }, iconPrefix: faIconPrefix, internalIcons: { information: "info-circle", alert: "exclamation-triangle", "alert-circle": "exclamation-circle", "chevron-right": "angle-right", "chevron-left": "angle-left", "chevron-down": "angle-down", "eye-off": "eye-slash", "menu-down": "caret-down", "menu-up": "caret-up", "close-circle": "times-circle" } }; }; const getIcons = () => { let icons = { mdi: mdiIcons, fa: faIcons(), fas: faIcons(), far: faIcons(), fad: faIcons(), fab: faIcons(), fal: faIcons(), "fa-solid": faIcons(), "fa-regular": faIcons(), "fa-light": faIcons(), "fa-thin": faIcons(), "fa-duotone": faIcons(), "fa-brands": faIcons() }; return icons; }; var _sfc_main$4 = vue.defineComponent({ name: "BIcon", props: { type: [String, Object], component: String, pack: String, icon: { type: String, required: true }, size: String, customSize: String, customClass: String, both: Boolean // This is used internally to show both MDI and FA icon }, computed: { iconConfig() { const allIcons = getIcons(); return allIcons[this.newPack]; }, iconPrefix() { if (this.iconConfig && this.iconConfig.iconPrefix) { return this.iconConfig.iconPrefix; } return ""; }, /* * Internal icon name based on the pack. * If pack is 'fa', gets the equivalent FA icon name of the MDI, * internal icons are always MDI. */ newIcon() { return `${this.iconPrefix}${this.getEquivalentIconOf(this.icon)}`; }, newPack() { return this.pack || config.defaultIconPack; }, newType() { if (!this.type) return; let splitType = []; if (typeof this.type === "string") { splitType = this.type.split("-"); } else { for (const key in this.type) { if (this.type[key]) { splitType = key.split("-"); break; } } } if (splitType.length <= 1) return; const [, ...type] = splitType; return `has-text-${type.join("-")}`; }, newCustomSize() { return this.customSize || this.customSizeByPack; }, customSizeByPack() { if (this.iconConfig && this.iconConfig.sizes) { if (this.size && this.iconConfig.sizes[this.size] !== void 0) { return this.iconConfig.sizes[this.size]; } else if (this.iconConfig.sizes.default) { return this.iconConfig.sizes.default; } } return null; }, useIconComponent() { return this.component || config.defaultIconComponent; } }, methods: { /* * Equivalent icon name of the MDI. */ getEquivalentIconOf(value) { if (!this.both) { return value; } if (this.iconConfig == null) { return value; } const maybeInternal = this.iconConfig; if (maybeInternal && maybeInternal.internalIcons && maybeInternal.internalIcons[value]) { return maybeInternal.internalIcons[value]; } return value; } } }); var _export_sfc = (sfc, props) => { const target = sfc.__vccOpts || sfc; for (const [key, val] of props) { target[key] = val; } return target; }; function _sfc_render$4(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock( "span", { class: vue.normalizeClass(["icon", [_ctx.newType, _ctx.size]]) }, [ !_ctx.useIconComponent ? (vue.openBlock(), vue.createElementBlock( "i", { key: 0, class: vue.normalizeClass([_ctx.newPack, _ctx.newIcon, _ctx.newCustomSize, _ctx.customClass]) }, null, 2 /* CLASS */ )) : (vue.openBlock(), vue.createBlock(vue.resolveDynamicComponent(_ctx.useIconComponent), { key: 1, icon: [_ctx.newPack, _ctx.newIcon], size: _ctx.newCustomSize, class: vue.normalizeClass([_ctx.customClass]) }, null, 8, ["icon", "size", "class"])) ], 2 /* CLASS */ ); } var BIcon = /* @__PURE__ */ _export_sfc(_sfc_main$4, [["render", _sfc_render$4]]); var __defProp$3 = Object.defineProperty; var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols; var __hasOwnProp$3 = Object.prototype.hasOwnProperty; var __propIsEnum$3 = Object.prototype.propertyIsEnumerable; var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$3 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$3.call(b, prop)) __defNormalProp$3(a, prop, b[prop]); if (__getOwnPropSymbols$3) for (var prop of __getOwnPropSymbols$3(b)) { if (__propIsEnum$3.call(b, prop)) __defNormalProp$3(a, prop, b[prop]); } return a; }; const items = 1; const sorted$1 = 3; const Sorted$1 = sorted$1; var ProviderParentMixin = (itemName, flags) => { const mixin = { provide() { return { ["b" + itemName]: this }; } }; if (hasFlag(flags, items)) { mixin.data = function() { return __spreadValues$3({ childItems: [] }, hasFlag(flags, sorted$1) ? { nextIndex: 0 } : {}); }; mixin.methods = { _registerItem(item) { if (hasFlag(flags, sorted$1)) { item.dynamicIndex = this.nextIndex; ++this.nextIndex; } this.childItems.push(item); }, _unregisterItem(item) { this.childItems = this.childItems.filter((i) => i.uniqueValue !== item.uniqueValue); } }; if (hasFlag(flags, sorted$1)) { mixin.computed = { /* * When items are added/removed sort them according to their position */ sortedItems() { return this.childItems.slice().sort((i1, i2) => { return i1.index - i2.index; }); } }; } } return mixin; }; var _sfc_main$3 = vue.defineComponent({ name: "BCarousel", components: { BIcon }, mixins: [ProviderParentMixin("carousel", Sorted$1)], props: { modelValue: { type: Number, default: 0 }, animated: { type: String, default: "slide" }, interval: Number, hasDrag: { type: Boolean, default: true }, autoplay: { type: Boolean, default: true }, pauseHover: { type: Boolean, default: true }, pauseInfo: { type: Boolean, default: true }, pauseInfoType: { type: String, default: "is-white" }, pauseText: { type: String, default: "Pause" }, arrow: { type: Boolean, default: true }, arrowHover: { type: Boolean, default: true }, repeat: { type: Boolean, default: true }, iconPack: String, iconSize: String, iconPrev: { type: String, default: () => { return config.defaultIconPrev; } }, iconNext: { type: String, default: () => { return config.defaultIconNext; } }, indicator: { type: Boolean, default: true }, indicatorBackground: Boolean, indicatorCustom: Boolean, indicatorCustomSize: { type: String, default: "is-small" }, indicatorInside: { type: Boolean, default: true }, indicatorMode: { type: String, default: "click" }, indicatorPosition: { type: String, default: "is-bottom" }, indicatorStyle: { type: String, default: "is-dots" }, overlay: Boolean, progress: Boolean, progressType: { type: String, default: "is-primary" }, withCarouselList: Boolean }, emits: { /* eslint-disable @typescript-eslint/no-unused-vars */ change: (_index) => true, click: () => true, "update:modelValue": (_value) => true /* eslint-enable @typescript-eslint/no-unused-vars */ }, data() { return { transition: "next", activeChild: this.modelValue || 0, isPause: false, dragX: false, timer: void 0 }; }, computed: { indicatorClasses() { return [ { "has-background": this.indicatorBackground, "has-custom": this.indicatorCustom, "is-inside": this.indicatorInside }, this.indicatorCustom && this.indicatorCustomSize, this.indicatorInside && this.indicatorPosition ]; }, // checking arrows hasPrev() { return this.repeat || this.activeChild !== 0; }, hasNext() { return this.repeat || this.activeChild < this.childItems.length - 1; }, activeChildIndex() { const item = this.sortedItems[this.activeChild]; return item != null ? item.index : void 0; } }, watch: { /* * When v-model is changed set the new active item. */ modelValue(value) { this.changeActive(value); }, /* * When carousel-items are updated, set active one. */ sortedItems(items) { if (this.activeChild >= items.length && this.activeChild > 0) { this.changeActive(this.activeChild - 1); } }, /* * When autoplay is changed, start or pause timer accordingly */ autoplay(status) { status ? this.startTimer() : this.pauseTimer(); }, /* * Since the timer can get paused at the end, if repeat is changed we need to restart it */ repeat(status) { if (status) { this.startTimer(); } } }, methods: { startTimer() { if (!this.autoplay || this.timer) return; this.isPause = false; this.timer = setInterval(() => { if (!this.repeat && this.activeChild >= this.childItems.length - 1) { this.pauseTimer(); } else { this.next(); } }, this.interval || config.defaultCarouselInterval); }, pauseTimer() { this.isPause = true; if (this.timer) { clearInterval(this.timer); this.timer = void 0; } }, restartTimer() { this.pauseTimer(); this.startTimer(); }, checkPause() { if (this.pauseHover && this.autoplay) { this.pauseTimer(); } }, /* * Change the active item and emit change event. * action only for animated slide, there true = next, false = prev */ changeActive(newIndex, direction = 0) { if (this.activeChild === newIndex || isNaN(newIndex)) return; direction = direction || newIndex - this.activeChild; newIndex = this.repeat ? mod(newIndex, this.childItems.length) : bound(newIndex, 0, this.childItems.length - 1); this.transition = direction > 0 ? "prev" : "next"; this.activeChild = newIndex; if (newIndex !== this.modelValue) { this.$emit("update:modelValue", newIndex); } this.restartTimer(); this.$emit("change", newIndex); }, // Indicator trigger when change active item. modeChange(trigger, value) { if (this.indicatorMode === trigger) { return this.changeActive(value); } }, prev() { this.changeActive(this.activeChild - 1, -1); }, next() { this.changeActive(this.activeChild + 1, 1); }, // handle drag event dragStart(event) { if (!this.hasDrag || !event.target.draggable) return; const touches = event.touches; this.dragX = touches ? event.changedTouches[0].pageX : event.pageX; if (touches) { this.pauseTimer(); } else { event.preventDefault(); } }, dragEnd(event) { if (this.dragX === false) return; const touches = event.touches; const detected = touches ? event.changedTouches[0].pageX : event.pageX; const diffX = detected - this.dragX; if (Math.abs(diffX) > 30) { if (diffX < 0) { this.next(); } else { this.prev(); } } else { event.target.click(); this.sortedItems[this.activeChild].$emit("click"); this.$emit("click"); } if (touches) { this.startTimer(); } this.dragX = false; } }, mounted() { this.startTimer(); }, beforeUnmount() { this.pauseTimer(); } }); const _hoisted_1$3 = ["value", "max"]; const _hoisted_2$1 = { key: 1, class: "carousel-pause" }; const _hoisted_3$1 = ["onMouseover", "onClick"]; function _sfc_render$3(_ctx, _cache, $props, $setup, $data, $options) { const _component_b_icon = vue.resolveComponent("b-icon"); return vue.openBlock(), vue.createElementBlock( "div", { class: vue.normalizeClass(["carousel", { "is-overlay": _ctx.overlay }]), onMouseenter: _cache[4] || (_cache[4] = (...args) => _ctx.checkPause && _ctx.checkPause(...args)), onMouseleave: _cache[5] || (_cache[5] = (...args) => _ctx.startTimer && _ctx.startTimer(...args)) }, [ _ctx.progress ? (vue.openBlock(), vue.createElementBlock("progress", { key: 0, class: vue.normalizeClass(["progress", _ctx.progressType]), value: _ctx.activeChild, max: _ctx.childItems.length - 1 }, vue.toDisplayString(_ctx.childItems.length - 1), 11, _hoisted_1$3)) : vue.createCommentVNode("v-if", true), vue.createElementVNode( "div", { class: "carousel-items", onMousedown: _cache[0] || (_cache[0] = (...args) => _ctx.dragStart && _ctx.dragStart(...args)), onMouseup: _cache[1] || (_cache[1] = (...args) => _ctx.dragEnd && _ctx.dragEnd(...args)), onTouchstart: _cache[2] || (_cache[2] = vue.withModifiers((...args) => _ctx.dragStart && _ctx.dragStart(...args), ["stop"])), onTouchend: _cache[3] || (_cache[3] = vue.withModifiers((...args) => _ctx.dragEnd && _ctx.dragEnd(...args), ["stop"])) }, [ vue.renderSlot(_ctx.$slots, "default"), _ctx.arrow ? (vue.openBlock(), vue.createElementBlock( "div", { key: 0, class: vue.normalizeClass(["carousel-arrow", { "is-hovered": _ctx.arrowHover }]) }, [ vue.withDirectives(vue.createVNode(_component_b_icon, { class: "has-icons-left", onClick: _ctx.prev, pack: _ctx.iconPack, icon: _ctx.iconPrev, size: _ctx.iconSize, both: "" }, null, 8, ["onClick", "pack", "icon", "size"]), [ [vue.vShow, _ctx.hasPrev] ]), vue.withDirectives(vue.createVNode(_component_b_icon, { class: "has-icons-right", onClick: _ctx.next, pack: _ctx.iconPack, icon: _ctx.iconNext, size: _ctx.iconSize, both: "" }, null, 8, ["onClick", "pack", "icon", "size"]), [ [vue.vShow, _ctx.hasNext] ]) ], 2 /* CLASS */ )) : vue.createCommentVNode("v-if", true) ], 32 /* NEED_HYDRATION */ ), _ctx.autoplay && _ctx.pauseHover && _ctx.pauseInfo && _ctx.isPause ? (vue.openBlock(), vue.createElementBlock("div", _hoisted_2$1, [ vue.createElementVNode( "span", { class: vue.normalizeClass(["tag", _ctx.pauseInfoType]) }, vue.toDisplayString(_ctx.pauseText), 3 /* TEXT, CLASS */ ) ])) : vue.createCommentVNode("v-if", true), _ctx.withCarouselList && !_ctx.indicator ? vue.renderSlot(_ctx.$slots, "list", { key: 2, active: _ctx.activeChild, switch: _ctx.changeActive }) : vue.createCommentVNode("v-if", true), _ctx.indicator ? (vue.openBlock(), vue.createElementBlock( "div", { key: 3, class: vue.normalizeClass(["carousel-indicator", _ctx.indicatorClasses]) }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.sortedItems, (item, index) => { return vue.openBlock(), vue.createElementBlock("a", { class: vue.normalizeClass(["indicator-item", { "is-active": item.isActive }]), onMouseover: ($event) => _ctx.modeChange("hover", index), onClick: ($event) => _ctx.modeChange("click", index), key: item.uniqueValue }, [ vue.renderSlot(_ctx.$slots, "indicators", { i: index }, () => [ vue.createElementVNode( "span", { class: vue.normalizeClass(["indicator-style", _ctx.indicatorStyle]) }, null, 2 /* CLASS */ ) ]) ], 42, _hoisted_3$1); }), 128 /* KEYED_FRAGMENT */ )) ], 2 /* CLASS */ )) : vue.createCommentVNode("v-if", true), _ctx.overlay ? vue.renderSlot(_ctx.$slots, "overlay", { key: 4 }) : vue.createCommentVNode("v-if", true) ], 34 /* CLASS, NEED_HYDRATION */ ); } var Carousel = /* @__PURE__ */ _export_sfc(_sfc_main$3, [["render", _sfc_render$3]]); var __defProp$2 = Object.defineProperty; var __defProps = Object.defineProperties; var __getOwnPropDescs = Object.getOwnPropertyDescriptors; var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols; var __hasOwnProp$2 = Object.prototype.hasOwnProperty; var __propIsEnum$2 = Object.prototype.propertyIsEnumerable; var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$2 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$2.call(b, prop)) __defNormalProp$2(a, prop, b[prop]); if (__getOwnPropSymbols$2) for (var prop of __getOwnPropSymbols$2(b)) { if (__propIsEnum$2.call(b, prop)) __defNormalProp$2(a, prop, b[prop]); } return a; }; var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b)); const sorted = 1; const optional = 2; const Sorted = sorted; var InjectedChildMixin = (parentItemName, flags) => { const mixin = { // FIXME: initializing `parent` with an empty string does not make // sense at all, but some code supposes that `parent` is non-null. // so I leave it as is for now. inject: { parent: { from: "b" + parentItemName, default: "" } }, props: { // if `value` is non-null, it must be unique among all the siblings. // see `uniqueValue` value: { type: String, default: null } }, computed: { // `ProviderParentMixin` uses `uniqueValue` computed value to // identify the child in its `childItems` collection. // so the value must be unique among all the siblings. // falls back to the `uid` internal field to ensure uniqueness. uniqueValue() { return this.value != null ? this.value : this.$.uid; } }, created() { if (!this.parent) { if (!hasFlag(flags, optional)) { throw new Error("You should wrap " + this.$options.name + " in a " + parentItemName); } } else if (this.parent._registerItem) { this.parent._registerItem(this); } }, beforeUnmount() { if (this.parent && this.parent._unregisterItem) { this.parent._unregisterItem(this); } } }; if (hasFlag(flags, sorted)) { mixin.props = __spreadProps(__spreadValues$2({}, mixin.props), { order: { type: Number, required: false } }); mixin.data = () => { return { dynamicIndex: void 0 }; }; mixin.computed = __spreadProps(__spreadValues$2({}, mixin.computed), { index() { return this.order != null ? this.order : this.dynamicIndex; } }); } return mixin; }; var _sfc_main$2 = vue.defineComponent({ name: "BCarouselItem", mixins: [InjectedChildMixin("carousel", Sorted)], data() { return { transitionName: null }; }, computed: { transition() { if (this.parent.animated === "fade") { return "fade"; } else if (this.parent.transition) { return "slide-" + this.parent.transition; } else { return void 0; } }, isActive() { return this.parent.activeChildIndex === this.index; } } }); const _hoisted_1$2 = { class: "carousel-item" }; function _sfc_render$2(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createBlock(vue.Transition, { name: _ctx.transition, persisted: "" }, { default: vue.withCtx(() => [ vue.withDirectives(vue.createElementVNode( "div", _hoisted_1$2, [ vue.renderSlot(_ctx.$slots, "default") ], 512 /* NEED_PATCH */ ), [ [vue.vShow, _ctx.isActive] ]) ]), _: 3 /* FORWARDED */ }, 8, ["name"]); } var CarouselItem = /* @__PURE__ */ _export_sfc(_sfc_main$2, [["render", _sfc_render$2]]); var __defProp$1 = Object.defineProperty; var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols; var __hasOwnProp$1 = Object.prototype.hasOwnProperty; var __propIsEnum$1 = Object.prototype.propertyIsEnumerable; var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues$1 = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]); if (__getOwnPropSymbols$1) for (var prop of __getOwnPropSymbols$1(b)) { if (__propIsEnum$1.call(b, prop)) __defNormalProp$1(a, prop, b[prop]); } return a; }; const BULMA_KNOWN_RATIO = [ "square", "1by1", "5by4", "4by3", "3by2", "5by3", "16by9", "b2y1", "3by1", "4by5", "3by4", "2by3", "3by5", "9by16", "1by2", "1by3" ]; function isBulmaKnownRatio(value) { return BULMA_KNOWN_RATIO.indexOf(value) !== -1; } var _sfc_main$1 = vue.defineComponent({ name: "BImage", props: { src: String, alt: String, srcFallback: String, webpFallback: { type: String, default: () => { return config.defaultImageWebpFallback; } }, lazy: { type: Boolean, default: () => { return config.defaultImageLazy; } }, responsive: { type: Boolean, default: () => { return config.defaultImageResponsive; } }, ratio: { type: String, default: () => { return config.defaultImageRatio; } }, placeholder: String, srcset: String, srcsetSizes: Array, srcsetFormatter: { type: Function, default: (src, size, vm) => { { return vm.formatSrcset(src, size); } } }, rounded: { type: Boolean, default: false }, captionFirst: { type: Boolean, default: false }, customClass: String }, emits: { /* eslint-disable @typescript-eslint/no-unused-vars */ load: (event, src) => true, error: (event, src) => true /* eslint-enable @typescript-eslint/no-unused-vars */ }, data() { return { clientWidth: 0, webpSupportVerified: false, webpSupported: false, useNativeLazy: false, observer: null, inViewPort: false, loaded: false, failed: false }; }, computed: { ratioPattern() { return /([0-9]+)by([0-9]+)/; }, hasRatio() { return this.ratio != null && this.ratioPattern.test(this.ratio); }, figureClasses() { const classes = { image: this.responsive }; if (this.hasRatio && isBulmaKnownRatio(this.ratio)) { classes[`is-${this.ratio}`] = true; } return classes; }, figureStyles() { if (this.hasRatio && !isBulmaKnownRatio(this.ratio)) { const ratioValues = this.ratioPattern.exec(this.ratio); return { paddingTop: `${+ratioValues[2] / +ratioValues[1] * 100}%` }; } return void 0; }, imgClasses() { return __spreadValues$1({ "is-rounded": this.rounded, "has-ratio": this.hasRatio }, this.customClass ? { [this.customClass]: !!this.customClass } : {}); }, srcExt() { return this.getExt(this.src); }, isWepb() { return this.srcExt === "webp"; }, computedSrc() { let src = this.src; if (this.failed && this.srcFallback) { src = this.srcFallback; } if (!this.webpSupported && this.isWepb && this.webpFallback) { if (this.webpFallback.startsWith(".")) { return src.replace(/\.webp/gi, `${this.webpFallback}`); } return this.webpFallback; } return src; }, computedWidth() { if (this.responsive && this.clientWidth > 0) { return this.clientWidth; } return void 0; }, computedNativeLazy() { if (this.lazy && this.useNativeLazy) { return "lazy"; } return void 0; }, isDisplayed() { return (this.webpSupportVerified || !this.isWepb) && (!this.lazy || this.useNativeLazy || this.inViewPort); }, placeholderExt() { if (this.placeholder) { return this.getExt(this.placeholder); } return void 0; }, isPlaceholderWepb() { if (this.placeholder) { return this.placeholderExt === "webp"; } return false; }, computedPlaceholder() { if (!this.webpSupported && this.isPlaceholderWepb && this.webpFallback && this.webpFallback.startsWith(".")) { return this.placeholder.replace(/\.webp/gi, `${this.webpFallback}`); } return this.placeholder; }, isPlaceholderDisplayed() { return !this.loaded && (this.$slots.placeholder || this.placeholder && (this.webpSupportVerified || !this.isPlaceholderWepb)); }, computedSrcset() { if (this.srcset) { if (!this.webpSupported && this.isWepb && this.webpFallback && this.webpFallback.startsWith(".")) { return this.srcset.replace(/\.webp/gi, `${this.webpFallback}`); } return this.srcset; } if (this.srcsetSizes && Array.isArray(this.srcsetSizes) && this.srcsetSizes.length > 0) { return this.srcsetSizes.map((size) => { return `${this.srcsetFormatter(this.computedSrc, size, this)} ${size}w`; }).join(","); } return void 0; }, computedSizes() { if (this.computedSrcset && this.computedWidth) { return `${this.computedWidth}px`; } return void 0; }, isCaptionFirst() { return this.$slots.caption && this.captionFirst; }, isCaptionLast() { return this.$slots.caption && !this.captionFirst; } }, methods: { getExt(filename, clean = true) { if (filename) { const noParam = clean ? filename.split("?")[0] : filename; return noParam.split(".").pop(); } return ""; }, setWidth() { this.clientWidth = this.$el.clientWidth; }, formatSrcset(src, size) { const ext = this.getExt(src, false); const name = src.split(".").slice(0, -1).join("."); return `${name}-${size}.${ext}`; }, onLoad(event) { this.loaded = true; this.emitSrc(event, (src) => this.$emit("load", event, src)); }, onError(event) { this.emitSrc(event, (src) => this.$emit("error", event, src)); if (!this.failed) { this.failed = true; } }, emitSrc(event, emit) { const target = event.target; emit(target.currentSrc || target.src || this.computedSrc); } }, created() { if (this.isWepb) { isWebpSupported().then((supported) => { this.webpSupportVerified = true; this.webpSupported = supported; }); } if (this.lazy) { const nativeLazySupported = typeof window !== "undefined" && "HTMLImageElement" in window && "loading" in HTMLImageElement.prototype; const intersectionObserverSupported = typeof window !== "undefined" && "IntersectionObserver" in window; if (!nativeLazySupported && intersectionObserverSupported) { this.observer = new IntersectionObserver((events) => { const { target, isIntersecting } = events[0]; if (isIntersecting && !this.inViewPort) { this.inViewPort = true; this.observer.unobserve(target); } }); } else { this.useNativeLazy = true; } } }, mounted() { if (this.lazy && this.observer) { this.observer.observe(this.$el); } this.setWidth(); if (typeof window !== "undefined") { window.addEventListener("resize", this.setWidth); } }, beforeUnmount() { if (this.observer) { this.observer.disconnect(); } if (typeof window !== "undefined") { window.removeEventListener("resize", this.setWidth); } } }); const _hoisted_1$1 = { key: 0 }; const _hoisted_2 = ["srcset", "src", "alt", "width", "sizes", "loading"]; const _hoisted_3 = ["src", "alt"]; const _hoisted_4 = { key: 1 }; function _sfc_render$1(_ctx, _cache, $props, $setup, $data, $options) { return vue.openBlock(), vue.createElementBlock( "figure", { class: vue.normalizeClass(["b-image-wrapper", _ctx.figureClasses]), style: vue.normalizeStyle(_ctx.figureStyles) }, [ _ctx.isCaptionFirst ? (vue.openBlock(), vue.createElementBlock("figcaption", _hoisted_1$1, [ vue.renderSlot(_ctx.$slots, "caption") ])) : vue.createCommentVNode("v-if", true), vue.createVNode(vue.Transition, { name: "fade" }, { default: vue.withCtx(() => [ _ctx.isDisplayed ? (vue.openBlock(), vue.createElementBlock("img", { key: 0, srcset: _ctx.computedSrcset, src: _ctx.computedSrc, alt: _ctx.alt, class: vue.normalizeClass(_ctx.imgClasses), width: _ctx.computedWidth, sizes: _ctx.computedSizes, loading: _ctx.computedNativeLazy, onLoad: _cache[0] || (_cache[0] = (...args) => _ctx.onLoad && _ctx.onLoad(...args)), onError: _cache[1] || (_cache[1] = (...args) => _ctx.onError && _ctx.onError(...args)) }, null, 42, _hoisted_2)) : vue.createCommentVNode("v-if", true) ]), _: 1 /* STABLE */ }), vue.createVNode(vue.Transition, { name: "fade" }, { default: vue.withCtx(() => [ _ctx.isPlaceholderDisplayed ? vue.renderSlot(_ctx.$slots, "placeholder", { key: 0 }, () => [ vue.createElementVNode("img", { src: _ctx.computedPlaceholder, alt: _ctx.alt, class: vue.normalizeClass([_ctx.imgClasses, "placeholder"]) }, null, 10, _hoisted_3) ]) : vue.createCommentVNode("v-if", true) ]), _: 3 /* FORWARDED */ }), _ctx.isCaptionLast ? (vue.openBlock(), vue.createElementBlock("figcaption", _hoisted_4, [ vue.renderSlot(_ctx.$slots, "caption") ])) : vue.createCommentVNode("v-if", true) ], 6 /* CLASS, STYLE */ ); } var BImage = /* @__PURE__ */ _export_sfc(_sfc_main$1, [["render", _sfc_render$1]]); var __defProp = Object.defineProperty; var __getOwnPropSymbols = Object.getOwnPropertySymbols; var __hasOwnProp = Object.prototype.hasOwnProperty; var __propIsEnum = Object.prototype.propertyIsEnumerable; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __spreadValues = (a, b) => { for (var prop in b || (b = {})) if (__hasOwnProp.call(b, prop)) __defNormalProp(a, prop, b[prop]); if (__getOwnPropSymbols) for (var prop of __getOwnPropSymbols(b)) { if (__propIsEnum.call(b, prop)) __defNormalProp(a, prop, b[prop]); } return a; }; var _sfc_main = vue.defineComponent({ name: "BCarouselList", components: { BIcon, BImage }, props: { data: { type: Array, default: () => [] }, modelValue: { type: Number, default: 0 }, scrollValue: { type: Number, default: 0 }, hasDrag: { type: Boolean, default: true }, hasGrayscale: Boolean, hasOpacity: Boolean, repeat: Boolean, itemsToShow: { type: Number, default: 4 }, itemsToList: { type: Number, default: 1 }, asIndicator: Boolean, arrow: { type: Boolean, default: true }, arrowHover: { type: Boolean, default: true }, iconPack: String, iconSize: String, iconPrev: { type: String, default: () => { return config.defaultIconPrev; } }, iconNext: { type: String, default: () => { return config.defaultIconNext; } }, breakpoints: { type: Object, default: () => ({}) } }, emits: { /* eslint-disable @typescript-eslint/no-unused-vars */ switch: (_value) => true, "update:modelValue": (_value) => true, "updated:scroll": (_index) => true /* eslint-enable @typescript-eslint/no-unused-vars */ }, data() { return { activeItem: this.modelValue, scrollIndex: this.asIndicator ? this.scrollValue : this.modelValue, delta: 0, dragX: false, hold: 0, windowWidth: 0, touch: false, observer: null, refresh_: 0 }; }, computed: { dragging() { return this.dragX !== false; }, listClass() { return [ { "has-grayscale": this.settings.hasGrayscale, "has-opacity": this.settings.hasOpacity, "is-dragging": this.dragging } ]; }, itemStyle() { return `width: ${this.itemWidth}px;`; }, translation() { return -bound( this.delta + this.scrollIndex * this.itemWidth, 0, (this.data.length - this.settings.itemsToShow) * this.itemWidth ); }, total() { return this.data.length - this.settings.itemsToShow; }, hasPrev() { return this.settings.repeat || this.scrollIndex > 0; }, hasNext() { return this.settings.repeat || this.scrollIndex < this.total; }, breakpointKeys() { return Object.keys(this.breakpoints).sort((a, b) => +b - +a); }, settings() { const breakpoint = this.breakpointKeys.filter((breakpoint2) => { if (this.windowWidth >= +breakpoint2) { return true; } else { return false; } })[0]; if (breakpoint) { return __spreadValues(__spreadValues({}, this.$props), this.breakpoints[+breakpoint]); } return this.$props; }, itemWidth() { if (this.windowWidth) { this.refresh_; const rect = this.$el.getBoundingClientRect(); return rect.width / this.settings.itemsToShow; } return 0; } }, watch: { /* * When v-model is changed set the new active item. */ modelValue(value) { this.switchTo(this.asIndicator ? value - (this.itemsToShow - 3) / 2 : value); if (this.activeItem !== value) { this.activeItem = bound(value, 0, this.data.length - 1); } }, scrollValue(value) { this.switchTo(value); } }, methods: { resized() { this.windowWidth = window.innerWidth; }, switchTo(newIndex) { if (newIndex === this.scrollIndex || isNaN(newIndex)) { return; } if (this.settings.repeat) { newIndex = mod(newIndex, this.total + 1); } newIndex = bound(newIndex, 0, this.total); this.scrollIndex = newIndex; if (!this.asIndicator && this.modelValue !== newIndex) { this.$emit("update:modelValue", newIndex); } else if (this.scrollIndex !== newIndex) { this.$emit("updated:scroll", newIndex); } }, next() { this.switchTo(this.scrollIndex + this.settings.itemsToList); }, prev() { this.switchTo(this.scrollIndex - this.settings.itemsToList); }, checkAsIndicator(value, event) { if (!this.asIndicator) return; const dragEndX = event.changedTouches ? event.changedTouches[0].clientX : event.clientX; if (this.hold - Date.now() > 2e3 || Math.abs(+this.dragX - dragEndX) > 10) return; this.dragX = false; this.hold = 0; event.preventDefault(); this.activeItem = value; this.$emit("switch", value); }, // handle drag event dragStart(event) { if (this.dragging || !this.settings.hasDrag || event.button !== 0 && event.type !== "touchstart") return; this.hold = Date.now(); this.touch = !!event.touches; this.dragX = this.touch ? event.touches[0].clientX : event.clientX; window.addEventListener(this.touch ? "touchmove" : "mousemove", this.dragMove); window.addEventListener(this.touch ? "touchend" : "mouseup", this.dragEnd); }, dragMove(event) { if (!this.dragging) return; const dragEndX = event.touches ? (event.changedTouches[0] || event.touches[0]).clientX : event.clientX; this.delta = +this.dragX - dragEndX; if (!event.touches) { event.preventDefault(); } }, dragEnd() { if (!this.dragging && !this.hold) return; if (this.hold) { const signCheck = sign(this.delta); const results = Math.round(Math.abs(this.delta / this.itemWidth) + 0.15); this.switchTo(this.scrollIndex + signCheck * results); } this.delta = 0; this.dragX = false; window.removeEventListener(this.touch ? "touchmove" : "mousemove", this.dragMove); window.removeEventListener(this.touch ? "touchend" : "mouseup", this.dragEnd); }, refresh() { this.$nextTick(() => { this.refresh_++; }); } }, mounted() { if (typeof window !== "undefined") { if (window.ResizeObserver) { this.observer = new ResizeObserver(this.refresh); this.observer.observe(this.$el); } window.addEventListener("resize", this.resized); document.addEventListener("animationend", this.refresh); document.addEventListener("transitionend", this.refresh); document.addEventListener("transitionstart", this.refresh); this.resized(); } if (this.$attrs.config) { throw new Error("The config prop was removed, you need to use v-bind instead"); } }, beforeUnmount() { if (typeof window !== "undefined") { if (window.ResizeObserver) { this.observer.disconnect(); } window.removeEventListener("resize", this.resized); document.removeEventListener("animationend", this.refresh); document.removeEventListener("transitionend", this.refresh); document.removeEventListener("transitionstart", this.refresh); this.dragEnd(); } } }); const _hoisted_1 = ["onMouseup", "onTouchend"]; function _sfc_render(_ctx, _cache, $props, $setup, $data, $options) { const _component_b_image = vue.resolveComponent("b-image"); const _component_b_icon = vue.resolveComponent("b-icon"); return vue.openBlock(), vue.createElementBlock( "div", { class: vue.normalizeClass(["carousel-list", { "has-shadow": _ctx.scrollIndex > 0 }]), onMousedown: _cache[0] || (_cache[0] = vue.withModifiers((...args) => _ctx.dragStart && _ctx.dragStart(...args), ["prevent"])), onTouchstart: _cache[1] || (_cache[1] = (...args) => _ctx.dragStart && _ctx.dragStart(...args)) }, [ vue.createElementVNode( "div", { class: vue.normalizeClass(["carousel-slides", _ctx.listClass]), style: vue.normalizeStyle("transform:translateX(" + _ctx.translation + "px)") }, [ (vue.openBlock(true), vue.createElementBlock( vue.Fragment, null, vue.renderList(_ctx.data, (list, index) => { return vue.openBlock(), vue.createElementBlock("div", { class: vue.normalizeClass(["carousel-slide", { "is-active": _ctx.asIndicator ? _ctx.activeItem === index : _ctx.scrollIndex === index }]), onMouseup: ($event) => _ctx.checkAsIndicator(index, $event), onTouchend: ($event) => _ctx.checkAsIndicator(index, $event), key: index, style: vue.normalizeStyle(_ctx.itemStyle) }, [ vue.renderSlot(_ctx.$slots, "item", vue.mergeProps({ index, active: _ctx.activeItem, scroll: _ctx.scrollIndex }, list, { list }), () => [ vue.createVNode(_component_b_image, vue.mergeProps({ src: list.image }, list), null, 16, ["src"]) ]) ], 46, _hoisted_1); }), 128 /* KEYED_FRAGMENT */ )) ], 6 /* CLASS, STYLE */ ), _ctx.arrow ? (vue.openBlock(), vue.createElementBlock( "div", { key: 0, class: vue.normalizeClass(["carousel-arrow", { "is-hovered": _ctx.settings.arrowHover }]) }, [ vue.withDirectives(vue.createVNode(_component_b_icon, { class: "has-icons-left", onClick: vue.withModifiers(_ctx.prev, ["prevent"]), pack: _ctx.settings.iconPack, icon: _ctx.settings.iconPrev, size: _ctx.settings.iconSize, both: "" }, null, 8, ["onClick", "pack", "icon", "size"]), [ [vue.vShow, _ctx.hasPrev] ]), vue.withDirectives(vue.createVNode(_component_b_icon, { class: "has-icons-right", onClick: vue.withModifiers(_ctx.next, ["prevent"