From 322158d2be9a5c4df966adc58d1296b5acadcedb Mon Sep 17 00:00:00 2001 From: tangjinzhou <415800467@qq.com> Date: Sat, 18 Sep 2021 19:23:52 +0800 Subject: [PATCH] feat: message support configprovider.config --- components/message/index.tsx | 34 ++++++---- components/modal/Modal.tsx | 13 ++-- components/vc-notification/Notification.jsx | 75 ++++++++++++--------- 3 files changed, 72 insertions(+), 50 deletions(-) diff --git a/components/message/index.tsx b/components/message/index.tsx index 7bc555a1d..b0ea95c4b 100644 --- a/components/message/index.tsx +++ b/components/message/index.tsx @@ -1,28 +1,30 @@ -import type { CSSProperties, VNodeTypes } from 'vue'; +import type { CSSProperties } from 'vue'; import Notification from '../vc-notification'; import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined'; import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled'; import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled'; import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled'; import InfoCircleFilled from '@ant-design/icons-vue/InfoCircleFilled'; +import type { VueNode } from '../_util/type'; let defaultDuration = 3; let defaultTop: string; let messageInstance: any; let key = 1; -let prefixCls = 'ant-message'; +let localPrefixCls = ''; let transitionName = 'move-up'; let getContainer = () => document.body; let maxCount: number; -function getMessageInstance(callback: (i: any) => void) { +function getMessageInstance(args: MessageArgsProps, callback: (i: any) => void) { if (messageInstance) { callback(messageInstance); return; } Notification.newInstance( { - prefixCls, + prefixCls: args.prefixCls || localPrefixCls, + rootPrefixCls: args.rootPrefixCls, transitionName, style: { top: defaultTop }, // 覆盖原来的样式 getContainer, @@ -60,20 +62,21 @@ export interface MessageType { } export interface MessageArgsProps { - content: VNodeTypes; + content: string | (() => VueNode) | VueNode; duration: number | null; type: NoticeType; + prefixCls?: string; + rootPrefixCls?: string; onClose?: () => void; - icon?: VNodeTypes; + icon?: (() => VueNode) | VueNode; key?: string | number; style?: CSSProperties; class?: string; + appContext?: any; } function notice(args: MessageArgsProps): MessageType { const duration = args.duration !== undefined ? args.duration : defaultDuration; - const Icon = iconMap[args.type]; - const iconNode = Icon ? : ''; const target = args.key || key++; const closePromise = new Promise(resolve => { @@ -83,19 +86,22 @@ function notice(args: MessageArgsProps): MessageType { } return resolve(true); }; - getMessageInstance(instance => { + getMessageInstance(args, instance => { instance.notice({ key: target, duration, style: args.style || {}, class: args.class, - content: () => { + appContext: args.appContext, + content: ({ prefixCls }) => { + const Icon = iconMap[args.type]; + const iconNode = Icon ? : ''; return (
- {args.icon || iconNode} - {args.content} + {typeof args.icon === 'function' ? args.icon : args.icon || iconNode} + {typeof args.content === 'function' ? args.content() : args.content}
); }, @@ -115,7 +121,7 @@ function notice(args: MessageArgsProps): MessageType { } type ConfigDuration = number | (() => void); -type JointContent = VNodeTypes | MessageArgsProps; +type JointContent = VueNode | MessageArgsProps; export type ConfigOnClose = () => void; function isArgsProps(content: JointContent): content is MessageArgsProps { @@ -145,7 +151,7 @@ const api: any = { defaultDuration = options.duration; } if (options.prefixCls !== undefined) { - prefixCls = options.prefixCls; + localPrefixCls = options.prefixCls; } if (options.getContainer !== undefined) { getContainer = options.getContainer; diff --git a/components/modal/Modal.tsx b/components/modal/Modal.tsx index 4066abed8..dd1ec7158 100644 --- a/components/modal/Modal.tsx +++ b/components/modal/Modal.tsx @@ -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 classNames from '../_util/classNames'; import Dialog from '../vc-dialog'; @@ -13,6 +13,7 @@ import LocaleReceiver from '../locale-provider/LocaleReceiver'; import { getComponent, getSlot } from '../_util/props-util'; import initDefaultProps from '../_util/props-util/initDefaultProps'; import { defaultConfigProvider } from '../config-provider'; +import type { VueNode } from '../_util/type'; let mousePosition: { x: number; y: number } | null = null; // ref: https://github.com/ant-design/ant-design/issues/15795 @@ -95,9 +96,9 @@ export interface ModalFuncProps { prefixCls?: string; class?: string; visible?: boolean; - title?: string | (() => VNodeTypes) | VNodeTypes; + title?: string | (() => VueNode) | VueNode; closable?: boolean; - content?: string | (() => VNodeTypes) | VNodeTypes; + content?: string | (() => VueNode) | VueNode; // TODO: find out exact types onOk?: (...args: any[]) => any; onCancel?: (...args: any[]) => any; @@ -105,10 +106,10 @@ export interface ModalFuncProps { cancelButtonProps?: ButtonPropsType; centered?: boolean; width?: string | number; - okText?: string | (() => VNodeTypes) | VNodeTypes; + okText?: string | (() => VueNode) | VueNode; okType?: LegacyButtonType; - cancelText?: string | (() => VNodeTypes) | VNodeTypes; - icon?: (() => VNodeTypes) | VNodeTypes; + cancelText?: string | (() => VueNode) | VueNode; + icon?: (() => VueNode) | VueNode; /* Deprecated */ iconType?: string; mask?: boolean; diff --git a/components/vc-notification/Notification.jsx b/components/vc-notification/Notification.jsx index 28d0a7d8b..b138e41fc 100644 --- a/components/vc-notification/Notification.jsx +++ b/components/vc-notification/Notification.jsx @@ -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 { getComponent } from '../_util/props-util'; import BaseMixin from '../_util/BaseMixin'; import createChainedFunction from '../_util/createChainedFunction'; import Notice from './Notice'; import { getTransitionGroupProps, TransitionGroup } from '../_util/transition'; +import ConfigProvider, { globalConfig } from '../config-provider'; function noop() {} @@ -95,7 +96,9 @@ const Notification = defineComponent({ key, }; return ( - {typeof content === 'function' ? content() : content} + + {typeof content === 'function' ? content({ prefixCls }) : content} + ); }); const className = { @@ -120,7 +123,13 @@ const Notification = defineComponent({ }); 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'); if (getContainer) { const root = getContainer(); @@ -128,37 +137,43 @@ Notification.newInstance = function newNotificationInstance(properties, callback } else { document.body.appendChild(div); } - const app = createApp({ - mounted() { - const self = this; - this.$nextTick(() => { - callback({ - notice(noticeProps) { - self.$refs.notification.add(noticeProps); - }, - removeNotice(key) { - self.$refs.notification.remove(key); - }, - component: self, - destroy() { - app.unmount(div); - if (div.parentNode) { - div.parentNode.removeChild(div); - } - }, + let vm = null; + const Wrapper = defineComponent({ + setup(_props, { attrs }) { + const notiRef = ref(); + onMounted(() => { + nextTick(() => { + callback({ + notice(noticeProps) { + notiRef.value?.add(noticeProps); + }, + removeNotice(key) { + notiRef.value?.remove(key); + }, + destroy() { + vm?.unmount(div); + if (div.parentNode) { + div.parentNode.removeChild(div); + } + }, + }); }); }); - }, - render() { - const p = { - ...props, - ref: 'notification', - style, - class: className, + return () => { + const { getPrefixCls, getRootPrefixCls } = globalConfig(); + const prefixCls = getPrefixCls('message', customizePrefixCls); + const rootPrefixCls = getRootPrefixCls(customRootPrefixCls, prefixCls); + return ( + + + + ); }; - return ; }, }); - app.mount(div); + + vm = createVNode(Wrapper, props); + vm.appContext = appContext || vm.appContext; + vueRender(vm, div); }; export default Notification;