Tab.vue 1.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. <template>
  2. <div v-if="shouldRender" v-show="active" class="flex flex-col flex-1">
  3. <slot></slot>
  4. </div>
  5. </template>
  6. <script setup lang="ts">
  7. import {
  8. onMounted,
  9. onBeforeUnmount,
  10. inject,
  11. computed,
  12. watch,
  13. } from "@nuxtjs/composition-api"
  14. import { TabMeta, TabProvider } from "./Tabs.vue"
  15. const props = defineProps({
  16. label: { type: String, default: null },
  17. info: { type: String, default: null },
  18. indicator: { type: Boolean, default: false },
  19. icon: { type: String, default: null },
  20. id: { type: String, default: null, required: true },
  21. selected: {
  22. type: Boolean,
  23. default: false,
  24. },
  25. })
  26. const tabMeta = computed<TabMeta>(() => ({
  27. icon: props.icon,
  28. indicator: props.indicator,
  29. info: props.info,
  30. label: props.label,
  31. }))
  32. const {
  33. activeTabID,
  34. renderInactive,
  35. addTabEntry,
  36. updateTabEntry,
  37. removeTabEntry,
  38. } = inject<TabProvider>("tabs-system")!
  39. const active = computed(() => activeTabID.value === props.id)
  40. const shouldRender = computed(() => {
  41. // If render inactive is true, then it should be rendered nonetheless
  42. if (renderInactive.value) return true
  43. // Else, return whatever is the active state
  44. return active.value
  45. })
  46. onMounted(() => {
  47. addTabEntry(props.id, tabMeta.value)
  48. })
  49. watch(tabMeta, (newMeta) => {
  50. updateTabEntry(props.id, newMeta)
  51. })
  52. onBeforeUnmount(() => {
  53. removeTabEntry(props.id)
  54. })
  55. </script>