update: [tooltip] more API supported
							parent
							
								
									3f09f3f6dc
								
							
						
					
					
						commit
						d79ac1e85d
					
				|  | @ -2,19 +2,37 @@ | |||
|   <div> | ||||
|     <tool-tip | ||||
|       placement="top" | ||||
|       :title="showText"> | ||||
|       <h1 @click="boom" style="display: inline-block">This is just a test, put your cursor here</h1> | ||||
|       :title="showText" | ||||
|       :autoAdjustOverflow="autoAdjustOverflow" | ||||
|     > | ||||
|       <h1 @click="boom" class="test">撞到边缘翻转位置 & 点击更新</h1> | ||||
|     </tool-tip> | ||||
|     <ant-button>{{showText}}</ant-button> | ||||
|     <ant-button @click="reverse" type="primary">{{autoAdjustOverflow ? '启用' : '关闭'}}自动调整中</ant-button> | ||||
|     <div class="box"> | ||||
|       <h2>切换arrowPointAtCenter模式</h2> | ||||
|       <ant-button @click="change">{{arrowPointAtCenter}}</ant-button> | ||||
|       <table> | ||||
|         <tr v-for="(tr, index) in table" :key="index"> | ||||
|           <td v-for="(td, i) in tr" :key="i"> | ||||
|             <tool-tip v-if="td" :placement="td" :title="td"><AntButton type="primary">{{td}}</AntButton></tool-tip> | ||||
|             <tool-tip | ||||
|               v-if="td" | ||||
|               :placement="td" | ||||
|               :title="td" | ||||
|               :arrowPointAtCenter="arrowPointAtCenter" | ||||
|             > | ||||
|               <AntButton type="primary">{{td}}</AntButton> | ||||
|             </tool-tip> | ||||
|           </td> | ||||
|         </tr> | ||||
|       </table> | ||||
|     </div> | ||||
|     <div> | ||||
|       <p> | ||||
|         <tool-tip :arrowPointAtCenter="true" title="Consider using the NamedModulesPlugin for module names." placement="topLeft"> | ||||
|           <ant-button>arrowPointAtCenter arrowPointAtCenter arrowPointAtCenter</ant-button> | ||||
|         </tool-tip> | ||||
|       </p> | ||||
|     </div> | ||||
|   </div> | ||||
| </template> | ||||
| 
 | ||||
