UNPKG

bootstrap-vue-next

Version:

Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development

705 lines (704 loc) 24.1 kB
import { S as useToNumber, r as createSharedComposable } from "./dist-DKc2ivHS.js"; import { _ as useMouse$1, i as onClickOutside } from "./dist-9-XTMhb-.js"; import { n as warn } from "./console-DaUCJgpk.js"; import { a as getSafeWindow, i as getSafeDocument } from "./dom-BdUQrX99.js"; import { t as useDefaults } from "./useDefaults-BzP4qZBu.js"; import { t as useId$1 } from "./useId-Fh-Arhb7.js"; import { t as useShowHide } from "./useShowHide-C95Y9EKL.js"; import { t as ConditionalTeleport_default } from "./ConditionalTeleport-BCKPLEun.js"; import { a as flip, d as size, f as getNodeName, i as computePosition, l as offset, n as autoPlacement, o as hide, p as isNode, r as autoUpdate, s as inline, t as arrow$1, u as shift } from "./floating-ui.dom-C7UZexJK.js"; import { t as getElement } from "./getElement-uvhh1lgL.js"; import { Fragment, Transition, computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, getCurrentScope, guardReactiveProps, h, mergeModels, mergeProps, nextTick, normalizeClass, normalizeProps, normalizeStyle, onBeforeUnmount, onMounted, onScopeDispose, openBlock, ref, render, renderSlot, shallowReadonly, shallowRef, toDisplayString, toValue, unref, useAttrs, useModel, useSlots, useTemplateRef, vShow, watch, withCtx, withDirectives } from "vue"; //#region ../../node_modules/.pnpm/@floating-ui+vue@2.0.1_vue@3.5.41_typescript@5.9.3_/node_modules/@floating-ui/vue/dist/floating-ui.vue.mjs function isComponentPublicInstance(target) { return target != null && typeof target === "object" && "$el" in target; } function unwrapElement(target) { if (isComponentPublicInstance(target)) { const element = target.$el; return isNode(element) && getNodeName(element) === "#comment" ? null : element; } return target; } /** * Positions an inner element of the floating element such that it is centered to the reference element. * @param options The arrow options. * @see https://floating-ui.com/docs/arrow */ function arrow(options) { return { name: "arrow", options, fn(args) { const element = unwrapElement(toValue(options.element)); if (element == null) return {}; return arrow$1({ element, padding: options.padding }).fn(args); } }; } function getDPR(element) { if (typeof window === "undefined") return 1; return (element.ownerDocument.defaultView || window).devicePixelRatio || 1; } function roundByDPR(element, value) { const dpr = getDPR(element); return Math.round(value * dpr) / dpr; } /** * Computes the `x` and `y` coordinates that will place the floating element next to a reference element when it is given a certain CSS positioning strategy. * @param reference The reference template ref. * @param floating The floating template ref. * @param options The floating options. * @see https://floating-ui.com/docs/vue */ function useFloating(reference, floating, options) { if (options === void 0) options = {}; const whileElementsMountedOption = options.whileElementsMounted; const openOption = computed(() => { var _toValue; return (_toValue = toValue(options.open)) != null ? _toValue : true; }); const middlewareOption = computed(() => toValue(options.middleware)); const placementOption = computed(() => { var _toValue2; return (_toValue2 = toValue(options.placement)) != null ? _toValue2 : "bottom"; }); const strategyOption = computed(() => { var _toValue3; return (_toValue3 = toValue(options.strategy)) != null ? _toValue3 : "absolute"; }); const transformOption = computed(() => { var _toValue4; return (_toValue4 = toValue(options.transform)) != null ? _toValue4 : true; }); const referenceElement = computed(() => unwrapElement(reference.value)); const floatingElement = computed(() => unwrapElement(floating.value)); const x = ref(0); const y = ref(0); const strategy = ref(strategyOption.value); const placement = ref(placementOption.value); const middlewareData = shallowRef({}); const isPositioned = ref(false); const floatingStyles = computed(() => { const initialStyles = { position: strategy.value, left: "0", top: "0" }; if (!floatingElement.value) return initialStyles; const xVal = roundByDPR(floatingElement.value, x.value); const yVal = roundByDPR(floatingElement.value, y.value); if (transformOption.value) return { ...initialStyles, transform: "translate(" + xVal + "px, " + yVal + "px)", ...getDPR(floatingElement.value) >= 1.5 && { willChange: "transform" } }; return { position: strategy.value, left: xVal + "px", top: yVal + "px" }; }); let whileElementsMountedCleanup; function update() { if (referenceElement.value == null || floatingElement.value == null) return; const open = openOption.value; computePosition(referenceElement.value, floatingElement.value, { middleware: middlewareOption.value, placement: placementOption.value, strategy: strategyOption.value }).then((position) => { x.value = position.x; y.value = position.y; strategy.value = position.strategy; placement.value = position.placement; middlewareData.value = position.middlewareData; /** * The floating element's position may be recomputed while it's closed * but still mounted (such as when transitioning out). To ensure * `isPositioned` will be `false` initially on the next open, avoid * setting it to `true` when `open === false` (must be specified). */ isPositioned.value = open !== false; }); } function cleanup() { if (typeof whileElementsMountedCleanup === "function") { whileElementsMountedCleanup(); whileElementsMountedCleanup = void 0; } } function attach() { cleanup(); if (whileElementsMountedOption === void 0) { update(); return; } if (referenceElement.value != null && floatingElement.value != null) { whileElementsMountedCleanup = whileElementsMountedOption(referenceElement.value, floatingElement.value, update); return; } } function reset() { if (!openOption.value) isPositioned.value = false; } watch([ middlewareOption, placementOption, strategyOption, openOption ], update, { flush: "sync" }); watch([referenceElement, floatingElement], attach, { flush: "sync" }); watch(openOption, reset, { flush: "sync" }); if (getCurrentScope()) onScopeDispose(cleanup); return { x: shallowReadonly(x), y: shallowReadonly(y), strategy: shallowReadonly(strategy), placement: shallowReadonly(placement), middlewareData: shallowReadonly(middlewareData), isPositioned: shallowReadonly(isPositioned), floatingStyles, update }; } //#endregion //#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$2 = 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 off = props.offset !== null ? offsetNumber.value : props.tooltip ? 6 : 8; const arr = [offset(off)]; if (!props.noFlip && !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) arr.push(shift({ boundary: boundary.value, rootBoundary: rootBoundary.value, padding: props.boundaryPadding })); if (!props.noHide) arr.push(hide({ boundary: boundary.value, rootBoundary: rootBoundary.value, padding: props.boundaryPadding })); if (props.inline) arr.push(inline()); arr.push(arrow({ element: arrow$2, padding: 10 })); if (!props.noSize) 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: () => 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, element: floatingElement, id: 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) { 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 warn("BPopover", "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 warn("BPopover", "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) 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 updateBind = (el, binding, props) => { const div = el.$__element; if (!div) { bind(el, binding, props); return; } render(h(BPopover_default, props), 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, useFloating as d, resolveActiveStatus as i, updateBind as l, isBoundary as n, resolveContent as o, isRootBoundary as r, resolveDirectiveProps as s, bind as t, BPopover_default as u }; //# sourceMappingURL=floatingUi-BlKoACvc.js.map