feat: update popconfirm and tooltip
parent
23fd134f90
commit
0bb79c27a6
|
@ -234,7 +234,7 @@ const initDefaultProps = (propTypes, defaultProps) => {
|
||||||
export function mergeProps () {
|
export function mergeProps () {
|
||||||
const args = [].slice.call(arguments, 0)
|
const args = [].slice.call(arguments, 0)
|
||||||
const props = {}
|
const props = {}
|
||||||
args.forEach((p, i) => {
|
args.forEach((p = {}, i) => {
|
||||||
for (const [k, v] of Object.entries(p)) {
|
for (const [k, v] of Object.entries(p)) {
|
||||||
props[k] = props[k] || {}
|
props[k] = props[k] || {}
|
||||||
if (isPlainObject(v)) {
|
if (isPlainObject(v)) {
|
||||||
|
|
|
@ -6,8 +6,7 @@ exports[`Popconfirm should show overlay when trigger is clicked 1`] = `
|
||||||
<div role="tooltip" class="ant-popover-inner">
|
<div role="tooltip" class="ant-popover-inner">
|
||||||
<div class="ant-popover-inner-content">
|
<div class="ant-popover-inner-content">
|
||||||
<div class="ant-popover-message"><i class="anticon anticon-exclamation-circle"><svg viewBox="64 64 896 896" data-icon="exclamation-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" class="">
|
<div class="ant-popover-message"><i class="anticon anticon-exclamation-circle"><svg viewBox="64 64 896 896" data-icon="exclamation-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" class="">
|
||||||
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm0 820c-205.4 0-372-166.6-372-372s166.6-372 372-372 372 166.6 372 372-166.6 372-372 372z"></path>
|
<path d="M512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm-32 232c0-4.4 3.6-8 8-8h48c4.4 0 8 3.6 8 8v272c0 4.4-3.6 8-8 8h-48c-4.4 0-8-3.6-8-8V296zm32 440a48.01 48.01 0 0 1 0-96 48.01 48.01 0 0 1 0 96z"></path>
|
||||||
<path d="M464 688a48 48 0 1 0 96 0 48 48 0 1 0-96 0zm24-112h48c4.4 0 8-3.6 8-8V296c0-4.4-3.6-8-8-8h-48c-4.4 0-8 3.6-8 8v272c0 4.4 3.6 8 8 8z"></path>
|
|
||||||
</svg></i>
|
</svg></i>
|
||||||
<div class="ant-popover-message-title">code</div>
|
<div class="ant-popover-message-title">code</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,6 +5,10 @@ function $$ (className) {
|
||||||
return document.body.querySelectorAll(className)
|
return document.body.querySelectorAll(className)
|
||||||
}
|
}
|
||||||
describe('Popconfirm', () => {
|
describe('Popconfirm', () => {
|
||||||
|
const eventObject = expect.objectContaining({
|
||||||
|
target: expect.anything(),
|
||||||
|
preventDefault: expect.any(Function),
|
||||||
|
})
|
||||||
it('should popup Popconfirm dialog', async () => {
|
it('should popup Popconfirm dialog', async () => {
|
||||||
const onVisibleChange = jest.fn()
|
const onVisibleChange = jest.fn()
|
||||||
|
|
||||||
|
@ -29,12 +33,12 @@ describe('Popconfirm', () => {
|
||||||
triggerNode.trigger('click')
|
triggerNode.trigger('click')
|
||||||
})
|
})
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(onVisibleChange).toBeCalledWith(true)
|
expect(onVisibleChange).toHaveBeenLastCalledWith(true, undefined)
|
||||||
expect($$('.popconfirm-test').length).toBe(1)
|
expect($$('.popconfirm-test').length).toBe(1)
|
||||||
triggerNode.trigger('click')
|
triggerNode.trigger('click')
|
||||||
}, 1000)
|
}, 1000)
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
expect(onVisibleChange).toBeCalledWith(false)
|
expect(onVisibleChange).toHaveBeenLastCalledWith(false, undefined)
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -3,7 +3,7 @@ import omit from 'omit.js'
|
||||||
import Tooltip from '../tooltip'
|
import Tooltip from '../tooltip'
|
||||||
import abstractTooltipProps from '../tooltip/abstractTooltipProps'
|
import abstractTooltipProps from '../tooltip/abstractTooltipProps'
|
||||||
import PropTypes from '../_util/vue-types'
|
import PropTypes from '../_util/vue-types'
|
||||||
import { getOptionProps, hasProp, getComponentFromProp } from '../_util/props-util'
|
import { getOptionProps, hasProp, getComponentFromProp, mergeProps } from '../_util/props-util'
|
||||||
import BaseMixin from '../_util/BaseMixin'
|
import BaseMixin from '../_util/BaseMixin'
|
||||||
import buttonTypes from '../button/buttonTypes'
|
import buttonTypes from '../button/buttonTypes'
|
||||||
import Icon from '../icon'
|
import Icon from '../icon'
|
||||||
|
@ -26,6 +26,8 @@ const Popconfirm = {
|
||||||
okText: PropTypes.any,
|
okText: PropTypes.any,
|
||||||
cancelText: PropTypes.any,
|
cancelText: PropTypes.any,
|
||||||
icon: PropTypes.any,
|
icon: PropTypes.any,
|
||||||
|
okButtonProps: PropTypes.object,
|
||||||
|
cancelButtonProps: PropTypes.object,
|
||||||
},
|
},
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
model: {
|
model: {
|
||||||
|
@ -38,18 +40,23 @@ const Popconfirm = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
data () {
|
data () {
|
||||||
return {
|
const props = getOptionProps(this)
|
||||||
sVisible: this.$props.visible,
|
const state = { sVisible: false }
|
||||||
|
if ('visible' in props) {
|
||||||
|
state.sVisible = props.visible
|
||||||
|
} else if ('defaultVisible' in props) {
|
||||||
|
state.sVisible = props.defaultVisible
|
||||||
}
|
}
|
||||||
|
return state
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
onConfirm (e) {
|
onConfirm (e) {
|
||||||
this.setVisible(false)
|
this.setVisible(false, e)
|
||||||
this.$emit('confirm', e)
|
this.$emit('confirm', e)
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancel (e) {
|
onCancel (e) {
|
||||||
this.setVisible(false)
|
this.setVisible(false, e)
|
||||||
this.$emit('cancel', e)
|
this.$emit('cancel', e)
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -57,18 +64,35 @@ const Popconfirm = {
|
||||||
this.setVisible(sVisible)
|
this.setVisible(sVisible)
|
||||||
},
|
},
|
||||||
|
|
||||||
setVisible (sVisible) {
|
setVisible (sVisible, e) {
|
||||||
if (!hasProp(this, 'visible')) {
|
if (!hasProp(this, 'visible')) {
|
||||||
this.setState({ sVisible })
|
this.setState({ sVisible })
|
||||||
}
|
}
|
||||||
this.$emit('visibleChange', sVisible)
|
this.$emit('visibleChange', sVisible, e)
|
||||||
},
|
},
|
||||||
getPopupDomNode () {
|
getPopupDomNode () {
|
||||||
return this.$refs.tooltip.getPopupDomNode()
|
return this.$refs.tooltip.getPopupDomNode()
|
||||||
},
|
},
|
||||||
renderOverlay (popconfirmLocale) {
|
renderOverlay (popconfirmLocale) {
|
||||||
const { prefixCls, okType } = this
|
const { prefixCls, okType, okButtonProps, cancelButtonProps } = this
|
||||||
const icon = getComponentFromProp(this, 'icon') || <Icon type='exclamation-circle' />
|
const icon = getComponentFromProp(this, 'icon') || <Icon type='exclamation-circle' theme='filled'/>
|
||||||
|
const cancelBtnProps = mergeProps({
|
||||||
|
props: {
|
||||||
|
size: 'small',
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
click: this.onCancel,
|
||||||
|
},
|
||||||
|
}, cancelButtonProps)
|
||||||
|
const okBtnProps = mergeProps({
|
||||||
|
props: {
|
||||||
|
type: okType,
|
||||||
|
size: 'small',
|
||||||
|
},
|
||||||
|
on: {
|
||||||
|
click: this.onConfirm,
|
||||||
|
},
|
||||||
|
}, okButtonProps)
|
||||||
return (
|
return (
|
||||||
<div class={`${prefixCls}-inner-content`}>
|
<div class={`${prefixCls}-inner-content`}>
|
||||||
<div class={`${prefixCls}-message`}>
|
<div class={`${prefixCls}-message`}>
|
||||||
|
@ -78,10 +102,10 @@ const Popconfirm = {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class={`${prefixCls}-buttons`}>
|
<div class={`${prefixCls}-buttons`}>
|
||||||
<Button onClick={this.onCancel} size='small'>
|
<Button {...cancelBtnProps}>
|
||||||
{getComponentFromProp(this, 'cancelText') || popconfirmLocale.cancelText}
|
{getComponentFromProp(this, 'cancelText') || popconfirmLocale.cancelText}
|
||||||
</Button>
|
</Button>
|
||||||
<Button onClick={this.onConfirm} type={okType} size='small'>
|
<Button {...okBtnProps}>
|
||||||
{getComponentFromProp(this, 'okText') || popconfirmLocale.okText}
|
{getComponentFromProp(this, 'okText') || popconfirmLocale.okText}
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -61,25 +61,13 @@ export default {
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
|
|
||||||
isHoverTrigger () {
|
|
||||||
const { trigger } = this.$props
|
|
||||||
if (!trigger || trigger === 'hover') {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
if (Array.isArray(trigger)) {
|
|
||||||
return trigger.indexOf('hover') >= 0
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
},
|
|
||||||
|
|
||||||
// Fix Tooltip won't hide at disabled button
|
// Fix Tooltip won't hide at disabled button
|
||||||
// mouse events don't trigger at disabled button in Chrome
|
// mouse events don't trigger at disabled button in Chrome
|
||||||
// https://github.com/react-component/tooltip/issues/18
|
// https://github.com/react-component/tooltip/issues/18
|
||||||
getDisabledCompatibleChildren (ele) {
|
getDisabledCompatibleChildren (ele) {
|
||||||
const isAntBtn = ele.componentOptions && ele.componentOptions.Ctor.options.__ANT_BUTTON
|
const isAntBtn = ele.componentOptions && ele.componentOptions.Ctor.options.__ANT_BUTTON
|
||||||
if (((isAntBtn && (ele.componentOptions.propsData.disabled || ele.componentOptions.propsData.disabled === '')) ||
|
if (((isAntBtn && (ele.componentOptions.propsData.disabled || ele.componentOptions.propsData.disabled === '')) ||
|
||||||
(ele.tag === 'button' && ele.data && ele.data.attrs.disabled !== false)) &&
|
(ele.tag === 'button' && ele.data && ele.data.attrs.disabled !== false))) {
|
||||||
this.isHoverTrigger()) {
|
|
||||||
// Pick some layout related style properties up to span
|
// Pick some layout related style properties up to span
|
||||||
// Prevent layout bugs like https://github.com/ant-design/ant-design/issues/5254
|
// Prevent layout bugs like https://github.com/ant-design/ant-design/issues/5254
|
||||||
const { picked, omitted } = splitObject(
|
const { picked, omitted } = splitObject(
|
||||||
|
|
|
@ -155,21 +155,6 @@ describe('Tooltip', () => {
|
||||||
// expect(wrapper2.find('span').at(0).element.style.display).toBe('block')
|
// expect(wrapper2.find('span').at(0).element.style.display).toBe('block')
|
||||||
// })
|
// })
|
||||||
|
|
||||||
// it('should not wrap span when trigger is not hover', () => {
|
|
||||||
// const wrapper = mount(
|
|
||||||
// <Tooltip
|
|
||||||
// title='xxxxx'
|
|
||||||
// trigger='click'
|
|
||||||
// mouseEnterDelay={0}
|
|
||||||
// mouseLeaveDelay={0}
|
|
||||||
// >
|
|
||||||
// <button disabled>Hello world!</button>
|
|
||||||
// </Tooltip>
|
|
||||||
// )
|
|
||||||
|
|
||||||
// expect(wrapper.find('span')).toHaveLength(0)
|
|
||||||
// })
|
|
||||||
|
|
||||||
// it('should works for arrowPointAtCenter', () => {
|
// it('should works for arrowPointAtCenter', () => {
|
||||||
// const arrowWidth = 5
|
// const arrowWidth = 5
|
||||||
// const horizontalArrowShift = 16
|
// const horizontalArrowShift = 16
|
||||||
|
|
|
@ -3,6 +3,7 @@ const triggerType = PropTypes.oneOf(['hover', 'focus', 'click', 'contextmenu'])
|
||||||
export default () => ({
|
export default () => ({
|
||||||
trigger: PropTypes.oneOfType([triggerType, PropTypes.arrayOf(triggerType)]).def('hover'),
|
trigger: PropTypes.oneOfType([triggerType, PropTypes.arrayOf(triggerType)]).def('hover'),
|
||||||
visible: PropTypes.bool,
|
visible: PropTypes.bool,
|
||||||
|
defaultVisible: PropTypes.bool,
|
||||||
placement: PropTypes.oneOf(['top', 'left', 'right', 'bottom',
|
placement: PropTypes.oneOf(['top', 'left', 'right', 'bottom',
|
||||||
'topLeft', 'topRight', 'bottomLeft', 'bottomRight',
|
'topLeft', 'topRight', 'bottomLeft', 'bottomRight',
|
||||||
'leftTop', 'leftBottom', 'rightTop', 'rightBottom']).def('top'),
|
'leftTop', 'leftBottom', 'rightTop', 'rightBottom']).def('top'),
|
||||||
|
|
|
@ -83,6 +83,7 @@ export default function getPlacements (config) {
|
||||||
...rcPlacements[key],
|
...rcPlacements[key],
|
||||||
overflow: getOverflowOptions(autoAdjustOverflow),
|
overflow: getOverflowOptions(autoAdjustOverflow),
|
||||||
}
|
}
|
||||||
|
placementMap[key].ignoreShake = true
|
||||||
})
|
})
|
||||||
return placementMap
|
return placementMap
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue