feat: message support configprovider.config
parent
bcd69f0008
commit
322158d2be
|
@ -1,28 +1,30 @@
|
||||||
import type { CSSProperties, VNodeTypes } from 'vue';
|
import type { CSSProperties } from 'vue';
|
||||||
import Notification from '../vc-notification';
|
import Notification from '../vc-notification';
|
||||||
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
|
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
|
||||||
import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled';
|
import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled';
|
||||||
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
|
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
|
||||||
import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled';
|
import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled';
|
||||||
import InfoCircleFilled from '@ant-design/icons-vue/InfoCircleFilled';
|
import InfoCircleFilled from '@ant-design/icons-vue/InfoCircleFilled';
|
||||||
|
import type { VueNode } from '../_util/type';
|
||||||
|
|
||||||
let defaultDuration = 3;
|
let defaultDuration = 3;
|
||||||
let defaultTop: string;
|
let defaultTop: string;
|
||||||
let messageInstance: any;
|
let messageInstance: any;
|
||||||
let key = 1;
|
let key = 1;
|
||||||
let prefixCls = 'ant-message';
|
let localPrefixCls = '';
|
||||||
let transitionName = 'move-up';
|
let transitionName = 'move-up';
|
||||||
let getContainer = () => document.body;
|
let getContainer = () => document.body;
|
||||||
let maxCount: number;
|
let maxCount: number;
|
||||||
|
|
||||||
function getMessageInstance(callback: (i: any) => void) {
|
function getMessageInstance(args: MessageArgsProps, callback: (i: any) => void) {
|
||||||
if (messageInstance) {
|
if (messageInstance) {
|
||||||
callback(messageInstance);
|
callback(messageInstance);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Notification.newInstance(
|
Notification.newInstance(
|
||||||
{
|
{
|
||||||
prefixCls,
|
prefixCls: args.prefixCls || localPrefixCls,
|
||||||
|
rootPrefixCls: args.rootPrefixCls,
|
||||||
transitionName,
|
transitionName,
|
||||||
style: { top: defaultTop }, // 覆盖原来的样式
|
style: { top: defaultTop }, // 覆盖原来的样式
|
||||||
getContainer,
|
getContainer,
|
||||||
|
@ -60,20 +62,21 @@ export interface MessageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MessageArgsProps {
|
export interface MessageArgsProps {
|
||||||
content: VNodeTypes;
|
content: string | (() => VueNode) | VueNode;
|
||||||
duration: number | null;
|
duration: number | null;
|
||||||
type: NoticeType;
|
type: NoticeType;
|
||||||
|
prefixCls?: string;
|
||||||
|
rootPrefixCls?: string;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
icon?: VNodeTypes;
|
icon?: (() => VueNode) | VueNode;
|
||||||
key?: string | number;
|
key?: string | number;
|
||||||
style?: CSSProperties;
|
style?: CSSProperties;
|
||||||
class?: string;
|
class?: string;
|
||||||
|
appContext?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
function notice(args: MessageArgsProps): MessageType {
|
function notice(args: MessageArgsProps): MessageType {
|
||||||
const duration = args.duration !== undefined ? args.duration : defaultDuration;
|
const duration = args.duration !== undefined ? args.duration : defaultDuration;
|
||||||
const Icon = iconMap[args.type];
|
|
||||||
const iconNode = Icon ? <Icon /> : '';
|
|
||||||
|
|
||||||
const target = args.key || key++;
|
const target = args.key || key++;
|
||||||
const closePromise = new Promise(resolve => {
|
const closePromise = new Promise(resolve => {
|
||||||
|
@ -83,19 +86,22 @@ function notice(args: MessageArgsProps): MessageType {
|
||||||
}
|
}
|
||||||
return resolve(true);
|
return resolve(true);
|
||||||
};
|
};
|
||||||
getMessageInstance(instance => {
|
getMessageInstance(args, instance => {
|
||||||
instance.notice({
|
instance.notice({
|
||||||
key: target,
|
key: target,
|
||||||
duration,
|
duration,
|
||||||
style: args.style || {},
|
style: args.style || {},
|
||||||
class: args.class,
|
class: args.class,
|
||||||
content: () => {
|
appContext: args.appContext,
|
||||||
|
content: ({ prefixCls }) => {
|
||||||
|
const Icon = iconMap[args.type];
|
||||||
|
const iconNode = Icon ? <Icon /> : '';
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
class={`${prefixCls}-custom-content${args.type ? ` ${prefixCls}-${args.type}` : ''}`}
|
class={`${prefixCls}-custom-content${args.type ? ` ${prefixCls}-${args.type}` : ''}`}
|
||||||
>
|
>
|
||||||
{args.icon || iconNode}
|
{typeof args.icon === 'function' ? args.icon : args.icon || iconNode}
|
||||||
<span>{args.content}</span>
|
<span>{typeof args.content === 'function' ? args.content() : args.content}</span>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
@ -115,7 +121,7 @@ function notice(args: MessageArgsProps): MessageType {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ConfigDuration = number | (() => void);
|
type ConfigDuration = number | (() => void);
|
||||||
type JointContent = VNodeTypes | MessageArgsProps;
|
type JointContent = VueNode | MessageArgsProps;
|
||||||
export type ConfigOnClose = () => void;
|
export type ConfigOnClose = () => void;
|
||||||
|
|
||||||
function isArgsProps(content: JointContent): content is MessageArgsProps {
|
function isArgsProps(content: JointContent): content is MessageArgsProps {
|
||||||
|
@ -145,7 +151,7 @@ const api: any = {
|
||||||
defaultDuration = options.duration;
|
defaultDuration = options.duration;
|
||||||
}
|
}
|
||||||
if (options.prefixCls !== undefined) {
|
if (options.prefixCls !== undefined) {
|
||||||
prefixCls = options.prefixCls;
|
localPrefixCls = options.prefixCls;
|
||||||
}
|
}
|
||||||
if (options.getContainer !== undefined) {
|
if (options.getContainer !== undefined) {
|
||||||
getContainer = options.getContainer;
|
getContainer = options.getContainer;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import type { ExtractPropTypes, VNodeTypes, CSSProperties, PropType } from 'vue';
|
import type { ExtractPropTypes, CSSProperties, PropType } from 'vue';
|
||||||
import { defineComponent, inject, computed } from 'vue';
|
import { defineComponent, inject, computed } from 'vue';
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import Dialog from '../vc-dialog';
|
import Dialog from '../vc-dialog';
|
||||||
|
@ -13,6 +13,7 @@ import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||||
import { getComponent, getSlot } from '../_util/props-util';
|
import { getComponent, getSlot } from '../_util/props-util';
|
||||||
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
import { defaultConfigProvider } from '../config-provider';
|
||||||
|
import type { VueNode } from '../_util/type';
|
||||||
|
|
||||||
let mousePosition: { x: number; y: number } | null = null;
|
let mousePosition: { x: number; y: number } | null = null;
|
||||||
// ref: https://github.com/ant-design/ant-design/issues/15795
|
// ref: https://github.com/ant-design/ant-design/issues/15795
|
||||||
|
@ -95,9 +96,9 @@ export interface ModalFuncProps {
|
||||||
prefixCls?: string;
|
prefixCls?: string;
|
||||||
class?: string;
|
class?: string;
|
||||||
visible?: boolean;
|
visible?: boolean;
|
||||||
title?: string | (() => VNodeTypes) | VNodeTypes;
|
title?: string | (() => VueNode) | VueNode;
|
||||||
closable?: boolean;
|
closable?: boolean;
|
||||||
content?: string | (() => VNodeTypes) | VNodeTypes;
|
content?: string | (() => VueNode) | VueNode;
|
||||||
// TODO: find out exact types
|
// TODO: find out exact types
|
||||||
onOk?: (...args: any[]) => any;
|
onOk?: (...args: any[]) => any;
|
||||||
onCancel?: (...args: any[]) => any;
|
onCancel?: (...args: any[]) => any;
|
||||||
|
@ -105,10 +106,10 @@ export interface ModalFuncProps {
|
||||||
cancelButtonProps?: ButtonPropsType;
|
cancelButtonProps?: ButtonPropsType;
|
||||||
centered?: boolean;
|
centered?: boolean;
|
||||||
width?: string | number;
|
width?: string | number;
|
||||||
okText?: string | (() => VNodeTypes) | VNodeTypes;
|
okText?: string | (() => VueNode) | VueNode;
|
||||||
okType?: LegacyButtonType;
|
okType?: LegacyButtonType;
|
||||||
cancelText?: string | (() => VNodeTypes) | VNodeTypes;
|
cancelText?: string | (() => VueNode) | VueNode;
|
||||||
icon?: (() => VNodeTypes) | VNodeTypes;
|
icon?: (() => VueNode) | VueNode;
|
||||||
/* Deprecated */
|
/* Deprecated */
|
||||||
iconType?: string;
|
iconType?: string;
|
||||||
mask?: boolean;
|
mask?: boolean;
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { createApp, defineComponent } from 'vue';
|
import { defineComponent, createVNode, render as vueRender, onMounted, ref, nextTick } from 'vue';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import { getComponent } from '../_util/props-util';
|
import { getComponent } from '../_util/props-util';
|
||||||
import BaseMixin from '../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
import createChainedFunction from '../_util/createChainedFunction';
|
import createChainedFunction from '../_util/createChainedFunction';
|
||||||
import Notice from './Notice';
|
import Notice from './Notice';
|
||||||
import { getTransitionGroupProps, TransitionGroup } from '../_util/transition';
|
import { getTransitionGroupProps, TransitionGroup } from '../_util/transition';
|
||||||
|
import ConfigProvider, { globalConfig } from '../config-provider';
|
||||||
|
|
||||||
function noop() {}
|
function noop() {}
|
||||||
|
|
||||||
|
@ -95,7 +96,9 @@ const Notification = defineComponent({
|
||||||
key,
|
key,
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<Notice {...noticeProps}>{typeof content === 'function' ? content() : content}</Notice>
|
<Notice {...noticeProps}>
|
||||||
|
{typeof content === 'function' ? content({ prefixCls }) : content}
|
||||||
|
</Notice>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
const className = {
|
const className = {
|
||||||
|
@ -120,7 +123,13 @@ const Notification = defineComponent({
|
||||||
});
|
});
|
||||||
|
|
||||||
Notification.newInstance = function newNotificationInstance(properties, callback) {
|
Notification.newInstance = function newNotificationInstance(properties, callback) {
|
||||||
const { getContainer, style, class: className, ...props } = properties || {};
|
const {
|
||||||
|
getContainer,
|
||||||
|
appContext,
|
||||||
|
prefixCls: customizePrefixCls,
|
||||||
|
rootPrefixCls: customRootPrefixCls,
|
||||||
|
...props
|
||||||
|
} = properties || {};
|
||||||
const div = document.createElement('div');
|
const div = document.createElement('div');
|
||||||
if (getContainer) {
|
if (getContainer) {
|
||||||
const root = getContainer();
|
const root = getContainer();
|
||||||
|
@ -128,37 +137,43 @@ Notification.newInstance = function newNotificationInstance(properties, callback
|
||||||
} else {
|
} else {
|
||||||
document.body.appendChild(div);
|
document.body.appendChild(div);
|
||||||
}
|
}
|
||||||
const app = createApp({
|
let vm = null;
|
||||||
mounted() {
|
const Wrapper = defineComponent({
|
||||||
const self = this;
|
setup(_props, { attrs }) {
|
||||||
this.$nextTick(() => {
|
const notiRef = ref();
|
||||||
callback({
|
onMounted(() => {
|
||||||
notice(noticeProps) {
|
nextTick(() => {
|
||||||
self.$refs.notification.add(noticeProps);
|
callback({
|
||||||
},
|
notice(noticeProps) {
|
||||||
removeNotice(key) {
|
notiRef.value?.add(noticeProps);
|
||||||
self.$refs.notification.remove(key);
|
},
|
||||||
},
|
removeNotice(key) {
|
||||||
component: self,
|
notiRef.value?.remove(key);
|
||||||
destroy() {
|
},
|
||||||
app.unmount(div);
|
destroy() {
|
||||||
if (div.parentNode) {
|
vm?.unmount(div);
|
||||||
div.parentNode.removeChild(div);
|
if (div.parentNode) {
|
||||||
}
|
div.parentNode.removeChild(div);
|
||||||
},
|
}
|
||||||
|
},
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
return () => {
|
||||||
render() {
|
const { getPrefixCls, getRootPrefixCls } = globalConfig();
|
||||||
const p = {
|
const prefixCls = getPrefixCls('message', customizePrefixCls);
|
||||||
...props,
|
const rootPrefixCls = getRootPrefixCls(customRootPrefixCls, prefixCls);
|
||||||
ref: 'notification',
|
return (
|
||||||
style,
|
<ConfigProvider prefixCls={rootPrefixCls}>
|
||||||
class: className,
|
<Notification ref={notiRef} {...attrs} prefixCls={prefixCls} />
|
||||||
|
</ConfigProvider>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
return <Notification {...p} />;
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
app.mount(div);
|
|
||||||
|
vm = createVNode(Wrapper, props);
|
||||||
|
vm.appContext = appContext || vm.appContext;
|
||||||
|
vueRender(vm, div);
|
||||||
};
|
};
|
||||||
export default Notification;
|
export default Notification;
|
||||||
|
|
Loading…
Reference in New Issue