bootstrap-vue-next
Version:
Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development
530 lines (529 loc) • 18.5 kB
JavaScript
import { D as createSharedComposable, a as onClickOutside, v as useMouse$1, z as useToNumber } from "./dist-B10a-gZ8.mjs";
import { a as getSafeWindow, i as getSafeDocument } from "./dom-AhkaSoh8.mjs";
import { t as useDefaults } from "./useDefaults-BKgBaqOV.mjs";
import { t as useId$1 } from "./useId-BKZFSYm8.mjs";
import { t as useShowHide } from "./useShowHide-yAK5dhPT.mjs";
import { t as ConditionalTeleport_default } from "./ConditionalTeleport-BNsziElf.mjs";
import { a as flip, d as size, i as autoUpdate, l as offset, n as useFloating, o as hide, r as autoPlacement, s as inline, t as arrow, u as shift } from "./floating-ui.vue-CAMaNcqI.mjs";
import { t as getElement } from "./getElement-0_htvrFw.mjs";
import { Fragment, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, guardReactiveProps, h, mergeModels, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, openBlock, ref, render, renderSlot, toDisplayString, toRef, toValue, unref, useAttrs, useModel, useSlots, useTemplateRef, vShow, watch, withCtx, withDirectives } from "vue";
//#region src/composables/useMouse.ts
var useMouse = createSharedComposable(useMouse$1);
//#endregion
//#region src/components/BPopover/BPopover.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = ["id"];
var _hoisted_2 = ["id"];
//#endregion
//#region src/components/BPopover/BPopover.vue
var BPopover_default = /* @__PURE__ */ defineComponent({
inheritAttrs: false,
__name: "BPopover",
props: /* @__PURE__ */ mergeModels({
body: { default: void 0 },
bodyClass: { default: void 0 },
boundary: { default: "clippingAncestors" },
boundaryPadding: { default: void 0 },
click: {
type: Boolean,
default: void 0
},
closeOnHide: {
type: Boolean,
default: false
},
focus: {
type: Boolean,
default: void 0
},
hover: {
type: Boolean,
default: void 0
},
delay: { default: () => ({
show: 100,
hide: 300
}) },
floatingMiddleware: { default: void 0 },
hideMargin: { default: 2 },
id: { default: void 0 },
inline: {
type: Boolean,
default: false
},
manual: {
type: Boolean,
default: false
},
noAutoClose: {
type: Boolean,
default: false
},
noFlip: {
type: Boolean,
default: false
},
noHide: {
type: Boolean,
default: false
},
noShift: {
type: Boolean,
default: false
},
noSize: {
type: Boolean,
default: false
},
noninteractive: {
type: Boolean,
default: false
},
offset: { default: null },
placement: { default: "top" },
realtime: {
type: Boolean,
default: false
},
reference: {
type: [
String,
Object,
null,
Function
],
default: null
},
strategy: { default: "absolute" },
target: {
type: [
String,
Object,
null,
Function
],
default: null
},
title: { default: void 0 },
titleClass: { default: void 0 },
tooltip: {
type: Boolean,
default: false
},
teleportDisabled: {
type: Boolean,
default: false
},
teleportTo: { default: void 0 },
initialAnimation: {
type: Boolean,
default: false
},
noAnimation: { type: Boolean },
noFade: {
type: Boolean,
default: false
},
lazy: {
type: Boolean,
default: false
},
unmountLazy: {
type: Boolean,
default: false
},
show: {
type: Boolean,
default: false
},
transProps: {},
visible: {
type: Boolean,
default: false
}
}, {
"modelValue": {
type: Boolean,
default: false
},
"modelModifiers": {}
}),
emits: /* @__PURE__ */ mergeModels([
"click",
"pointerleave",
"blur",
"click-outside",
"close-on-hide",
"hide",
"hide-prevented",
"hidden",
"show",
"show-prevented",
"shown",
"toggle",
"toggle-prevented"
], ["update:modelValue"]),
setup(__props, { expose: __expose, emit: __emit }) {
const props = useDefaults(__props, "BPopover");
const emit = __emit;
const slots = useSlots();
const attrs = useAttrs();
const modelValue = useModel(__props, "modelValue");
const computedId = useId$1(() => props.id, "popover");
const hidden = ref(false);
const floatingElement = useTemplateRef("_element");
const content = useTemplateRef("_content");
const arrow$1 = useTemplateRef("_arrow");
const placeholder = useTemplateRef("_placeholder");
const referenceElement = ref(null);
const triggerElement = ref(null);
const isAutoPlacement = computed(() => props.placement.startsWith("auto"));
const offsetNumber = useToNumber(() => props.offset ?? NaN);
const boundary = computed(() => isBoundary(props.boundary) ? props.boundary : void 0);
const rootBoundary = computed(() => isRootBoundary(props.boundary) ? props.boundary : void 0);
const sizeStyles = ref({});
const floatingMiddleware = computed(() => {
if (props.floatingMiddleware !== void 0) return props.floatingMiddleware;
const arr = [offset(props.offset !== null ? offsetNumber.value : props.tooltip ? 6 : 8)];
if (props.noFlip === false && !isAutoPlacement.value) arr.push(flip({
boundary: boundary.value,
rootBoundary: rootBoundary.value,
padding: props.boundaryPadding
}));
if (isAutoPlacement.value) arr.push(autoPlacement({
alignment: props.placement.split("-")[1] || void 0,
boundary: boundary.value,
rootBoundary: rootBoundary.value,
padding: props.boundaryPadding
}));
if (props.noShift === false) arr.push(shift({
boundary: boundary.value,
rootBoundary: rootBoundary.value,
padding: props.boundaryPadding
}));
if (props.noHide === false) arr.push(hide({
boundary: boundary.value,
rootBoundary: rootBoundary.value,
padding: props.boundaryPadding
}));
if (props.inline === true) arr.push(inline());
arr.push(arrow({
element: arrow$1,
padding: 10
}));
if (props.noSize === false) arr.push(size({
boundary: boundary.value,
rootBoundary: rootBoundary.value,
padding: props.boundaryPadding,
apply({ availableWidth, availableHeight }) {
sizeStyles.value = {
"--bv-floating-max-height": availableHeight >= (content.value?.scrollHeight ?? 0) ? void 0 : availableHeight ? `${Math.max(0, availableHeight)}px` : void 0,
"--bv-floating-max-width": availableWidth >= (content.value?.scrollWidth ?? 0) ? void 0 : availableWidth ? `${Math.max(0, availableWidth)}px` : void 0
};
}
}));
return arr;
});
const { floatingStyles, middlewareData, placement, update } = useFloating(referenceElement, floatingElement, {
placement: computed(() => isAutoPlacement.value ? void 0 : props.placement),
middleware: floatingMiddleware,
strategy: toRef(() => props.strategy)
});
const arrowStyle = ref({ position: "absolute" });
let cleanup;
const { showRef, hide: hide$1, show, toggle, throttleHide, computedNoAnimation, transitionProps, contentShowing, isVisible, isActive, renderRef, localTemporaryHide, setLocalTemporaryHide } = useShowHide(modelValue, props, emit, floatingElement, computedId, {
showFn: () => {
update();
nextTick(() => {
cleanup = autoUpdate(referenceElement.value, floatingElement.value, update, { animationFrame: props.realtime });
});
},
hideFn: () => {
if (cleanup) {
cleanup();
cleanup = void 0;
}
}
});
watch(middlewareData, (newValue) => {
if (props.noHide === false) {
if (newValue.hide?.referenceHidden && !hidden.value && showRef.value) if (props.closeOnHide && !props.noAutoClose && !props.manual) throttleHide("close-on-hide");
else {
setLocalTemporaryHide(true);
hidden.value = true;
}
else if (localTemporaryHide.value && !newValue.hide?.referenceHidden) {
setLocalTemporaryHide(false);
hidden.value = false;
}
}
if (newValue.arrow) {
const { x, y } = newValue.arrow;
arrowStyle.value = {
position: "absolute",
top: y ? `${y}px` : "",
left: x ? `${x}px` : ""
};
}
});
const computedClasses = computed(() => {
const type = props.tooltip ? "tooltip" : "popover";
return [
type,
`b-${type}`,
{
show: isVisible.value && !hidden.value,
fade: !computedNoAnimation.value,
[`bs-${type}-${resolveBootstrapPlacement(placement.value)}`]: placement.value !== void 0
}
];
});
const { x, y } = useMouse();
const isElementAndTriggerOutside = () => {
const triggerRect = triggerElement.value?.getBoundingClientRect();
const elementRect = floatingElement.value?.getBoundingClientRect();
const margin = Number.parseInt(props.hideMargin, 10) || 0;
const offsetX = getSafeWindow()?.scrollX || 0;
const offsetY = getSafeWindow()?.scrollY || 0;
return {
triggerIsOutside: !triggerRect || x.value < triggerRect.left + offsetX - margin || x.value > triggerRect.right + offsetX + margin || y.value < triggerRect.top + offsetY - margin || y.value > triggerRect.bottom + offsetY + margin,
isOutside: !elementRect || x.value < elementRect.left + offsetX - margin || x.value > elementRect.right + offsetX + margin || y.value < elementRect.top + offsetY - margin || y.value > elementRect.bottom + offsetY + margin
};
};
let looptimeout;
const tryHide = (e) => {
const { triggerIsOutside, isOutside } = isElementAndTriggerOutside();
const doc = getSafeDocument();
if (!props.noninteractive && isOutside && triggerIsOutside && doc && !floatingElement.value?.contains(doc.activeElement) && (!computedTriggers.value.focus || !triggerElement.value?.contains(doc.activeElement)) || props.noninteractive && triggerIsOutside) hide$1(e?.type);
else {
if (looptimeout) clearTimeout(looptimeout);
looptimeout = setTimeout(() => {
tryHide(e);
}, 50);
}
};
watch(isVisible, () => {
update();
});
__expose({
hide: hide$1,
show,
toggle
});
const localToggle = (e) => {
if (showRef.value) hide$1(e.type === "click" ? "click" : "toggle");
else show();
};
const localShow = () => {
show();
};
const computedTriggers = computed(() => {
if (props.manual) return {
hover: false,
focus: false,
click: false
};
if (props.hover !== void 0 || props.focus !== void 0 || props.click !== void 0) return {
hover: props.hover ?? false,
focus: props.focus ?? false,
click: props.click ?? false
};
return {
hover: true,
focus: true,
click: false
};
});
const bind = () => {
if (props.target) {
const elem = getElement(toValue(props.target));
if (elem) triggerElement.value = elem;
else console.warn("Target element not found", props.target);
} else triggerElement.value = placeholder.value?.nextElementSibling;
if (props.reference) {
const elem = getElement(toValue(props.reference));
if (elem) referenceElement.value = elem;
else console.warn("Reference element not found", props.reference);
} else referenceElement.value = triggerElement.value;
if (!triggerElement.value || props.manual) return;
const triggers = computedTriggers.value;
if (triggers.click) triggerElement.value.addEventListener("click", localToggle);
if (triggers.hover) {
triggerElement.value.addEventListener("pointerenter", localShow);
triggerElement.value.addEventListener("pointerleave", tryHide);
}
if (triggers.focus) {
triggerElement.value.addEventListener("focus", localShow);
triggerElement.value.addEventListener("blur", tryHide);
}
};
const unbind = () => {
if (triggerElement.value) {
triggerElement.value.removeEventListener("click", localToggle);
triggerElement.value.removeEventListener("pointerenter", localShow);
triggerElement.value.removeEventListener("pointerleave", tryHide);
triggerElement.value.removeEventListener("focus", localShow);
triggerElement.value.removeEventListener("blur", tryHide);
}
};
onClickOutside(floatingElement, () => {
if (showRef.value && computedTriggers.value.click && !props.noAutoClose && !props.manual) hide$1("click-outside");
}, { ignore: [triggerElement] });
watch([
() => props.click,
() => props.hover,
() => props.focus,
() => props.manual,
() => props.target,
() => props.reference
], () => {
unbind();
bind();
});
const sharedSlots = computed(() => ({
toggle,
show,
hide: hide$1,
id: computedId.value,
visible: isVisible.value,
active: isActive.value
}));
onMounted(() => {
bind();
nextTick(() => {
update();
});
});
onBeforeUnmount(unbind);
return (_ctx, _cache) => {
return openBlock(), createElementBlock(Fragment, null, [
createElementVNode("span", {
id: unref(computedId) + "_placeholder",
ref: "_placeholder",
style: { "display": "none" }
}, null, 8, _hoisted_1),
renderSlot(_ctx.$slots, "target", normalizeProps(guardReactiveProps(sharedSlots.value))),
createVNode(ConditionalTeleport_default, {
to: unref(props).teleportTo,
disabled: !unref(props).teleportTo || unref(props).teleportDisabled
}, {
default: withCtx(() => [unref(renderRef) || unref(contentShowing) ? (openBlock(), createBlock(Transition, mergeProps({ key: 0 }, unref(transitionProps), { appear: modelValue.value || unref(props).visible }), {
default: withCtx(() => [withDirectives(createElementVNode("div", mergeProps({ id: unref(computedId) }, unref(attrs), {
ref: "_element",
class: computedClasses.value,
role: "tooltip",
tabindex: "-1",
style: unref(floatingStyles)
}), [createElementVNode("div", {
ref: "_arrow",
class: normalizeClass(`${unref(props).tooltip ? "tooltip" : "popover"}-arrow`),
style: normalizeStyle(arrowStyle.value),
"data-popper-arrow": ""
}, null, 6), createElementVNode("div", {
ref: "_content",
class: "overflow-auto b-floating-size",
style: normalizeStyle(sizeStyles.value)
}, [unref(props).title || slots.title ? (openBlock(), createElementBlock("div", {
key: 0,
class: normalizeClass(["position-sticky top-0", [unref(props).tooltip ? "tooltip-inner" : "popover-header", unref(props).titleClass]])
}, [renderSlot(_ctx.$slots, "title", normalizeProps(guardReactiveProps(sharedSlots.value)), () => [createTextVNode(toDisplayString(unref(props).title), 1)])], 2)) : createCommentVNode("", true), unref(props).tooltip && !slots.title && !unref(props).title || !unref(props).tooltip ? (openBlock(), createElementBlock("div", {
key: 1,
class: normalizeClass([unref(props).tooltip ? "tooltip-inner" : "popover-body", unref(props).bodyClass])
}, [renderSlot(_ctx.$slots, "default", normalizeProps(guardReactiveProps(sharedSlots.value)), () => [createTextVNode(toDisplayString(unref(props).body) + toDisplayString(unref(attrs).content), 1)])], 2)) : createCommentVNode("", true)], 4)], 16, _hoisted_2), [[vShow, unref(showRef) && !hidden.value]])]),
_: 3
}, 16, ["appear"])) : createCommentVNode("", true)]),
_: 3
}, 8, ["to", "disabled"])
], 64);
};
}
});
//#endregion
//#region src/utils/floatingUi.ts
var resolveBootstrapPlacement = (placement) => {
const [_placement] = placement.split("-");
switch (_placement) {
case "left": return "start";
case "right": return "end";
default: return _placement || "start";
}
};
var resolveBootstrapCaret = (placement) => {
const [_placement] = placement.split("-");
switch (_placement) {
case "left": return "start";
case "right": return "end";
case "top": return "up";
case "bottom": return "down";
default: return _placement || "start";
}
};
var resolveActiveStatus = (values) => typeof values !== "object" || values.active !== false;
var resolveContent = (values, el) => {
if (!resolveActiveStatus(values)) return {};
const missingBindingValue = typeof values === "undefined" || typeof values === "object" && !values.title && !values.content && !values.body;
if (getSafeDocument() !== null) {
const titleAttr = el.getAttribute("title") || el.getAttribute("data-original-title");
if (titleAttr) {
el.removeAttribute("title");
el.setAttribute("data-original-title", titleAttr);
}
if (missingBindingValue) {
if (titleAttr) return { body: titleAttr };
return {};
}
if (typeof values === "string") return {
title: titleAttr || void 0,
body: values
};
} else if (missingBindingValue) return {};
if (typeof values === "string") return { body: values };
if (values?.content) console.warn("v-b-popover/v-b-tooltip: `content` is deprecated, use `body` instead");
return {
title: values?.title ? values?.title : void 0,
body: values?.body ? values?.body : values?.content ? values?.content : void 0
};
};
var resolveDirectiveProps = (binding, el) => ({
target: el,
modelValue: binding.modifiers.show,
inline: binding.modifiers.inline,
click: binding.modifiers.click,
hover: binding.modifiers.hover,
focus: binding.modifiers.focus,
manual: binding.modifiers.manual,
realtime: binding.modifiers.realtime,
lazy: binding.modifiers.lazy,
placement: binding.modifiers.left ? "left" : binding.modifiers.right ? "right" : binding.modifiers.bottom ? "bottom" : binding.modifiers.top ? "top" : void 0,
...typeof binding.value === "object" ? binding.value : void 0,
...binding.modifiers.interactive ? { noninteractive: false } : void 0,
title: null,
body: null
});
var bind = (el, binding, props) => {
const doc = getSafeDocument();
if (doc === null) return;
const div = doc.createElement("span");
if (binding.modifiers.body) doc.body.appendChild(div);
else if (binding.modifiers.child) el.appendChild(div);
else el.parentNode?.insertBefore(div, el.nextSibling);
render(h(BPopover_default, props), div);
el.$__element = div;
};
var unbind = (el) => {
const div = el.$__element;
if (!div) return;
render(null, div);
if (getSafeDocument() !== null) {
delete el.$__element;
return;
}
queueMicrotask(() => {
div.remove();
if (el.$__element === div) delete el.$__element;
});
};
var isBoundary = (input) => input === "clippingAncestors" || input instanceof Element || Array.isArray(input);
var isRootBoundary = (input) => !isBoundary(input);
//#endregion
export { resolveBootstrapCaret as a, unbind as c, resolveActiveStatus as i, BPopover_default as l, isBoundary as n, resolveContent as o, isRootBoundary as r, resolveDirectiveProps as s, bind as t };
//# sourceMappingURL=floatingUi-DHMrP__c.mjs.map