-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
index.tsx
106 lines (97 loc) · 3.07 KB
/
index.tsx
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
import { tag, h, WeElement, extractClass } from 'omi'
import * as css from './index.scss'
import { MDCTabBar } from '@material/tab-bar'
import '../icon'
import { domReady } from '../util/dom-ready'
//@ts-ignore
import '../theme.ts'
// @ts-ignore
import { extract, htmlToVdom } from '../util.ts'
interface Props {
defaultActive: string,
width: string,
align: 'start' | 'end' | 'center', // 三种可能值 start | end | center
useMinWidth: boolean,
stacked: boolean
}
@tag('m-tab')
export default class Tab extends WeElement<Props>{
static css = css
data = {
active: null,
tabBar: null
}
static propTypes = {
defaultActive: String,
width: String,
align: String,
useMinWidth: Boolean,
stacked: Boolean
}
installed() {
domReady(() => {
//update first
this.update()
//init mdc tab
this.data.tabBar = new MDCTabBar(this.shadowRoot.querySelector('.mdc-tab-bar'));
this.data.tabBar.listen('MDCTabBar:activated', (e) => {
let item = this.props.children[e.detail.index]
this.fire('change', item.attributes)
})
})
}
uninstall() {
this.data.tabBar.destroy()
}
activateTab(value) {
// @ts-ignore
let index = [].findIndex(this.props.children, (item => item.attributes.value === value))
this.data.tabBar.activateTab(index)
}
renderButton(vnode, activeProp) {
const { attributes: props } = vnode
//todo fix this?
if (props['svg-icon']) {
props.svgIcon = JSON.parse(props['svg-icon'].replace(/(['"])?([a-zA-Z0-9_]+)(['"])?:([^\/])/g, '"$2":$4').replace(/'([\s\S]*?)'/g, '"$1"'))
}
const isActive = activeProp === props.value
return (
<button {...extractClass(props, 'mdc-tab', {
'mdc-tab--active': isActive,
'mdc-tab--min-width': this.props.useMinWidth,
'mdc-tab--stacked': this.props.stacked
})} role="tab" aria-selected={isActive}>
<span class="mdc-tab__content">
{props.icon && <span class="mdc-tab__icon material-icons" aria-hidden="true">{props.icon}</span>}
{props.svgIcon && <span class="mdc-tab__icon" aria-hidden="true"><m-icon {...props.svgIcon}></m-icon></span>}
<span class="mdc-tab__text-label">{vnode.attributes.label}</span>
</span>
<span {...extractClass(props, 'mdc-tab-indicator', { 'mdc-tab-indicator--active': isActive })}>
<span class="mdc-tab-indicator__content mdc-tab-indicator__content--underline"></span>
</span>
<span class="mdc-tab__ripple"></span>
</button>
)
}
render(props) {
const { defaultActive, width, align } = props
if (this.innerHTML && !props.children) {
props.children = htmlToVdom(this.innerHTML)
}
const { children } = props
const style = { width: width || '100%' }
const alignClass = align && 'mdc-tab-scroller--align-' + align
const scrollerClasses = extractClass(props, 'mdc-tab-scroller', alignClass)
return (
<div class="mdc-tab-bar" style={style} role="tablist">
<div {...scrollerClasses}>
<div class="mdc-tab-scroller__scroll-area">
<div class="mdc-tab-scroller__scroll-content">
{children && children.map(vnode => this.renderButton(vnode, defaultActive))}
</div>
</div>
</div>
</div>
)
}
}