HEX
Server: Apache/2.4.52 (Ubuntu)
System: Linux spn-python 5.15.0-89-generic #99-Ubuntu SMP Mon Oct 30 20:42:41 UTC 2023 x86_64
User: arjun (1000)
PHP: 8.1.2-1ubuntu2.20
Disabled: NONE
Upload Files
File: //home/arjun/projects/buyercall/node_modules/bootstrap-vue-next/src/components/BTabs/BTab.vue
<template>
  <component
    :is="tag"
    :id="computedId"
    ref="el"
    class="tab-pane"
    :class="computedClasses"
    role="tabpanel"
    :aria-labelledby="buttonId"
    v-bind="attrs"
  >
    <slot v-if="showSlot" />
  </component>
</template>

<script setup lang="ts">
import {computed, inject, onMounted, onUnmounted, ref, toRef, useAttrs, watch} from 'vue'
import {useBooleanish, useId} from '../../composables'
import type {Booleanish, ClassValue, TabType} from '../../types'
import {tabsInjectionKey} from '../../utils'

const props = withDefaults(
  defineProps<{
    active?: Booleanish
    buttonId?: string
    disabled?: Booleanish
    id?: string
    lazy?: Booleanish
    lazyOnce?: Booleanish
    noBody?: Booleanish
    tag?: string
    title?: string
    titleItemClass?: ClassValue
    titleLinkAttributes?: Record<string, unknown>
    titleLinkClass?: ClassValue
  }>(),
  {
    active: false,
    buttonId: undefined,
    disabled: false,
    id: undefined,
    lazy: undefined,
    lazyOnce: undefined,
    noBody: false,
    tag: 'div',
    title: undefined,
    titleItemClass: undefined,
    titleLinkAttributes: undefined,
    titleLinkClass: undefined,
  }
)

const slots = defineSlots<{
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  default?: (props: Record<string, never>) => any
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  title?: (props: Record<string, never>) => any
}>()

const emit = defineEmits<{
  'update:active': [value: boolean]
}>()

defineOptions({
  inheritAttrs: false,
})

const parentData = inject(tabsInjectionKey, null)
const computedId = useId(() => props.id, 'tabpane')
const buttonId = useId(() => props.buttonId, 'tab')

const activeBoolean = useBooleanish(() => props.active)
const disabledBoolean = useBooleanish(() => props.disabled)
const lazyBoolean = useBooleanish(() => props.lazyOnce ?? props.lazy)
const noBodyBoolean = useBooleanish(() => props.noBody)

const lazyRenderCompleted = ref(false)
const el = ref<HTMLElement | null>(null)

const {onClick, ...attrs} = useAttrs()

const tab = computed(
  () =>
    ({
      id: computedId.value,
      buttonId: buttonId.value,
      disabled: disabledBoolean.value,
      title: props.title,
      titleComponent: slots.title,
      titleItemClass: props.titleItemClass,
      titleLinkAttributes: props.titleLinkAttributes,
      titleLinkClass: props.titleLinkClass,
      onClick,
      el: el.value,
    }) as TabType
)

onMounted(() => {
  if (!parentData) return
  parentData.registerTab(tab)
  if (activeBoolean.value) {
    parentData.activateTab(computedId.value)
  }
})

onUnmounted(() => {
  if (!parentData) return
  parentData.unregisterTab(computedId.value)
})

const isActive = toRef(() => parentData?.activeId.value === computedId.value)
const show = ref(isActive.value)

const computedLazy = toRef(() => !!(parentData?.lazy.value || lazyBoolean.value))
const computedLazyOnce = toRef(() => props.lazyOnce !== undefined)

const computedActive = toRef(() => isActive.value && !disabledBoolean.value)
const showSlot = toRef(
  () =>
    computedActive.value ||
    !computedLazy.value ||
    (computedLazy.value && computedLazyOnce.value && lazyRenderCompleted.value)
)

watch(isActive, (active) => {
  if (active) {
    emit('update:active', true)
    setTimeout(() => {
      show.value = true
    }, 0)
    return
  }
  show.value = false
  emit('update:active', false)
})
watch(activeBoolean, (active) => {
  if (!parentData) return
  if (!active) {
    if (isActive.value) {
      parentData.activateTab(undefined)
    }
    return
  }
  parentData.activateTab(computedId.value)
})

const computedClasses = computed(() => [
  {
    'active': isActive.value,
    'show': show.value,
    'card-body': parentData?.card.value && noBodyBoolean.value === false,
    'fade': !parentData?.noFade.value,
  },
  show.value && parentData?.activeTabClass ? parentData.activeTabClass : null,
])

watch(showSlot, (shown) => {
  if (shown && !lazyRenderCompleted.value) lazyRenderCompleted.value = true
})
</script>