UNPKG

bootstrap-vue-next

Version:

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

579 lines (578 loc) 22.7 kB
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_flattenFragments = require("./flattenFragments-C1WWqm25.js"); const require_classes = require("./classes-D5wrmmVs.js"); const require_useAlignment = require("./useAlignment-D5xKBRez.js"); let vue = require("vue"); //#endregion //#region src/components/BTabs/BTab.vue var BTab_default = /* @__PURE__ */ (0, vue.defineComponent)({ inheritAttrs: false, __name: "BTab", props: /* @__PURE__ */ (0, vue.mergeModels)({ buttonId: { default: void 0 }, disabled: { type: Boolean, default: false }, id: { default: void 0 }, lazy: { type: Boolean, default: void 0 }, unmountLazy: { type: Boolean, default: void 0 }, noBody: { type: Boolean, default: false }, tag: { default: "div" }, title: { default: void 0 }, titleItemClass: { default: void 0 }, titleLinkAttrs: { default: void 0 }, titleLinkClass: { default: void 0 } }, { "active": { type: Boolean, default: false }, "activeModifiers": {} }), emits: ["update:active"], setup(__props, { expose: __expose }) { const props = require_useDefaults.useDefaults(__props, "BTab"); const slots = (0, vue.useSlots)(); const attrs = (0, vue.useAttrs)(); const activeModel = (0, vue.useModel)(__props, "active"); const parentData = (0, vue.inject)(require_keys.tabsInjectionKey, null); const localId = (0, vue.ref)(props.id); const internalId = require_useId.useId("", "tabpane"); const computedId = (0, vue.computed)(() => props.id ?? localId.value ?? internalId.value); const computedButtonId = require_useId.useId(() => props.buttonId, "tab"); const lazyRenderCompleted = (0, vue.ref)(false); const el = (0, vue.useTemplateRef)("_el"); const processedAttrs = (0, vue.computed)(() => { const { onClick: _, ...tabAttrs } = attrs; return tabAttrs; }); function updateTab() { if (!parentData) return; const newId = parentData.registerTab((0, vue.computed)(() => ({ internalId: internalId.value, id: computedId.value, active: activeModel.value, buttonId: computedButtonId.value, disabled: props.disabled, title: props.title, titleComponent: slots.title, titleItemClass: props.titleItemClass, titleLinkAttrs: props.titleLinkAttrs, titleLinkClass: props.titleLinkClass, onClick: attrs.onClick, el }))); if (newId !== localId.value) localId.value = newId; } if (parentData) { updateTab(); if (activeModel.value) parentData.activateTab(internalId.value); } (0, vue.onUnmounted)(() => { if (!parentData) return; parentData.unregisterTab(internalId.value); }); const isActive = (0, vue.computed)(() => parentData?.activeId.value === computedId.value); const show = (0, vue.ref)(isActive.value); const computedLazy = (0, vue.computed)(() => !!(parentData?.lazy.value || props.lazy)); const computedActive = (0, vue.computed)(() => isActive.value && !props.disabled); const showSlot = (0, vue.computed)(() => computedActive.value || !computedLazy.value || computedLazy.value && !props.unmountLazy && lazyRenderCompleted.value); (0, vue.watch)(showSlot, (shown) => { if (shown && !lazyRenderCompleted.value) lazyRenderCompleted.value = true; }); (0, vue.watch)(isActive, (active) => { if (active) { activeModel.value = true; setTimeout(() => { show.value = true; }, 0); return; } show.value = false; activeModel.value = false; }); (0, vue.watch)(activeModel, (active) => { if (props.disabled) { activeModel.value = false; return; } if (!parentData) return; if (!active) { if (isActive.value) parentData.activateTab(void 0); return; } if (!isActive.value) parentData.activateTab(internalId.value); }); const computedClasses = (0, vue.computed)(() => [ { "active": isActive.value, "show": show.value, "card-body": parentData?.card.value && props.noBody === false, "fade": !parentData?.noFade.value }, show.value ? parentData?.activeTabClass.value : parentData?.inactiveTabClass.value, parentData?.tabClass.value ]); __expose({ activate: () => { activeModel.value = true; }, deactivate: () => { activeModel.value = false; } }); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(props).tag), (0, vue.mergeProps)({ id: computedId.value, ref: "_el", class: ["tab-pane", computedClasses.value], role: "tabpanel", "aria-labelledby": (0, vue.unref)(computedButtonId) }, processedAttrs.value), { default: (0, vue.withCtx)(() => [showSlot.value ? (0, vue.renderSlot)(_ctx.$slots, "default", { key: 0 }) : (0, vue.createCommentVNode)("", true)]), _: 3 }, 16, [ "id", "class", "aria-labelledby" ]); }; } }); //#endregion //#region src/components/BTabs/BTabs.vue?vue&type=script&setup=true&lang.ts var _hoisted_1 = ["aria-orientation"]; var _hoisted_2 = [ "id", "aria-controls", "aria-selected", "disabled", "tabindex", "onClick" ]; //#endregion //#region src/components/BTabs/BTabs.vue var BTabs_default = /* @__PURE__ */ (0, vue.defineComponent)({ __name: "BTabs", props: /* @__PURE__ */ (0, vue.mergeModels)({ activeNavItemClass: { default: void 0 }, activeTabClass: { default: void 0 }, align: { default: void 0 }, card: { type: Boolean, default: false }, contentClass: { default: void 0 }, end: { type: Boolean, default: false }, fill: { type: Boolean, default: false }, id: { default: void 0 }, index: {}, inactiveNavItemClass: { default: void 0 }, inactiveTabClass: { default: void 0 }, justified: { type: Boolean, default: false }, lazy: { type: Boolean, default: false }, navClass: { default: void 0 }, navItemClass: { default: void 0 }, navWrapperClass: { default: void 0 }, noFade: { type: Boolean, default: false }, noKeyNav: { type: Boolean, default: false }, noNavStyle: { type: Boolean, default: false }, pills: { type: Boolean, default: false }, small: { type: Boolean, default: false }, tag: { default: "div" }, tabClass: { default: void 0 }, underline: { type: Boolean, default: false }, vertical: { type: Boolean, default: false } }, { "index": { default: -1 }, "indexModifiers": {}, "modelValue": { default: void 0 }, "modelModifiers": {} }), emits: /* @__PURE__ */ (0, vue.mergeModels)(["activate-tab"], ["update:index", "update:modelValue"]), setup(__props, { emit: __emit }) { const props = require_useDefaults.useDefaults(__props, "BTabs"); const emit = __emit; const slots = (0, vue.useSlots)(); const activeIndex = (0, vue.useModel)(__props, "index"); const activeId = (0, vue.useModel)(__props, "modelValue"); const ReusableEmptyTab = require_dist.createReusableTemplate(); const tabsInternal = (0, vue.ref)([]); const tabElementsArray = (0, vue.ref)([]); const isChildActive = (0, vue.ref)(false); const initialIds = (0, vue.ref)([]); const hasExplicitIds = (0, vue.ref)(false); const updateTabElementsArray = () => { const tabElements = require_flattenFragments.flattenFragments(slots.default?.({}) ?? []); tabElementsArray.value = (Array.isArray(tabElements) ? tabElements : [tabElements]).filter((tab) => tab.type === BTab_default); if (initialIds.value.length === 0) { initialIds.value = tabElementsArray.value.map((tab) => (0, vue.unref)(require_useId.useId(() => tab.props?.id, "tabpane"))); hasExplicitIds.value = tabElementsArray.value.some((tab) => tab.props?.id !== void 0); } isChildActive.value = tabElementsArray.value.some((tab) => tab.props?.active !== void 0 && tab.props?.active !== false); }; updateTabElementsArray(); (0, vue.watch)(() => slots.default?.({}), () => { updateTabElementsArray(); (0, vue.nextTick)(() => { sortTabs(); }); }); const tabs = (0, vue.computed)(() => { if (tabsInternal.value.length === 0) { const _activeIndex = tabElementsArray.value.findIndex((tab) => tab.props?.active !== void 0 && (tab.props.disabled === false || tab.props.disabled === void 0) || activeId.value && tab.props?.id === activeId.value); return tabElementsArray.value.map((tab, index) => { const active = _activeIndex !== -1 ? index === _activeIndex : activeIndex.value > -1 ? index === activeIndex.value : index === 0; return { id: tab.props?.id ?? initialIds.value[index], internalId: `premount-${index}`, buttonId: tab.props?.buttonId, disabled: tab.props?.disabled, title: tab.props?.title, titleComponent: tab.children?.title, titleItemClass: tab.props?.titleItemClass, titleLinkAttrs: tab.props?.titleLinkAttrs, titleLinkClass: tab.props?.titleLinkClass, onClick: tab.props?.onClick, active, navItemClasses: [ { active, disabled: !(tab.props?.disabled === false || tab.props?.disabled === void 0) }, active ? props.activeNavItemClass : props.inactiveNavItemClass, props.navItemClass ] }; }); } return tabsInternal.value.map((_tab) => { const tab = (0, vue.unref)(_tab); const active = tab.id === activeId.value; return { ...tab, active, navItemClasses: [ { active, disabled: tab.disabled }, active ? props.activeNavItemClass : props.inactiveNavItemClass, props.navItemClass ] }; }); }); let initialized = false; let updateInitialActiveIndex = false; let updateInitialActiveId = false; let delayedTabSelection = false; if (activeIndex.value > -1 && !activeId.value && !hasExplicitIds.value && tabElementsArray.value.length > 0) { delayedTabSelection = true; updateInitialActiveId = true; } else if (activeIndex.value === -1 && activeId.value) if (tabs.value.findIndex((t) => t.id === activeId.value) !== -1) activeIndex.value = tabs.value.findIndex((t) => t.id === activeId.value); else updateInitialActiveIndex = true; else if (activeIndex.value > -1 && !activeId.value) if (tabs.value[activeIndex.value]?.id) activeId.value = tabs.value[activeIndex.value]?.id; else updateInitialActiveId = true; else if (activeIndex.value === -1 && !activeId.value && !isChildActive.value) { activeIndex.value = tabs.value.findIndex((t) => t.disabled === void 0 || t.disabled === false); activeId.value = tabs.value[activeIndex.value]?.id; } else if (activeIndex.value === -1 && !activeId.value && isChildActive.value) { activeIndex.value = tabs.value.findIndex((t) => t.active !== void 0 && t.active !== false && (t.disabled === void 0 || t.disabled === false)); activeId.value = tabs.value[activeIndex.value]?.id; } function updateInitialIndexAndId() { if (updateInitialActiveIndex) { const index = tabs.value.findIndex((t) => t.id === activeId.value); if (index !== -1) (0, vue.nextTick)(() => { activeIndex.value = index; updateInitialActiveIndex = false; }); } if (updateInitialActiveId) { if (delayedTabSelection && tabsInternal.value.length === 0) return; if (activeIndex.value > -1 && tabs.value[activeIndex.value]?.id) (0, vue.nextTick)(() => { activeId.value = tabs.value[activeIndex.value]?.id; updateInitialActiveId = false; delayedTabSelection = false; }); } } updateInitialIndexAndId(); const showEmpty = (0, vue.computed)(() => !(tabs?.value && tabs.value.length > 0)); const computedClasses = (0, vue.computed)(() => ({ "d-flex": props.vertical, "align-items-start": props.vertical })); const alignment = require_useAlignment.useAlignment(() => props.align); const navTabsClasses = (0, vue.computed)(() => ({ "nav-pills": props.pills, "nav-underline": props.underline, "flex-column me-3": props.vertical, [alignment.value]: props.align !== void 0, "nav-fill": props.fill, "card-header-tabs": props.card && !props.pills && !props.underline, "card-header-pills": props.card && props.pills, "nav-justified": props.justified, "nav-tabs": !props.noNavStyle && !props.pills && !props.underline, "small": props.small })); const handleClick = (event, index) => { if (index >= 0 && !tabs.value[index]?.disabled && tabs.value[index]?.onClick && typeof tabs.value[index].onClick === "function") { tabs.value[index].onClick?.(event); if (event.defaultPrevented) { require_dom.getSafeDocument()?.getElementById(tabs.value[index].buttonId)?.blur(); return; } } activeIndex.value = index; }; const keynav = (e, direction) => { if (tabs.value.length <= 0 || props.noKeyNav) return; e.preventDefault(); e.stopPropagation(); activeIndex.value = nextIndex(activeIndex.value + direction, direction); (0, vue.nextTick)(() => { if (activeIndex.value >= 0) require_dom.getSafeDocument()?.getElementById(tabs.value[activeIndex.value]?.buttonId)?.focus(); }); }; const nextIndex = (start, direction) => { let index = start; let minIdx = -1; let maxIdx = -1; for (let i = 0; i < tabs.value.length; i++) if (!tabs.value[i]?.disabled) { if (minIdx === -1) minIdx = i; maxIdx = i; } while (index >= minIdx && index <= maxIdx && tabs.value[index]?.disabled) index += direction; if (index < minIdx) index = minIdx; if (index > maxIdx) index = maxIdx; return index; }; let previousIndex; let isReverting = false; (0, vue.watch)(activeIndex, (newValue, oldValue) => { if (tabs.value.length <= 0 || tabs.value.filter((t) => !t.disabled).length <= 0) return; if (isReverting) { isReverting = false; return; } const index = nextIndex(newValue, newValue > oldValue ? 1 : -1); if (index !== newValue) { previousIndex = oldValue; activeIndex.value = index; return; } const tabEvent = new require_classes.BvEvent("activate-tab", { cancelable: true }); emit("activate-tab", { newTabId: tabs.value[index]?.id, prevTabId: tabs.value[previousIndex ?? oldValue]?.id, newTabIndex: index, prevTabIndex: previousIndex ?? oldValue, event: tabEvent }); if (tabEvent.defaultPrevented) { isReverting = true; const prev = previousIndex ?? oldValue ?? nextIndex(0, 1); previousIndex = void 0; if (activeId.value !== tabs.value[prev]?.id) activeId.value = tabs.value[prev]?.id; (0, vue.nextTick)(() => { if (prev >= 0) require_dom.getSafeDocument()?.getElementById(tabs.value[prev]?.buttonId)?.focus(); }); return; } if (activeId.value !== tabs.value[index]?.id) activeId.value = tabs.value[index]?.id; previousIndex = void 0; }); (0, vue.watch)(activeId, (newValue, oldValue) => { if (tabs.value.length <= 0 || tabs.value.filter((t) => !t.disabled).length <= 0) return; const index = tabs.value.findIndex((t) => t.id === newValue); if (index === activeIndex.value) return; const oldIndex = tabs.value.findIndex((t) => t.id === oldValue); if (tabs.value[index]?.disabled) { activeIndex.value = nextIndex(index, index > oldIndex ? 1 : -1); return; } if (index === -1) { activeIndex.value = nextIndex(0, 1); (0, vue.nextTick)(() => { activeId.value = tabs.value[activeIndex.value]?.id; }); return; } activeIndex.value = index; }); const registerTab = (tab) => { const idx = tabsInternal.value.findIndex((t) => t.value.internalId === tab.value.internalId); if (idx === -1) { tabsInternal.value.push(tab); if (initialized) (0, vue.nextTick)(() => { sortTabs(); }); else if (delayedTabSelection) (0, vue.nextTick)(() => { updateInitialIndexAndId(); }); } else { tabsInternal.value[idx] = tab; if (initialized) sortTabs(); } const idx2 = tabsInternal.value.findIndex((t) => t.value.internalId === tab.value.internalId); return tab.value.id ?? (!initialized ? initialIds.value[idx2] : tab.value.internalId); }; (0, vue.onMounted)(() => { updateInitialIndexAndId(); sortTabs(); initialized = true; }); const sortTabs = () => { tabsInternal.value.sort((a, b) => require_dom.sortSlotElementsByPosition(a.value.el.value, b.value.el.value)); if (activeId.value && activeIndex.value !== tabs.value.findIndex((t) => t.id === activeId.value)) activeIndex.value = tabs.value.findIndex((t) => t.id === activeId.value); }; const unregisterTab = (id) => { tabsInternal.value = tabsInternal.value.filter((t) => t.value.internalId !== id); }; (0, vue.provide)(require_keys.tabsInjectionKey, { lazy: (0, vue.toRef)(() => props.lazy), card: (0, vue.toRef)(() => props.card), noFade: (0, vue.toRef)(() => props.noFade), activeTabClass: (0, vue.toRef)(() => props.activeTabClass), inactiveTabClass: (0, vue.toRef)(() => props.inactiveTabClass), tabClass: (0, vue.toRef)(() => props.tabClass), registerTab, unregisterTab, activeId, activateTab: (internalId) => { const idx = tabs.value.findIndex((t) => t.internalId === internalId); if (internalId === void 0 || idx === -1) { activeIndex.value = nextIndex(0, 1); return; } activeIndex.value = idx; } }); return (_ctx, _cache) => { return (0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)((0, vue.unref)(props).tag), { id: (0, vue.unref)(props).id, class: (0, vue.normalizeClass)(["tabs", computedClasses.value]) }, { default: (0, vue.withCtx)(() => [ (0, vue.createVNode)((0, vue.unref)(ReusableEmptyTab).define, null, { default: (0, vue.withCtx)(() => [(0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(["tab-content", (0, vue.unref)(props).contentClass]) }, [(0, vue.renderSlot)(_ctx.$slots, "default"), showEmpty.value ? ((0, vue.openBlock)(), (0, vue.createElementBlock)("div", { key: "bv-empty-tab", class: (0, vue.normalizeClass)(["tab-pane active", { "card-body": (0, vue.unref)(props).card }]) }, [(0, vue.renderSlot)(_ctx.$slots, "empty")], 2)) : (0, vue.createCommentVNode)("", true)], 2)]), _: 3 }), (0, vue.unref)(props).end ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(ReusableEmptyTab).reuse, { key: 0 })) : (0, vue.createCommentVNode)("", true), (0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)([(0, vue.unref)(props).navWrapperClass, { "card-header": (0, vue.unref)(props).card, "ms-auto": __props.vertical && (0, vue.unref)(props).end }]) }, [(0, vue.createElementVNode)("ul", { class: (0, vue.normalizeClass)(["nav", [navTabsClasses.value, (0, vue.unref)(props).navClass]]), role: "tablist", "aria-orientation": (0, vue.unref)(props).vertical ? "vertical" : "horizontal" }, [ (0, vue.renderSlot)(_ctx.$slots, "tabs-start"), ((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(tabs.value, (tab, idx) => { return (0, vue.openBlock)(), (0, vue.createElementBlock)("li", { key: tab.id ?? tab.internalId, class: (0, vue.normalizeClass)(["nav-item", tab.titleItemClass]), role: "presentation" }, [(0, vue.createElementVNode)("button", (0, vue.mergeProps)({ id: tab.buttonId, class: ["nav-link", [tab.navItemClasses, tab.titleLinkClass]], role: "tab", "aria-controls": tab.id, "aria-selected": tab.active, disabled: tab.disabled, tabindex: (0, vue.unref)(props).noKeyNav ? void 0 : tab.active ? void 0 : -1, type: "button" }, { ref_for: true }, tab.titleLinkAttrs, { onKeydown: [ _cache[0] || (_cache[0] = (0, vue.withKeys)((0, vue.withModifiers)(($event) => !(0, vue.unref)(props).vertical && keynav($event, -1), ["exact"]), ["left"])), _cache[1] || (_cache[1] = (0, vue.withKeys)((0, vue.withModifiers)(($event) => !(0, vue.unref)(props).vertical && keynav($event, -999), ["shift"]), ["left"])), _cache[2] || (_cache[2] = (0, vue.withKeys)((0, vue.withModifiers)(($event) => (0, vue.unref)(props).vertical && keynav($event, -1), ["exact"]), ["up"])), _cache[3] || (_cache[3] = (0, vue.withKeys)((0, vue.withModifiers)(($event) => (0, vue.unref)(props).vertical && keynav($event, -999), ["shift"]), ["up"])), _cache[4] || (_cache[4] = (0, vue.withKeys)((0, vue.withModifiers)(($event) => !(0, vue.unref)(props).vertical && keynav($event, 1), ["exact"]), ["right"])), _cache[5] || (_cache[5] = (0, vue.withKeys)((0, vue.withModifiers)(($event) => !(0, vue.unref)(props).vertical && keynav($event, 999), ["shift"]), ["right"])), _cache[6] || (_cache[6] = (0, vue.withKeys)((0, vue.withModifiers)(($event) => (0, vue.unref)(props).vertical && keynav($event, 1), ["exact"]), ["down"])), _cache[7] || (_cache[7] = (0, vue.withKeys)((0, vue.withModifiers)(($event) => (0, vue.unref)(props).vertical && keynav($event, 999), ["shift"]), ["down"])), _cache[8] || (_cache[8] = (0, vue.withKeys)(($event) => keynav($event, -999), ["page-up"])), _cache[9] || (_cache[9] = (0, vue.withKeys)(($event) => keynav($event, 999), ["page-down"])), _cache[10] || (_cache[10] = (0, vue.withKeys)(($event) => keynav($event, -999), ["home"])), _cache[11] || (_cache[11] = (0, vue.withKeys)(($event) => keynav($event, 999), ["end"])) ], onClick: (0, vue.withModifiers)((e) => handleClick(e, idx), ["stop"]) }), [tab.titleComponent ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)(tab.titleComponent), { key: 0 })) : ((0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: 1 }, [(0, vue.createTextVNode)((0, vue.toDisplayString)(tab.title), 1)], 64))], 16, _hoisted_2)], 2); }), 128)), (0, vue.renderSlot)(_ctx.$slots, "tabs-end") ], 10, _hoisted_1)], 2), !(0, vue.unref)(props).end ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.unref)(ReusableEmptyTab).reuse, { key: 1 })) : (0, vue.createCommentVNode)("", true) ]), _: 3 }, 8, ["id", "class"]); }; } }); //#endregion Object.defineProperty(exports, "BTab_default", { enumerable: true, get: function() { return BTab_default; } }); Object.defineProperty(exports, "BTabs_default", { enumerable: true, get: function() { return BTabs_default; } }); //# sourceMappingURL=BTabs-DiYaJi22.js.map