tabs
							parent
							
								
									b0a21a5b08
								
							
						
					
					
						commit
						3b6008151b
					
				|  | @ -23,3 +23,5 @@ export { default as Tag } from './tag' | |||
| export { default as Avatar } from './avatar' | ||||
| 
 | ||||
| export { default as Badge } from './badge' | ||||
| 
 | ||||
| export { default as Tabs } from './tabs' | ||||
|  |  | |||
|  | @ -8,3 +8,4 @@ import './rate/style' | |||
| import './pagination/style' | ||||
| import './avatar/style' | ||||
| import './badge/style' | ||||
| import './tabs/style' | ||||
|  |  | |||
|  | @ -0,0 +1,18 @@ | |||
| export default { | ||||
|   /** | ||||
|    * LEFT | ||||
|    */ | ||||
|   LEFT: 37, // also NUM_WEST
 | ||||
|   /** | ||||
|    * UP | ||||
|    */ | ||||
|   UP: 38, // also NUM_NORTH
 | ||||
|   /** | ||||
|    * RIGHT | ||||
|    */ | ||||
|   RIGHT: 39, // also NUM_EAST
 | ||||
|   /** | ||||
|    * DOWN | ||||
|    */ | ||||
|   DOWN: 40, // also NUM_SOUTH
 | ||||
| } | ||||
|  | @ -0,0 +1,7 @@ | |||
| export default { | ||||
|   saveRef (name) { | ||||
|     return node => { | ||||
|       this[name] = node | ||||
|     } | ||||
|   }, | ||||
| } | ||||
|  | @ -0,0 +1,75 @@ | |||
| <template> | ||||
|   <button :class="classes" :disabled="disabled" | ||||
|     @click="handleClick" @mouseout="mouseout" @mouseover="mouseover"> | ||||
|     {{tab}} | ||||
|   </button> | ||||
| </template> | ||||
| <script> | ||||
| 
 | ||||
