/
VTab.ts
129 lines (106 loc) Β· 2.66 KB
/
VTab.ts
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
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
// Mixins
import { factory as GroupableFactory } from '../../mixins/groupable'
import Routable from '../../mixins/routable'
import Themeable from '../../mixins/themeable'
// Utilities
import { keyCodes } from './../../util/helpers'
import mixins from '../../util/mixins'
import { ExtractVue } from './../../util/mixins'
// Types
import { VNode } from 'vue/types'
// Components
import VTabsBar from '../VTabs/VTabsBar'
const baseMixins = mixins(
Routable,
// Must be after routable
// to overwrite activeClass
GroupableFactory('tabsBar'),
Themeable
)
type VTabBarInstance = InstanceType<typeof VTabsBar>
interface options extends ExtractVue<typeof baseMixins> {
$el: HTMLElement
tabsBar: VTabBarInstance
}
export default baseMixins.extend<options>().extend(
/* @vue/component */
).extend({
name: 'v-tab',
props: {
ripple: {
type: [Boolean, Object],
default: true,
},
},
data: () => ({
proxyClass: 'v-tab--active',
}),
computed: {
classes (): object {
return {
'v-tab': true,
...Routable.options.computed.classes.call(this),
'v-tab--disabled': this.disabled,
...this.groupClasses,
}
},
value (): any {
let to = this.to || this.href
if (to == null) return to
if (this.$router &&
this.to === Object(this.to)
) {
const resolve = this.$router.resolve(
this.to,
this.$route,
this.append
)
to = resolve.href
}
return to.replace('#', '')
},
},
methods: {
click (e: KeyboardEvent | MouseEvent): void {
// Prevent keyboard actions
// from children elements
// within disabled tabs
if (this.disabled) {
e.preventDefault()
return
}
// If user provides an
// actual link, do not
// prevent default
if (this.href &&
this.href.indexOf('#') > -1
) e.preventDefault()
if (e.detail) this.$el.blur()
this.$emit('click', e)
this.to || this.toggle()
},
toggle () {
// VItemGroup treats a change event as a click
if (!this.isActive || (!this.tabsBar.mandatory && !this.to)) {
this.$emit('change')
}
},
},
render (h): VNode {
const { tag, data } = this.generateRouteLink()
data.attrs = {
...data.attrs,
'aria-selected': String(this.isActive),
role: 'tab',
tabindex: this.disabled ? -1 : 0,
}
data.on = {
...data.on,
keydown: (e: KeyboardEvent) => {
if (e.keyCode === keyCodes.enter) this.click(e)
this.$emit('keydown', e)
},
}
return h(tag, data, this.$slots.default)
},
})