bootstrap-vue-next
Version:
Seamless integration of Vue 3, Bootstrap 5, and TypeScript for modern, type-safe UI development
404 lines (403 loc) • 14.7 kB
JavaScript
require("./chunk-CoQrYLCe.js");
const require_keys = require("./keys-durSVUrO.js");
const require_dist = require("./dist-BJ15ThEs.js");
const require_dom = require("./dom-Bs6DzM72.js");
const require_useDefaults = require("./useDefaults-DsLf4iRY.js");
const require_useId = require("./useId-DHrBgM7P.js");
const require_useShowHide = require("./useShowHide-BTCaeU5j.js");
const require_BButton = require("./BButton-DBRs8Pz_.js");
const require_ConditionalTeleport = require("./ConditionalTeleport-BJZk6HAx.js");
const require_floating_ui_vue = require("./floating-ui.vue-GXIS2sFG.js");
const require_ConditionalWrapper = require("./ConditionalWrapper-Cc7EIszd.js");
const require_floatingUi = require("./floatingUi-Cs4rDXmO.js");
const require_getElement = require("./getElement-CxWWOx3K.js");
let vue = require("vue");
//#region src/components/BDropdown/BDropdown.vue?vue&type=script&setup=true&lang.ts
var _hoisted_1 = { class: "visually-hidden" };
var _hoisted_2 = [
"id",
"aria-labelledby",
"role"
];
//#endregion
//#region src/components/BDropdown/BDropdown.vue
var BDropdown_default = /* @__PURE__ */ (0, vue.defineComponent)({
__name: "BDropdown",
props: /* @__PURE__ */ (0, vue.mergeModels)({
ariaLabel: { default: void 0 },
autoClose: {
type: [Boolean, String],
default: true
},
boundary: { default: "clippingAncestors" },
boundaryPadding: { default: void 0 },
disabled: {
type: Boolean,
default: false
},
floatingMiddleware: { default: void 0 },
icon: {
type: Boolean,
default: false
},
id: { default: void 0 },
isNav: {
type: Boolean,
default: false
},
menuClass: { default: void 0 },
noCaret: {
type: Boolean,
default: false
},
noFlip: {
type: Boolean,
default: false
},
noShift: {
type: Boolean,
default: false
},
noSize: {
type: Boolean,
default: false
},
offset: { default: 0 },
role: { default: "menu" },
size: { default: "md" },
noWrapper: {
type: Boolean,
default: false
},
split: {
type: Boolean,
default: false
},
splitButtonType: { default: "button" },
splitClass: { default: void 0 },
splitDisabled: {
type: Boolean,
default: void 0
},
splitHref: { default: void 0 },
splitTo: { default: void 0 },
splitVariant: { default: void 0 },
strategy: { default: "absolute" },
text: { default: void 0 },
toggleClass: { default: void 0 },
toggleText: { default: "Toggle dropdown" },
variant: { default: "secondary" },
wrapperClass: { default: void 0 },
placement: { default: "bottom-start" },
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: { default: void 0 },
visible: {
type: Boolean,
default: false
}
}, {
"modelValue": {
type: Boolean,
default: false
},
"modelModifiers": {}
}),
emits: /* @__PURE__ */ (0, vue.mergeModels)([
"split-click",
"hide",
"hide-prevented",
"hidden",
"show",
"show-prevented",
"shown",
"toggle",
"toggle-prevented"
], ["update:modelValue"]),
setup(__props, { expose: __expose, emit: __emit }) {
const props = require_useDefaults.useDefaults(__props, "BDropdown");
const emit = __emit;
const computedId = require_useId.useId(() => props.id, "dropdown");
const modelValue = (0, vue.useModel)(__props, "modelValue");
const inInputGroup = (0, vue.inject)(require_keys.inputGroupKey, false);
const inButtonGroup = (0, vue.inject)(require_keys.buttonGroupKey, false);
const offsetToNumber = require_dist.useToNumber((0, vue.computed)(() => typeof props.offset === "string" || typeof props.offset === "number" ? props.offset : NaN));
const floatingElement = (0, vue.useTemplateRef)("_floating");
const button = (0, vue.useTemplateRef)("_button");
const splitButton = (0, vue.useTemplateRef)("_splitButton");
const boundary = (0, vue.computed)(() => require_floatingUi.isBoundary(props.boundary) ? props.boundary : void 0);
const rootBoundary = (0, vue.computed)(() => require_floatingUi.isRootBoundary(props.boundary) ? props.boundary : void 0);
const referenceElement = (0, vue.computed)(() => !props.split ? splitButton.value : button.value);
let cleanup;
const { showRef, renderRef, hide, show, toggle, computedNoAnimation, transitionProps, contentShowing, isVisible, isActive } = require_useShowHide.useShowHide(modelValue, props, emit, referenceElement, computedId, {
showFn: () => {
update();
(0, vue.nextTick)(() => {
cleanup = require_floating_ui_vue.autoUpdate(referenceElement.value, floatingElement.value, update, { animationFrame: false });
});
},
hideFn: () => {
if (cleanup) {
cleanup();
cleanup = void 0;
}
}
});
const computedMenuClasses = (0, vue.computed)(() => [{
show: isVisible.value,
fade: !computedNoAnimation.value
}]);
require_dist.onKeyStroke("Escape", () => {
hide();
require_getElement.getElement(referenceElement.value)?.focus();
}, { target: referenceElement });
require_dist.onKeyStroke("Escape", () => {
hide();
require_getElement.getElement(referenceElement.value)?.focus();
}, {
target: floatingElement,
passive: true
});
const keynav = (e, v) => {
if (floatingElement.value?.contains(e.target?.closest("form"))) return;
if (/input|select|option|textarea|form/i.test(e.target?.tagName)) return;
e.preventDefault();
if (!showRef.value) {
show();
const loop = setInterval(() => {
if (isVisible.value) {
clearInterval(loop);
(0, vue.nextTick)(() => keynav(e, v));
}
}, 16);
return;
}
const list = floatingElement.value?.querySelectorAll(".dropdown-item:not(.disabled):not(:disabled)");
const doc = require_dom.getSafeDocument();
if (!list || !doc) return;
if (floatingElement.value?.contains(doc.activeElement)) {
const active = floatingElement.value.querySelector(".dropdown-item:focus");
const index = Array.prototype.indexOf.call(list, active) + v;
if (index >= 0 && index < list?.length) list[index]?.focus();
} else list[v === -1 ? list.length - 1 : 0]?.focus();
};
require_dist.onKeyStroke("ArrowUp", (e) => keynav(e, -1), { target: referenceElement });
require_dist.onKeyStroke("ArrowDown", (e) => keynav(e, 1), { target: referenceElement });
require_dist.onKeyStroke("ArrowUp", (e) => keynav(e, -1), { target: floatingElement });
require_dist.onKeyStroke("ArrowDown", (e) => keynav(e, 1), { target: floatingElement });
const sizeStyles = (0, vue.ref)({});
const { update, floatingStyles } = require_floating_ui_vue.useFloating(referenceElement, floatingElement, {
placement: () => props.placement,
middleware: (0, vue.computed)(() => {
if (props.floatingMiddleware !== void 0) return props.floatingMiddleware;
const arr = [require_floating_ui_vue.offset(typeof props.offset === "string" || typeof props.offset === "number" ? offsetToNumber.value : props.offset)];
if (props.noFlip === false) arr.push(require_floating_ui_vue.flip({
boundary: boundary.value,
rootBoundary: rootBoundary.value,
padding: props.boundaryPadding
}));
if (props.noShift === false) arr.push(require_floating_ui_vue.shift({
boundary: boundary.value,
rootBoundary: rootBoundary.value,
padding: props.boundaryPadding
}));
if (props.noSize === false) arr.push(require_floating_ui_vue.size({
boundary: boundary.value,
rootBoundary: rootBoundary.value,
padding: props.boundaryPadding,
apply({ availableWidth, availableHeight }) {
sizeStyles.value = {
"--bv-floating-max-height": availableHeight >= (floatingElement.value?.scrollHeight ?? 0) ? void 0 : availableHeight ? `${Math.max(0, availableHeight)}px` : void 0,
"--bv-floating-max-width": availableWidth >= (floatingElement.value?.scrollWidth ?? 0) ? void 0 : availableWidth ? `${Math.max(0, availableWidth)}px` : void 0
};
}
}));
return arr;
}),
strategy: (0, vue.toRef)(() => props.strategy)
});
const inButtonGroupAttributes = inButtonGroup ? {
class: "btn-group",
role: "group"
} : void 0;
const computedClasses = (0, vue.computed)(() => [
inButtonGroupAttributes?.class,
props.wrapperClass,
{
"btn-group": !props.wrapperClass && props.split,
[`drop${require_floatingUi.resolveBootstrapCaret(props.placement)}`]: !props.wrapperClass,
"position-static": props.boundary !== "clippingAncestors" && !props.isNav
}
]);
const buttonClasses = (0, vue.computed)(() => [props.split ? props.splitClass : props.toggleClass, {
"nav-link": props.isNav,
"dropdown-toggle": !props.split,
"dropdown-toggle-no-caret": props.noCaret && !props.split,
"show": props.split ? void 0 : showRef.value
}]);
const onButtonClick = () => {
toggle();
};
const onSplitClick = (event) => {
if (props.split) {
emit("split-click", event);
return;
}
onButtonClick();
};
require_dist.onClickOutside(floatingElement, () => {
if (showRef.value && (props.autoClose === true || props.autoClose === "outside")) hide();
}, { ignore: [button, splitButton] });
const onClickInside = () => {
if (showRef.value && (props.autoClose === true || props.autoClose === "inside")) hide();
};
(0, vue.watch)(isVisible, () => {
update();
});
__expose({
hide,
show,
toggle
});
(0, vue.provide)(require_keys.dropdownInjectionKey, {
id: computedId,
show,
hide,
toggle,
visible: (0, vue.readonly)(showRef),
isNav: (0, vue.toRef)(() => props.isNav)
});
return (_ctx, _cache) => {
return (0, vue.openBlock)(), (0, vue.createBlock)(require_ConditionalWrapper.ConditionalWrapper_default, {
skip: (0, vue.unref)(inInputGroup) || (0, vue.unref)(props).noWrapper,
class: (0, vue.normalizeClass)(computedClasses.value),
role: (0, vue.unref)(inButtonGroupAttributes)?.role
}, {
default: (0, vue.withCtx)(() => [
(0, vue.createVNode)(require_BButton.BButton_default, {
id: (0, vue.unref)(computedId),
ref: "_splitButton",
variant: (0, vue.unref)(props).splitVariant || (0, vue.unref)(props).variant,
size: (0, vue.unref)(props).size,
class: (0, vue.normalizeClass)(buttonClasses.value),
disabled: (0, vue.unref)(props).splitDisabled || (0, vue.unref)(props).disabled,
type: (0, vue.unref)(props).splitButtonType,
"aria-label": (0, vue.unref)(props).ariaLabel,
"aria-expanded": (0, vue.unref)(props).split ? void 0 : (0, vue.unref)(showRef),
"aria-haspopup": (0, vue.unref)(props).split ? void 0 : "menu",
href: (0, vue.unref)(props).split ? (0, vue.unref)(props).splitHref : void 0,
icon: (0, vue.unref)(props).icon,
to: (0, vue.unref)(props).split && (0, vue.unref)(props).splitTo ? (0, vue.unref)(props).splitTo : void 0,
onClick: onSplitClick
}, {
default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "button-content", {}, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(props).text), 1)])]),
_: 3
}, 8, [
"id",
"variant",
"size",
"class",
"disabled",
"type",
"aria-label",
"aria-expanded",
"aria-haspopup",
"href",
"icon",
"to"
]),
(0, vue.unref)(props).split ? ((0, vue.openBlock)(), (0, vue.createBlock)(require_BButton.BButton_default, {
key: 0,
id: (0, vue.unref)(computedId) + "-split",
ref: "_button",
variant: (0, vue.unref)(props).variant,
size: (0, vue.unref)(props).size,
disabled: (0, vue.unref)(props).disabled,
class: (0, vue.normalizeClass)([[(0, vue.unref)(props).toggleClass, { show: (0, vue.unref)(showRef) }], "dropdown-toggle-split dropdown-toggle"]),
"aria-expanded": (0, vue.unref)(showRef),
"aria-haspopup": "menu",
onClick: onButtonClick
}, {
default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("span", _hoisted_1, [(0, vue.renderSlot)(_ctx.$slots, "toggle-text", {}, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)((0, vue.unref)(props).toggleText), 1)])])]),
_: 3
}, 8, [
"id",
"variant",
"size",
"disabled",
"class",
"aria-expanded"
])) : (0, vue.createCommentVNode)("", true),
(0, vue.createVNode)(require_ConditionalTeleport.ConditionalTeleport_default, {
to: (0, vue.unref)(props).teleportTo,
disabled: !(0, vue.unref)(props).teleportTo || (0, vue.unref)(props).teleportDisabled
}, {
default: (0, vue.withCtx)(() => [(0, vue.unref)(renderRef) || (0, vue.unref)(contentShowing) ? ((0, vue.openBlock)(), (0, vue.createBlock)(vue.Transition, (0, vue.mergeProps)({ key: 0 }, (0, vue.unref)(transitionProps), { appear: modelValue.value || (0, vue.unref)(props).visible }), {
default: (0, vue.withCtx)(() => [(0, vue.withDirectives)((0, vue.createElementVNode)("ul", {
id: (0, vue.unref)(computedId) + "-menu",
ref: "_floating",
style: (0, vue.normalizeStyle)([
(0, vue.unref)(floatingStyles),
sizeStyles.value,
{ display: (0, vue.unref)(showRef) || (0, vue.unref)(isActive) ? "block" : "none" }
]),
class: (0, vue.normalizeClass)(["dropdown-menu overflow-auto b-floating-size", [(0, vue.unref)(props).menuClass, computedMenuClasses.value]]),
"aria-labelledby": (0, vue.unref)(computedId),
role: (0, vue.unref)(props).role,
onClick: onClickInside
}, [(0, vue.unref)(contentShowing) ? (0, vue.renderSlot)(_ctx.$slots, "default", {
key: 0,
id: (0, vue.unref)(computedId),
hide: (0, vue.unref)(hide),
show: (0, vue.unref)(show),
visible: (0, vue.unref)(showRef),
click: onClickInside,
toggle: onButtonClick,
active: (0, vue.unref)(showRef)
}) : (0, vue.createCommentVNode)("", true)], 14, _hoisted_2), [[vue.vShow, (0, vue.unref)(showRef)]])]),
_: 3
}, 16, ["appear"])) : (0, vue.createCommentVNode)("", true)]),
_: 3
}, 8, ["to", "disabled"])
]),
_: 3
}, 8, [
"skip",
"class",
"role"
]);
};
}
});
//#endregion
Object.defineProperty(exports, "BDropdown_default", {
enumerable: true,
get: function() {
return BDropdown_default;
}
});
//# sourceMappingURL=BDropdown-C1AxRj81.js.map