|  | @ -33,7 +51,9 @@ | |||
|           ['left', '', '', '', 'right'], | ||||
|           ['leftBottom', '', '', '', 'rightBottom'], | ||||
|           ['', 'bottomLeft', 'bottom', 'bottomRight', ''], | ||||
|         ] | ||||
|         ], | ||||
|         arrowPointAtCenter: false, | ||||
|         autoAdjustOverflow: true, | ||||
|       } | ||||
| 		}, | ||||
|     methods: { | ||||
|  | @ -43,6 +63,12 @@ | |||
|         } else { | ||||
| 		      this.showText += ' ' | ||||
|         } | ||||
|       }, | ||||
|       change() { | ||||
| 		    this.arrowPointAtCenter = !this.arrowPointAtCenter | ||||
|       }, | ||||
|       reverse() { | ||||
| 		    this.autoAdjustOverflow = !this.autoAdjustOverflow | ||||
|       } | ||||
|     }, | ||||
|     components: { | ||||
|  | @ -52,6 +78,10 @@ | |||
| 	} | ||||
| </script> | ||||
| <style scoped lang="less"> | ||||
|   .test { | ||||
|     margin: 20px; | ||||
|     display: inline-block; | ||||
|   } | ||||
|   .box { | ||||
|     margin: 100px; | ||||
|   } | ||||
|  |  | |||
|  | @ -34,6 +34,8 @@ export default { | |||
|       left: 0, | ||||
|       top: 0, | ||||
|       realPlacement: this.placement, | ||||
|       t1: null, | ||||
|       t2: null, | ||||
|     } | ||||
|   }, | ||||
|   computed: { | ||||
|  | @ -72,13 +74,30 @@ export default { | |||
|             top: 0, | ||||
|           } | ||||
|         }, | ||||
|         methods: { | ||||
|           hideSelf(e) { | ||||
|             if (that.t1) { | ||||
|               clearTimeout(that.t1) | ||||
|               that.t1 = null | ||||
|             } | ||||
|             if (that.mouseLeaveDelay) { | ||||
|               that.t2 = window.setTimeout(() => { | ||||
|                 if (e.relatedTarget === that.$el) { | ||||
|                   return | ||||
|                 } | ||||
|                 that.visible = false | ||||
|               }, +that.mouseLeaveDelay * 1e3) | ||||
|             } | ||||
|           } | ||||
|         }, | ||||
|         render(h) { | ||||
|           return ( | ||||
|             <transition name="zoom-big"> | ||||
|             <transition name={that.transitionName}> | ||||
|               <div | ||||
|                 v-show={that.visible} | ||||
|                 class={`ant-tooltip ant-tooltip-placement-${that.realPlacement}`} | ||||
|                 style={{ left: this.left + 'px', top: this.top + 'px' }} | ||||
|                 onMouseleave={this.hideSelf} | ||||
|               > | ||||
|                 <div class="ant-tooltip-content"> | ||||
|                   <div class="ant-tooltip-arrow"/> | ||||
|  | @ -98,25 +117,25 @@ export default { | |||
|     }, | ||||
|     onPopupAlign: (placement, domNode, target, align) => { | ||||
|       if (!placement) { | ||||
|         return; | ||||
|         return | ||||
|       } | ||||
|       // 根据当前坐标设置动画点 | ||||
|       const rect = domNode.getBoundingClientRect() | ||||
|       const transformOrigin = { | ||||
|         top: '50%', | ||||
|         left: '50%', | ||||
|       }; | ||||
|       } | ||||
|       if (placement.indexOf('top') >= 0 || placement.indexOf('Bottom') >= 0) { | ||||
|         transformOrigin.top = `${rect.height - align.offset[1]}px`; | ||||
|         transformOrigin.top = `${rect.height - align.offset[1]}px` | ||||
|       } else if (placement.indexOf('Top') >= 0 || placement.indexOf('bottom') >= 0) { | ||||
|         transformOrigin.top = `${-align.offset[1]}px`; | ||||
|         transformOrigin.top = `${-align.offset[1]}px` | ||||
|       } | ||||
|       if (placement.indexOf('left') >= 0 || placement.indexOf('Right') >= 0) { | ||||
|         transformOrigin.left = `${rect.width - align.offset[0]}px`; | ||||
|         transformOrigin.left = `${rect.width - align.offset[0]}px` | ||||
|       } else if (placement.indexOf('right') >= 0 || placement.indexOf('Left') >= 0) { | ||||
|         transformOrigin.left = `${-align.offset[0]}px`; | ||||
|         transformOrigin.left = `${-align.offset[0]}px` | ||||
|       } | ||||
|       target.style.transformOrigin = `${transformOrigin.left} ${transformOrigin.top}`; | ||||
|       target.style.transformOrigin = `${transformOrigin.left} ${transformOrigin.top}` | ||||
|     }, | ||||
|     addEventHandle(old, fn) { | ||||
|       if (!old) { | ||||
|  | @ -127,29 +146,36 @@ export default { | |||
|         return old === fn ? old : [old, fn] | ||||
|       } | ||||
|     }, | ||||
|     computeOffset(popup, text, placement) { | ||||
|     computeOffset(popup, text, placement, scale) { | ||||
|       let { width, height, top, left } = text | ||||
|       //  you cant change the properties of DOMRect | ||||
|       top += window.scrollY | ||||
|       left += window.scrollX | ||||
|       // FIXME: we can get the numbers from scale, but that's not what we really want | ||||
|       const p = { width: popup.width / scale, height: popup.height / scale } | ||||
|       const ret = { left, top } | ||||
| 
 | ||||
|       if (/top/.test(placement)) ret.top -= popup.height + 5 | ||||
|       if (/bottom/.test(placement)) ret.top += height + 5 | ||||
|       if (/left/.test(placement)) ret.left -= popup.width + 10 | ||||
|       if (/right/.test(placement)) ret.left += width + 5 | ||||
|       if (/top/.test(placement)) ret.top -= p.height | ||||
|       if (/bottom/.test(placement)) ret.top += height | ||||
|       if (/left/.test(placement)) ret.left -= p.width | ||||
|       if (/right/.test(placement)) ret.left += width | ||||
| 
 | ||||
|       // FIXME: magic number 20 & 14 comes from the offset of triangle | ||||
|       if (/Left/.test(placement)) { | ||||
|         if (this.arrowPointAtCenter) ret.left += width / 2 - 20 | ||||
|       } else if(/Right/.test(placement)) { | ||||
|         ret.left += (width - popup.width) | ||||
|         ret.left += (width - p.width) | ||||
|         if (this.arrowPointAtCenter) ret.left -= width / 2 - 20 | ||||
|       } else if(/(top)|(bottom)/.test(placement)) { | ||||
|         ret.left += (width - popup.width) / 2 | ||||
|         ret.left += (width - p.width) / 2 | ||||
|       } | ||||
|       if (/Top/.test(placement)) { | ||||
|         if (this.arrowPointAtCenter) ret.top += height / 2 - 14 | ||||
|       } else if(/Bottom/.test(placement)) { | ||||
|         ret.top += (height - popup.height) | ||||
|         ret.top += (height - p.height) | ||||
|         if (this.arrowPointAtCenter) ret.top -= height / 2 - 14 | ||||
|       } else if(/(left)|(right)/.test(placement)) { | ||||
|         ret.top += (height - popup.height) / 2 | ||||
|         ret.top += (height - p.height) / 2 | ||||
|       } | ||||
|       return ret | ||||
|     }, | ||||
|  | @ -158,41 +184,69 @@ export default { | |||
|         this.visible = true | ||||
|         this.$nextTick(() => { | ||||
|           const popup = this.vnode.$el.getBoundingClientRect() | ||||
|           const [, scale = 1] = window.getComputedStyle(this.vnode.$el).transform.match(/matrix\((.*?),/) || [] | ||||
|           const content = this.$el.getBoundingClientRect() | ||||
|           const place = this.checkPosition(popup, content, this.placement) | ||||
|           const place = this.autoAdjustOverflow ? this.checkPosition(popup, content, this.placement, scale) : this.placement | ||||
|           this.realPlacement = place | ||||
|           const { left, top } = this.computeOffset(popup, content, place) | ||||
|           const { left, top } = this.computeOffset(popup, content, place, scale) | ||||
|           this.vnode.left = left | ||||
|           this.vnode.top = top | ||||
|         }) | ||||
|         this.onPopupAlign(this.realPlacement, this.$el, this.vnode.$el, { offset: [0,0] }) | ||||
|       }) | ||||
|     }, | ||||
|     hideNode() { | ||||
|     hideNode(e) { | ||||
|       if (!this.vnode) return | ||||
|       if (e.relatedTarget === this.vnode.$el) { | ||||
|         return | ||||
|       } | ||||
|       this.visible = false | ||||
|     }, | ||||
|     checkShow(e) { | ||||
|       if (this.t2) { | ||||
|         clearTimeout(this.t2) | ||||
|         this.t2 = null | ||||
|       } | ||||
|       if (this.mouseEnterDelay) { | ||||
|         this.t1 = window.setTimeout(() => { | ||||
|           this.showNode(e) | ||||
|         }, +this.mouseEnterDelay * 1e3) | ||||
|       } | ||||
|     }, | ||||
|     checkHide(e) { | ||||
|       if (this.t1) { | ||||
|         clearTimeout(this.t1) | ||||
|         this.t1 = null | ||||
|       } | ||||
|       if (this.mouseLeaveDelay) { | ||||
|         this.t2 = window.setTimeout(() => { | ||||
|           this.hideNode(e) | ||||
|         }, +this.mouseLeaveDelay * 1e3) | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   render(h) { | ||||
|     const inner = this.$slots.default[0] | ||||
|     inner.data = inner.data || {} | ||||
|     inner.data.on = inner.data.on || {} | ||||
|     inner.data.on.mouseenter = this.addEventHandle(inner.data.on.mouseenter, this.showNode) | ||||
|     inner.data.on.mouseleave = this.addEventHandle(inner.data.on.mouseleave, this.hideNode) | ||||
|     inner.data.on.mouseenter = this.addEventHandle(inner.data.on.mouseenter, this.checkShow) | ||||
|     inner.data.on.mouseleave = this.addEventHandle(inner.data.on.mouseleave, this.checkHide) | ||||
| 
 | ||||
|     return this.$slots.default[0] | ||||
|   }, | ||||
|   updated() { | ||||
|     if (!this.vnode) return | ||||
|     const popup = this.vnode.$el.getBoundingClientRect() | ||||
|     const [, scale = 1] = window.getComputedStyle(this.vnode.$el).transform.match(/matrix\((.*?),/) || [] | ||||
|     const content = this.$el.getBoundingClientRect() | ||||
|     const { left, top } = this.computeOffset(popup, content, this.realPlacement) | ||||
|     const { left, top } = this.computeOffset(popup, content, this.realPlacement, scale) | ||||
|     this.vnode.left = left | ||||
|     this.vnode.top = top | ||||
|   }, | ||||
|   beforeDestroy() { | ||||
|     if (!this.vnode) return | ||||
|     this.vnode.$el.remove() | ||||
|     this.vnode.$destroy(); | ||||
|     this.vnode.$destroy() | ||||
|   } | ||||
| } | ||||
| </script> | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 wanlei
						wanlei