summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/pipeline_editor/components/ui/editor_tab.vue
blob: b0acd3ca2ee655c57b2d3a94c228f81671abe19f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
<script>
import { GlTab } from '@gitlab/ui';

/**
 * Wrapper of <gl-tab> to optionally lazily render this tab's content
 * when its shown **without dismounting after its hidden**.
 *
 * Usage:
 *
 * API is the same as <gl-tab>, for example:
 *
 * <gl-tabs>
 *   <editor-tab title="Tab 1" :lazy="true">
 *     lazily mounted content (gets mounted if this is first tab)
 *   </editor-tab>
 *   <editor-tab title="Tab 2" :lazy="true">
 *     lazily mounted content
 *   </editor-tab>
 *   <editor-tab title="Tab 3">
 *      eagerly mounted content
 *   </editor-tab>
 * </gl-tabs>
 *
 * Once the tab is selected it is permanently set as "not-lazy"
 * so it's contents are not dismounted.
 *
 * lazy is "false" by default, as in <gl-tab>.
 */

export default {
  components: {
    GlTab,
    // Use a small renderless component to know when the tab content mounts because:
    // - gl-tab always gets mounted, even if lazy is `true`. See:
    // https://github.com/bootstrap-vue/bootstrap-vue/blob/dev/src/components/tabs/tab.js#L180
    // - we cannot listen to events on <slot />
    MountSpy: {
      render: () => null,
    },
  },
  inheritAttrs: false,
  props: {
    lazy: {
      type: Boolean,
      required: false,
      default: false,
    },
  },
  data() {
    return {
      isLazy: this.lazy,
    };
  },
  methods: {
    onContentMounted() {
      // When a child is first mounted make the entire tab
      // permanently mounted by setting 'lazy' to false.
      this.isLazy = false;
    },
  },
};
</script>
<template>
  <gl-tab :lazy="isLazy" v-bind="$attrs" v-on="$listeners">
    <slot v-for="slot in Object.keys($slots)" :slot="slot" :name="slot"></slot>
    <mount-spy @hook:mounted="onContentMounted" />
  </gl-tab>
</template>