feat: update popconfirm and tooltip

pull/309/head
tangjinzhou 2018-12-10 21:44:14 +08:00
parent 23fd134f90
commit 0bb79c27a6
8 changed files with 46 additions and 44 deletions

View File

@ -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)) {

View File

@ -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>

View File

@ -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)
}) })
}) })

View File

@ -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>

View File

@ -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(

View File

@ -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

View File

@ -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'),

View File

@ -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
} }