aboutsummaryrefslogtreecommitdiff
path: root/resources/vue/components/courseware/layouts/CoursewareTabs.vue
blob: dec9ed006631fa8ace42be7e3e6e4f7b685d1827 (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
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
<template>
    <div class="tabs cw-tabs">
        <div class="tab-buttons cw-tabs-nav">
            <button
                v-for="(tab, index) in tabs"
                :key="index"
                :data-index="index"
                :class="[
                    activeTab === index ? 'is-active' : '',
                    tab.icon !== '' && tab.name !== '' ? 'cw-tabs-nav-icon-text-' + tab.icon : '',
                    tab.icon !== '' && tab.name === '' ? 'cw-tabs-nav-icon-solo-' + tab.icon : '',
                ]"
                :tabindex="activeTab === index ? 0 : -1"
                :aria-selected="activeTab === index"
                @click="selectTab(index)"
                @keydown="handleKeyEvent($event)"
                :ref="'tabnav' + index"
            >
                {{ tab.name }}
            </button>
        </div>
        <div class="tab-content cw-tabs-content">
            <slot></slot>
        </div>
    </div>
</template>

<script>
export default {
    name: 'CoursewareTabs',
    emits: ['update:modelValue'],
    props: {
        modelValue: { type: Number },
    },
    data() {
        return {
            activeTab: 0,
            tabs: [],
        };
    },
    methods: {
        selectTab(index) {
            if (index >= this.tabs.length || index < 0) {
                return;
            }
            this.activeTab = index;
            this.$refs['tabnav' + index][0].focus();
        },
        addTab(tab) {
            this.tabs.push(tab);
        },
        handleKeyEvent(e) {
            const index = parseInt(e.target.dataset.index);
            switch (e.keyCode) {
                case 37: // left
                case 38: // up
                    if (index !== 0) {
                        this.selectTab(index - 1);
                    } else {
                        this.selectTab(this.tabs.length - 1);
                    }
                    break;
                case 39: // right
                case 40: // down
                    if (index !== this.tabs.length - 1) {
                        this.selectTab(index + 1);
                    } else {
                        this.selectTab(0);
                    }
                    break;
                case 36: //pos1
                    this.selectTab(0);
                    break;
                case 35: //end
                    this.selectTab(this.tabs.length - 1);
                    break;
            }
        },
        getActiveTabElement() {
            return this.$refs['tabnav' + this.activeTab][0];
        },
    },
    provide() {
        return {
            addTab: this.addTab,
            activeTab: () => this.activeTab,
        };
    },
    mounted() {
        this.$nextTick(() => {
            if (this.modelValue) {
                this.selectTab(this.modelValue);
            }
        });
    },
    watch: {
        modelValue(newValue) {
            this.selectTab(newValue);
        },
        activeTab(newValue) {
            if (this.modelValue !== newValue) {
                this.$emit('update:modelValue', newValue);
            }
        },
    },
};
</script>