bootstrap-vue-next
Version:
Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development
415 lines (414 loc) • 14.5 kB
JavaScript
import { o as carouselInjectionKey } from "./keys-CQKrwmvN.mjs";
import { L as useIntervalFn, f as useElementHover, o as onKeyStroke, x as useSwipe, z as useToNumber } from "./dist-B10a-gZ8.mjs";
import { o as isEmptySlot } from "./dom-AhkaSoh8.mjs";
import { t as useDefaults } from "./useDefaults-BKgBaqOV.mjs";
import { t as useId$1 } from "./useId-BKZFSYm8.mjs";
import { t as BvCarouselEvent } from "./classes-B0E5Y78Y.mjs";
import { t as BImg_default } from "./BImg-BQqZfIM9.mjs";
import { Fragment, TransitionGroup, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createVNode, defineComponent, inject, mergeModels, normalizeClass, normalizeStyle, onMounted, openBlock, provide, ref, renderList, renderSlot, resolveDynamicComponent, toDisplayString, toRef, unref, useModel, useSlots, useTemplateRef, vShow, watch, withCtx, withDirectives } from "vue";
//#region src/utils/getSlotElements.ts
var getSlotElements = (slot, filterBy) => (slot?.() ?? []).reduce((arr, slot) => {
if (typeof slot.type === "symbol") arr = arr.concat(slot.children);
else arr.push(slot);
return arr;
}, []).filter((child) => child.type?.__name === filterBy);
//#endregion
//#region src/components/BCarousel/BCarousel.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1$1 = ["id"];
var _hoisted_2 = ["aria-label", "aria-owns"];
var _hoisted_3 = [
"aria-current",
"aria-label",
"aria-controls",
"aria-describedby",
"onClick"
];
var _hoisted_4 = {
ref: "_relatedTarget",
class: "carousel-inner"
};
var _hoisted_5 = { class: "visually-hidden" };
var _hoisted_6 = { class: "visually-hidden" };
//#endregion
//#region src/components/BCarousel/BCarousel.vue
var BCarousel_default = /* @__PURE__ */ defineComponent({
__name: "BCarousel",
props: /* @__PURE__ */ mergeModels({
background: { default: void 0 },
controls: {
type: Boolean,
default: false
},
controlsNextText: { default: "Next" },
controlsPrevText: { default: "Previous" },
fade: {
type: Boolean,
default: false
},
id: { default: void 0 },
imgHeight: { default: void 0 },
imgWidth: { default: void 0 },
indicators: {
type: Boolean,
default: false
},
indicatorsButtonLabel: { default: "Slide" },
interval: { default: 5e3 },
labelIndicators: { default: "Select a slide to display" },
keyboard: {
type: Boolean,
default: true
},
noAnimation: {
type: Boolean,
default: false
},
noHoverPause: {
type: Boolean,
default: false
},
noTouch: {
type: Boolean,
default: false
},
noWrap: {
type: Boolean,
default: false
},
ride: {
type: [Boolean, String],
default: false
},
rideReverse: {
type: Boolean,
default: false
},
touchThreshold: { default: 50 }
}, {
"modelValue": { default: 0 },
"modelModifiers": {}
}),
emits: /* @__PURE__ */ mergeModels([
"slide",
"slid",
"prev-click",
"next-click"
], ["update:modelValue"]),
setup(__props, { expose: __expose, emit: __emit }) {
const props = useDefaults(__props, "BCarousel");
const emit = __emit;
const slots = useSlots();
const computedId = useId$1(() => props.id, "carousel");
const buttonOwnership = useId$1(void 0, "carousel-button-ownership");
const modelValue = useModel(__props, "modelValue");
const slideValues = useTemplateRef("_slideValues");
const touchThresholdNumber = useToNumber(() => props.touchThreshold);
const slideInterval = ref(null);
onMounted(() => {
slideInterval.value = slideValues.value?.find((slid) => slid.$el.style.display !== "none")?._interval ?? null;
});
const intervalNumber = useToNumber(() => slideInterval.value ?? props.interval);
const isTransitioning = ref(false);
const rideStarted = ref(false);
const direction = ref(true);
const relatedTarget = useTemplateRef("_relatedTarget");
const element = useTemplateRef("_element");
const previousModelValue = ref(modelValue.value);
const isHovering = useElementHover(element);
const enterClasses = computed(() => `carousel-item carousel-item-${!direction.value ? "next" : "prev"} carousel-item-${!direction.value ? "start" : "end"}`);
const leaveClasses = computed(() => `carousel-item active carousel-item-${direction.value ? "start" : "end"}`);
const { pause, resume } = useIntervalFn(() => {
if (props.rideReverse) {
prev();
return;
}
next();
}, intervalNumber, { immediate: props.ride === "carousel" });
const isRiding = computed(() => props.ride === true && rideStarted.value === true || props.ride === "carousel");
const slides = computed(() => getSlotElements(slots.default, "BCarouselSlide"));
const computedClasses = computed(() => ({ "carousel-fade": props.fade }));
const buildBvCarouselEvent = (event) => new BvCarouselEvent(event, {
componentId: computedId.value,
cancelable: false,
target: element.value,
direction: direction.value ? "right" : "left",
from: previousModelValue.value,
to: modelValue.value,
relatedTarget: relatedTarget.value?.children[modelValue.value] ?? null
});
const goToValue = (value) => {
if (isTransitioning.value === true) return;
if (props.ride === true) rideStarted.value = true;
if (isRiding.value === true) resume();
direction.value = value < modelValue.value ? false : true;
if (value >= slides.value.length) {
if (props.noWrap) return;
modelValue.value = 0;
return;
}
if (value < 0) {
if (props.noWrap) return;
modelValue.value = slides.value.length - 1;
return;
}
previousModelValue.value = modelValue.value;
modelValue.value = value;
};
const prev = () => {
goToValue(modelValue.value - 1);
};
const next = () => {
goToValue(modelValue.value + 1);
};
const onKeydown = (fn) => {
if (props.keyboard === false) return;
fn();
};
const onMouseEnter = () => {
if (props.noHoverPause) return;
pause();
};
const onMouseLeave = () => {
if (!isRiding.value) return;
resume();
};
const { lengthX } = useSwipe(element, {
passive: true,
onSwipeStart() {
if (props.noTouch === true) return;
pause();
},
onSwipeEnd() {
if (props.noTouch === true) return;
const resumeRiding = () => {
if (isRiding.value === false) return;
resume();
};
if (lengthX.value >= touchThresholdNumber.value) {
next();
resumeRiding();
return;
}
if (lengthX.value <= -touchThresholdNumber.value) {
prev();
resumeRiding();
}
}
});
const onBeforeLeave = () => {
emit("slide", buildBvCarouselEvent("slide"));
isTransitioning.value = true;
};
const onAfterLeave = () => {
emit("slid", buildBvCarouselEvent("slid"));
isTransitioning.value = false;
};
const onAfterEnter = (el) => {
if (modelValue.value !== 0) el.classList.add("carousel-item");
};
const onEnter = (el) => {
slideInterval.value = slideValues.value?.find((slid) => slid.$el === el)?._interval ?? null;
};
onKeyStroke("ArrowLeft", () => {
onKeydown(prev);
}, { target: element });
onKeyStroke("ArrowRight", () => {
onKeydown(next);
}, {
target: element,
passive: true
});
watch(() => props.ride, () => {
rideStarted.value = false;
});
watch(isHovering, (newValue) => {
if (newValue) {
onMouseEnter();
return;
}
onMouseLeave();
});
const onClickPrev = (event) => {
emit("prev-click", event);
if (event.defaultPrevented) return;
prev();
};
const onClickNext = (event) => {
emit("next-click", event);
if (event.defaultPrevented) return;
next();
};
__expose({
next,
pause,
prev,
resume
});
provide(carouselInjectionKey, {
background: toRef(() => props.background),
width: toRef(() => props.imgWidth),
height: toRef(() => props.imgHeight)
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
id: unref(computedId),
ref: "_element",
class: normalizeClass(["carousel slide pointer-event", computedClasses.value])
}, [
unref(props).indicators ? (openBlock(), createElementBlock("div", {
key: 0,
class: "carousel-indicators",
"aria-label": unref(props).labelIndicators,
"aria-owns": unref(buttonOwnership)
}, [(openBlock(true), createElementBlock(Fragment, null, renderList(slides.value.length, (_, i) => {
return openBlock(), createElementBlock("button", {
key: i,
type: "button",
"data-bs-target": "",
class: normalizeClass(i === modelValue.value ? "active" : ""),
"aria-current": i === modelValue.value ? true : void 0,
"aria-label": `${unref(props).indicatorsButtonLabel} ${i}`,
"aria-controls": unref(buttonOwnership),
"aria-describedby": slideValues.value?.[i]?._id,
onClick: ($event) => goToValue(i)
}, null, 10, _hoisted_3);
}), 128))], 8, _hoisted_2)) : createCommentVNode("", true),
createElementVNode("div", _hoisted_4, [createVNode(TransitionGroup, {
"enter-from-class": enterClasses.value,
"enter-active-class": enterClasses.value,
"enter-to-class": enterClasses.value,
"leave-from-class": leaveClasses.value,
"leave-active-class": leaveClasses.value,
"leave-to-class": leaveClasses.value,
onBeforeLeave,
onAfterLeave,
onAfterEnter,
onEnter
}, {
default: withCtx(() => [(openBlock(true), createElementBlock(Fragment, null, renderList(slides.value, (slide, i) => {
return withDirectives((openBlock(), createBlock(resolveDynamicComponent(slide), {
key: i,
ref_for: true,
ref: "_slideValues",
class: normalizeClass({ active: i === modelValue.value && isTransitioning.value === false }),
style: normalizeStyle(unref(props).noAnimation && { transition: "none" })
}, null, 8, ["class", "style"])), [[vShow, i === modelValue.value]]);
}), 128))]),
_: 1
}, 8, [
"enter-from-class",
"enter-active-class",
"enter-to-class",
"leave-from-class",
"leave-active-class",
"leave-to-class"
])], 512),
unref(props).controls ? (openBlock(), createElementBlock(Fragment, { key: 1 }, [createElementVNode("button", {
class: "carousel-control-prev",
type: "button",
onClick: onClickPrev
}, [_cache[0] || (_cache[0] = createElementVNode("span", {
class: "carousel-control-prev-icon",
"aria-hidden": "true"
}, null, -1)), createElementVNode("span", _hoisted_5, toDisplayString(unref(props).controlsPrevText), 1)]), createElementVNode("button", {
class: "carousel-control-next",
type: "button",
onClick: onClickNext
}, [_cache[1] || (_cache[1] = createElementVNode("span", {
class: "carousel-control-next-icon",
"aria-hidden": "true"
}, null, -1)), createElementVNode("span", _hoisted_6, toDisplayString(unref(props).controlsNextText), 1)])], 64)) : createCommentVNode("", true)
], 10, _hoisted_1$1);
};
}
});
//#endregion
//#region src/components/BCarousel/BCarouselSlide.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = ["id"];
//#endregion
//#region src/components/BCarousel/BCarouselSlide.vue
var BCarouselSlide_default = /* @__PURE__ */ defineComponent({
__name: "BCarouselSlide",
props: {
background: { default: void 0 },
caption: { default: void 0 },
captionTag: { default: "h3" },
contentTag: { default: "div" },
contentVisibleUp: { default: void 0 },
id: { default: void 0 },
imgAlt: { default: void 0 },
imgBlank: {
type: Boolean,
default: false
},
imgBlankColor: { default: "transparent" },
imgHeight: { default: void 0 },
imgSrc: { default: void 0 },
imgSrcset: { default: void 0 },
imgWidth: { default: void 0 },
interval: { default: void 0 },
text: { default: void 0 },
textTag: { default: "p" }
},
setup(__props, { expose: __expose }) {
const props = useDefaults(__props, "BCarouselSlide");
const slots = useSlots();
const computedId = useId$1(() => props.id, "carousel-slide");
const parentData = inject(carouselInjectionKey, null);
const hasText = computed(() => props.text || !isEmptySlot(slots.text));
const hasCaption = computed(() => props.caption || !isEmptySlot(slots.caption));
const hasContent = computed(() => hasText.value || hasCaption.value || !isEmptySlot(slots.default));
const computedStyle = computed(() => ({ background: `${props.background || parentData?.background.value || "rgb(171, 171, 171)"} none repeat scroll 0% 0%` }));
const computedContentClasses = computed(() => ({
"d-none": props.contentVisibleUp !== void 0,
[`d-${props.contentVisibleUp}-block`]: props.contentVisibleUp !== void 0
}));
__expose({
_interval: toRef(() => props.interval),
_id: computedId
});
return (_ctx, _cache) => {
return openBlock(), createElementBlock("div", {
id: unref(computedId),
class: "carousel-item",
style: normalizeStyle(computedStyle.value)
}, [renderSlot(_ctx.$slots, "img", {}, () => [createVNode(BImg_default, {
class: "d-block w-100",
alt: unref(props).imgAlt,
srcset: unref(props).imgSrcset,
src: unref(props).imgSrc,
width: unref(props).imgWidth || unref(parentData)?.width.value,
height: unref(props).imgHeight || unref(parentData)?.height.value,
blank: unref(props).imgBlank,
"blank-color": unref(props).imgBlankColor
}, null, 8, [
"alt",
"srcset",
"src",
"width",
"height",
"blank",
"blank-color"
])]), hasContent.value ? (openBlock(), createBlock(resolveDynamicComponent(unref(props).contentTag), {
key: 0,
class: normalizeClass(["carousel-caption", computedContentClasses.value])
}, {
default: withCtx(() => [
hasCaption.value ? (openBlock(), createBlock(resolveDynamicComponent(unref(props).captionTag), { key: 0 }, {
default: withCtx(() => [renderSlot(_ctx.$slots, "caption", {}, () => [createElementVNode("span", null, toDisplayString(unref(props).caption), 1)])]),
_: 3
})) : createCommentVNode("", true),
hasText.value ? (openBlock(), createBlock(resolveDynamicComponent(unref(props).textTag), { key: 1 }, {
default: withCtx(() => [renderSlot(_ctx.$slots, "text", {}, () => [createElementVNode("span", null, toDisplayString(unref(props).text), 1)])]),
_: 3
})) : createCommentVNode("", true),
renderSlot(_ctx.$slots, "default")
]),
_: 3
}, 8, ["class"])) : createCommentVNode("", true)], 12, _hoisted_1);
};
}
});
//#endregion
export { BCarousel_default as n, BCarouselSlide_default as t };
//# sourceMappingURL=BCarousel-D81alfFC.mjs.map