fix
							parent
							
								
									2e07f98d40
								
							
						
					
					
						commit
						b9fe970682
					
				|  | @ -1,12 +1,13 @@ | ||||||
|  | import clonedeep from 'lodash.clonedeep' | ||||||
| export function cloneVNode (vnode, deep) { | export function cloneVNode (vnode, deep) { | ||||||
|   const cloned = new vnode.constructor( |   const cloned = new vnode.constructor( | ||||||
|     vnode.tag, |     vnode.tag, | ||||||
|     vnode.data, |     clonedeep(vnode.data), | ||||||
|     vnode.children, |     vnode.children, | ||||||
|     vnode.text, |     vnode.text, | ||||||
|     vnode.elm, |     vnode.elm, | ||||||
|     vnode.context, |     vnode.context, | ||||||
|     vnode.componentOptions, |     clonedeep(vnode.componentOptions), | ||||||
|     vnode.asyncFactory |     vnode.asyncFactory | ||||||
|   ) |   ) | ||||||
|   cloned.ns = vnode.ns |   cloned.ns = vnode.ns | ||||||
|  | @ -30,7 +31,7 @@ export function cloneVNodes (vnodes, deep) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export function cloneElement (node, nodeProps) { | export function cloneElement (node, nodeProps) { | ||||||
|   const { props, key, ref } = nodeProps |   const { props, key } = nodeProps | ||||||
|   if (node.componentOptions) { |   if (node.componentOptions) { | ||||||
|     Object.assign(node.componentOptions.propsData, props) |     Object.assign(node.componentOptions.propsData, props) | ||||||
|   } |   } | ||||||
|  | @ -40,7 +41,7 @@ export function cloneElement (node, nodeProps) { | ||||||
|     attrs = data.attrs, |     attrs = data.attrs, | ||||||
|     on = data.on, |     on = data.on, | ||||||
|   } = nodeProps |   } = nodeProps | ||||||
|   Object.assign(node.data, { style, attrs, class: cls, on }) |   node.data = Object.assign(data, { style, attrs, class: cls, on }) | ||||||
|   if (key !== undefined) { |   if (key !== undefined) { | ||||||
|     node.key = key |     node.key = key | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  | @ -1,11 +1,14 @@ | ||||||
| import warning from 'warning' | import warning from 'warning' | ||||||
| 
 | 
 | ||||||
| const warned = {} | const warned = {} | ||||||
| export default (valid, message) => { | export default (valid, message, throwError) => { | ||||||
|   if (process.env.NODE_ENV !== 'production') { |   if (process.env.NODE_ENV !== 'production') { | ||||||
|     if (!valid && !warned[message]) { |     if (!valid && !warned[message]) { | ||||||
|       warning(false, message) |       warning(false, message) | ||||||
|       warned[message] = true |       warned[message] = true | ||||||
|  |       if (throwError) { | ||||||
|  |         throw Error(message) | ||||||
|  |       } | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <script> | <script> | ||||||
| import PropTypes from 'vue-types' | import PropTypes from '../_util/vue-types' | ||||||
| import align from 'dom-align' | import align from 'dom-align' | ||||||
| import clonedeep from 'lodash.clonedeep' | import clonedeep from 'lodash.clonedeep' | ||||||
| import addEventListener from '../_util/Dom/addEventListener' | import addEventListener from '../_util/Dom/addEventListener' | ||||||
|  |  | ||||||
|  | @ -39,7 +39,7 @@ export default { | ||||||
|     return ( |     return ( | ||||||
|       <div |       <div | ||||||
|         style={{ |         style={{ | ||||||
|           margin: 50, |           margin: '50px', | ||||||
|         }} |         }} | ||||||
|       > |       > | ||||||
|         <p> |         <p> | ||||||
|  |  | ||||||
|  | @ -43,6 +43,8 @@ export default { | ||||||
|       const { value } = this.$props |       const { value } = this.$props | ||||||
|       if (value === undefined) { |       if (value === undefined) { | ||||||
|         this.stateValue = e.target.value |         this.stateValue = e.target.value | ||||||
|  |         this.$emit('change.value', e.target.value) | ||||||
|  |         this.$emit('change', e) | ||||||
|       } else { |       } else { | ||||||
|         this.$forceUpdate() |         this.$forceUpdate() | ||||||
|         this.$emit('change.value', e.target.value) |         this.$emit('change.value', e.target.value) | ||||||
|  |  | ||||||
|  | @ -209,7 +209,7 @@ | ||||||
| 
 | 
 | ||||||
| // Animation | // Animation | ||||||
| @animation-duration-slow: .3s; // Modal | @animation-duration-slow: .3s; // Modal | ||||||
| @animation-duration-base: .2s; | @animation-duration-base: 20s; | ||||||
| @animation-duration-fast: .1s; // Tooltip | @animation-duration-fast: .1s; // Tooltip | ||||||
| 
 | 
 | ||||||
| // Form | // Form | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <script> | <script> | ||||||
| import PropTypes from 'vue-types' | import PropTypes from '../_util/vue-types' | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|   props: { |   props: { | ||||||
|  |  | ||||||
|  | @ -13,11 +13,18 @@ export default { | ||||||
|     destroyPopupOnHide: PropTypes.bool, |     destroyPopupOnHide: PropTypes.bool, | ||||||
|     prefixCls: PropTypes.string, |     prefixCls: PropTypes.string, | ||||||
|     getContainer: PropTypes.func, |     getContainer: PropTypes.func, | ||||||
|  |     transitionName: PropTypes.string, | ||||||
|  |     animation: PropTypes.any, | ||||||
|  |     maskAnimation: PropTypes.string, | ||||||
|  |     maskTransitionName: PropTypes.string, | ||||||
|  |     mask: PropTypes.bool, | ||||||
|  |     zIndex: PropTypes.number, | ||||||
|   }, |   }, | ||||||
|   mounted () { |   mounted () { | ||||||
|     this.rootNode = this.getPopupDomNode() |     this.rootNode = this.getPopupDomNode() | ||||||
|     this._container = this.getContainer() |     this._container = this.getContainer() | ||||||
|     this._container.appendChild(this.$el) |     // this._container.appendChild(this.$el) | ||||||
|  |     // this.$refs.alignInstance.forceAlign() | ||||||
|   }, |   }, | ||||||
|   beforeDestroy () { |   beforeDestroy () { | ||||||
|     this._container && this._container.parentNode.removeChild(this._container) |     this._container && this._container.parentNode.removeChild(this._container) | ||||||
|  | @ -37,7 +44,7 @@ export default { | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     getPopupDomNode () { |     getPopupDomNode () { | ||||||
|       return this.$refs.popupInstance |       return this.$refs.popupInstance ? this.$refs.popupInstance.$el : null | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     getTarget () { |     getTarget () { | ||||||
|  | @ -60,7 +67,7 @@ export default { | ||||||
|       if (!transitionName && props.animation) { |       if (!transitionName && props.animation) { | ||||||
|         transitionName = `${props.prefixCls}-${props.animation}` |         transitionName = `${props.prefixCls}-${props.animation}` | ||||||
|       } |       } | ||||||
|       return transitionName |       return 'fade' | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|     getClassName (currentAlignClassName) { |     getClassName (currentAlignClassName) { | ||||||
|  | @ -116,16 +123,16 @@ export default { | ||||||
|           </Align>) : null} |           </Align>) : null} | ||||||
|         </transition>) |         </transition>) | ||||||
|       } |       } | ||||||
|       popupInnerProps.props.hiddenClassName = hiddenClassName |       popupInnerProps.props.hiddenClassName = 'hiddenClassName' | ||||||
|       return (<transition |       return (<transition | ||||||
|         name={this.getTransitionName()} |         name={this.getTransitionName()} | ||||||
|       > |       > | ||||||
|         <Align |         <Align | ||||||
|  |           v-show={visible} | ||||||
|           target={this.getTarget} |           target={this.getTarget} | ||||||
|           key='popup' |           key='popup' | ||||||
|           ref='alignInstance' |           ref='alignInstance' | ||||||
|           monitorWindowResize |           monitorWindowResize | ||||||
|           childrenProps={{ visible }} |  | ||||||
|           disabled={!visible} |           disabled={!visible} | ||||||
|           align={align} |           align={align} | ||||||
|           onAlign={this.onAlign} |           onAlign={this.onAlign} | ||||||
|  | @ -181,9 +188,20 @@ export default { | ||||||
|       <div> |       <div> | ||||||
|         {this.getMaskElement()} |         {this.getMaskElement()} | ||||||
|         {this.getPopupElement()} |         {this.getPopupElement()} | ||||||
|  |         <transition name='fade'> | ||||||
|  |           <div v-show={this.visible}>hello</div> | ||||||
|  |         </transition> | ||||||
|       </div> |       </div> | ||||||
|     ) |     ) | ||||||
|   }, |   }, | ||||||
|  |   // render () { | ||||||
|  |   //   return ( | ||||||
|  |   //     <transition name='fade'> | ||||||
|  |   //       <div v-show={this.visible}>hello</div> | ||||||
|  |   //     </transition> | ||||||
|  |   //   ) | ||||||
|  |   // }, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| </script> | </script> | ||||||
|  | 
 | ||||||
|  |  | ||||||
|  | @ -1,5 +1,5 @@ | ||||||
| <script> | <script> | ||||||
| import PropTypes from 'vue-types' | import PropTypes from '../_util/vue-types' | ||||||
| import LazyRenderBox from './LazyRenderBox' | import LazyRenderBox from './LazyRenderBox' | ||||||
| 
 | 
 | ||||||
| export default { | export default { | ||||||
|  |  | ||||||
|  | @ -1,5 +1,10 @@ | ||||||
| @triggerPrefixCls: rc-trigger-popup; | @triggerPrefixCls: rc-trigger-popup; | ||||||
| 
 | .fade-enter-active, .fade-leave-active { | ||||||
|  |   transition: opacity 0.5s; | ||||||
|  | } | ||||||
|  | .fade-enter, .fade-leave-to /* .fade-leave-active in below version 2.1.8 */ { | ||||||
|  |   opacity: 0; | ||||||
|  | } | ||||||
| .@{triggerPrefixCls} { | .@{triggerPrefixCls} { | ||||||
|   position: absolute; |   position: absolute; | ||||||
|   left: -9999px; |   left: -9999px; | ||||||
|  |  | ||||||
|  | @ -36,19 +36,49 @@ const popupBorderStyle = { | ||||||
| export default { | export default { | ||||||
|   render () { |   render () { | ||||||
|     return ( |     return ( | ||||||
|       <div> |       <div style={{ margin: '200px' }}> | ||||||
|         <div style={{ margin: '50px' }}> |         <div> | ||||||
|           <Trigger |           <Trigger | ||||||
|             popupPlacement='right' |             popupPlacement='left' | ||||||
|             action={['click']} |             action={['click']} | ||||||
|             builtinPlacements={builtinPlacements} |             builtinPlacements={builtinPlacements} | ||||||
|  |           > | ||||||
|  |             <div slot='popup' style={popupBorderStyle}>i am a click popup</div> | ||||||
|  |             <span> | ||||||
|  |               <div ref='saveContainerRef1' /> | ||||||
|  |               <Trigger | ||||||
|  |                 popupPlacement='bottom' | ||||||
|  |                 action={['hover']} | ||||||
|  |                 builtinPlacements={builtinPlacements} | ||||||
|  |                 getPopupContainer={() => this.$refs.saveContainerRef1} | ||||||
|  |               > | ||||||
|  |                 <div slot='popup' style={popupBorderStyle}>i am a hover popup</div> | ||||||
|  |                 <span href='#' style={{ margin: '20px' }}>trigger</span> | ||||||
|  |               </Trigger> | ||||||
|  |             </span> | ||||||
|  |           </Trigger> | ||||||
|  |         </div> | ||||||
|  |         { false ? <div style={{ margin: '50px' }}> | ||||||
|  |           <Trigger | ||||||
|  |             popupPlacement='right' | ||||||
|  |             action={['click', 'hover']} | ||||||
|  |             builtinPlacements={builtinPlacements} | ||||||
|           > |           > | ||||||
|             <div style={popupBorderStyle} slot='popup' onClick={(e) => { e.stopPropagation() }}> |             <div style={popupBorderStyle} slot='popup' onClick={(e) => { e.stopPropagation() }}> | ||||||
|               jjj |               <div ref='saveContainerRef' /> | ||||||
|  |               <Trigger | ||||||
|  |                 popupPlacement='bottom' | ||||||
|  |                 action={['click']} | ||||||
|  |                 builtinPlacements={builtinPlacements} | ||||||
|  |                 getPopupContainer={() => this.$refs.saveContainerRef} | ||||||
|  |               > | ||||||
|  |                 <div slot='popup' style={popupBorderStyle}>I am inner Trigger Popup</div> | ||||||
|  |                 <span href='#' style={{ margin: 20 }}>clickToShowInnerTrigger</span> | ||||||
|  |               </Trigger> | ||||||
|             </div> |             </div> | ||||||
|             <span href='#' style={{ margin: '20px' }} onClick={console.log}>trigger</span> |             <span href='#' style={{ margin: '20px' }} onClick={console.log}>trigger</span> | ||||||
|           </Trigger> |           </Trigger> | ||||||
|         </div> |         </div> : null} | ||||||
|       </div> |       </div> | ||||||
|     ) |     ) | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
|  | @ -0,0 +1,279 @@ | ||||||
|  | <script> | ||||||
|  | import Trigger from '../index' | ||||||
|  | import '../assets/index.less' | ||||||
|  | import { Input, Button, Checkbox } from 'antd' | ||||||
|  | function getPopupAlign (state) { | ||||||
|  |   return { | ||||||
|  |     offset: [state.offsetX, state.offsetY], | ||||||
|  |     overflow: { | ||||||
|  |       adjustX: 1, | ||||||
|  |       adjustY: 1, | ||||||
|  |     }, | ||||||
|  |   } | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const builtinPlacements = { | ||||||
|  |   left: { | ||||||
|  |     points: ['cr', 'cl'], | ||||||
|  |   }, | ||||||
|  |   right: { | ||||||
|  |     points: ['cl', 'cr'], | ||||||
|  |   }, | ||||||
|  |   top: { | ||||||
|  |     points: ['bc', 'tc'], | ||||||
|  |   }, | ||||||
|  |   bottom: { | ||||||
|  |     points: ['tc', 'bc'], | ||||||
|  |   }, | ||||||
|  |   topLeft: { | ||||||
|  |     points: ['bl', 'tl'], | ||||||
|  |   }, | ||||||
|  |   topRight: { | ||||||
|  |     points: ['br', 'tr'], | ||||||
|  |   }, | ||||||
|  |   bottomRight: { | ||||||
|  |     points: ['tr', 'br'], | ||||||
|  |   }, | ||||||
|  |   bottomLeft: { | ||||||
|  |     points: ['tl', 'bl'], | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function preventDefault (e) { | ||||||
|  |   e.preventDefault() | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | function getPopupContainer (trigger) { | ||||||
|  |   return trigger.parentNode | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | export default { | ||||||
|  |   data () { | ||||||
|  |     return { | ||||||
|  |       mask: false, | ||||||
|  |       maskClosable: false, | ||||||
|  |       placement: 'right', | ||||||
|  |       trigger: { | ||||||
|  |         hover: 1, | ||||||
|  |       }, | ||||||
|  |       offsetX: undefined, | ||||||
|  |       offsetY: undefined, | ||||||
|  |       transitionName: '', | ||||||
|  |       destroyPopupOnHide: false, | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  |   methods: { | ||||||
|  |     setState (state, callback) { | ||||||
|  |       Object.assign(this.$data, state) | ||||||
|  |       this.$nextTick(() => { | ||||||
|  |         callback && callback() | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |     onPlacementChange (e) { | ||||||
|  |       this.setState({ | ||||||
|  |         placement: e.target.value, | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     onTransitionChange (e) { | ||||||
|  |       this.setState({ | ||||||
|  |         transitionName: e.target.checked ? e.target.value : '', | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     onTriggerChange (e) { | ||||||
|  |       const trigger = Object.assign({}, this.$data.trigger) | ||||||
|  |       if (e.target.checked) { | ||||||
|  |         trigger[e.target.value] = 1 | ||||||
|  |       } else { | ||||||
|  |         delete trigger[e.target.value] | ||||||
|  |       } | ||||||
|  |       this.setState({ | ||||||
|  |         trigger, | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     onOffsetXChange (e) { | ||||||
|  |       const targetValue = e.target.value | ||||||
|  |       this.setState({ | ||||||
|  |         offsetX: targetValue || undefined, | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     onOffsetYChange (e) { | ||||||
|  |       const targetValue = e.target.value | ||||||
|  |       this.setState({ | ||||||
|  |         offsetY: targetValue || undefined, | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     onVisibleChange (visible) { | ||||||
|  |       console.log('tooltip', visible) | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     onMask (e) { | ||||||
|  |       this.setState({ | ||||||
|  |         mask: e.target.checked, | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     onMaskClosable (e) { | ||||||
|  |       this.setState({ | ||||||
|  |         maskClosable: e.target.checked, | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     destroy () { | ||||||
|  |       this.setState({ | ||||||
|  |         destroyed: true, | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  | 
 | ||||||
|  |     handleDestroyPopupOnHide (e) { | ||||||
|  |       this.setState({ | ||||||
|  |         destroyPopupOnHide: e.target.checked, | ||||||
|  |       }) | ||||||
|  |     }, | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   render () { | ||||||
|  |     const state = this.$data | ||||||
|  |     const trigger = state.trigger | ||||||
|  |     if (state.destroyed) { | ||||||
|  |       return null | ||||||
|  |     } | ||||||
|  |     return (<div > | ||||||
|  |       <div style={{ margin: '10px 20px' }}> | ||||||
|  |         <label> | ||||||
|  |           placement: | ||||||
|  |           <select value={state.placement} onChange={this.onPlacementChange}> | ||||||
|  |             <option>right</option> | ||||||
|  |             <option>left</option> | ||||||
|  |             <option>top</option> | ||||||
|  |             <option>bottom</option> | ||||||
|  |             <option>topLeft</option> | ||||||
|  |             <option>topRight</option> | ||||||
|  |             <option>bottomRight</option> | ||||||
|  |             <option>bottomLeft</option> | ||||||
|  |           </select> | ||||||
|  |         </label> | ||||||
|  |              | ||||||
|  |         <label> | ||||||
|  |           <Checkbox | ||||||
|  |             value='rc-trigger-popup-zoom' | ||||||
|  |             onChange={this.onTransitionChange} | ||||||
|  |             checked={state.transitionName === 'rc-trigger-popup-zoom'} | ||||||
|  |           /> | ||||||
|  |           transitionName | ||||||
|  |         </label> | ||||||
|  | 
 | ||||||
|  |              | ||||||
|  | 
 | ||||||
|  |         trigger: | ||||||
|  | 
 | ||||||
|  |         <label> | ||||||
|  |           <Checkbox | ||||||
|  |             value='hover' | ||||||
|  |             checked={!!trigger.hover} | ||||||
|  |             onChange={this.onTriggerChange} | ||||||
|  |           /> | ||||||
|  |           hover | ||||||
|  |         </label> | ||||||
|  |         <label> | ||||||
|  |           <Checkbox | ||||||
|  |             value='focus' | ||||||
|  |             checked={!!trigger.focus} | ||||||
|  |             onChange={this.onTriggerChange} | ||||||
|  |           /> | ||||||
|  |           focus | ||||||
|  |         </label> | ||||||
|  |         <label> | ||||||
|  |           <Checkbox | ||||||
|  |             value='click' | ||||||
|  |             checked={!!trigger.click} | ||||||
|  |             onChange={this.onTriggerChange} | ||||||
|  |           /> | ||||||
|  |           click | ||||||
|  |         </label> | ||||||
|  |         <label> | ||||||
|  |           <Checkbox | ||||||
|  |             value='contextMenu' | ||||||
|  |             checked={!!trigger.contextMenu} | ||||||
|  |             onChange={this.onTriggerChange} | ||||||
|  |           /> | ||||||
|  |           contextMenu | ||||||
|  |         </label> | ||||||
|  |              | ||||||
|  |         <label> | ||||||
|  |           <Checkbox | ||||||
|  |             checked={!!state.destroyPopupOnHide} | ||||||
|  |             onChange={this.handleDestroyPopupOnHide} | ||||||
|  |           /> | ||||||
|  |           destroyPopupOnHide | ||||||
|  |         </label> | ||||||
|  | 
 | ||||||
|  |              | ||||||
|  |         <label> | ||||||
|  |           <Checkbox | ||||||
|  |             checked={!!state.mask} | ||||||
|  |             onChange={this.onMask} | ||||||
|  |           /> | ||||||
|  |           mask | ||||||
|  |         </label> | ||||||
|  | 
 | ||||||
|  |              | ||||||
|  |         <label> | ||||||
|  |           <Checkbox | ||||||
|  |             checked={!!state.maskClosable} | ||||||
|  |             onChange={this.onMaskClosable} | ||||||
|  |           /> | ||||||
|  |           maskClosable | ||||||
|  |         </label> | ||||||
|  | 
 | ||||||
|  |         <br /> | ||||||
|  |         <label> | ||||||
|  |           offsetX: | ||||||
|  |           <Input | ||||||
|  |             type='text' | ||||||
|  |             onChange={this.onOffsetXChange} | ||||||
|  |             style={{ width: '50px' }} | ||||||
|  |           /> | ||||||
|  |         </label> | ||||||
|  |              | ||||||
|  |         <label> | ||||||
|  |           offsetY: | ||||||
|  |           <Input | ||||||
|  |             type='text' | ||||||
|  |             onChange={this.onOffsetYChange} | ||||||
|  |             style={{ width: '50px' }} | ||||||
|  |           /> | ||||||
|  |         </label> | ||||||
|  |              | ||||||
|  |         <Button onClick={this.destroy}>destroy</Button> | ||||||
|  |       </div> | ||||||
|  |       <div style={{ margin: '100px', position: 'relative' }}> | ||||||
|  |         <Trigger | ||||||
|  |           getPopupContainer={undefined && getPopupContainer} | ||||||
|  |           popupAlign={getPopupAlign(state)} | ||||||
|  |           popupPlacement={state.placement} | ||||||
|  |           destroyPopupOnHide={state.destroyPopupOnHide} | ||||||
|  |           // zIndex={40} | ||||||
|  |           mask={state.mask} | ||||||
|  |           maskClosable={state.maskClosable} | ||||||
|  |           // maskAnimation="fade" | ||||||
|  |           // mouseEnterDelay={0.1} | ||||||
|  |           // mouseLeaveDelay={0.1} | ||||||
|  |           action={Object.keys(state.trigger)} | ||||||
|  |           builtinPlacements={builtinPlacements} | ||||||
|  |           popupTransitionName={state.transitionName} | ||||||
|  |         > | ||||||
|  |           <div slot='popup' style={{ border: '1px solid red', padding: '10px', background: 'white' }}> | ||||||
|  |               i am a popup | ||||||
|  |           </div> | ||||||
|  |           <a href='#' style={{ margin: '20px' }} onClick={preventDefault}>trigger</a> | ||||||
|  |         </Trigger> | ||||||
|  |       </div> | ||||||
|  |     </div>) | ||||||
|  |   }, | ||||||
|  | } | ||||||
|  | </script> | ||||||
|  | @ -0,0 +1,160 @@ | ||||||
|  | ## API | ||||||
|  | 
 | ||||||
|  | ### props | ||||||
|  | 
 | ||||||
|  | <table class="table table-bordered table-striped"> | ||||||
|  |     <thead> | ||||||
|  |     <tr> | ||||||
|  |         <th style="width: 100px;">name</th> | ||||||
|  |         <th style="width: 50px;">type</th> | ||||||
|  |         <th style="width: 50px;">default</th> | ||||||
|  |         <th>description</th> | ||||||
|  |     </tr> | ||||||
|  |     </thead> | ||||||
|  |     <tbody> | ||||||
|  |         <tr> | ||||||
|  |           <td>popupClassName</td> | ||||||
|  |           <td>string</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>additional className added to popup</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>forceRender</td> | ||||||
|  |           <td>boolean</td> | ||||||
|  |           <td>false</td> | ||||||
|  |           <td>whether render popup before first show</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>destroyPopupOnHide</td> | ||||||
|  |           <td>boolean</td> | ||||||
|  |           <td>false</td> | ||||||
|  |           <td>whether destroy popup when hide</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>getPopupClassNameFromAlign</td> | ||||||
|  |           <td>getPopupClassNameFromAlign(align: Object):String</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>additional className added to popup according to align</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>action</td> | ||||||
|  |           <td>string[]</td> | ||||||
|  |           <td>['hover']</td> | ||||||
|  |           <td>which actions cause popup shown. enum of 'hover','click','focus','contextMenu'</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>mouseEnterDelay</td> | ||||||
|  |           <td>number</td> | ||||||
|  |           <td>0</td> | ||||||
|  |           <td>delay time to show when mouse enter. unit: s.</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>mouseLeaveDelay</td> | ||||||
|  |           <td>number</td> | ||||||
|  |           <td>0.1</td> | ||||||
|  |           <td>delay time to hide when mouse leave. unit: s.</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>popupStyle</td> | ||||||
|  |           <td>Object</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>additional style of popup</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>prefixCls</td> | ||||||
|  |           <td>String</td> | ||||||
|  |           <td>rc-trigger-popup</td> | ||||||
|  |           <td>prefix class name</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>popupTransitionName</td> | ||||||
|  |           <td>String|Object</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>https://github.com/react-component/animate</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>maskTransitionName</td> | ||||||
|  |           <td>String|Object</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>https://github.com/react-component/animate</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>mask</td> | ||||||
|  |           <td>boolean</td> | ||||||
|  |           <td>false</td> | ||||||
|  |           <td>whether to support mask</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>maskClosable</td> | ||||||
|  |           <td>boolean</td> | ||||||
|  |           <td>true</td> | ||||||
|  |           <td>whether to support click mask to hide</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>popupVisible</td> | ||||||
|  |           <td>boolean</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>whether popup is visible</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>zIndex</td> | ||||||
|  |           <td>number</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>popup's zIndex</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>defaultPopupVisible</td> | ||||||
|  |           <td>boolean</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>whether popup is visible initially</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>popupAlign</td> | ||||||
|  |           <td>Object: alignConfig of [dom-align](https://github.com/yiminghe/dom-align)</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>popup 's align config</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>getPopupContainer</td> | ||||||
|  |           <td>getPopupContainer(): HTMLElement</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>function returning html node which will act as popup container</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>getDocument</td> | ||||||
|  |           <td>getDocument(): HTMLElement</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>function returning document node which will be attached click event to close trigger</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>popupPlacement</td> | ||||||
|  |           <td>string</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>use preset popup align config from builtinPlacements, can be merged by popupAlign prop</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>builtinPlacements</td> | ||||||
|  |           <td>object</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>builtin placement align map. used by placement prop</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>popupVisibleChange</td> | ||||||
|  |           <td>$emit(visible)</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>call when popup visible is changed</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>popupAlign</td> | ||||||
|  |           <td>$emit(popupDomNode, align)</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>callback when popup node is aligned</td> | ||||||
|  |         </tr> | ||||||
|  |         <tr> | ||||||
|  |           <td>popup</td> | ||||||
|  |           <td>slot='popup'</td> | ||||||
|  |           <td></td> | ||||||
|  |           <td>popup content</td> | ||||||
|  |         </tr> | ||||||
|  |     </tbody> | ||||||
|  | </table> | ||||||
|  | @ -2,11 +2,11 @@ | ||||||
| import PropTypes from '../_util/vue-types' | import PropTypes from '../_util/vue-types' | ||||||
| import contains from '../_util/Dom/contains' | import contains from '../_util/Dom/contains' | ||||||
| import addEventListener from '../_util/Dom/addEventListener' | import addEventListener from '../_util/Dom/addEventListener' | ||||||
|  | import warning from '../_util/warning' | ||||||
| import Popup from './Popup' | import Popup from './Popup' | ||||||
| import { getAlignFromPlacement, getPopupClassNameFromAlign } from './utils' | import { getAlignFromPlacement, getPopupClassNameFromAlign } from './utils' | ||||||
| import getContainerRenderMixin from '../_util/getContainerRenderMixin' |  | ||||||
| import StateMixin from '../_util/StateMixin' | import StateMixin from '../_util/StateMixin' | ||||||
| import { cloneElement } from '../_util/vnode' | import { cloneElement, cloneVNode } from '../_util/vnode' | ||||||
| 
 | 
 | ||||||
| function returnEmptyString () { | function returnEmptyString () { | ||||||
|   return '' |   return '' | ||||||
|  | @ -19,26 +19,6 @@ function returnDocument () { | ||||||
| const ALL_HANDLERS = ['click', 'mousedown', 'touchStart', 'mouseenter', | const ALL_HANDLERS = ['click', 'mousedown', 'touchStart', 'mouseenter', | ||||||
|   'mouseleave', 'focus', 'blur', 'contextMenu'] |   'mouseleave', 'focus', 'blur', 'contextMenu'] | ||||||
| 
 | 
 | ||||||
| const mixins = [] |  | ||||||
| 
 |  | ||||||
| mixins.push( |  | ||||||
|   getContainerRenderMixin({ |  | ||||||
|     autoMount: false, |  | ||||||
| 
 |  | ||||||
|     isVisible (instance) { |  | ||||||
|       return instance.$data.sPopupVisible |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     isForceRender (instance) { |  | ||||||
|       return instance.$props.forceRender |  | ||||||
|     }, |  | ||||||
| 
 |  | ||||||
|     getContainer (instance) { |  | ||||||
|       return instance.getContainer() |  | ||||||
|     }, |  | ||||||
|   }) |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| export default { | export default { | ||||||
|   name: 'Trigger', |   name: 'Trigger', | ||||||
|   props: { |   props: { | ||||||
|  | @ -65,7 +45,7 @@ export default { | ||||||
|     zIndex: PropTypes.number, |     zIndex: PropTypes.number, | ||||||
|     focusDelay: PropTypes.number.def(0), |     focusDelay: PropTypes.number.def(0), | ||||||
|     blurDelay: PropTypes.number.def(0.15), |     blurDelay: PropTypes.number.def(0.15), | ||||||
|     getPopupContainer: Function, |     getPopupContainer: PropTypes.func, | ||||||
|     getDocument: PropTypes.func.def(returnDocument), |     getDocument: PropTypes.func.def(returnDocument), | ||||||
|     forceRender: PropTypes.bool, |     forceRender: PropTypes.bool, | ||||||
|     destroyPopupOnHide: PropTypes.bool.def(false), |     destroyPopupOnHide: PropTypes.bool.def(false), | ||||||
|  | @ -74,15 +54,15 @@ export default { | ||||||
|     // onPopupAlign: PropTypes.func, |     // onPopupAlign: PropTypes.func, | ||||||
|     popupAlign: PropTypes.object.def({}), |     popupAlign: PropTypes.object.def({}), | ||||||
|     popupVisible: PropTypes.bool, |     popupVisible: PropTypes.bool, | ||||||
|     // defaultPopupVisible: PropTypes.bool.def(false), |     defaultPopupVisible: PropTypes.bool.def(false), | ||||||
|     // maskTransitionName: PropTypes.oneOfType([ |     maskTransitionName: PropTypes.oneOfType([ | ||||||
|     //   PropTypes.string, |       PropTypes.string, | ||||||
|     //   PropTypes.object, |       PropTypes.object, | ||||||
|     // ]), |     ]), | ||||||
|     // maskAnimation: PropTypes.string, |     maskAnimation: PropTypes.string, | ||||||
|   }, |   }, | ||||||
| 
 | 
 | ||||||
|   mixins: [StateMixin, ...mixins], |   mixins: [StateMixin], | ||||||
|   data () { |   data () { | ||||||
|     const props = this.$props |     const props = this.$props | ||||||
|     let popupVisible |     let popupVisible | ||||||
|  | @ -184,9 +164,9 @@ export default { | ||||||
| 
 | 
 | ||||||
|     onPopupMouseleave (e) { |     onPopupMouseleave (e) { | ||||||
|       if (e.relatedTarget && !e.relatedTarget.setTimeout && |       if (e.relatedTarget && !e.relatedTarget.setTimeout && | ||||||
|       this._component && |       this.$refs.popup && | ||||||
|       this._component.getPopupDomNode && |       this.$refs.popup.getPopupDomNode && | ||||||
|       contains(this._component.getPopupDomNode(), e.relatedTarget)) { |       contains(this.$refs.popup.getPopupDomNode(), e.relatedTarget)) { | ||||||
|         return |         return | ||||||
|       } |       } | ||||||
|       this.delaySetPopupVisible(false, this.$props.mouseLeaveDelay) |       this.delaySetPopupVisible(false, this.$props.mouseLeaveDelay) | ||||||
|  | @ -271,8 +251,8 @@ export default { | ||||||
|     }, |     }, | ||||||
|     getPopupDomNode () { |     getPopupDomNode () { | ||||||
|     // for test |     // for test | ||||||
|       if (this._component && this._component.getPopupDomNode) { |       if (this.$refs.popup && this.$refs.popup.getPopupDomNode) { | ||||||
|         return this._component.getPopupDomNode() |         return this.$refs.popup.getPopupDomNode() | ||||||
|       } |       } | ||||||
|       return null |       return null | ||||||
|     }, |     }, | ||||||
|  | @ -426,15 +406,17 @@ export default { | ||||||
| 
 | 
 | ||||||
|     createTwoChains (event) { |     createTwoChains (event) { | ||||||
|       const child = this.$slots.default[0] |       const child = this.$slots.default[0] | ||||||
|       let fn = () => {} |       let fn = () => { | ||||||
|       if (child && child.data && child.data.on) { |         console.log('event', event) | ||||||
|         const childEvents = child.data.on |  | ||||||
|         const events = (this.data ? this.data.on : {}) || {} |  | ||||||
|         if (childEvents[event] && events[event]) { |  | ||||||
|           return this[`fire${event}`] |  | ||||||
|         } |  | ||||||
|         fn = childEvents[event] || events[event] || fn |  | ||||||
|       } |       } | ||||||
|  |       child.data = child.data || {} | ||||||
|  |       child.data.on = child.data.on || {} | ||||||
|  |       const childEvents = child.data.on | ||||||
|  |       const events = (this.data ? this.data.on : {}) || {} | ||||||
|  |       if (childEvents[event] && events[event]) { | ||||||
|  |         return this[`fire${event}`] | ||||||
|  |       } | ||||||
|  |       fn = childEvents[event] || events[event] || fn | ||||||
|       return fn |       return fn | ||||||
|     }, |     }, | ||||||
| 
 | 
 | ||||||
|  | @ -473,14 +455,15 @@ export default { | ||||||
|       return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1 |       return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1 | ||||||
|     }, |     }, | ||||||
|     forcePopupAlign () { |     forcePopupAlign () { | ||||||
|       if (this.$data.sPopupVisible && this._component && this._component.$refs.alignInstance) { |       if (this.$data.sPopupVisible && this.$refs.popup && this.$refs.popup.$refs.alignInstance) { | ||||||
|         this._component.$refs.alignInstance.forceAlign() |         this.$refs.popup.$refs.alignInstance.forceAlign() | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|     fireEvents (type, e) { |     fireEvents (type, e) { | ||||||
|       const child = this.$slots.default[0] |       const child = this.$slots.default[0] | ||||||
|       if (child && child.data && child.on && child.on[type]) { |       if (child && child.data && child.data.on && child.data.on[type]) { | ||||||
|         child.on[type](e) |         console.log(type, child.data.on[type]) | ||||||
|  |         // child.data.on[type](e) | ||||||
|       } |       } | ||||||
|       if (this.data && this.data.on && this.data.on[type]) { |       if (this.data && this.data.on && this.data.on[type]) { | ||||||
|         this.data.on[type](e) |         this.data.on[type](e) | ||||||
|  | @ -493,6 +476,9 @@ export default { | ||||||
|   }, |   }, | ||||||
|   render () { |   render () { | ||||||
|     const children = this.$slots.default |     const children = this.$slots.default | ||||||
|  |     if (children.length > 1) { | ||||||
|  |       warning(false, 'Trigger $slots.default.length > 1, just support only one default', true) | ||||||
|  |     } | ||||||
|     const child = children[0] |     const child = children[0] | ||||||
|     const newChildProps = { |     const newChildProps = { | ||||||
|       props: {}, |       props: {}, | ||||||
|  | @ -533,12 +519,17 @@ export default { | ||||||
|       newChildProps.on.blur = this.createTwoChains('blur') |       newChildProps.on.blur = this.createTwoChains('blur') | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     const trigger = cloneElement(child, newChildProps) |     const trigger = cloneElement(cloneVNode(child), newChildProps) | ||||||
| 
 |     const { sPopupVisible, forceRender } = this | ||||||
|  |     if (sPopupVisible || forceRender || this._component) { | ||||||
|  |       this._component = this.getComponent() | ||||||
|  |     } else { | ||||||
|  |       this._component = null | ||||||
|  |     } | ||||||
|     return ( |     return ( | ||||||
|       <span> |       <span> | ||||||
|         {trigger} |         {trigger} | ||||||
|         {this.getComponent()} |         {this._component} | ||||||
|       </span> |       </span> | ||||||
|     ) |     ) | ||||||
|   }, |   }, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	 tangjinzhou
						tangjinzhou