refactor: popconfirm
parent
0ade597b55
commit
783fb2c8a9
|
@ -7,3 +7,5 @@ date 相关组件: dayjs, UI 变动
|
||||||
steps: add responsive、percent
|
steps: add responsive、percent
|
||||||
|
|
||||||
collapse: add ghost、collapsible
|
collapse: add ghost、collapsible
|
||||||
|
|
||||||
|
popconfirm: add cancelButton、okButton、esc 隐藏
|
||||||
|
|
|
@ -153,6 +153,13 @@ const collapseMotion = (style: Ref<CSSProperties>, className: Ref<string>): CSSM
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export { Transition, TransitionGroup, collapseMotion };
|
const getTransitionName = (rootPrefixCls: string, motion: string, transitionName?: string) => {
|
||||||
|
if (transitionName !== undefined) {
|
||||||
|
return transitionName;
|
||||||
|
}
|
||||||
|
return `${rootPrefixCls}-${motion}`;
|
||||||
|
};
|
||||||
|
|
||||||
|
export { Transition, TransitionGroup, collapseMotion, getTransitionName };
|
||||||
|
|
||||||
export default Transition;
|
export default Transition;
|
||||||
|
|
|
@ -5,7 +5,7 @@ exports[`Popconfirm should show overlay when trigger is clicked 1`] = `
|
||||||
<div class="ant-popover-arrow"><span class="ant-popover-arrow-content"></span></div>
|
<div class="ant-popover-arrow"><span class="ant-popover-arrow-content"></span></div>
|
||||||
<div class="ant-popover-inner" role="tooltip">
|
<div class="ant-popover-inner" role="tooltip">
|
||||||
<div class="ant-popover-inner-content">
|
<div class="ant-popover-inner-content">
|
||||||
<div class="ant-popover-message"><span role="img" aria-label="exclamation-circle" class="anticon anticon-exclamation-circle"><svg class="" data-icon="exclamation-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896" focusable="false"><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 010-96 48.01 48.01 0 010 96z"></path></svg></span>
|
<div class="ant-popover-message"><span role="img" aria-label="exclamation-circle" class="anticon anticon-exclamation-circle"><svg focusable="false" class="" data-icon="exclamation-circle" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><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 010-96 48.01 48.01 0 010 96z"></path></svg></span>
|
||||||
<div class="ant-popover-message-title">code</div>
|
<div class="ant-popover-message-title">code</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="ant-popover-buttons"><button class="ant-btn ant-btn-sm" type="button">
|
<div class="ant-popover-buttons"><button class="ant-btn ant-btn-sm" type="button">
|
||||||
|
|
|
@ -68,12 +68,11 @@ describe('Popconfirm', () => {
|
||||||
await asyncExpect(() => {
|
await asyncExpect(() => {
|
||||||
const popup = popconfirm.vm.$refs.popconfirm.getPopupDomNode();
|
const popup = popconfirm.vm.$refs.popconfirm.getPopupDomNode();
|
||||||
expect(popup).not.toBe(null);
|
expect(popup).not.toBe(null);
|
||||||
expect(popup.className).toContain('ant-popover-placement-top');
|
|
||||||
expect(popup.innerHTML).toMatchSnapshot();
|
expect(popup.innerHTML).toMatchSnapshot();
|
||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
|
|
||||||
fit('should not open in disabled', async () => {
|
it('should not open in disabled', async () => {
|
||||||
const popconfirm = mount(
|
const popconfirm = mount(
|
||||||
{
|
{
|
||||||
render() {
|
render() {
|
||||||
|
@ -87,7 +86,6 @@ describe('Popconfirm', () => {
|
||||||
{ sync: false },
|
{ sync: false },
|
||||||
);
|
);
|
||||||
popconfirm.find('span').trigger('click');
|
popconfirm.find('span').trigger('click');
|
||||||
popconfirm.vm.$refs.popconfirm.$forceUpdate();
|
|
||||||
const popup = popconfirm.vm.$refs.popconfirm.getPopupDomNode();
|
const popup = popconfirm.vm.$refs.popconfirm.getPopupDomNode();
|
||||||
expect(popup).toBeFalsy();
|
expect(popup).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,159 +1,201 @@
|
||||||
import omit from 'omit.js';
|
import omit from 'omit.js';
|
||||||
import type { PropType } from 'vue';
|
import { computed, ExtractPropTypes, onMounted, PropType, ref, toRef } from 'vue';
|
||||||
import { defineComponent, inject } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
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, getComponent, mergeProps } from '../_util/props-util';
|
import { initDefaultProps } from '../_util/props-util';
|
||||||
import BaseMixin from '../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
import type { LegacyButtonType } from '../button/buttonTypes';
|
import type { ButtonProps, LegacyButtonType } from '../button/buttonTypes';
|
||||||
import { convertLegacyProps } from '../button/buttonTypes';
|
import { convertLegacyProps } from '../button/buttonTypes';
|
||||||
import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled';
|
import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled';
|
||||||
import Button from '../button';
|
import Button from '../button';
|
||||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
|
||||||
import defaultLocale from '../locale-provider/default';
|
import defaultLocale from '../locale-provider/default';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
|
||||||
import { withInstall } from '../_util/type';
|
import { withInstall } from '../_util/type';
|
||||||
|
import useMergedState from '../_util/hooks/useMergedState';
|
||||||
|
import devWarning from '../vc-util/devWarning';
|
||||||
|
import KeyCode from '../_util/KeyCode';
|
||||||
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
|
import classNames from '../_util/classNames';
|
||||||
|
import { getTransitionName } from '../_util/transition';
|
||||||
|
import { cloneVNodes } from '../_util/vnode';
|
||||||
|
|
||||||
const tooltipProps = abstractTooltipProps();
|
export const popconfirmProps = () => ({
|
||||||
|
...abstractTooltipProps(),
|
||||||
|
prefixCls: PropTypes.string,
|
||||||
|
content: PropTypes.any,
|
||||||
|
title: PropTypes.any,
|
||||||
|
okType: {
|
||||||
|
type: String as PropType<LegacyButtonType>,
|
||||||
|
default: 'primary',
|
||||||
|
},
|
||||||
|
disabled: PropTypes.looseBool.def(false),
|
||||||
|
okText: PropTypes.any,
|
||||||
|
cancelText: PropTypes.any,
|
||||||
|
icon: PropTypes.any,
|
||||||
|
okButtonProps: PropTypes.object,
|
||||||
|
cancelButtonProps: PropTypes.object,
|
||||||
|
});
|
||||||
|
|
||||||
|
export type PopconfirmProps = Partial<ExtractPropTypes<ReturnType<typeof popconfirmProps>>>;
|
||||||
|
|
||||||
|
export interface PopconfirmLocale {
|
||||||
|
okText: string;
|
||||||
|
cancelText: string;
|
||||||
|
}
|
||||||
|
|
||||||
const Popconfirm = defineComponent({
|
const Popconfirm = defineComponent({
|
||||||
name: 'APopconfirm',
|
name: 'APopconfirm',
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
props: {
|
props: initDefaultProps(popconfirmProps(), {
|
||||||
...tooltipProps,
|
trigger: 'click',
|
||||||
prefixCls: PropTypes.string,
|
transitionName: 'zoom-big',
|
||||||
transitionName: PropTypes.string.def('zoom-big'),
|
align: () => ({}),
|
||||||
content: PropTypes.any,
|
placement: 'top',
|
||||||
title: PropTypes.any,
|
mouseEnterDelay: 0.1,
|
||||||
trigger: tooltipProps.trigger.def('click'),
|
mouseLeaveDelay: 0.1,
|
||||||
okType: {
|
arrowPointAtCenter: false,
|
||||||
type: String as PropType<LegacyButtonType>,
|
autoAdjustOverflow: true,
|
||||||
default: 'primary',
|
okType: 'primary',
|
||||||
},
|
disabled: false,
|
||||||
disabled: PropTypes.looseBool.def(false),
|
}),
|
||||||
okText: PropTypes.any,
|
slots: ['title', 'content', 'okText', 'icon', 'cancelText', 'cancelButton', 'okButton'],
|
||||||
cancelText: PropTypes.any,
|
|
||||||
icon: PropTypes.any,
|
|
||||||
okButtonProps: PropTypes.object,
|
|
||||||
cancelButtonProps: PropTypes.object,
|
|
||||||
onConfirm: PropTypes.func,
|
|
||||||
onCancel: PropTypes.func,
|
|
||||||
onVisibleChange: PropTypes.func,
|
|
||||||
},
|
|
||||||
emits: ['update:visible', 'confirm', 'cancel', 'visibleChange'],
|
emits: ['update:visible', 'confirm', 'cancel', 'visibleChange'],
|
||||||
setup() {
|
setup(props: PopconfirmProps, { slots, emit, expose }) {
|
||||||
return {
|
onMounted(() => {
|
||||||
configProvider: inject('configProvider', defaultConfigProvider),
|
devWarning(
|
||||||
|
props.defaultVisible === undefined,
|
||||||
|
'Popconfirm',
|
||||||
|
`'defaultVisible' is deprecated, please use 'v-model:visible'`,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
const tooltipRef = ref();
|
||||||
|
|
||||||
|
expose({
|
||||||
|
getPopupDomNode: () => {
|
||||||
|
return tooltipRef.value?.getPopupDomNode?.();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
const [visible, setVisible] = useMergedState(false, {
|
||||||
|
value: toRef(props, 'visible'),
|
||||||
|
defaultValue: props.defaultVisible,
|
||||||
|
});
|
||||||
|
|
||||||
|
const settingVisible = (value: boolean, e?: MouseEvent | KeyboardEvent) => {
|
||||||
|
if (props.visible === undefined) {
|
||||||
|
setVisible(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
emit('update:visible', value);
|
||||||
|
emit('visibleChange', value, e);
|
||||||
};
|
};
|
||||||
},
|
|
||||||
data() {
|
|
||||||
const props = getOptionProps(this) as any;
|
|
||||||
const state = { sVisible: false };
|
|
||||||
if ('visible' in props) {
|
|
||||||
state.sVisible = props.visible;
|
|
||||||
}
|
|
||||||
if ('defaultVisible' in props) {
|
|
||||||
state.sVisible = props.defaultVisible;
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
visible(val) {
|
|
||||||
this.sVisible = val;
|
|
||||||
},
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
onConfirmHandle(e: Event) {
|
|
||||||
this.setVisible(false, e);
|
|
||||||
this.$emit('confirm', e);
|
|
||||||
},
|
|
||||||
|
|
||||||
onCancelHandle(e: Event) {
|
const onConfirm = (e: MouseEvent) => {
|
||||||
this.setVisible(false, e);
|
settingVisible(false, e);
|
||||||
this.$emit('cancel', e);
|
emit('confirm', e);
|
||||||
},
|
};
|
||||||
|
|
||||||
onVisibleChangeHandle(sVisible: boolean) {
|
const onCancel = (e: MouseEvent) => {
|
||||||
const { disabled } = this.$props;
|
settingVisible(false, e);
|
||||||
|
emit('cancel', e);
|
||||||
|
};
|
||||||
|
|
||||||
|
const onKeyDown = (e: KeyboardEvent) => {
|
||||||
|
if (e.keyCode === KeyCode.ESC && visible) {
|
||||||
|
settingVisible(false, e);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onVisibleChange = (value: boolean) => {
|
||||||
|
const { disabled } = props;
|
||||||
if (disabled) {
|
if (disabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.setVisible(sVisible);
|
settingVisible(value);
|
||||||
},
|
};
|
||||||
|
const { prefixCls: prefixClsConfirm, configProvider } = useConfigInject('popconfirm', props);
|
||||||
setVisible(sVisible: boolean, e?: Event) {
|
const rootPrefixCls = computed(() => configProvider.getPrefixCls());
|
||||||
if (!hasProp(this, 'visible')) {
|
const popoverPrefixCls = computed(() => configProvider.getPrefixCls('popover'));
|
||||||
this.setState({ sVisible });
|
const [popconfirmLocale] = useLocaleReceiver('Popconfirm', defaultLocale.Popconfirm);
|
||||||
}
|
const renderOverlay = () => {
|
||||||
this.$emit('update:visible', sVisible);
|
const {
|
||||||
this.$emit('visibleChange', sVisible, e);
|
okButtonProps,
|
||||||
},
|
cancelButtonProps,
|
||||||
getPopupDomNode() {
|
title = slots.title?.(),
|
||||||
return (this.$refs.tooltip as any).getPopupDomNode();
|
cancelText = slots.cancel?.(),
|
||||||
},
|
okText = slots.okText?.(),
|
||||||
renderOverlay(prefixCls: string, popconfirmLocale) {
|
okType,
|
||||||
const { okType, okButtonProps, cancelButtonProps } = this;
|
icon = slots.icon?.(),
|
||||||
const icon = getComponent(this, 'icon') || <ExclamationCircleFilled />;
|
} = props;
|
||||||
const cancelBtnProps = mergeProps({
|
const { cancelButton, okButton } = slots;
|
||||||
|
const cancelProps: ButtonProps = {
|
||||||
|
onClick: onCancel,
|
||||||
size: 'small',
|
size: 'small',
|
||||||
onClick: this.onCancelHandle,
|
|
||||||
...cancelButtonProps,
|
...cancelButtonProps,
|
||||||
});
|
};
|
||||||
const okBtnProps = mergeProps({
|
const okProps: ButtonProps = {
|
||||||
|
onClick: onConfirm,
|
||||||
...convertLegacyProps(okType),
|
...convertLegacyProps(okType),
|
||||||
size: 'small',
|
size: 'small',
|
||||||
onClick: this.onConfirmHandle,
|
|
||||||
...okButtonProps,
|
...okButtonProps,
|
||||||
});
|
};
|
||||||
return (
|
return (
|
||||||
<div class={`${prefixCls}-inner-content`}>
|
<div class={`${popoverPrefixCls.value}-inner-content`}>
|
||||||
<div class={`${prefixCls}-message`}>
|
<div class={`${popoverPrefixCls.value}-message`}>
|
||||||
{icon}
|
{icon || <ExclamationCircleFilled />}
|
||||||
<div class={`${prefixCls}-message-title`}>{getComponent(this, 'title')}</div>
|
<div class={`${popoverPrefixCls.value}-message-title`}>{title}</div>
|
||||||
</div>
|
</div>
|
||||||
<div class={`${prefixCls}-buttons`}>
|
<div class={`${popoverPrefixCls.value}-buttons`}>
|
||||||
<Button {...cancelBtnProps}>
|
{cancelButton ? (
|
||||||
{getComponent(this, 'cancelText') || popconfirmLocale.cancelText}
|
cancelButton(cancelProps)
|
||||||
</Button>
|
) : (
|
||||||
<Button {...okBtnProps}>
|
<Button {...cancelProps}>{cancelText || popconfirmLocale.value.cancelText}</Button>
|
||||||
{getComponent(this, 'okText') || popconfirmLocale.okText}
|
)}
|
||||||
</Button>
|
{okButton ? (
|
||||||
|
okButton(okProps)
|
||||||
|
) : (
|
||||||
|
<Button {...okProps}>{okText || popconfirmLocale.value.okText}</Button>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
const props = getOptionProps(this);
|
|
||||||
const { prefixCls: customizePrefixCls } = props;
|
|
||||||
const { getPrefixCls } = this.configProvider;
|
|
||||||
const prefixCls = getPrefixCls('popover', customizePrefixCls);
|
|
||||||
|
|
||||||
const otherProps = omit(props, [
|
|
||||||
'title',
|
|
||||||
'content',
|
|
||||||
'cancelText',
|
|
||||||
'okText',
|
|
||||||
'onUpdate:visible',
|
|
||||||
]);
|
|
||||||
const overlay = (
|
|
||||||
<LocaleReceiver
|
|
||||||
componentName="Popconfirm"
|
|
||||||
defaultLocale={defaultLocale.Popconfirm}
|
|
||||||
children={popconfirmLocale => this.renderOverlay(prefixCls, popconfirmLocale)}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
const tooltipProps = {
|
|
||||||
...otherProps,
|
|
||||||
title: overlay,
|
|
||||||
prefixCls,
|
|
||||||
visible: this.sVisible,
|
|
||||||
ref: 'tooltip',
|
|
||||||
onVisibleChange: this.onVisibleChangeHandle,
|
|
||||||
};
|
};
|
||||||
return <Tooltip {...tooltipProps}>{this.$slots?.default()}</Tooltip>;
|
|
||||||
|
return () => {
|
||||||
|
const { placement, overlayClassName, ...restProps } = props;
|
||||||
|
const otherProps = omit(restProps, [
|
||||||
|
'title',
|
||||||
|
'content',
|
||||||
|
'cancelText',
|
||||||
|
'okText',
|
||||||
|
'onUpdate:visible',
|
||||||
|
]);
|
||||||
|
const overlayClassNames = classNames(prefixClsConfirm.value, overlayClassName);
|
||||||
|
return (
|
||||||
|
<Tooltip
|
||||||
|
{...otherProps}
|
||||||
|
prefixCls={popoverPrefixCls.value}
|
||||||
|
placement={placement}
|
||||||
|
onVisibleChange={onVisibleChange}
|
||||||
|
visible={visible.value}
|
||||||
|
overlayClassName={overlayClassNames}
|
||||||
|
transitionName={getTransitionName(rootPrefixCls.value, 'zoom-big', props.transitionName)}
|
||||||
|
v-slots={{ title: renderOverlay }}
|
||||||
|
ref={tooltipRef}
|
||||||
|
>
|
||||||
|
{cloneVNodes(
|
||||||
|
slots.default?.() || [],
|
||||||
|
{
|
||||||
|
onKeydown: (e: KeyboardEvent) => {
|
||||||
|
onKeyDown(e);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
false,
|
||||||
|
)}
|
||||||
|
</Tooltip>
|
||||||
|
);
|
||||||
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
export default withInstall(Popconfirm);
|
export default withInstall(Popconfirm);
|
||||||
|
|
|
@ -0,0 +1,8 @@
|
||||||
|
@import '../../style/themes/index';
|
||||||
|
@import '../../style/mixins/index';
|
||||||
|
|
||||||
|
@popconfirm-prefix-cls: ~'@{ant-prefix}-popconfirm';
|
||||||
|
|
||||||
|
.@{popconfirm-prefix-cls} {
|
||||||
|
z-index: @zindex-popoconfirm;
|
||||||
|
}
|
|
@ -4,3 +4,5 @@ import '../../style/index.less';
|
||||||
// deps-lint-skip: tooltip, popover
|
// deps-lint-skip: tooltip, popover
|
||||||
import '../../popover/style';
|
import '../../popover/style';
|
||||||
import '../../button/style';
|
import '../../button/style';
|
||||||
|
|
||||||
|
import './index.less';
|
|
@ -323,8 +323,8 @@
|
||||||
@layout-trigger-color-light: @text-color;
|
@layout-trigger-color-light: @text-color;
|
||||||
|
|
||||||
// z-index list, order by `z-index`
|
// z-index list, order by `z-index`
|
||||||
@zindex-badge: 1;
|
@zindex-badge: auto;
|
||||||
@zindex-table-fixed: 1;
|
@zindex-table-fixed: 2;
|
||||||
@zindex-affix: 10;
|
@zindex-affix: 10;
|
||||||
@zindex-back-top: 10;
|
@zindex-back-top: 10;
|
||||||
@zindex-picker-panel: 10;
|
@zindex-picker-panel: 10;
|
||||||
|
@ -336,7 +336,8 @@
|
||||||
@zindex-popover: 1030;
|
@zindex-popover: 1030;
|
||||||
@zindex-dropdown: 1050;
|
@zindex-dropdown: 1050;
|
||||||
@zindex-picker: 1050;
|
@zindex-picker: 1050;
|
||||||
@zindex-tooltip: 1060;
|
@zindex-popoconfirm: 1060;
|
||||||
|
@zindex-tooltip: 1070;
|
||||||
@zindex-image: 1080;
|
@zindex-image: 1080;
|
||||||
|
|
||||||
// Animation
|
// Animation
|
||||||
|
|
|
@ -6,12 +6,13 @@ import classNames from '../_util/classNames';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import { PresetColorTypes } from '../_util/colors';
|
import { PresetColorTypes } from '../_util/colors';
|
||||||
import warning from '../_util/warning';
|
import warning from '../_util/warning';
|
||||||
import { getPropsSlot, getStyle, filterEmpty, isValidElement } from '../_util/props-util';
|
import { getStyle, filterEmpty, isValidElement, initDefaultProps } from '../_util/props-util';
|
||||||
import { cloneElement } from '../_util/vnode';
|
import { cloneElement } from '../_util/vnode';
|
||||||
import type { triggerTypes, placementTypes } from './abstractTooltipProps';
|
import type { triggerTypes, placementTypes } from './abstractTooltipProps';
|
||||||
import abstractTooltipProps from './abstractTooltipProps';
|
import abstractTooltipProps from './abstractTooltipProps';
|
||||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
import getPlacements, { AdjustOverflow, PlacementsConfig } from './placements';
|
import getPlacements, { AdjustOverflow, PlacementsConfig } from './placements';
|
||||||
|
import firstNotUndefined from '../_util/firstNotUndefined';
|
||||||
|
|
||||||
export { AdjustOverflow, PlacementsConfig };
|
export { AdjustOverflow, PlacementsConfig };
|
||||||
|
|
||||||
|
@ -40,36 +41,45 @@ const splitObject = (obj: any, keys: string[]) => {
|
||||||
});
|
});
|
||||||
return { picked, omitted };
|
return { picked, omitted };
|
||||||
};
|
};
|
||||||
const props = abstractTooltipProps();
|
|
||||||
|
|
||||||
const PresetColorRegex = new RegExp(`^(${PresetColorTypes.join('|')})(-inverse)?$`);
|
const PresetColorRegex = new RegExp(`^(${PresetColorTypes.join('|')})(-inverse)?$`);
|
||||||
|
|
||||||
export const tooltipProps = {
|
export const tooltipProps = () => ({
|
||||||
...props,
|
...abstractTooltipProps(),
|
||||||
title: PropTypes.VNodeChild,
|
title: PropTypes.any,
|
||||||
};
|
});
|
||||||
|
|
||||||
export type TriggerTypes = typeof triggerTypes[number];
|
export type TriggerTypes = typeof triggerTypes[number];
|
||||||
|
|
||||||
export type PlacementTypes = typeof placementTypes[number];
|
export type PlacementTypes = typeof placementTypes[number];
|
||||||
|
|
||||||
export type TooltipProps = Partial<ExtractPropTypes<typeof tooltipProps>>;
|
export type TooltipProps = Partial<ExtractPropTypes<ReturnType<typeof tooltipProps>>>;
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'ATooltip',
|
name: 'ATooltip',
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
props: tooltipProps,
|
props: initDefaultProps(tooltipProps(), {
|
||||||
|
trigger: 'hover',
|
||||||
|
transitionName: 'zoom-big-fast',
|
||||||
|
align: () => ({}),
|
||||||
|
placement: 'top',
|
||||||
|
mouseEnterDelay: 0.1,
|
||||||
|
mouseLeaveDelay: 0.1,
|
||||||
|
arrowPointAtCenter: false,
|
||||||
|
autoAdjustOverflow: true,
|
||||||
|
}),
|
||||||
|
slots: ['title'],
|
||||||
emits: ['update:visible', 'visibleChange'],
|
emits: ['update:visible', 'visibleChange'],
|
||||||
setup(props, { slots, emit, attrs, expose }) {
|
setup(props, { slots, emit, attrs, expose }) {
|
||||||
const { prefixCls, getTargetContainer } = useConfigInject('tooltip', props);
|
const { prefixCls, getTargetContainer } = useConfigInject('tooltip', props);
|
||||||
|
|
||||||
const visible = ref(false);
|
const visible = ref(firstNotUndefined([props.visible, props.defaultVisible]));
|
||||||
|
|
||||||
const tooltip = ref();
|
const tooltip = ref();
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
warning(
|
warning(
|
||||||
!('default-visible' in attrs) || !('defaultVisible' in attrs),
|
props.defaultVisible === undefined,
|
||||||
'Tooltip',
|
'Tooltip',
|
||||||
`'defaultVisible' is deprecated, please use 'v-model:visible'`,
|
`'defaultVisible' is deprecated, please use 'v-model:visible'`,
|
||||||
);
|
);
|
||||||
|
@ -79,11 +89,10 @@ export default defineComponent({
|
||||||
val => {
|
val => {
|
||||||
visible.value = !!val;
|
visible.value = !!val;
|
||||||
},
|
},
|
||||||
{ immediate: true },
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const isNoTitle = () => {
|
const isNoTitle = () => {
|
||||||
const title = getPropsSlot(slots, props, 'title');
|
const title = props.title ?? slots.title;
|
||||||
return !title && title !== 0;
|
return !title && title !== 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -164,8 +173,7 @@ export default defineComponent({
|
||||||
};
|
};
|
||||||
|
|
||||||
const getOverlay = () => {
|
const getOverlay = () => {
|
||||||
const title = getPropsSlot(slots, props, 'title');
|
return props.title ?? slots.title?.();
|
||||||
return title ?? '';
|
|
||||||
};
|
};
|
||||||
|
|
||||||
const onPopupAlign = (domNode: HTMLElement, align: any) => {
|
const onPopupAlign = (domNode: HTMLElement, align: any) => {
|
||||||
|
@ -234,7 +242,6 @@ export default defineComponent({
|
||||||
prefixCls: prefixCls.value,
|
prefixCls: prefixCls.value,
|
||||||
getTooltipContainer: getPopupContainer || getTargetContainer.value,
|
getTooltipContainer: getPopupContainer || getTargetContainer.value,
|
||||||
builtinPlacements: tooltipPlacements.value,
|
builtinPlacements: tooltipPlacements.value,
|
||||||
overlay: getOverlay(),
|
|
||||||
visible: tempVisible,
|
visible: tempVisible,
|
||||||
ref: tooltip,
|
ref: tooltip,
|
||||||
overlayClassName: customOverlayClassName,
|
overlayClassName: customOverlayClassName,
|
||||||
|
@ -249,6 +256,7 @@ export default defineComponent({
|
||||||
arrowContent: () => (
|
arrowContent: () => (
|
||||||
<span class={`${prefixCls.value}-arrow-content`} style={arrowContentStyle}></span>
|
<span class={`${prefixCls.value}-arrow-content`} style={arrowContentStyle}></span>
|
||||||
),
|
),
|
||||||
|
overlay: getOverlay,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{visible.value ? cloneElement(child, { class: childCls }) : child}
|
{visible.value ? cloneElement(child, { class: childCls }) : child}
|
||||||
|
|
|
@ -21,23 +21,23 @@ export default () => ({
|
||||||
trigger: PropTypes.oneOfType([
|
trigger: PropTypes.oneOfType([
|
||||||
PropTypes.oneOf(triggerTypes),
|
PropTypes.oneOf(triggerTypes),
|
||||||
PropTypes.arrayOf(PropTypes.oneOf(triggerTypes)),
|
PropTypes.arrayOf(PropTypes.oneOf(triggerTypes)),
|
||||||
]).def('hover'),
|
]),
|
||||||
visible: PropTypes.looseBool,
|
visible: PropTypes.looseBool,
|
||||||
// defaultVisible: PropTypes.looseBool,
|
defaultVisible: PropTypes.looseBool,
|
||||||
placement: PropTypes.oneOf(placementTypes).def('top'),
|
placement: PropTypes.oneOf(placementTypes),
|
||||||
color: PropTypes.string,
|
color: PropTypes.string,
|
||||||
transitionName: PropTypes.string.def('zoom-big-fast'),
|
transitionName: PropTypes.string,
|
||||||
overlayStyle: PropTypes.object.def(() => ({})),
|
overlayStyle: PropTypes.style,
|
||||||
overlayClassName: PropTypes.string,
|
overlayClassName: PropTypes.string,
|
||||||
openClassName: PropTypes.string,
|
openClassName: PropTypes.string,
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
mouseEnterDelay: PropTypes.number.def(0.1),
|
mouseEnterDelay: PropTypes.number,
|
||||||
mouseLeaveDelay: PropTypes.number.def(0.1),
|
mouseLeaveDelay: PropTypes.number,
|
||||||
getPopupContainer: PropTypes.func,
|
getPopupContainer: PropTypes.func,
|
||||||
arrowPointAtCenter: PropTypes.looseBool.def(false),
|
arrowPointAtCenter: PropTypes.looseBool,
|
||||||
autoAdjustOverflow: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]).def(true),
|
autoAdjustOverflow: PropTypes.oneOfType([PropTypes.looseBool, PropTypes.object]),
|
||||||
destroyTooltipOnHide: PropTypes.looseBool.def(false),
|
destroyTooltipOnHide: PropTypes.looseBool,
|
||||||
align: PropTypes.object.def(() => ({})),
|
align: PropTypes.object,
|
||||||
builtinPlacements: PropTypes.object,
|
builtinPlacements: PropTypes.object,
|
||||||
children: PropTypes.array,
|
children: PropTypes.array,
|
||||||
onVisibleChange: PropTypes.func,
|
onVisibleChange: PropTypes.func,
|
||||||
|
|
|
@ -22,7 +22,7 @@ export default defineComponent({
|
||||||
openClassName: PropTypes.string,
|
openClassName: PropTypes.string,
|
||||||
animation: PropTypes.any,
|
animation: PropTypes.any,
|
||||||
align: PropTypes.object,
|
align: PropTypes.object,
|
||||||
overlayStyle: PropTypes.object.def(() => ({})),
|
overlayStyle: PropTypes.style,
|
||||||
placement: PropTypes.string.def('bottomLeft'),
|
placement: PropTypes.string.def('bottomLeft'),
|
||||||
overlay: PropTypes.any,
|
overlay: PropTypes.any,
|
||||||
trigger: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]).def(
|
trigger: PropTypes.oneOfType([PropTypes.string, PropTypes.arrayOf(PropTypes.string)]).def(
|
||||||
|
|
|
@ -4,7 +4,6 @@ import PropTypes from '../../_util/vue-types';
|
||||||
|
|
||||||
const tooltipContentProps = {
|
const tooltipContentProps = {
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
overlay: PropTypes.any,
|
|
||||||
id: PropTypes.string,
|
id: PropTypes.string,
|
||||||
overlayInnerStyle: PropTypes.any,
|
overlayInnerStyle: PropTypes.any,
|
||||||
};
|
};
|
||||||
|
@ -14,7 +13,8 @@ export type TooltipContentProps = Partial<ExtractPropTypes<typeof tooltipContent
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Content',
|
name: 'Content',
|
||||||
props: tooltipContentProps,
|
props: tooltipContentProps,
|
||||||
setup(props: TooltipContentProps) {
|
slots: ['overlay'],
|
||||||
|
setup(props: TooltipContentProps, { slots }) {
|
||||||
return () => (
|
return () => (
|
||||||
<div
|
<div
|
||||||
class={`${props.prefixCls}-inner`}
|
class={`${props.prefixCls}-inner`}
|
||||||
|
@ -22,7 +22,7 @@ export default defineComponent({
|
||||||
role="tooltip"
|
role="tooltip"
|
||||||
style={props.overlayInnerStyle}
|
style={props.overlayInnerStyle}
|
||||||
>
|
>
|
||||||
{typeof props.overlay === 'function' ? props.overlay() : props.overlay}
|
{slots.overlay?.()}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -16,8 +16,7 @@ export default defineComponent({
|
||||||
transitionName: PropTypes.string,
|
transitionName: PropTypes.string,
|
||||||
animation: PropTypes.any,
|
animation: PropTypes.any,
|
||||||
afterVisibleChange: PropTypes.func.def(() => {}),
|
afterVisibleChange: PropTypes.func.def(() => {}),
|
||||||
overlay: PropTypes.any,
|
overlayStyle: PropTypes.style,
|
||||||
overlayStyle: PropTypes.object,
|
|
||||||
overlayClassName: PropTypes.string,
|
overlayClassName: PropTypes.string,
|
||||||
prefixCls: PropTypes.string.def('rc-tooltip'),
|
prefixCls: PropTypes.string.def('rc-tooltip'),
|
||||||
mouseEnterDelay: PropTypes.number.def(0.1),
|
mouseEnterDelay: PropTypes.number.def(0.1),
|
||||||
|
@ -47,8 +46,8 @@ export default defineComponent({
|
||||||
key="content"
|
key="content"
|
||||||
prefixCls={prefixCls}
|
prefixCls={prefixCls}
|
||||||
id={tipId}
|
id={tipId}
|
||||||
overlay={getPropsSlot(slots, props, 'overlay')}
|
|
||||||
overlayInnerStyle={overlayInnerStyle}
|
overlayInnerStyle={overlayInnerStyle}
|
||||||
|
v-slots={{ overlay: slots.overlay }}
|
||||||
/>,
|
/>,
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
|
|
|
@ -55,7 +55,7 @@ export default defineComponent({
|
||||||
onPopupVisibleChange: PropTypes.func.def(noop),
|
onPopupVisibleChange: PropTypes.func.def(noop),
|
||||||
afterPopupVisibleChange: PropTypes.func.def(noop),
|
afterPopupVisibleChange: PropTypes.func.def(noop),
|
||||||
popup: PropTypes.any,
|
popup: PropTypes.any,
|
||||||
popupStyle: PropTypes.object.def(() => ({})),
|
popupStyle: PropTypes.style,
|
||||||
prefixCls: PropTypes.string.def('rc-trigger-popup'),
|
prefixCls: PropTypes.string.def('rc-trigger-popup'),
|
||||||
popupClassName: PropTypes.string.def(''),
|
popupClassName: PropTypes.string.def(''),
|
||||||
popupPlacement: PropTypes.string,
|
popupPlacement: PropTypes.string,
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
import demo from '../v2-doc/src/docs/collapse/demo/index.vue';
|
import demo from '../v2-doc/src/docs/popconfirm/demo/index.vue';
|
||||||
// import Affix from '../components/affix';
|
// import Affix from '../components/affix';
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: {
|
components: {
|
||||||
|
|
Loading…
Reference in New Issue