I guess you and I are coming from the same point of of waiting too long for bootstrapvue to be updated. I had already created THIS repository with a similar goal, and I have looked at your components. I had an idea, instead of using the data api (data-bs-
), since bootstrap already provides a pure javascript API for the components, why not use bootstrap's javascript directly?
I had done a collapse component and a collapse directive and you can get the idea here:
// Collapse.vue Component
<template>
<div v-collapse="{ state: show, parent: parent }">
<slot></slot>
</div>
</template>
<script lang="ts">
import BCollapse from "@/directives/BCollapse";
import { defineComponent, ref, Ref, toRef } from "vue";
export default defineComponent({
name: "VbCollapse",
props: {
show: {
type: Boolean,
default: false,
},
parent: {
type: ref,
default: null,
},
},
setup(props) {
const show: Ref<Boolean> = toRef(props, "show");
const parent = toRef(props, "parent");
return {
show,
parent,
};
},
directives: {
collapse: BCollapse,
},
});
</script>
// BCollapse directive
import { DirectiveBinding, VNode } from "vue";
import Collapse from "bootstrap/js/src/collapse";
const getBsCollapse: any = (el: HTMLElement | Element, binding: DirectiveBinding) => {
const state = binding.value?.state || false;
const parent = binding.value?.parent || null;
return new Collapse(el, { toggle: state, parent: parent || '' });
}
export default {
created(el: HTMLElement, binding: DirectiveBinding, vnode: VNode) {
el.classList.add("collapse");
getBsCollapse(el, binding);
},
beforeUpdate(el: Element, binding: DirectiveBinding, vnode: VNode) {
const state = binding.value?.state || false;
if (state) {
getBsCollapse(el, binding).show();
} else {
getBsCollapse(el, binding).hide();
}
},
}
<template>
<vb-button variant="danger" @click="toggleCollapse">Toggle Collapse</vb-button>
<vb-collapse :show="collapse">
<h3>Hi There!</h3>
<p>
Hi there! I am a collapsable element that can only be shown once show is
set to true.
</p>
</vb-collapse>
</template>
<script lang="ts">
import vuebootstrapSample from "@/lib-components/vuebootstrap-sample.vue";
import VbButton from "@/lib-components/buttons/Button.vue";
import VbCollapse from "@/lib-components/collapse/Collapse.vue";
import VbAccordionItem from "@/lib-components/accordion/AccordionItem.vue";
import VbAccordion from "@/lib-components/accordion/Accordion.vue";
import { defineComponent, ref } from "vue";
export default defineComponent({
components: {
vuebootstrapSample,
VbButton,
VbCollapse,
VbAccordion,
VbAccordionItem,
},
name: "ServeDev",
setup() {
const collapse = ref(false);
const toggleCollapse = () => {
collapse.value = !collapse.value;
};
return {
toggleCollapse,
collapse,
};
},
});
</script>
Let me know in case you are interested in collaboration.