trigger
parent
78d3332bb3
commit
2e07f98d40
|
@ -1,3 +1,4 @@
|
|||
import Vue from 'vue'
|
||||
function defaultGetContainer () {
|
||||
const container = document.createElement('div')
|
||||
document.body.appendChild(container)
|
||||
|
@ -19,7 +20,7 @@ export default function getContainerRenderMixin (config) {
|
|||
mixin = {
|
||||
...mixin,
|
||||
mounted () {
|
||||
this.renderComponent()
|
||||
// this.renderComponent()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -28,7 +29,7 @@ export default function getContainerRenderMixin (config) {
|
|||
mixin = {
|
||||
...mixin,
|
||||
beforeDestroy () {
|
||||
this.removeContainer()
|
||||
// this.removeContainer()
|
||||
},
|
||||
}
|
||||
}
|
||||
|
@ -44,21 +45,29 @@ export default function getContainerRenderMixin (config) {
|
|||
},
|
||||
renderComponent (componentArg) {
|
||||
if (
|
||||
!isVisible || isVisible(this) ||
|
||||
!isVisible || this._component || isVisible(this) ||
|
||||
(isForceRender && isForceRender(this))
|
||||
) {
|
||||
if (!this._container) {
|
||||
this._container = getContainer(this)
|
||||
}
|
||||
this._container.appendChild(this.$el)
|
||||
let component
|
||||
if (this.getComponent) {
|
||||
component = this.getComponent(componentArg)
|
||||
} else {
|
||||
component = getComponent(this, componentArg)
|
||||
}
|
||||
this._component = component
|
||||
const vmC = document.createElement('div')
|
||||
this._container.appendChild(vmC)
|
||||
|
||||
new Vue({
|
||||
el: vmC,
|
||||
render () {
|
||||
return component
|
||||
},
|
||||
})
|
||||
}
|
||||
let component
|
||||
if (this.getComponent) {
|
||||
component = this.getComponent(componentArg)
|
||||
} else {
|
||||
component = getComponent(this, componentArg)
|
||||
}
|
||||
this._component = component
|
||||
},
|
||||
},
|
||||
}
|
||||
|
|
|
@ -30,15 +30,17 @@ export function cloneVNodes (vnodes, deep) {
|
|||
}
|
||||
|
||||
export function cloneElement (node, nodeProps) {
|
||||
const { props, key } = nodeProps
|
||||
const { props, key, ref } = nodeProps
|
||||
if (node.componentOptions) {
|
||||
Object.assign(node.componentOptions.propsData, props)
|
||||
}
|
||||
if (node.data) {
|
||||
const data = node.data
|
||||
const { style = data.style, class: cls = data.class, attrs = data.attrs } = nodeProps
|
||||
Object.assign(node.data, { style, attrs, class: cls })
|
||||
}
|
||||
const data = node.data || {}
|
||||
const { style = data.style,
|
||||
class: cls = data.class,
|
||||
attrs = data.attrs,
|
||||
on = data.on,
|
||||
} = nodeProps
|
||||
Object.assign(node.data, { style, attrs, class: cls, on })
|
||||
if (key !== undefined) {
|
||||
node.key = key
|
||||
}
|
||||
|
|
|
@ -0,0 +1,258 @@
|
|||
import isPlainObject from 'lodash.isplainobject'
|
||||
import { noop, toType, getType, isFunction, validateType, isInteger, isArray, warn } from './utils'
|
||||
|
||||
const VuePropTypes = {
|
||||
|
||||
get any () {
|
||||
return toType('any', {
|
||||
type: null,
|
||||
})
|
||||
},
|
||||
|
||||
get func () {
|
||||
return toType('function', {
|
||||
type: Function,
|
||||
}).def(currentDefaults.func)
|
||||
},
|
||||
|
||||
get bool () {
|
||||
return toType('boolean', {
|
||||
type: Boolean,
|
||||
}).def(currentDefaults.bool)
|
||||
},
|
||||
|
||||
get string () {
|
||||
return toType('string', {
|
||||
type: String,
|
||||
}).def(currentDefaults.string)
|
||||
},
|
||||
|
||||
get number () {
|
||||
return toType('number', {
|
||||
type: Number,
|
||||
}).def(currentDefaults.number)
|
||||
},
|
||||
|
||||
get array () {
|
||||
return toType('array', {
|
||||
type: Array,
|
||||
}).def(currentDefaults.array)
|
||||
},
|
||||
|
||||
get object () {
|
||||
return toType('object', {
|
||||
type: Object,
|
||||
}).def(currentDefaults.object)
|
||||
},
|
||||
|
||||
get integer () {
|
||||
return toType('integer', {
|
||||
type: Number,
|
||||
validator (value) {
|
||||
return isInteger(value)
|
||||
},
|
||||
}).def(currentDefaults.integer)
|
||||
},
|
||||
|
||||
get symbol () {
|
||||
return toType('symbol', {
|
||||
type: null,
|
||||
validator (value) {
|
||||
return typeof value === 'symbol'
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
custom (validatorFn, warnMsg = 'custom validation failed') {
|
||||
if (typeof validatorFn !== 'function') {
|
||||
throw new TypeError('[VueTypes error]: You must provide a function as argument')
|
||||
}
|
||||
|
||||
return toType(validatorFn.name || '<<anonymous function>>', {
|
||||
validator (...args) {
|
||||
const valid = validatorFn(...args)
|
||||
if (!valid) warn(`${this._vueTypes_name} - ${warnMsg}`)
|
||||
return valid
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
oneOf (arr) {
|
||||
if (!isArray(arr)) {
|
||||
throw new TypeError('[VueTypes error]: You must provide an array as argument')
|
||||
}
|
||||
const msg = `oneOf - value should be one of "${arr.join('", "')}"`
|
||||
const allowedTypes = arr.reduce((ret, v) => {
|
||||
if (v !== null && v !== undefined) {
|
||||
ret.indexOf(v.constructor) === -1 && ret.push(v.constructor)
|
||||
}
|
||||
return ret
|
||||
}, [])
|
||||
|
||||
return toType('oneOf', {
|
||||
type: allowedTypes.length > 0 ? allowedTypes : null,
|
||||
validator (value) {
|
||||
const valid = arr.indexOf(value) !== -1
|
||||
if (!valid) warn(msg)
|
||||
return valid
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
instanceOf (instanceConstructor) {
|
||||
return toType('instanceOf', {
|
||||
type: instanceConstructor,
|
||||
})
|
||||
},
|
||||
|
||||
oneOfType (arr) {
|
||||
if (!isArray(arr)) {
|
||||
throw new TypeError('[VueTypes error]: You must provide an array as argument')
|
||||
}
|
||||
|
||||
let hasCustomValidators = false
|
||||
|
||||
const nativeChecks = arr.reduce((ret, type, i) => {
|
||||
if (isPlainObject(type)) {
|
||||
if (type._vueTypes_name === 'oneOf') {
|
||||
return ret.concat(type.type || [])
|
||||
}
|
||||
if (type.type && !isFunction(type.validator)) {
|
||||
if (isArray(type.type)) return ret.concat(type.type)
|
||||
ret.push(type.type)
|
||||
} else if (isFunction(type.validator)) {
|
||||
hasCustomValidators = true
|
||||
}
|
||||
return ret
|
||||
}
|
||||
ret.push(type)
|
||||
return ret
|
||||
}, [])
|
||||
|
||||
if (!hasCustomValidators) {
|
||||
// we got just native objects (ie: Array, Object)
|
||||
// delegate to Vue native prop check
|
||||
return toType('oneOfType', {
|
||||
type: nativeChecks,
|
||||
})
|
||||
}
|
||||
|
||||
const typesStr = arr.map((type) => {
|
||||
if (type && isArray(type.type)) {
|
||||
return type.type.map(getType)
|
||||
}
|
||||
return getType(type)
|
||||
}).reduce((ret, type) => ret.concat(isArray(type) ? type : [type]), []).join('", "')
|
||||
|
||||
return this.custom(function oneOfType (value) {
|
||||
const valid = arr.some((type) => {
|
||||
if (type._vueTypes_name === 'oneOf') {
|
||||
return type.type ? validateType(type.type, value, true) : true
|
||||
}
|
||||
return validateType(type, value, true)
|
||||
})
|
||||
if (!valid) warn(`oneOfType - value type should be one of "${typesStr}"`)
|
||||
return valid
|
||||
})
|
||||
},
|
||||
|
||||
arrayOf (type) {
|
||||
return toType('arrayOf', {
|
||||
type: Array,
|
||||
validator (values) {
|
||||
const valid = values.every((value) => validateType(type, value))
|
||||
if (!valid) warn(`arrayOf - value must be an array of "${getType(type)}"`)
|
||||
return valid
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
objectOf (type) {
|
||||
return toType('objectOf', {
|
||||
type: Object,
|
||||
validator (obj) {
|
||||
const valid = Object.keys(obj).every((key) => validateType(type, obj[key]))
|
||||
if (!valid) warn(`objectOf - value must be an object of "${getType(type)}"`)
|
||||
return valid
|
||||
},
|
||||
})
|
||||
},
|
||||
|
||||
shape (obj) {
|
||||
const keys = Object.keys(obj)
|
||||
const requiredKeys = keys.filter((key) => obj[key] && obj[key].required === true)
|
||||
|
||||
const type = toType('shape', {
|
||||
type: Object,
|
||||
validator (value) {
|
||||
if (!isPlainObject(value)) {
|
||||
return false
|
||||
}
|
||||
const valueKeys = Object.keys(value)
|
||||
|
||||
// check for required keys (if any)
|
||||
if (requiredKeys.length > 0 && requiredKeys.some((req) => valueKeys.indexOf(req) === -1)) {
|
||||
warn(`shape - at least one of required properties "${requiredKeys.join('", "')}" is not present`)
|
||||
return false
|
||||
}
|
||||
|
||||
return valueKeys.every((key) => {
|
||||
if (keys.indexOf(key) === -1) {
|
||||
if (this._vueTypes_isLoose === true) return true
|
||||
warn(`shape - object is missing "${key}" property`)
|
||||
return false
|
||||
}
|
||||
const type = obj[key]
|
||||
return validateType(type, value[key])
|
||||
})
|
||||
},
|
||||
})
|
||||
|
||||
Object.defineProperty(type, '_vueTypes_isLoose', {
|
||||
enumerable: false,
|
||||
writable: true,
|
||||
value: false,
|
||||
})
|
||||
|
||||
Object.defineProperty(type, 'loose', {
|
||||
get () {
|
||||
this._vueTypes_isLoose = true
|
||||
return this
|
||||
},
|
||||
enumerable: false,
|
||||
})
|
||||
|
||||
return type
|
||||
},
|
||||
|
||||
}
|
||||
|
||||
const typeDefaults = () => ({
|
||||
func: undefined,
|
||||
bool: undefined,
|
||||
string: undefined,
|
||||
number: undefined,
|
||||
array: undefined,
|
||||
object: undefined,
|
||||
integer: undefined,
|
||||
})
|
||||
|
||||
let currentDefaults = typeDefaults()
|
||||
|
||||
Object.defineProperty(VuePropTypes, 'sensibleDefaults', {
|
||||
enumerable: false,
|
||||
set (value) {
|
||||
if (value === false) {
|
||||
currentDefaults = {}
|
||||
} else if (value === true) {
|
||||
currentDefaults = typeDefaults()
|
||||
} else if (isPlainObject(value)) {
|
||||
currentDefaults = value
|
||||
}
|
||||
},
|
||||
get () {
|
||||
return currentDefaults
|
||||
},
|
||||
})
|
||||
|
||||
export default VuePropTypes
|
|
@ -0,0 +1,188 @@
|
|||
import isPlainObject from 'lodash.isplainobject'
|
||||
|
||||
const ObjProto = Object.prototype
|
||||
const toString = ObjProto.toString
|
||||
export const hasOwn = ObjProto.hasOwnProperty
|
||||
|
||||
const FN_MATCH_REGEXP = /^\s*function (\w+)/
|
||||
|
||||
// https://github.com/vuejs/vue/blob/dev/src/core/util/props.js#L159
|
||||
export const getType = (fn) => {
|
||||
const type = (fn !== null && fn !== undefined) ? (fn.type ? fn.type : fn) : null
|
||||
const match = type && type.toString().match(FN_MATCH_REGEXP)
|
||||
return match && match[1]
|
||||
}
|
||||
|
||||
export const getNativeType = (value) => {
|
||||
if (value === null || value === undefined) return null
|
||||
const match = value.constructor.toString().match(FN_MATCH_REGEXP)
|
||||
return match && match[1]
|
||||
}
|
||||
|
||||
/**
|
||||
* No-op function
|
||||
*/
|
||||
export const noop = () => {}
|
||||
|
||||
/**
|
||||
* Checks for a own property in an object
|
||||
*
|
||||
* @param {object} obj - Object
|
||||
* @param {string} prop - Property to check
|
||||
*/
|
||||
export const has = (obj, prop) => hasOwn.call(obj, prop)
|
||||
|
||||
/**
|
||||
* Determines whether the passed value is an integer. Uses `Number.isInteger` if available
|
||||
*
|
||||
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger
|
||||
* @param {*} value - The value to be tested for being an integer.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isInteger = Number.isInteger || function (value) {
|
||||
return typeof value === 'number' && isFinite(value) && Math.floor(value) === value
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines whether the passed value is an Array.
|
||||
*
|
||||
* @param {*} value - The value to be tested for being an array.
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isArray = Array.isArray || function (value) {
|
||||
return toString.call(value) === '[object Array]'
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if a value is a function
|
||||
*
|
||||
* @param {any} value - Value to check
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const isFunction = (value) => toString.call(value) === '[object Function]'
|
||||
|
||||
/**
|
||||
* Adds a `def` method to the object returning a new object with passed in argument as `default` property
|
||||
*
|
||||
* @param {object} type - Object to enhance
|
||||
*/
|
||||
export const withDefault = function (type) {
|
||||
Object.defineProperty(type, 'def', {
|
||||
value (def) {
|
||||
if (def === undefined && this.default === undefined) {
|
||||
this.default = undefined
|
||||
return this
|
||||
}
|
||||
if (!isFunction(def) && !validateType(this, def)) {
|
||||
warn(`${this._vueTypes_name} - invalid default value: "${def}"`, def)
|
||||
return this
|
||||
}
|
||||
this.default = (isArray(def) || isPlainObject(def)) ? function () {
|
||||
return def
|
||||
} : def
|
||||
|
||||
return this
|
||||
},
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a `isRequired` getter returning a new object with `required: true` key-value
|
||||
*
|
||||
* @param {object} type - Object to enhance
|
||||
*/
|
||||
export const withRequired = function (type) {
|
||||
Object.defineProperty(type, 'isRequired', {
|
||||
get () {
|
||||
this.required = true
|
||||
return this
|
||||
},
|
||||
enumerable: false,
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds `isRequired` and `def` modifiers to an object
|
||||
*
|
||||
* @param {string} name - Type internal name
|
||||
* @param {object} obj - Object to enhance
|
||||
* @returns {object}
|
||||
*/
|
||||
export const toType = (name, obj) => {
|
||||
Object.defineProperty(obj, '_vueTypes_name', {
|
||||
enumerable: false,
|
||||
writable: false,
|
||||
value: name,
|
||||
})
|
||||
withRequired(obj)
|
||||
withDefault(obj)
|
||||
|
||||
if (isFunction(obj.validator)) {
|
||||
obj.validator = obj.validator.bind(obj)
|
||||
}
|
||||
return obj
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates a given value against a prop type object
|
||||
*
|
||||
* @param {Object|*} type - Type to use for validation. Either a type object or a constructor
|
||||
* @param {*} value - Value to check
|
||||
* @param {boolean} silent - Silence warnings
|
||||
* @returns {boolean}
|
||||
*/
|
||||
export const validateType = (type, value, silent = false) => {
|
||||
let typeToCheck = type
|
||||
let valid = true
|
||||
let expectedType
|
||||
if (!isPlainObject(type)) {
|
||||
typeToCheck = { type }
|
||||
}
|
||||
const namePrefix = typeToCheck._vueTypes_name ? (typeToCheck._vueTypes_name + ' - ') : ''
|
||||
|
||||
if (hasOwn.call(typeToCheck, 'type') && typeToCheck.type !== null) {
|
||||
if (isArray(typeToCheck.type)) {
|
||||
valid = typeToCheck.type.some((type) => validateType(type, value, true))
|
||||
expectedType = typeToCheck.type.map((type) => getType(type)).join(' or ')
|
||||
} else {
|
||||
expectedType = getType(typeToCheck)
|
||||
|
||||
if (expectedType === 'Array') {
|
||||
valid = isArray(value)
|
||||
} else if (expectedType === 'Object') {
|
||||
valid = isPlainObject(value)
|
||||
} else if (expectedType === 'String' || expectedType === 'Number' || expectedType === 'Boolean' || expectedType === 'Function') {
|
||||
valid = getNativeType(value) === expectedType
|
||||
} else {
|
||||
valid = value instanceof typeToCheck.type
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!valid) {
|
||||
silent === false && warn(`${namePrefix}value "${value}" should be of type "${expectedType}"`)
|
||||
return false
|
||||
}
|
||||
|
||||
if (hasOwn.call(typeToCheck, 'validator') && isFunction(typeToCheck.validator)) {
|
||||
valid = typeToCheck.validator(value)
|
||||
if (!valid && silent === false) warn(`${namePrefix}custom validation failed`)
|
||||
return valid
|
||||
}
|
||||
return valid
|
||||
}
|
||||
|
||||
let warn = noop
|
||||
|
||||
if (process.env.NODE_ENV !== 'production') {
|
||||
const hasConsole = typeof console !== 'undefined'
|
||||
warn = (msg) => {
|
||||
if (hasConsole) {
|
||||
console.warn(`[VueTypes warn]: ${msg}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { warn }
|
|
@ -1,6 +1,7 @@
|
|||
<script>
|
||||
import PropTypes from 'vue-types'
|
||||
import align from 'dom-align'
|
||||
import clonedeep from 'lodash.clonedeep'
|
||||
import addEventListener from '../_util/Dom/addEventListener'
|
||||
import { cloneElement } from '../_util/vnode.js'
|
||||
import isWindow from './isWindow'
|
||||
|
@ -38,7 +39,8 @@ export default {
|
|||
},
|
||||
watch: {
|
||||
'$props': {
|
||||
handler: function (props, prevProps) {
|
||||
handler: function (props) {
|
||||
const prevProps = this.prevProps
|
||||
this.$nextTick(() => {
|
||||
let reAlign = false
|
||||
if (!props.disabled) {
|
||||
|
@ -106,16 +108,11 @@ export default {
|
|||
},
|
||||
|
||||
render () {
|
||||
this.prevProps = clonedeep(this.$props)
|
||||
const { childrenProps } = this.$props
|
||||
const child = this.$slots.default[0]
|
||||
if (childrenProps) {
|
||||
const newProps = {}
|
||||
for (const prop in childrenProps) {
|
||||
if (childrenProps.hasOwnProperty(prop)) {
|
||||
newProps[prop] = this.props[childrenProps[prop]]
|
||||
}
|
||||
}
|
||||
return cloneElement(child, { props: newProps })
|
||||
return cloneElement(child, { props: childrenProps })
|
||||
}
|
||||
return child
|
||||
},
|
||||
|
|
|
@ -7,7 +7,7 @@ export default {
|
|||
hiddenClassName: PropTypes.string,
|
||||
},
|
||||
render () {
|
||||
const { hiddenClassName, visible } = this.props
|
||||
const { hiddenClassName, visible } = this.$props
|
||||
|
||||
if (hiddenClassName || this.$slots.default.length > 1) {
|
||||
let cls = ''
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import PropTypes from 'vue-types'
|
||||
import PropTypes from '../_util/vue-types'
|
||||
import Align from '../align'
|
||||
import PopupInner from './PopupInner'
|
||||
import LazyRenderBox from './LazyRenderBox'
|
||||
|
@ -12,10 +12,16 @@ export default {
|
|||
align: PropTypes.any,
|
||||
destroyPopupOnHide: PropTypes.bool,
|
||||
prefixCls: PropTypes.string,
|
||||
getContainer: PropTypes.func,
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.rootNode = this.getPopupDomNode()
|
||||
this._container = this.getContainer()
|
||||
this._container.appendChild(this.$el)
|
||||
},
|
||||
beforeDestroy () {
|
||||
this._container && this._container.parentNode.removeChild(this._container)
|
||||
this._container = null
|
||||
},
|
||||
methods: {
|
||||
onAlign (popupDomNode, align) {
|
||||
|
@ -75,7 +81,7 @@ export default {
|
|||
if (!visible) {
|
||||
this.currentAlignClassName = null
|
||||
}
|
||||
|
||||
// visible = true
|
||||
const popupInnerProps = {
|
||||
props: {
|
||||
prefixCls,
|
||||
|
@ -89,12 +95,10 @@ export default {
|
|||
ref: 'popupInstance',
|
||||
style: { ...this.getZIndexStyle() },
|
||||
}
|
||||
|
||||
if (destroyPopupOnHide) {
|
||||
return (<Animate
|
||||
component=''
|
||||
exclusive
|
||||
transitionAppear
|
||||
transitionName={this.getTransitionName()}
|
||||
return (<transition
|
||||
name={this.getTransitionName()}
|
||||
>
|
||||
{visible ? (<Align
|
||||
target={this.getTarget}
|
||||
|
@ -110,23 +114,18 @@ export default {
|
|||
{$slots.default}
|
||||
</PopupInner>
|
||||
</Align>) : null}
|
||||
</Animate>)
|
||||
</transition>)
|
||||
}
|
||||
popupInnerProps.props.hiddenClassName = hiddenClassName
|
||||
return (<Animate
|
||||
component=''
|
||||
exclusive
|
||||
transitionAppear
|
||||
transitionName={this.getTransitionName()}
|
||||
showProp='xVisible'
|
||||
return (<transition
|
||||
name={this.getTransitionName()}
|
||||
>
|
||||
<Align
|
||||
target={this.getTarget}
|
||||
key='popup'
|
||||
ref='alignInstance'
|
||||
monitorWindowResize
|
||||
xVisible={visible}
|
||||
childrenProps={{ visible: 'xVisible' }}
|
||||
childrenProps={{ visible }}
|
||||
disabled={!visible}
|
||||
align={align}
|
||||
onAlign={this.onAlign}
|
||||
|
@ -137,7 +136,7 @@ export default {
|
|||
{$slots.default}
|
||||
</PopupInner>
|
||||
</Align>
|
||||
</Animate>)
|
||||
</transition>)
|
||||
},
|
||||
|
||||
getZIndexStyle () {
|
||||
|
@ -165,15 +164,11 @@ export default {
|
|||
)
|
||||
if (maskTransition) {
|
||||
maskElement = (
|
||||
<Animate
|
||||
key='mask'
|
||||
showProp='visible'
|
||||
transitionAppear
|
||||
component=''
|
||||
transitionName={maskTransition}
|
||||
<transition
|
||||
name={maskTransition}
|
||||
>
|
||||
{maskElement}
|
||||
</Animate>
|
||||
</transition>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@ export default {
|
|||
props: {
|
||||
hiddenClassName: PropTypes.string.def(''),
|
||||
prefixCls: PropTypes.string,
|
||||
visible: PropTypes.bool,
|
||||
},
|
||||
methods: {
|
||||
onMouseEnter (e) {
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
@triggerPrefixCls: rc-trigger-popup;
|
||||
|
||||
.@{triggerPrefixCls} {
|
||||
position: absolute;
|
||||
left: -9999px;
|
||||
top: -9999px;
|
||||
z-index: 1050;
|
||||
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.effect() {
|
||||
animation-duration: 0.3s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
|
||||
&-zoom-enter,&-zoom-appear {
|
||||
opacity: 0;
|
||||
.effect();
|
||||
animation-timing-function: cubic-bezier(0.18, 0.89, 0.32, 1.28);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
&-zoom-leave {
|
||||
.effect();
|
||||
animation-timing-function: cubic-bezier(0.6, -0.3, 0.74, 0.05);
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
&-zoom-enter&-zoom-enter-active, &-zoom-appear&-zoom-appear-active {
|
||||
animation-name: rcTriggerZoomIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&-zoom-leave&-zoom-leave-active {
|
||||
animation-name: rcTriggerZoomOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
@keyframes rcTriggerZoomIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
transform-origin: 50% 50%;
|
||||
transform: scale(0, 0);
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
transform-origin: 50% 50%;
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
}
|
||||
@keyframes rcTriggerZoomOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform-origin: 50% 50%;
|
||||
transform: scale(1, 1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
transform-origin: 50% 50%;
|
||||
transform: scale(0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@import "./mask";
|
|
@ -0,0 +1,63 @@
|
|||
.@{triggerPrefixCls} {
|
||||
&-mask {
|
||||
position: fixed;
|
||||
top: 0;
|
||||
right: 0;
|
||||
left: 0;
|
||||
bottom: 0;
|
||||
background-color: rgb(55, 55, 55);
|
||||
background-color: rgba(55, 55, 55, 0.6);
|
||||
height: 100%;
|
||||
filter: alpha(opacity=50);
|
||||
z-index: 1050;
|
||||
|
||||
&-hidden {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
|
||||
.fade-effect() {
|
||||
animation-duration: 0.3s;
|
||||
animation-fill-mode: both;
|
||||
animation-timing-function: cubic-bezier(0.55, 0, 0.55, 0.2);
|
||||
}
|
||||
|
||||
&-fade-enter,&-fade-appear {
|
||||
opacity: 0;
|
||||
.fade-effect();
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
&-fade-leave {
|
||||
.fade-effect();
|
||||
animation-play-state: paused;
|
||||
}
|
||||
|
||||
&-fade-enter&-fade-enter-active,&-fade-appear&-fade-appear-active {
|
||||
animation-name: rcTriggerMaskFadeIn;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
&-fade-leave&-fade-leave-active {
|
||||
animation-name: rcDialogFadeOut;
|
||||
animation-play-state: running;
|
||||
}
|
||||
|
||||
@keyframes rcTriggerMaskFadeIn {
|
||||
0% {
|
||||
opacity: 0;
|
||||
}
|
||||
100% {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes rcDialogFadeOut {
|
||||
0% {
|
||||
opacity: 1;
|
||||
}
|
||||
100% {
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<script>
|
||||
import Trigger from '../index'
|
||||
import '../assets/index.less'
|
||||
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'],
|
||||
},
|
||||
}
|
||||
|
||||
const popupBorderStyle = {
|
||||
border: '1px solid red',
|
||||
padding: '10px',
|
||||
}
|
||||
|
||||
export default {
|
||||
render () {
|
||||
return (
|
||||
<div>
|
||||
<div style={{ margin: '50px' }}>
|
||||
<Trigger
|
||||
popupPlacement='right'
|
||||
action={['click']}
|
||||
builtinPlacements={builtinPlacements}
|
||||
>
|
||||
<div style={popupBorderStyle} slot='popup' onClick={(e) => { e.stopPropagation() }}>
|
||||
jjj
|
||||
</div>
|
||||
<span href='#' style={{ margin: '20px' }} onClick={console.log}>trigger</span>
|
||||
</Trigger>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
</script>
|
|
@ -1,3 +1,3 @@
|
|||
// export this package's api
|
||||
import Trigger from './src/'
|
||||
import Trigger from './index.vue'
|
||||
export default Trigger
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
<script>
|
||||
import PropTypes from 'vue-types'
|
||||
import PropTypes from '../_util/vue-types'
|
||||
import contains from '../_util/Dom/contains'
|
||||
import addEventListener from '../_util/Dom/addEventListener'
|
||||
import Popup from './Popup'
|
||||
|
@ -16,8 +16,8 @@ function returnDocument () {
|
|||
return window.document
|
||||
}
|
||||
|
||||
const ALL_HANDLERS = ['onClick', 'onMouseDown', 'onTouchStart', 'onMouseEnter',
|
||||
'onMouseLeave', 'onFocus', 'onBlur', 'onContextMenu']
|
||||
const ALL_HANDLERS = ['click', 'mousedown', 'touchStart', 'mouseenter',
|
||||
'mouseleave', 'focus', 'blur', 'contextMenu']
|
||||
|
||||
const mixins = []
|
||||
|
||||
|
@ -26,11 +26,11 @@ mixins.push(
|
|||
autoMount: false,
|
||||
|
||||
isVisible (instance) {
|
||||
return instance.state.sPopupVisible
|
||||
return instance.$data.sPopupVisible
|
||||
},
|
||||
|
||||
isForceRender (instance) {
|
||||
return instance.props.forceRender
|
||||
return instance.$props.forceRender
|
||||
},
|
||||
|
||||
getContainer (instance) {
|
||||
|
@ -65,7 +65,7 @@ export default {
|
|||
zIndex: PropTypes.number,
|
||||
focusDelay: PropTypes.number.def(0),
|
||||
blurDelay: PropTypes.number.def(0.15),
|
||||
getPopupContainer: PropTypes.func,
|
||||
getPopupContainer: Function,
|
||||
getDocument: PropTypes.func.def(returnDocument),
|
||||
forceRender: PropTypes.bool,
|
||||
destroyPopupOnHide: PropTypes.bool.def(false),
|
||||
|
@ -74,15 +74,15 @@ export default {
|
|||
// onPopupAlign: PropTypes.func,
|
||||
popupAlign: PropTypes.object.def({}),
|
||||
popupVisible: PropTypes.bool,
|
||||
defaultPopupVisible: PropTypes.bool.def(false),
|
||||
maskTransitionName: PropTypes.oneOfType([
|
||||
PropTypes.string,
|
||||
PropTypes.object,
|
||||
]),
|
||||
maskAnimation: PropTypes.string,
|
||||
// defaultPopupVisible: PropTypes.bool.def(false),
|
||||
// maskTransitionName: PropTypes.oneOfType([
|
||||
// PropTypes.string,
|
||||
// PropTypes.object,
|
||||
// ]),
|
||||
// maskAnimation: PropTypes.string,
|
||||
},
|
||||
|
||||
mixins: [StateMixin, mixins],
|
||||
mixins: [StateMixin, ...mixins],
|
||||
data () {
|
||||
const props = this.$props
|
||||
let popupVisible
|
||||
|
@ -99,15 +99,14 @@ export default {
|
|||
beforeCreate () {
|
||||
ALL_HANDLERS.forEach((h) => {
|
||||
this[`fire${h}`] = (e) => {
|
||||
this.fireEvents(h, e)
|
||||
const ev = `on${h[0].toUpperCase() + h.slice(1)}`
|
||||
this.fireEvents(ev, e)
|
||||
}
|
||||
})
|
||||
},
|
||||
|
||||
mounted () {
|
||||
this.updated({}, {
|
||||
sPopupVisible: this.$data.sPopupVisible,
|
||||
})
|
||||
this.updatedCal()
|
||||
},
|
||||
watch: {
|
||||
popupVisible (val) {
|
||||
|
@ -122,43 +121,8 @@ export default {
|
|||
},
|
||||
},
|
||||
|
||||
updated (_, prevState) {
|
||||
const props = this.$props
|
||||
const state = this.$data
|
||||
this.renderComponent()
|
||||
|
||||
// We must listen to `mousedown` or `touchstart`, edge case:
|
||||
// https://github.com/ant-design/ant-design/issues/5804
|
||||
// https://github.com/react-component/calendar/issues/250
|
||||
// https://github.com/react-component/trigger/issues/50
|
||||
if (state.sPopupVisible) {
|
||||
let currentDocument
|
||||
if (!this.clickOutsideHandler && (this.isClickToHide() || this.isContextMenuToShow())) {
|
||||
currentDocument = props.getDocument()
|
||||
this.clickOutsideHandler = addEventListener(currentDocument,
|
||||
'mousedown', this.onDocumentClick)
|
||||
}
|
||||
// always hide on mobile
|
||||
if (!this.touchOutsideHandler) {
|
||||
currentDocument = currentDocument || props.getDocument()
|
||||
this.touchOutsideHandler = addEventListener(currentDocument,
|
||||
'touchstart', this.onDocumentClick)
|
||||
}
|
||||
// close popup when trigger type contains 'onContextMenu' and document is scrolling.
|
||||
if (!this.contextMenuOutsideHandler1 && this.isContextMenuToShow()) {
|
||||
currentDocument = currentDocument || props.getDocument()
|
||||
this.contextMenuOutsideHandler1 = addEventListener(currentDocument,
|
||||
'scroll', this.onContextMenuClose)
|
||||
}
|
||||
// close popup when trigger type contains 'onContextMenu' and window is blur.
|
||||
if (!this.contextMenuOutsideHandler2 && this.isContextMenuToShow()) {
|
||||
this.contextMenuOutsideHandler2 = addEventListener(window,
|
||||
'blur', this.onContextMenuClose)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
this.clearOutsideHandler()
|
||||
updated () {
|
||||
this.updatedCal()
|
||||
},
|
||||
|
||||
beforeDestroy () {
|
||||
|
@ -166,21 +130,59 @@ export default {
|
|||
this.clearOutsideHandler()
|
||||
},
|
||||
methods: {
|
||||
onMouseEnter (e) {
|
||||
this.fireEvents('onMouseEnter', e)
|
||||
updatedCal () {
|
||||
const props = this.$props
|
||||
const state = this.$data
|
||||
// this.renderComponent()
|
||||
|
||||
// We must listen to `mousedown` or `touchstart`, edge case:
|
||||
// https://github.com/ant-design/ant-design/issues/5804
|
||||
// https://github.com/react-component/calendar/issues/250
|
||||
// https://github.com/react-component/trigger/issues/50
|
||||
if (state.sPopupVisible) {
|
||||
let currentDocument
|
||||
if (!this.clickOutsideHandler && (this.isClickToHide() || this.isContextMenuToShow())) {
|
||||
currentDocument = props.getDocument()
|
||||
this.clickOutsideHandler = addEventListener(currentDocument,
|
||||
'mousedown', this.onDocumentClick)
|
||||
}
|
||||
// always hide on mobile
|
||||
if (!this.touchOutsideHandler) {
|
||||
currentDocument = currentDocument || props.getDocument()
|
||||
this.touchOutsideHandler = addEventListener(currentDocument,
|
||||
'touchstart', this.onDocumentClick)
|
||||
}
|
||||
// close popup when trigger type contains 'onContextMenu' and document is scrolling.
|
||||
if (!this.contextMenuOutsideHandler1 && this.isContextMenuToShow()) {
|
||||
currentDocument = currentDocument || props.getDocument()
|
||||
this.contextMenuOutsideHandler1 = addEventListener(currentDocument,
|
||||
'scroll', this.onContextMenuClose)
|
||||
}
|
||||
// close popup when trigger type contains 'onContextMenu' and window is blur.
|
||||
if (!this.contextMenuOutsideHandler2 && this.isContextMenuToShow()) {
|
||||
this.contextMenuOutsideHandler2 = addEventListener(window,
|
||||
'blur', this.onContextMenuClose)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
this.clearOutsideHandler()
|
||||
},
|
||||
onMouseenter (e) {
|
||||
this.fireEvents('mouseenter', e)
|
||||
this.delaySetPopupVisible(true, this.$props.mouseEnterDelay)
|
||||
},
|
||||
|
||||
onMouseLeave (e) {
|
||||
this.fireEvents('onMouseLeave', e)
|
||||
onMouseleave (e) {
|
||||
this.fireEvents('mouseleave', e)
|
||||
this.delaySetPopupVisible(false, this.$props.mouseLeaveDelay)
|
||||
},
|
||||
|
||||
onPopupMouseEnter () {
|
||||
onPopupMouseenter () {
|
||||
this.clearDelayTimer()
|
||||
},
|
||||
|
||||
onPopupMouseLeave (e) {
|
||||
onPopupMouseleave (e) {
|
||||
if (e.relatedTarget && !e.relatedTarget.setTimeout &&
|
||||
this._component &&
|
||||
this._component.getPopupDomNode &&
|
||||
|
@ -191,7 +193,7 @@ export default {
|
|||
},
|
||||
|
||||
onFocus (e) {
|
||||
this.fireEvents('onFocus', e)
|
||||
this.fireEvents('focus', e)
|
||||
// incase focusin and focusout
|
||||
this.clearDelayTimer()
|
||||
if (this.isFocusToShow()) {
|
||||
|
@ -200,18 +202,18 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
onMouseDown (e) {
|
||||
this.fireEvents('onMouseDown', e)
|
||||
onMousedown (e) {
|
||||
this.fireEvents('mousedown', e)
|
||||
this.preClickTime = Date.now()
|
||||
},
|
||||
|
||||
onTouchStart (e) {
|
||||
this.fireEvents('onTouchStart', e)
|
||||
this.fireEvents('touchStart', e)
|
||||
this.preTouchTime = Date.now()
|
||||
},
|
||||
|
||||
onBlur (e) {
|
||||
this.fireEvents('onBlur', e)
|
||||
this.fireEvents('blur', e)
|
||||
this.clearDelayTimer()
|
||||
if (this.isBlurToHide()) {
|
||||
this.delaySetPopupVisible(false, this.$props.blurDelay)
|
||||
|
@ -220,7 +222,7 @@ export default {
|
|||
|
||||
onContextMenu (e) {
|
||||
e.preventDefault()
|
||||
this.fireEvents('onContextMenu', e)
|
||||
this.fireEvents('contextMenu', e)
|
||||
this.setPopupVisible(true)
|
||||
},
|
||||
|
||||
|
@ -231,7 +233,7 @@ export default {
|
|||
},
|
||||
|
||||
onClick (event) {
|
||||
this.fireEvents('onClick', event)
|
||||
this.fireEvents('click', event)
|
||||
// focus will trigger click
|
||||
if (this.focusTime) {
|
||||
let preTime
|
||||
|
@ -276,10 +278,10 @@ export default {
|
|||
},
|
||||
|
||||
getRootDomNode () {
|
||||
return this.$el
|
||||
return this.$el.children[0] || this.$el
|
||||
},
|
||||
|
||||
getPopupClassNameFromAlign (align) {
|
||||
getPopupClassFromAlign (align) {
|
||||
const className = []
|
||||
const props = this.$props
|
||||
const { popupPlacement, builtinPlacements, prefixCls } = props
|
||||
|
@ -301,21 +303,21 @@ export default {
|
|||
return popupAlign
|
||||
},
|
||||
onPopupAlign () {
|
||||
this.emit('popupAlign', ...arguments)
|
||||
this.$emit('popupAlign', ...arguments)
|
||||
},
|
||||
getComponent () {
|
||||
const mouseProps = {}
|
||||
if (this.isMouseEnterToShow()) {
|
||||
mouseProps.mouseenter = this.onPopupMouseEnter
|
||||
mouseProps.mouseenter = this.onPopupMouseenter
|
||||
}
|
||||
if (this.isMouseLeaveToHide()) {
|
||||
mouseProps.mouseleave = this.onPopupMouseLeave
|
||||
mouseProps.mouseleave = this.onPopupMouseleave
|
||||
}
|
||||
const { prefixCls, destroyPopupOnHide, sPopupVisible,
|
||||
popupStyle, popupClassName, action, onPopupAlign,
|
||||
popupAnimation, getPopupClassNameFromAlign, getRootDomNode,
|
||||
popupAnimation, getPopupClassFromAlign, getRootDomNode,
|
||||
mask, zIndex, popupTransitionName, getPopupAlign,
|
||||
maskAnimation, maskTransitionName, popup, $slots } = this
|
||||
maskAnimation, maskTransitionName, popup, $slots, getContainer } = this
|
||||
const popupProps = {
|
||||
props: {
|
||||
prefixCls,
|
||||
|
@ -324,13 +326,14 @@ export default {
|
|||
action,
|
||||
align: getPopupAlign(),
|
||||
animation: popupAnimation,
|
||||
getClassNameFromAlign: getPopupClassNameFromAlign,
|
||||
getClassNameFromAlign: getPopupClassFromAlign,
|
||||
getRootDomNode,
|
||||
mask,
|
||||
zIndex,
|
||||
transitionName: popupTransitionName,
|
||||
maskAnimation,
|
||||
maskTransitionName,
|
||||
getContainer,
|
||||
},
|
||||
on: {
|
||||
align: onPopupAlign,
|
||||
|
@ -343,6 +346,7 @@ export default {
|
|||
return (
|
||||
<Popup
|
||||
{...popupProps}
|
||||
ref='popup'
|
||||
>
|
||||
{typeof popup === 'function' ? popup() : popup}
|
||||
{popup === undefined ? $slots.popup : null}
|
||||
|
@ -368,10 +372,11 @@ export default {
|
|||
setPopupVisible (sPopupVisible) {
|
||||
this.clearDelayTimer()
|
||||
if (this.$data.sPopupVisible !== sPopupVisible) {
|
||||
if (this.$props.popupVisible !== undefined) {
|
||||
if (this.$props.popupVisible === undefined) {
|
||||
this.setState({
|
||||
sPopupVisible,
|
||||
})
|
||||
this.$forceUpdate()
|
||||
}
|
||||
this.$emit('popupVisibleChange', sPopupVisible)
|
||||
}
|
||||
|
@ -420,12 +425,17 @@ export default {
|
|||
},
|
||||
|
||||
createTwoChains (event) {
|
||||
const childPros = this.$props.children.props
|
||||
const props = this.$props
|
||||
if (childPros[event] && props[event]) {
|
||||
return this[`fire${event}`]
|
||||
const child = this.$slots.default[0]
|
||||
let fn = () => {}
|
||||
if (child && child.data && 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 childPros[event] || props[event]
|
||||
return fn
|
||||
},
|
||||
|
||||
isClickToShow () {
|
||||
|
@ -445,12 +455,12 @@ export default {
|
|||
|
||||
isMouseEnterToShow () {
|
||||
const { action, showAction } = this.$props
|
||||
return action.indexOf('hover') !== -1 || showAction.indexOf('mouseEnter') !== -1
|
||||
return action.indexOf('hover') !== -1 || showAction.indexOf('mouseenter') !== -1
|
||||
},
|
||||
|
||||
isMouseLeaveToHide () {
|
||||
const { action, hideAction } = this.$props
|
||||
return action.indexOf('hover') !== -1 || hideAction.indexOf('mouseLeave') !== -1
|
||||
return action.indexOf('hover') !== -1 || hideAction.indexOf('mouseleave') !== -1
|
||||
},
|
||||
|
||||
isFocusToShow () {
|
||||
|
@ -463,18 +473,17 @@ export default {
|
|||
return action.indexOf('focus') !== -1 || hideAction.indexOf('blur') !== -1
|
||||
},
|
||||
forcePopupAlign () {
|
||||
if (this.state.popupVisible && this._component && this._component.$refs.alignInstance) {
|
||||
if (this.$data.sPopupVisible && this._component && this._component.$refs.alignInstance) {
|
||||
this._component.$refs.alignInstance.forceAlign()
|
||||
}
|
||||
},
|
||||
fireEvents (type, e) {
|
||||
const childCallback = this.$props.children.props[type]
|
||||
if (childCallback) {
|
||||
childCallback(e)
|
||||
const child = this.$slots.default[0]
|
||||
if (child && child.data && child.on && child.on[type]) {
|
||||
child.on[type](e)
|
||||
}
|
||||
const callback = this.$props[type]
|
||||
if (callback) {
|
||||
callback(e)
|
||||
if (this.data && this.data.on && this.data.on[type]) {
|
||||
this.data.on[type](e)
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -494,39 +503,44 @@ export default {
|
|||
if (this.isContextMenuToShow()) {
|
||||
newChildProps.on.contextMenu = this.onContextMenu
|
||||
} else {
|
||||
newChildProps.on.contextMenu = this.createTwoChains('onContextMenu')
|
||||
newChildProps.on.contextMenu = this.createTwoChains('contextMenu')
|
||||
}
|
||||
|
||||
if (this.isClickToHide() || this.isClickToShow()) {
|
||||
newChildProps.on.click = this.onClick
|
||||
newChildProps.on.mousedown = this.onMouseDown
|
||||
newChildProps.on.mousedown = this.onMousedown
|
||||
// newChildProps.on.touchStart = this.onTouchStart
|
||||
} else {
|
||||
newChildProps.on.click = this.createTwoChains('onClick')
|
||||
newChildProps.on.mousedown = this.createTwoChains('onMouseDown')
|
||||
newChildProps.on.click = this.createTwoChains('click')
|
||||
newChildProps.on.mousedown = this.createTwoChains('mousedown')
|
||||
// newChildProps.on.TouchStart = this.createTwoChains('onTouchStart')
|
||||
}
|
||||
if (this.isMouseEnterToShow()) {
|
||||
newChildProps.on.mouseenter = this.onMouseEnter
|
||||
newChildProps.on.mouseenter = this.onMouseenter
|
||||
} else {
|
||||
newChildProps.on.mouseenter = this.createTwoChains('onMouseEnter')
|
||||
newChildProps.on.mouseenter = this.createTwoChains('mouseenter')
|
||||
}
|
||||
if (this.isMouseLeaveToHide()) {
|
||||
newChildProps.on.mouseleave = this.onMouseLeave
|
||||
newChildProps.on.mouseleave = this.onMouseleave
|
||||
} else {
|
||||
newChildProps.on.mouseleave = this.createTwoChains('onMouseLeave')
|
||||
newChildProps.on.mouseleave = this.createTwoChains('mouseleave')
|
||||
}
|
||||
if (this.isFocusToShow() || this.isBlurToHide()) {
|
||||
newChildProps.on.focus = this.onFocus
|
||||
newChildProps.on.blur = this.onBlur
|
||||
} else {
|
||||
newChildProps.on.focus = this.createTwoChains('onFocus')
|
||||
newChildProps.on.blur = this.createTwoChains('onBlur')
|
||||
newChildProps.on.focus = this.createTwoChains('focus')
|
||||
newChildProps.on.blur = this.createTwoChains('blur')
|
||||
}
|
||||
|
||||
const trigger = cloneElement(child, newChildProps)
|
||||
|
||||
return trigger
|
||||
return (
|
||||
<span>
|
||||
{trigger}
|
||||
{this.getComponent()}
|
||||
</span>
|
||||
)
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
"eslint-plugin-vue": "^3.13.0",
|
||||
"lodash.clonedeep": "^4.5.0",
|
||||
"lodash.debounce": "^4.0.8",
|
||||
"lodash.isplainobject": "^4.0.6",
|
||||
"omit.js": "^1.0.0",
|
||||
"vue-types": "^1.0.2",
|
||||
"warning": "^3.0.0"
|
||||
|
|
Loading…
Reference in New Issue