feat: update tabs

This commit is contained in:
wangxueliang 2018-12-11 20:53:56 +08:00
parent 0eafff36d8
commit 2fb1de4e29
5 changed files with 154 additions and 72 deletions

View File

@ -0,0 +1,38 @@
<cn>
#### 自定义页签头
自定义页签头
</cn>
<us>
#### Customized bar of tab
Customized bar of tab.
</us>
```html
<template>
<div>
<a-tabs defaultActiveKey="1">
<a-tab-pane tab="Tab 1" key="1" style="height: 200px">Content of Tab Pane 1</a-tab-pane>
<a-tab-pane tab="Tab 2" key="2" forceRender>Content of Tab Pane 2</a-tab-pane>
<a-tab-pane tab="Tab 3" key="3">Content of Tab Pane 3</a-tab-pane>
<template slot="renderTabBar" slot-scope="props, DefaultTabBar">
<component :is="DefaultTabBar" {...props} />
</template>
</a-tabs>
</div>
</template>
<script>
export default {
data () {
return {
}
},
methods: {
callback (key) {
console.log(key)
},
},
}
</script>
```

View File

@ -10,6 +10,7 @@ import Icon from './icon'
import Position from './position'
import Size from './size'
import Slide from './slide'
import CustomTabBar from './custom-tab-bar'
import CN from '../index.zh-CN.md'
import US from '../index.en-US.md'
@ -53,16 +54,17 @@ export default {
<div>
<md cn={md.cn} us={md.us}/>
<Basic />
<CardTop />
<Card />
<CustomAddTrigger />
<Disabled />
<EditableCard />
<Extra />
<Icon />
<Position />
<Size />
<Slide/>
<Extra />
<Size />
<Position />
<Card />
<EditableCard />
<CardTop />
<CustomAddTrigger />
<CustomTabBar />
<api>
<template slot='cn'>
<CN/>

View File

@ -0,0 +1,58 @@
import Icon from '../icon'
import ScrollableInkTabBar from '../vc-tabs/src/ScrollableInkTabBar'
import { cloneElement } from '../_util/vnode'
const TabBar = {
functional: true,
render (h, context) {
const {
tabBarStyle,
animated = true,
renderTabBar,
tabBarExtraContent,
tabPosition,
prefixCls,
} = context.props
const inkBarAnimated = typeof animated === 'object' ? animated.inkBar : animated
const isVertical = tabPosition === 'left' || tabPosition === 'right'
const prevIconType = isVertical ? 'up' : 'left'
const nextIconType = isVertical ? 'down' : 'right'
const prevIcon = (
<span class={`${prefixCls}-tab-prev-icon`}>
<Icon type={prevIconType} class={`${prefixCls}-tab-prev-icon-target`} />
</span>
)
const nextIcon = (
<span class={`${prefixCls}-tab-next-icon`}>
<Icon type={nextIconType} class={`${prefixCls}-tab-next-icon-target`} />
</span>
)
const renderProps = {
props: {
...context.props,
inkBarAnimated,
extraContent: tabBarExtraContent,
prevIcon,
nextIcon,
},
style: tabBarStyle,
on: {
...context.listeners,
},
}
let RenderTabBar
if (renderTabBar) {
RenderTabBar = renderTabBar(renderProps, ScrollableInkTabBar)
} else {
RenderTabBar = <ScrollableInkTabBar {...renderProps} />
}
return cloneElement(RenderTabBar, renderProps)
},
}
export default TabBar

View File

@ -1,49 +1,42 @@
import Icon from '../icon'
import VcTabs, { TabPane } from '../vc-tabs/src'
import ScrollableInkTabBar from '../vc-tabs/src/ScrollableInkTabBar'
import TabContent from '../vc-tabs/src/TabContent'
import isFlexSupported from '../_util/isFlexSupported'
import { hasProp, getComponentFromProp, isEmptyElement, getSlotOptions, getOptionProps, filterEmpty, mergeProps } from '../_util/props-util'
import warning from '../_util/warning'
import PropTypes from '../_util/vue-types'
import { getComponentFromProp, getOptionProps, filterEmpty } from '../_util/props-util'
import { cloneElement } from '../_util/vnode'
import TabBar from './TabBar'
export default {
TabPane,
name: 'ATabs',
props: {
prefixCls: { type: String, default: 'ant-tabs' },
activeKey: String,
defaultActiveKey: String,
hideAdd: { type: Boolean, default: false },
tabBarStyle: Object,
tabBarExtraContent: [String, Number, Function],
destroyInactiveTabPane: { type: Boolean, default: false },
type: {
validator (value) {
return ['line', 'card', 'editable-card'].includes(value)
},
},
tabPosition: {
validator (value) {
return ['top', 'right', 'bottom', 'left'].includes(value)
},
},
size: {
validator (value) {
return ['default', 'small', 'large'].includes(value)
},
},
animated: { type: [Boolean, Object], default: undefined },
tabBarGutter: Number,
prefixCls: PropTypes.string.def('ant-tabs'),
activeKey: PropTypes.string,
defaultActiveKey: PropTypes.string,
hideAdd: PropTypes.bool.def(false),
tabBarStyle: PropTypes.object,
tabBarExtraContent: PropTypes.oneOfType([
PropTypes.string,
PropTypes.number,
PropTypes.func,
]),
destroyInactiveTabPane: PropTypes.bool.def(false),
type: PropTypes.oneOf(['line', 'card', 'editable-card']),
tabPosition: PropTypes.oneOf(['top', 'right', 'bottom', 'left']),
size: PropTypes.oneOf(['default', 'small', 'large']),
animated: PropTypes.oneOfType([
PropTypes.bool,
PropTypes.object,
]),
tabBarGutter: PropTypes.number,
renderTabBar: PropTypes.func,
},
model: {
prop: 'activeKey',
event: 'change',
},
methods: {
createNewTab (targetKey) {
this.$emit('edit', targetKey, 'add')
},
removeTab (targetKey, e) {
e.stopPropagation()
if (!targetKey) {
@ -51,10 +44,12 @@ export default {
}
this.$emit('edit', targetKey, 'remove')
},
handleChange (activeKey) {
this.$emit('change', activeKey)
},
createNewTab (targetKey) {
this.$emit('edit', targetKey, 'add')
},
onTabClick (val) {
this.$emit('tabClick', val)
},
@ -74,37 +69,29 @@ export default {
}
},
render (createElement) {
render () {
const {
prefixCls,
size,
type = 'line',
tabPosition,
tabBarStyle,
animated = true,
hideAdd,
onTabClick,
onPrevClick,
onNextClick,
animated,
tabBarGutter,
} = this
renderTabBar,
} = this.$props
const children = filterEmpty(this.$slots.default)
let tabBarExtraContent = getComponentFromProp(this, 'tabBarExtraContent')
let { inkBarAnimated, tabPaneAnimated } = typeof animated === 'object' ? { // eslint-disable-line
inkBarAnimated: !!animated.inkBar, tabPaneAnimated: !!animated.tabPane,
} : {
inkBarAnimated: animated === undefined || animated, tabPaneAnimated: animated === undefined || animated,
}
let tabPaneAnimated = typeof animated === 'object' ? animated.tabPane : animated
// card tabs should not have animation
if (type !== 'line') {
tabPaneAnimated = animated === undefined ? false : tabPaneAnimated
}
const cls = {
[`${prefixCls}-small`]: size === 'small',
[`${prefixCls}-large`]: size === 'large',
[`${prefixCls}-default`]: size === 'default',
[`${prefixCls}-vertical`]: tabPosition === 'left' || tabPosition === 'right',
[`${prefixCls}-${size}`]: !!size,
[`${prefixCls}-card`]: type.indexOf('card') >= 0,
[`${prefixCls}-${type}`]: true,
[`${prefixCls}-no-animation`]: !tabPaneAnimated,
@ -120,6 +107,7 @@ export default {
const closeIcon = closable ? (
<Icon
type='close'
class={`${prefixCls}-close-x`}
onClick={e => this.removeTab(child.key, e)}
/>
) : null
@ -152,27 +140,23 @@ export default {
</div>
) : null
const renderTabBar = () => {
const scrollableInkTabBarProps = {
props: {
inkBarAnimated,
extraContent: tabBarExtraContent,
tabBarGutter,
},
on: {
tabClick: onTabClick,
prevClick: onPrevClick,
nextClick: onNextClick,
},
style: tabBarStyle,
}
return <ScrollableInkTabBar {...scrollableInkTabBarProps}/>
const renderTabBarSlot = renderTabBar || this.$scopedSlots.renderTabBar
const tabBarProps = {
props: {
...this.$props,
tabBarExtraContent,
renderTabBar: renderTabBarSlot,
},
on: {
...this.$listeners,
},
}
const tabsProps = {
props: {
...getOptionProps(this),
tabBarPosition: tabPosition,
renderTabBar: renderTabBar,
renderTabBar: () => <TabBar {...tabBarProps}/>,
renderTabContent: () => <TabContent animated={tabPaneAnimated} animatedWithMargin />,
children: childrenWithClose.length > 0 ? childrenWithClose : children,
__propsSymbol__: Symbol(),

View File

@ -8,7 +8,7 @@ export default {
name: 'ScrollableInkTabBar',
inheritAttrs: false,
props: ['extraContent', 'inkBarAnimated', 'tabBarGutter', 'prefixCls',
'navWrapper', 'tabBarPosition', 'panels', 'activeKey'],
'navWrapper', 'tabBarPosition', 'panels', 'activeKey', 'prevIcon', 'nextIcon'],
render () {
const props = { ...this.$props }
const listeners = this.$listeners