| export default { | ||||
|   name: 'TabBar', | ||||
|   props: { | ||||
|     prefixCls: { | ||||
|       default: 'ant-tabs', | ||||
|       type: String, | ||||
|     }, | ||||
|     tabBarPosition: { | ||||
|       default: 'top', | ||||
|       validator (value) { | ||||
|         return ['top', 'bottom'].includes(value) | ||||
|       }, | ||||
|     }, | ||||
|     disabled: Boolean, | ||||
|     onKeyDown: Function, | ||||
|     onTabClick: Function, | ||||
|     activeKey: String, | ||||
|     tab: String, | ||||
|   }, | ||||
|   data () { | ||||
|     return { | ||||
|       sizeMap: { | ||||
|         large: 'lg', | ||||
|         small: 'sm', | ||||
|       }, | ||||
|       clicked: false, | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     classes () { | ||||
|       const { prefixCls, type, shape, size, loading, ghost, clicked, sizeMap } = this | ||||
|       const sizeCls = sizeMap[size] || '' | ||||
|       return { | ||||
|         [`${prefixCls}`]: true, | ||||
|         [`${prefixCls}-${type}`]: type, | ||||
|         [`${prefixCls}-${shape}`]: shape, | ||||
|         [`${prefixCls}-${sizeCls}`]: sizeCls, | ||||
|         [`${prefixCls}-loading`]: loading, | ||||
|         [`${prefixCls}-clicked`]: clicked, | ||||
|         [`${prefixCls}-background-ghost`]: ghost || type === 'ghost', | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   methods: { | ||||
|     handleClick (event) { | ||||
|       if (this.clicked) { | ||||
|         return | ||||
|       } | ||||
|       this.clicked = true | ||||
|       clearTimeout(this.timeout) | ||||
|       this.timeout = setTimeout(() => (this.clicked = false), 500) | ||||
|       this.$emit('click', event) | ||||
|     }, | ||||
|     mouseover (event) { | ||||
|       this.$emit('mouseover', event) | ||||
|     }, | ||||
|     mouseout (event) { | ||||
|       this.$emit('mouseout', event) | ||||
|     }, | ||||
|   }, | ||||
|   beforeDestroy () { | ||||
|     if (this.timeout) { | ||||
|       clearTimeout(this.timeout) | ||||
|     } | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | @ -0,0 +1,66 @@ | |||
| <script> | ||||
| import { | ||||
|   getTransformByIndex, | ||||
|   getActiveIndex, | ||||
|   getTransformPropValue, | ||||
|   getMarginStyle, | ||||
| } from './utils' | ||||
| export default { | ||||
|   name: 'TabContent', | ||||
|   props: { | ||||
|     animated: { type: Boolean, default: true }, | ||||
|     animatedWithMargin: { type: Boolean, default: true }, | ||||
|     prefixCls: { | ||||
|       default: 'ant-tabs', | ||||
|       type: String, | ||||
|     }, | ||||
|     activeKey: String, | ||||
|     tabBarPosition: String, | ||||
|   }, | ||||
|   data () { | ||||
|     return { | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     classes () { | ||||
|       const { animated, prefixCls } = this | ||||
|       return { | ||||
|         [`${prefixCls}-content`]: true, | ||||
|         [animated | ||||
|           ? `${prefixCls}-content-animated` | ||||
|           : `${prefixCls}-content-no-animated`]: true, | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   methods: { | ||||
|   }, | ||||
|   render () { | ||||
|     const { | ||||
|       activeKey, | ||||
|       tabBarPosition, animated, animatedWithMargin, classes, | ||||
|     } = this | ||||
|     let style = {} | ||||
|     if (animated && this.$slots.default) { | ||||
|       const activeIndex = getActiveIndex(this.$slots.default, activeKey) | ||||
|       if (activeIndex !== -1) { | ||||
|         const animatedStyle = animatedWithMargin | ||||
|           ? getMarginStyle(activeIndex, tabBarPosition) | ||||
|           : getTransformPropValue(getTransformByIndex(activeIndex, tabBarPosition)) | ||||
|         style = animatedStyle | ||||
|       } else { | ||||
|         style = { | ||||
|           display: 'none', | ||||
|         } | ||||
|       } | ||||
|     } | ||||
|     return ( | ||||
|       <div | ||||
|         class={classes} | ||||
|         style={style} | ||||
|       > | ||||
|         {this.$slots.default} | ||||
|       </div> | ||||
|     ) | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | @ -0,0 +1,48 @@ | |||
| <template> | ||||
|   <div | ||||
|     role="tabpanel" | ||||
|     :aria-hidden="active ? 'false' : 'true'" | ||||
|     :class="classes" | ||||
|   > | ||||
|     <slot v-if="isRender || forceRender"> | ||||
|     </slot> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| export default { | ||||
|   name: 'TabPane', | ||||
|   props: { | ||||
|     pKey: [String, Number], | ||||
|     forceRender: Boolean, | ||||
|     // placeholder: [Function, String, Number], | ||||
|   }, | ||||
|   data () { | ||||
|     const { prefixCls, destroyInactiveTabPane, activeKey } = this.$parent | ||||
|     return { | ||||
|       rootPrefixCls: prefixCls, | ||||
|       destroyInactiveTabPane, | ||||
|       active: this.pKey === activeKey, | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     classes () { | ||||
|       const { rootPrefixCls, active } = this | ||||
|       const prefixCls = `${rootPrefixCls}-tabpane` | ||||
|       return { | ||||
|         [`${prefixCls}`]: true, | ||||
|         [`${prefixCls}-inactive`]: !active, | ||||
|         [`${prefixCls}-active`]: active, | ||||
|       } | ||||
|     }, | ||||
|     isRender () { | ||||
|       const { | ||||
|         destroyInactiveTabPane, active, | ||||
|       } = this | ||||
|       this._isActived = this._isActived || active | ||||
|       return destroyInactiveTabPane ? active : this._isActived | ||||
|     }, | ||||
|   }, | ||||
|   methods: { | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | @ -0,0 +1,174 @@ | |||
| <script> | ||||
| import Icon from '../icon' | ||||
| import KeyCode from './KeyCode' | ||||
| import TabBar from './TabBar' | ||||
| import TabContent from './TabContent' | ||||
| function getDefaultActiveKey (t) { | ||||
|   let activeKey | ||||
|   t.$slot.default.forEach((child) => { | ||||
|     if (child && !activeKey && !child.disabled) { | ||||
|       activeKey = child.pKey | ||||
|     } | ||||
|   }) | ||||
|   return activeKey | ||||
| } | ||||
| function activeKeyIsValid (t, key) { | ||||
|   const keys = t.$slot.default.map(child => child && child.pKey) | ||||
|   return keys.indexOf(key) >= 0 | ||||
| } | ||||
| export default { | ||||
|   name: 'Tabs', | ||||
|   components: { Icon }, | ||||
|   props: { | ||||
|     prefixCls: { | ||||
|       default: 'ant-tabs', | ||||
|       type: String, | ||||
|     }, | ||||
|     tabBarPosition: { | ||||
|       default: 'top', | ||||
|       validator (value) { | ||||
|         return ['top', 'bottom'].includes(value) | ||||
|       }, | ||||
|     }, | ||||
|     destroyInactiveTabPane: Boolean, | ||||
|     activeKey: String, | ||||
|     defaultActiveKey: String, | ||||
|   }, | ||||
|   data () { | ||||
|     return { | ||||
|       stateActiveKey: this.getStateActiveKey(), | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|     classes () { | ||||
|       const { prefixCls, tabBarPosition } = this | ||||
|       return { | ||||
|         [`${prefixCls}`]: true, | ||||
|         [`${prefixCls}-${tabBarPosition}`]: true, | ||||
|       } | ||||
|     }, | ||||
|   }, | ||||
|   beforeUpdate () { | ||||
|     if ('activeKey' in this) { | ||||
|       this.stateActiveKey = this.activeKey | ||||
|     } else if (!activeKeyIsValid(this, this.stateActiveKey)) { | ||||
|       this.stateActiveKey = getDefaultActiveKey(this) | ||||
|     } | ||||
|   }, | ||||
|   methods: { | ||||
|     getStateActiveKey () { | ||||
|       let activeKey | ||||
|       if ('activeKey' in this) { | ||||
|         activeKey = this.activeKey | ||||
|       } else if ('defaultActiveKey' in this) { | ||||
|         activeKey = this.defaultActiveKey | ||||
|       } else { | ||||
|         activeKey = getDefaultActiveKey(this) | ||||
|       } | ||||
|       return activeKey | ||||
|     }, | ||||
|     onTabClick (activeKey) { | ||||
|       if (this.tabBar.props.onTabClick) { | ||||
|         this.tabBar.props.onTabClick(activeKey) | ||||
|       } | ||||
|       this.setActiveKey(activeKey) | ||||
|     }, | ||||
| 
 | ||||
|     onNavKeyDown (e) { | ||||
|       const eventKeyCode = e.keyCode | ||||
|       if (eventKeyCode === KeyCode.RIGHT || eventKeyCode === KeyCode.DOWN) { | ||||
|         e.preventDefault() | ||||
|         const nextKey = this.getNextActiveKey(true) | ||||
|         this.onTabClick(nextKey) | ||||
|       } else if (eventKeyCode === KeyCode.LEFT || eventKeyCode === KeyCode.UP) { | ||||
|         e.preventDefault() | ||||
|         const previousKey = this.getNextActiveKey(false) | ||||
|         this.onTabClick(previousKey) | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     setActiveKey (activeKey) { | ||||
|       if (this.stateActiveKey !== activeKey) { | ||||
|         if (!('activeKey' in this)) { | ||||
|           this.stateActiveKey = activeKey | ||||
|         } | ||||
|         this.$emit('change', activeKey) | ||||
|       } | ||||
|     }, | ||||
| 
 | ||||
|     getNextActiveKey (next) { | ||||
|       const activeKey = this.stateActiveKey | ||||
|       const children = [] | ||||
|       this.$slot.default.forEach((c) => { | ||||
|         if (c && !c.disabled) { | ||||
|           if (next) { | ||||
|             children.push(c) | ||||
|           } else { | ||||
|             children.unshift(c) | ||||
|           } | ||||
|         } | ||||
|       }) | ||||
|       const length = children.length | ||||
|       let ret = length && children[0].key | ||||
|       children.forEach((child, i) => { | ||||
|         if (child.pKey === activeKey) { | ||||
|           if (i === length - 1) { | ||||
|             ret = children[0].key | ||||
|           } else { | ||||
|             ret = children[i + 1].key | ||||
|           } | ||||
|         } | ||||
|       }) | ||||
|       return ret | ||||
|     }, | ||||
|   }, | ||||
|   beforeDestroy () { | ||||
|   }, | ||||
|   render () { | ||||
|     const { | ||||
|       prefixCls, | ||||
|       tabBarPosition, | ||||
|       destroyInactiveTabPane, | ||||
|       onNavKeyDown, | ||||
|       onTabClick, | ||||
|       stateActiveKey, | ||||
|       classes, | ||||
|       setActiveKey, | ||||
|       $slots, | ||||
|     } = this | ||||
|     const hasSlot = !!$slots.default | ||||
|     const tabBarProps = [] | ||||
|     if (hasSlot) { | ||||
|       $slots.default.forEach(tab => { | ||||
|         tab.data && tabBarProps.push( | ||||
|           <TabBar | ||||
|             {...tab.data} | ||||
|             prefixCls={prefixCls} | ||||
|             onKeyDown={onNavKeyDown} | ||||
|             tabBarPosition={tabBarPosition} | ||||
|             onTabClick={onTabClick} | ||||
|             activeKey={stateActiveKey} />) | ||||
|       }) | ||||
|     } | ||||
|     const tabContentProps = { | ||||
|       props: { | ||||
|         prefixCls, | ||||
|         tabBarPosition, | ||||
|         activeKey: stateActiveKey, | ||||
|         destroyInactiveTabPane, | ||||
|         onChange: setActiveKey, | ||||
|         key: 'tabContent', | ||||
|       }} | ||||
|     return ( | ||||
|       <div | ||||
|         class={classes} | ||||
|       > | ||||
|         {tabBarProps} | ||||
|         <TabContent {...tabContentProps}> | ||||
|           {$slots.default} | ||||
|         </TabContent> | ||||
|       </div> | ||||
|     ) | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | @ -0,0 +1,17 @@ | |||
| <template> | ||||
|   <div> | ||||
|     <Tabs activeKey="test1"> | ||||
|       <TabPane pKey="test1" tab="tab1">hello</TabPane> | ||||
|       <TabPane pKey="test2" tab="tab2">world</TabPane> | ||||
|     </Tabs> | ||||
|   </div> | ||||
| </template> | ||||
| <script> | ||||
| import { Tabs } from 'antd' | ||||
| export default { | ||||
|   components: { | ||||
|     Tabs, | ||||
|     TabPane: Tabs.TabPane, | ||||
|   }, | ||||
| } | ||||
| </script> | ||||
|  | @ -1,6 +1,6 @@ | |||
| import Tabs from './Tabs' | ||||
| import TabPane from './TabPane' | ||||
| import TabContent from './TabContent' | ||||
| 
 | ||||
| // import TabContent from './TabContent'
 | ||||
| Tabs.TabPane = TabPane | ||||
| export default Tabs | ||||
| export { TabPane, TabContent } | ||||
| export { TabPane } | ||||
|  |  | |||
|  | @ -1,3 +1,29 @@ | |||
| export function toArray (children) { | ||||
|   // allow [c,[a,b]]
 | ||||
|   const c = [] | ||||
|   children.forEach(child => { | ||||
|     if (child.data) { | ||||
|       c.push(child) | ||||
|     } | ||||
|   }) | ||||
|   return c | ||||
| } | ||||
| 
 | ||||
| export function getActiveIndex (children, activeKey) { | ||||
|   const c = toArray(children) | ||||
|   for (let i = 0; i < c.length; i++) { | ||||
|     const pKey = c[i].pKey || c[i].componentOptions.propsData.pKey | ||||
|     if (pKey === activeKey) { | ||||
|       return i | ||||
|     } | ||||
|   } | ||||
|   return -1 | ||||
| } | ||||
| 
 | ||||
| export function getActiveKey (children, index) { | ||||
|   const c = toArray(children) | ||||
|   return c[index].pKey | ||||
| } | ||||
| 
 | ||||
| export function setTransform (style, v) { | ||||
|   style.transform = v | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou